ucos 任務優先級計算詳解

介紹下任務優先級小於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.總結

這種問題個人感覺可以現在網上瀏覽下別人的理解,但是我總是不能完全看懂別人的說法,可能理解方式不同,因此看到差不多的時候可以看着代碼分析,這樣可以更快理解。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章