嵌入式OS入門筆記-以RTX為案例:六.RTX的任務調度
上一篇筆記介紹了一些繞開排程器(或調度程序,scheduler)來進行時間管理的一些小方法。這一篇詳細介紹RTX的任務調度原理。
RTX主要有三種調度方式:
- Pre-emptive: 搶斷式
- Round robin: 輪轉式
- Co-operative: 合作式
在正式介紹這些方式之前。先看一下RTX的進程優先等級設置。
1.RTX的優先度
每個task在創建之初都會有一個優先級(os_tsk_create(task_name,priority);)。優先級是一個從0到255的整形數據,該數據越高的task。優先級越高。每個優先級都有一個先入先出的隊列結構。
首先,RTX並不能處理高速中斷(FIQ。ARM處理器中最高優先級的中斷),相反地,當高速中斷發生時。RTX內核可能會被打斷。
然后到普通中斷,普通中斷並非一個進程,所以不須要設定優先度,但普通中斷一定會打斷進程。
然后就到優先度為2-255的進程,這些進程會依照先入先出的順序執行。低優先度的進程不能打斷高優先度的進程,但高優先度的進程會打斷低優先度的進程。假設當前最高優先度是x。但全部優先度為x的進程都處於等待狀態,那么排程器就會考慮下一優先度(x-1)的進程。但一旦任一x進程進入就緒狀態。排程器會打斷低優先度進程。
優先度為1的進程時輪轉進程,以下介紹到輪轉排程時會記錄它與優先度為2-255進程的差別。
優先度為0的進程為空暇進程。
當沒有進程運行時,RTX會運行它,並提升其優先度到1.
幾個特殊進程的優先度:os_idle_demon(void) 的優先度永遠為0, RTX實在沒進程可跑才會執行這個進程。os_error (U32 err_code)的優先度永遠為255。用於處理錯誤的。這兩個進程原型都在RTX_CONFIG.C文件里。
另外,除了創建時給進程分配優先級。優先級也是能夠通過調用下面服務改變:
os_tsk_prio(taskID,priority);用於改變其它進程的優先度。
os_tsk_prio_self(priority); 用於改變當前進程的優先度。
2.RTX的調度
搞清楚RTX的優先級后,事實上RTX的調度不難理解。
1. pre-emptive
每個進程都有不同的優先級。最高優先級的進程會執行,排程器不會終止它。所以它會執行直到它自行中止掛起(blocked),或者被更高優先級的進程打斷。
自行掛起的辦法事實上我們上一節介紹過,就三個:os_tsk_pass();, os_dly_wait(delay_time);和os_itv_wait(void);.假設其被中止掛起。其余優先級最高的進程會執行。這個配置的辦法就是除能在RTX_CONFIG.C中的Round-Robin Task Switching項。
2. Round robin
每個進程的優先級都是1。每個進程都會被分配到一個時間片,在執行完這個時間片后,該進程就會增加優先級為1的隊列的末端,然后隊列最前端的進程繼續執行。
時間片由RTX_CONFIG.C中的Round_Robin Timeout[ticks]決定。准確時間是Round_Robin Timeout[ticks]×Time tick value[us] (μs). 如上圖所看到的。那么時間片就是10000×5=50000μs.配置該排程須要使能Round-Robin Task switching項。
3. Co-operative
這個是全部進程都是同樣的優先度(比如1,)且除能了輪轉式排程。
在這樣的合作模式下,進程不會被排程器掛起,僅僅能自己中止。
3.小結
事實上RTX的任務調度非常靈活,最經常使用的就是輪轉和搶斷式調度混用: 一部分進程的優先度是大於2的。其它進程的優先度是1(輪轉式排程)。也就是說假設優先度大於2的進程就緒了,優先執行,假設沒有就緒的大於2的進程,那么就先執行輪轉式的進程。並且加上不同的進程間能夠相互調節進程的優先度,所以調度的自由度非常大的。
另一些具體的細節問題,比如優先度反轉等問題,在記錄到進程間通訊后。再具體記錄一下吧。