,,,
(1.西安工業(yè)大學 計算機科學與工程學院,西安 710021; 2.西北工業(yè)大學 計算機學院,西安 710072)
在實時操作系統(tǒng)中,事件觸發(fā)指一個任務只有在與之相關的特定事件發(fā)生的條件下才能開始運行。早在最初的嵌入式領域中,事件觸發(fā)機制已經(jīng)得到了廣泛應用[1],然而在航空、航天及核電等領域,由于系統(tǒng)的高可靠性與硬實時性要求,事件觸發(fā)方式無論在設計,還是維護方面都存在較大困難[2]。許多任務可能因為等待資源而超時,這樣就無法滿足任務的實時性要求,更無法保證安全關鍵任務的完成。為此,很多基于事件觸發(fā)的操作系統(tǒng)變得愈發(fā)復雜,不僅降低了研發(fā)效率,而且增加了維護成本[3]。
時間觸發(fā)機制指在預先計劃好的時間點執(zhí)行系統(tǒng)行為,從而使系統(tǒng)具有良好的先驗性和確定性[4]。時間觸發(fā)設計思想中時間可控的特點從根本上提高了系統(tǒng)的實時性,避免了可能的直接沖突。因此,對于任務確定的嵌入式系統(tǒng),時間觸發(fā)設計思想具有明顯優(yōu)勢[5-7]。然而單純采用時間觸發(fā)的系統(tǒng)在某種程度上會降低系統(tǒng)的靈活性和動態(tài)交互性,很難完全滿足多樣性的系統(tǒng)需求,尤其針對混合關鍵任務的執(zhí)行[8-10]。因此,在實際應用中,往往需要將時間觸發(fā)和事件觸發(fā)機制相結合,設計出一種支持時間觸發(fā)和事件觸發(fā)的混合調度機制。
由于μC/OS-II是一款僅支持事件觸發(fā)的開源、可移植、可裁剪的的實時操作系統(tǒng),通過分析該系統(tǒng)的特點,將其改造為支持兩種觸發(fā)機制的操作系統(tǒng)。
μC/OS-II操作系統(tǒng)中的任務由三個部分組成:任務程序代碼,任務堆棧和任務控制塊。
任務程序代碼通常被設計為一個無限循環(huán)結構。在這個循環(huán)中可以響應中斷。任務堆棧是給每個任務分配的一塊獨立的連續(xù)內(nèi)存空間,用來在任務切換和響應中斷時保存CPU寄存器中的內(nèi)容,或任務調用其他函數(shù)時使用。任務控制塊(Task Control Block, TCB)的數(shù)據(jù)結構OS_TCB,用來記錄任務的堆棧指針、任務的當前狀態(tài)、任務的優(yōu)先級等一系列與任務管理有關的屬性。
任務調度主要包括兩部分內(nèi)容:一是判斷哪些任務處于就緒狀態(tài);二是從處于就緒態(tài)的任務中確定應該馬上執(zhí)行的任務并為其分配CPU。μC/OS-II中完成第一部分工作的是任務就緒表,完成第二部分工作的是調度器。μC/OS-II中設計了一個位圖來登記系統(tǒng)中所有處于就緒狀態(tài)的任務,這個位圖就是任務就緒表。位圖的每一位代表系統(tǒng)中的每一個任務,該位置的狀態(tài)(1或0)就表示對應任務是否處于就緒狀態(tài)。
為了能夠同時支持TT(Time-Triggered)任務和ET (Event-Triggered) 任務,將系統(tǒng)分為兩大部分:時間觸發(fā)模塊和事件觸發(fā)模塊,這兩部分相對獨立又緊密聯(lián)系。以時間觸發(fā)模塊為上層主要模塊,事件觸發(fā)模塊為下層基礎模塊的層次性架構如圖1所示。
圖1 時間和事件雙重觸發(fā)的系統(tǒng)調度架構圖
應用API任務集輸入位于整個內(nèi)核架構的最外層,包括對應用提供的系統(tǒng)服務、系統(tǒng)配置和用戶應用程序。系統(tǒng)配置模塊可以配置與具體應用相關的參數(shù)和選項等,用戶應用程序即包括用戶創(chuàng)建的任務,其中有時間觸發(fā)模塊提供的API,也有事件觸發(fā)模塊提供的API。
任務調度入口將應用API分為時間觸發(fā)任務和事件觸發(fā)任務。在調度器內(nèi)核中,時間觸發(fā)模塊為TT任務的管理和調度服務,事件觸發(fā)模塊為ET任務進行管理和服務,該模塊仍然采用原μC/OS-II中的管理方法。
在TT任務調度中,系統(tǒng)任務僅由預設的時間點來觸發(fā),調度器在運行期間每一時刻,都是通過提前計算好的調度表來進行調度決策的。
事件觸發(fā)模塊主要負責ET任務的管理、調度以及與安全性相關的訪問控制決策和實施。此外,還包括中斷管理和任務間通信等內(nèi)核與硬件無關的部分。
包括與具體硬件平臺相關的任務堆棧管理、任務切換、時鐘中斷等模塊,根據(jù)不同的應用環(huán)境進行個性化移植。
整個內(nèi)核中,時間觸發(fā)模塊占主體地位,系統(tǒng)為其預先分配固定的時間槽用以執(zhí)行時間觸發(fā)任務,主要保證系統(tǒng)的可靠性和確定性。事件觸發(fā)模塊在時間觸發(fā)模塊的空閑時間內(nèi)處理,而空閑時間也可以根據(jù)時間觸發(fā)任務的實際運行情況動態(tài)調整,提高了系統(tǒng)的靈活性。
時間觸發(fā)模塊主要完成TT任務的管理與調度、任務間的通信以及中斷管理等。為了更好的保留μC/OS-II的原有特性和代碼結構,時間觸發(fā)模塊的實現(xiàn)是在由改造μC/OS-II實現(xiàn)的事件觸發(fā)模塊之上,另外新建的一個模塊。其結構定義如下:
typedefstructos_tt_tcb
{OS_STK* OSTT_TCBStkPtr; /*TT任務的堆棧指針*/
ttTaskTypeOSTT_TCBTaskID; /*任務標識符*/
ttAppModeTypeOSTT_TCBAppMode; /*任務所屬應用模式*/
INT8U OSTT_TCBStartTime; /*TT任務的發(fā)布時間*/
INT8U OSTT_TCBDeadline; /*TT任務的時限時間*/
ttTaskStateTypeOSTT_TCBState; /*TT任務的狀態(tài)*/
INT8U criti_level; /*混合關鍵任務的關鍵級別*/
OS_TT_TASK_INFO info[MAX_CRITICALITY];
}OS_TT_TCB;
其中OS_TT_TASK_INFO包含時間觸發(fā)的關鍵任務處于各個關鍵級別時的信息,包括任務在各關鍵級別上的最壞執(zhí)行時間和后續(xù)任務。而常量MAX_CRITICALITY表示系統(tǒng)的最大的關鍵級別數(shù),如果MAX_CRITICALITY等于1,則表示系統(tǒng)中只有一種關鍵級別的任務,則整個任務的調度就簡化為普通的時間觸發(fā)任務調度,只需要一張調度表即可。OS_TT_TASK_INFO的定義如下:
typedefstructos_tt_task_info
{ INT8U OSTT_TCBWcet; /*TT任務的最壞執(zhí)行時間*/
structos_tt_tcb* OSTT_TCBNext; /*指向下一個OS_TT_TCB的指針*/
}OS_TT_TASK_INFO;
和μC/OS-II一樣,事先定義了一批時間觸發(fā)任務控制塊,其數(shù)量由宏定義OS_TTTASK_MAX靜態(tài)配置。系統(tǒng)將建立一個空閑TT任務鏈表和一個TT任務控制塊鏈表來管理這些時間觸發(fā)任務控制塊。
時間觸發(fā)的任務調度需要多張調度表,每張調度表就是一個任務控制塊鏈表,對應每一個任務的優(yōu)先級別。為此,設計了以下結構:
typedefstructos_tt_appmode
{
structos_tt_tcb* first[MAX_CRITICALITY]; /*指向任務的頭結點*/
}OS_TT_APPMODE;
structos_tt_tcb*類型的數(shù)組first包含了指向各張調度表中第一個TT任務控制塊的指針,即各個TT任務控制塊鏈表的頭結點指針。
為了更方便快捷地管理被搶占的TT任務,設計了任務恢復鏈表,將被搶占的TT任務的任務控制塊鏈接在一起,其中的任務按照最早時限排列,在恢復任務執(zhí)行時,總是最先取出表頭時限時間最找的任務。TT任務恢復鏈表由任務恢復鏈表節(jié)點OS_TT_PREEMPTED_TCB鏈接而成,其定義如下:
typedefstructos_preempted_tt_tcb
{
OS_TT_TCB*OSTT_PTcb; /*指向需要恢復執(zhí)行的時間觸發(fā)任務*/
structos_preempted_tt_tcb*OSTT_PNext; /*指向鏈表中下一個元素*/
}OS_TT_PREEMPTED_TCB;
和空閑TT任務鏈表類似,設計了一個OS_TT_PREEMPTED_TCB類型的數(shù)組OSTTPTCBTbl[],其元素個數(shù)由OS_TT_PREEMPTED_MAX靜態(tài)配置,表示系統(tǒng)最多可以維護被搶占的任務控制塊的個數(shù)。把各個元素鏈接成一個鏈表,這就是空閑TT任務恢復鏈表,其頭指針為OSTTPTCBFreeList,用于任務恢復鏈表節(jié)點的分配;OSTTResumeFirst和OSTTResumeLast分別為任務恢復鏈表頭與表尾指針。
圖2 任務控制塊鏈表和任務恢復鏈表
圖2表示了TT任務控制塊鏈表和空閑TT任務鏈表,任務恢復鏈表和空閑任務恢復鏈表及其相互間的關系。其中,OSTTCur表示當前正在運行的TT任務的控制塊,OSTTNext指向下一個將要運行的TT任務的控制塊。
時間觸發(fā)模塊中的任務調度和事件觸發(fā)一樣,也分為中斷級調度和任務級調度。
3.3.1 中斷級調度
時間觸發(fā)模塊中,中斷級調度主要發(fā)生在時鐘中斷服務程序OSTickISR()中,調度通過ttSchedTick()函數(shù)實現(xiàn)。中斷服務程序完成后退出中斷時,調用ttSchedTick()函數(shù),該函數(shù)會確認是否開始新一輪調度、是否有新的TT任務需要運行、是否TT任務都已執(zhí)行完等各種情況。
1)如果開始新一輪調度,則時鐘節(jié)拍重置為0,將當前執(zhí)行任務指針OSTTCur置為NULL,將下一個將要執(zhí)行的任務指針OSTTNext指向低級調度表中的第一個任務,開始重新執(zhí)行;
如果不開始新一輪調度:
2)還沒到下一個TT任務的觸發(fā)時間,當前的TT任務還未執(zhí)行完且執(zhí)行時間未達到當前級別下的最壞執(zhí)行時間時,則當前任務繼續(xù)執(zhí)行,不進行任務切換;
3)當前的TT任務是高級別安全關鍵任務,執(zhí)行時間已達到當前級別下的最壞執(zhí)行時間而還未執(zhí)行完時,則系統(tǒng)發(fā)生狀態(tài)切換,提高系統(tǒng)所處關鍵級別和調度表,根據(jù)調度表將OSTTNext指向高級調度表中下一任務,當前任務繼續(xù)執(zhí)行,不進行任務切換;
4)如果下一個TT任務觸發(fā),則搶占當前的TT任務并進行任務切換;
5)如果當前TT任務已執(zhí)行完且下一個任務還未到達,則對時間觸發(fā)模塊來說,當前處于空閑時間,將系統(tǒng)切換到事件觸發(fā)模塊,進行ET任務的調度和切換。
中斷級調度中的任務切換不需要保存任務上下文,因為任務被中斷時已經(jīng)進行了保存。中斷級調度的主要流程圖如圖3所示。
圖3 中斷級調度流程圖
3.3.2 任務級調度
時間觸發(fā)模塊中,任務級調度發(fā)生在任務執(zhí)行完畢時,調用ttTaskEnd(),可以讓系統(tǒng)提前進行任務調度,而不必等時鐘中斷到來。
1)如果恢復鏈表為空,說明當前所有TT任務均已執(zhí)行完畢,則將系統(tǒng)切換到事件觸發(fā)模塊,進行ET任務的調度和切換。
2)若恢復鏈表不為空,當前結束任務為恢復鏈表中最后一個任務,則將當前任務從恢復鏈表中刪除,啟動ET任務調度和切換。
3)若恢復鏈表不為空,當前結束任務不是恢復鏈表中最后一個任務,將當前任務從恢復鏈表中刪除,然后恢復鏈表中下一個TT任務的執(zhí)行,進行TT任務的任務切換。
4)若恢復鏈表不為空,且當前任務不在恢復鏈表中,則將恢復鏈表中的第一個任務恢復運行,進行TT任務切換。
任務級調度的主要流程圖如圖4所示。
圖4 任務級調度流程圖
將設計的內(nèi)核移植到Xilinx Virtex-5 FXT FPGA ML507 的評估平臺上進行測試。內(nèi)核在開發(fā)板上的移植工作主要通過Xilinx ISE Design Suite 12.3軟件完成。實驗選取4個事件觸發(fā)任務(ET任務)和3個時間觸發(fā)任務(TT任務);任務的各項參數(shù)如表1和2所示。
表1 事件觸發(fā)任務
表2 時間觸發(fā)任務
ET任務的優(yōu)先級數(shù)字越小表示其優(yōu)先級越高,實驗環(huán)境下系統(tǒng)時鐘節(jié)拍為1 ms,TT任務執(zhí)行周期為50 ms。在完成多次實驗后,選取任務開始執(zhí)行的第一個周期內(nèi)的執(zhí)行結果,實驗結果如圖5所示。
圖5 實驗結果圖
由實驗結果可知,tick = 0時刻,ET任務etTask1,etTask2,etTask3,etIdle在任務創(chuàng)建完成后就緒,由于優(yōu)先級etTask3 > etTask2 > etTask1 >etIdle,所以任務etTask3優(yōu)先執(zhí)行,此后etTask2,etTask1和etIdle依次執(zhí)行。當tick = 10時,ttTask1開始執(zhí)行,直到tick = 12時,ttTask1還未執(zhí)行結束,這時ttTask2觸發(fā)并搶占ttTask1任務執(zhí)行。當tick = 15時,ttTask2執(zhí)行結束,ttTask1恢復執(zhí)行;當tick = 22時,ttTask1執(zhí)行結束。之后,ET任務etIdle,etTask2,etTask3依次就緒并執(zhí)行。當tick = 30時,ttTask3搶占etTask3開始執(zhí)行;在tick = 32時ttTask3執(zhí)行結束,之后etTask3恢復執(zhí)行并在tick = 37時執(zhí)行結束。此后,ET任務etIdle,etTask1,etTask2依次就緒并執(zhí)行。
隨著外部事件的不可預知性和實時任務復雜性的增加,單純的事件觸發(fā)機制或時間觸發(fā)機制都難以保證系統(tǒng)的安全性和可靠性。只有將事件觸發(fā)和時間觸發(fā)結合起來,才能解決單一觸發(fā)機制無法滿足復雜嵌入式系統(tǒng)要求的問題,才能既保證系統(tǒng)的可靠性和確定性,又保證系統(tǒng)對外部事件擁有良好的響應能力。實驗說明了這種方式可行,后期的工作將在時間觸發(fā)模塊內(nèi)部,還要實現(xiàn)針對混合關鍵任務的調度算法和對應的安全級別調度表的設計,保證系統(tǒng)對安全關鍵任務的支持。在事件觸發(fā)模塊內(nèi)部,還要實現(xiàn)包括決策和實施在內(nèi)的訪問控制機制,保證系統(tǒng)具備一定的安全性。