介紹下任務優先級小於64的情況。
1.首先看下任務優先級介紹的圖片,這個圖比較直觀,也是中文的,從網上拷貝的:
2.幾個變量說明下:
OS_PRIO:可以理解爲任務創建時分配的優先級,YYY表示任務優先級組,即OSRdyGrp,XXX表示組中的某一位。比如YYY爲1,XXX爲2,則可以對應到OSRdyTbl中的10。
OSRdyGrp:每一個bit代表一個組,一共8組,每組管理8個任務(具體哪一個記錄在OSRdyTbl中),即爲INT8U類型。
OSRdyTbl:每一個bit代表一個優先級,對應上圖中的優先級準備表,即爲INT8U OSRdyTbl[8]類型。可以理解爲8*8,0~63
INT8U const OSUnMapTbl[256] = {
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 */
}; 這個表對應了0~255中最低位1所在的位置,因爲數值越小優先級越高,因此創建了這個表,其中第一行
0u==0x00 ==00000000b 最低位爲1的位數爲 bit0==0u (其實爲空,空的情況默認爲0,不影響計算)
1u==0x01 ==00000001b 最低位爲1的位數爲 bit0==0u
2u==0x02 ==00000010b 最低位爲1的位數爲 bit1==1u
3u==0x03 ==00000011b 最低位爲1的位數爲 bit0==0u (有兩個爲1的位,bit0,bit1,取最小的,因爲OSRdyGrp或OSOSRdyTbl中最小的位數 對應的優先級越大)
4u==0x04 ==00000100b 最低位爲1的位數爲 bit2==2u
5u==0x05 ==00000101b 最低位爲1的位數爲 bit0==0u
6u==0x06 ==00000110b 最低位爲1的位數爲 bit1==1u
7u==0x07 ==00000111b 最低位爲1的位數爲 bit0==0u
8u==0x08 ==00001000b 最低位爲1的位數爲 bit3==3u
9u==0x09 ==00001001b 最低位爲1的位數爲 bit0==0u
Au==0x0A ==00001010b 最低位爲1的位數爲 bit1==1u
Bu==0x0B ==00001011b 最低位爲1的位數爲 bit0==0u
Cu==0x0C ==00001100b 最低位爲1的位數爲 bit2==2u
Du==0x0D ==00001101b 最低位爲1的位數爲 bit0==0u
Eu==0x0E ==00001110b 最低位爲1的位數爲 bit1==1u
Fu==0x0F ==00001111b 最低位爲1的位數爲 bit0==0u
3.計算公式
OSPrioHighRdy = 優先級組序號*8 + 該優先級組中序號,即上面說的YYY,XXX
4.跟着源代碼走一遍
(1)OS_TCBInit()任務塊初始化中,ptcb->OSTCBPrio = prio;將創建任務時的優先級賦值給任務塊。
(2)OSMutexPend()中 ptcb->OSTCBY = (INT8U)( ptcb->OSTCBPrio >> 3); 優先級組序號
ptcb->OSTCBX = (INT8U)( ptcb->OSTCBPrio & 0x07); 該組中優先級對應bit的位置
ptcb->OSTCBBitY = (INT8U)(1 << ptcb->OSTCBY);
ptcb->OSTCBBitX = (INT8U)(1 << ptcb->OSTCBX); 優先級對應位置1
(3)OSRdyGrp |= ptcb->OSTCBBitY; 對應的組序號置1
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; 對應該組中的相應優先級位置1
(4)y = OSUnMapTbl[OSRdyGrp]; 取出優先級最高的組序號
OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]); 計算優先級,這裏用到了OSUnMapTbl,當OSRdyGrp第1位爲1時,不管其他爲是多少,取到的值都是0,所以可以y = OSUnMapTbl[OSRdyGrp];這樣寫。
5.總結
這種問題個人感覺可以現在網上瀏覽下別人的理解,但是我總是不能完全看懂別人的說法,可能理解方式不同,因此看到差不多的時候可以看着代碼分析,這樣可以更快理解。