實(shí)時(shí)操作系統(tǒng) (RTOS) 正在進(jìn)入幾乎所有物聯(lián)網(wǎng)設(shè)備,RTOS 管理低級(jí)資源和復(fù)雜時(shí)序要求的能力使其非常適合這些應(yīng)用程序,盡管嵌入式開發(fā)人員為如何設(shè)計(jì)包含 RTOS 的軟件架構(gòu)而苦苦掙扎并不少見。在今天的文章中,我們將探討開發(fā)基于 RTOS 的強(qiáng)大且靈活的軟件架構(gòu)的幾個(gè)技巧。
提示 #1 – 打破應(yīng)用程序?qū)?RTOS 的依賴
在基于 RTOS 的軟件架構(gòu)中經(jīng)常看到的一個(gè)問題是開發(fā)人員選擇他們的 RTOS,然后圍繞它構(gòu)建他們的整個(gè)軟件架構(gòu)。雖然這似乎不是一個(gè)壞主意,但維護(hù)或?qū)⒃摯a移植到可能使用不同 RTOS 的其他應(yīng)用程序可能會(huì)變得相當(dāng)頭疼。想想看,沒有 RTOS 開發(fā)人員遵循的 RTOS 接口標(biāo)準(zhǔn)(盡管 Arm 確實(shí)有 CMSIS-RTOSv2)。相反,大約有 100 個(gè)不同的 RTOS,每個(gè)都有自己的 API。切換 RTOS 需要找到并更改每個(gè) RTOS API 調(diào)用,這可能很耗時(shí)。
設(shè)計(jì)架構(gòu)的更好方法是使應(yīng)用程序與 RTOS 無關(guān)。由于大多數(shù) RTOS 都提供類似的功能,因此將 RTOS 置于操作系統(tǒng)抽象層 (OSAL) 之后,可以推遲對(duì)特定 RTOS 的選擇,同時(shí)減少應(yīng)用程序 RTOS 依賴性并提高架構(gòu)的靈活性。
提示 #2 – 使用由外而內(nèi)的技術(shù)來定義初始任務(wù)
定義任務(wù)的由外而內(nèi)的方法是一種允許嵌入式開發(fā)人員查看系統(tǒng),然后從用戶與之交互的物理特征開始分解它,然后向內(nèi)處理與應(yīng)用程序相關(guān)的任務(wù)的方法。例如,你可以想象一個(gè)連接互聯(lián)網(wǎng)的恒溫器,它具有以下功能:液晶顯示器、觸摸屏、LED背光、無線上網(wǎng)、內(nèi)存存儲(chǔ)、溫度、濕度和電流等傳感器接口、扇子、藍(lán)牙。
如你所見,這些設(shè)備大多是外向的、面向用戶的和基于硬件的設(shè)備,但由此產(chǎn)生的任務(wù)可能會(huì)被組織成以下任務(wù):輸入處理、網(wǎng)絡(luò)管理、印刷、控制器、內(nèi)存管理。
請(qǐng)記住,這是一種幫助你決定需要哪些任務(wù)的技術(shù),通常有不止一種方法可以構(gòu)建同樣有效的任務(wù)。(而且有一些只會(huì)導(dǎo)致比它們的價(jià)值更多的麻煩)。
提示 #3 – 使用速率單調(diào)調(diào)度 (RMS) 來定義任務(wù)優(yōu)先級(jí)
一旦在架構(gòu)中定義了任務(wù),使用速率單調(diào)調(diào)度來確定任務(wù)設(shè)計(jì)是否朝著正確的方向發(fā)展是很有用的。假設(shè)你有十幾個(gè)任務(wù),問題真的變成了:“我真的可以成功地安排所有這些任務(wù)并確保沒有錯(cuò)過最后期限嗎?”。RMS 旨在幫助嵌入式開發(fā)人員回答這個(gè)問題。
創(chuàng)建一個(gè)任務(wù)表,包含想要跟蹤的有關(guān)任務(wù)的所有參數(shù)。例如,包括以下數(shù)據(jù):
任務(wù)優(yōu)先級(jí)(即使我可能還沒有分配)
任務(wù)堆棧大小(或深度取決于 RTOS)
任務(wù)估計(jì)執(zhí)行時(shí)間(以毫秒為單位)
任務(wù)周期(以毫秒為單位)
任務(wù)CPU利用率(執(zhí)行時(shí)間/周期)
創(chuàng)建表后,我們將每個(gè)任務(wù)的利用率相加,然后根據(jù)系統(tǒng)中的任務(wù)數(shù)確保 CPU 利用率小于下表中的值:
如果我們的系統(tǒng)有五個(gè)任務(wù),我們希望我們的 CPU 利用率總和小于 0.743,以確保我們的任務(wù)可以被調(diào)度。(請(qǐng)記住,RMS 有很多假設(shè),但它是一個(gè)很好的健全性檢查)。
提示 #4 – 創(chuàng)建數(shù)據(jù)流圖
數(shù)據(jù)流圖通常提供數(shù)據(jù)如何流經(jīng)應(yīng)用程序的單個(gè)高級(jí)應(yīng)用程序圖片。使用 RTOS 時(shí),該圖顯示:
數(shù)據(jù)產(chǎn)生的地方
數(shù)據(jù)如何從產(chǎn)生的地方轉(zhuǎn)移到消費(fèi)的地方
數(shù)據(jù)存儲(chǔ)在哪里
如何訪問數(shù)據(jù)
該圖通常也有助于嵌入式開發(fā)人員了解系統(tǒng)中的主要 RTOS 組件。例如,圖表通常會(huì)顯示:
任務(wù)
隊(duì)列
信號(hào)量
受互斥鎖保護(hù)的共享數(shù)據(jù)
中斷服務(wù)程序
事件標(biāo)志
在布置框架代碼以測(cè)試架構(gòu)時(shí),該圖可以提供極大的幫助。
提示 #5 – 預(yù)先定義任務(wù)和消息接口
一旦創(chuàng)建了數(shù)據(jù)流圖就可以深入研究并開始編寫應(yīng)用程序,這無疑會(huì)在一段時(shí)間內(nèi)順利進(jìn)行,但如果開發(fā)人員不花時(shí)間仔細(xì)定義任務(wù)和消息接口,可能會(huì)導(dǎo)致返工。雖然數(shù)據(jù)流程圖通常顯示數(shù)據(jù)是如何通過應(yīng)用程序傳播的,但它并不一定需要定義數(shù)據(jù)結(jié)構(gòu)。
然后,目標(biāo)是預(yù)先檢查每個(gè)消息隊(duì)列,然后為這些消息構(gòu)建結(jié)構(gòu)。這很重要,因?yàn)樗鼘⒍x消息的外觀,但也將有助于任何底層模塊的接口外觀。例如,管理一系列閥門的任務(wù)可能需要包含以下內(nèi)容的消息:
閥門 ID
閥門狀態(tài)
閥門所需的準(zhǔn)時(shí)
定義閥門狀態(tài)的面罩
準(zhǔn)時(shí)列表
歸根結(jié)底,做事的方法總是不止一種,一種不一定比另一種更好。但是,在為支持任務(wù)執(zhí)行的其他模塊構(gòu)建接口時(shí),了解正在傳遞的消息將有所幫助。
結(jié)論
開發(fā) RTOS 軟件架構(gòu)是了解將要構(gòu)建的應(yīng)用程序及其主要組件的好方法。我們?cè)诮裉斓奈恼轮刑接懥藥讉€(gè)技巧,這些技巧不僅可以幫助嵌入式開發(fā)人員創(chuàng)建基于 RTOS 的更清晰、更靈活的應(yīng)用程序,還可以幫助他們傳達(dá)應(yīng)用程序的設(shè)計(jì)意圖,快速開始他們的應(yīng)用程序開發(fā),同時(shí)最大限度地減少對(duì) RTOS 的依賴。