解讀uCos中優先級判定表OSUnMapTbl原理

OSOSRdyTbl[0]的bit7-bit0對應於優先級7-0,
OSOSRdyTbl[1]的bit7-bit0對應於優先級15-8,
OSOSRdyTbl[2]的bit7-bit0對應於優先級23-16,
OSOSRdyTbl[3]的bit7-bit0對應於優先級31-24,
OSOSRdyTbl[4]的bit7-bit0對應於優先級39-32,
OSOSRdyTbl[5]的bit7-bit0對應於優先級47-40,
OSOSRdyTbl[6]的bit7-bit0對應於優先級55-48,
OSOSRdyTbl[7]的bit7-bit0對應於優先級63-56
OSRdyGrp確定了優先級的次低三位(bit5-bit3),OSOSRdyTbl確定了優先級的低三位(bit2-bit0),

OSRdyGrp = 0x011;  //0b00010001
OSRdyTbl[0] = 0x0a; //0b00001010
OSRdyTbl[4] = 0x01; //0b00000001
計算出存在的幾個優先級爲;0*8+1=1,0*8+3=3,4*8+0=32
假設OSRdyGrp最低位爲1的是X位,OSRdyTbl[X]最低爲1的是Y位,
則優先級=X*8+Y
因此只要知道了上述的X,Y就可算出最高優先級
OSUnMapTbl就是將0x00-0xff每個數據中最低位爲1的位數一一列舉出來
INT8U  const  OSUnMapTbl[256] = {
    0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x00 to 0x0F                             */
    //OSUnMapTbl[0]    
    //OSUnMapTbl[1]    1        bit0       
    //OSUnMapTbl[2]    2        bit1 
    //OSUnMapTbl[3]    3        bit0 
    //................

    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                             */

};

其中第一行
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

其他行類推,能得出上表,其實通過上面的推導,可以看出,上表中主要是求0~255(0x00~0xFF)之間數的最低位爲1的所在的位數,


X = OSUnMapTbl[OSRdyGrp];
Y = OSUnMapTbl[OSRdyTbl[X]];

最高優先級爲X*8+Y


----------------------------------

      咋一看這個數組還真有點怪異。數組如下:

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                             */
};

        INT8U是爲防止不同編譯器相同數據類型的長度不一導致代碼可移植差而在在os_cpu.h中聲明的一個數據類型,跟unsigned char相同,表示無符號的8位數。

       這個有256個元素的數組是通過任務就緒表找到就緒任務中優先級最高的任務所用到的數組。代碼如下:

y=OSUnMapTal[OSRdyGrp];//獲得優先級別的D5、D4、D3位

x=OSUnMapTal[OSRdyTbl[y]]; //獲得優先級別的D2、D1 、D0位

prio=(y<<3)+x;

        prio是表示優先級的一個無符號八位數,不過只有低六位有效。prio與就緒任務表的兩個數組的關係是這樣的:prio高三位表示組數,即OSRdyGrp[]中的哪一位是一。低三位表示這一組中的位數,即OSRdyTbl[]中的哪一位是一。例如,如果prio是00011001,即優先級是25。則OSRdyGrp[]中的第三位是被置一的,OSRdyTbl[]中的第一位是被置一的。

        由於有可能有很多任務是處於就緒狀態的,也就是說OSRdyGrp[]和OSRdyTbl[]中均有可能不止一位是被置一的。由於優先級的數字越小,級數越高,所以要從這些就緒的任務中找出優先級最高的任務,就需要找出這兩個數組中被置爲一的最低位。

        於是這個數組就這樣產生了:當OSRdyGrp[]中被置爲一的最低位是第三位(0~7位)時,表示優先級最高位是處於第三組(0~7),也就是說prio的有效位的高三位應該是011。於是OSUnMapTbl[]數組中所有對應於x x x x1000的元素的值都是011(3)。其它元素值同理可得。

         低三位同理。由就緒任務表通過這個數組就找到了所有就緒任務中優先級最高的任務的優先級了。

        當然由任務表找出處於就緒狀態的擁有最高優先級的任務的優先級也可以編寫一個循環程序在就緒表中查找。但是這樣比較耗時,並且犯了實時系統的大忌——運算時間不可預測。所以採用了這樣一個查表的方法。也算是用空間換取時間吧。

爲了您的安全,請只打開來源可靠的網址

打開網站    取消

來自: http://hi.baidu.com/xqgoth/blog/item/015ee4a9fbc8fcfa1f17a275.html
---------------------------------------------

uCOS-II中就緒表到最高優先級的查表表格解讀

剛開始接觸uCOS-II的時候,對於OSUnMapTbl[]中的數據比較模糊,害得自己折騰了一段時間才弄明白,爲了方便像我這樣的新手學習,現將當時的筆記整理出來,以下是整理出來的學習筆記。

 

    接觸過uCOS-II的都應該知道,任務調度中的就緒表由兩部分組成:OSRdyGrp和OSRdyTbl[]。在需要進行任務切換時,通過:

                   y = OSUnMapTbl[OSRdyGrp];-----------(1)

                   x = OSUnMapTbl[OSRdyTbl[y]];--------(2)

                   prio = (y << 3) + x;----------------(3)

    即可以查到當前就緒態的任務中的最高優先級任務。

 

在此,便有一個疑問:爲什麼通過查找OSUnMapTbl[]中的數據,便能間接得到當前就緒態的任務中的最高優先級呢?

首先,來看看OSRdyGrp和OSRdyTbl[]。

 

    接着,再看看OSUnMapTbl[]的數據內容:

 

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     */

};

 

    我們知道,OSRdyGrp和OSRdyTbl[]均爲INT8U的類型,每個數據均爲8bit,每一個bit均可獨立設置,故存在各個位均已設置的情況,從而需要考慮的最多情況爲2^8=256種,如上表所示。

    對於OSRdyGrp而言,其查表方式爲:OSUnMapTbl[OSRdyGrp];易知:OSRdyGrp爲奇數時(即bit0 = 1時),對應的有效的bit mask爲bit 0(如OSRdyGrp=0x03、0x07,此時優先級最高的bit mask爲bit 0),所以OSUnMapTbl[]表中的所有奇數下標位置對應的值全爲0(如OSUnMapTbl[1]=OSUnMapTbl[3]=OSUnMapTbl[5]=0)。同理,OSRdyGrp最低有效位爲bit 1時(OSRdyGrp=0x020、0x06,此時優先級最高的bit mask爲bit 1),對應的有效的bit mask爲bit 1,故該表中的所有0b00000010 + 0b00000100*n(n=0,1,2...)的位置的下標位置的值全爲1(如OSUnMapTbl[2]=OSUnMapTbl[6]=OSUnMapTbl[10]=1)。

    對於OSRdyTbl[]而言,其查表方式爲:OSUnMapTbl[OSRdyTbl[y]] ,其中y =OSUnMapTbl[OSRdyGrp];該表達式的意義爲:根據查得的最高優先級對應的Group,找出該Group中的就緒態的最高優先級號,其思路跟上面完全一致。

    綜上,可得:

    y = 0x01<<a+(0x01<<(a+1))*n=(0x01<<a)*(1+2n)

    a表示Group中的最低有效位(最低的非0的位)的位置,同時表示在該表中的數據,範圍0-7;(n=0,1,2...),y表示表中的位置,該位置對應的值爲a。

    即:對於OSUnMapTbl[]中的任意位置y,其值爲a,對應公式爲上面的表達式。

   

    由此,我們可以清楚的看出OSUnMapTbl[]表格是如何生成的,反過來也可以發現,該表是爲了滿足嵌入式系統實時性的特性而使用的,這種通過查表降低運算量提高實時性的思想在做項目的時候可以進行借鑑



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