uC/OS-III-6.2-uC/OS-III內部任務管理(任務狀態)
1.任務狀態
從使用者的觀點來看,任務可以是有 5種狀態,見圖 5-6。展示了任務狀態間的轉換關係。
{休眠狀態,就緒狀態,執行狀態,掛起狀態,中斷狀態}
(1).處於休眠狀態的任務駐留於記憶體但未被uC/OS-III使能。通過呼叫OSTaskCreate()函式uC/OS-III建立任務。 任務程式碼是存在於ROM的。但需要用OSTaskCreate()函式通知uC/OS-III關於任務的相關資訊。如果任務的使命完成了,就要呼叫 OSTaskDel()刪除該任務。OSTaskDel()實際上不是刪除任務的程式碼,只是讓任務不再具有使用CPU的資格而已。
(2).就緒狀態的任務根據優先順序有序地排列於就緒列表中。就緒列表中對就緒任務的個數沒有限制。
(3). 正在執行的任務被置為執行狀態。 在單CPU中, 任何時刻只能有一個任務被執行。當應用程式呼叫 OSStart()或者呼叫 OSIntExit()或者呼叫OS_TASK_SW()時 uC/OS-III從就緒佇列中選擇優先順序最高的任務去執行。正如前面所提到的,有些時候任務必須等待某些事件發生,若事件還未發生時,任務就會被設定為掛起狀態。
(4).掛起狀態的任務被放置在掛起列表中以表明任務在等待某些事件的發生。 等待的時候, 任務是不會佔用CPU的。 事件發生時,該任務會被放到就緒佇列中。 在這種情況下, 正在執行的任務可能會被搶佔 ( 被放回就緒列表), 並由uC/OS-III選擇優先順序最高的任務去執行。換句話說,如果新的任務優先順序最高,那麼它就會被立即執行。
請注意, 呼叫OSTaskSuspend()會任務無條件地停止執行。 有些時候呼叫 OSTaskSuspend()不是為了等待某個事件的發生,而是等待另一個任務呼叫OSTaskResume()函式恢復這個任務。
(5).若中斷髮生, 中斷會掛起正在執行的任務並去處理ISR。ISR中可能有某些任務等待的事件。 一般來說, 中斷用來通知任務某些事件的發生,並讓在任務級處理實際的響應操作。 ISR程式越短越好,實際響應中斷的操作應該被設定在任務級以便能讓 uC/OS-III管理這些操作。 ISR中只允許呼叫一些提交函式(OSFlagPost(),OSQPost(),OSSemPost() , OSTaskQPost() , OSTaskSemPost()) ,除 了OSMutexPost()。因為mutex只允許在任務級被修改。
2.任務追蹤
uC/OS-III一直追蹤著任務的狀態如圖 5-7。事實上,這些都是以
一個變數的形式儲存在每個任務的 TCB中。圖小括號中的數值表示
著任務的狀態,每個任務都可以有 8 種狀態。(詳見 OS.H,
OS_TASK_STATE_???)
圖中不包括休眠態, 因為uC/OS-III不支援休眠態。 在這裡, 中斷
以及中斷的巢狀會有更深的講解。
(0).狀態 0表示任務已經就緒。每個任務在被執行之前都必須處於就緒狀態。
(1).任務可以通過呼叫 OSTimeDly()或者 OSTimeDlyHMSM()等待期滿。 當期滿或者延時刪除時 ( 通過呼叫OSTimeDlyResume()),任務會轉為就緒狀態。
(2).任務可以通過呼叫掛起函式 ( OSFlagPend(),OSMutexPend(),OSQPend, OSSemPend, OSTaskQPend(), OSTaskSemPend())等待某事件的發生。 當事件發生時、 該任務被刪除、 或者被另一個任務取消等待時,等待停止。
(3).如前面所說,任務可以等待事件發生。但任務也可以被設等待多少時間。 如果在這段時間內事件沒有發生, 任務也會被設為就緒狀態,並通知這個任務是等待超時而被掛起的。{掛起函式都有一個關於函式執行結果錯誤代號,可以檢視這個代號知道任務是因何被就緒的}
(4).任務暫停自己或者被其他任務暫停(通過呼叫OSTaskSuspend())。暫停中的任務只能通過呼叫OSTaskResume()被恢復。
(5).一個延時中的任務也可以被其它任務設定為停止。在這種情況下, 效果會被疊加。 換句話說, 延時需被執行、 停止狀態需被解除。該任務才會被執行。
(6).一個掛起狀態中的任務也可能被其它任務設定為停止。同樣的, 效果會被疊加。 事件發生且停止狀態被移除後, 任務才會被執行。
(7).任務可以等待事件的發生,但可以給它設定一個期限。同樣的, 它也可能被設為停止, 效果是疊加的。 除非移除停止狀態並事件發生或等待事件超時,任務才會被執行。