再議基于μC/OS-II的時間片調度法設計
引言
筆者曾在本刊2008年12期上發表過一篇文章——《基于μC/OS-11的時間片調度法設計》,近期在網絡上看到有很多感興趣的技術同行作了大量引用和轉載。根據在實際項目中的應用經驗,有必要對其再議,主要原因如下:
①多任務的時間片調度在嵌入式領域有實用價值。一方面是很多嵌入式軟件系統升級有這種需求,舊的軟件模塊基于Endless Loop實現,升級到μC/OS-II后,若要最大限度地復用舊的軟件模塊,時間片調度算法是實現舊的設計模式到新架構之間最簡單的橋梁。另一方面,對于控制領域,存在大量的耗時任務無法自動釋放控制權,時間片調度降低了任務設計的復雜度。剛剛發布不久的μC/OS-II,推出的重大改進之一就是增加了對Round Robin的支持,更是表明μC/OS-II的使用者們對該功能的實際需求是切實存在的。
②不更改μC/OS-II內核代碼實現時間片調度?!痘?mu;C/OS-II的時間片調度法設計》對OS內核代碼作了修改,雖然很少但增加了系統耦合度,對日后的項目維護和第三方升級都是不利的。如果存在完全不用更改內核而僅基于OS服務的正常調用的實現方案,對系統的可靠性和移植性都是有益的。
③相對μC/OS-III,μC/OS-II仍然有廣泛的應用領域。μC/OS-III作出了重大的改進,增加了時間片調度,擴展了任務數的限制,允許了同等優先級任務的存在,更多新特性的引入帶來了內核結構的重整以及運行時開銷的增加。雖然可以通過配置優化系統,但就大部分的應用而言,μC/OS-II完全能夠勝任,至少不需要僅僅為了時間片調度功能而選用μC/OS-III。
1 調度原理
該調度算法對系統的要求有兩點:首先要建立一個額外的調度任務用于管理待調度的用戶任務時間片計時及其切換,我們將其命名為TaskRB_Scheduler;其次是保證其任務優先級高于所有的待調度時間片任務,保證調度任務能搶占所有被調度任務的控制權。
我們假設系統中有3個任務需要分享時間片,分別為TaskRB_1、TaskRB_2、TaskRB_3。為了實現時間片的調度功能,還需要額外的調度任務TaskRB Scheduler,于是系統中的將會有4個任務。其中,TaskRB Scheduler由初始化代碼創建,而待調度的3個用戶任務的創建和管理完全由TaskRB Scheduler任務來完成。
TaskRB_Scheduler的運行分為兩個階段:首先是初始化階段,負責所有時間片任務的創立并確保其處于Suspend狀態;然后是調度運行階段,如圖1所示。
下面對照圖1對調度運行階段的各個步驟進行描述。
①TaskRB_Scheduler通過調用OSTaskResume使TaskRB_1處于Ready狀態(其他任務處于Suspend態)。
②TaskRB_Scheduler調用OSTimeDly釋放控制權進入延時等待狀態,延時參數即為TaskRB_1任務運行的時間片長度,此時唯一處于Ready態的用戶任務TaskRB_1獲得控制權進入Running狀態。
③OSTimeDly超時發生,TaskRB_Schedulcr處于Rcady態并且由于任務優先級高于TaskRB_1搶占其控制權,于是TaskRB_Scheduler進入運行狀態,TaskRB_1返回Ready態。
④TaskRB_Scheduler調用OSTaskSuspend讓處于Ready態的TaskRB_1進入Suspend狀態,避免其競爭下一個時間片。
⑤~⑧重復①~④步驟,對TaskRB_2分配運行時間片。
⑨~重復①~④步驟,對TaskRB_3分配運行時間片。
簡而言之,調度任務因為具有最高優先級,可以根據時間片分配表啟動并打斷待調度的時間片任務,雖然時間片任務優先級各不相同,但通過確保僅有一個時間片任務處于Readsr態的方法,避免了不同時間片任務之間的競爭
沖突。
為簡化示意圖,并沒有標注中斷ISR行為的影響,事實上ISR只能影響到任務時間片的長度而不會影響到任務片調度的流程;而對于時間片調度系統而言,通常都采用類似于前后臺系統的信號同步策略處理中斷數據,這已經不是本文討論的重點。
2 實現代碼
原理比較簡單,僅僅給出 TaskRB_Scheduler部分代碼:
3 應用擴展
有項目經驗的人都深知Demo和產品有著天壤之別,這句話同樣適用于此時間片調度方案。在實際應用中,我們還須關注到以下幾個方面。
(1)如何與非時間片調度任務協同工作
對于混合系統而言,作為時間片調度的任務通常都對實時性要求比較低,因此通常的做法是設置優先級:實時任務優先級>TaskRB_Sche duler>時間片任務>IDLE,時間片精度會會因為實時任務的搶占受到影響。
(2)如何處理時間片任務中的critical_section
critical section的處理很重要,我們一般不希望一個時間片任務在發送UART數據包的過程中被TaskRB_Scheduler暫時掐斷,但TaskRB_ Scheduler又的確無法預知時間片用戶的狀態。有兩種解決辦法:一是通過調度器上鎖,二是通過時間片任務和調度任務共享互斥量。顯然,調度器上鎖不是個好主意,會封鎖正常的任務切換,在上述的混合系統中簡直是不可想象的,但在純粹的時間片調度系統中不會帶來太多的麻煩。共享互斥量增加了系統資源的消耗,在混合系統中的運行時效率更高。
(3)運行時配置
TaskRB_Scheduler一方面是時間片的調度器,另一方面也是一個普通的μC/OS-II任務,在實際項目中可以通過創建任務鏈表的方式維護管理納入時間片調度的用戶任務,在運行時靈活地添加刪除任務列表以及調整時間片寬度。鑒于原理都很簡單,實現代碼不再贅述。
評論