本文首先從實時內核的定義出發(fā),對實時操作系統(tǒng)進行了介紹,并對實時操作系統(tǒng)的特點進行了說明,接著從內核的功能和結構角度介紹了整體式內核,層次式內核,以及微內核。最后對具有微內核特性的VxWorks Wind內核進行了介紹。
“實時”表示控制系統(tǒng)能夠及時處理系統(tǒng)中發(fā)生的要求控制的外部事件。從事件發(fā)生到系統(tǒng)產(chǎn)生響應的反應時間稱為延遲(Latency)。對于實時系統(tǒng),一個最重要的條件就是延遲有確定的上界(這樣的系統(tǒng)屬于確定性系統(tǒng))。滿足這個條件后,根據(jù)這個上界大小再區(qū)分不同實時系統(tǒng)的性能。這里的“系統(tǒng)”是從系統(tǒng)論的觀點講的一個功能完整的設計,能夠獨立和外部世界交互、實現(xiàn)預期功能。這包括實時硬件系統(tǒng)設計、實時操作系統(tǒng)設計、實時多任務設計3部分。后兩者可以概括為實時軟件系統(tǒng)設計。實現(xiàn)實時系統(tǒng)是這3部分有機結合的結果。
從另外一個角度,即實時程度看,可以把系統(tǒng)分為硬實時系統(tǒng)和軟實時系統(tǒng)。硬實時系統(tǒng)是這樣一種系統(tǒng),它的時間要求有一個確定的截止期限(Deadline),超出截止期限的響應,即是計算無誤,也是無法容忍的錯誤結果,通常會引起嚴重的后果,這樣的系統(tǒng)屬于硬實時系統(tǒng)。對于軟實時系統(tǒng)來說,“實時性”僅僅是“程度”概念,在提交諸如中斷、計時和調度的操作系統(tǒng)服務時,系統(tǒng)定義一個時間范圍內的延遲。在該范圍內,越早給出響應越有價值,只要不超出范圍,晚點給出的結果價值下降,但可以容忍。
因此一個RTOS內核必須滿足許多特定的實時環(huán)境所提出的基本要求,這些包括:
實時硬件系統(tǒng)設計是其它兩部分的基礎。實時硬件系統(tǒng)設計要求在滿足軟件系統(tǒng)充分高效的前提下,必須提供足夠的處理能力。例如,硬件系統(tǒng)提供的中斷處理邏輯能同時響應的外部事件數(shù)量、硬件反應時間、內存大小、處理器計算能力、總線能力等,以保證最壞情況下所有計算仍然得以完成。多處理的硬件系統(tǒng)還包括內部通信速率設計。當硬件系統(tǒng)不能保證達到實時要求時,可以確信整個系統(tǒng)不是實時的。目前,各種硬件速度不斷提高,先進技術大量涌現(xiàn),硬件在大多數(shù)應用中已經(jīng)不是實時系統(tǒng)的瓶頸。因而,實時系統(tǒng)的關鍵集中在實時軟件系統(tǒng)設計,這方面也成了實時性研究的主要內容,也是最復雜的部分。許多場合甚至對實時硬件系統(tǒng)和實時操作系統(tǒng)不加區(qū)分。
先來看實時操作系統(tǒng)性能評價的幾個主要指標:
從實時性角度看,操作系統(tǒng)經(jīng)歷了前后臺系統(tǒng)、分時操作系統(tǒng)和實時操作系統(tǒng)3個階段。
前后臺系統(tǒng)(Foreground/Background System)其實沒有操作系統(tǒng),系統(tǒng)中只運行一個無限主循環(huán),沒有多任務的概念,但是通過中斷服務程序響應外部事件。在前后臺系統(tǒng)中,對外部事件的實時響應特性從兩方面看。
分時操作系統(tǒng)(Time-sharing Operating System)將系統(tǒng)計算能力分成時間片,按照一定的策略分配給各個任務,通常在分配過程中追求某種意義上的公平,分時操作系統(tǒng)不保證實時性。
實時操作系統(tǒng)(RTOS)的目的是實現(xiàn)對外部事件的實時響應,即根據(jù)前面對實時性的定義,實時操作系統(tǒng)必須在確定的時間內給出響應。實時操作系統(tǒng)必須滿足下面4個條件:
1.2優(yōu)先級反轉示意圖
上述問題的一種解決方法是使用優(yōu)先級繼承協(xié)議(Priority Inheritance Protocol)。當高優(yōu)先級任務需要低優(yōu)先級任務占用資源時,將低優(yōu)先級任務的優(yōu)先級別提高到和高優(yōu)先級同樣的級別,即相當于低優(yōu)先級任務繼承高優(yōu)先級任務的優(yōu)先級級別;防止優(yōu)先級翻轉的另外一種協(xié)議是優(yōu)先級天花板(Priority Ceiling),其設計策略是對優(yōu)先級翻轉采取“預防”,而不是“補救”。也就是說:不論是否阻塞了高優(yōu)先級任務,持有該協(xié)議的任務在執(zhí)行期間都被賦予優(yōu)先級天花板所占用的優(yōu)先級,以使任務盡快完成操作,因此可以把任務優(yōu)先級天花板看作是更“積極”的一種保護優(yōu)先級的方式,我們在后面的博文中將會詳細分析者兩種方案的設計與實現(xiàn)。
滿足上面4個必要條件后,RTOS內核具體的實現(xiàn)機制就決定了其實時性的優(yōu)劣。VxWorks的Wind內核是一個真正的實時微內核,滿足上述條件。同時wind內核采取單一實時地址空間,任務切換開銷非常低,相當于在UNIX這樣的主機上切換到相同進程內的另一個線程,并且沒有系統(tǒng)調用開銷。高效的實時設計使Wind內核在從工業(yè)現(xiàn)場控制到國防、航空等眾多領域中表現(xiàn)出優(yōu)秀的實時性(嚴格的說用在航空領域的是VxWorks 653版本)。
傳統(tǒng)上,一個操作系統(tǒng)分為核心態(tài)和用戶態(tài)。內核在核心態(tài)運行,為用戶態(tài)的應用程序提供服務。內核是操作系統(tǒng)的靈魂和中心,決定了操作系統(tǒng)的效率和應用領域。在設計操作系統(tǒng)時,內核包含哪些功能以及內核功能采取何種組織結構,都是由設計者決定的。從內核功能和結構特點看,操作系統(tǒng)具有單體式內核、層次式內核、微內核三種不同形式。
單體式內核以過程集合的方式編寫,鏈接成一個大型可執(zhí)行的二進制程序。使用這種技術,系統(tǒng)中的每一個過程可以自由調動其它過程,只有后者提供了前者需要的一些有用的計算工作。這些可以不受限制,彼此調用的成千個過程,常常導致出現(xiàn)一個笨拙且難以理解的系統(tǒng)。單體式內核結構的操作系統(tǒng)不進行任何的數(shù)據(jù)封裝和隱藏,在具有較高效率的同時,存在著難以擴展和升級的缺點。
層次式內核結構的操作系統(tǒng)將模塊功能劃分為不同層次,下層模塊封裝內部細節(jié),上層模塊調用下層模塊提供的接口。Unix,Linux,Multics等屬于層次結構操作系統(tǒng)。層次化使操作系統(tǒng)結構簡單,易于調試和擴展。單體式內核和層次式內核結構如圖1.3所示。
1.3整體式內核和層次式內核結構圖
不管單體式結構,還是層次式結構,它們的操作系統(tǒng)都包括了許多將其用于各種可能領域時需要的功能,故被稱為宏內核(Monolithic kernel)操作系統(tǒng),整個核心程序都是以核心空間(Kernel Space)的身份及監(jiān)管者(也稱特權)模式(Supervisor Mode)來運行,以至于可以認為該內核本身便是一個完整的操作系統(tǒng)。以UNIX為例,其內核包括了進程管理、文件系統(tǒng)、設備管理、網(wǎng)絡通信等功能,用戶層僅僅提供一個操作系統(tǒng)外殼和一些實用工具程序。
用層次式方法設計操作系統(tǒng),設計者需要確定在哪里劃分內核-用戶的邊界。在傳統(tǒng)上,所有的層都在內核中,但是這樣做是沒有必要的。事實上,盡可能減少內核態(tài)功能的做法更好,因為內核中的錯誤會快速拖累系統(tǒng);相反可以把用戶級任務設置位較小的權限,這樣某一個錯誤的后果將不是致命的。微內核的設計思想是,為了實現(xiàn)其高可靠性,將操作系統(tǒng)劃分為小的、定義良好的模塊,只有其中一個模塊(微內核模塊)運行在內核態(tài)上,其余的模塊由于功能相對較弱,則作為普通用戶任務運行。特別的是地,由于把每個設備驅動和文件系統(tǒng)分別作為普通任務,這些模塊中的錯誤雖然會使得這些模塊崩潰,但不會使得整個系統(tǒng)死機。例如在音頻驅動中的錯誤會使得聲音斷續(xù)或者停止,但是不會使這個計算機系統(tǒng)崩潰。相反在宏內核操作系統(tǒng)中,由于所有的設備驅動都在內核中,一個有故障的音頻驅動很容易導致無效的地址引用,進而造成惱人的系統(tǒng)停機。
有許多微內核已經(jīng)實現(xiàn)并投入應用。微內核在實時、工業(yè)、航空以及軍事應用中特別流行,因為這些領域都是關鍵任務,需要有高度的可靠性。因此嵌入式操作系統(tǒng)大多采用微內核結構。微內核操作系統(tǒng)是近二十年新發(fā)展起來的技術,內核非常小但效率高,從數(shù)十KB到數(shù)百KB字節(jié),適合于資源相對有限的嵌入式應用。微內核將很多通用操作的功能從內核中分離出來(如文件系統(tǒng),設備驅動,網(wǎng)絡協(xié)議棧等),只保留最基本的內容。知名的內核有Green Hills Software公司開發(fā)的INTEGRITY實時操作系統(tǒng),windriver系統(tǒng)公司開發(fā)的vxWorks,黑莓手機(BlackBerry)制造商RIM(Research In Motion Ltd.,RIM)使用的QNX實時系統(tǒng),以及L4、PikeOS、Minix3等。
備注:從微內核模塊運行在CPU核心態(tài)上,其它模塊運行在非核心態(tài),這個角度來說,VxWorks的Wind內核并不能算是嚴格意義上的微內核系統(tǒng)。Wind內核通過全局變量kernelState模擬了Wind內核的特權態(tài)。Wind內核中以wind*開頭的例程構成Wind內核的核心服務例程。當kernelState為FALSE時,意味著Wind內核此時沒有程序訪問,VxWorks的外圍模塊可以調試Wind內核的核心服務例程;當kernelState為TRUE時,意味著其它程序正在使用內核態(tài)例程,當前需要調用核心服務例程的程序必須放置到延遲隊列中,直到處于核心態(tài)的程序退出內核態(tài)(即kernelState為FALSE),延遲的內核態(tài)例程才會被執(zhí)行,從這里我們可以看出,kernelState模擬的核心態(tài)是非搶占式的。VxWorks的wind內核采用全局變量模擬了核心態(tài)服務例程,在加上其高度的可配置型,也具有一般微內核操作系統(tǒng)所具有的的特性。
一般認為微內核操作系統(tǒng)具有如下優(yōu)點:
由于操作系統(tǒng)核心常駐內存,而微內核結構精簡了操作系統(tǒng)的核心功能,內核規(guī)模比較小,一些功能都移到了外存上,所以微內核結構十分適合嵌入式的專用系統(tǒng),如圖1-4所示的VxWorks系統(tǒng)結構,大家可以直觀的感受到Wind內核在VxWorks系統(tǒng)中的地位O(∩_∩)O。
圖1-4 VxWorks系統(tǒng)結構
為了提高微內核效率,有兩種實現(xiàn)模式:受保護的虛地址空間模式和無保護的單一實地址空間模式。前者在宏內核操作系統(tǒng)(如Unix)和某些微內核操作系統(tǒng)(如QNX,Minix3)中采用。這種模式的優(yōu)點是顯而易見的:任務獨立運行、不受其他任務錯誤影響、系統(tǒng)可靠性高。
VxWorks的Wind內核采取單一實地址空間模式,所有任務在同一地址空間運行,不區(qū)分核心態(tài)和用戶態(tài)。其優(yōu)勢在于:
備注:系統(tǒng)調用需要從用戶態(tài)切換到核心態(tài),以執(zhí)行用戶態(tài)下不能執(zhí)行的操作,在許多處理器上這是通過一條等價于系統(tǒng)調用的TRAP指令實現(xiàn)的,在執(zhí)行該指令前要經(jīng)過嚴格的參數(shù)檢查。VxWorks中不存在這樣的切換,因此系統(tǒng)調用和一般函數(shù)調用沒有什么差別。但本系列博文中仍然沿用一般說法。
對于兩種模式孰優(yōu)孰劣,各自的支持者們進行了大量的爭論。比較各有所長的東西往往非常困難。本文傾向于認為,對于嵌入式實時應用,單一實地址模式要合適一些。許多實踐也證明,依靠虛地址保護來提高可靠性總存在局限性,畢竟程序運行出了錯誤,從某種程度上說虛地址保護只是使已經(jīng)出現(xiàn)的錯誤經(jīng)過一個延遲、積累和放大的過程,用過Windows就會有這種感觸。而經(jīng)過大量關鍵應用檢驗的VxWorks操作系統(tǒng),則被充分證明是高度可靠的(當然了,可靠的系統(tǒng)必須由可靠的操作系統(tǒng)和可靠的應用系統(tǒng)組成)。
層次結構的Wind內核僅提供多任務環(huán)境、進程間通信和同步功能的服務例程。這些服務例程足夠支持VxWorks在較高層次所提供的豐富性能的要求。VxWorks的Wind內核操作對于用戶是不可見的。應用程序為了實現(xiàn)需要內核參與的任務管理和同步使用一些系統(tǒng)調用,但這些調用的處理對于調用任務是不可見的。應用程序僅鏈接恰當?shù)腣xWorks例程(通常使用VxWorks的動態(tài)鏈接功能),就象調用子程序一樣發(fā)出系統(tǒng)調用。這種接口不象Linux內核需要一個跳轉表接口,用戶需要通過一個整數(shù)來指定一個內核功能調用。
VxWorks采用類和對象的思想將Wind內核分成5個組成部分:任務管理模塊、內存管理模塊、消息隊列管理模塊、信號量管理模塊、以及看門狗管理模塊。
備注:除了上面的五個模塊之后,還有虛擬內存管理接口(VxVMI)模塊和TTY環(huán)形緩沖區(qū)管理模塊也是Wind內核用類和對象思想管理的兩個模塊。虛擬內存接口模塊(VxVMI)是VxWorks的一個功能模塊,它利用用戶片上或板上的內存管理單元(MMU),為用戶提供了對內存的高級管理功能;TTY環(huán)形緩沖區(qū)管理模塊是ttyDrv設備的核心,ttyDrv設備稱為虛擬設備,處在I/O系統(tǒng)和真正驅動程序之間形成了一個轉換層,為VxWorks提供了一個標準的I/O接口,一個虛擬ttyDrv設備可以管理多個串行設備驅動程序。這兩個模塊嚴格意義上來說并不是一個RTOS內核理論上的組成部分,因此才不把它們列在Wind內核的組成部分上。
在wind內核中,所有的對象都是類的組成部分,類定義了操作對象的方法(Method),同時維護著對所有對象的操作記錄。Wind內核采用了c++的語義,但是采用c語言來實現(xiàn)。整個Wind內核通過顯式編碼實現(xiàn),其編譯過程并不依賴于具體的編譯器。這意味著Wind內核不但可以在vxWorks自帶的diab編譯上編譯,也可以使用開源的gnu/gcc編譯器。VxWorks為Wind內核設計了一個元類(Meta-class),所有的對象類(Obj-class)都是基于該元類。每個對象類只負責維護各自對象(Object)的操作方法(比如創(chuàng)建對象、初始化對象、注銷對象等)、以及管理統(tǒng)計記錄(比如一個創(chuàng)建對象的數(shù)據(jù)、銷毀對象的數(shù)目等)。圖1.5實現(xiàn)了元類、對象類、以及對象之間的邏輯關系。
圖1-5 元類、對象類、對象間關系圖
備注:每次畫這種類和對象關系圖的時候,我就異常的糾結。因為在wind內核的設計中,元類classClass有一個ID號classClassId,每個對象類X-objClass也有一個ID號X-objClassId。在C語言的實現(xiàn)中classClassId和X-objClassId都是指針變量,存放的是相應類的地址。在初始化對象類和對象時,對象類和對象的objCore域存放的該指針變量的值(即相應類的地址),跟classClassId沒有太大的關系。圖1.5真實地反應了objCore存放的類地址這個真實的關系。
如果從邏輯上來看的話,圖1.6看起來更舒服,雖然從C語言實現(xiàn)來說,classClassId和X-objClassId的作用是錯誤的,但是從邏輯上看圖1.6能更清晰的描述問題(并且圖也更美觀O(∩_∩)O),雖然圖1.6上objCore存放的指向類地址的指針。正因為如此,在畫類和對象關系圖時,我采用圖1-6所示的方式。
圖1-6 元類、對象類、對象間關系圖
正如圖1-5,圖1-6所示的那樣每個對象類都指向元類classClass,每個對象類只負責管理各自的對象。Wind內核完整的元類、對象類、以及對象間邏輯關鍵,見圖1-7。
圖1-7 wind內核各個組成模塊間對象類、對象和元類的關系
備注:類管理模式不是Wind內核的特性,從功能上來說它僅僅是Wind內核組織各個模塊的手段,所有內核模塊的對象類、類對象都依賴于它。VxWorks采用類及對象來組織操作系統(tǒng)的結構,一個最重要的優(yōu)勢是增加了代碼的安全性,即在創(chuàng)建新的對象類和對象、以及刪除對象類和對象都可以對對象類、對象進行驗證。
VxWorks的Wind內核自然具有1.2節(jié)所描述的所有RTOS所共有的四個特性,其所有特點可以概括如下:
備注:本系列博文接下來的部分將詳細分析wind內核如何進行設計,以具有這些特性。
再廢話幾句O(∩_∩)O:我在分析Wind內核時所秉持的宗旨是策略(Mechanism)和機制(Policy)相分離的原則,策略(Mechanism)和機制(Policy)相分離是微內核設計的指導思想,換句話說微內核操作系統(tǒng)設計的指導原則是提供機制而不是策略。為了更清楚地說明這一點,我們以任務調度為例。一個簡單的調度算法是為每一個任務賦予一個優(yōu)先級,并讓內核執(zhí)行具有最高優(yōu)先級的就緒任務。在這個例子中,機制(Mechanism)是在內核中尋找最高優(yōu)先級的就緒任務并運行之;而策略(Policy)則是賦予任務相應的優(yōu)先級。換句話說機制負責提供什么樣的功能,策略則負責如何使用這些功能。策略和機制相分離指導思想可以使操作系統(tǒng)內核變得更小,更穩(wěn)定。正如一句話說的好“一個優(yōu)美的內核不是還有什么樣的功能還可以增加,而是還有什么樣的功能還可以減少”(哥們忘記是誰說的了⊙﹏⊙b汗)。
本系列博文力求在分析研究Wind內核的同時,思考RTOS的內核設計思想源泉。VxWorks的Wind內核經(jīng)歷了近20年的發(fā)展完善,達到目前的穩(wěn)定狀態(tài)。采用目前的這種設計、一定有其內部的考量,我希望盡可能的從一個系統(tǒng)設計者的角度來分析Wind內核的設計思想、工作機制、以及具有的特性,為我們設計一個款優(yōu)秀的RTOS內核提供借鑒!
待續(xù)......O(∩_∩)O哈哈~