快速回顾
本文进一步解析μC/OS-Ⅱ中,软件定时器的函数源码。
μC/OSⅡ中的定时器系统
软件定时器并不属于事件系统,是一类特殊的模型,有自己独特的执行逻辑。更具体来说,除了手动创建、启动和销毁,软件定时器的其它生命周期过程无需用户操作,更不与其它任务相关联,它和定时器任务共同构成了软件定时器系统。
在定时器系统中,最重要的就是如何检查定时器的到期,对于一个同步系统来说,基本只能使用“轮询”的方式,即定期检查,这种方式存在两个关键问题:
①如何把控轮询间隔,首先轮询间隔必须是固定(否则步长不定,时间精度也就无从谈起),而且间隔不能太长,否则定时器的时间精度就下降了。也不能太短,这样太消耗资源;
②二是当定时器很多时,遍历的时间就会线性增加,如何设计结构提高遍历效率。
对于问题①,比较好解决,可以选一个稳定且周期性的中断作为轮询出发点(比如STM32里的滴答中断),并根据用户需求进行间隔时长的配置。
对于问题②,为了提高轮询效率,μC/OSⅡ使用“车轮式”(Wheel)的查询结构,将时间线周期性地均匀缠绕在“车轮”上,好比钟表走时一样,每一根车辐都对应一个时间刻度,进而可以将不同的定时器通过到期时间归属到对应的时刻上,每一时刻只需盘点该时刻下的定时器,可以减少对大量定时器的遍历,提高查询效率。这种算法本质上还是用空间换取时间。

相关结构和类型
和软件定时器相关的变量如下:
//ucos_ii.h
OS_EXT INT16U OSTmrFree; /* 剩余可用的空白定时器 */
OS_EXT INT16U OSTmrUsed; /* 已使用的定时器数量 */
OS_EXT INT32U OSTmrTime; /* 当前时间 */
OS_EXT OS_EVENT *OSTmrSem; /* 操作定时器的权限 */
OS_EXT OS_EVENT *OSTmrSemSignal; /* 当定时器更新(到期)时,用于提醒定时器任务运行的信号量 */
OS_EXT OS_TMR OSTmrTbl[OS_TMR_CFG_MAX]; /* 软件定时器数组 */
OS_EXT OS_TMR *OSTmrFreeList; /* 空白软件定时器链表 */
OS_EXT OS_STK OSTmrTaskStk[OS_TASK_TMR_STK_SIZE]; //软件定时器堆栈大小
OS_EXT OS_TMR_WHEEL OSTmrWheelTbl[OS_TMR_CFG_WHEEL_SIZE]; //时间车轮数组,每一个成员代表一个时间刻度
OS_TMR_CFG_MAX表示定时器的最大数量,OS_TMR_CFG_WHEEL_SIZE表示时间车轮的车辐数,也即时间刻度数,下文中的“车辐”和“刻度”表示一个意思。
两个信号量,OSTmrSem是获取定时器操作权限的信号量,OSTmrSemSignal是滴答中断用来提醒定时器任务执行的信号量。
这里面比较重要的类型就是定时器OS_TMR和时间车轮OS_TMR_WHEEL:
OS_TMR
与任务、事件类似,定时器也是以链表的形式进行遍历检索的(除了存储定时器的原始数组),且是双向链表的形式,方便在链表中进行插入和删除元素。
//ucos_ii.h
typedef struct os_tmr {
INT8U OSTmrType; /* 初始化后被设置位OS_TMR_TYPE(其它类型无效) */
OS_TMR_CALLBACK OSTmrCallback; /* 定时器回调函数 */
void *OSTmrCallbackArg; /* 需要传给回调函数的参数 */
void *OSTmrNext; /* 和OSTmrPrev共同构成双向链表指针 */
void *OSTmrPrev;
INT32U OSTmrMatch; /* 到期时间,即当OSTmrTime=OSTmrMatch时定时器到期 */
INT32U OSTmrDly; /* 开启定时器前的延时 */
INT32U OSTmrPeriod; /* 定时器周期 */
#if OS_TMR_CFG_NAME_EN > 0u
INT8U *OSTmrName; /* 定时器名称 */
#endif
INT8U OSTmrOpt; /* 选项(如OS_TMR_OPT_xxx) */
INT8U OSTmrState; /* 定时器状态,有四种 */
} OS_TMR;
里面有两个成员可以进一步解析,一个是选项OSTmrOpt:
//ucos_ii.h
#define OS_TMR_OPT_NONE 0u /* 无选项 */
#define OS_TMR_OPT_ONE_SHOT 1u /* 单次定时器,不会自动重启 */
#define OS_TMR_OPT_PERIODIC 2u /* 周期性定时器,到期后自动重启 */
#define OS_TMR_OPT_CALLBACK 3u /* OSTmrStop() option to call 'callback' w/

最低0.47元/天 解锁文章
514

被折叠的 条评论
为什么被折叠?



