Wind內(nèi)核是一種強(qiáng)實(shí)時(shí)操作系統(tǒng)內(nèi)核,但和當(dāng)前其它成熟的操作系統(tǒng)一樣,并不是“硬實(shí)時(shí)”的操作系統(tǒng)。所謂“硬實(shí)時(shí)”是指當(dāng)某種事件發(fā)生時(shí),系統(tǒng)必須在預(yù)定時(shí)間之內(nèi),或者說在限期之前做出反應(yīng),否則就會(huì)造成災(zāi)難性的后果。具有這一特征的操作系統(tǒng)要做到對(duì)于所提交的每一項(xiàng)作業(yè)及其時(shí)間要求,或者做出承諾,或者立即拒絕(以使提交者可以考慮采取其他措施),對(duì)于做出的承諾則保證其實(shí)現(xiàn)。提交給硬實(shí)時(shí)系統(tǒng)的作業(yè)也可以是不帶時(shí)間要求的,但是對(duì)這些作業(yè)的承諾當(dāng)然也就不包含時(shí)間的因素,那將當(dāng)作后臺(tái)作業(yè)來對(duì)待。 VxWorks 沒有使用基于時(shí)間限(deadline)的調(diào)度算法,也就是不接受任何作業(yè)提交的時(shí)間要求。為了提高實(shí)時(shí)性,目前采用的方法都是優(yōu)先級(jí)搶占式調(diào)度,使得高優(yōu)先級(jí)的任務(wù)的到優(yōu)先執(zhí)行。這樣,在一定計(jì)算資源前提下,通過恰當(dāng)?shù)娜蝿?wù)劃分和設(shè)定任務(wù)優(yōu)先級(jí)可以滿足實(shí)時(shí)性的要求。 備注:網(wǎng)上有人說VxWorks內(nèi)核是一種硬實(shí)時(shí)內(nèi)核,這是不準(zhǔn)確的。準(zhǔn)確的說VxWorks系統(tǒng)是實(shí)時(shí)系統(tǒng),但是它的實(shí)時(shí)性是在一定計(jì)算資源前提下,通過恰當(dāng)?shù)娜蝿?wù)劃分和設(shè)定任務(wù)優(yōu)先級(jí)來實(shí)現(xiàn)的,其它系統(tǒng)比如uC/OS系統(tǒng),F(xiàn)reeRTOS都是如此。 2.1 Wind內(nèi)核結(jié)構(gòu)為了提高系統(tǒng)的實(shí)時(shí)性,大多數(shù)操作系統(tǒng)都提供了各種機(jī)制,如可搶占的內(nèi)核、中斷的后半段處理等。VxWorks 為了提高實(shí)時(shí)性,構(gòu)造成了一個(gè)帶有微內(nèi)核的層次結(jié)構(gòu)。 在計(jì)算機(jī)的早期,操作系統(tǒng)大部分是一個(gè)統(tǒng)一的實(shí)體(monolithic)。在這樣的系統(tǒng)中,提供不同功能的模塊是獨(dú)立考慮的,如處理器管理、內(nèi)存管理、文件管理等,較少考慮模塊間的關(guān)系。這樣的操作系統(tǒng)結(jié)構(gòu)清晰,構(gòu)造簡(jiǎn)單,但是由于操作系統(tǒng)本身很復(fù)雜,在這種大粒度的操作系統(tǒng)中難以劃分可搶占部分和不可搶占部分的邊界,難以避免有冗余的操作在操作系統(tǒng)的不可搶占部分中執(zhí)行,造成系統(tǒng)的實(shí)時(shí)性比較差,不適合實(shí)時(shí)應(yīng)用環(huán)境。 而帶有微內(nèi)核的層次結(jié)構(gòu)的操作系統(tǒng)則較好的解決了這個(gè)問題。在這樣的操作系統(tǒng)中,以內(nèi)核作為層次結(jié)構(gòu)的起點(diǎn),每一層功能對(duì)較低層進(jìn)行封裝。內(nèi)核僅需要包含最重要的操作指令,提供高層軟件與下層硬件的抽象層,形成操作系統(tǒng)其它部分所需的最小操作集。這樣就可以比較容易的精確確定可搶占部分與不可搶占部分的邊界,減少了需要在內(nèi)核不可搶占部分執(zhí)行的操作,有利于實(shí)現(xiàn)更快的內(nèi)核搶占,提高系統(tǒng)的實(shí)時(shí)性。 操作系統(tǒng)的最好的內(nèi)部結(jié)構(gòu)模型是一個(gè)層次性的結(jié)構(gòu),最底層是內(nèi)核。這些層次可以看成為一個(gè)倒置的金字塔,每一層都建立在較低層的功能之上。 內(nèi)核僅包含一個(gè)操作系統(tǒng)執(zhí)行的最重要的底層功能。正象一個(gè)統(tǒng)一結(jié)構(gòu)的操作系統(tǒng),內(nèi)核提供了在高層軟件與下層硬件之間的抽象層。然而,內(nèi)核僅提供了構(gòu)造操作系統(tǒng)其他部分所需的最小操作集。 VxWorks 的Wind內(nèi)核就是這樣的一個(gè)有利于構(gòu)造層次結(jié)構(gòu)的微內(nèi)核,它由 kernelLib庫、taskLib庫、semLib庫、tickLib庫、wdLib庫、schedLib庫、workQLib庫、windLib庫、windAlib庫、semAlib庫、以及workQAlib庫組成的。其中其中kernelLib庫、taskLib庫、semLib庫、tickLib庫、以及wdLib庫組成了VxWorks內(nèi)核的基本功能,同時(shí)也是Wind內(nèi)核底層最基本、最核心的函數(shù)。在這樣的內(nèi)核中,容易實(shí)現(xiàn)很強(qiáng)的實(shí)時(shí)性;而對(duì)內(nèi)核高層次的封裝則使得用戶在開發(fā) VxWorks 的應(yīng)用程序時(shí),只需要調(diào)用頂層的函數(shù),不必關(guān)心底層的實(shí)現(xiàn),程序設(shè)計(jì)也很方便。VxWorks內(nèi)核結(jié)構(gòu)從邏輯上可以分成3層,如圖2.1所示。 2.1 VxWorks內(nèi)核層次結(jié)構(gòu) 其中由全局變量kernelState包含的例程構(gòu)成了Wind內(nèi)核的核心態(tài),當(dāng)kernelState設(shè)置為TRUE時(shí),表示此時(shí)存在代碼正在內(nèi)核態(tài)運(yùn)行。VxWorks的內(nèi)核態(tài)的本質(zhì)是保護(hù)內(nèi)核數(shù)據(jù)結(jié)構(gòu),以防止多處代碼對(duì)內(nèi)核數(shù)據(jù)結(jié)構(gòu)同時(shí)進(jìn)行訪問,所以其不同于通用操作系統(tǒng)內(nèi)核態(tài)的概念。 進(jìn)入內(nèi)核態(tài)只需要簡(jiǎn)單的將全局變量kernelState置為TRUE,從這一點(diǎn)開始所有的內(nèi)核數(shù)據(jù)將會(huì)被保護(hù),而避免競(jìng)爭(zhēng)。當(dāng)結(jié)束內(nèi)核操作時(shí),VxWorks通過windExit()例程將kernelState重新設(shè)置為FALSE。讓我們考慮一下當(dāng)處在內(nèi)核態(tài)時(shí),誰會(huì)競(jìng)爭(zhēng)使用內(nèi)核數(shù)據(jù)結(jié)構(gòu),顯然中斷服務(wù)例程是僅有可能的在Wind內(nèi)核處于內(nèi)核時(shí),請(qǐng)求內(nèi)核額外工作的始作俑者。這也就意味著,一旦系統(tǒng)進(jìn)入內(nèi)核態(tài),應(yīng)用程序請(qǐng)求內(nèi)核服務(wù)的僅有方式通過中斷服務(wù)程序。 kernelState在設(shè)置之前總是會(huì)被檢查是否已經(jīng)被置位。這就是互斥機(jī)制的精髓,VxWorks內(nèi)核使用將工作延遲來作為互斥機(jī)制實(shí)現(xiàn)方式的技術(shù),當(dāng)kernelState為TRUE的時(shí)候,要做的工作不會(huì)立即執(zhí)行,而是作為一個(gè)延遲的Job放到延時(shí)工作隊(duì)列中。內(nèi)核延時(shí)工作隊(duì)列只能在恢復(fù)前一個(gè)將要執(zhí)行的任務(wù)上下文之前,被windExit()清空(或者當(dāng)中斷ISR首先進(jìn)入內(nèi)核態(tài)的條件下的,intExit()清空)。在內(nèi)核態(tài)即將結(jié)束的時(shí)刻關(guān)中斷,windExit()會(huì)檢查工作隊(duì)列是否為空,并進(jìn)入一個(gè)被選擇的任務(wù)上下文。 正如前文所述,Wind內(nèi)核使用kernelState全局變量從軟件上模擬了一個(gè)特權(quán)態(tài),處于特權(quán)態(tài)禁止任務(wù)搶占。處于特權(quán)態(tài)例程的函數(shù)在windLib庫中。執(zhí)行windLib庫中的例程,更高層次的調(diào)用例程將會(huì)進(jìn)入內(nèi)核態(tài)(kernelState=1),獲得對(duì)所有內(nèi)核隊(duì)列的互斥使用。windLib庫中的例程具有自由支配任務(wù)內(nèi)核數(shù)據(jù)結(jié)構(gòu)的能力。內(nèi)核態(tài)(kernelState=1)是一種強(qiáng)有力的互斥工具,處于內(nèi)核態(tài)的時(shí)間內(nèi),搶占是被禁止的。高的搶占時(shí)延破壞了實(shí)時(shí)系統(tǒng)的響應(yīng)時(shí)延的快速性,因此必須非常保守的使用這種機(jī)制(目前使用這種設(shè)計(jì)機(jī)制的開源RTOS,只有RTEMS)。實(shí)際上微內(nèi)核的設(shè)計(jì)理念是保持內(nèi)核足夠小的同時(shí),使其仍具有支持更高級(jí)別應(yīng)用的能力,還記得我在前一章說過的話嗎?“一個(gè)優(yōu)美的內(nèi)核不是還有什么樣的功能還可以增加,而是還有什么樣的功能還可以減少”。 Wind內(nèi)核在處于特權(quán)態(tài)時(shí)是開中斷的,這就意味此時(shí)內(nèi)核仍可以繼續(xù)響應(yīng)外部中斷,Wind內(nèi)核的創(chuàng)新之處在于提出了工作隊(duì)列(Work Queue)的概念。由于內(nèi)核態(tài)只能被高層次的應(yīng)用互斥訪問,當(dāng)中斷發(fā)生時(shí),如果沒有程序訪問內(nèi)核態(tài)例程,當(dāng)前中斷ISR首先會(huì)進(jìn)入內(nèi)核態(tài)(將kernelState置為TRUE),然后執(zhí)行相應(yīng)的中斷ISR;如果內(nèi)核態(tài)已經(jīng)被占用(kernelState=FALSE),那邊當(dāng)前中斷的ISR將會(huì)被放置到內(nèi)核工作隊(duì)列后直接返回。等到占用內(nèi)核態(tài)的程序退出內(nèi)核態(tài)(調(diào)用windExit()例程)時(shí)會(huì)執(zhí)行內(nèi)核工作隊(duì)列中的工作(即Job),其中的中斷ISR將會(huì)得到處理(我會(huì)在后續(xù)的博文中結(jié)合代碼具體分析O(∩_∩)O)。 wind內(nèi)核中kernelState包含的內(nèi)核態(tài)例程在windLib庫中,以wind*開頭的例程,見圖2.2。 圖2.2 VxWorks內(nèi)核態(tài)例程示意圖 其中: *表示中斷ISR不能調(diào)用該例程,只能在任務(wù)級(jí)被調(diào)用; @*表示可以在中斷ISR中調(diào)用該例程; #表示將在wind內(nèi)核內(nèi)部使用; @表示可以在內(nèi)核態(tài)運(yùn)行; VxWorks系統(tǒng)的組成部分見圖2.3。 圖2.3 VxWorks系統(tǒng)構(gòu)成圖 2.2 Wind內(nèi)核的類和對(duì)象VxWorks的Wind內(nèi)核采用類和對(duì)象的思想將wind內(nèi)核的5個(gè)組成部分:任務(wù)管理模塊、內(nèi)存管理模塊、消息隊(duì)列管理模塊、信號(hào)量管理模塊、以及看門狗管理模塊組織起來。 在Wind內(nèi)核中,所有的對(duì)象都是類的組成部分,類定義了操作對(duì)象的方法(Method),同時(shí)維護(hù)著對(duì)所有對(duì)象的操作記錄。Wind內(nèi)核采用了C++的語義,但是采用C語言來實(shí)現(xiàn)。整個(gè)Wind內(nèi)核通過顯式編碼實(shí)現(xiàn),其編譯過程并不依賴于具體的編譯器。這意味著Wind內(nèi)核不但可以在VxWorks自帶的diab編譯上編譯,也可以使用開源的GNU/GCC編譯器。VxWorks為Wind內(nèi)核設(shè)計(jì)了一個(gè)元類(Meta-class),所有的對(duì)象類(Obj-class)都是基于該元類。每個(gè)對(duì)象類只負(fù)責(zé)維護(hù)各自對(duì)象(Object)的操作方法(比如創(chuàng)建對(duì)象、初始化對(duì)象、注銷對(duì)象等)、以及管理統(tǒng)計(jì)記錄(比如一個(gè)創(chuàng)建對(duì)象的數(shù)據(jù)、銷毀對(duì)象的數(shù)目等)。類管理模式不是VxWorks內(nèi)核的特性,它是操作系統(tǒng)的組成部分;但是所有的內(nèi)核對(duì)象都依賴于它。Wind內(nèi)核各個(gè)組成模塊間對(duì)象類、對(duì)象和元類的關(guān)系如圖2.4所示。 圖2.4 對(duì)象類、對(duì)象和元類的關(guān)系示意圖 備注:采用對(duì)象和類的設(shè)計(jì)思想,可以將VxWorks的Wind內(nèi)核的各個(gè)組件有機(jī)的組織起來,創(chuàng)建相同組件的各個(gè)實(shí)例時(shí)都便于驗(yàn)證實(shí)例類型的正確性,同時(shí)所有的組件對(duì)象類都來源于基類,對(duì)所有對(duì)象的操作記錄。 2.3 wind內(nèi)核特性多任務(wù):內(nèi)核的基本功能是提供一個(gè)多任務(wù)環(huán)境。多任務(wù)使得許多程序在表面上表現(xiàn)為并發(fā)執(zhí)行,而事實(shí)上內(nèi)核是根據(jù)基本的調(diào)度算法使他們分段執(zhí)行。每個(gè)明顯獨(dú)立的程序被成為一個(gè)任務(wù)。每個(gè)任務(wù)擁有自己的上下文,其中包含在內(nèi)核調(diào)度使該任務(wù)執(zhí)行的時(shí)候它所看到的CPU環(huán)境和系統(tǒng)資源。 任務(wù)狀態(tài):內(nèi)核維護(hù)系統(tǒng)中的每個(gè)任務(wù)的當(dāng)前狀態(tài)。狀態(tài)遷移發(fā)生在應(yīng)用程序調(diào)用內(nèi)核功能服務(wù)的時(shí)候。下面定義了Wind內(nèi)核狀態(tài): 就緒態(tài)----一個(gè)任務(wù)當(dāng)前除了CPU不等待任何資源 阻塞態(tài)----一個(gè)任務(wù)由于某些資源不可獲得而被阻塞 延遲態(tài)----一個(gè)任務(wù)睡眠一段時(shí)間 掛起態(tài)----主要用于調(diào)試的一個(gè)輔助狀態(tài),掛起禁止任務(wù)的執(zhí)行 任務(wù)被創(chuàng)建以后進(jìn)入掛起態(tài),需要通過特定的操作使被創(chuàng)建的任務(wù)進(jìn)入就緒態(tài),這一操作執(zhí)行速度很快,使應(yīng)用程序能夠提前創(chuàng)建任務(wù),并以一種快捷的方式激活該任務(wù)。 調(diào)度控制:多任務(wù)需要一個(gè)調(diào)度算法分配CPU給就緒的任務(wù)。在VxWorks中默認(rèn)的調(diào)度算法是基于優(yōu)先級(jí)的搶占調(diào)度,但應(yīng)用程序也可以選擇使用時(shí)間片輪轉(zhuǎn)調(diào)度。 - 基于優(yōu)先級(jí)搶占調(diào)度:基于優(yōu)先級(jí)的搶占調(diào)度,每個(gè)任務(wù)被指定一個(gè)優(yōu)先級(jí),內(nèi)核分配CPU給處于就緒態(tài)的優(yōu)先級(jí)最高的任務(wù)。調(diào)度采用搶占的方式,是因?yàn)楫?dāng)一個(gè)優(yōu)先級(jí)高于當(dāng)前任務(wù)的任務(wù)變?yōu)榫途w態(tài)時(shí),內(nèi)核將立即保存當(dāng)前任務(wù)的上文,并切換到高優(yōu)先級(jí)任務(wù)的上文。VxWorks有從0到255共256個(gè)優(yōu)先級(jí)。在創(chuàng)建的時(shí)候任務(wù)被指定一個(gè)優(yōu)先級(jí),在任務(wù)運(yùn)行的過程中可以動(dòng)態(tài)地修改優(yōu)先級(jí)以便跟蹤真實(shí)世界的事件優(yōu)先級(jí)。外部中斷被指定優(yōu)先于任何任務(wù)的優(yōu)先級(jí),這樣能夠在任何時(shí)候搶占一個(gè)任務(wù)。
- 時(shí)間片輪轉(zhuǎn):基于優(yōu)先級(jí)搶占調(diào)度可以擴(kuò)充時(shí)間片輪轉(zhuǎn)調(diào)度。時(shí)間片輪轉(zhuǎn)調(diào)度允許在相同優(yōu)先級(jí)的處于就緒態(tài)的任務(wù)公平地共享CPU。沒有時(shí)間片輪轉(zhuǎn)調(diào)度,當(dāng)有多個(gè)任務(wù)在同一優(yōu)先級(jí)共享處理器時(shí),一個(gè)任務(wù)可能獨(dú)占CPU,不會(huì)被阻塞直到被一個(gè)更高優(yōu)先級(jí)的任務(wù)搶占,而不給同一優(yōu)先級(jí)的其他任務(wù)運(yùn)行的機(jī)會(huì)。如果時(shí)間片輪轉(zhuǎn)被使能,執(zhí)行任務(wù)的時(shí)間計(jì)數(shù)器在每個(gè)時(shí)鐘滴答遞增。當(dāng)指定的時(shí)間片耗盡,計(jì)數(shù)器會(huì)被清零,該任務(wù)被放在同一優(yōu)先級(jí)任務(wù)隊(duì)列的隊(duì)尾。加入特定優(yōu)先級(jí)組的新任務(wù)被放在該組任務(wù)的隊(duì)尾,并將運(yùn)行計(jì)數(shù)器初始化為零。
基本的任務(wù)函數(shù):用于狀態(tài)控制的基本任務(wù)函數(shù)包括一個(gè)任務(wù)的創(chuàng)建、刪除、掛起和喚醒。一個(gè)任務(wù)也可以使自己睡眠一個(gè)特定的時(shí)間間隔不去運(yùn)行。許多其他任務(wù)例程提供由任務(wù)上下文獲得的狀態(tài)信息。這些例程包括訪問一個(gè)任務(wù)當(dāng)前處理器寄存器控制。 任務(wù)刪除問題: wind內(nèi)核提供防止任務(wù)被意外刪除的機(jī)制。通常,一個(gè)執(zhí)行在臨界區(qū)或訪問臨界資源的任務(wù)要被特別保護(hù)。我們?cè)O(shè)想下面的情況:一個(gè)任務(wù)獲得一些數(shù)據(jù)結(jié)構(gòu)的互斥訪問權(quán),當(dāng)它正在臨界區(qū)內(nèi)執(zhí)行時(shí)被另一個(gè)任務(wù)刪除。由于任務(wù)無法完成對(duì)臨界區(qū)的操作,該數(shù)據(jù)結(jié)構(gòu)可能還處于被破壞或不一致的狀態(tài)。而且,假想任務(wù)沒有機(jī)會(huì)釋放該資源,那么現(xiàn)在其他任何任務(wù)現(xiàn)在就不能獲得該資源,資源被凍結(jié)了。 任何要?jiǎng)h除或終止一個(gè)設(shè)定了刪除保護(hù)的任務(wù)的任務(wù)將被阻塞。當(dāng)被保護(hù)的任務(wù)完成臨界區(qū)操作以后,它將取消刪除保護(hù)以使自己可以被刪除,從而解阻塞刪除任務(wù)。 正如上面所展示的,任務(wù)刪除保護(hù)通常伴有互斥操作。 這樣,為了方便性和效率,互斥信號(hào)量包含了刪除保護(hù)選項(xiàng)(我會(huì)在后續(xù)的博文中詳細(xì)介紹) 任務(wù)間通信: 為了提供完整的多任務(wù)系統(tǒng)的功能,Wind內(nèi)核提供了一套豐富的任務(wù)間通信與同步的機(jī)制。這些通信功能使一個(gè)應(yīng)用中各個(gè)獨(dú)立的任務(wù)協(xié)調(diào)他們的活動(dòng)。 共享地址空間: Wind內(nèi)核的任務(wù)間通信機(jī)制的基礎(chǔ)是所有任務(wù)所在的共享地址空間。通過共享地址空間,任務(wù)能夠使用共享數(shù)據(jù)結(jié)構(gòu)的指針自由地通信。管道不需要映射一塊內(nèi)存區(qū)到兩個(gè)互相通信任務(wù)的尋址空間。 備注:不幸的是,共享地址空間具有上述優(yōu)點(diǎn)的同時(shí),帶來了未被保護(hù)內(nèi)存的重入訪問的危險(xiǎn)。UNIX,Linux操作系統(tǒng)通過隔離進(jìn)程提供這樣的保護(hù),但同時(shí)帶來了對(duì)于實(shí)時(shí)操作系統(tǒng)來說巨大的性能損失。 互斥操作: 當(dāng)一個(gè)共享地址空間簡(jiǎn)化了數(shù)據(jù)交換,通過互斥訪問避免資源競(jìng)爭(zhēng)就變?yōu)楸匾牧?。用來獲得一個(gè)資源的互斥訪問的許多機(jī)制僅在這些互斥所作用的范圍上存在差別。實(shí)現(xiàn)互斥的方法包括禁止中斷、禁止任務(wù)搶占和通過信號(hào)量進(jìn)行資源鎖定。 - 中斷禁止:最強(qiáng)的互斥方法是屏蔽中斷。這樣的鎖定保證了對(duì)CPU的互斥訪問。這種方法當(dāng)然能夠解決互斥的問題,但它對(duì)于實(shí)時(shí)是不恰當(dāng)?shù)?,因?yàn)樗阪i定期間阻止系統(tǒng)響應(yīng)外部事件。長(zhǎng)的中斷延時(shí)對(duì)于要求有確定的響應(yīng)時(shí)間的應(yīng)用來說是不可接受的。
- 搶占禁止:禁止搶占提供了強(qiáng)制性較弱的互斥方式。 當(dāng)前任務(wù)運(yùn)行的過程中不允許其他任務(wù)搶占,而中斷服務(wù)程序可以執(zhí)行。這也可能引起較差的實(shí)時(shí)響應(yīng),就象被禁止中斷一樣,被阻塞的任務(wù)會(huì)有相當(dāng)長(zhǎng)時(shí)間的搶占延時(shí),就緒態(tài)的高優(yōu)先級(jí)的任務(wù)可能會(huì)在能夠執(zhí)行前被強(qiáng)制等待一段不可接受的時(shí)間。為避免這種情況,在可能的情況下盡量使用信號(hào)量實(shí)現(xiàn)互斥。
- 互斥信號(hào)量:信號(hào)量是用于鎖定共享資源訪問的基本方式。不象禁止中斷或搶占,信號(hào)量限制了互斥操作僅作用于相關(guān)的資源。一個(gè)信號(hào)量被創(chuàng)建來保護(hù)資源。VxWorks的信號(hào)量遵循Dijkstra的P()和V()操作模式。
當(dāng)一個(gè)任務(wù)請(qǐng)求信號(hào)量,P()操作根據(jù)在發(fā)出調(diào)用時(shí)信號(hào)量的置位或清零的狀態(tài), 會(huì)發(fā)生兩種情況。如果信號(hào)量處于置位態(tài), 信號(hào)量會(huì)被清零,并且任務(wù)立即繼續(xù)執(zhí)行。如果信號(hào)量處于清零態(tài),任務(wù)會(huì)被阻塞來等待信號(hào)量。 當(dāng)一個(gè)任務(wù)釋放信號(hào)量,V()操作會(huì)發(fā)生幾種情況。如果信號(hào)量已經(jīng)處于置位態(tài),釋放信號(hào)量不會(huì)產(chǎn)生任何影響。如果信號(hào)量處于清零態(tài)且沒有任務(wù)等待該信號(hào)量,信號(hào)量只是被簡(jiǎn)單地置位。如果信號(hào)量處于清零態(tài)且有一個(gè)或多個(gè)任務(wù)等待該信號(hào)量,最高優(yōu)先級(jí)的任務(wù)被解阻塞,信號(hào)量仍為清零態(tài)。 通過將一些資源與信號(hào)量關(guān)聯(lián),能夠?qū)崿F(xiàn)互斥操作。當(dāng)一個(gè)任務(wù)要操作資源,它必須首先獲得信號(hào)量。只要任務(wù)擁有信號(hào)量,所有其他的任務(wù)由于請(qǐng)求該信號(hào)量而被阻塞。當(dāng)一個(gè)任務(wù)使用完該資源,它釋放信號(hào)量,允許等待該信號(hào)量的另一個(gè)任務(wù)訪問該資源。 Wind內(nèi)核提供了二值信號(hào)量來解決互斥操作所引起的問題。 這些問題包括資源擁有者的刪除保護(hù),由資源競(jìng)爭(zhēng)引起的優(yōu)先級(jí)逆轉(zhuǎn): - 刪除保護(hù):互斥引起的一個(gè)問題會(huì)涉及到任務(wù)刪除。在由信號(hào)量保護(hù)的臨界區(qū)中,需要防止執(zhí)行任務(wù)被意外地刪除。刪除一個(gè)在臨界區(qū)執(zhí)行的任務(wù)是災(zāi)難性的。資源會(huì)被破壞,保護(hù)資源的信號(hào)量會(huì)變?yōu)椴豢色@得,從而該資源不可被訪問。通常刪除保護(hù)是與互斥操作共同提供的。由于這個(gè)原因,互斥信號(hào)量通常提供選項(xiàng)來隱含地提供前面提到的任務(wù)刪除保護(hù)的機(jī)制。
- 優(yōu)先級(jí)逆轉(zhuǎn)/優(yōu)先級(jí)繼承:優(yōu)先級(jí)逆轉(zhuǎn)發(fā)生在一個(gè)高優(yōu)先級(jí)的任務(wù)被強(qiáng)制等待一段不確定的時(shí)間以便一個(gè)較低優(yōu)先級(jí)的任務(wù)完成執(zhí)行??紤]下面的假設(shè)(我已經(jīng)在前面的博文中介紹過,這里在啰嗦下O(∩_∩)O):
T1,T2和T3分別是高、中、低優(yōu)先級(jí)的任務(wù)。T3通過擁有信號(hào)量而獲得相關(guān)的資源。當(dāng)T1搶占T3,為競(jìng)爭(zhēng)使用該資源而請(qǐng)求相同的信號(hào)量的時(shí)候,它被阻塞。如果我們假設(shè)T1僅被阻塞到T3使用完該資源為止,情況并不是很糟。畢竟資源是不可被搶占的。然而,低優(yōu)先級(jí)的任務(wù)并不能避免被中優(yōu)先級(jí)的任務(wù)搶占,一個(gè)搶占的任務(wù)如T2將阻止T3完成對(duì)資源的操作。這種情況可能會(huì)持續(xù)阻塞T1等待一段不可確定的時(shí)間。這種情況成為優(yōu)先級(jí)逆轉(zhuǎn),因?yàn)楸M管系統(tǒng)是基于優(yōu)先級(jí)的調(diào)度,但卻使一個(gè)高優(yōu)先級(jí)的任務(wù)等待一個(gè)低優(yōu)先級(jí)的任務(wù)完成執(zhí)行。 互斥信號(hào)量有一個(gè)選項(xiàng)允許實(shí)現(xiàn)優(yōu)先級(jí)繼承的算法。優(yōu)先級(jí)繼承通過在T1被阻塞期間提升T3的優(yōu)先級(jí)到T1解決了優(yōu)先級(jí)逆轉(zhuǎn)引起的問題。這防止了T3,間接地防止T1,被T2搶占。通俗地說,優(yōu)先級(jí)繼承協(xié)議使一個(gè)擁有資源的任務(wù)以等待該資源的任務(wù)中優(yōu)先級(jí)最高的任務(wù)的優(yōu)先級(jí)執(zhí)行。當(dāng)執(zhí)行完成,任務(wù)釋放該資源并返回到它正常的或標(biāo)準(zhǔn)的優(yōu)先級(jí)。因此,繼承優(yōu)先級(jí)的任務(wù)避免了被任何中間優(yōu)先級(jí)的任務(wù)搶占。 同步:信號(hào)量另一種通常的用法是用于任務(wù)間的同步機(jī)制。在這種情況下,信號(hào)量代表一個(gè)任務(wù)所等待的條件或事件。最初,信號(hào)量是在清零態(tài)。一個(gè)任務(wù)或中斷通過置位該信號(hào)量來指示一個(gè)事件的發(fā)生。等待該信號(hào)量的任務(wù)將被阻塞直到事件發(fā)生、該信號(hào)量被置位。一旦被解阻塞,任務(wù)就執(zhí)行恰當(dāng)?shù)氖录幚沓绦颉P盘?hào)量在任務(wù)同步中的應(yīng)用對(duì)于將中斷服務(wù)程序從冗長(zhǎng)的事件處理中解放出來以縮短中斷響應(yīng)時(shí)間是很有用的。 消息隊(duì)列:消息隊(duì)列提供了在任務(wù)與中斷服務(wù)程序或其他任務(wù)間交換變長(zhǎng)消息的一種較低層的機(jī)制。這種機(jī)制在功能上類似于管道,但有較少的開銷。 管道、套接字、遠(yuǎn)程過程調(diào)用和許多高層的vxWorks機(jī)制提供任務(wù)間通信的更高層的抽象,包括管道、TCP/IP套接字、遠(yuǎn)程過程調(diào)用和更多。為了保持裁減內(nèi)核為僅包含足夠支持高層功能的一個(gè)最小函數(shù)集的設(shè)計(jì)目標(biāo),這些特性都是基于上面描述的內(nèi)核同步方式的。 2.4 Wind 內(nèi)核設(shè)計(jì)的優(yōu)點(diǎn)Wind內(nèi)核的一個(gè)重要的設(shè)計(jì)特性是最小的搶占延時(shí)。其他的主要設(shè)計(jì)的優(yōu)點(diǎn)包括史無前例的可配置性,對(duì)不可預(yù)見的應(yīng)用需求的可擴(kuò)展性,在各種微處理器應(yīng)用開發(fā)中的移植性。 最小的搶占延時(shí): 正如前面所討論的,禁止搶占是獲得代碼臨界資源互斥操作的通常手段。這種技巧的不期望的負(fù)面影響是高的搶占延時(shí),這可以通過盡量使用信號(hào)量實(shí)現(xiàn)互斥和保持臨界區(qū)盡量緊湊。但即使廣泛地使用信號(hào)量也不能解決所有的可能導(dǎo)致?lián)屨佳訒r(shí)的根源。內(nèi)核本身就是一個(gè)導(dǎo)致?lián)屨佳訒r(shí)的根源。為了理解其原因,我們必須更好地理解內(nèi)核所需的互斥操作。 內(nèi)核級(jí)和任務(wù)級(jí):在任何多任務(wù)系統(tǒng)中,大量的應(yīng)用是發(fā)生在一個(gè)或多個(gè)任務(wù)的上下文中。然而,有些CPU時(shí)間片不在任何任務(wù)的上下文。這些時(shí)間片發(fā)生在內(nèi)核改變內(nèi)部隊(duì)列或決定任務(wù)調(diào)度。在這些時(shí)間片中,CPU在內(nèi)核級(jí)執(zhí)行而非任務(wù)級(jí)。 為了內(nèi)核安全地操作它的內(nèi)部的數(shù)據(jù)結(jié)構(gòu),必須有互斥操作。內(nèi)核級(jí)沒有相關(guān)的任務(wù)上下文,內(nèi)核不能使用信號(hào)量保護(hù)內(nèi)部鏈表。內(nèi)核使用工作延期作為實(shí)現(xiàn)互斥的方式。當(dāng)有內(nèi)核參與時(shí),中斷服務(wù)程序調(diào)用的函數(shù)不是被直接激活,而是被放在內(nèi)核的工作隊(duì)列中。內(nèi)核完成這些請(qǐng)求的執(zhí)行而清空內(nèi)核工作隊(duì)列。 當(dāng)內(nèi)核正在執(zhí)行已經(jīng)被請(qǐng)求服務(wù)時(shí)系統(tǒng)將不響應(yīng)到達(dá)內(nèi)核的函數(shù)調(diào)用??梢院?jiǎn)單地認(rèn)為內(nèi)核狀態(tài)類似于禁止搶占。如前面所討論的,搶占延時(shí)在實(shí)時(shí)系統(tǒng)中是不期望有的,因?yàn)樗黾恿藢?duì)于會(huì)引起應(yīng)用任務(wù)重新調(diào)度的事件的響應(yīng)時(shí)間。盡管操作系統(tǒng)在內(nèi)核級(jí)(此時(shí)禁止搶占)完全避免消耗時(shí)間是不可能的,但減少這些時(shí)間是很重要的。這是減少由內(nèi)核執(zhí)行的函數(shù)的數(shù)量的主要原因,也是不采用統(tǒng)一結(jié)構(gòu)的系統(tǒng)設(shè)計(jì)方式的原因。 VxWorks顯示了采用任務(wù)級(jí)操作系統(tǒng)服務(wù)設(shè)計(jì)的一個(gè)最小內(nèi)核是能夠滿足需求的。VxWorks是現(xiàn)在能夠獲得的獨(dú)立于任何處理器的、擁有相當(dāng)小內(nèi)核的、功能完全的層次結(jié)構(gòu)的實(shí)時(shí)操作系統(tǒng)。 VxWorks系統(tǒng)在Wind內(nèi)核之上提供了大量的功能。它包括內(nèi)存管理,一個(gè)完整的BSD4.3網(wǎng)絡(luò)包,TCP/IP,網(wǎng)絡(luò)文件系統(tǒng)(NFS),遠(yuǎn)程過程調(diào)用(RPC),UNIX兼容的鏈接加載模塊,C語言的解釋界面,各種類型的定時(shí)器,性能監(jiān)測(cè)組件,調(diào)試工具,額外的通信工具如管道、信號(hào)和套接字,I/O和文件系統(tǒng),和許多功能例程。這些都不是運(yùn)行在內(nèi)核級(jí),所以不會(huì)禁止中斷或任務(wù)搶占。 可配置性: 實(shí)時(shí)應(yīng)用有多種內(nèi)核需求。沒有哪個(gè)內(nèi)核有一個(gè)用來滿足每種需求的很好的設(shè)計(jì)折衷。然而,一個(gè)內(nèi)核可以通過配置來調(diào)整特定的性能特性,裁減實(shí)時(shí)系統(tǒng)來最好地適應(yīng)一個(gè)應(yīng)用的要求。不可預(yù)見的內(nèi)核配置性以用戶可選擇的內(nèi)核排隊(duì)算法的形式提供給應(yīng)用。 排隊(duì)策略:vxWorks中的排隊(duì)庫是獨(dú)立于使用他們的內(nèi)核隊(duì)列功能而執(zhí)行的,這樣提供了將來增加新的排隊(duì)方式的靈活性。 在VxWorks中有各種內(nèi)核隊(duì)列。就緒隊(duì)列是一個(gè)按優(yōu)先級(jí)索引的所有等待調(diào)度的任務(wù)隊(duì)列。滴答隊(duì)列用于定時(shí)功能。信號(hào)量隊(duì)列是一個(gè)等待信號(hào)量的被阻塞任務(wù)的鏈表?;顒?dòng)隊(duì)列是一個(gè)系統(tǒng)中所有任務(wù)的一個(gè)先進(jìn)先出(FIFO)的鏈表。這些隊(duì)列中的每個(gè)隊(duì)列都需要一個(gè)不同的排隊(duì)算法。這些算法不是被內(nèi)嵌在內(nèi)核中,而是被抽取到一個(gè)自治的、可轉(zhuǎn)換的排隊(duì)庫中。這種靈活的組織形式是滿足特殊的配置需求的基礎(chǔ)。 可擴(kuò)展性: 支持不可預(yù)見的內(nèi)核擴(kuò)展的能力與以有功能的可配置性是同樣重要的。簡(jiǎn)單的內(nèi)核接口和互斥方法使內(nèi)核級(jí)功能擴(kuò)展相當(dāng)容易; 在某些情況下,應(yīng)用可以僅利用內(nèi)核鉤子函數(shù)來實(shí)現(xiàn)特定的擴(kuò)展。 內(nèi)部鉤子函數(shù):為了不修改內(nèi)核而能夠向系統(tǒng)增加額外的任務(wù)相關(guān)的功能,VxWorks提供了任務(wù)創(chuàng)建、切換和刪除的鉤子函數(shù)。這些允許在任務(wù)被創(chuàng)建、 上下文切換和任務(wù)被刪除的時(shí)候額外的例程被調(diào)用執(zhí)行。這些鉤子函數(shù)可以利用任務(wù)上下文中的空閑區(qū)創(chuàng)建Wind內(nèi)核的任務(wù)特性。 未來考慮: 有許多系統(tǒng)函數(shù)現(xiàn)在變得越來越重要,而且會(huì)影響到內(nèi)核設(shè)計(jì)時(shí)的搶占延時(shí)。盡管涉及這些問題一個(gè)完整的討論超出了本博文的范圍,但值得簡(jiǎn)單地提一下。 設(shè)計(jì)一個(gè)獨(dú)立于CPU的操作系統(tǒng)一直是一個(gè)挑戰(zhàn)。隨著新的RSIC(精簡(jiǎn)指令集)處理器變得很流行,這些難度也加大了。為了在RISC環(huán)境下有效地執(zhí)行,內(nèi)核和操作系統(tǒng)需要有執(zhí)行不同策略的靈活性。 例如,考慮在任務(wù)切換時(shí)內(nèi)核執(zhí)行的例程。在CISC(復(fù)雜指令集,如680x0或80x86)CPU,內(nèi)核為每個(gè)任務(wù)存儲(chǔ)一套完整的寄存器,在運(yùn)行任務(wù)的時(shí)候?qū)⑦@些寄存器換入換出。在一個(gè)RISC機(jī)器上,這樣是不合理的,因?yàn)樯婕暗教嗟募拇嫫鳌K詢?nèi)核需要一個(gè)更精密復(fù)雜的策略,如為任務(wù)緩存寄存器,允許應(yīng)用指定一些寄存器給特殊的任務(wù)。 移植性:為了使Wind內(nèi)核在他們出現(xiàn)的結(jié)構(gòu)上能夠運(yùn)行,需要有一個(gè)可移植的內(nèi)核版本。這使移植是可行的,但不是最優(yōu)化的。 多處理:支持緊耦合的多處理需求要求實(shí)時(shí)內(nèi)核的內(nèi)部功能包含,在理想情況下,在遠(yuǎn)端請(qǐng)求內(nèi)核調(diào)用,如從一個(gè)處理器到另一個(gè)處理器。這就要涉及到信號(hào)量調(diào)用(為處理器間同步)和任務(wù)調(diào)用(為了控制另一個(gè)CPU上的任務(wù))。這種復(fù)雜性無疑會(huì)增加內(nèi)核級(jí)功能調(diào)用的開銷,但是許多服務(wù)如對(duì)象標(biāo)識(shí)可以在任務(wù)級(jí)執(zhí)行。在多處理系統(tǒng)中保持一個(gè)最小內(nèi)核的優(yōu)點(diǎn)是處理器之間的互鎖可以有較好的時(shí)間粒度。大的內(nèi)核將在內(nèi)核級(jí)消耗額外的時(shí)間,僅能獲得粗糙的互鎖時(shí)間粒度。 實(shí)時(shí)內(nèi)核的重要尺度:許多性能特性被用來比較已有的實(shí)時(shí)內(nèi)核,這些包括: - 快速的任務(wù)上下文切換----由于實(shí)時(shí)系統(tǒng)的多任務(wù)的特性,系統(tǒng)能夠快速地從一個(gè)任務(wù)切換到另一個(gè)任務(wù)是很重要的。在分時(shí)系統(tǒng)中,如UNIX,上下文切換是在ms級(jí)。Wind內(nèi)核執(zhí)行原始上下文切換用us級(jí)來衡量。
- 最小的同步開銷----因?yàn)橥绞菍?shí)現(xiàn)資源互斥訪問的基本方法,這些操作所引起的開銷最小化是很重要的。在vxWorks中,請(qǐng)求和釋放二值信號(hào)量也是用us級(jí)來衡量。
- 最小的中斷延時(shí)----因?yàn)橥獠渴澜鐏淼氖录ǔR灾袛嗟男问降絹?,操作系統(tǒng)快速的處理這些中斷是很重要的。內(nèi)核在操作一些臨界數(shù)據(jù)結(jié)構(gòu)的時(shí)候必須禁止中斷。為了減小中斷延時(shí),必須使這些時(shí)間最小化。Wind內(nèi)核的中斷延時(shí)也是us級(jí)別。
備注:具體的數(shù)值性能指標(biāo),只有在具體的目標(biāo)板上直接測(cè)量后,才能獲取。 搶占延時(shí)對(duì)性能指標(biāo)的影響: 當(dāng)許多的實(shí)時(shí)解決方案被提交給應(yīng)用工程師時(shí), 性能指標(biāo)對(duì)于評(píng)估供應(yīng)商的產(chǎn)品變得越來越重要。不象上下文切換和中斷延時(shí),搶占延時(shí)很難測(cè)量。所以它很少在說明中被提及。但是考慮到當(dāng)內(nèi)核通常禁止上下文切換會(huì)長(zhǎng)達(dá)數(shù)百微妙,而聲稱一個(gè)50us的固定長(zhǎng)度(與任務(wù)個(gè)數(shù)無關(guān))的上下文切換時(shí)間是毫無意義的。除了很難測(cè)量外,搶占延時(shí)可能會(huì)削弱許多性能指標(biāo)的有效性。Wind內(nèi)核通過減小內(nèi)核的大小來盡量減小搶占延時(shí)。 包含繁多功能的內(nèi)核必將引起長(zhǎng)的搶占延時(shí)。 此致,Wind內(nèi)核我做了一個(gè)粗粒度的介紹,接下來的文章,我將就Wind內(nèi)核具體方面,結(jié)合代碼來詳細(xì)的闡述。。。。O(∩_∩)O
|