1. 程式人生 > >如何選擇一個合適的嵌入式作業系統?

如何選擇一個合適的嵌入式作業系統?

選擇一個合適的嵌入式作業系統,可以考慮以下幾個因素:

第一是應用。如果你想開發的嵌入式裝置是一個和網路應用密切相關或者就是一個網路裝置,那麼你應該選擇用嵌入式Linux或者uCLinux,而不是uC/OS-II。

第二是實時性。沒有一個絕對的數字可以告訴你什麼是硬實時,什麼是軟實時,他們之間的界限也是十分模糊的,這與你選擇什麼樣的CPU,它的主頻、記憶體等引數有一定關係。如果你使用加入實時補丁等技術的嵌入式Linux,如Monta Vista Linux(2.4.17版本),最壞的情況只有436微秒,而99.9%的情況是195微秒以內。考慮到最新的Linux在實時性方面的改進,它可以適合於90~95%的各種嵌入式系統應用。當然,你如果希望更快的實時響應,如高速A/D轉換需要幾個微秒以內的中斷延時,可能採用uC/OS-II是合適的。當然,採用像Vxworks這樣傳統的嵌入式作業系統也可以滿足這樣的強實時性要求。

為什麼選擇Linux作業系統

Linux系統作為一個GPOS(通用作業系統)發展至今已經非常成熟可靠了,並且由於遵循GPL協議,開放所有系統原始碼,非常易於裁剪。更重要的是,與其他開源的GPOS或RTOS相比,Linux系統支援多種處理器、開發板,提供多種軟體開發工具,同時Linux系統對網路和圖形介面的支援非常出色。顯然,選擇Linux作業系統在產品的開發週期和成本控制方面都有巨大優勢。

憑藉經濟和技術方面的諸多優勢,Linux正被越來越多的嵌入式裝置所使用。Linux在嵌入式系統市場的佔用率越來越高,以下是大部分產品選擇Linux系統的原因:

  1. Linux支援的硬體裝置種類繁多。

  2. Linux支援非常多的應用程式和網路協議。

  3. Linux的擴充套件性很好,從小型的消費電子產品到大型、笨重的電信級交換機和路由器都可以採用Linux。

  4. 和傳統的專有嵌入式作業系統不同,部署Linux不需要繳納專利費。

  5. Linux吸引了為數眾多的活躍的開發者,能很快支援新的硬體架構、平臺和裝置。

  6. 越來越多的硬體和軟體廠商,包括幾乎所有的頂級晶片製造商和獨立軟體開發商,現在都支援Linux。

什麼是實時?

實時系統的典型定義如下:“所謂實時系統,就是系統中計算結果的正確性不僅取決於計算邏輯的正確性,還取決於產生結果的時間。如果完成時間不符合要求,則可以說系統發生了問題。”也就是說,不管實時應用程式進行的是何種任務,它不僅需要正確進行該任務而且還必須及時完成它。

人們很容易對實時產生誤解,認為實時即速度足夠快,實際上,實時並不意味著速度快。實時的關鍵在於保證完成時間,而不在於原始速度,因為速度效能與硬體相關,可以通過搭建快速硬體平臺(處理器、儲存器子系統等)來獲得所需的效能。而實時的行為是一個軟體問題,其目標是讓關鍵的操作能夠在所保證的時間之內完成。

實時程序不會影響自己在執行環境中的排程,反而是環境影響實時應用程式的排程。也就是說,實時程序通常和某個物理事件相關聯,比如外圍裝置的中斷。那麼顯然,影響實時的原因在於中斷響應延時,在Linux系統中可細分為中斷延時、中斷處理、排程延時。一般來說,針對使用者對超出時間限制所造成的影響的可接受程度,實時又可分為軟實時和硬實時。

軟實時

大多數人都同意軟實時意味著操作有時間限制。如果超過了時間限制後操作還沒有完成的話,體驗的質量就會下降,但不會帶來致命後果。桌面工作站就是一個需要軟實時功能的絕好例子。編輯文件時,你期望在按鍵之後立刻在螢幕上看到結果。在播放MP3檔案時,你期望聽到沒有任何雜音、爆音或中斷的高品質音樂。如果這些所謂的軟實時事件錯過了時限,結果可能不盡如人意,並導致體驗的質量有所下降,但這並不是災難性的。

硬實時

硬實時的特點是錯過時限會造成嚴重結果。在一個硬實時系統中,如果錯過了時限,後果往往是災難性的。當然,“災難”是相對而言的。但如果你的嵌入式裝置正在控制噴氣式飛機引擎的燃料流,而它沒有能夠及時響應飛行員輸入的命令或操作特性的變化,致命後果就不可避免了。

這裡,我們總結一下軟實時和硬實時的定義。對於軟實時系統,如果錯過了時限,系統的計算值或結果會不太理想。然而,對於硬實時系統,如果錯過了某個時限,系統就是失敗的,而且可能會造成災難性的後果。

制約標準Linux作業系統實時性的因素

雖然Linux系統功能強大、實用性強、易於軟體的二次開發,並且提供程式設計人員熟悉的標準API。但是由於Linux系統一開始就被設計成GPOS(通用作業系統),它的目的是構建一個完整、穩定的開源作業系統,儘量縮短系統的平均響應時間,提高吞吐量,注重作業系統的整體功能需求,達到更好地平均效能。(在作業系統中,我們可以把吞吐量簡單的理解為在單位時間內系統能夠處理的事件總數。)

因此在設計Linux的程序排程演算法時主要考慮的是公平性,也就是說,排程器儘可能將可用的資源平均分配給所有需要處理器的程序,並保證每個程序都得以執行。但這個設計目標是和實時程序的需求背道而馳的,所以標準Linux並不提供強實時性。

Linux系統實時性不強使其在嵌入式應用中有一定的侷限性,主要是受核心可搶佔性、程序排程方式、中斷處理機制、時鐘粒度等幾個方面的制約,具體如下:

(1) 程序排程

Linux系統提供符合POSIX標準的排程策略,包括FIFO排程策略(SCHED_FIFO)、帶時間片輪轉的實時排程策略(SCHED_RR)和靜態優先順序搶佔式排程策略(SCHED_OTHER)。Linux程序預設的排程策略為SCHED_OTHER,這種排程方式雖然可以讓程序公平地使用CPU和其它資源,但是並不能保證對時間要求嚴格或者高優先順序的程序將先於低優先順序的執行,這將嚴重影響系統實時性。那麼,將實時程序的排程策略設定為SCHED_FIFO 或SCHED_RR ,似乎使得Linux系統具備根據程序優先順序進行實時排程的能力,但問題在於,Linux系統在使用者態支援可搶佔排程策略,而在核心態卻不完全支援搶佔式排程策略。這樣執行在Linux核心態的任務(包括系統呼叫和中斷處理)是不能被其它優先順序更高的任務所搶佔的,由此引起優先順序逆轉問題。

(2) 核心搶佔機制

Linux的系統程序執行分為使用者態和核心態兩種模式。當程序執行在使用者態時,具有高的優先順序的程序可以搶佔程序,可以較好地完成任務;但是當程序執行在核心態時,即使其他高優先順序程序也不能搶佔該程序。當程序通過系統呼叫進入核心態執行時,實時任務必須等待系統呼叫返回後才能獲得系統資源。這和實時系統所要求的高優先順序任務執行是相互矛盾的。

當然,這種情況在Linux2.6版本的核心釋出以來有了顯著改進,Linux2.6版本後的核心是搶佔式的,這意味著程序無論在處於核心態還是使用者態,都可能被搶佔。Linux2.6以後的核心提供以下3種搶佔模式供使用者選擇。

PREEMPT_NONE——沒有強制性的搶佔。整體的平均延時較低,但偶爾也會出現一些較長的延時。它最適合那些以整體吞吐率為首要設計準則的應用。

PREEMPT_VOLUNTARY——降低延時的第一階段。它會在核心程式碼的一些關鍵位置上放置額外的顯示搶佔點,以降低延時。但這是以犧牲整體吞吐率為代價的。

PREEMPT/PREEMPT_DESKTOP——這種模式使核心在任何地方都是可搶佔的,臨界區除外。這種模式適用於那些需要軟實時效能的應用程式,比如音訊和多媒體。這也是以犧牲整體吞吐率為代價的。

(3) 中斷遮蔽

Linux在進行中斷處理時都會關閉中斷,這樣可以更快、更安全地完成自己的任務,但是在此期間,即使有更高優先順序的實時程序發生中斷,系統也無法響應,必須等到當前中斷任務處理完畢。這種狀況下會導致中斷延時和排程延時增大,降低Linux系統的實時性。

(4) 時鐘粒度粗糙

時鐘系統是計算機的重要組成部分,相當於整個作業系統的脈搏。系統所能提供的最小時間間隔稱為時鐘粒度,時鐘粒度與程序響應的延遲性是正比關係,即粒度越粗糙,延遲性越長。但時鐘粒度並不是越小越好,就同等硬體環境而言,較小的時間粒度會導致系統開銷增大,降低整體吞吐率。

在Linux2.6核心中,時鐘中斷髮生頻率範圍是50~1200Hz,週期不小於0.8ms,對於需要幾十微秒的響應精度的應用來說顯然不滿足要求。而在嵌入式Linux系統中,為了提高整體吞吐率,時鐘頻率一般設定為100HZ或250HZ。

另外,系統時鐘負責軟定時,當軟定時器逐漸增多時會引起定時器衝突,增加系統負荷。

(5) 虛擬記憶體管理

Linux採用虛擬記憶體技術,程序可以執行在比實際空間大得多的虛擬空間中。在分時系統中,虛擬記憶體機制非常適用,然而對於實時系統這是難以忍受的,頻繁的頁面換進換出會使得系統程序執行無法在規定時間內完成。

對於此問題,Linux系統提供記憶體鎖定功能,以避免在實時處理中儲存頁被換出。

(6) 共享資源的互斥訪問差異

多個任務互斥地訪問同一共享資源時,需要防止資料遭到破壞,系統通常採用訊號量機制解決互斥問題。然而,在採取基於優先順序排程的實時系統中,訊號量機制容易造成優先順序倒置,即低優先順序任務佔用高優先順序任務資源,導致高優先順序任務無法執行。

雖然從2.6.12版本之後,Linux核心已經可以在較快的x86處理器上實現10毫秒以內的軟實時效能。但如果想實現可預測、可重複的微秒級的延時,使Linux系統更好地應用於嵌入式實時環境,則需要在保證Linux系統功能的基礎上對其進行改造。下一節將介紹通過實時補丁來提高Linux實時性的方法。

常用的實時Linux改造方案

根據實時性系統要求以及Linux的特點和效能分析,對標準Linux實時性的改造存在多種方法,較為合理的兩大類方法為:直接修改Linux核心原始碼、雙核心法。

1.直接修改Linux核心原始碼

對Linux核心程式碼進行細微修改並不對核心作大規模的變動,在遵循GPL協議的情況下,直接修改核心原始碼將Linux改造成一個完全可搶佔的實時系統。核心修改面向區域性,不會從根本上改變Linux核心,並且一些改動還可以通過Linux的模組載入來完成,即系統需要處理實時任務時載入該功能模組,不需要時動態解除安裝該模組。

目前kernel.org釋出的主線核心版本還不支援硬實時。為了開啟硬實時的功能,必須對程式碼打補丁。實時核心補丁是多方努力的共同成果,目的是為了降低Linux核心的延時。這個補丁有多位程式碼貢獻者,目前由Ingo Molnar維護,補丁網址如下:www.kernel.org/pub/linux/kernel/projects/rt/。

在配置已經打過實時補丁的核心程式碼時,我們發現實時補丁添加了第4種搶佔模式,稱為PREEMPT_RT(實時搶佔)。實時補丁在Linux核心中添加了幾個重要特性,包括使用可搶佔的互斥量來替代自旋鎖;除了使用preempt_disable()保護的區域以外,核心中的所有地方都開啟了非自願式搶佔(involuntary preemption)功能。這種模式能夠顯著降低抖動(延時的變化),並且使那些對延時要求很高的實時應用具有可預測的較低延時。

這種方法存在的問題是:很難百分之百保證,在任何情況下,GPOS程式程式碼絕不會阻礙RTOS的實時行為。也就是說,通過修改Linux核心,難以保證實時程序的執行不會遭到非實時程序所進行的不可預測活動的干擾。

2. 雙核心法

實際上,雙核心的設計緣由在於,人們不相信標準Linux核心可以在任何情況下兌現它的實時承諾,因為GPOS核心本身就很複雜,更多的程式程式碼通常會導致更多的不確定性,這樣將無法符合可預測性的要求。更何況Linux核心極快的發展速度,使其會在很短的時間內帶來很大的變化,直接修改Linux核心原始碼的方法將難以保持同步。

雙核心法是在同一硬體平臺上採用兩個相互配合,共同工作的系統核心,通過在Linux系統的最底層增加一層實時核心來實現。其中的一個核心提供精確的實時多工處理,另一個核心提供複雜的非實時通用功能。

雙核心方法的實質是把標準的Linux核心作為一個普通程序在另一個核心上執行。關鍵的改造部分是在Linux和中斷控制器之間加一箇中斷控制的模擬層,成為其實時核心的一部分。該中斷模擬機制提供了一個標誌用來記錄Linux的關開中斷情況。一般只在修改核心資料結構關鍵程式碼時才關中斷,所以其中斷響應很小。其優點是可以做到硬實時,並且能很方便地實現一種新的排程策略。

為方便使用,實時核心通常由一套可動態載入的模組提供,也可以像編譯任何一般的子系統那樣在Linux原始碼樹中直接編譯。常用的雙核心法實時補丁有RTLinux/GPL、RTAI 和 Xenomai,其中RTLinux/GPL只允許以核心模組的形式提供實時應用;而RTAI和Xenomai支援在具有MMU保護的使用者空間中執行實時程式。下面,我們將對RTAI與Xenomai進行分析。

圖1. RTAI(左)和Xenomai(右)實時核心在Linux中的分層結構

圖1所示為RTAI和Xenomai兩個實時核心分別與標準Linux核心組成雙核心系統是的分層結構。可以看到兩者有稍微不同的組織形式,與Xenomai讓ADEOS掌控所有的中斷源不同的是,RTAI攔截它們,使用ADEOS將那些RTAI不感興趣的中斷通知送給Linux(也就是,中斷不影響實時時序)。這樣混合過程的目的是提高效能,因為在這種情況下,如果中斷是要喚醒一個實時任務,就避免了由ADEOS管理中斷的開銷。從這裡可以看出,RTAI的實時效能應該是比Xenomai要好的。

RTAI(Real-Time Linux Application interface)雖然實時效能較好,但對ARM支援不夠,更新速度極慢,造成專案開發週期長,研發成本高。

與RTAI相比,Xenomai更加專注於使用者態下的實時性、提供多套與主流商業RTOS相容的API以及對硬體的廣泛支援,在其之上構建的應用系統能保持較高實時性,而且穩定性和相容性更好;此外,Xenomai社群活躍,緊跟主流核心更新,支援多種架構,對ARM的支援很好。

Xenomai是Linux核心的一個實時開發框架。它希望無縫地整合到Linux環境中來給使用者空間應用程式提供全面的、與介面無關的硬實時效能。Xenomai是基於一個抽象實時作業系統核心的,可以被用來在一個通用實時作業系統呼叫的核心上,構建任意多個不同的實時介面。Xenomai專案始於2001年8月。2003年它和RTAI專案合併推出了RTAI/fusion。

2005年,因為開發理念不同,RTAI/fusion專案又從RTAI中獨立出來作為Xenomai專案。相比之下,RTAI專案致力於技術上可行的最低延遲;Xenomai除此之外還很著重擴充套件性、可移植性以及可維護性。Xenomai專案將對Ingo Molnar的PREEMPT_PT實時搶佔補丁提供支援,這又是與RTAI專案的一個顯著的不同。RTAI和Xenomai都有開發者社群支援,都可以作為一個VxWorks的開源替代。

Xenomai是基於Adeos(Adaptive Domain Environment for Operating System)實現的,Adeos的目標是為作業系統提供了一個靈活的、可擴充套件的自適應環境;在這個環境下,多個相同或不同的作業系統可以共存,共享硬體資源。基於Adeos的系統中,每個作業系統都在獨立的域內執行,每個域可以有獨立的地址空間和類似於程序、虛擬記憶體等的軟體抽象層,而且這些資源也可以由不同的域共享。與以往傳統的作業系統共存方法不同,Adeos是在已有的作業系統下插入一個軟體層,通過向上層多個作業系統提供某些原語和機制實現硬體共享。應用上主要是提供了一個用於“硬體-核心”介面的納核心(超微核心),使基於Linux環境的系統能滿足硬實時的要求。

Xenomai正是充分利用了Adeos技術,它的首要目標是幫助人們儘量平緩地移植那些依賴傳統RTOS的應用程式到GNU/Linux環境,避免全部重寫應用程式。它提供一個模擬器模擬傳統實時作業系統的API,這樣就很容易移植應用程式到GNU/Linux環境中,同時又能保持很好的實時性。Xenomai的核心技術就是使用一個實時微核心來構建這些實時API,也稱作“Skin”。Xenomai通過這種介面變種技術實現了針對多種傳統RTOS的應用程式設計介面,方便傳統RTOS應用程式向GNU/Linux的移植。圖2描述了Xenomai的這種帶Skin的分層架構。

圖2. 帶Skin介面的Xenomai分層結構

從圖2可以看出,Xenomai系統包含多個抽象層:Adeos納核心直接工作在硬體之上;位於Adeos之上的是與處理器體系結構相關的硬體抽象層(Hardware Abstraction Layer, HAL);系統的中心部分是執行在硬體抽象層之上的抽象的實時核心,實時核心實現了一系列通用RTOS的基本服務。

這些基本服務可以由Xenomai的本地API(Native)或由建立在實時核心上的針對其他傳統RTOS的客戶API提供,如RTAI、POSIX、VxWorks、uITRON、pSOS+等。客戶API旨在相容其所支援的傳統RTOS的應用程式在Xenomai上的移植,使應用程式在向Xenomai/Linux體系移植的過程中不需要完全重新改寫,此特性保證了Xenomai系統的穩健性。Xenomai/Linux系統為使用者程式提供了使用者空間和核心空間兩種模式,前者通過系統呼叫介面實現,後者通過實時核心實現。使用者空間的執行模式保證了系統的可靠性和良好的軟實時性,核心空間程式則能提供優秀的硬實時性。

免責宣告:本文系網路轉載,版權歸原作者所有。如涉及作品版權問題,請與我們聯絡,我們將根據您提供的版權證明材料確認版權並支付稿酬或者刪除內容。