1. 程式人生 > >uC/OS-II任務排程中判斷最高優先順序

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

一、任務優先順序的表示

   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就應該定義為63OS_RDY_TBL_SIZE就是。OSRdyTbl就是一個含8個元素的陣列。

       好了,OSRdyGrp的每一位表示一個組,如果該位為1,表示有任務用到了該組內的優先順序(由於優先順序不能相同,也表明有該任務,否則沒有)。OSRdyTbl[x]的每一位表示該組內的每一個優先順序,為1就有。例如OSRdyGrp[bit : 2] = 1;第三組記憶體在一個任務,也即是優先順序

16~238個優先順序存在一個及多個。如果此時OSRdyTbl[2][bit :4] = 1; 表示第三組的第5個優先順序存在,也就是數值為20的優先順序存在。

二、設定OSRdyGrpOSRdyTbl

        講了優先順序列表如何表示,那麼接下來就是建立一個任務時,如何將其對應的優先順序加入到列表中。這是OS_TCBInit函式的關於設定OSRdyGrpOSRdyTbl的程式碼。注:以下原始碼,就不摘錄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是傳人的引數,由於不會大於64prio6位值,因此OSTCBYprio3位,表示組,不會大於8OSTCBXprio3, 表示一個組的偏移量。OSRdyGrpOSRdyTbl是按位表示的,就得將數值轉化為位模式。接上面的例子prio = 20 = 0x10100OSTCBY是prio高3位,為1, 表明該優先順序落在第二組(從0開始), OSTCBBitY=0x10,也就是bit:11。同理,OSTCBX= 4OSTCBBitX bit :51OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; 就是設定OSRdyTbl[1]bit5.

三、任務排程中判斷最高優先順序

        uC/OS-II每次任務排程都是執行最高優先順序的任務。那麼如何在所有的任務中尋找最高優先順序了?前面已經介紹了,優先順序資訊存在OSRdyGrpOSRdyTbl中。低位代表高優先順序。先檢查組,由低位到高位檢查,檢查到後,再在該組中由低位到高位檢查,第一個為1的就是最高優先順序了。

       這個過程,說白了就是檢查一個char型的數,所有位是1的最小的那個位。uC/OS-II中用的查表法進行的。表如下:

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

    下面是OS_SchedNew()函式中獲取最高優先順序的程式碼:

       y  =  OSUnMapTbl[OSRdyGrp];
       OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]);
    y就是查表得到的最小的那一個組的,上面已經解釋過了,優先順序的高3位表示組,所以左移3位到高三位。加上查表得到的該組內的偏移量,就是最高優先順序的數值了。

四、結語

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

相關推薦

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

一、任務優先順序的表示    uC/OS-II中,規定最多可以有64個任務。每個任務的優先順序不能相同,因此,優先順序為0~63.數字越小,優先順序越高,那麼0就是最高優先順序,63就是最低優先順序。系統保留了優先順序最高及最低的各4個,因此使用者不能使用這8個優先順序作為自己的任務的優先順序。巨集OS_L

uC/OS-II任務排程之就緒表及最高優先順序任務判定演算法

uC/OS-II是Jean J. Labrosse設計的完整的、可移植、可固化、可裁剪的搶佔式實時多工核心,絕大部分程式碼都是用標準的C語言編寫的,開源、規模不大,比較適合初次接觸嵌入式作業系統的人員

uc/os-ii任務排程的鎖定與解鎖

排程器上鎖函式OSSchedlock()的功能是用於禁止任務排程,使任務保持對CPU的控制權。排程器開鎖函式OSSchedUnlock()的功能是解除對任務排程的禁止。 排程器上鎖和開鎖的實現原理是:對全域性變數鎖定巢狀計數器OSLockNesting進行操作

uc/os-ii任務排程(二)

任務排程關鍵是任務執行環境的切換。任務執行環境包括以下: 1. 程式的斷點地址(PC) 2. 程式狀態字暫存器(xPSR) 3. 通用暫存器內容 4. 任務堆疊指標(SP) 其中1、2、3儲存在任務堆疊中,4儲存在任務的任務控制塊中。 程式切換的關鍵

UC/OS-II 任務的狀態

uc/os是一個搶佔式多工的實時作業系統,每個任務都有各自的狀態,並且狀態之間都有一定的轉換關係。寫下此文以作記錄及幫助自己理清關係。 在uc/os-ii中,任務的狀態有5種:睡眠態、就緒態、執行態、等待態及中斷服務態。通過下圖可以有一個大致的認知: 最

uC/OS-II任務機制理解

        半年前接觸的uC/OS,看了兩個月之後又因為其他的事把他放下了。現在因為專案需要又把它重拾起來。         uC/OS----Micro Controller OS微控制器作業系

嵌入式實時作業系統uc-os-ii原理及應用 第三章 uc/os-ii任務

3.1-3.4.3  印象比較深的點在作業系統中程式叫做程序或執行緒。系統任務:空閒任務和統計任務。不同處理器,堆疊的增長方向不同。實時作業系統,時間操作必須為常量,所以不能用for,配合break或continue。不然每個任務執行時間不同。

uC/OS-II任務同步與通訊

在多工合作過程中的,作業系統應解決兩個問題:一是各任務之間應具有一種互斥關係,即對於某個共享資源的共享,如果一個任務正在使用,則其他任務只能等待,等到該任務釋放該資源以後,等待的任務之一才能使用它;二是相關的任務在執行上要有先後次序,一個任務要等其夥伴發來通知或建立了某個條件

uc/os-ii刪除任務

uC/OS-II中與刪除任務相關的函式有兩個,刪除任務函式OSTaskDel() 和請求刪除任務函式OSTaskDelReq() 。 刪除任務函式原始碼如下,主要工作: 判斷引數的有效性 把要刪除的任務從任務就緒表中刪除 使被刪除的任務不等待延時期滿 ,

uC/OS-II優先順序機制分析

在uC/OS-II中共有64個優先順序,0優先順序最高,63優先順序最低。每個優先順序只能對應到一個任務,也就是說在uC/OS-II不支援具有相同優先順序的任務,所以只能建立64個任務,而使用者只能建立56個任務,有一個優先順序最低的空閒任務,在沒有使用者任務執行的

Ucos-ii獲取最高優先順序的原理(任務和事件)

1.      任務優先順序表是按照由左至右,由上至下的順序增長的,且優先順序號越小優先順序越高。 2.      任務優先順序儲存在一個位元組型數組裡,陣列大小為8,其還有一個行表,即一個位元組單元,用於確定在陣列的哪行有任務。 3.      任務優先順序由一個位元組的低6個bit組成,其最低優先順序為

uC/OS-II訊息佇列及操作

使用訊息佇列可在任務之間傳遞多條訊息,訊息佇列由三部分組成:事件控制塊、訊息佇列和訊息。 事件控制元件塊成員OSEventPtr指向一個叫做佇列控制塊(OS_Q)的結構,該結構管理著一個數組MsgTb1[],該陣列中的元素都是指向訊息的指標。一. 訊息佇列的操作 1. 建立

uc/os-ii訊息佇列

使用訊息佇列可以在任務之間傳遞多條訊息。訊息佇列由三個部分組成:事件控制塊、訊息佇列和訊息。 訊息佇列的資料結構如下圖所示。從圖中可以看到,訊息佇列相當於一個共用一個任務等待列表的訊息郵箱陣列,事件控制塊成員OSEventPtr指向了一個叫做佇列控制塊(OS_

uC/OS-II 學習筆記之:訊息佇列

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

嵌入式實時作業系統uc/os-ii 原理及應用 讀書筆記

對任務就緒表的操作理解: 將優先級別為prio的任務置為就緒狀態,可使用如下程式碼 OSRdyGrp |= OSMapTbl[prio >>3];//將prio任務所在的組狀態置為1,表示該組有任務就緒。 OSRdyTbl[prio>>3] |= O

uC/OS-II核心架構解析---uC/OS-II通訊與同步

1. 訊息郵箱Mbox       Mbox用於多工間單一訊息的傳遞,uC/OS-II使用ECB管理Mbox的基本資訊,OSEventPtr指向建立Mbox時指定的記憶體空間。事件的建立由具體的事件管理程式實現。主要包含在C原始檔OS_MBOX.C中。 OS_EVENT

spring 任務排程出現懶載入 no session 問題

相信大家在web開發過程中一定遇到過一種情況,Class班級類一對多關聯一個Student學生類,所以為了效能考慮,配置一個lazy-init=true,然後在前臺頁面需要訪問懶載入資料時需要額外配置一個OpenSessionInViewFilter,但是可能並

UC/OS-II功能介紹、要點記錄

可見總用時位各過程的總和,我們可以想象得出這樣的做法是很浪費時間的,我們任何人都不會這麼去做,採用UC/OS-II多工管理思想則可以將此事務按照另一種方式完成,如圖Pic1.2中的多執行緒方式,由圖比較可以看出,整個事務在t5時刻完成,當菜炒好時飯也做好不久,這樣的方法使總用時減少了,分析原因,可以知道是我們

最詳細的uC/OS-II 移植到STM32

這個圖表達了什麼資訊呢,其實就是告訴移植者需要將那些檔案移植到你的工程當中,首先是uC/OS-ii的原始檔,就是OS_CORE.C、OS_FLAG.C.....ucos_ii.H這些檔案,其實是uC/OS-ii的Port檔案,包括4個,分別是OS_CPU_C.C,OS_CPU_A.ASM,OS_CPU.H,O

UC/OS II 訊息佇列

訊息郵箱只能儲存一條訊息,訊息佇列沒有這一侷限,可以容納多條資訊佇列,按照先進先出(FIFO)的原則傳送和接受訊息。 訊息佇列的實體不是作業系統提供的,而是由使用者任務提供的。作業系統提供的是對其進行管理的程式。 1:訊息佇列的資料結構 訊息佇列的資料結構主要包括訊息佇列、