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的所在的位數,
Y = OSUnMapTbl[OSRdyTbl[X]];
最高優先級爲X*8+Y
----------------------------------
---------------------------------------------剛開始接觸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[]表格是如何生成的,反過來也可以發現,該表是爲了滿足嵌入式系統實時性的特性而使用的,這種通過查表降低運算量提高實時性的思想在做項目的時候可以進行借鑑