一種嵌入式微調度器的實現方法
| [日期:2008-10-23] |
來源:單片機與嵌入式系統應用 作者:重慶郵電大學 曾素華 蔣建春 |
[字型:大 中 小] |
智能儀錶是自動控制技術的重要組成部分。隨著智能儀錶在工業控制、通訊和汽車電子中的廣泛應用,智能儀錶逐漸向數字化、網路化、智能化方向發展;同時,智能儀錶複雜度不斷增加,對即時性要求幾乎達到了苛刻的程度。在編程方式和代碼重複利用等方面,超迴圈方式的智能儀錶越來越不能滿足資源管理和系統的即時要求,迫切需要在中低端智能儀錶中加入一些輕量級的多任務管理的調度器或即時作業系統。本文根據智能儀錶對嵌入式作業系統的特殊要求設計了一種新的任務調度演算法,並實現了一個應用於中低端儀器儀錶的嵌入式微調度器。
1 即時任務調度的一般方法和策略
在即時作業系統中,系統把應用分為行為可以預知的、功能確定的多個任務。每個任務一般處於3種狀態:執行狀態、就緒狀態和等待狀態(有的作業系統還具有掛起和休眠狀態)。為了滿足即時性要求,系統根據一定的原則選擇合適的任務執行。
常見的任務調度演算法分為靜態算和動態演算法兩類:
① 靜態演算法:在系統在運行前(即系統初始化階段),就為所有的任務分配固定的優先順序別,在系統執行過程中優先順序保持不變。當一個事件發生時,發送器只需要查就緒表,就可以調度哪個任務處於運行狀態。
② 動態演算法:在系統初始化時初步分配一個優先順序。每一個任務在運行時可以改變它的優先順序。當前的嵌入式作業系統一般採用靜態演算法,只在處理優先順序反轉時臨時採用動態優先順序演算法。
2 儀器儀錶對調度演算法的要求
為了提高儀錶的可靠性,實現高效能、多功能應用,應用於智能儀錶的調度器必須滿足以下要求:
①良好的即時性。智能儀錶必須即時地對通過現場匯流排採集的資料進行數字編碼,通過人機介面進行顯示,並把使用者對被監控系統的參數設定即時地傳送給執行組件。
② 基於優先順序的任務調度策略。在複雜的大規模應用中需要使用大量的感應器、執行器和控制器等,對其資料顯示和傳輸控制需要通過不同優先順序的任務來控制。
③ 低消耗要求。隨著應用環境的複雜化,對智能儀錶的計算能力要求越來越高,勢必要求調度器必須佔用較少的系統資源。
④ 低成本要求。為了降低成本,在硬體設計上,儲存空間的大小是成本控制的一個方面。因此,要求提供的調度器必須具備小核心以減小儲存空間。此外,還要求調度器必須有精確定時的功能,也就是事件驅動和時鐘驅動相結合,以滿足智能儀錶中週期性任務執行和突發性任務執行的需要。
3 嵌入式微調度器的設計與實現
根據智能儀錶對調度演算法即時性、多任務、低消耗的要求,本文提出了一種新的靜態優先順序,單任務隊列、具有4種任務狀態的非搶佔式調度的輕量型工作調度演算法,並根據這種演算法實現了應用於智能儀錶的調度器。該演算法的特點是以任務在任務控制塊數組中的相對位置表示優先順序高低,任務的狀態和延時量使用統一的任務狀態字,在少量任務的輕量級應用中具有很好的時間和空間效能。
3.1 任務的狀態
在本調度器中任務有4種狀態:就緒狀態、運行狀態、等待狀態和掛起狀態。記憶體中的任務必須處於這4種狀態之一。
就緒狀態:指任務啟動並執行時間條件和資源條件都滿足,等待調度演算法選擇最合適的任務進入就緒狀態。任務一旦建立就處於就緒狀態,這一點和μC/0S—II相同。
運行狀態:是當前時刻任務佔有CPU資源正在啟動並執行狀態。本調度演算法選擇進入就緒任務隊列中優先順序最高的任務運行。任何時刻只能有一個任務處於運行狀態。
等待狀態:如果任務需要等待一段時間才能運行,那麼這個任務當前處於等待狀態。使任務延遲一段時間可通過調用0s_TasK_Delay()函數實現。調度器在每個系統時鐘節拍檢查任務延遲時間,一旦任務定義的延遲時間到,就使任務進入就緒狀態。
掛起狀態:正在啟動並執行任務需要等待某一事件的發生,如果該事件沒有發生那麼任務就處於掛起狀態。事件的發生可能來自另外一個任務,也可能來自中斷服務程式。
除此之外,系統還可能處在中斷服務狀態。這是一種特殊的運行狀態,當系統響應中斷時,正在執行的任務被掛起,中斷服務程式控制了CPU的使用權,系統就進入中斷服務狀態。
其中,空閑任務優先順序最低,而且永遠處於就緒狀態,而且當所有的任務都在等待事件發生或者延遲時間結束時,作業系統就會執行空閑任務。
3.2 調度器核心資料結構
3.2.1 任務控制塊和任務控制塊列表
任務控制塊由任務堆棧、任務入口地址、任務狀態字和任務優先順序4個部分組成。任務堆棧用於保護被中斷的現場資料;任務入口地址是指向任務程式的指標,用於指定任務所進行的操作;任務狀態字用來表示任務當前的狀態和延遲的時間間隔;任務優先順序表示就緒列表中的哪個任務可以優先進入運行狀態。在整個調度過程中使用一個全域的任務控制塊數組來表示任務控制塊列表。每個任務使用唯一一個任務控制塊表示,任務的優先順序通過任務控制塊在任務控制塊數組中的相對位置來表示。每個任務有且僅有一個優先順序,所以任務的優先順序也可以用任務的ID號來表示。任務控制塊結構如下:
typedef struct{ //tsk_tcb結構定義
pStack stack; //tsk_tcb堆棧入口
pTAsK task; //tsk_tcb指向的任務
U8 state; //tsk.tcb任務目前的狀態
U8 prior; //任務優先順序
}TCB;
3.2.2 任務調度演算法及實現
這種演算法已在16位單片機Motorola MC9S12DP256B和8位單片機AT89C52上實現。一些與硬體相關的演算法,主要給出在MC9S12DP256B上的演算法實現。
①建立任務Os—Task-Create()演算法。任務建立函數代碼如下:
void 0s_Task_Create(0S_STACK*task_stack,
uW0rd task_id,pTASK task_func){
os_tcb[task_id].task=task_func;
os_tcb[task_id].stack=task_stack;
os_tcb[task_id].prior=task_id;
}
該程式表示了系統建立任務的過程。如上節所述每個任務對應一個優先順序,所以任務ID也可表示任務的優先順序。建立任務的過程就是,把任務控制塊數組的任務入口地址對應ID(即任務優先順序)的任務控制塊的任務入口地址指向任務函數的地址,並初始化該任務的任務堆棧。
② 任務調度演算法的功能是找到當前就緒列表中優先順序最高的任務,並把這個任務切換到運行狀態。在任務控制塊列表中使用任務在列表中的相對位置表示優先順序的高低,並不需要實際地對任務優先順序進行比較。演算法流程1所示。
從任務控制塊隊列的頭部(即任務優先順序為O的任務)開始依次檢查任務就緒標誌(os_tcb.state),如果當前任務標誌≠1,表示當前任務為非就緒狀態,繼續檢查下一優先順序的任務。如果當前任務標誌為1,則找到最高優先順序任務退出迴圈,調用任務調度函數進行任務狀態切換。
任務的調度演算法如下:
void os_schedule_task(void){
int i ;
pCur_task=pHi_task;
for(i=O;i<TASKNUM&&os_tcb[i].state!=1;i++){
}
Hi_task=i;
if(pHi_task!=&os_tcb[i]){
pHi_task=&os_tcb[i];
os_sw_task();
}
}
任務級切換函數需要改變程式計數器(PC),所以必須通過非強制中斷實現。在非強制中斷服務函數中改變當前運行任務的TCB指標到最高優先順序就緒任務,執行中斷返回指令在新的任務堆棧中彈出最高優先順序任務的PSW和PC指標,從而完成任務切換。
③ 任務狀態轉換主要是啟用任務os_TasK_Active()、掛起任務os_TasK_Suspend()和延遲任務os_TasK_Delay()。掛起任務使任務進入掛起狀態,延遲任務使任務進入等待狀態,而啟用任務函數可以使任務從掛起狀態或者等待狀態直接進入就緒狀態。任務的狀態由任務控制塊中的任務狀態字(os_tcb.state)給出。當os_tcb.state=1時表示任務進入就緒狀態;當os_tcb.state=O時表示任務處於掛起狀態;當os_tcb.state>1時表示任務等待os_tcb.state-1個系統時鐘間隔之後進入就緒狀態。任務狀態切換2所示。
④由於這些中低端的儀器儀錶每個任務的執行時間都比較短,為了避免優先順序反轉和死結,採用非搶佔式調度方式,進入就緒態的任務必須在當前任務執行完成後才能被調度。調度時處於就緒表中優先順序最高的任務進入運行。
3.2.3 調度演算法的時鐘驅動
時間驅動需要硬體提供時鐘節拍來實現任務的定時。時鐘節拍訊號源可以是專門的硬體定時器,比如AT89C52中的Timer2。也可以使用其他更精確的方式提供系統時鐘節拍。在這裡使用MC9S12DP256B捕獲器的第7個通道來實現,時鐘中斷處理函數如下:
的捕獲器中有一個自動成長主時鐘,每一個硬體周期驅動TCNT+1,並與TC7相比較。設定TC7=TCNT+OS_TICK_OC_CNTS(在系統設定檔中定義),當度過OS_TICK_OC_CNTS個硬體周期時,TCNT=TC7則產生中斷。在中斷中調用系統時鐘節拍函數提供精確的系統時鐘節拍,並再次初始化TC7=TCNT+OS_TICK_OC_CNTS,產生下一個時鐘節拍。
系統時鐘節拍函數自動檢查每個被延遲的任務,當任務的延遲周期結束後,自動將任務切換到就緒狀態。具體演算法如下:
① 從任務控制塊列表頭部開始順序檢查各任務狀態字,將所有延遲任務的任務狀態字減1。
② 當前延遲任務的狀態字變為1時,該任務延時結束,置就緒工作清單改變標誌位。
③ 恢複被中斷任務狀態,返回中斷。系統時鐘驅動代碼如下
結 語
本文提出的任務調度演算法是一個應用於智能儀錶系統的中介軟體,目的是良好地管理CPU資源,提供方便的使用者應用介面,具有良好的可移植性、時間效能和空間效能。在具有大量週期性任務的輕量級智能儀錶的應用中,效能和易用性的提高是非常明顯的。該演算法已經成功應用於車載智能儀錶的圖形作業系統中。