1. 程式人生 > >任務延時函式,OSTimeDly()

任務延時函式,OSTimeDly()

µC/OS-Ⅱ提供了這樣一個系統服務:申請該服務的任務可以延時一段時間,這段時間的長短是用時鐘節拍的數目來確定的。實現這個系統服務的函式叫做OSTimeDly()。呼叫該函式會使µC/OS-Ⅱ進行一次任務排程,並且執行下一個優先順序最高的就緒態任務。任務呼叫OSTimeDly()後,一旦規定的時間期滿或者有其它的任務通過呼叫OSTimeDlyResume()取消了延時,它就會馬上進入就緒狀態。注意,只有當該任務在所有就緒任務中具有最高的優先順序時,它才會立即執行。
程式清單 L5.1所示的是任務延時函式OSTimeDly()的程式碼。使用者的應用程式是通過提供延時的時鐘節拍數——一個1 到65535之間的數,來呼叫該函式的。如果使用者指定0值[L5.1(1)],則表明使用者不想延時任務,函式會立即返回到呼叫者。非0值會使得任務延時函式OSTimeDly()將當前任務從就緒表中移除[L5.1(2)]。接著,這個延時節拍數會被儲存在當前任務的OS_TCB中[L5.1(3)],並且通過OSTimeTick()每隔一個時鐘節拍就減少一個延時節拍數。最後,既然任務已經不再處於就緒狀態,任務排程程式會執行下一個優先順序最高的就緒任務。

程式清單 L 5.1	OSTimeDly().
void OSTimeDly (INT16U ticks)
{
    if (ticks > 0) {                                                         (1)
        OS_ENTER_CRITICAL();
        if ((OSRdyTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0) {     (2)
            OSRdyGrp &= ~OSTCBCur->OSTCBBitY;        }
        OSTCBCur->OSTCBDly = ticks;                                        (3)
        OS_EXIT_CRITICAL();
        OSSched();                                                            (4)
    }
}

	清楚地認識0到一個節拍之間的延時過程是非常重要的。換句話說,如果使用者只想延時一個時鐘節拍,而實際上是在0到一個節拍之間結束延時。即使使用者的處理器的負荷不是很重,這種情況依然是存在的。圖F5.1詳細說明了整個過程。系統每隔10ms發生一次時鐘節拍中斷[F5.1(1)]。假如使用者沒有執行其它的中斷並且此時的中斷是開著的,時鐘節拍中斷服務就會發生[F5.1(2)]。也許使用者有好幾個高優先順序的任務(HPT)在等待延時期滿,它們會接著執行[F5.1(3)]。接下來,圖5.1中所示的低優先順序任務(LPT)會得到執行的機會,該任務在執行完後馬上呼叫[F5.1(4)]所示的OSTimeDly(1)。µC/OS-Ⅱ會使該任務處於休眠狀態直至下一個節拍的到來。當下一個節拍到來後,時鐘節拍中斷服務子程式會執行[F5.1(5)],但是這一次由於沒有高優先順序的任務被執行,µC/OS-Ⅱ會立即執行申請延時一個時鐘節拍的任務[F5.1(6)]。正如使用者所看到的,該任務實際的延時少於一個節拍!在負荷很重的系統中,任務甚至有可能會在時鐘中斷即將發生時呼叫OSTimeDly(1),在這種情況下,任務幾乎就沒有得到任何延時,因為任務馬上又被重新排程了。如果使用者的應用程式至少得延時一個節拍,必須要呼叫OSTimeDly(2),指定延時兩個節拍!