UC/OS基礎知識之任務就緒表

UC/OS基礎知識之任務就緒表

1.任務就緒表
系統總是從處於就緒狀態的任務中選擇任務運行,爲此係統需要一個就緒任務登記表,它登記了系統中所有處於就緒狀態的任務,在UC/OS中這個就緒表就是一個位圖,系統中的每個任務都在這個位圖中佔據一個進制位,該位值得狀態(1或者0)表示該任務是否處於就緒狀態。
其示意圖如下圖所示:


OSRdyTbl[]數組的一個元素代表8個任務的就緒狀態,一個元素構成一個任務組,數組有8個元素就能表示64個任務了,爲了便於對就緒表進行查找,UC/OS有定義了一個數據類型爲INT8U的變量OSRdyGrp,並使該變量的每一位對應OSRdyTbl[]的一個元素,若OSRdyTbl[]某個元素不爲零,則在變量OSRdyGrp中把該位對應的位置1,。例如OSRdyGrp=11100101,那麼OSRdyTbl[0],OSRdyTbl[2],OSRdyTbl[5],OSRdyTbl[6],OSRdyTbl[7]任務組中有任務就緒。
示意圖如下圖

由於優先級別是一個單字節的數字,而且最大值不會超過63,即二進制形式的00111111,因此可以將優先級別看成是一個6位的二進制數,用高3位(D5D4D3)來指明OSRdyGrp的具體數據位,並且用來確定就緒表數組元素下標,用低3位(D2D1D0)來指明該元素具體的數據位。

2.對任務就緒表的操作
2.1.登記
當某個任務處於就緒狀態時,系統就將該任務登記在任務就緒表中,即在任務就緒表中將該任務的對應位置1。對優先級別爲prio的任務設置爲就緒狀態:

OSRdyGrp|= OSMapTbl[prio>>3];//確定它的行,置1   Prio的次高三位可以確定OSRdyGrp
OSRdyTbl[prio>>3]|=OSMapTbl[prio&0x07];//確定它的列,置1   低三位可以確定OSRdyTbl[]

OSMapTbl[]是爲加快運算速度定義的一個數組
其定義如下:

2.2.註銷
當某個任務脫離了就緒狀態時,系統就在就緒表中將該任務的對應位設置爲0。實現的代碼如下。

  if((OSRdyTbl[Prio>>3] &=~OSMapTbl[Prio&0x07]) = = 0)
OSRdyGrp  &= ~OSMapTbl[Prio>>3];

2.3找出進入就緒態的優先級最高的任務

y = OSUnMapTbl[OSRdyGrp];
x= OSUnMapTbl[OSRdyTbl[y]];
prio = y<<3 +x;

這裏 OSUnMapTbl[]同樣是uC/OS-II爲提高查找速度定義的一個數組,它共有256個元素,其定義如下:

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

在查找最高級就緒任務時,如果使用循環程序在就緒表中進行查找的方法會造成查找時間的不確定,所以Jean J.Labrosse 在設計的時候設置了這樣一個數組,在查找最高級就緒任務時,只要以變量OSRdyGrp爲下標,就可直接在數組OSUnMapTbl[]得到就緒任務的y值了;
由於在使用數組OSUnMapTbl[]時是以OSRdyGrp爲下標的因此這個數組一共有256個元素。也就是說,無論OSRdyGrp是多少,在數組OSUnMapTbl[]中總能找到對應的元素值,而且這個元素值就是最高級就緒任務優先級別的y。因爲數組OSUnMapTbl[]各個元素的值是基於這樣一個思想來設置的:表示任務組的變量OSRdyGrp是一個8位二進制數,從這個數的最低位向高位查找,碰到的第一個爲1的位所對應的就緒任務足一定是最高優先級別任務所在的組,所以它的組號一定是最高優先級別就緒任務的級別(6位數)的高3位。例如:OSRdyGrp中第一個爲1的位爲D3,那麼最高優先級別就緒任務級別的高3位一定爲011(十進制的3),於是在數組OSUnMapTbl[]的256個元素中,凡是其下標的D3位1,且D2,D1,D0都爲0的元素值均定義爲3。同樣,這個數組也用來查找最高級就緒任務的x值。當然,這時是以OSRdyTbl[y]爲下標來進行查找的。

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