ucosii里 ,时钟节拍就好比是人的心脏一样重要,它对于CPU能顺利在各个任务之间切换有着至关重要的作用
使用时钟源有一个特别需要注意的地方:用户必须在多任务系统启动以后再开启时钟节拍器,也就是在调用OSStart之后,
ucos中时钟节拍服务是通过定时器中断服务子程序中调用OSTimeTick()实现的
void OSTimeTick(void)
{
OS_TCB *ptcb;
OSTimeTickHook();
ptcb=OSTCBList;
while(ptcb->OSTCBPrio!=OSTCBPrio!=OS_IDLE_PRIO)
{
OS_ENTER_CRITICAL();
if(ptcb->OSTCBDly!=0)
{
if(--ptcb->OSTCBDly==0)
{
if(!(ptcb->OSTCBStat&OS_STAT_SUSPEND))
{
OSRdyGrp|=ptcb->OSTCBBitY;
OSRdyTbl[ptcb->OSTCBy]|=ptcb->OSTCBBitX;
}
else
{
ptcb->OSTCBDly=1;
}
}
}
Ptcb=ptcb->OSTCBNext;
OS_EXIT_CRITICAL();
}
OS_ENTER_CRITICAL();
OSTime++;
OS_EXIT_CRITICAL();
}
我们知道,CPU总是执行就绪表中优先级最高的任务,任务有没有在就绪表中就得到依靠OSTimeTick()了,OSTimeTick很大的工作是给每个
用户任务控制块OS_TCB中延时项OSTCBDly减1;当某个任务的任务控制块中的时间延时项OSTCBDly减到了零,这个任务就进入就绪态。
下面是对以上代码的分析。
OSTimtick()先调用可由用户定义的时钟节拍外连函数OSTimeTickHook(),这个外连函数可以将时钟节拍函数OSTimetick扩展,ucos的决定首先调用OSTimTickHook()
是打算在时钟节拍中断服务一开始就给用户一个可以做点什么的机会,因为用户可能会有一些时间要求苛刻的工作要做。OSTimtick()中大量的工作是给用户任务控制OS_TCB
中的时间延时项OSTCBDly减1.OSTimTick()从OSTCBList开始,沿着OS_TCB链表做,一直做到空任务(3),当某个任务的任务控制块的时间延时项OSTCBDly减到了零,这个任务就进入了就绪态(5).而确切被任务挂起的函数OSTaskSuspend挂起的任务则不会进入就绪态(4),OSTimeTick的执行时间直接与应用程序中建立了多少个任务成正比,OSTimTick还通过调用OSTime(7),累加从开机以来的时间,用的是一个无符号32位变量,注意再给OSTime加1之前使用了关中断,因为多数微处理器给32位加1操作都得多条指令,