實時系統介紹
實時系統有各種各樣的實現方式和使用情況。本書的重點是如何使用實時操作系統(RTOS)在微控制器單元(MCU)上創建實時應用程序。
在這一章中,我們將首先概述什么是RTOS,并了解可能有實時要求的廣泛系統。從那里,我們將看看實現實時性能的一些不同方法,以及可能使用的系統類型(如硬件、固件和軟件)的概述。最后,我們將討論什么時候在MCU應用中使用RTOS是明智的,什么時候可能完全沒有必要。
到底什么是實時性?
任何對特定事件有確定響應的系統都可以被認為是 "實時 "的。如果一個系統在不符合時間要求時被認為是失敗的,它一定是實時的。如何定義故障(以及故障系統的后果)可以有很大不同。認識到實時性要求可以有很大的不同,這一點極其重要,既包括時間要求的速度,也包括如果沒有達到所要求的實時期限,后果的嚴重性。
時序要求的范圍
為了說明可能遇到的定時要求的范圍,讓我們考慮從模數轉換器(ADC analog-to-digital converters)獲取讀數的幾個不同系統。
我們要看的第一個系統是一個控制系統,它被設置為控制烙鐵的溫度(如下圖所示)。我們所關注的系統部分是MCU、ADC、傳感器和加熱器。
MCU負責以下工作:
- 通過ADC從溫度傳感器獲取讀數
- 運行閉環控制算法(以保持烙鐵頭的溫度恒定)。
- 根據需要調整加熱器的輸出
由于焊頭的溫度變化不是非常快,MCU可能只需要每秒獲取50個ADC樣本(50Hz)。負責調整加熱器的控制算法(以保持恒定的溫度)以更慢的速度運行,5赫茲:
ADC將斷言硬件線路,表示轉換已經完成,并準備讓MCU將讀數轉移到其內部存儲器。讀取ADC的MCU有多達20毫秒的時間將數據從ADC傳輸到內部存儲器,然后才需要進行新的讀取。MCU還需要運行控制算法來計算加熱器輸出的更新值,頻率為5赫茲(200毫秒)。這兩種情況(雖然不是特別快)都是實時要求的例子:
現在,在ADC讀數的另一端,我們可能有高帶寬的網絡分析儀或示波器,它將以幾十GHz的速率讀取ADC!在這種情況下,ADC的原始讀數很可能是在幾百個小時內完成!原始ADC讀數可能會被轉換成頻域,并在高分辨率前面板上以圖形方式顯示,每秒幾十次。像這樣的系統需要進行大量的處理,必須遵守極其嚴格的時間要求,如果它要正常運作的話。
在光譜的中間位置,你會發現諸如閉環運動控制器等系統,它們通常需要在數百赫茲至數十千赫茲之間執行其PID控制回路,以便在快速移動的系統中提供穩定性。那么,實時性有多快?嗯,僅從ADC的例子就可以看出,這取決于。
在前面的一些例子中,如示波器或電烙鐵,如果不能滿足計時要求,就會導致性能不佳或報告錯誤的數據。在電烙鐵的情況下,這可能是溫度控制不佳(這可能導致組件損壞)。對于測試設備來說,錯過最后期限可能導致錯誤的讀數,這就是失敗。這對一些人來說可能不是什么大問題,但對該設備的用戶來說,他們依賴所報告數據的準確性,這可能是非常重要的。一些用于標準驗證的實驗室設備對產品的一致性進行檢查。如果設備中存在未被發現的故障,導致測量不準確,就可能報告出不正確的數值。可能有可能重新進行可疑的測試。然而,最終,如果重新測試的頻率過高,可靠的讀數不能指望,那么測試設備將開始變得可疑,并被視為不可靠,銷售將下降--所有這些都是因為一個實時要求沒有得到持續滿足。
在其他系統中,如無人機的飛行控制或工業過程控制中的運動控制,如果不能及時運行控制算法,可能會導致更多的物理災難,如崩潰。在這種情況下,其后果有可能危及生命。
值得慶幸的是,可以采取一些措施來避免所有這些故障情況的發生。
保證實時行為的方法
確保一個系統做它要做的事情的最簡單的方法之一是確保它在滿足要求的同時盡可能的簡單。這意味著要抵制將簡單的任務過度復雜化的沖動。如果烤面包機是用來烤面包的,就不要在上面加一個顯示屏,讓它也告訴你天氣情況;只要讓它在適當的時間內打開加熱元件即可。這個簡單的任務已經完成了多年,不需要任何代碼或可編程設備。
作為程序員,如果我們遇到一個問題,我們傾向于立即伸手去拿最近的MCU并開始編碼。然而,產品的一些功能(尤其是當產品有電子機械部件時)最好不用代碼來處理。車窗其實不需要帶輪詢循環的MCU來運行,通過驅動器打開電機,觀察傳感器的反饋來關閉它們。這項任務實際上可以由一些機械開關和二極管來處理。如果給定的系統需要一個反饋報告機制--比如在窗口卡住的情況下需要斷言錯誤--那么可能別無選擇,只能使用一個更復雜的解決方案。然而,作為工程師,我們的目標應該始終是相同的--盡可能簡單地解決問題,不增加額外的復雜性。
如果一個問題可以單獨通過硬件來解決,那么在拿出MCU之前,先與團隊一起探討這種可能性。如果問題可以通過使用簡單的while循環來執行一些傳感器狀態的輪詢來處理,那么就簡單地輪詢傳感器的狀態;可能沒有必要開始編碼中斷服務程序(ISRs)。如果設備的功能是單一用途的,那么在很多情況下,完整的實時操作系統可能會妨礙工作--所以不要使用它!
實時系統的類型
有許多不同的方法來實現實時行為。下面的部分是關于你可能遇到的各種類型的實時系統的討論。還要注意的是,有可能出現以下系統的組合,作為子系統一起工作。這些不同的子系統可以出現在產品、板卡、甚至是芯片層面(這種方法在第16章多處理器和多核系統中討論)
硬件
最初的實時系統,即硬件,仍然是滿足極其嚴格的公差和/或快速定時要求的首選。它可以用離散數字邏輯、模擬組件、可編程邏輯或特定應用集成組件(ASIC application-specific integrated component)來實現。可編程邏輯器件(PLD Programmable logic devices)、復雜可編程邏輯器件(CPLD complex programmable logic devices)和域可編程門陣列(FPGA field-programmable gate arrays)是該解決方案中可編程邏輯器件部分的不同成員。基于硬件的實時系統可以涵蓋從模擬濾波器、閉環控制和簡單的狀態機到復雜的視頻編解碼器的任何東西。當實施時考慮到省電,可以使ASIC比基于MCU的解決方案消耗更少的功率。一般來說,硬件的優點是可以即時并行地進行操作(當然,這是過度簡化),而單核MCU則只能給人以并行處理的假象。
實時硬件開發的缺點一般包括以下幾點:
- 非可編程設備的不靈活性。
- 所需的專業技術通常不如軟件/固件開發人員那么普遍。
- 全功能可編程器件的成本(例如,大型FPGA)。
- 開發定制ASIC的高成本。
裸機固件
裸機固件被認為是(為我們的目的)不是建立在某種類型的預先存在的內核/調度器之上的任何固件。一些工程師更進一步,認為真正的裸機固件不能使用任何預先存在的庫(如供應商提供的硬件抽象庫),這種觀點也有一定的道理。裸機實現的好處是,用戶的代碼可以完全控制硬件的所有方面。主循環代碼執行被打斷的唯一方法是中斷發生時。在這種情況下,其他東西控制CPU的唯一方法是讓現有的ISR完成,或讓另一個更優先的中斷啟動。
當有少量相對簡單的任務需要執行時,或者有單一的任務時,裸機固件解決方案就很出色。如果固件保持專注并遵循最佳實踐,由于ISR(或在某些情況下,缺乏ISR)之間的相互作用相對較少,確定的性能通常容易測量和保證。在一些極端的情況下,對于高負載的MCU(或在ROM/RAM方面受到高度限制的MCU),裸機是唯一的選擇。
隨著裸機實現在異步處理事件時變得更加復雜,它們開始與實時操作系統提供的功能重疊。要記住的一個重要考慮是,通過使用RTOS--而不是試圖推出你自己的線程安全系統--你會自動受益于RTOS供應商所做的所有測試。你也有機會使用具有事后分析能力的代碼--今天所有的RTOS都已經存在了好幾年了。作者一直在調整和增加功能,以使它們在不同的應用中變得強大和靈活。
基于RTOS的固件
在MCU上運行調度內核的固件是基于RTOS的固件。調度器和一些RTOS原件的引入允許任務在它們自己擁有處理器的假象下運行(在第2章,了解RTOS任務中詳細討論)。使用RTOS可以使系統在后臺執行其他復雜任務的同時保持對最重要事件的響應。
所有這些任務的運行都有一些弊端。共享數據的任務之間可能會出現相互依賴的情況--如果處理不當,這種依賴性會導致任務意外地阻塞。雖然有處理這種情況的規定,但它確實增加了代碼的復雜性。中斷一般會使用任務信令來盡快處理中斷,并將盡可能多的處理推遲到任務中。如果處理得當,這種解決方案對于保持復雜系統的響應是非常好的,盡管有許多復雜的互動。然而,如果處理不當,這種設計范式會導致更多的時間抖動和更少的確定性。
基于RTOS的軟件
運行在包含內存管理單元(MMU)和中央處理單元(CPU)的完整操作系統上的軟件被認為是基于RTOS的軟件。用這種方法實現的應用程序可能非常復雜,需要在各種內部和外部系統之間進行許多不同的交互。使用完整的操作系統的好處是伴隨著它的所有能力--包括硬件和軟件。
在硬件方面,通常有更多的CPU核心以更高的時鐘速率運行。可以有數千兆字節的內存和持久性存儲器。增加外圍硬件可以像增加一塊卡一樣簡單(只要有預先存在的驅動程序)。
在軟件方面,有大量用于網絡堆棧、用戶界面開發、文件處理等的開源和供應商專有解決方案。在所有這些能力和選項之下,內核仍然以這樣一種方式實現,即關鍵任務不會被無限期地阻斷,這在傳統的操作系統中是可能的。正因為如此,獲得確定性的性能仍然是可以做到的,就像RTOS固件一樣。
精心制作的操作系統軟件
與基于RTOS的軟件類似,一個標準的操作系統擁有開發者可以要求的所有庫和功能。然而,缺少的是對滿足時間要求的嚴格關注。一般來說,用傳統操作系統實現的系統會有更少的確定性行為(在安全關鍵的情況下,沒有一個可以真正指望的)。如果在沒有災難性后果的情況下,有一個寬松的實時性要求,如果沒有按時完成一個躊躇滿志的最后期限,只要在選擇運行什么軟件堆棧和控制它們的資源使用方面謹慎行事,標準的操作系統就可以發揮作用。帶有PREEMPT_RT補丁的Linux內核是這種類型的實時系統的一個很好的例子。
所以,現在實現實時系統的所有選項都已被列出,現在是時候準確定義我們說的RTOS,特別是基于MCU的RTOS是什么意思。
定義實時操作系統
操作系統(如Windows、Linux和macOS)的創建是為了提供一個一致的編程環境,將底層硬件抽象化,使其更容易編寫和維護計算機程序。它們為應用程序員提供了許多不同的基元(如線程和互斥),可以用來創建更復雜的行為。例如,可以創建一個多線程程序,提供對共享數據的保護性訪問:
前面的應用程序并沒有實現線程和互斥基元,它只是利用了它們。線程和互斥的實際實現是由操作系統處理的。這有幾個優點:
- 應用程序代碼不那么復雜。
- 更容易理解--無論哪個程序員都使用相同的原語,從而更容易理解由不同人創建的代碼。
- 硬件可移植性更好--有了適當的預防措施,代碼可以在操作系統支持的任何硬件上運行而無需修改。
在前面的例子中,mutex被用來確保每次只有一個線程可以訪問共享數據。在通用操作系統的情況下,每個線程都會很高興地等待突變體無限期地可用,然后再去訪問共享數據。這是實時操作系統與通用操作系統不同的地方。在RTOS中,所有阻塞的系統調用都是有時間限制的。RTOS不允許無限期地等待mutex,而是允許指定一個最大延遲。例如,如果線程1試圖獲取Mutex,但在100毫秒(或1秒)后仍未得到它,它將繼續等待Mutex變得可用。
在RTOS的實現中,要指定等待Mutex變得可用的最大時間。如果線程1指定它必須在100毫秒內獲取Mutex,并且在101毫秒后仍未收到Mutex,線程1將收到通知,說Mutex沒有被及時獲取。指定這個超時是為了幫助創建確定性的系統。
任何提供執行給定代碼的確定性方式的操作系統都可以被認為是實時操作系統。這個實時操作系統的定義涵蓋了相當多的系統。
有幾個特征傾向于將RTOS應用與另一RTOS應用區分開來:不滿足實時截止日期的頻率是可以接受的,以及不滿足實時截止日期的嚴重程度。不同范圍的RTOS應用通常被歸納為三類--硬、固和軟實時系統。
不要太糾結于固和軟實時系統之間的區別。這些術語的定義在我們的行業內甚至沒有一致的意見。重要的是,你要知道你的系統的要求,并設計一個解決方案來滿足這些要求!
如果故障會導致生命或重大財產的損失,那么故障的嚴重程度一般被認為是安全關鍵型的。有一些硬實時系統與安全無關。
硬實時系統
硬實時系統必須在100%的時間內滿足其最后期限。如果系統沒有達到最后期限,那么它就被認為是失敗了。這并不一定意味著如果故障發生在硬實時系統中就會傷害到人,只是說如果系統錯過了一個截止日期,它就失敗了。
硬實時系統的一些例子可以在醫療設備中找到,如心臟起搏器和具有極其嚴格控制參數的控制系統。在心臟起搏器的情況下,如果心臟起搏器錯過了在正確的時間點進行電脈沖的最后期限,它可能會殺死病人(這就是為什么心臟起搏器被定義為安全關鍵型系統)。
相反,如果計算機數控(CNC)銑床上的運動控制系統沒有及時對指令做出反應,它可能會將刀具插入正在加工的零件的錯誤部位,從而毀掉它。在我們提到的這些案例中,故障造成了生命損失,而另一個則把一些金屬變成了廢品,但這兩個故障都是由錯過的最后期限造成的。
固實時系統
與硬實時系統相比,固實時系統幾乎在所有時間都需要達到其最后期限。如果視頻和音頻瞬間失去同步,可能不會被認為是系統故障,但可能會使視頻的消費者感到不安。
在大多數控制系統中(類似于前一個例子中的烙鐵),稍微超出規定時間的幾個樣本的讀取不太可能完全破壞系統控制。如果控制系統有ADC,可以自動獲取新的樣本,如果MCU沒有及時讀取新的樣本,它將被新的樣本覆蓋。這種情況可能偶爾發生,但如果發生得太頻繁或太頻繁,溫度穩定性就會被破壞。在要求特別高的系統中,可能只需要錯過幾個樣本,整個控制系統就會失靈。
軟實時系統
當涉及到系統必須滿足其最后期限的頻率時,軟實時系統是最寬松的。這些系統通常只提供一個遵守最后期限的最大努力的承諾。
汽車中的巡航控制是軟實時系統的很好的例子,因為對它沒有硬性規定或期望。駕駛員通常不期望他們的速度能收斂到設定速度的+/- x mph/kph之內。他們期望在合理的情況下,例如沒有大的坡度,控制系統最終會讓他們在大多數時間內接近他們的理想速度。
實時操作系統的范圍
實時操作系統的功能各不相同,它們最適合的處理器架構和尺寸也各不相同。在較小的方面,我們有較小的以8-32位MCU為重點的RTOS,如FreeRTOS、Keil RTX、Micrium μC、ThreadX,以及更多。 這類RTOS適合在微控制器上使用,并提供一個緊湊的實時內核作為最基本的產品。當從MCU轉向32位和64位應用處理器時,你會傾向于找到RTOS,如Wind River VxWorks和Wind River Linux、Green Hills的Integrity OS,甚至是帶有PREEMPT_RT內核擴展的Linux。這些完整的操作系統提供了大量的軟件選擇,為實時調度要求以及一般計算任務提供了解決方案。即使有了我們剛剛提到的操作系統,我們也只是觸及了可用的表面。在所有級別的實時操作系統中,無論大小,都有免費和付費的解決方案(有些價格遠遠超過10000美元)。
那么,既然有免費的解決方案,你為什么還要選擇付費呢?免費提供的RTOS解決方案和付費解決方案之間的主要區別因素是安全批準、中間件和客戶支持。 因為實時操作系統提供了高度確定的執行環境,它們經常被用于復雜的安全關鍵型應用。我們所說的安全關鍵,一般是指一個系統,其故障可能會傷害人或造成重大損失。這些系統需要確定性的操作,因為它們必須一直以可預測的方式行事。保證代碼在固定的時間內對事件做出反應是確保它們行為一致的重要一步。這些安全關鍵型應用中的大多數都受到監管,并有自己的一套管理機構和標準,如飛機的DO-178B和DO-178C或工業應用的IEC 61508 SIL 3和ISO 26262 ASILD。為了使安全關鍵型認證更經濟實惠,設計者通常會保持這些系統的代碼極其簡單(因此有可能從數學上證明系統將穩定運行,不會出錯),或者轉向已經通過認證的商業RTOS解決方案,作為一個起點。威騰斯丁公司的SafeRTOS是FreeRTOS的衍生產品,已獲得工業、醫療和汽車領域的認證。
中間件也可以是復雜系統中的一個極其重要的組成部分。中間件是運行在用戶代碼(你,應用程序員編寫的代碼)和較低層,如RTOS或裸機(無RTOS)之間的代碼。付費解決方案的另一個價值主張是,生態系統提供了一套預集成的高質量中間件(如文件系統、網絡堆棧、GUI框架、工業協議等),最大限度地減少了開發,降低了整體項目風險。使用中間件而不是自己開發的原因是為了減少內部開發團隊編寫的原始代碼量。這既降低了風險,也減少了團隊花費的總時間--因此,根據項目復雜性和進度要求等因素,這可能是一項值得的投資。
付費解決方案通常也會直接由固件供應商提供某種程度的客戶支持。雇傭和保留工程師的成本很高。管理人員最害怕的莫過于走進一個滿是工程師的房間,這些人正在為他們的工具而困惑,而不是為需要解決的真正問題而工作。有了專家的幫助,只需一封電子郵件或一個電話,就可以大大提高團隊的生產力,從而縮短周轉時間,使每個人的工作環境更加愉快。
FreeRTOS有付費的支持和培訓選項,以及付費的中間件解決方案,這些都可以被整合。然而,也有開放源碼和/或免費提供的中間件組件,其中一些將在本書中討論。
本書使用的RTOS
什么這本書只涉及一個MCU模型上的一個RTOS?有幾個原因,其中一個原因是我們要講的大部分概念幾乎適用于任何可用的RTOS,就像良好的編碼習慣超越了你碰巧要編碼的語言一樣。通過專注于一個RTOS和一個MCU的單一實現,我們將能夠更深入地探討一些話題,而不是在嘗試討論所有的替代方案時才有可能。
FreeRTOS是最流行的用于MCU的RTOS實現之一,而且非常廣泛。它已經存在了15年之久,并且已經被移植到幾十個平臺。如果你曾經與熟悉RTOS編程的真正的底層嵌入式系統工程師交談過,他們肯定聽說過FreeRTOS,而且很可能至少使用過一次。通過把注意力集中在FreeRTOS上,你將有能力迅速地把你的FreeRTOS知識遷移到其他硬件上,或者在情況需要時過渡到其他RTOS。
我們使用FreeRTOS的另一個原因?嗯,它是免費的! FreeRTOS是在MIT許可下發布的。
下面的圖表顯示了FreeRTOS在一個典型的ARM固件堆棧中的位置。堆棧指的是構成系統的所有不同層的固件組件,以及它們是如何堆疊在一起的。這里的用戶是指使用FreeRTOS的程序員(而不是嵌入式系統的終端用戶):
一些值得注意的項目如下:
- 用戶代碼能夠訪問相同的FreeRTOS API,不管底層的硬件端口實現如何。
- FreeRTOS并不阻止用戶代碼使用供應商提供的驅動程序、CMSIS或原始硬件寄存器。
- 擁有一個在不同硬件間一致的標準化的API意味著代碼可以很容易地在硬件目標之間遷移,而不需要不斷地重寫。讓代碼直接與硬件對話的能力也提供了必要時編寫極其有效的代碼的手段(以犧牲可移植性為代價)。
何時使用實時操作系統
偶爾,當有人第一次了解到實時操作系統這個術語時,他們會錯誤地認為實時操作系統是在嵌入式系統中實現實時行為的唯一方法。這當然是可以理解的(尤其是考慮到這個名字),但這與事實相去甚遠。有時,最好把RTOS看作是一種潛在的解決方案,而不是用于一切的解決方案。一般來說,對于一個基于MCU的RTOS來說,要成為一個特定問題的理想解決方案,它需要有Goldilocks級別的復雜性--不要太簡單,但也不要太復雜。
如果有一個極其簡單的問題,例如監測兩個狀態并在它們同時出現時觸發警報,那么解決方案可能是一個直接的硬件解決方案(例如一個AND門)。在這種情況下,可能沒有理由使事情進一步復雜化,因為AND門的解決方案將是非常快的,具有高度的確定性和極端的可靠性。它也將需要很少的開發時間。
現在,考慮一下只有一兩個任務需要執行的情況,如控制電機的速度和觀察編碼器以確保正確的距離被穿越。這當然可以用離散的模擬和數字硬件來實現,但有可配置的距離會增加一些復雜性。此外,調整控制環路的系數很可能需要調整電位器的設置(可能是針對每個單獨的板子),按照今天的制造標準,這在某些或大多數情況下是不可取的。因此,在硬件解決方案方面,我們只能用CPLD或FPGA來實現運動控制算法和跟蹤行走的距離。這恰好是一個非常合適的選擇,因為它有可能小到可以裝入CPLD,但在某些情況下,FPGA的成本可能是不可接受的。這個問題也是由MCU經常處理的。如果現有的內部資源不具備硬件語言或工具鏈所需的專業知識,那么裸機MCU固件解決方案可能是一個不錯的選擇。
假設問題更加復雜,例如控制幾個不同執行器的設備,從傳感器中讀取數據,并將這些值存儲在本地存儲器中。也許該設備還需要坐在某種網絡上,如以太網、Wi-Fi、控制器區域網絡(CAN),等等。一TOS可以很好地解決這種類型的問題。事實上,有許多不同的任務需要完成,或多或少地相互異步,這使得我們很容易認為RTOS帶來的額外復雜性將得到回報。實時操作系統幫助我們確保低優先級的、更復雜的任務,如網絡和文件系統堆棧,不會干擾時間更緊迫的任務(如控制執行器和讀取傳感器)。在許多情況下,可能會有某種形式的控制系統,通常會從在明確的時間間隔內運行中受益,這是實時操作系統的優勢。
現在,考慮一個與前面類似的系統,但現在有多種網絡要求,例如為網頁提供服務,處理復雜的企業環境中的用戶認證,以及將文件推送到需要基于不同網絡文件協議的各種共享目錄。這種復雜程度可以用RTOS來實現,但同樣,根據可用的團隊資源,這可能最好留給完整的操作系統來處理(無論是RTOS還是通用的),因為許多所需的復雜軟件堆棧已經存在。有時,可以采取多核方法,其中一個核心運行RTOS,另一個運行通用操作系統。
現在,可能很明顯,沒有確切的方法來確定哪種實時解決方案對所有情況都是正確的。每個項目和團隊都有自己獨特的要求、背景、技能組合和背景,為這個決定提供了舞臺。選擇一個問題的解決方案有很多因素;重要的是要保持開放的心態,選擇在那個時間點上最適合你的團隊和項目的解決方案。
評論
查看更多