天天看點

uC/OS-II源碼分析(五)

每個任務被賦予不同的優先級等級,從0 級到最低優先級OS_LOWEST_PR1O,包括0 和

OS_LOWEST_PR1O 在内。當μC/OS-Ⅱ初始化的時候,最低優先級OS_LOWEST_PR1O 總是被賦給空閑任務idle task 。注意,最多任務數目OS_MAX_TASKS 和最低優先級數是沒有關系的。使用者應用程式可以隻有10 個任務,而仍然可以有32 個優先級的級别(如果使用者将最低優先級數設為31 的話)。

每個任務的就緒态标志都放入就緒表中的,就緒表中有兩個變量OSRedyGrp 和OSRdyTbl[]。在OSRdyGrp 中,任務按優先級分組,8 個任務為一組。OSRdyGrp 中的每一位表示8 組任務中每一組中是否有進入就緒态的任務。任務進入就緒态時,就緒表OSRdyTbl[] 中的相應元素的相應位也置位。就緒表OSRdyTbl[] 數組的大小取決于OS_LOWEST_PR1O。當使用者的應用程式中任務數目比較少時,減少OS_LOWEST_PR1O 的值可以降低μC/OS-Ⅱ對RAM(資料空間)的需求量。

為确定下次該哪個優先級的任務運作了,核心排程器總是将OS_LOWEST_PR1O 在就緒表中相應位元組的相應位置1。OSRdyGrp 和OSRdyTbl[] 之間的關系見圖3.3,是按以下規則給出的:

當OSRdyTbl[0] 中的任何一位是1 時,OSRdyGrp 的第0 位置1,

當OSRdyTbl[1] 中的任何一位是1 時,OSRdyGrp 的第1 位置1,

當OSRdyTbl[2] 中的任何一位是1 時,OSRdyGrp 的第2 位置1,

當OSRdyTbl[3] 中的任何一位是1 時,OSRdyGrp 的第3 位置1,

當OSRdyTbl[4] 中的任何一位是1 時,OSRdyGrp 的第4 位置1,

當OSRdyTbl[5] 中的任何一位是1 時,OSRdyGrp 的第5 位置1,

當OSRdyTbl[6] 中的任何一位是1 時,OSRdyGrp 的第6 位置1,

當OSRdyTbl[7] 中的任何一位是1 時,OSRdyGrp 的第7 位置1,

用于将任務放入就緒表,Prio 是任務的優先級。

OSRdyGrp |= OSMapTbl[prio >> 3]; 

OSRdyTbl[prio >> 3] |= OSMapTbl[prio & 0x07];

OSMapTbl[] 的值:

任務優先級的低三位用于确定任務在總就緒表OSRdyTbl[] 中的所在位。接下去的三位用于确定是在OSRdyTbl[] 數組的第幾個元素。OSMapTbl[] 是在ROM 中的屏蔽字,用于限制OSRdyTbl[] 數組的元素下标在0 到7 之間,如果一個任務被删除了,則用 下面代碼做求反處理。

if ((OSRdyTbl[prio >> 3] &= ~OSMapTbl[prio & 0x07]) == 0) 

OSRdyGrp &= ~OSMapTbl[prio >> 3]; 

以上代碼将就緒任務表數組OSRdyTbl[] 中相應元素的相應位清零,而對于OSRdyGrp, 隻有當被删除任務所在任務組中全組任務一個都沒有進入就緒态時,才将相應位清零。也就是說OSRdyTbl[prio>>3] 所有的位都是零時,OSRdyGrp 的相應位才清零。為了找到那個進入就緒态的優先級最高的任務,并不需要從OSRdyTbl[0] 開始掃描整個就緒任務表,隻需要查另外一張表,即優先級判定表OSUnMapTbl([256]) 。

OSRdyTbl[] 中每個位元組的8 位代表這一組的8 個任務哪些進入就緒态了,低位的優先級高于高位。利用這個位元組為下标來查OSUnMapTbl 這張表,傳回的位元組就是該組任務中就緒态任務中優先級最高的那個任務所在的位置。這個傳回值在0 到7 之間。确定進入就緒态的優先級最高的任務是用以下代碼完成的,

y = OSUnMapTbl[OSRdyGrp]; 

x = OSUnMapTbl[OSRdyTbl[y]]; 

prio = (y << 3) + x;

例如,如果OSRdyGrp 的值為二進制01101000,查OSUnMapTbl[OSRdyGrp] 得到的值是3, 它相應于OSRdyGrp 中的第3 位bit3,這裡假設最右邊的一位是第0 位bit0 。類似地,如果OSRdyTbl[3]的值是二進制11100100, 則OSUnMapTbl[OSRdyTbc[3]]的值是2,即第2 位。于是任務的優先級Prio 就等于26(3*8+2)。利用這個優先級的值。查任務控制塊優先級表OSTCBPrioTbl[],得到指向相應任務的任務控制塊OS_TCB 的工作就完成了。

INT8U  const  OSMapTbl[]   = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};

INT8U  const  OSUnMapTbl[] = {

    0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x00 to 0x0F                             

    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x10 to 0x1F                             

    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x20 to 0x2F                             

    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x30 to 0x3F                             

    6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x40 to 0x4F                           

    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x50 to 0x5F                             

    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x60 to 0x6F                             

    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x70 to 0x7F                             

    7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x80 to 0x8F                             

    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x90 to 0x9F                             

    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xA0 to 0xAF                             

    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xB0 to 0xBF                             

    6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xC0 to 0xCF                             

    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xD0 to 0xDF                             

    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xE0 to 0xEF                             

    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0        /* 0xF0 to 0xFF                             

}; 

作者:

洞庭散人

出處:

http://phinecos.cnblogs.com/

    

本部落格遵從

Creative Commons Attribution 3.0 License

,若用于非商業目的,您可以自由轉載,但請保留原作者資訊和文章連結URL。

繼續閱讀