软定时器的删除与状态查询
目录
软定时器的删除
设计实现
软定时器的删除
将软定时器从所在列表中移除。
设计实现
- 定时器删除(调用tTimerStop函数)
- 定时器状态查询(状态查询结构:初次启动延后的ticks数、周期定时时的周期tick数、定时回调函数、传递给回调函数的参数、定时器配置参数、定时器状态)
tTimer.c
#include "tinyOS.h"
static tList tTimerHardList; //中断服务处理程序中处理的软定时器列表
static tList tTimerSoftList; //定时器任务处理的软定时器列表
static tSem tTimerProtectSem; //定时器任务以及其他任务访问SoftList的信号量
static tSem tTimerTickSem; //中断服务处理程序中通知定时器任务有定时中断发生
/* 软定时器初始化 */
//参数:软定时器,初始延时的tick数,周期数,定时器的回调函数,回调函数参数,配置
void tTimerInit(tTimer *timer, uint32_t delayTicks, uint32_t durationTicks, void (*timerFunc)(void *arg), void *arg, uint32_t config)
{
tNodeInit(&timer->linkNode);
timer->startDelayTicks = delayTicks;
timer->durationTicks = durationTicks;
timer->timerFunc = timerFunc;
timer->arg = arg;
timer->config = config;
if(delayTicks == 0)
{
timer->delayTicks = durationTicks;//定时器当前计数值等于使用周期的计数器
}
else
{
//有延时
timer->delayTicks = timer->startDelayTicks;
}
timer->state = tTimerCreated;
}
/* 软定时器启动函数 */
void tTimerStart(tTimer *timer)
{
//判断定时器状态
switch(timer->state)
{
case tTimerCreated:
case tTimerStopped://创建或已停止才能启动
//设置初始延时tick数
timer->delayTicks = timer->startDelayTicks ? timer->startDelayTicks : timer->durationTicks;
timer->state = tTimerStarted;
//根据配置决定插入到哪个定时器列表中
if(timer->config & TIMER_CONFIG_TYPE_HARD)
{
//时钟节拍的中断处理函数中也会访问定时器中断列表,开启临界区保护
uint32_t status = tTaskEnterCritical();
tListAddFirst(&tTimerHardList, &timer->linkNode);
tTaskExitCritical(status);
}
else
{
//信号量保护,中断中已经不允许访问SoftList
//想在中断中调用不能用信号量保护,需要使用临界区保护
tSemWait(&tTimerProtectSem, 0);
tListAddFirst(&tTimerSoftList, &timer->linkNode);
tSemNotify(&tTimerProtectSem);
}
break;
default:
break;
}
}
/* 软定时器停止函数 */
void tTimerStop(tTimer *timer)
{
switch (timer->state)
{
case tTimerStarted:
case tTimerRunning://已经启动或正在运行才能停止
if(timer->config & TIMER_CONFIG_TYPE_HARD)
{
uint32_t status = tTaskEnterCritical();
tListRemove(&tTimerHardList, &timer->linkNode);
tTaskExitCritical(status);
}
else
{
tSemWait(&tTimerProtectSem, 0);
tListRemove(&tTimerSoftList, &timer->linkNode);
tSemNotify(&tTimerProtectSem);
}
break;
default:
break;
}
}
/* 软定时器删除函数 */
void tTimerDestroy(tTimer *timer)
{
tTimerStop(timer);
timer->state = tTimerDestroyed;
}
/* 软定时器状态查询函数 */
void tTimerGetInfo(tTimer *timer, tTimerInfo *info)
{
uint32_t status = tTaskEnterCritical();
info->startDelayTicks = timer->startDelayTicks;
info->durationTicks = timer->durationTicks;
info->timerFunc = timer->timerFunc;
info->arg = timer->arg;
info->config = timer->config;
info->state = timer->state;
tTaskExitCritical(status);
}
/* 对软定时器列表进行处理函数 */
static void tTimerCallFuncList(tList *timerList)
{
//遍历各结点
tNode *node;
for(node = timerList->headNode.nextNode; node != &(timerList->headNode); node = node->nextNode)
{
tTimer *timer = tNodeParent(node, tTimer, linkNode);//取出结点对应的定时器
//判断定时器延时时间是否到达或者对定时器延时计数减减操作后为0
if((timer->delayTicks == 0) || (--timer->delayTicks == 0))
{
//调用定时器处理函数
timer->state = tTimerRunning;
timer->timerFunc(timer->arg);
timer->state = tTimerStarted;
//检查定时器是否需要周期计数
if(timer->durationTicks > 0)
{
timer->delayTicks = timer->durationTicks;
}
else
{
tListRemove(timerList, &timer->linkNode);
timer->state = tTimerStopped;
}
}
}
}
static tTask tTimerTask;//定时器任务
static tTaskStack tTimerTaskStack[TINYOS_TIMERTASK_STACK_SIZE];//定时器任务堆栈
/* 定时器任务函数 */
static void tTimerSoftTask(void *param)
{
for(;;)
{
tSemWait(&tTimerTickSem, 0);//等待tTimerTickSem,在系统节拍处理函数中向信号量发送通知
tSemWait(&tTimerProtectSem, 0);//申请tTimerProtectSem信号量,定时器任务拥有对SoftList访问权
tTimerCallFuncList(&tTimerSoftList);//对SoftList中软定时器处理
tSemNotify(&tTimerProtectSem);//释放信号量
}
}
/* 通知信号量相应的tick中断已发生函数 */
//中断服务函数中调用,计数器恢复运行
void tTimerModuleTickNotify(void)
{
uint32_t status = tTaskEnterCritical();
//函数在中断服务处理函数中调用,同时处理HandList定时器列表
tTimerCallFuncList(&tTimerHardList);
tTaskExitCritical(status);
tSemNotify(&tTimerTickSem);//通知信号量,计数值加1。定时器任务函数SemWait函数唤醒
}
/* 定时器初始化 */
void tTimerModuleInit(void)
{
//初始化定时器列表
tListInit(&tTimerHardList);
tListInit(&tTimerSoftList);
//初始化信号量
tSemInit(&tTimerProtectSem, 1, 1);//初始值和最大计数值均为1
tSemInit(&tTimerTickSem, 0, 0); //初始值为0,最大计数值没有限制
//初始化任务
//任务定时器优先级要大于空闲任务优先级
#if TINYOS_TIMERTASK_PRIO >= (TINYOS_PRO_COUNT - 1)
#error "The proprity of timer tasker must be greater then (TINYOS_PRO_COUNT - 1)"
#endif
tTaskInit(&tTimerTask, tTimerSoftTask, (void *)0, TINYOS_TIMERTASK_PRIO, &tTimerTaskStack[TINYOS_TIMERTASK_STACK_SIZE]);
}
tTimer.h
#ifndef __TTIMER_H
#define __TTIMER_H
#include "tEvent.h"
/* 软定时器状态 */
typedef enum _tTimerState
{
tTimerCreated, //已创建
tTimerStarted, //已启动
tTimerRunning, //正在运行
tTimerStopped, //已停止
tTimerDestroyed //已销毁
}tTimerState;
/* 软定时器结构 */
typedef struct _tTimer
{
tNode linkNode; //链接结点
uint32_t startDelayTicks; //初始时的延时计数
uint32_t durationTicks; //周期的计数值
uint32_t delayTicks; //当前的计数值
void (*timerFunc)(void *arg); //定时器的回调处理函数
void *arg; //传递给回调处理函数的参数
uint32_t config; //定时器配置
tTimerState state; //定时器状态
}tTimer;
/* 软定时器状态查询结构 */
typedef struct _tTimerInfo
{
uint32_t startDelayTicks; //初始时的延时计数
uint32_t durationTicks; //周期的计数值
void (*timerFunc)(void *arg); //定时器的回调处理函数
void *arg; //传递给回调处理函数的参数
uint32_t config; //定时器配置
tTimerState state; //定时器状态
}tTimerInfo;
//定时器是在定时器任务中处理的还是系统时钟节拍中断中处理的宏
#define TIMER_CONFIG_TYPE_HARD (1 << 0) //中断中
#define TIMER_CONFIG_TYPE_SOFT (0 << 0) //任务中
void tTimerInit(tTimer *timer, uint32_t delayTicks, uint32_t durationTicks, void (*timerFunc)(void *arg), void *arg, uint32_t config);
void tTimerStart(tTimer *timer);
void tTimerStop(tTimer *timer);
void tTimerDestroy(tTimer *timer);
void tTimerGetInfo(tTimer *timer, tTimerInfo *info);
void tTimerModuleTickNotify(void);
void tTimerModuleInit(void);
#endif
app.c
#include "tinyOS.h"
#include "string.h"
//定义任务,分别为它们配备独立的堆栈空间
tTask tTask1;
tTask tTask2;
tTask tTask3;
tTask tTask4;
tTaskStack task1Env[1024];
tTaskStack task2Env[1024];
tTaskStack task3Env[1024];
tTaskStack task4Env[1024];
tTimer timer1;
tTimer timer2;
tTimer timer3;
uint32_t bit1 = 0;
uint32_t bit2 = 0;
uint32_t bit3 = 0;
//传32位整型指针的值,将值原来对应变量的最低位取反
void timerFunc(void *arg)
{
uint32_t *ptrBit = (uint32_t *)arg;
*ptrBit ^= 0x1;
}
//定义任务要执行的功能
int task1Flag;
void task1Entry(void *param)
{
uint32_t destroy = 0;
tTimerInfo timerinfo;
tSetSysTickPeriod(10);//初始化
tTimerInit(&timer1, 100, 10, timerFunc, (void *)&bit1, TIMER_CONFIG_TYPE_HARD);
tTimerStart(&timer1);
tTimerInit(&timer2, 200, 20, timerFunc, (void *)&bit2, TIMER_CONFIG_TYPE_HARD);
tTimerStart(&timer2);
tTimerInit(&timer3, 300, 0, timerFunc, (void *)&bit3, TIMER_CONFIG_TYPE_SOFT);
tTimerStart(&timer3);
for(;;)//任务里是for的死循环
{
task1Flag = 0;
tTaskDelay(1);
task1Flag = 1;
tTaskDelay(1);
if(destroy == 0)
{
tTaskDelay(200);
tTimerDestroy(&timer1);
destroy = 1;
}
tTimerGetInfo(&timer2, &timerinfo);
}
}
int task2Flag;
void task2Entry(void *param)
{
for(;;)
{
task2Flag = 0;
tTaskDelay(1);
task2Flag = 1;
tTaskDelay(1);
}
}
int task3Flag;
void task3Entry(void *param)
{
for(;;)
{
task3Flag = 0;
tTaskDelay(1);
task3Flag = 1;
tTaskDelay(1);
}
}
int task4Flag;
void task4Entry(void *param)
{
for(;;)
{
task4Flag = 0;
tTaskDelay(1);
task4Flag = 1;
tTaskDelay(1);
}
}
/* 应用任务初始化函数 */
void tInitApp(void)
{
//最后一个参数:传堆栈末端地址,因为堆栈是向下生长的,初始堆栈地址是堆栈空间最后一个单元地址的末端
tTaskInit(&tTask1, task1Entry, (void *)0x11111111, 0, &task1Env[1024]);
tTaskInit(&tTask2, task2Entry, (void *)0x22222222, 1, &task2Env[1024]);
tTaskInit(&tTask3, task3Entry, (void *)0x22222222, 1, &task3Env[1024]);
tTaskInit(&tTask4, task4Entry, (void *)0x22222222, 1, &task4Env[1024]);
}