VxWorks內核解讀-1





目錄(?)[-]

    1.   11實時內核概述
      1. 1  實時硬件系統設計
      2. 1  實時操作系統設計
    2. 12微內核操作系統設計理念
    3. 13 wind微內核設計
    4. 14 Wind內核類設計思想
    5. 15 Wind內核的特性

前言:我曾經在做VxWorks培訓期間跟身邊的嵌入式工程師同行交流的時候,發現大家對嵌入式VxWorks系統的Wind內核不是特別瞭解,而網上對於VxWorks的Wind內核也沒有系統性的解讀與分析,因此我決定發表一系列的博文來系統性地解讀Wind內核的設計思想。我選擇的是VxWorks5.5系統的Wind 2.6版本內核(這個版本的代碼網上都有分享O(∩_∩)O),在分析的過程中,大家有任何的疑問,都可以給我留言,以便我進一步的完善博文,使得後來者閱讀起來更爲流暢。

本文首先從實時內核的定義出發,對實時操作系統進行了介紹,並對實時操作系統的特點進行了說明,接着從內核的功能和結構角度介紹了整體式內核,層次式內核,以及微內核。最後對具有微內核特性的VxWorks Wind內核進行了介紹。

1.1實時內核概述

“實時”表示控制系統能夠及時處理系統中發生的要求控制的外部事件。從事件發生到系統產生響應的反應時間稱爲延遲(Latency)。對於實時系統,一個最重要的條件就是延遲有確定的上界(這樣的系統屬於確定性系統)。滿足這個條件後,根據這個上界大小再區分不同實時系統的性能。這裏的“系統”是從系統論的觀點講的一個功能完整的設計,能夠獨立和外部世界交互、實現預期功能。這包括實時硬件系統設計、實時操作系統設計、實時多任務設計3部分。後兩者可以概括爲實時軟件系統設計。實現實時系統是這3部分有機結合的結果。

從另外一個角度,即實時程度看,可以把系統分爲硬實時系統和軟實時系統。硬實時系統是這樣一種系統,它的時間要求有一個確定的截止期限(Deadline),超出截止期限的響應,即是計算無誤,也是無法容忍的錯誤結果,通常會引起嚴重的後果,這樣的系統屬於硬實時系統。對於軟實時系統來說,“實時性”僅僅是“程度”概念,在提交諸如中斷、計時和調度的操作系統服務時,系統定義一個時間範圍內的延遲。在該範圍內,越早給出響應越有價值,只要不超出範圍,晚點給出的結果價值下降,但可以容忍。

因此一個RTOS內核必須滿足許多特定的實時環境所提出的基本要求,這些包括:

  • 多任務:由於真實世界的事件的異步性,能夠運行許多併發進程或任務是很重要的。多任務提供了一個較好的對真實世界的匹配,因爲它允許對應於許多外部事件的多線程執行。系統內核分配CPU給這些任務來獲得併發性。
  • 搶佔調度:真實世界的事件具有繼承的優先級,在分配CPU的時候要注意到這些優先級。基於優先級的搶佔調度,任務都被指定了優先級, 在能夠執行的任務(沒有被掛起或正在等待資源)中,優先級最高的任務被分配CPU資源。換句話說,當一個高優先級的任務變爲可執行態(Wind內核中稱爲就緒態Ready State),它會立即搶佔當前正在運行的較低優先級的任務。
  • 快速靈活的任務間的通信與同步:在一個實時系統中,可能有許多任務作爲一個應用的一部分執行。系統必須提供這些任務間的快速且功能強大的通信機制。內核也要提供爲了有效地共享不可搶佔的資源或臨界區所需的同步機制。
  • 方便的任務與中斷之間的通信:儘管真實世界的事件通常作爲中斷方式到來,但爲了提供有效的排隊、優先化和減少中斷延時,我們通常希望在任務級處理相應的工作(uC/OS-III內核採用了這種策略)。所以需要任務級和中斷級之間存在通信。
  • 性能邊界:一個實時內核必須提供最壞情況的性能優化,而非針對吞吐量的性能優化。我們更期望一個系統能夠始終以50微妙(us)執行一個函數,而不期望系統平均以10微妙(us)執行該函數,但偶爾會以75微妙(us)執行它。
  • 特殊考慮:由於對實時內核的要求的增加,必須考慮對內核支持不斷增加的複雜功能的要求。這包括多進程處理(比如VxWorks RTP),對更新的、功能更強的處理器結構(比如Multicore CPU)的支持。

1.  實時硬件系統設計

實時硬件系統設計是其它兩部分的基礎。實時硬件系統設計要求在滿足軟件系統充分高效的前提下,必須提供足夠的處理能力。例如,硬件系統提供的中斷處理邏輯能同時響應的外部事件數量、硬件反應時間、內存大小、處理器計算能力、總線能力等,以保證最壞情況下所有計算仍然得以完成。多處理的硬件系統還包括內部通信速率設計。當硬件系統不能保證達到實時要求時,可以確信整個系統不是實時的。目前,各種硬件速度不斷提高,先進技術大量涌現,硬件在大多數應用中已經不是實時系統的瓶頸。因而,實時系統的關鍵集中在實時軟件系統設計,這方面也成了實時性研究的主要內容,也是最複雜的部分。許多場合甚至對實時硬件系統和實時操作系統不加區分。

1.  實時操作系統設計

先來看實時操作系統性能評價的幾個主要指標:

  • 中斷延遲時間:對一個實時操作系統來說,最重要的指標就是中斷關了多長時間,所有實時系統在進入臨界區代碼段之前都要關中斷,執行完臨界代碼之後再開中斷。關中斷的時間越長,中斷延遲就越長。因此中斷延遲時間可以表述爲關中斷的最長時間與開始執行中斷服務子程序第一條指令的時間之和,有時也表述爲從系統接收中斷信號到操作系統做出響應,進入中斷服務程序的時間。
  • 中斷響應時間:中斷響應時間定義爲從中斷髮生到開始執行用戶中斷服務子程序代碼來處理這個中斷的時間。中斷響應時間包括開始處理這個中斷前的全部開銷。中斷響應時間包含了中斷延遲時間,因此在考慮一個實時系統對外部中斷的處理時間時,通常指考慮中斷響應時間。典型地將執行用戶代碼之前保護現場,將CPU 的各寄存器推入堆棧的時間記爲中斷響應時間。
  • 任務切換時間:多任務之間進行切換所花費的時間,即從前一個任務開始保存上下文的第一條指令開始,到後一個任務恢復上下文開始運行第一條指令爲止的時間段。

從實時性角度看,操作系統經歷了前後臺系統、分時操作系統和實時操作系統3個階段。

前後臺系統(Foreground/Background System)其實沒有操作系統,系統中只運行一個無限主循環,沒有多任務的概念,但是通過中斷服務程序響應外部事件。在前後臺系統中,對外部事件的實時響應特性從兩方面看。

  • 中斷延遲時間:主循環一般保持中斷開放狀態,因此前後臺系統中斷響應非常快,並且通常允許嵌套;
  • 中斷響應時間:需要經歷一次主循環才能對中斷服務程序中採集的外部請求進行處理,因此係統響應時間決定於主循環週期。

分時操作系統(Time-sharing Operating System)將系統計算能力分成時間片,按照一定的策略分配給各個任務,通常在分配過程中追求某種意義上的公平,分時操作系統不保證實時性。

實時操作系統(RTOS)的目的是實現對外部事件的實時響應,即根據前面對實時性的定義,實時操作系統必須在確定的時間內給出響應。實時操作系統必須滿足下面4個條件:

  • 可搶佔式的優先級調度內核,當一個運行着的任務使一個比它優先級高的任務進入了就緒態,當前任務的CPU 使用權就被剝奪了,或者說被掛起了,那個高優先級的任務立刻得到了CPU的控制權,即始終保證優先級最高的任務擁有CPU使用權,如圖1.1所示

VxWorks內核解讀-1

  • 中斷具有優先級,且中斷可嵌套,即高優先級的中斷可以打斷正在執行的低優先級中斷處理程序,優先得到執行,等到其處理完畢再回到低優先級的任務繼續執行,
  • 防止優先級反轉,系統服務的優先級由請求該服務的任務的優先級確定,具有優先級保護機制,以防止優先級翻轉;優先級翻轉式指當一個高優先級的任務被迫等待一個低優先級的任務不確定的完成時間的時候,優先級反轉將會發生。考慮下面的情景:任務T1、T2、T3是三個優先級依次降低的任務。T3已經通過獲取與保護資源相關的信號量,從而獲取了這些資源。當T1搶佔T3通過獲取相同的信號量來競爭這些資源的時候,T3將會被阻塞。如果我們能夠保證T1阻塞的時間不會長於T3正在執行後釋放這些資源的時間,情況不會發生特別嚴重,畢竟T1佔用的這個資源是不可搶佔的。但是低優先級的任務是脆弱的,通常會被中等優先級的任務所搶佔。例如此時的T2,這將會使T3無法釋放T1需要的資源。這種情況將會一直存在,將會使得處於最高優先級的T1阻塞的時間不確定。示意圖如1.2。

VxWorks內核解讀-1

1.2優先級反轉示意圖

上述問題的一種解決方法是使用優先級繼承協議(Priority Inheritance Protocol)。當高優先級任務需要低優先級任務佔用資源時,將低優先級任務的優先級別提高到和高優先級同樣的級別,即相當於低優先級任務繼承高優先級任務的優先級級別;防止優先級翻轉的另外一種協議是優先級天花板(Priority Ceiling),其設計策略是對優先級翻轉採取“預防”,而不是“補救”。也就是說:不論是否阻塞了高優先級任務,持有該協議的任務在執行期間都被賦予優先級天花板所佔用的優先級,以使任務儘快完成操作,因此可以把任務優先級天花板看作是更“積極”的一種保護優先級的方式,我們在後面的博文中將會詳細分析者兩種方案的設計與實現。

  •  實時操作系統(RTOS)的性能評價指標(中斷響應時間和任務切換時間)具有固定上界。

滿足上面4個必要條件後,RTOS內核具體的實現機制就決定了其實時性的優劣。VxWorks的Wind內核是一個真正的實時微內核,滿足上述條件。同時wind內核採取單一實時地址空間,任務切換開銷非常低,相當於在UNIX這樣的主機上切換到相同進程內的另一個線程,並且沒有系統調用開銷。高效的實時設計使Wind內核在從工業現場控制到國防、航空等衆多領域中表現出優秀的實時性(嚴格的說用在航空領域的是VxWorks 653版本)。

1.2微內核操作系統設計理念

傳統上,一個操作系統分爲核心態和用戶態。內核在覈心態運行,爲用戶態的應用程序提供服務。內核是操作系統的靈魂和中心,決定了操作系統的效率和應用領域。在設計操作系統時,內核包含哪些功能以及內核功能採取何種組織結構,都是由設計者決定的。從內核功能和結構特點看,操作系統具有單體式內核、層次式內核、微內核三種不同形式。

單體式內核以過程集合的方式編寫,鏈接成一個大型可執行的二進制程序。使用這種技術,系統中的每一個過程可以自由調動其它過程,只有後者提供了前者需要的一些有用的計算工作。這些可以不受限制,彼此調用的成千個過程,常常導致出現一個笨拙且難以理解的系統。單體式內核結構的操作系統不進行任何的數據封裝和隱藏,在具有較高效率的同時,存在着難以擴展和升級的缺點。

層次式內核結構的操作系統將模塊功能劃分爲不同層次,下層模塊封裝內部細節,上層模塊調用下層模塊提供的接口。Unix,Linux,Multics等屬於層次結構操作系統。層次化使操作系統結構簡單,易於調試和擴展。單體式內核和層次式內核結構如圖1.3所示。

VxWorks內核解讀-1

1.3整體式內核和層次式內核結構圖

不管單體式結構,還是層次式結構,它們的操作系統都包括了許多將其用於各種可能領域時需要的功能,故被稱爲宏內核(Monolithic kernel)操作系統,整個核心程序都是以核心空間(Kernel Space)的身份及監管者(也稱特權)模式(Supervisor Mode)來運行,以至於可以認爲該內核本身便是一個完整的操作系統。以UNIX爲例,其內核包括了進程管理、文件系統、設備管理、網絡通信等功能,用戶層僅僅提供一個操作系統外殼和一些實用工具程序。

用層次式方法設計操作系統,設計者需要確定在哪裏劃分內核-用戶的邊界。在傳統上,所有的層都在內核中,但是這樣做是沒有必要的。事實上,儘可能減少內核態功能的做法更好,因爲內核中的錯誤會快速拖累系統;相反可以把用戶級任務設置位較小的權限,這樣某一個錯誤的後果將不是致命的。微內核的設計思想是,爲了實現其高可靠性,將操作系統劃分爲小的、定義良好的模塊,只有其中一個模塊(微內核模塊)運行在內核態上,其餘的模塊由於功能相對較弱,則作爲普通用戶任務運行。特別的是地,由於把每個設備驅動和文件系統分別作爲普通任務,這些模塊中的錯誤雖然會使得這些模塊崩潰,但不會使得整個系統死機。例如在音頻驅動中的錯誤會使得聲音斷續或者停止,但是不會使這個計算機系統崩潰。相反在宏內核操作系統中,由於所有的設備驅動都在內核中,一個有故障的音頻驅動很容易導致無效的地址引用,進而造成惱人的系統停機。

有許多微內核已經實現並投入應用。微內核在實時、工業、航空以及軍事應用中特別流行,因爲這些領域都是關鍵任務,需要有高度的可靠性。因此嵌入式操作系統大多采用微內核結構。微內核操作系統是近二十年新發展起來的技術,內核非常小但效率高,從數十KB到數百KB字節,適合於資源相對有限的嵌入式應用。微內核將很多通用操作的功能從內核中分離出來(如文件系統,設備驅動,網絡協議棧等),只保留最基本的內容。知名的內核有Green Hills Software公司開發的INTEGRITY實時操作系統,windriver系統公司開發的vxWorks,黑莓手機(BlackBerry)製造商RIM(Research In Motion Ltd.,RIM)使用的QNX實時系統,以及L4、PikeOS、Minix3等。

備註:從微內核模塊運行在CPU核心態上,其它模塊運行在非核心態,這個角度來說,VxWorks的Wind內核並不能算是嚴格意義上的微內核系統。Wind內核通過全局變量kernelState模擬了Wind內核的特權態。Wind內核中以wind*開頭的例程構成Wind內核的核心服務例程。當kernelState爲FALSE時,意味着Wind內核此時沒有程序訪問,VxWorks的外圍模塊可以調試Wind內核的核心服務例程;當kernelState爲TRUE時,意味着其它程序正在使用內核態例程,當前需要調用核心服務例程的程序必須放置到延遲隊列中,直到處於核心態的程序退出內核態(即kernelState爲FALSE),延遲的內核態例程纔會被執行,從這裏我們可以看出,kernelState模擬的核心態是非搶佔式的。VxWorks的wind內核採用全局變量模擬了核心態服務例程,在加上其高度的可配置型,也具有一般微內核操作系統所具有的的特性

一般認爲微內核操作系統具有如下優點:

  •  統一的接口,在用戶態和核心態之間無需進行識別;
  • 可伸縮性好,易於擴充,能適應硬件更新和應用變化;
  • 可移植性好,操作系統要移植到不同的硬件平臺上,只需修改微內核中極少代碼即可;
  • 實時性好,內核響應速度快,可以方便地支持實時處理;
  • 安全可靠性高,微內核將安全性作爲系統內部特性來進行設計,對外僅使用少量應用編程接口。

由於操作系統核心常駐內存,而微內核結構精簡了操作系統的核心功能,內核規模比較小,一些功能都移到了外存上,所以微內核結構十分適合嵌入式的專用系統,如圖1-4所示的VxWorks系統結構,大家可以直觀的感受到Wind內核在VxWorks系統中的地位O(∩_∩)O。

VxWorks內核解讀-1

圖1-4 VxWorks系統結構

1.3 wind微內核設計

爲了提高微內核效率,有兩種實現模式:受保護的虛地址空間模式和無保護的單一實地址空間模式。前者在宏內核操作系統(如Unix)和某些微內核操作系統(如QNX,Minix3)中採用。這種模式的優點是顯而易見的:任務獨立運行、不受其他任務錯誤影響、系統可靠性高。

VxWorks的Wind內核採取單一實地址空間模式,所有任務在同一地址空間運行,不區分核心態和用戶態。其優勢在於:

  • 任務切換時不需要進行虛擬地址空間切換
  • 任務間可以直接共享變量,不需要通過內核在不同的地址空間複製數據;
  • 系統調用時不需要在覈心態和用戶態之間切換,相當於直接的函數調用。

備註:系統調用需要從用戶態切換到核心態,以執行用戶態下不能執行的操作,在許多處理器上這是通過一條等價於系統調用的TRAP指令實現的,在執行該指令前要經過嚴格的參數檢查。VxWorks中不存在這樣的切換,因此係統調用和一般函數調用沒有什麼差別。但本系列博文中仍然沿用一般說法。

對於兩種模式孰優孰劣,各自的支持者們進行了大量的爭論。比較各有所長的東西往往非常困難。本文傾向於認爲,對於嵌入式實時應用,單一實地址模式要合適一些。許多實踐也證明,依靠虛地址保護來提高可靠性總存在侷限性,畢竟程序運行出了錯誤,從某種程度上說虛地址保護只是使已經出現的錯誤經過一個延遲、積累和放大的過程,用過Windows就會有這種感觸。而經過大量關鍵應用檢驗的VxWorks操作系統,則被充分證明是高度可靠的(當然了,可靠的系統必須由可靠的操作系統和可靠的應用系統組成)。

層次結構的Wind內核僅提供多任務環境、進程間通信和同步功能的服務例程。這些服務例程足夠支持VxWorks在較高層次所提供的豐富性能的要求。VxWorks的Wind內核操作對於用戶是不可見的。應用程序爲了實現需要內核參與的任務管理和同步使用一些系統調用,但這些調用的處理對於調用任務是不可見的。應用程序僅鏈接恰當的VxWorks例程(通常使用VxWorks的動態鏈接功能),就象調用子程序一樣發出系統調用。這種接口不象Linux內核需要一個跳轉表接口,用戶需要通過一個整數來指定一個內核功能調用。

1.4 Wind內核類設計思想

VxWorks採用類和對象的思想將Wind內核分成5個組成部分:任務管理模塊、內存管理模塊、消息隊列管理模塊、信號量管理模塊、以及看門狗管理模塊

備註:除了上面的五個模塊之後,還有虛擬內存管理接口(VxVMI)模塊和TTY環形緩衝區管理模塊也是Wind內核用類和對象思想管理的兩個模塊。虛擬內存接口模塊(VxVMI)是VxWorks的一個功能模塊,它利用用戶片上或板上的內存管理單元(MMU),爲用戶提供了對內存的高級管理功能;TTY環形緩衝區管理模塊是ttyDrv設備的核心,ttyDrv設備稱爲虛擬設備,處在I/O系統和真正驅動程序之間形成了一個轉換層,爲VxWorks提供了一個標準的I/O接口,一個虛擬ttyDrv設備可以管理多個串行設備驅動程序。這兩個模塊嚴格意義上來說並不是一個RTOS內核理論上的組成部分,因此纔不把它們列在Wind內核的組成部分上。

在wind內核中,所有的對象都是類的組成部分,類定義了操作對象的方法(Method),同時維護着對所有對象的操作記錄。Wind內核採用了c++的語義,但是採用c語言來實現。整個Wind內核通過顯式編碼實現,其編譯過程並不依賴於具體的編譯器。這意味着Wind內核不但可以在vxWorks自帶的diab編譯上編譯,也可以使用開源的gnu/gcc編譯器。VxWorks爲Wind內核設計了一個元類(Meta-class),所有的對象類(Obj-class)都是基於該元類。每個對象類只負責維護各自對象(Object)的操作方法(比如創建對象、初始化對象、註銷對象等)、以及管理統計記錄(比如一個創建對象的數據、銷燬對象的數目等)。圖1.5實現了元類、對象類、以及對象之間的邏輯關係。

VxWorks內核解讀-1

圖1-5 元類、對象類、對象間關係圖

備註:每次畫這種類和對象關係圖的時候,我就異常的糾結。因爲在wind內核的設計中,元類classClass有一個ID號classClassId,每個對象類X-objClass也有一個ID號X-objClassId。在C語言的實現中classClassId和X-objClassId都是指針變量,存放的是相應類的地址。在初始化對象類和對象時,對象類和對象的objCore域存放的該指針變量的值(即相應類的地址),跟classClassId沒有太大的關係。圖1.5真實地反應了objCore存放的類地址這個真實的關係。

如果從邏輯上來看的話,圖1.6看起來更舒服,雖然從C語言實現來說,classClassId和X-objClassId的作用是錯誤的,但是從邏輯上看圖1.6能更清晰的描述問題(並且圖也更美觀O(∩_∩)O),雖然圖1.6上objCore存放的指向類地址的指針。正因爲如此,在畫類和對象關係圖時,我採用圖1-6所示的方式。

VxWorks內核解讀-1

圖1-6 元類、對象類、對象間關係圖

正如圖1-5,圖1-6所示的那樣每個對象類都指向元類classClass,每個對象類只負責管理各自的對象。Wind內核完整的元類、對象類、以及對象間邏輯關鍵,見圖1-7。

VxWorks內核解讀-1

圖1-7 wind內核各個組成模塊間對象類、對象和元類的關係

備註:類管理模式不是Wind內核的特性,從功能上來說它僅僅是Wind內核組織各個模塊的手段,所有內核模塊的對象類、類對象都依賴於它。VxWorks採用類及對象來組織操作系統的結構,一個最重要的優勢是增加了代碼的安全性,即在創建新的對象類和對象、以及刪除對象類和對象都可以對對象類、對象進行驗證。

1.5 Wind內核的特性

VxWorks的Wind內核自然具有1.2節所描述的所有RTOS所共有的四個特性,其所有特點可以概括如下:

  • 可裁剪的微內核設計;
  • 多任務併發執行;
  • 可搶佔的優先級調度算法;
  • 可選的時間片輪轉算法;
  • 任務間通信和同步機制;
  • 快速的上下文切換時間;
  • 低中斷延時;
  • 快速的中斷響應時間;
  • 可嵌套中斷支持;
  • 256個任務優先級;
  • 任務刪除保護;
  • 優先級繼承;
  • 基於函數的調用,不採用陷阱指令和跳轉表;
  • VxWorks內核運行在處理器特權模式;
  • VxWorks內核分層實現,VxWorks的核心庫Wind內核處於核心態,由全局管理kernelState進行保護。

備註:本系列博文接下來的部分將詳細分析wind內核如何進行設計,以具有這些特性。

再廢話幾句O(∩_∩)O:我在分析Wind內核時所秉持的宗旨是策略(Mechanism)和機制(Policy)相分離的原則,策略(Mechanism)和機制(Policy)相分離是微內核設計的指導思想,換句話說微內核操作系統設計的指導原則是提供機制而不是策略。爲了更清楚地說明這一點,我們以任務調度爲例。一個簡單的調度算法是爲每一個任務賦予一個優先級,並讓內核執行具有最高優先級的就緒任務。在這個例子中,機制(Mechanism)是在內核中尋找最高優先級的就緒任務並運行之;而策略(Policy)則是賦予任務相應的優先級。換句話說機制負責提供什麼樣的功能,策略則負責如何使用這些功能。策略和機制相分離指導思想可以使操作系統內核變得更小,更穩定。正如一句話說的好“一個優美的內核不是還有什麼樣的功能還可以增加,而是還有什麼樣的功能還可以減少”(哥們忘記是誰說的了⊙﹏⊙b汗)。

本系列博文力求在分析研究Wind內核的同時,思考RTOS的內核設計思想源泉。VxWorks的Wind內核經歷了近20年的發展完善,達到目前的穩定狀態。採用目前的這種設計、一定有其內部的考量,我希望儘可能的從一個系統設計者的角度來分析Wind內核的設計思想、工作機制、以及具有的特性,爲我們設計一個款優秀的RTOS內核提供借鑑!

待續......O(∩_∩)O哈哈~



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章