就緒任務的管理

uc/OS-II在RAM中設立了一個記錄表,系統中的每一個任務在表中佔一個位置,並用這個位置的狀態(0和1)來表示任務是否處於就緒狀態。這個表叫作任務就緒狀態表。算法

就緒任務表其實是一個類型爲INT8U的數組OSRdyTbl[]。其中每一個字節的每一個位表示一個任務,這樣一個數組元素就能夠表示8個任務的就緒狀態。以任務優先級別高低爲順序,好比OSRdyTbl[0]的第1位表示任務優先級0,OSRdyTbl[1]的第8位表示任務優先級15.當其位爲1時任務處於就緒狀態,0則爲非就緒狀態。數組

咱們能夠把數組元素的8個任務當作是一個任務組,爲了便於就緒表的查找,uc/OS-II又定義了一個數據類型爲INT8U的變量OSRdyGrp,並使該變量的每個位對應OSRdyTbl[]的一個任務組(即數組的一個元素)。若是某任務組中有任務就緒,則在變量OSRdyGrp裏把該任務組對應的位置置1,不然置爲0。好比OSRdyGrp=0x00000011,則表示OSRdyTbl[0],OSRdyTbl[1]任務組中有任務就緒。spa

因爲變量OSRdyGrp爲8位,OSRdyTbl[]數組元素也有8位,因此算下來uc/OS-II就能夠管理8x8=64個任務。下面是一張任務就緒表:源碼


如何根據任務優先級別找到任務在就緒表中的位置。uc/os是這樣設定的,因爲優先級別是一個單字節的數字,並且其最大值不會超過63,即二進制形式的00111111,所以可把優先級別當作是一個6位的二進制數。這樣就能夠用高3位來指明變量OSRdyGrp的具體數據位,並用來肯定就緒表數組元素的下表,即上圖中的Y。用低3位來指明該數組元素的具體數據位,即上圖的X。因而根據任務的優先級別就能夠肯定該任務在就緒表中的確切位置了。另外,uc/OS-II在初始化時建立任務就緒表,並把其中全部數據位都置位0。it

就緒表的操做有兩項:一是把應就緒的任務在就緒表中進行登記,二是把任務從就緒表中刪除。io

1.在就緒表中登記就緒任務變量

使用下面兩行代碼就能夠把優先級別爲prio的任務置位就緒狀態。循環

OSRdyGrp |= OSMapTbl[prio>>3];數據類型

OSRdyTbl[prio>>3] |= OSMapTbl[prio&0x07];二進制

這就是根據上面的分析寫出的代碼。

其中OSMapTblp[]是uc/OS-II爲加快運算速度定義的一個數組,數組以下:

INT8U  const  OSMapTbl[]   = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};

2.從就緒表中刪除任務

優先級別爲prio,代碼以下

if((OSRdyTbl[prio>>3] &= ~OSMapTbl[prio&0x07]) == 0)

OSRdyGrp &= ~OSMapTbl[prio>>3];

其中若是OSRdyTbl[]數組元素每位爲0的話,則相應OSRdyGrp的其中二進制位也要清零。

3.從就緒表中獲取優先級別最高的就緒任務

其操做代碼以下:

y = OSUnMapTbl[OSRdyGrp];

x = OSUnMapTbl[OSRdyTbl[y]];

prio = (y<<3) + x;

還有一種代碼:

y = OSUnMapTbl[OSRdyGrp];

prio = (INT8U)((y<<3) + OSUnMapTbl[OSRdyTbl[y]]);

經過以上代碼就能夠找出最高優先級就緒任務的優先級別,其中OSUnMapTbl[]與OSMapTblp[]做用相似,是uc/OS-II爲加快運算速度定義的一個數組,一共有256個元素。其數組以下:

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

上面這個數組大有意思啊。剛開始我也好奇這是怎麼來的,看了書而後仔細想一想就想通了,不得不感嘆寫源碼的人的高明啊。

解釋以下,由上面的代碼看出,使用數組OSUnMapTbl[]時是以OSRdyGrp爲下標的,所以這個數組一共有256個元素。也就是說,不管OSRdyGrp值爲多少,在數組OSUnMapTbl[]總能找到對應的元素值,並且這個元素值就是最高就緒任務優先級別的y。由於數組OSUnMapTbl[]各元素的值是基於這樣一個思想來設置的:表示任務組的變量OSRdyGrp是一個8位二進制數,從這個數的最低位向高位查找,碰到的第一個爲1的位所對應的就緒任務組必定是最高優先級別就緒任務所在的組,因此它的組號必定是最高優先級別就緒任務的級別(6位數)的高3位。好比OSRdyGrp中第一個爲1的位是第3位,那麼最高優先級別就緒任務級別的高3位必定是011,因而在數組OSUnMapTbl[]的256個元素值中,凡是其下標值的第3位爲1的元素值均定義爲3.

因此有了這樣一個數組,在查找最高級就緒任務時,只要以變量OSRdyGrp爲下標,就可直接在在數組OSUnMapTbl[]獲得就緒任務的y值了;不然,就要編寫一個循環程序在就緒表中進行查找,這樣不但耗時,並且犯了實時系統的大忌——運算時間不可預測。

固然此數組也用來查找最高就緒任務的x值。固然是以OSRdyTbl[y]爲下表來查找的。這個跟超找y座標相似。好比OSRdyGrp爲0x28(00101000),最高優先組在OSRdyTbl[3],而OSRdyTbl[3]的元素爲01100000,則第一個爲1的位是咱們要找的最高優先級別的就緒任務。位5爲1,則說明了x座標爲5,即最高任務優先級別的低3位確定爲5。因而在數組OSUnMapTbl[]的256個元素中,凡是其下標爲5的位爲1的元素值均定義爲5.

uc/OS-II常常使用這種相似於就緒表形式的表來記錄任務的某種狀態。這算不算一種算法呢?

相關文章
相關標籤/搜索