uC/OS-III之定时器管理
来源:互联网 发布:java nio 关闭连接 编辑:程序博客网 时间:2024/05/16 04:06
1.所谓定时器本质上是递减计数器,当计数器减到零时可以出发某种动作的执行。这种动作可以通过回调函数(callback funtion,简称回调)来实现。需要注意的是,一定要避免在回调函数中使用阻塞调用。
注:定时器在一些协议栈的实现中很有用,也可以用来定期轮训IO设备。
2.定时器任务的频率通过宏定义OS_CFG_TMR_TASK_RATE_HZ来实现,单位是Hz。
该宏定义位于文件os_cfg_app.h中。
注:定时器任务频率的常用推荐值是10Hz。
3.定时器是一个内核对象,其数据类型为OS_TMR。它的定义位于文件os.h中。
typedef struct os_tmr OS_TMR; // 643行struct os_tmr { // 1001行 - 1018行 OS_OBJ_TYPE Type; // 类型,这里说明一下,内核对象结构体的定义都是以Type作为第一个成员变量,这样uC/OS-III就可以判断结构体是那种内核对象。 CPU_CHAR *NamePtr; // 定时器的名字 OS_TMR_CALLBACK_PTR CallbackPtr; // 回调函数指针 void *CallbackPtrArg; // 回调函数的参数 OS_TMR *NextPtr; // 这两个指针构成双向链表,连接定时器 OS_TMR *PrevPtr; OS_TICK Match; // 当计数器的值到达该值时,定时时间到 OS_TICK Remain; // 存储距离定时器定时时间到的剩余时间 OS_TICK Dly; // 开始之前的初始值 OS_TICK Period; // 定时周期 OS_OPT Opt; // 选项 OS_STATE State; // 定时器的状态#if OS_CFG_DBG_EN > 0u // 允许调试 OS_TMR *DbgPrevPtr; OS_TMR *DbgNextPtr;#endif};
4.定时器的状态有4种:未使用、停止、运行、完成。
(1)“未使用”状态代表定时器未被创建或者已经删除
(2)定时器已创建但未调用OSTmrStart()函数之前或调用OSTmrStop()函数之后,定时器处于“停止”状态
(3)调用OSTmrStart()之后,定时器处于“运行”状态
(4)“完成”状态是指单次定时器过期后所处的状态
5.定时器列表包含一个表(OSCfg_TmrWheel[],在os_cfg_app.c中声明)和一个计数器(OSTmrTickCtr,在os.h中声明)。
6.OSCfg_TmrWheel[]表称为定时器轮。定时器轮中的每个条目的数据类型是OS_TMR_SPOKE(该结构体定义在os.h中),它的大小由宏定义OS_CFG_TMR_WHEEL_SIZE(定义在os_cfg_app.h中)设定。
建议不要将OS_CFG_TMR_WHEEL_SIZE设为定时器任务率的偶数倍,最好使用素数。
7.OS_TMR_SPOKE结构体的定义位于os.h中
typedef struct os_tmr_spoke OS_TMR_SPOKE; // 644行struct os_tmr_spoke { // 1022行 - 1026行 OS_TMR *FirstPtr; // 在双向链表中指向第一个定时器 OS_OBJ_QTY NbrEntries; // 链接到这个条目的定时器的数量 OS_OBJ_QTY NbrEntriesMax; // 用来跟踪表中最大定时器数目};
8.定时任务OS_TmrTask()的定位位于os_tmr.c中,1041行 - 1101行
void OS_TmrTask (void *p_arg){ CPU_BOOLEAN done; OS_ERR err; OS_TMR_CALLBACK_PTR p_fnct; OS_TMR_SPOKE *p_spoke; OS_TMR *p_tmr; OS_TMR *p_tmr_next; OS_TMR_SPOKE_IX spoke; CPU_TS ts; CPU_TS ts_start; CPU_TS ts_end; p_arg = p_arg; // 参数 while (DEF_ON) { (void)OSTaskSemPend((OS_TICK )0, // 等待信号量。若用直接发布模式,该信号量来自OSTimeTick();若用延迟发布模式,该信号量来自OS_IntQTask() (OS_OPT )OS_OPT_PEND_BLOCKING, (CPU_TS *)&ts, (OS_ERR *)&err); OSSchedLock(&err); // 锁定调度器 ts_start = OS_TS_GET(); // 记录定时任务的开始执行时间 OSTmrTickCtr++; // 计数器加1 spoke = (OS_TMR_SPOKE_IX)(OSTmrTickCtr % OSCfg_TmrWheelSize); // 获取定时器轮的条目位置 p_spoke = &OSCfg_TmrWheel[spoke]; // 根据条目位置获取条目 p_tmr = p_spoke->FirstPtr; // 获取该条目下的第一个定时器 done = DEF_FALSE; while (done == DEF_FALSE) { if (p_tmr != (OS_TMR *)0) { p_tmr_next = (OS_TMR *)p_tmr->NextPtr; // 获取下一个定时器 if (OSTmrTickCtr == p_tmr->Match) { // 定时时间到 OS_TmrUnlink(p_tmr); // 从当前条目中删除定时器 if (p_tmr->Opt == OS_OPT_TMR_PERIODIC) { // 周期执行 OS_TmrLink(p_tmr, OS_OPT_LINK_PERIODIC); // 在定时器轮中重新分配一个位置给定时器 } else { // 单次执行 p_tmr->State = OS_TMR_STATE_COMPLETED; // 定时器的状态改为“完成” } p_fnct = p_tmr->CallbackPtr; // 执行回调函数 if (p_fnct != (OS_TMR_CALLBACK_PTR)0) { (*p_fnct)((void *)p_tmr, p_tmr->CallbackPtrArg); } p_tmr = p_tmr_next; // 定时器指针向后移 } else { // 定时时间未到 done = DEF_TRUE; } } else { done = DEF_TRUE; } } ts_end = OS_TS_GET() - ts_start; // 测量定时任务的执行时间 OSSchedUnlock(&err); // 解锁定时器 if (ts_end > OSTmrTaskTimeMax) { // 记录定时任务执行的最长时间 OSTmrTaskTimeMax = ts_end; } }}
- uC/OS-III之定时器管理
- uC/OS-III之中断管理总结
- uC/OS-III之时间管理
- uC/OS iii(三)任务管理之任务状态
- uC/OS-III之资源管理
- uC/OS-III之信号量
- uc/os-iii学习笔记-任务管理
- uc/os-iii学习笔记-中断管理
- uc/os-iii学习笔记-时间管理
- uc/os-III任务管理总结
- uc/os iii(二)时间管理
- uC/OS-III的任务管理
- uC/OS-III之系统内部任务
- uC/OS-III之任务调度总结
- uC/OS-III之学习总结
- uC/OS-III之时钟节拍列表
- uC/OS-III之资源管理--互斥型信号量
- uC/OS-III之任务挂起表
- bzoj 3223 splay 解题报告
- myeclipse中快捷键
- 远程数据库备份到本地(本地无数据库)
- sql中exists,not exists的用法
- 单元测试Mock使用方法
- uC/OS-III之定时器管理
- 斐波那契数列问题汇总
- java word转pdf的几种方法
- Linux IPC通信方式
- android常用缩写
- openwrt上移植wifidog
- Java过滤器与SpringMVC拦截器之间的关系与区别
- Struts2_ValueStack,OGNL详解
- nginx+RTMP搭建流媒体服务器