任務管理的數據結構包括任務控制塊、任務空閑鏈表和任務就緒鏈表、任務優先級指針表、任務堆棧等,是uC/OS-II內核的核心部分之一。離開了這些數據結構,內核什么功能也完成不了。這些數據的內容完全反映了任務的運行情況。
任務控制塊是任務管理的核心數據結構,操作系統在啟動的時候,首先要在內存中創建一定數量的任務控制塊。任務控制塊的數量等于操作系統能同時管理的最多任務數。
uC/OS將任務控制塊劃分為兩個鏈表:就緒鏈表和空閑鏈表。創建一個任務,就從空閑鏈表中取出一個空閑的任務控制塊,將任務的各種屬性添入該控制塊,并將該任務控制塊移到就緒鏈表,更改就緒表和就緒組,任務就從睡眠態轉換到就緒態,當沒有更高優先級的任務在運行時,任務就可以得到運行。相反,要結束一個任務的運行,就要將該任務的任務控制塊從就緒鏈表移到空閑鏈表,然后修改就緒表和就緒組,取消任務的就緒標志,就緒就從就緒態轉換到其他狀態,而只有再回到就緒態才有可能得到運行。
任務控制塊的基本結構體在ucos_ii.h文件中定義:
51.png (33.04 KB, 下載次數: 80)
下載附件
2013-7-14 04:00 上傳
52.png (13.83 KB, 下載次數: 76)
下載附件
2013-7-14 04:00 上傳
對任務控制塊結構OS_TCB說明如下:
(1)*OSTCBStkPtr是指向OS_STK數據類型的指針。OS_STK在OS_CPU.h文件中定義:
54.png (53.21 KB, 下載次數: 68)
下載附件
2013-7-14 04:00 上傳
因此,OS_STK就是無符號整形。OS_STK是任務堆棧的每個數據項的類型,對于不同的硬件系統是不同的,在做移植的時候就需要進行修改。OS_CPU.h中定義了和CPU有關的數據結構和全局變量。
任務堆棧的操作是最底層的,要用匯編語言來寫代碼,因此指針在整個結構體的第一句開始定義。那么在定義結構體的實體后,控制塊的0地址就存儲了任務堆棧的棧頂地址,方便了匯編語言操作。
換句話說,OSTCBStkPtr是只想任務堆棧棧頂的指針。每個任務都有自己的任務堆棧,任務堆棧是進行任務切換的關鍵數據結構,任務運行的CPU環境,包括任務的代碼的地址都保存在任務堆棧中。
(2)結構體OS_TCB中,使用了條件編譯語句(#if和#endif)。條件編譯的含義是只有在OS_TASK_CREATE_EXT_EN>0的情況下,#if和#endif之間的代碼才會被編譯,任務控制塊才會包含這些字段。OS_TASK_CREATE_EXT_EN是在頭文件中定義的宏,當它為1時,表示使用任務創建擴展功能,該段代碼就會被編譯,OS_TCB中就包含了#if和#endif之間的5種結構體字段。相反,如果OS_TASK_CREATE_EXT_EN=0,那么該5種字段不會被包含。這樣的設計能最小化程序的代碼和使用最小的內存空間。
在操作系統的設計過程中,空間和效率是至關重要的,條件編譯語句使用的非常多。
(3)接下來又是一個條件編譯,含義為如果使用消息隊列或消息郵箱或信號量(包括普通信號量和互斥信號量),那么任務要用到事件控制塊,OSTCBEventPtr即指向事件控制塊的指針。否則不定義該字段。在默認情況下,是要用到事件控制塊的。從這個條件編譯指令可以知道,消息、隊列、信號量等都要用到事件控制塊。
(4)任務狀態OSTCBStat。任務狀態的取值范圍和對應的宏如表
(5)任務優先級OSTCBPrio。每個任務有唯一的優先級,因此uC/OS-II以優先級作為事件的標志,作為任務管理的主鍵。任務的優先級可以是0~63,但優先級62和63被統計任務和空閑任務占用,用戶任務的優先級可以選擇0~61,數字越低,優先級越高。
(
6)
53.png (1.42 KB, 下載次數: 68)
下載附件
2013-7-14 04:00 上傳
該處4項都與設置就緒表有關,而就緒表中的內容對應著任務的優先級,因此,這4項都是關于優先級的運算。其目的在于提前進行運算,即在任務創建時運行一次,而在任務調度的時候不需要反復進行運算,以節省時間,含義如表所示: