1. 程式人生 > >uCOS-II中任務優先級的判定和處理方法

uCOS-II中任務優先級的判定和處理方法

www 一行 con blog 方法 cloud 問題 找到 引入

轉載請註明原文出處,http://www.cnblogs.com/flyingcloude/p/6992346.html

在uCOS-II中,最多有64個優先級,把這64個優先級每8個分成一組,總共可以分成8組。對應的數組名稱是OSRdyTbl[x] (0≦x≦7)。為了更快捷的判斷出進入就緒態的
任務,又引入了變量OSRdyGrp。OSRdyGrp來標識哪組任務中有進入就緒態的任務。例如:
優先級為12的任務進入就緒態,那麽OSRdyTbl[1]的第四位置1,OSRdyGrp的第一位置1。通過下面的圖表能更明確的看出來。
通過這個表格,我們也能看出,對於OSRdyTbl[x] (0≦x≦7),如果OSRdyTbl[x]的某一位置1,那麽OSRdyGrp對應的第x位也置1。

假設優先級為12的任務進入就緒態,其對應的十六進制數為0x1100,那麽相應的表達式為:
OSRdyGrp |= 0x02;
OSRdyTbl[1] |= 0x10;
而0x02是2的1次方,0x10是2的4次方;而1和4又恰好為0x1100的次第三位和第三位。其實OSRdyTbl[x]中存放的是優先級的低三位;OSRdyGrp存放的是優先級的高三位。
為了加快計算速度,uCOS-II中增加了一下數組,這樣CPU就沒必要再去計算諸如乘方等運算了,這是一種用空間換速度的做法。這個數足就是
OSMapTbl[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
同樣當優先級為12時:
OSRdyGrp |= OSMapTbl [prio >>3];
OSRdyTbl[1] |= OSMapTbl [prio & 0x07];
其實,所有進入就緒態的任務都可以通過上述方法進入就緒表。
感興趣的話你可以測試其他的優先級情況。
那麽,uCOS-II是如何找到優先級最高的任務的呢(優先級的數值最小)。
假設OSRdyGrp = 0x11;OSRdyTbl[0] = 0x11;OSRdyTbl[4] = 0x22;則進入就緒態的任務的優先級分別為:0*8+0 = 0; 0*8+3 = 3; 4*8+1 = 33; 4*8+5 = 37。
通過上面的情況可以看出,優先級最高的任務肯定是在OSRdyGrp中為1的最低位對應的那一組OSRdyTbl[]中,而OSRdyTbl[]裏面的為1的最低位對應的任務也就是就緒表中
優先級最高的任務。所以,如果想找出優先級最高的任務,其實就是找出OSRdyGrp中為1的最低位x以及OSRdyTbl[x]中為1的最低位y。然後優先級就是prio = x*8+y;現在的問題就
變成確定x和y了。
跟上面提到的相同,在uCOS-II中有定義了一個數組,
INT8U const OSUnMapTbl[] = {

0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,

4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
};
y = OSUnMapTbl[OSRdyGrp];
x = OSUnMapTbl[OSRdyTbl[y]];
到此為止,處於就緒態的優先級最高的任務就確定了。
數組OSUnMapTbl[]為優先級判定表,書上和網上對優先級判定表沒做詳細的說明,經過和王老師一番探討,對優先級判定表的制作原理作如下解析:
首先,我們要明確一點,我們是要查找優先級最高的任務。
其次,假設OSRdyGrp = 0x11,OSRdyGrp十進制表示為17,二進制表示為00010001,OSRdyGrp的二進制第一位和第五位為1說明第一行和第五行有就緒任務,優先級高的當然是第一行的,所以y=OSUnMapTbl[OSRdyGrp]=0, 也就是說OSUnMapTbl[]的第十八個元素為0。假設OSRdyTbl[0]=0x11,同樣的OSRdyTbl[0]十進制表示為17,二進制表 示為00010001,OSRdyGrp的二進制第一位和第五位為1說明第一列和第五列有就緒任務,所以優先級高的當然是第一列的。
最後,不難發現不管是找行優先級高的還是列優先級高的,它們的本質一樣的,就是行數低的優先級高,列數低的優先級高,按照這樣的原則以OSRdyGrp或 就緒表元素值為下標,以優先級高任務的行數或列數所對應的優先級(行數減一或列數減一)為值創建出來的就是優先級判定表了!

轉載請註明原文出處,http://www.cnblogs.com/flyingcloude/p/6992346.html

uCOS-II中任務優先級的判定和處理方法