大部分嵌入式項目還需要實時操作系統(tǒng)嗎?這個問題問得好,因為現(xiàn)代高性能處理器和 Linux、Windows 和其他通用操作系統(tǒng) (GPOS) 的實時補丁的可用性都在飛速發(fā)展。嵌入式設備的本質(zhì)道出了答案。在許多情況下,制造設備都需要幾千甚至幾百萬個部件。哪怕設備硬件的單位成本節(jié)省 1 美元,都會為制造商帶來不小的財富。換言之,設備無法承受數(shù)千兆赫茲級處理器的成本(更不用說熱耗散了)。例如,在汽車遠程信息處理技術(shù)市場,常見的 32 位處理器以約 600 Mhz 的速度運行——遠遠慢于臺式機和服務器的常用處理器。在這種運行環(huán)境中,實時操作系統(tǒng)能得到低端硬件超快、可預測的響應,因此具有顯著的節(jié)約成本的優(yōu)勢。
除節(jié)約成本之外,實時操作系統(tǒng)提供的服務還能使許多計算問題迎刃而解,特別是當多種運行爭奪系統(tǒng)資源時。例如,試想一個用戶期望(或需要)立即響應輸入的系統(tǒng)。利用實時操作系統(tǒng),軟件開發(fā)人員能確保用戶啟動的操作會先于其他系統(tǒng)活動執(zhí)行,除非必須先執(zhí)行更重要的任務(如幫助保護用戶安全的運行)。
再試想一個必須滿足服務質(zhì)量 (QoS) 要求的系統(tǒng),例如一臺可播放現(xiàn)場視頻的設備。如果設備依靠軟件播放其內(nèi)容,它可能會以用戶無法接受的速率出現(xiàn)失幀現(xiàn)象——從用戶的角度看,該設備不可靠。但使用實時操作系統(tǒng)的話,軟件開發(fā)人員就能精確控制軟件進程的執(zhí)行順序,確保以適當和一致的媒體速率播放。
?實時操作系統(tǒng)并不“公平”
對“硬”實時的需求(以及對實現(xiàn)該功能的實時操作系統(tǒng)的需求)仍然是嵌入式產(chǎn)品業(yè)的普遍要求。問題是,實時操作系統(tǒng)具備哪些通用操作系統(tǒng)所不具備的功能呢?適用于一些通用操作系統(tǒng)的實時擴展組件有多大用處呢?它們能提供和實時操作系統(tǒng)一樣的性能嗎?
讓我們先從任務調(diào)度開始。在通用操作系統(tǒng)中,調(diào)度程序通常使用一種“公平”策略,將線程和進程分配到 CPU 中。這種策略可確保臺式機和服務器的應用程序所需的較高的總吞吐量,但無法保證優(yōu)先級高、時間要求嚴格的線程先于優(yōu)先級低的線程執(zhí)行。
例如,通用操作系統(tǒng)可能會降低分配給優(yōu)先級高的線程的優(yōu)先級,或按照有利于系統(tǒng)內(nèi)其他線程的公平原則,以動態(tài)方式調(diào)整優(yōu)先級。因此,優(yōu)先級高的線程就可能被優(yōu)先級低的線程搶占。此外,大多數(shù)通用操作系統(tǒng)都具有無限期的分配潛伏期:系統(tǒng)內(nèi)的線程越多,通用操作系統(tǒng)調(diào)度線程執(zhí)行所需的時間就越久。其中任何一種因素都能導致優(yōu)先級高的線程錯過最后期限,即使在速度很快的 CPU 上。
另一方面,在實時操作系統(tǒng)中,線程會按其優(yōu)先級的順序執(zhí)行。如果優(yōu)先級高的線程準備運行,它能在很短且有限的時間間隔內(nèi),從正在執(zhí)行的優(yōu)先級低的線程那里接管 CPU。此外,優(yōu)先級高的線程還能不間斷地運行直到完成任務為止——當然,除非它被優(yōu)先級更高的線程搶占。這種眾所周知的基于優(yōu)先級的搶占式調(diào)度,可確保優(yōu)先級高的線程始終如一地滿足最后期限的要求,即使在其他線程爭奪 CPU 時間時。
搶占式內(nèi)核
大多數(shù)通用操作系統(tǒng)的操作系統(tǒng)內(nèi)核都不是搶占式的。因此,優(yōu)先級高的用戶線程無法搶占內(nèi)核調(diào)用,相反,它必須等待整個調(diào)用全部結(jié)束——即使是系統(tǒng)內(nèi)優(yōu)先級低的進程進行調(diào)用。此外,當驅(qū)動程序或其他系統(tǒng)服務(通常在內(nèi)核調(diào)用中運行)以客戶端線程的名義執(zhí)行時,操作系統(tǒng)通常會丟失所有優(yōu)先級信息。這種系統(tǒng)行為會導致無法預料的延遲,而且會妨礙關(guān)鍵運行按時完成。
另一方面,在實時操作系統(tǒng)中,內(nèi)核運行是可搶占的。雖然仍有一些時間窗無法搶占,但在設計精密的實時操作系統(tǒng)中,這些間隔非常短暫,通常大約僅幾百納秒。另外,實時操作系統(tǒng)會針對搶占推遲和中斷禁止的時限設置上限;這能保證軟件開發(fā)人員確定情況最糟的延遲期。
為實現(xiàn)這一目標,實時操作系統(tǒng)內(nèi)核必須盡可能簡單、精致。實現(xiàn)這種簡單性的最佳途徑是設計一種只包含短執(zhí)行路徑服務的內(nèi)核。通過排除內(nèi)核中任務集中的運行(如進程加載)并將其分配到外部進程或線程,實時操作系統(tǒng)的設計人員就能保證通過內(nèi)核的最長的非搶占代碼路徑有上限。
在一些通用操作系統(tǒng),內(nèi)核增加了某種程度的可搶占性。但無法搶占的時間間隔仍然比常見實時操作系統(tǒng)的長得多;這種搶占間隔的長度取決于通用操作系統(tǒng)內(nèi)核中包含的最長的關(guān)鍵模塊部分(如網(wǎng)絡)。另外,搶占式通用操作系統(tǒng)內(nèi)核不能解決可能的無限期延遲情形,例如因為客戶端調(diào)用驅(qū)動程序或其他系統(tǒng)服務時丟失優(yōu)先級信息。
避免優(yōu)先級反轉(zhuǎn)的機制
即使在實時操作系統(tǒng)中,優(yōu)先級低的線程也能在無意中阻止優(yōu)先級高的線程訪問 CPU——這種情況被稱為優(yōu)先級反轉(zhuǎn)。當出現(xiàn)無限期的優(yōu)先級反轉(zhuǎn)時,可能會錯過關(guān)鍵的最后期限,進而導致系統(tǒng)運行異常和全面故障的結(jié)果。遺憾的是,在系統(tǒng)設計過程中人們往往會忽視優(yōu)先級反轉(zhuǎn)。有很多優(yōu)先級反轉(zhuǎn)的實例,包括 1997 年 7 月火星探路者項目遭受困擾的實例。1
一般來說,當優(yōu)先級不同的兩個任務共享資源,而優(yōu)先級高的任務無法從優(yōu)先級低的任務那里獲得資源時,就會出現(xiàn)優(yōu)先級反轉(zhuǎn)。為防止這種狀況超過有限的時間間隔,實時操作系統(tǒng)可提供一種通用操作系統(tǒng)不具備的選擇機制,包括優(yōu)先級繼承和優(yōu)先級封頂模擬。我們不能單純地評價兩種機制的優(yōu)劣,所以我們著重介紹優(yōu)先級繼承的實例。
首先,我們必須考慮任務同步如何能造成阻塞,而阻塞反過來又如何導致優(yōu)先級反轉(zhuǎn)。我們假設有任務 1 和任務 2 兩個任務正在運行,其中任務 1 具有較高的優(yōu)先級。如果任務 1 準備執(zhí)行,但必須等待任務 2 完成運行,就出現(xiàn)阻塞的狀況。同步化也會導致這種阻塞;例如,任務 1 和任務 2 共享由鎖或信號量控制的資源,任務 1 等待任務 2 對資源進行解鎖。或者,當任務 1 請求目前正由任務 2 使用的服務時,也會出現(xiàn)阻塞狀況。
1 Michael Barr.“優(yōu)先級反轉(zhuǎn)簡介”《嵌入式系統(tǒng)編程》(Embedded Systems Programming),第 15 卷:2002 年 4 月 第 4 版。 3
阻塞允許任務 2 運行,直到任務 1 等待的條件出現(xiàn)為止(例如,任務 2 對兩個任務共享的資源解鎖)。此時,任務 1 可以執(zhí)行。任務 1 須等待的總時間會隨最少時間、平均時間和最多時間變化。這種間隔就是阻塞因數(shù)。如果任務 1 必須滿足一定的時間限制,該因數(shù)就不能隨任何參數(shù)變化,如線程數(shù)或系統(tǒng)內(nèi)的輸入。換句話說,必須限制阻塞因數(shù)。
現(xiàn)在,我們引入第三個任務(任務 3)——其優(yōu)先級比任務 2 的高但比任務 1 的低(參見圖 1)。當任務 2 正在運行時,任務 3 準備運行,它會搶占任務 2,而任務 2 在任務 3 被阻塞或完成前都無法運行。當然,這樣會增加任務 1 的阻塞因數(shù);也就是說,它會進一步延遲任務 1 的運行。搶占導致的總延遲就是優(yōu)先級反轉(zhuǎn)。
實際上,可以有多個任務以這種方式搶占任務 2,從而導致連續(xù)阻塞的結(jié)果。在這種情況下,任務 2 可能被無限期地搶占,產(chǎn)生無限期的優(yōu)先級反轉(zhuǎn),導致任務 1 無法滿足其最后期限。
這時優(yōu)先級繼承就會發(fā)揮作用。如果我們回到上述假設中,在同步期內(nèi)使任務 2 以任務 1 的優(yōu)先級運行,那么任務 3 就無法搶占任務 2,這樣就能避免優(yōu)先級反轉(zhuǎn)的產(chǎn)生(參見圖 2)。
圖 1——當任務 3 搶占任務 2 時,任務 1 等待任務 2 完成運行。這進一步推遲了任務 1 的運行。 4
圖 2——任務 2 繼承了任務 1 的優(yōu)先級,因而阻止了任務 3 搶占任務 2。任務 3 不再推遲任務 1 的運行。
評論