VxWorks內核分析

     VxWorks操作系統是美國WindRiver公司於1983年設計開發的一種嵌入式實時操作系統(RTOS),是嵌入式開發環境的關鍵組成部分。良好的持續能力、高性能的內核以及友好的用戶開發環境,在嵌入式實時操作系統領域佔據一席之地。它以其良好的可靠性和卓越的實時性被廣泛地應用在通信、軍事、航空、航天等高精尖技術及實時性要求極高的領域中,如衛星通訊、軍事演習、彈道制導、飛機導航等。在美國的 F-16、FA-18 戰鬥機、B-2 隱形轟炸機和愛國者導彈上,甚至連1997年在火星表面登陸的火星探測器上也使用到了VxWorks。
    從操作系統能否滿足實時性要求來區分,可把操作系統分成分時操作系統和實時操作統。分時操作系統按照相等的時間片調度進程流運行,分時操作系統由調度程序自動計算進程的優先級,而不是由用戶控制進程的優先級。這樣的系統無法實時響應外部異步事件。實時操作系統能夠在限定的時間內執行完所規定的功能,並能在限定的時間內對外部的異步事件作出響應。分時系統主要應用於科學計算和一般實時性要求不高的場合。實時性系統主要應用於過程制、數據採集、通信、多媒體信息處理等對時間敏感的場合。

 

1. 實時操作系統的結構
    在計算的早期開發的操作系統的最原始的結構形式是一個統一的實體(monolithic)。在這樣的系統中,提供的不同功能的模塊,如處理器管理、內存管理、輸入輸出等,通常是獨立的。然而他們在執行過程中並不考慮其他正在使用中的模塊,各個模塊都以相同的時間粒度運行。
    由於現代實時環境需要許多不同的功能,以及在這樣的環境中存在的併發活動所引起的異步性和非確定性,操作系統變得更加複雜。所以早期操作系統的統一結構的組織已經被更加精確的內部結構所淘汰。

 

層次結構的起點----內核
    操作系統的最好的內部結構模型是一個層次性的結構,最低層是內核。這些層次可以看成爲一個倒置的金字塔,每一層都建立在較低層的功能之上。 內核僅包含一個操作系統執行的最重要的低層功能。正象一個統一結構的操作系統,內核提供了在高層軟件與下層硬件之間的抽象層。然而,內核僅提供了構造操作系統其他部分所需的最小操作集。


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

 

擁有其它名字的內核
    許多商用化的內核支持的功能遠強於上面所列的要求。在這方面,他們不是真正的內核,而更象一個小的統一結構的操作系統。因爲他們包含簡單的內存分配、時鐘管理、甚至一些輸入輸出系統調用的功能。
    這種分類不僅僅是在語義上的爭論,在這篇文章的後面章節將說明限制內核功能和優化這些功能的重要性。

 

2. VxWorks內核:Wind
    VxWorks操作系統是一種功能最全的現在可以獲得的獨立於處理器的實時系統。然而,VxWorks是帶有一個相當小的真正微內核的層次結構。內核僅提供多任務環境、進程間通信和同步功能。這些功能模塊足夠支持VxWorks在較高層次所提供的豐富的性能的要求。 通常內核操作對於用戶是不可見的。應用程序爲了實現需要內核參與的任務管理和同步使用一些系統調用,但這些調用的處理對於調用任務是不可見的。應用程序僅鏈接恰當的VxWorks例程(通常使用VxWorks的動態鏈接功能),就象調用子程序一樣發出系統調用。這種接口不象有些系統需要一個笨拙的跳轉表接口,用戶需要通過一個整數來指定一個內核功能調用。

 

多任務
    內核的基本功能是提供一個多任務環境。多任務使得許多程序在表面上表現爲併發執行,而事實上內核是根據基本的調度算法使他們分段執行。每個明顯獨立的程序被成爲一個任務。每個任務擁有自己的上下文,其中包含在內核調度使該任務執行的時候它所看到的CPU環境和系統資源。

 

任務狀態
    內核維護系統中的每個任務的當前狀態。狀態遷移發生在應用程序調用內核功能服務的時候。下面定義了wind內核狀態:
(1)就緒態----一個任務當前除了CPU不等待任何資源
(2)阻塞態----一個任務由於某些資源不可獲得而被阻塞
(3)延遲態----一個任務睡眠一段時間
(4)掛起態----主要用於調試的一個輔助狀態,掛起禁止任務的執行
    任務被創建以後進入掛起態,需要通過特定的操作使被創建的任務進入就緒態,這一操作執行速度很快,使應用程序能夠提前創建任務,並以一種快捷的方式激活該任務。

 

調度控制
    多任務需要一個調度算法分配CPU給就緒的任務。在VxWorks中默認的調度算法是基於優先級的搶佔調度,但應用程序也可以選擇使用時間片輪轉調度。基於優先級搶佔調度:基於優先級的搶佔調度,每個任務被指定一個優先級,內核分配CPU給處於就緒態的優先級最高的任務。調度採用搶佔的方式,是因爲當一個優先級高於當前任務的任務變爲就緒態時,內核將立即保存當前任務的上文,並切換到高優先級任務的上文。VxWorks有從0到255共256個優先級。在創建的時候任務被指定一個優先級,在任務運行的過程中可以動態地修改優先級以便跟蹤真實世界的事件優先級。外部中斷被指定優先於任何任務的優先級,這樣能夠在任何時候搶佔一個任務。
    時間片輪轉:基於優先級搶佔調度可以擴充時間片輪轉調度。時間片輪轉調度允許在相同優先級的處於就緒態的任務公平地共享CPU。沒有時間片輪轉調度,當有多個任務在同一優先級共享處理器時,一個任務可能獨佔CPU,不會被阻塞直到被一個更高優先級的任務搶佔,而不給同一優先級的其他任務運行的機會。如果時間片輪轉被使能,執行任務的時間計數器在每個時鐘滴答遞增。當指定的時間片耗盡,計數器會被清零,該任務被放在同一優先級任務隊列的隊尾。加入特定優先級組的新任務被放在該組任務的隊尾,並將運行計數器初始化爲零。

基本的任務函數
    用於狀態控制的基本任務函數包括一個任務的創建、刪除、掛起和喚醒。一個任務也可以使自己睡眠一個特定的時間間隔不去運行。許多其他任務例程提供由任務上下文獲得的狀態息。這些例程包括訪問一個任務當前處理器寄存器控制。

 

任務刪除問題
    wind內核提供防止任務被意外刪除的機制。通常,一個執行在臨界區或訪問臨界資源的任務要被特別保護。我們設想下面的情況:一個任務獲得一些數據結構的互斥訪問權,當它正在臨界區內執行時被另一個任務刪除。由於任務無法完成對臨界區的操作,該數據結構可能還處於被破壞或不一致的狀態。而且,假想任務沒有機會釋放該資源,那麼現在其他任何任務現在就不能獲得該資源,資源被凍結了。任何要刪除或終止一個設定了刪除保護的任務的任務將被阻塞。當被保護的任務完成臨界區操作以後,它將取消刪除保護以使自己可以被刪除,從而解阻塞刪除任務。
    正如上面所展示的,任務刪除保護通常伴有互斥操作。這樣,爲了方便性和效率,互斥信號量包含了刪除保護選項。(參見"互斥信號量")

 

任務間通信
    爲了提供完整的多任務系統的功能,wind內核提供了一套豐富的任務間通信與同步的機制。這些通信功能使一個應用中各個獨立的任務協調他們的活動。

共享地址空間
    wind內核的任務間通信機制的基礎是所有任務所在的共享地址空間。通過共享地址空間,任務能夠使用共享數據結構的指針自由地通信。管道不需要映射一塊內存區到兩個互相通信任務的尋址空間。不幸的是,共享地址空間具有上述優點的同時,帶來了未被保護內存的重入訪問的危險。UNIX操作系統通過隔離進程提供這樣的保護,但同時帶來了對於實時操作系統來說巨大的性能損失。

 

互斥操作
    當一個共享地址空間簡化了數據交換,通過互斥訪問避免資源競爭就變爲必要的了。用來獲得一個資源的互斥訪問的許多機制僅在這些互斥所作用的範圍上存在差別。實現互斥的方法包括禁止中斷、禁止任務搶佔和通過信號量進行資源鎖定。
    中斷禁止:最強的互斥方法是屏蔽中斷。這樣的鎖定保證了對CPU的互斥訪問。這種方法當然能夠解決互斥的問題,但它對於實時是不恰當的,因爲它在鎖定期間阻止系統響應外部事件。長的中斷延時對於要求有確定的響應時間的應用來說是不可接受的。
    搶佔禁止:禁止搶佔提供了強制性較弱的互斥方式。 當前任務運行的過程中不允許其他任務搶佔,而中斷服務程序可以執行。這也可能引起較差的實時響應,就象被禁止中斷一樣,被阻塞的任務會有相當長時間的搶佔延時,就緒態的高優先級的任務可能會在能夠執行前被強制等待一段不可接受的時間。爲避免這種情況,在可能的情況下儘量使用信號量實現互斥。
    互斥信號量:信號量是用於鎖定共享資源訪問的基本方式。不象禁止中斷或搶佔,信號量限制了互斥操作僅作用於相關的資源。一個信號量被創建來保護資源。VxWorks的信號量遵循Dijkstra的P()和V()操作模式。
    當一個任務請求信號量,P(),根據在發出調用時信號量的置位或清零的狀態,會發生兩種情況。如果信號量處於置位態,信號量會被清零,並且任務立即繼續執行。如果信號量處於清零態,任務會被阻塞來等待信號量。
   當一個任務釋放信號量,V(),會發生幾種情況。如果信號量已經處於置位態,釋放信號量不會產生任何影響。如果信號量處於清零態且沒有任務等待該信號量,信號量只是被簡單地置位。如果信號量處於清零態且有一個或多個任務等待該信號量,最高優先級的任務被解阻塞,信號量仍爲清零態。
    通過將一些資源與信號量關聯,能夠實現互斥操作。當一個任務要操作資源,它必須首先獲得信號量。只要任務擁有信號量,所有其他的任務由於請求該信號量而被阻塞。當一個任務使用完該資源,它釋放信號量,允許等待該信號量的另一個任務訪問該資源。
Wind內核提供了二值信號量來解決互斥操作所引起的問題。 這些問題包括資源擁有者的刪除保護,由資源競爭引起的優先級逆轉。
    刪除保護----互斥引起的一個問題會涉及到任務刪除。在由信號量保護的臨界區中,需要防止執行任務被意外地刪除。刪除一個在臨界區執行的任務是災難性的。資源會被破壞,保護資源的信號量會變爲不可獲得,從而該資源不可被訪問。通常刪除保護是與互斥操作共同提供的。由於這個原因,互斥信號量通常提供選項來隱含地提供前面提到的任務刪除保護的機制。
    優先級逆轉/優先級繼承----優先級逆轉發生在一個高優先級的任務被強制等待一段不確定的時間以便一個較低優先級的任務完成執行。考慮下面的假設:
T1,T2和T3分別是高、中、低優先級的任務。T3通過擁有信號量而獲得相關的資源。當T1搶佔T3,爲競爭使用該資源而請求相同的信號量的時候,它被阻塞。如果我們假設T1僅被阻塞到T3使用完該資源爲止,情況並不是很糟。畢竟資源是不可被搶佔的。然而,低優先級的任務並不能避免被中優先級的任務搶佔,一個搶佔的任務如T2將阻止T3完成對資源的操作。這種情況可能會持續阻塞T1等待一段不可確定的時間。這種情況成爲優先級逆轉,因爲儘管系統是基於優先級的調度,但卻使一個高優先級的任務等待一個低優先級的任務完成執行。
    互斥信號量有一個選項允許實現優先級繼承的算法。優先級繼承通過在T1被阻塞期間提升T3的優先級到T1解決了優先級逆轉引起的問題。這防止了T3,間接地防止T1,被T2搶佔。通俗地說,優先級繼承協議使一個擁有資源的任務以等待該資源的任務中優先級最高的任務的優先級執行。當執行完成,任務釋放該資源並返回到它正常的或標準的優先級。因此,繼承優先級的任務避免了被任何中間優先級的任務搶佔。


同步
    信號量另一種通常的用法是用於任務間的同步機制。在這種情況下,信號量代表一個任務所等待的條件或事件。最初,信號量是在清零態。一個任務或中斷通過置位該信號量來指示一個事件的發生。等待該信號量的任務將被阻塞直到事件發生、該信號量被置位。一旦被解阻塞,任務就執行恰當的事件處理程序。信號量在任務同步中的應用對於將中斷服務程序從冗長的事件處理中解放出來以縮短中斷響應時間是很有用的。

 

消息隊列
    消息隊列提供了在任務與中斷服務程序或其他任務間交換變長消息的一種較低層的機制。這種機制在功能上類似於管道,但有較少的開銷。管道、套接字、遠程過程調用和更多許多高層的VxWorks機制提供任務間通信的更高層的抽象,包括管道、TCP/IP套接字、遠程過程調用和更多。爲了保持裁減內核爲僅包含足夠支持高層功能的一個最小函數集的設計目標,這些特性都是基於上面描述的內核同步方式的。

 

3. 內核設計的優點
    wind內核的一個重要的設計特性是最小的搶佔延時。其他的主要設計的優點包括史無前例的可配置性,對不可預見的應用需求的可擴展性,在各種微處理器應用開發中的移植性。

 

最小的搶佔延時
    正如前面所討論的,禁止搶佔是獲得代碼臨界資源互斥操作的通常手段。這種技巧的不期望的負面影響是高的搶佔延時,這可以通過儘量使用信號量實現互斥和保持臨界區儘量緊湊被減小。但即使廣泛地使用信號量也不能解決所有的可能導致搶佔延時的根源。內核本身就是一個導致搶佔延時的根源。爲了理解其原因,我們必須更好地理解內核所需的互斥操作。

 

內核級和任務級
    在任何多任務系統中,大量的應用是發生在一個或多個任務的上下文。然而,有些CPU時間片不在任何任務的上下文。這些時間片發生在內核改變內部隊列或決定任務調度。在這些時間片中,CPU在內核級執行,而非任務級。
    爲了內核安全地操作它的內部的數據結構,必須有互斥操作。內核級沒有相關的任務上下文,內核不能使用信號量保護內部鏈表。內核使用工作延期作爲實現互斥的方式。當有內核參與時,中斷服務程序調用的函數不是被直接激活,而是被放在內核的工作隊列中。內核完成這些請求的執行而清空內核工作隊列。
    當內核正在執行已經被請求服務時系統將不響應到達內核的函數調用。可以簡單地認爲內核
狀態類似於禁止搶佔。如前面所討論的,搶佔延時在實時系統中是不期望有的,因爲它增加了對於會引起應用任務重新調度的事件的響應時間。
    儘管操作系統在內核級(此時禁止搶佔)完全避免消耗時間是不可能的,但減少這些時間是很重要的。這是減少由內核執行的函數的數量的主要原因, 也是不採用統一結構的系統設計方式的原因。例如,有一種流行的實時操作系統的每個函數都是在內核級執行。這意味着當一個低優先級的任務在執行分配內存、獲得任務信息的函數時所有高優先級的任務被禁止搶佔。

 

一個最小的內核
    已經說明了一個最小內核的優點和構造高層操作系統功能的必要功能,我們使用這些操作原語來執行一個傳統的內核級功能,而在VxWorks中作爲任務級功能執行,內存管理。 在這個例子中,考慮用戶可調用的子例程malloc, 用於分配所請求大小的內存區並返回一個指向該內存區的指針。假定空閒內存區是通過搜索一個空閒內存塊的隊列找到的,一個信號量必須被用來保護這個非搶佔多用戶資源。分配內存的操作如下:
(1)獲得互斥信號量
(2)搜索空閒內存塊鏈表
(3)釋放互斥信號量
值得注意的是搜索一個足夠大的空閒內存塊的可能的冗長的時間是發生在調用任務的上下文中。這是可以被高優先級的任務搶佔的(除了信號量調用的這段執行時間)。
在一個標準的統一結構的實時內核中,內存分配例程操作如下:
(1)進入內核
(2)搜索空閒內存塊鏈表
(3)退出內核
整個內存分配發生在內核級,任務搶佔被禁止如果高優先級的任務在此時變爲就緒態,它必須等待直到內核爲低優先級的任務完成內存分配。有些操作系統甚至在這段時間禁止中斷。

 

任務級操作系統服務
    Wind River System的實時操作系統,VxWorks,顯示了這樣設計的一個最小內核是能夠滿足需求的。VxWorks是現在能夠獲得的獨立於任何處理器的、擁有相當小內核的、功能完全的層次結構的實時操作系統。
    VxWorks在內核之上提供了大量的功能。它包括內存管理,一個完整的BSD4.3網絡包,TCP/IP,網絡文件系統(NFS),遠程過程調用(RPC),UNIX兼容的鏈接加載模塊,C語言的解釋界面,各種類型的定時器,性能監測組件,調試工具,額外的通信工具如管道、信號和套接字,I/O和文件系統,和許多功能例程。這些都不是運行在內核級,所以不會禁止中斷或任務搶佔。

 

可配置性
    實時應用有多種內核需求。沒有哪個內核有一個用來滿足每種需求的很好的設計折衷。然而,一個內核可以通過配置來調整特定的性能特性,裁減實時系統來最好地適應一個應用的要求。不可預見的內核配置性以用戶可選擇的內核排隊算法的形式提供給應用。

 

排隊策略
    VxWorks中的排隊庫是獨立於使用他們的內核隊列功能而執行的,這樣提供了將來增加新的排隊方式的靈活性。
    在VxWorks中有各種內核隊列。就緒隊列是一個按優先級索引的所有等待調度的任務隊列。滴答隊列用於定時功能。信號量是一個等待信號量的被阻塞任務的鏈表。活動隊列是一個系統中所有任務的一個先進先出(FIFO)的鏈表。這些隊列中的每個隊列都需要一個不同的排隊算法。這些算法不是被內嵌在內核中,而是被抽取到一個自治的、可轉換的排隊庫中。這種靈活的組織形式是滿足特殊的配置需求的基礎。

 

可擴展性
    支持不可預見的內核擴展的能力與以有功能的可配置性是同樣重要的。簡單的內核接口和互斥方法使內核級功能擴展相當容易; 在某些情況下,應用可以僅利用內核鉤子函數來實現特定的擴展。

 

內部鉤子函數
    爲了不修改內核而能夠向系統增加額外的任務相關的功能,VxWorks提供了任務創建、切換和刪除的鉤子函數。這些允許在任務被創建、 上下文切換和任務被刪除的時候額外的例程被調用執行。這些鉤子函數可以利用任務上下文中的空閒區創建wind內核的任務特性。

 

未來考慮
    有許多系統函數現在變得越來越重要,而且會影響到內核設計時的搶佔延時。儘管涉及這些問題一個完整的討論超出了本文的範圍,但值得簡單地提一下。

 

RISC/CISC
    設計一個獨立於CPU的操作系統一直是一個挑戰。隨着新的RSIC(精簡指令集)處理器變得很流行,這些難度也加大了。爲了在RISC環境下有效地執行,內核和操作系統需要有執行不同策略的靈活性。
    例如,考慮在任務切換時內核執行的例程。在CISC(複雜指令集,如680x0或80x86)CPU,內核爲每個任務存儲一套完整的寄存器,在運行任務的時候將這些寄存器換入換出。在一個RISC機器上,這樣是不合理的,因爲涉及到太多的寄存器。所以內核需要一個更精密複雜的策略,如爲任務緩存寄存器,允許應用指定一些寄存器給特殊的任務。

 

移植性
    爲了使wind內核在他們出現的結構上能夠運行,需要有一個可移植的內核版本。這使移植是可行的,但不是最優化的。

 

多處理
    支持緊耦合的多處理需求要求實時內核的內部功能包含,在理想情況下,在遠端請求內核調用,如從一個處理器到另一個處理器。這就要涉及到信號量調用(爲處理器間同步)和任務調用(爲了控制另一個CPU上的任務)。這種複雜性無疑會增加內核級功能調用的開銷,但是許多服務如對象標識可以在任務級執行。在多處理系統中保持一個最小內核的優點是處理器之間的互鎖可以有較好的時間粒度。大的內核將在內核級消耗額外的時間,僅能獲得粗糙的互鎖時間粒度。

 

Ada
    Ada語言爲實時系統設計者提供了象聚會機制這樣的任務原語。異常處理、任務終止、終止替換和聚會都將潛在地影響內核設計。這些操作可以由前面討論的任務和同步機制構造,爲了保持減小搶佔延時的設計目標,許多工作能夠在任務級執行。

 

4. 實時內核的重要尺度
    許多性能特性被用來比較以有的實時內核,這些包括:
(1)快速的任務上下文切換----由於實時系統的多任務的特性,系統能夠快速地從一個任務切換到另一個任務是很重要的。在分時系統中,如UNIX,上下文切換是在ms級。Wind內核執行原始上下文切換隻用17us。
(2)最小的同步開銷----因爲同步是實現資源互斥訪問的基本方法,這些操作所引起的開銷最小化是很重要的。在VxWorks中,請求和釋放二值信號量僅用8us。
(3)最小的中斷延時----因爲外部世界來的事件通常以中斷的形式到來,操作系統快速的處理這些中斷是很重要的。內核在操作一些臨界數據結構的時候必須禁止中斷。爲了減小中斷延時,必須使這些時間最小化。Wind內核的中斷延時小於10us。

 

搶佔延時對性能指標的影響
    當許多的實時解決方案被提交給應用工程師時, 性能指標對於評估供應商的產品變得越來越重要。不象上下文切換和中斷延時,搶佔延時很難測量。所以它很少在說明中被提及。但是考慮到當內核通常禁止上下文切換會長達數百微妙,而聲稱一個50us的固定長度(與任務個數無關)的上下文切換時間是毫無意義的。除了很難測量外,搶佔延時可能會削弱許多性能指標的有效性。
    Wind內核通過減小內核的大小來儘量減小搶佔延時。 包含繁多功能的內核必將引起長的搶佔延時。

 

5. 結論
    爲了滿足對實時內核日益增加的要求,如新的調度算法、多處理、Ada和RISC結構,wind內核始終以靈活性和可配置性爲設計目標。它所提供的優秀的運行性能將成爲實時應用需求新標準。
 
 
 

 

 

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