Nucleus PLUS任务调度
概述
Nucleus Plus內(nèi)核(Kernel)的主要目的是管理實時任務(wù)的競爭執(zhí)行(共享CPU),為應(yīng)用提供各種便利,高速響應(yīng)外部事件。Nucleus Plus的系統(tǒng)結(jié)構(gòu)如圖1所看到的,能夠看出線程控制是整個內(nèi)核的核心,通過郵箱、隊列、管道來實現(xiàn)任務(wù)之間的通信,通過信號量、事件組和信號實現(xiàn)任務(wù)間的同步。
線程控制部件用來管理實時任務(wù)和高級中斷服務(wù)的運(yùn)行,它是Nucleus 嵌入式實時操作系統(tǒng)最核心的部分。為了控制運(yùn)行過程,任務(wù)通常被分配一個優(yōu)先級。任務(wù)優(yōu)先級的范圍從0到255,優(yōu)先級0的優(yōu)先權(quán)最高。除非搶占標(biāo)示位被置為無效,否則低優(yōu)先級的任務(wù)將被高優(yōu)先級就緒的任務(wù)搶占。為保證對外部事件的實時性響應(yīng),Nucleus設(shè)計了高級中斷服務(wù)HISR,它的優(yōu)先級范圍從0到2,當(dāng)中優(yōu)先級0的級別最高。
任務(wù)調(diào)度線程就負(fù)責(zé)搶占式實時任務(wù)和HISR的調(diào)度管理。每一個用戶應(yīng)用由多個任務(wù)組成,一個任務(wù)就是具有特定目的的半獨(dú)立程序片段,任務(wù)處于五種狀態(tài)之中的一個--執(zhí)行、就緒、掛起、終止、完畢,如表1所看到的。任務(wù)具有不同的優(yōu)先級,高優(yōu)先級任務(wù)可以搶占低優(yōu)先級任務(wù),同優(yōu)先級任務(wù)依照進(jìn)入”就緒狀態(tài)“的順序調(diào)度,優(yōu)先級從0-255遞減。
表1 Nucleus任務(wù)的五種狀態(tài)
| | 狀態(tài)意義 |
| 執(zhí)行Executing | 任務(wù)當(dāng)前正在被CPU運(yùn)行。 |
| 就緒Ready | 任務(wù)就緒,可是還有一個任務(wù)當(dāng)前正在執(zhí)行。 |
| 掛起Suspended | 任務(wù)由于服務(wù)等待需求而體眠。當(dāng)需求滿足時,任務(wù)變?yōu)榫途w狀態(tài)。默認(rèn)情況下,新創(chuàng)建的任務(wù)都處于 |
| 終止Terminated | 任務(wù)被終止。當(dāng)任務(wù)處于這樣的狀態(tài)時,它將不再運(yùn)行直到它被復(fù)位。 |
| 完畢Finished | 任務(wù)完畢了.從入口函數(shù)中退出。任務(wù)處于這樣的狀態(tài)時,它將不再運(yùn)行直到受到復(fù)位。 |
(一)任務(wù)調(diào)度算法
Nucleus調(diào)度程序用來決定是否要進(jìn)行任務(wù)切換,假設(shè)須要切換的話,切換到哪個進(jìn)程等。Nucleus實時操作系統(tǒng)的任務(wù)調(diào)度算法很easy,它包含時間片輪轉(zhuǎn)算法和輪詢算法。
時間片輪轉(zhuǎn)算法是將同樣優(yōu)先級的任務(wù)都分配同樣的時間片,當(dāng)時間片用完后再轉(zhuǎn)到下一個任務(wù),輪流運(yùn)行直到這個優(yōu)先級的所有任務(wù)所有運(yùn)行完成,然后再轉(zhuǎn)到下一個優(yōu)先級。輪詢算法是在本優(yōu)先級內(nèi)的所有任務(wù)依照就緒時間的先后 順序運(yùn)行,當(dāng)這個優(yōu)先級的所有任務(wù)都運(yùn)行完成后,再運(yùn)行下一個優(yōu)先級的任務(wù)。
再者,Nucleus實時操作系統(tǒng)具有可搶占性,進(jìn)程調(diào)度的根據(jù)就是依照優(yōu)先級從高到低順序進(jìn)行調(diào)度。當(dāng)?shù)蛢?yōu)先級任務(wù)在運(yùn)行時,高優(yōu)先級任務(wù)就緒準(zhǔn)備運(yùn)行時則會搶占運(yùn)行,迫使低優(yōu)先級任務(wù)掛起。
Nucleus的調(diào)度時機(jī)包含:
(1)進(jìn)程狀態(tài)轉(zhuǎn)換的時刻,即進(jìn)程終止、進(jìn)程睡眠;
(2)可執(zhí)行隊列中新添加一個進(jìn)程時;
(3)當(dāng)前進(jìn)程的時間片用完;
(4)進(jìn)程從系統(tǒng)調(diào)用返回到用戶態(tài);
(5)內(nèi)核處理完中斷后,進(jìn)程返回到用戶態(tài)。
(二)Nucleus PLUS任務(wù)管理
1,主要任務(wù)控制結(jié)構(gòu)
Nucleus PLUS每個任務(wù)都有一個控制結(jié)構(gòu)體稱為線程控制塊Thread Control Block(TCB),任務(wù)支持動態(tài)的創(chuàng)建和刪除,TC通過一個雙向鏈表TCD_Created_Tasks_List管理全部的任務(wù),全局變量TCD_Total_Tasks表示已創(chuàng)建的總?cè)蝿?wù)數(shù)。
TCD_Priority_List是一個大小為256的TCB指針數(shù)組TC_TCB (*TCD_Priority_List)[256](數(shù)組大小與Nucleus PLUS優(yōu)先級數(shù)同樣),數(shù)組元素按任務(wù)優(yōu)先級索引。數(shù)組中的每一個元素都是某個優(yōu)先級就緒任務(wù)鏈表的頭。若某元素為空則表明那個優(yōu)先級沒有就緒任務(wù)。 對于每一個優(yōu)先級的就緒任務(wù)列表,TCB是以雙向列表的形式存儲。即Nucleus PLUS維護(hù)一個指針數(shù)組來調(diào)度不同優(yōu)先級的任務(wù)鏈表。
圖2 TCD_Priority_List
2,任務(wù)優(yōu)先級管理
Nucleus在進(jìn)行任務(wù)切換時須要計算最高優(yōu)先級,為了高速的計算就緒任務(wù)中最高的優(yōu)先級,Nucleus PLUS引入了一種優(yōu)先級分組+查找表機(jī)制。
2.1 TCD_Priority_Groups
任務(wù)的優(yōu)先級從0到255,0的優(yōu)先級別最高,255的優(yōu)先級別最低。256個優(yōu)先級分成32組,每組相應(yīng)8個級別。比如第0組相應(yīng)優(yōu)先級0~7、第1組相應(yīng) 8~15、...。用32位整型變量TCD_Priority_Groups的每一位標(biāo)示優(yōu)先級組是否有任務(wù)進(jìn)入就緒狀態(tài),某位為1表示改組至少有一個任務(wù)就緒。
圖3 TCD_Priority_Groups
2.2 TCD_Sub_Priority_Groups[]
子優(yōu)先級數(shù)組TCD_Sub_Priority_Groups[32]標(biāo)示一個組內(nèi)詳細(xì)的8個優(yōu)先級,數(shù)組元素為8位整型,每一位相應(yīng)組內(nèi)一個優(yōu)先級。如TCD_Sub_Priority_Groups[0]表示第0組(優(yōu)先級0-7)任務(wù)的就緒狀態(tài),第0位為1表明優(yōu)先級0的任務(wù)就緒、第7位為1表明優(yōu)先級7的任務(wù)就緒。
圖4 TCD_Sub_Priority_Groups
若任務(wù)的優(yōu)先級為Tc_priority, 該任務(wù)的子優(yōu)先級掩碼為:tc_sub_priority=1<<(tc_priority&7)。 該任務(wù)的優(yōu)先級組掩碼為:tc_priority_group=1<<((tc_priority)>>3)。
2.3 TCD_Lowest_Set_Bit[]
TCD_Lowest_Set_Bit[]是一個查找表(元素預(yù)先已計算出),該表是8位整型數(shù)據(jù)的序號和數(shù)據(jù)8個位中第一個為1的位的位置(從高往底數(shù))的,比如TCD_Lowest_Set_Bit[n]=value,n指8位整型數(shù)的值(就是序號),value指的是8個位中第一個為1的位置(從低往高數(shù))。如Unsigned Char 7的二進(jìn)制是0000 0111,第一個為1的位位0,value=0,TCD_Lowest_Set_Bit[7] = 0。
如此便能夠求得表TCD_Lowest_Set_Bit[256]。舉例,8位整型數(shù)中位0為1的數(shù)據(jù)包含1、3、5、7、9、11、13、15,...,253,255,所以有:
TCD_Lowest_Set_Bit[1]= 0, TCD_Lowest_Set_Bit[3]= 0, TCD_Lowest_Set_Bit[5]= 0, TCD_Lowest_Set_Bit[7]= 0, ..., TCD_Lowest_Set_Bit[253]= 0, TCD_Lowest_Set_Bit[255]= 0。 ?2.4 任務(wù)創(chuàng)建和優(yōu)先級管理的基本過程
任務(wù)優(yōu)先級管理全局變量
UNSIGNED TCD_Priority_Groups; DATA_ELEMENT TCD_Sub_Priority_Groups[TC_MAX_GROUPS]; UNSIGNED_CHAR TCD_Lowest_Set_Bit[256] = {0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0}; INT TCD_Highest_Priority;//就緒狀態(tài)任務(wù)的最高優(yōu)先級 i.創(chuàng)建一個task時(tcc.c)--TCC_Create_Task?funtion extern UNSIGNED TCD_Priority_Groups; extern DATA_ELEMENT TCD_Sub_Priority_Groups[TC_MAX_GROUPS]; extern UNSIGNED_CHAR TCD_Lowest_Set_Bit[]; extern INT TCD_Highest_Priority; task -> tc_priority = priority; task -> tc_priority_head = &(TCD_Priority_List[priority]); task -> tc_sub_priority = (DATA_ELEMENT) (1 << (priority & 7));//組內(nèi)子優(yōu)先級計算,0-7 priority = priority >> 3;//優(yōu)先級組計算,有32個組 task -> tc_priority_group = ((UNSIGNED) 1) << priority;//優(yōu)先級組響應(yīng)組標(biāo)示位置1 task -> tc_sub_priority_ptr = &(TCD_Sub_Priority_Groups[priority]);//指向子優(yōu)先級起始ii. 恢復(fù)執(zhí)行一個task時(tcc.c)--TCC_Resume_Task?fuction
iii.獲取當(dāng)前最高優(yōu)先級(tcc.c)
if (TCD_Priority_Groups & TC_HIGHEST_MASK) index = 0; else if (TCD_Priority_Groups & TC_NEXT_HIGHEST_MASK) index = 8; else if (TCD_Priority_Groups & TC_NEXT_LOWEST_MASK) index = 16; else index = 24; index = index + TCD_Lowest_Set_Bit[(INT)((TCD_Priority_Groups >> index) & TC_HIGHEST_MASK)];//獲取組號中1的最低排位,取值范圍0~31 temp = TCD_Sub_Priority_Groups[index];//與priority_group相應(yīng),有32個Sub_Priority_Groups,通過index查找到相應(yīng)的Sub_Priority_Groups TCD_Highest_Priority = (index << 3) + TCD_Lowest_Set_Bit[temp];//獲取到實際的最高優(yōu)先級 獲取到實際的最高優(yōu)先級后,將最高優(yōu)先級的任務(wù)掛入Tcd_priority_list[]、完畢調(diào)度后,該任務(wù)位會被清空,接著再次循環(huán)獲取下一個任務(wù)優(yōu)先級。轉(zhuǎn)載于:https://www.cnblogs.com/bhlsheji/p/3824916.html
總結(jié)
以上是生活随笔為你收集整理的Nucleus PLUS任务调度的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python----字符串方法
- 下一篇: Modbus和RS485是什么关系