一、时钟节拍
uC/OS-II需要提供周期性信号源,用于实现时间延迟和确认超时。时钟节拍率越高,系统的额外负荷就越重。时钟节拍的实际频率取决于应用程序的精度。时钟节拍可以是专门的硬件定时器,也可以是来自50/60Hz交流电源信号。
注意:必须在多任务系统启动以后,即在调用OSStart()之后,再开启时钟节拍器。调用OSStart()之后应做的第一件事就是初始化定时器中断。通常容易犯的错误是将允许时钟节拍中断放在系统初始化函数OSInit()之后,在启动多任务OSStart()之前。
uC/OS-II中的时钟节拍服务是通过在中断服务子程序中调用OSTimeTick()实现的。OSTimeTick()跟踪所有任务的定时器以及超时时限。
1 void OSTimeTick (void) 2 { 3 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ 4 OS_CPU_SR cpu_sr; 5 #endif 6 OS_TCB *ptcb; 7 8 9 OSTimeTickHook(); /* Call user definable hook */ 10 #if OS_TIME_GET_SET_EN > 0 11 OS_ENTER_CRITICAL(); /* Update the 32-bit tick counter */ 12 OSTime++; 13 OS_EXIT_CRITICAL(); 14 #endif 15 if (OSRunning == TRUE) { 16 ptcb = OSTCBList; /* Point at first TCB in TCB list */ 17 while (ptcb->OSTCBPrio != OS_IDLE_PRIO) { /* Go through all TCBs in TCB list */ 18 OS_ENTER_CRITICAL(); 19 if (ptcb->OSTCBDly != 0) { /* Delayed or waiting for event with TO */ 20 if (--ptcb->OSTCBDly == 0) { /* Decrement nbr of ticks to end of delay */ 21 if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == OS_STAT_RDY) { /* Is task suspended? */ 22 OSRdyGrp |= ptcb->OSTCBBitY; /* No, Make task R-to-R (timed out)*/ 23 OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; 24 } else { /* Yes, Leave 1 tick to prevent ... */ 25 ptcb->OSTCBDly = 1; /* ... loosing the task when the ... */ 26 } /* ... suspension is removed. */ 27 } 28 } 29 ptcb = ptcb->OSTCBNext; /* Point at next TCB in TCB list */ 30 OS_EXIT_CRITICAL(); 31 } 32 } 33 }
1、OSTimeTick首先调用由用户定义的函数OSTimeTickHook。OSTimeTick中工作量较大的是,给每个任务控制块OS_TCB中的时间延迟项OSTCBDly减1。
2、OSTimeTick还计算了自系统上电以来的时钟节拍数OSTime,这是一个无符号的32位数。
3、当某任务的任务控制块中的时间延迟项OSTCBDly减为0时,这个任务就进入了就绪态。
4、OSTimeTick的执行时间正比于应用程序中建立的任务数,然而执行时间仍然是可确定的。
二、时间管理
任务调用了OSTimeDly后,一旦规定的时间期满或者有其他的任务通过调用OSTimeDlyResume取消了延时,它就会立即进入就绪态。注意:只有当该任务在所有就绪任务中具有最高的优先级时,它才会立即运行。
时间: 2024-10-23 00:14:49