OSTimeTick分析

轉自:csshuke
ucos V2.52
OSTimeTick()函數解析
調用處:os_cpu_a.asm裏_OSTickISR
函數所有源文件:os_core.c
代碼:
void  OSTimeTick (void)
{
#if OS_CRITICAL_METHOD == 3           /* Allocate storage for CPU status register */
OS_CPU_SR  cpu_sr;
#endif    
OS_TCB    *ptcb;


OSTimeTickHook();                 /* Call user definable hook                 */
#if OS_TIME_GET_SET_EN > 0   
OS_ENTER_CRITICAL();             /* Update the 32-bit tick counter           */
OSTime++;                                                             //(1)
OS_EXIT_CRITICAL();
#endif
if (OSRunning == TRUE) {           //(2)
ptcb = OSTCBList;            /* Point at first TCB in TCB list           */     
while (ptcb->OSTCBPrio != OS_IDLE_PRIO) 
{    /* Go through all TCBs in TCB list          */   //(3)
OS_ENTER_CRITICAL();           //(4)
if (ptcb->OSTCBDly != 0) 
{       /* Delayed or waiting for event with TO     */    //(5)
if (--ptcb->OSTCBDly == 0) 
{      /* Decrement nbr of ticks to end of delay   */    //(6)
if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == OS_STAT_RDY) 
{ /* Is task suspended?    */    //(7)
/* No, Make task R-to-R (timed out)*/
OSRdyGrp |= ptcb->OSTCBBitY;
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;      //(8)
} else {            /* Yes, Leave 1 tick to prevent loosing the task when the suspension is removed.*/
ptcb->OSTCBDly = 1;  //(9)

}
}
ptcb = ptcb->OSTCBNext;  /* Point at next TCB in TCB list   */    //(10)
OS_EXIT_CRITICAL();          //(11)
}
}
}

內容解釋:
     (1)進入臨界段, OSTime++;
     (2)如果os已開始運行(OSStart()已執行,則執行if裏面的語句;
     (3)遍歷OSTCBList,直到idle task;
     (4)進入臨界段
     (5)如果ptcb->OSTCBDly不爲0,則需要處理
     (6)--ptcb->OSTCBDly,如果自減後爲0
     (7)如果任務不是由OSTaskSuspend()掛起的,由event掛起或只是OSTimeDly()掛起
     (8)使該優先級的任務處於就緒態
     (9)如果任務是由OSTaskSuspend()掛起的,則 ptcb->OSTCBDly重新置爲1.
     (10)得OSTCBList鏈表的下一個os_tcb項。
     (11)退出臨界段

1,重點解釋(9),爲什麼的馬OSTaskSuspend()掛起的任務的ptcb->OSTCBDly重新置爲1呢?
對OSTimeTick()函數來說,ptcb->OSTCBDly=0的task它不處理。
被OSTackSuspend()掛起的任務,可以被OSTaskResume()解除掛狀態,所以OSTimeTick()有義務持續檢測被掛起的任務,所以要保持ptcb->OSTCBDly>0。
而對於非OSTackSuspend()掛起的任務,不管是由event掛起或只是OSTimeDly()掛起,既然設置了超時時間,當ptcb->OSTCBDly=0時就要置爲就緒態。
2,(8)是如何使任務進入就緒態的呢?
首先,通過OSRdyGrp和OSRdyTbl[ptcb->OSTCBY]賦值,告知OS此優先級的任務已經準備就緒;
然後,在OS_Sched()裏尋找最高優先級任務,做任務切換。
3,(5),ptcb->OSTCBDly!=0人有一種情況,此任務是等待狀態的任務。可是是因爲event掛起或只是OSTimeDly()掛起。
ptcb->OSTCBDly=0有三種情況,一種是此任務是運行態的任務;第二種是此任務是就緒態的任務;第三種是此任務是等待狀態的任務,等待某個event,且timeout設置爲0.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章