最近再查一个代码的问题,问题现象是所有操作系统的soft timer的回调函数均失效了,没有任何被调用的迹象。操作系统的其他任务仍运行正常。
操作系统使用的是ucosii,在分析ucosii的soft timer实现代码时发现ucosii在soft timer实现的一个提高运行效率的技巧。
ucosii的soft timer工作流程如下:
soft timer在ucosii系统里时由一个叫做OSTmr_Task的任务管理的,在系统的OSTickISR函数中不仅要调用OSTimeTick函数还要调用OSTmrSignal函数向OSTmr_Task任务发送一个信号量触发OSTmr_Task的调度。
系统初始化时所有的soft timer初始化成一个单向链表。OSTmrWheelTbl变量是一个大小为OS_TMR_CFG_WHEEL_SIZE的soft timer链表入口数组,程序启动一个soft timer时,根据这个soft timer的tick时刻值(对OS_TMR_CFG_WHEEL_SIZE的取余值)向这个OSTmrWheelTbl链表入口数组的指定链表添加要启动的soft timer,添加时是维护一个双向链表,方便停止这个soft timer时将其从OSTmrWheelTbl的某一链表中删除。
OSTmr_Task任务在每一个tick检查当前tick时刻下需要处理的soft timer时不需要逐个检查整个soft timer数组,只需要检查当前tick值下对应的OSTmrWheelTbl的入口链表即可,可以提高OSTmr_Task任务的运行效率。
总结:利用取余计算的特性,将所有的soft timer根据各自的tick时刻值散列到一个链表数组中,通过在每个tick的处理只处理数组中的一个链表而不是处理所有soft timer来提高运行效率。
另外问题的原因可能是因为OSTmr_Task任务的堆栈向下溢出导致其邻近的soft timer数组OSTmrTbl被覆盖进而导致soft timer回调失效,还有待进一步确认。
阅读(377) | 评论(0) | 转发(0) |