嵌入式控制系統設計/作業系統
|
華夏公益教科書
嵌入式控制系統設計
|
作業系統是一個管理計算機硬體和軟體資源的計算機程式。它提供應用程式與系統硬體之間的介面。一般來說,嵌入式控制系統的作業系統具有以下職責: 任務管理 和 排程、中斷服務、程序間通訊 和 記憶體管理。這些詳細內容將在後面討論,因為我們首先從更通用的作業系統方法開始。
在為嵌入式控制系統選擇作業系統時,首先要問的問題是:作業系統真的有必要嗎?對於簡單的任務或只需要做一項工作的系統,建立直接在 微處理器 上執行的程式可能更容易、更有效率,也許可以使用 超級迴圈架構。當嵌入式控制系統必須執行更復雜的任務或能夠連線或與其他裝置互動時,就需要作業系統。作業系統將允許更大的靈活性。以下列表概述了最常見的即時作業系統。
為了便於選擇作業系統,可以考慮以下因素
- 相容性:並非所有作業系統都能在任何型別的微處理器上執行!因此,在選擇作業系統時,應該已經對可用的硬體有所瞭解。
- 系統要求和佔用空間:嵌入式系統的 佔用空間 是系統總大小。例如,如果嵌入式控制系統的總大小為 600 kB,則可以稱系統的佔用空間為 600 kB。這是一個小的佔用空間,更大的佔用空間將以 MB 為單位。必須考慮系統的佔用空間,以確保可用硬體能夠支援該系統。
- 軟體 支援:作業系統選擇中的另一個重要因素是可用的支援軟體。是編輯器、編譯器和庫很多,還是很少?這與列表中的下一個要點相關;
- 使用者數量:如果許多人使用一種作業系統,那麼該系統將有更多可用的軟體。也更容易找到文件、特定問題的解決方案或使用相同作業系統的其他人。
- 裝置驅動程式的可用性
- 動態新增程式碼的可能性:有時可能需要向已工作的系統中新增程式。作業系統允許這樣做嗎?
- 認證:某些特定應用程式要求作業系統獲得在該特定應用程式中使用的認證。一個例子是使用將在太空中使用的作業系統(衛星、火箭等)。
- 軟/硬即時:滿足定時約束有多重要?在軟即時中,計算在指定時間內未完成並不是災難(但不可取)。示例是音訊和影片播放。沒有人會注意到幾微秒的延遲。在硬即時中沒有例外:系統必須滿足指定的定時約束。硬即時系統例如外科手術機器人、太空探測器或精密機床。
在選擇作業系統時,還可以考慮以下趨勢
- 遠端訪問:越來越需要能夠遠端訪問系統。在全球各地運送機器的製造商,如果想訪問控制系統,無法去安裝機器的每個地方。因此,遠端訪問變得越來越重要。
- 安全完整性等級:安全完整性等級是對系統可靠性的相對衡量。控制危險過程的系統應該具有較高的 SIL 等級。為了達到該 SIL 等級,對軟硬體提出了具體要求。這也可能會影響作業系統的選擇。
- 作業系統開發:曾經有數百種可用的嵌入式作業系統。當微軟推出他們的 WinCE 系統時,許多系統消失了,不同系統的程式設計師共同努力建立了一個通用的嵌入式作業系統,從而進一步減少了可用系統的數量。
本節旨在更詳細地討論作業系統的基礎知識。如前所述,嵌入式作業系統需要完成的重要任務是:任務管理和排程、中斷服務、程序間通訊和記憶體管理。
任務(= 程序或執行緒)是正在執行的計算機程式的例項。程式本身只是一組被動的指令,而程序是實際執行這些指令的東西。多個程序可以與同一個程式相關聯——每個程序都會獨立執行。現代計算機系統允許在同一時間將多個程序載入到記憶體中,並且透過時間共享(或多工處理),即使只有一個處理器,也能讓人感覺它們是在同時執行的。
任務管理中困難的部分是確保特定任務能夠退出而不會阻塞其他任務。事實上,不應該盲目地刪除任務,因為它與其他任務共享了許多元件,因此在導致任務仍在使用其記憶體空間和鎖時,不應釋放其記憶體空間和鎖。
一般來說,多個任務會同時處於活動狀態。作業系統負責在任務之間共享可用資源(CPU 時間、記憶體等)。CPU 是重要的資源之一,決定如何將 CPU 在任務之間共享被稱為排程。
解決排程問題最簡單的方法是為所有任務分配靜態屬性。這意味著優先順序是在任務建立時給定的。然而,有時會為任務分配動態屬性:排程演算法必須根據動態變化引數(到下一個截止時間的時間、要處理的工作量等)線上計算任務的優先順序。很明顯,排程純粹是開銷:所有花費在計算下一個要執行的任務上的時間都被真正生產性任務浪費了。
中斷
[edit | edit source]作業系統還必須能夠為外圍硬體提供服務,例如定時器、電機、感測器、通訊裝置、磁碟等。所有這些都可以非同步地請求作業系統的關注,即當它們想要使用作業系統時,作業系統必須確保它已準備好為這些請求提供服務。這種請求關注被稱為中斷。
有兩種中斷
- 硬體中斷:外圍裝置可以在特定硬體通道上設定一個位,觸發執行作業系統的處理器,以發出裝置需要服務的訊號。該觸發的結果是處理器儲存其當前狀態,並跳轉到其記憶體空間中的一個地址,該地址在初始化時已連線到硬體中斷。
- 軟體中斷或同步中斷:許多處理器內建了軟體指令,這些指令可以用於在軟體中生成硬體中斷的效果。軟體中斷的結果也是觸發處理器,使其跳轉到預先指定的一個地址。軟體中斷出現的案例示例可能是除以零、記憶體段錯誤等。因此,這種中斷不是由硬體事件引起的,而是由特定的機器語言操作碼引起的。同步中斷通常被稱為陷阱。
許多系統擁有不止一條硬體中斷線,硬體製造商通常將所有這些中斷線組裝成一個中斷向量。硬體中斷和軟體中斷共享同一個中斷向量,但該向量隨後會為硬體中斷和軟體中斷提供獨立的範圍。
中斷控制器是一塊硬體,它可以保護作業系統免受中斷線的電子細節的影響。一些控制器能夠將中斷排隊,以確保沒有任何中斷丟失。
我們將在本書的其他章節中更詳細地討論中斷,嵌入式控制系統設計/即時作業系統#中斷服務和嵌入式控制系統設計/設計模式#中斷。
程序間通訊
[edit | edit source]不同的任務有時需要同步,例如,它們執行的順序很重要。任務之間也可能需要交換資料。一個例子是外圍裝置,其資料由專用任務處理,該任務反過來將結果傳遞給另一個任務。同步和資料交換統稱為程序間通訊。作業系統應該提供各種程序間通訊原語,以便任務可以輕鬆地同步或交換資料。
- 同步
- 訊號量
訊號量是一個受保護的變數(或抽象資料型別),是限制在多程式設計環境中訪問共享資源(例如儲存)的經典方法。它是由 Edsger Dijkstra 發明的,並首次在 THE 作業系統中使用。訊號量的值初始化為它被實現來控制的等效共享資源的數量。在只有一個等效共享資源的特殊情況下,訊號量被稱為二元訊號量。一般情況下的訊號量通常被稱為計數訊號量。訊號量是解決哲學家就餐問題的經典解決方案,儘管它們無法防止所有死鎖。 - 互斥鎖
互斥鎖是“互斥”的縮寫,是在搶佔式環境中使用的一種機制,可以防止對當前正在使用的資源進行未經授權的訪問。互斥鎖遵循以下幾個規則:互斥鎖是系統範圍內的物件,由核心維護。一次只能由一個程序擁有互斥鎖。可以透過請求核心將該互斥鎖分配給當前任務來獲取互斥鎖。如果互斥鎖已被分配,則請求函式將阻塞,直到互斥鎖可用。一般來說,儘快釋放互斥鎖被認為是良好的程式設計實踐。 - 條件變數
為了避免進入繁忙等待狀態,程序必須能夠相互發出有關其感興趣事件的訊號。監視器透過條件變數提供這種能力。當監視器函式需要滿足特定條件才能繼續執行時,它會在關聯的條件變數上等待。透過等待,它會放棄鎖並從可執行程序集中移除。任何隨後導致條件為真的程序都可以使用條件變數來通知等待該條件的程序。被通知的程序會重新獲得鎖並可以繼續執行。
- 訊號量
- 資料交換
- 緩衝區
緩衝區是記憶體中用於臨時儲存輸出或輸入資料的區域,類似於通訊中的緩衝區。資料可以輸出到或輸入自計算機外部的裝置或計算機內部的程序。緩衝區可以在硬體或軟體中實現,但絕大多數緩衝區都是用軟體實現的。當接收資料的速率與處理資料的速率不同時,或者當這些速率是可變的時,例如在印表機後臺列印程式中,就會使用緩衝區。 - FIFO
這個術語指的是儲存在佇列中的資料處理方式。佇列中的每個專案都儲存在一個佇列(simpliciter)資料結構中。新增到佇列中的第一個資料(入隊)將是第一個要刪除的資料(出隊),然後按順序依次進行處理。 - 訊息
訊息傳遞是併發程式設計、並行程式設計、面向物件程式設計和程序間通訊中使用的一種通訊形式。透過將訊息傳送到接收者來進行通訊。
- 緩衝區
記憶體管理
[edit | edit source]術語
在執行任務時,系統需要RAM記憶體。此 RAM 記憶體主要用於程式碼、資料管理和 IPC(程序間通訊)與其他任務。RAM 使得任務看起來像是執行時唯一佔用記憶體的任務。總結來說,它有三個主要任務
- 使記憶體看起來比實際更大。
- 將記憶體分配到多個頁面。
- 保護記憶體不被其他任務訪問。
在考慮這些一般作業系統要求時,必須記住它們不是即時系統的關注點。需要滿足的即時要求是
- 快速且確定的記憶體管理:當然,最快的記憶體管理是根本沒有記憶體。這意味著程式可以使用所有物理 RAM。這種方法僅在為小型嵌入式控制系統程式設計時有用。
- 頁面鎖定:每個任務都會在 RAM 中獲得固定數量的頁面。最近未使用過的頁面會被一個非確定性程序交換出去。當任務需要來自已交換頁面的程式碼或資料時,系統必須從磁碟中檢索該頁面,這通常需要 RAM 中的另一個頁面被交換出去。這意味著系統必須鎖定即時任務的頁面。否則,在程序執行期間,必要的頁面很可能被交換出去。因此,頁面鎖定是一種服務質量,意味著每個任務都能夠獲得它所需的記憶體量。
- 分配:在程序執行過程中的某個時刻,任務始終可能需要更多記憶體。這種額外的記憶體由物理 RAM 中鎖定的一個空閒頁面 池 提供。使用這種方法時要小心。無法保證記憶體池中始終有足夠的空閒頁面可用。
- 記憶體對映:即時和嵌入式系統必須訪問 外設。這些裝置將它們的資料儲存在板載暫存器中。然後,這些暫存器必須對映到相應裝置驅動程式任務的地址空間中。
- 記憶體共享:共享記憶體允許不同的任務相互通訊。作業系統將釋放共享記憶體,並同步對該記憶體的訪問。
- RAM 磁碟:這些磁碟可以用來模擬硬碟。這意味著記憶體被組織並作為檔案系統輸入。這種記憶體管理的好處是
- 避免訪問硬碟的非確定性開銷。
- 無需額外成本。
- 無需額外空間。
- 不會降低機械磁碟裝置的魯棒性。
- 快閃記憶體盤:當系統在電源關閉時需要資料儲存時,設計人員必須使用快閃記憶體盤。這些磁碟可以反覆燒錄,並且在沒有電源的情況下仍然可以保留記憶體。快閃記憶體從系統本身內部載入。
- 精簡庫:RAM 資源有限,因此設計人員更傾向於使用精簡版本的通用實用程式庫,例如 C 庫、GUI 庫 等。
Linux 中的共享記憶體
在 Linux 中,有多種方法可以分配共享記憶體。使用 RTLinux 時允許分配,而使用 RTAI 時則不允許。
- 啟動時分配:可以在啟動時保留一塊共享記憶體。這意味著 Linux 無法將其用於一般用途。不過,啟動時分配並非最佳選擇:當僅對核心映像中連結的程式碼可用時,使用這種分配的裝置驅動程式只能透過重新構建核心並重新啟動計算機來安裝或替換。
- 核心空間中的分配:使用這種方法意味著記憶體不必在啟動時準備好。此外,記憶體大小沒有限制。不幸的是,這不是一個即時程序。
- 模組中的分配:在 Linux 中,有一個名為“可載入模組支援”的選項。這意味著 Linux 可以分為不同的 模組,可以訪問和呼叫這些模組。這些模組實際上是將核心放到記憶體中並根據需要將其取出的程式碼片段。這種方法最好在啟動時使用。
裝置驅動程式
[edit | edit source]裝置驅動程式 的主要目標是允許作業系統和外設之間進行通訊。它還提供核心軟體和使用者軟體之間的連結。實現某種系統化的方法來執行此操作非常重要。這使得使用者更容易識別介面。驅動程式有責任隱藏硬體的細節,使其對作業系統乃至終端使用者不可見。本章將討論嵌入式控制系統中可用的幾種裝置驅動程式。
機制和策略
裝置驅動程式必須提供機制,而不是策略。它必須提供介面功能,但不能提供更多功能(機制)。驅動程式不會修改資料,它永遠不會更改資料流(策略)。它只是使裝置能夠以特定方式使用。
可用的裝置驅動程式
- Unix 裝置驅動程式:在 Unix 中,裝置驅動程式實際上是 Unix 核心的一部分。這使得驅動程式與獨立程式略有不同。核心由基本程式碼加上幫助系統與硬體通訊的驅動程式程式碼組成。在 Unix 中編寫裝置驅動程式時,需要檢查以下步驟
- 名稱空間:在編寫任何程式碼之前,務必為您的裝置命名。
- 記憶體分配:使用 kmalloc() 函式。這意味著記憶體以大小為 2 的冪的塊的形式提供。這方面有一個限制,即 131056 位元組。此外,kmalloc() 需要第二個引數:優先順序。然後,Kfree() 將為您提供分配記憶體的機會。
- 字元裝置與塊裝置:這是 Unix 下兩種主要的裝置型別。字元裝置不使用緩衝區,塊裝置透過快取訪問。
- 中斷 與 輪詢:中斷裝置驅動程式與輪詢裝置驅動程式之間存在差異。在 Unix 中,核心不是一個獨立的任務。系統中的每個部分或程序都有自己的核心副本[citation needed]。當系統向某個程序發出呼叫以執行某個任務時,這被稱為“核心模式”。程序沒有將控制權轉移到另一個程序。在核心模式下,資料放置位置顯而易見,因為程序在其自己的模式下執行。但是,當發生中斷時,它們會改變這種資料放置,並可能導致 宏[citation needed](允許系統訪問使用者空間記憶體)覆蓋隨機記憶體空間或導致核心崩潰。驅動程式必須安排中斷,並且在安排中斷時,它必須提供臨時空間來放置資訊。在塊裝置驅動程式中,緩衝區會安排這種臨時空間。使用字元裝置驅動程式時,裝置驅動程式本身負責分配。
- 複雜裝置驅動程式:普通裝置驅動程式只做一件事,即向外設寫入或讀取資料流。當裝置需要中斷來與使用者軟體通訊時,這些驅動程式往往會變得更加複雜。這種驅動程式需要 ISR,甚至可能還需要 DSR。裝置驅動程式變得複雜的另一個原因是:某些裝置允許使用共享記憶體甚至 直接記憶體訪問。這意味著沒有處理器參與資料交換。作業系統必須支援 DMA。在設計複雜的裝置驅動程式時,最好對裝置的結構和 API 進行標準化
- API:當裝置提供與其他裝置類似的機制時,設計人員可以使用相同的軟體介面。
- 結構:裝置驅動程式必須能夠處理介面功能的更多層。
- Comedi:資料採集卡用於測量和控制目的。Comedi 將為它們提供介面。這是一個模組化和複雜性之間的平衡。以下是設計人員在處理 Comedi 時需要牢記的一些問題
編寫 Comedi 裝置驅動程式以及編寫過程中的不同步驟在 此處 解釋。
- 即時序列線路驅動程式:這些型別的裝置驅動程式整合到 RTAI 中。它們提供
- 高度可配置的地址初始化,
- 中斷處理,
- 緩衝、回撥、非侵入式緩衝區檢查…
- 即時並行埠驅動程式:這些驅動程式整合在 Comedi 中。它們允許即時中斷處理程式連線到並行埠上的中斷。
- 即時網路驅動程式:整合在 RTAI 中,它為RTOS 和乙太網網路的裝置驅動程式提供一個通用的程式設計介面。
在開發作業系統時,如果設計符合某些標準,將有許多優勢。軟體是團隊開發的,標準使設計更容易、更快、更透明。標準提高了現有應用程式移植到新硬體的可移植性。它們還有助於不同軟體元件之間的協作。
POSIX 或“可移植作業系統介面”是由 IEEE 制定的一個系列相關標準的統稱,用於定義與 Unix 作業系統變體相容的軟體的應用程式程式設計介面 (API)。POSIX 在大約 15 個不同的文件中指定了對作業系統的使用者和軟體介面。對於即時系統,POSIX 具有以下標準
| 1003.1b | 即時擴充套件 | 即時系統所需的函式;包括對以下內容的支援:即時訊號、優先順序排程、計時器、非同步 I/O、優先順序 I/O、同步 I/O、檔案同步、對映檔案、記憶體鎖定、記憶體保護、訊息傳遞、訊號量 |
| 1003.1d | 其他即時擴充套件 | 其他介面;包括對以下內容的支援:新的程序建立語義 (spawn)、零星伺服器排程、程序和執行緒的執行時間監控、I/O 建議資訊、阻塞函式的超時、裝置控制 |
| 1003.1j | 高階即時擴充套件 | 更多即時函式,包括對以下內容的支援:型別化記憶體、nanosleep 改進、屏障同步、讀寫鎖、自旋鎖以及訊息佇列的持久通知 |
| 1003.21 | 分散式即時 | 支援即時分散式通訊的函式;包括對以下內容的支援:緩衝區管理、傳送控制塊、非同步和同步操作、有界阻塞、訊息優先順序、訊息標籤以及實現協議 |
POSIX 基於檔案系統的存在和程序的數量,定義了即時系統的配置檔案。
| 配置檔案 | 程序數量 | 執行緒 | 檔案系統 |
| 54 | 多個 | 是 | 是 |
| 53 | 多個 | 是 | 否 |
| 52 | 單個 | 是 | 是 |
| 51 | 單個 | 是 | 否 |
- 核心與使用者空間?
- 死鎖?