2 μC/OS-III中的时钟节拍管理机制 针对μC/OS-II时钟节拍服务的问题,μC/OS-III主要做了两点改进:①用时钟节拍任务来做时钟节拍处理;②用时钟节拍轮盘来分类管理延时任务以及指定超时时限的等待任务。 2.1 时钟节拍任务 在μC/OS-III中,增加了一个系统任务,即时钟节拍任务OS_TickTask()。该任务是μC/OS-III中两个总是会创建的系统任务之一。时钟节拍任务负责处理延时任务和指定超时时限的等待任务,这样,μC/OS-III就把时钟节拍的处理工作放到任务级代码中完成了。时钟节拍中断服务程序和时钟节拍任务之间的关系如图1所示。
不论在μC/OS-II还是在μC/OS-III中,都需要一个硬件定时器(或其他能产生周期性中断的外设)来产生几十到上千赫兹的时钟节拍中断。时钟节拍中断的具体频率取决于所用的处理器的性能以及应用需求。时钟节拍中断频率越高,系统的延时精度越高,对处理器的处理能力要求也越高。
每次产生时钟节拍中断,CPU都会跳转到时钟节拍中断服务程序(ISR)中执行。时钟节拍ISR会调用OSTimeTick()函数。前面提到过,μC /OS-II的时钟节拍ISR也会调用OSTimeTick()函数,在这一点上μC/OS-II和μC/OS-III看起来没有区别,但实际上μC/OS-III中的OS TimeTick()函数与μC/OS-II中的OSTimeTick()函数有很大区别。μC/OS-III中的OSTimeTick()函数主要完成如下操作:向时钟节拍任务发信号、调用OS_SchedRoundRobin()函数,以及向定时器任务发信号等。其中,后两点与时钟节拍的管理无关,这里不详细介绍。精简的OSTimeTick()函数如下面这段代码所示,其中只保留与时钟节拍管理相关的代码。
在μC/OS—III中,OSTimeTick()函数不需要遍历任务链表,只是通过OSTaskSemPost()函数向时钟节拍任务发信号。而时钟节拍任务绝大部分时间内都处于等待该信号的状态,每次收到该信号时,时钟节拍任务会恢复运行,调用OS_TiekListUpdate()函数处理延时的任务,然后再次进入等待该信号的状态,其代码如下:
![](http://embed.chinaitlab.com/UploadFiles_4615/201301/20130121114902267.jpg)
相比μC/OS—II的时钟节拍管理方式,μC/OS—III使用了专门的时钟节拍任务来处理时钟节拍,可大大减少时钟节拍中断服务程序的执行时间。
2.2 延时任务管理
μC/OS—III为了提高时钟节拍的处理速度,采用了哈希散列表机制来管理所有正在延时的任务和指定了超时时限的等待任务。这些任务都记录在时钟节拍列表(Tick List)中。时钟节拍列表包含两部分:一个称为时钟节拍轮盘的数组(OSCfg_TickWheel[])和一个时钟节拍计数器(OSTickCtr),如图2所示。
时钟节拍列表中的每个任务都有一个延时结束时刻或等待超时时限,假设为TM.比如,一个任务在时钟节拍计数器数值为OSTickCtr时调用OSTimeDly()延时dly个时钟节拍,那么该任务的延时结束时刻TM就等于OSTickCtr+dly.然后,用TM和时钟节拍轮盘的表项个数(OS_CFG_TI CK_WHEEL_SIZE)做取模运算,就可以得到一个余数I(I=TM%OS_CFG_TICK_WHEEL_SIZE)。那么,该延时任务就会放到时钟节拍轮盘第1个表项指向的任务链表中。
时钟节拍轮盘的每个表项都有3个成员:".NbrEntriesMax"、".NbrEntries"和".FirstPtr".其中,".FirstPtr"指向该表项对应的任务链表,所有分配到该表项的延时任务或指定超时时限的等待任务都会放到该任务链表中。".NbrEntries"和".NbrEntries Max"分别记录任务链表中的当前任务数目和历史最大任务数目。在任务链表中,任务按照延时结束时刻或超时时限排序,结束时刻早的任务排在链表的前面。 通过采用哈希散列表机制,在每次时钟节拍服务时,只需要处理时钟节拍轮盘的某个特定表项所指向的任务链表,因为恰好在该时钟节拍服务时延时结束或等待超时的任务都一定处于该表项所指向的任务链表中,而该表项的索引号就等于OSTickCtr%OS_CFG_TICK_WHEEL_SIZ E.另外,由于各个表项指向的任务链表中的任务是按照延时结束时刻和等待超时时限的顺序进行排序的,这样,在处理当前任务链表时,就可以从位于链表头部的任务开始判断任务延时结束时刻或等待超时时限是否等于OSTickCtr的当前值。如果等于,说明该任务延时结束或等待超时了,然后,再判断下一个任务;如果不等于,说明该任务延时没有结束或等待没有超时,同时也说明,排在链表后面的任务都不可能延时结束或等待超时,因此,可以立即结束对任务链表的处理。 由于采用了哈希散列表机制,μC/OS-III中的时钟节拍服务在大部分情况下只需要判断极少数任务的延时结束时刻或超时时限,看其是否等于时钟节拍计数器的当前值,这相比μC/OS-II中需要遍历整个任务链表的时钟节拍服务,显然效率要高很多。 结语 μC/OS-II中的时钟节拍服务有两个不足之处:一是需要遍历整个任务链表,二是需要在时钟节拍中断服务程序中进行时钟节拍的处理工作。当系统中任务数目较多时,会影响系统的实时性,这对于一个实时嵌入式操作系统来说是不完善的地方。在μC/OS-III中,通过增加一个时钟节拍系统任务并采用哈希散列表机制,很好地解决了这两点问题,即使在系统任务数目很多的时候,也可以确保系统的实时性。 |