RTOS 設計已成為許多嵌入式應用的關鍵,RTOS 用于超過 50% 的嵌入式應用程序,并且隨著如此多的設備開始連接并開始使用機器學習,這些數字只會增加。嵌入式開發人員在設計基于 RTOS 的應用程序時,有許多注意事項,在今天的文章中,我們探討5個RTOS 設計最佳實踐。
1. 數據決定設計
好的軟件設計是由數據驅動的,換句話說,數據決定設計。大多數系統是事件生成數據的實時系統,反過來,這些數據必須以各種方式流經應用程序,進行處理,然后存儲或輸出。
在開始 RTOS 設計,甚至任何嵌入式應用程序設計時,首先要識別應用程序中的所有數據源。首先創建一個列表;接下來,在圖表中繪制塊并標記數據源;最后,將數據源映射到它們的最終目的地,標記數據如何轉換、如何處理以及哪些應用程序區域使用數據。當完成時,任務、數據存儲、同步機制等自然會從數據流中出來。
2. 使用 RMS 驗證你的設計
RMS,最著名的是速率單調調度,是一種分析技術,設計人員可以使用它來測試他們關于系統中的任務是否可以成功調度的假設。RMS 存在多種模型,最基本的模型假設:
任務是周期性的
任務是獨立的
使用搶占式調度
每個任務都有一個恒定的最壞情況執行時間
所有任務都同樣重要
非周期性任務僅限于啟動和故障恢復
乍一看,其中一些假設對于現實世界似乎非常不切實際,但是,大多數設計都可以使用它們進行分解和驗證。(更復雜的模型改進了這些假設)。示例分析如下:
3. 任務分解從外向內開始
將應用程序分解為任務可能具有挑戰性,嵌入式開發人員經常發現自己會提出以下問題:
我的任務太多了嗎?
我沒有足夠的任務嗎?
可以安排所有這些任務嗎?
這些任務應該合并還是分開?
開始分解應用程序時,最好的方法是從外向內。首先查看硬件設備以及系統的輸入和輸出,查看數據和生成數據的速率,輸入/輸出和硬件及其數據流將有助于識別系統中的主要任務,例如,你最終可能會得到一個簡單的圖表,如下所示:
上圖標識了五個主要任務,然后是一個可以進一步分解的應用程序塊。
4. 使用 OSAL 解耦 RTOS
很多公司圍繞他們的 RTOS 構建他們的整個應用程序,RTOS 應該是應用程序中的一個組件,而不是應用程序的基礎。問題是開發人員無法控制 RTOS,如果 RTOS 發生更改,則應用程序無法免受這些更改的影響,如果 RTOS 突然不再可用或被某人購買,更改為不同的 RTOS 可能與重寫大部分應用程序一樣痛苦。
這里的最佳實踐是使用操作系統抽象層 (OSAL)。它可以非常優雅地融入軟件架構,如下圖所示:
請注意,RTOS 只是應用程序堆棧中間的另一個組件。如果我們想換出新的 RTOS,我們需要做的就是將 OSAL 映射更改為新的 RTOS。應用程序將不知道發生了什么變化!
OSAL 本質上充當依賴屏障,并將使用通用操作系統調用。例如,每個 RTOS 都有一個信號量、互斥量等。OSAL 為常見的 RTOS 功能提供了通用 API。如果需要一些特定于操作系統的功能,這些功能不在像 CMSIS-RTOS2 這樣的通用 OSAL 中,那么嵌入式開發人員應該為 OSAL 編寫自己的擴展。這將繼續限制應用程序對 RTOS 的耦合和依賴。畢竟,你永遠不知道它什么時候會改變。
5. 不要將信號量用作互斥體
互斥量和信號量是為不同的目的而設計的。互斥鎖旨在提供對資源的互斥訪問。信號量是為任務通知和協調而設計的。
設計人員和開發人員經常使用二進制信號量作為互斥體。互斥鎖可以鎖定/解鎖資源。可以給出或獲取二進制信號量,從而導致看起來很像鎖定/解鎖的狀態。但是,這兩者之間有一個重要的區別。互斥體有一個稱為優先級繼承的特性。在優先級倒置的情況下,優先級繼承可以提升任務的優先級,將優先級倒置的影響降到最低。
信號量不支持優先級繼承,因此當用作互斥體時會導致優先級反轉和其他設計問題。確保你了解這些差異,并且永遠不要使用信號量來保護數據訪問。使用正確的工具,即互斥鎖。
結論
RTOS 設計正在成為或已經成為嵌入式開發人員需要執行的一項常見活動,很多困難可以通過我們剛剛研究的5個RTOS設計最佳實踐來緩解。仔細研究這些方法,你可以避免很多煩惱。