利用實時內(nèi)核開發(fā)嵌入式多任務程序
摘要:嵌入式系統(tǒng)應用日益復雜化,傳統(tǒng)的前臺/后臺程序開發(fā)機制已經(jīng)不能滿足需求,目前更多地采用搶占式實時內(nèi)核開發(fā)嵌入式多任務系統(tǒng)。實時內(nèi)核為多任務應用程序提供最基本和最重要的服務。本文介紹實時內(nèi)核和多任務,并提出利用實時內(nèi)核進行系統(tǒng)開發(fā)時,根據(jù)系統(tǒng)功能合理構成任務的方法。 關鍵詞:實時內(nèi)核 多任務 任務構造 嵌入式系統(tǒng) 隨著嵌入式系統(tǒng)的廣泛使用,傳統(tǒng)的前臺/后臺程序開發(fā)機制已經(jīng)不能滿足日益復雜和多樣化的嵌入式應用需求,因而常常采用嵌入式實時操作系統(tǒng)內(nèi)核(簡稱實時內(nèi)核)開發(fā)實時多任務程序。嵌入式實時內(nèi)核提供多任務、任務管理、時間管理、任務間通信和同步、內(nèi)存管理等重要服務,使嵌入式應用程序容易設計和擴展。內(nèi)核是管理微處理器或者微控制器時間的軟件,確保所有時間關鍵的事件盡可能高效地得到處理;允許將系統(tǒng)分成多個獨立的任務,每個任務處理程序的一部分,從而簡化系統(tǒng)的設計過程。 一、非搶占式內(nèi)核和搶占式內(nèi)核 實時內(nèi)核分為兩種:非搶占式內(nèi)核和搶占式內(nèi)核。這兩種內(nèi)核都由中斷服務例程(ISR)處理異步事件。在非搶占式內(nèi)核中,一個ISR使優(yōu)先級更高的任務就緒,并不立即將CPU控制權交給優(yōu)先級高的任務,而是返回到被中斷的當前任務。只有當前任務執(zhí)行某種操作明確放棄CPU時,優(yōu)先級高的新任務才得到CPU 控制權。非搶占式內(nèi)核對實時事件的響應時間不確定,因而極少在實時應用中使用。圖1所示為非搶占式內(nèi)核程序流程:①低優(yōu)先級任務(LPT)執(zhí)行;②低優(yōu)先級任務被中斷;③執(zhí)行中斷服務例程,使高優(yōu)先級任務(HPT)就緒;
④中斷服務例程返回到被中斷的低優(yōu)先級任務;⑤低優(yōu)先級任務繼續(xù)執(zhí)行;⑥低優(yōu)先級任務放棄CPU;⑦高優(yōu)先級任務運行。 目前在大多數(shù)嵌入式實時多任務系統(tǒng)應用中,對系統(tǒng)實時響應要求很高,因此采用搶占式內(nèi)核確保時間關鍵的任務最先執(zhí)行,使優(yōu)先級最高的就緒任務總是最先得到 CPU控制權。優(yōu)先級低的當前任務能夠被優(yōu)先級更高的任務搶占,暫時掛起執(zhí)行,將CPU控制權交給優(yōu)先級高的任務。圖2所示為搶占式內(nèi)核程序流程:①低優(yōu)先級任務執(zhí)行;②異步事件使任務中斷;③響應異步事件,運行中斷服務例程,使高優(yōu)先級任務就緒;④中斷服務例程返回到高優(yōu)先級任務;⑤高優(yōu)先級任務執(zhí)行,直到它被中斷轉向執(zhí)行優(yōu)先級更高的任務;⑥高優(yōu)先級任務結束,內(nèi)核切換到低優(yōu)先級任務;⑦低優(yōu)先級任務繼續(xù)執(zhí)行。 二、多任務 利用實時內(nèi)核開發(fā)嵌入式多任務系統(tǒng)程序,要根據(jù)明確的設計目的確認系統(tǒng)功能,將系統(tǒng)功能合理分解,構造不同的任務,使每個任務負責完成應用要求的一部分功能;并根據(jù)任務相對于其他任務的重要性決定其優(yōu)先級。多個任務彼此獨立運行,具有獨立的私有堆??臻g,在被其他進程搶占時能夠保持任務執(zhí)行線程的上下文。 1.任務 任務是單線程序列指令形成的一個無限循環(huán),在系統(tǒng)程序中用函數(shù)表示(如下)。任務執(zhí)行時要調用內(nèi)核提供的服務,以等待某個事件發(fā)生。事件可以是定時間,或者是另一個任務、一個中斷服務例程發(fā)出事件通知。 Void Task (void) { While (true) { Run Application-specific codes; Wait for event by calling a service provided by the kernel; Run Application - specific codes; } } 2.任務管理 每個任務有5種狀態(tài);休眠、就緒、運行、等待、中斷。圖3所示為任務之間的狀態(tài)轉換。休眠狀態(tài)的任務駐留在存儲器中,還未被內(nèi)核使用;就緒狀態(tài)的任務準備執(zhí)行,優(yōu)先級低于當前執(zhí)行的任務,沒有得到CPU控制權;任務得到CPU控制權后就處于運行狀態(tài);等待事件發(fā)生的任務處于等待狀態(tài),事件可以是I/O操作完成、
共享資源可以利用、時鐘脈沖發(fā)生等;任務執(zhí)行過程被中斷服務例程中斷,任務就處于中斷狀態(tài)。 實時內(nèi)核通過任務控制塊(TCB)管理任務。TCB數(shù)據(jù)結構中包括任務的狀態(tài)、優(yōu)先、指向任務棧頂?shù)闹羔槨⒁约捌渌c內(nèi)核有關的信息。程序調用內(nèi)核服務(如調用內(nèi)核函數(shù)OSTaskCreate)創(chuàng)建任務,為此任務在內(nèi)存中分配一個TCB、進行初始化,使任務從休眠狀態(tài)轉變到就緒狀態(tài)。任務可以在多任務執(zhí)行之前靜態(tài)創(chuàng)建,也可以在多任務執(zhí)行過程動態(tài)創(chuàng)建。 內(nèi)核為實時多任務應用程序提供任務調度和轉換、任務間通信、定時順等服務,并作為系統(tǒng)調用提供給任務使用。實時內(nèi)核以事件為基礎、根據(jù)任務執(zhí)行狀態(tài)對任務進行切換,任務的狀態(tài)也隨之相應改變。在實時多任務程序中,內(nèi)存中存在多個任務控制塊以及各個任務獨立的私有堆棧。進行任務切換首先要保存CPU寄存器內(nèi)容到當前任務堆棧,將堆棧指針保存到當前任務的TCB中,然后從新任務的TCB中裝載堆棧指針,并將新任務上下文裝載到CPU寄存器中。這樣就從一個任務轉換到另一個任務運行。任務使用這時內(nèi)核提供的定時器系統(tǒng)調用,可以保持休眠狀態(tài)一段時間,或者等待一段時間后成為就緒狀態(tài)。在實時嵌入式系統(tǒng)中,外部中斷事件產(chǎn)生的任務具有高優(yōu)先級,因而以搶占方式獲得CPU控制權。 三、任務構造 1.I/O任務構造 根據(jù)3種不同的I/O事件;中斷驅動事件、輪詢事件、輸出事件來構造I/O任務。輪詢事件通常由1個任務實現(xiàn),實時內(nèi)核以固定周期對此任務進行調度,輸出事件常被設計為可重入程序而不是任務;中斷驅動事件是一類典型的異步事件。 下面將以1個簡單的串行設備驅動程序來說明I/O分解,突出I/O任務構造的重要特征。此設備分配得到1個中斷向量,在3種情況下產(chǎn)生中斷:接收到字符、輸出就緒、設備出錯。因為采用搶占式內(nèi)核,在I/O中斷發(fā)生進入中斷處理例程以后,程序要保存處理器狀態(tài),并根據(jù)不同的中斷原因進行任務調度;在中斷處理完成退出中斷處理例程之前,還要恢復處理器狀態(tài)。 設備中斷處理: IF 接收到字符THEN 將字符放入字符接收隊列; 執(zhí)行接收任務; IF 輸出就緒 THEN IF 繼續(xù)輸出 THEN 送下一個字符; ELSE 保存"設備輸出就緒"情況; IF 設備出錯 THEN 將錯誤狀態(tài)放入錯誤隊列; 執(zhí)行出錯處理任務; 接收任務: Void Task_receive() { While (true){ Wait on input char queue; If end of input string then Process input string; Else Save input; } } 對于中斷事件要合理劃分事件的處理級別,盡可能多地在任務級處理,從而最小化系統(tǒng)中斷延遲。對這個串行設備驅動中斷的處理就是一個劃分事件到中斷級和任務級處理的例子。中斷服務例程及時響應實時中斷,將實時要求相對低一些的事件(如字符出錯、出錯狀態(tài)處理)交給不同的任務處理。隊列是內(nèi)核提供的一種任務間通信結構,支持消息發(fā)送者和接收者異步訪問。在這里用于驅動程序和任務之間的通信,為驅動程序進程和任務進程提供消息緩沖。設備驅動程序負責及時響應中斷事件,并不關心接收任務的狀態(tài)。為了簡化接收任務的結構,減小系統(tǒng)延遲,這里將出錯處理劃分為獨立的任務,分配不同的優(yōu)先級。[!--empirenews.page--]
2.內(nèi)部任務構造 系統(tǒng)內(nèi)部任務可以分為:①周期性任務--實時內(nèi)核基于固定周期調度的任務;②異步任務--非周期或事件驅動的任務,內(nèi)核根據(jù)需要進行調度,用于處理系統(tǒng)內(nèi)部產(chǎn)生的事件;③控制對象--為狀態(tài)機創(chuàng)建的控制任務,用于實現(xiàn)狀態(tài)轉換;④用戶接口⑤--對應于用戶任務,在用戶驅動的系統(tǒng)中,用戶任務是具有高優(yōu)先級。 在嵌入式實時多任務系統(tǒng)中,大部分任務是非周期或事件驅動的異步任務,其函數(shù)形式如下: Void Task_aperiodic () { While (true){ Wait on an async data structure; Process input; Process output; } } 在異步任務中,驅動任務的異步數(shù)據(jù)是由實時內(nèi)核提供的任務間通信數(shù)據(jù)。內(nèi)核為應用程序提供信號量、消息隊列、消息郵箱、插口或管道等結構,進行事件管理和任務間通信。設計這些異步任務時采用合適的數(shù)據(jù)結構、正確定義數(shù)據(jù)能夠節(jié)省寶貴的調試時間,而且任務處理的函數(shù)不能太多,過于復雜,否則會增加調試的難度。 3.任務合并 利用任務的共同特征進行適當?shù)娜蝿蘸喜ⅲ梢院喕到y(tǒng)任務模型、減小系統(tǒng)復雜度、消除某些任務的切換開銷從而減少系統(tǒng)總體開銷。任務合并可分為:①根據(jù)時間一致合并,將同一事件激活的優(yōu)先級相同的函數(shù)合并在1個任務中;②根據(jù)控制一致合并,③根據(jù)函數(shù)一致合并,將幾個使用相同數(shù)據(jù)的函數(shù)合并,使原來共享的數(shù)據(jù)成為任務內(nèi)的局部數(shù)據(jù),從而減少互斥。 結束語 目前有許多廠商提供面向嵌入式應用領域的實時操作系統(tǒng)(RTOS),提供實時內(nèi)核、輸入/輸出管理器、窗口系統(tǒng)、文件系統(tǒng)、網(wǎng)絡、語言接口庫、調試器和交叉平臺編譯器的軟件包。其中實時內(nèi)核為嵌入式多任務程序提供最基本和最重要的功能。本文從利用實時內(nèi)核開發(fā)多任務應用程序的角度,對實時內(nèi)核和任務進行介紹,提出合理構造任務的方法??梢钥吹剑脤崟r內(nèi)核提供的服務,采用正確的開發(fā)方法,可以增加嵌入式實時多任務系統(tǒng)的功能,降低開發(fā)方法,可以增加嵌入式實時多任務系統(tǒng)的功能,降低開發(fā)難度。