uC OS II任務排程中判斷最高優先順序

2021-06-10 01:27:43 字數 3340 閱讀 1156

uc/os-ii中,規定最多可以有64

個任務。每個任務的優先順序不能相同,因此,優先順序為

0~63.

數字越小,優先順序越高,那麼

0就是最高優先順序,

63就是最低優先順序。系統保留了優先順序最高及最低的各

4個,因此使用者不能使用這

8個優先順序作為自己的任務的優先順序。巨集

os_lowest_prio

用於設定規定最低優先順序,如定義為

30,那麼比

30數字大的更低優先順序就不能用了。這裡有點拗口。也就是,所有的任務不能多於

31個。

系統將64

個優先順序分為

8組,每組

8個。osrdygrp 表示組, osrdytbl表示每一組。他們定義如下:

#if os_lowest_prio <= 63

os_ext int8u osrdygrp; /* ready list group */

os_ext int8u osrdytbl[os_rdy_tbl_size]; /* table of tasks which are ready to run */

#else

os_ext int16u osrdygrp; /* ready list group */

os_ext int16u osrdytbl[os_rdy_tbl_size]; /* table of tasks which are ready to run */

#endif

#if os_lowest_prio <= 63

....

#define os_rdy_tbl_size ( ( os_lowest_prio ) / 8 + 1 ) /* size of ready table */

#else

......

#define os_rdy_tbl_size ((os_lowest_prio) / 16 + 1) /* size of ready table */

#endif

這裡好像是做了擴充套件,不侷限於

8位,貌似最多的任務不只

64了。不管它,我們忽略另一種情況。因為不管多少任務,處理方式的是一樣的。我們考慮所有優先順序都有可能用到的情況,

os_lowest_prio

就應該定義為63,

os_rdy_tbl_size

就是。osrdytbl

就是乙個含

8個元素的陣列。

好了,osrdygrp

的每一位表示乙個組,如果該位為

1,表示有任務用到了該組內的優先順序(由於優先順序不能相同,也表明有該任務,否則沒有)。

osrdytbl[x]

的每一位表示該組內的每乙個優先順序,為

1就有。例如

osrdygrp[bit : 2] = 1

;第三組內存在乙個任務,也即是優先順序

16~23這8

個優先順序存在乙個及多個。如果此時

osrdytbl[2][bit :4] = 1; 

表示第三組的第

5個優先順序存在,也就是數值為

20的優先順序存在。

講了優先順序列表如何表示,那麼接下來就是建立乙個任務時,如何將其對應的優先順序加入到列表中。這是os_tcbinit

函式的關於設定

osrdygrp

及osrdytbl

的**。注:以下原始碼,就不摘錄

16位的情況。

ptcb->ostcby    =  (int8u)(prio >> 3);         /* pre-compute x, y, bitx and bity   */

ptcb->ostcbbity = (int8u)(1 << ptcb->ostcby);

ptcb->ostcbx = (int8u)(prio & 0x07);

ptcb->ostcbbitx = (int8u)(1 << ptcb->ostcbx);

.........

osrdygrp |= ptcb->ostcbbity; /* make task ready to run */

osrdytbl[ptcb->ostcby] |= ptcb->ostcbbitx;

優先順序prio是傳人的引數,由於不會大於

64,prio為6

位值,因此

ostcby

為prio高3

位,表示組,不會大於 8,

ostcbx

為prio低3

位, 表示乙個組的偏移量。osrdygrp

和osrdytbl

是按位表示的,就得將數值轉化為位模式。接上面的例子

prio = 20 = 0x10100

,ostcby是prio

的高3位,為

1, 表明該優先順序落在第二組(從

0開始), ostcbbity=0x10

,也就是

bit:1為1

。同理,ostcbx= 4

,ostcbbitx 

的bit :5為1

。osrdytbl[ptcb->ostcby] |= ptcb->ostcbbitx; 

就是設定

osrdytbl[1]

的bit5.

uc/os-ii每次任務排程都是執行最高優先順序的任務。那麼如何在所有的任務中尋找最高優先順序了?前面已經介紹了,優先順序資訊存在osrdygrp

,osrdytbl

中。低位代表高優先順序。先檢查組,由低位到高位檢查,檢查到後,再在該組中由低位到高位檢查,第乙個為

1的就是最高優先順序了。

這個過程,說白了就是檢查乙個char

型的數,所有位是

1的最小的那個位。

uc/os-ii中用的查表法進行的。表如下:

int8u const osunmaptbl[256] = ;

下面是os_schednew

()函式中獲取最高優先順序的**:

y  =  osunmaptbl[osrdygrp];

ospriohighrdy = (int8u)((y << 3) + osunmaptbl[osrdytbl[y]]);

y

就是查表得到的最小的那乙個組的,上面已經解釋過了,優先順序的高

3位表示組,所以左移

3位到高三位。加上查表得到的該組內的偏移量,就是最高優先順序的數值了。

該方法還是挺巧妙的。讓每次查詢進行幾條語句就可以實現了。這個方法可以借鑑到其他地方。

uCOS II任務排程過程

uc os ii的任務一般格式為 void taskn void pdata ucos ii是基於任務優先順序搶占式任務排程法的,就是核心在管理排程時,呼叫任務切換函式 一般為ssched 在該函式中將此時已處於就緒狀態 條件一 並且為最高優先順序 條件二 的任務的儲存於其棧中的相應資訊壓入cpu暫...

uCOS II的任務排程和時鐘

在ucos ii中,任務切換只是簡單的將處理器暫存器儲存到將被掛起的任務的堆疊中,並且將更高優先順序的任務從堆疊中恢復出來,或者叫copy複製出來,處於就緒狀態的任務的堆疊結構看起來就像剛發生過中斷並將所有的暫存器儲存到堆疊中的情形一樣。換句話說,ucos ii要執行處於就緒狀態的任務必須要做的事情...

我看ucosii的任務排程

以前只是知道每個task的格式是 void mystask void pd while 1 void mytask void pd 實際上,ostimedly nticks 裡就包含了一次任務排程,否則任務是不會自己進行排程的。而排程的程式os sched 中就只是查詢出優先順序最高的已經就緒的任務...