開發固件的團隊和嵌入式軟件經常根據目標開發軟件。雖然使用開發板來了解你正在編寫代碼的處理器、外圍設備和設備不一定有什么問題,但針對目標的開發效率低下且耗時。在運行你的代碼之前,你需要交叉編譯它,刪除目標,編程它,驗證它,然后開始你的調試會話。
在與CI/CD集成和測試代碼工作時存在潛在的伸縮問題。你曾經嘗試過在嵌入式目標上運行單元測試或覆蓋率報告嗎?這是可以做到的,但要正確設置和工作通常是相當痛苦的。相反,你可以使用幾種技術來模擬你的固件和嵌入式軟件,這將幫助你快速移動而沒有額外的麻煩。
模擬技術1: Renode.io和QEMU
嵌入式開發人員在模擬系統時面臨的最大挑戰是如何模擬低級軟件。最低級別與硬件交互,這意味著需要使用特殊工具來理解硬件。在使用微控制器時,有兩種工具相對流行:Renode.io和QEMU。
QEMU是一個通用的開源機器仿真器和虛擬化器。QEMU可以模擬各種處理器,允許為一種CPU設計的軟件在另一種CPU上運行。對于使用不同架構(如ARM、PowerPC、MIPS或x86)的嵌入式系統的固件或應用程序開發人員來說,該功能非常寶貴。QEMU的缺點是你會發現對微控制器的支持不多。例如,你可能會發現微控制器可以與USART外設一起使用,但不支持定時器和ADC。
Renode是一個開發框架,通過物理硬件模擬來加速物聯網和嵌入式系統的開發。開發人員可以模擬微控制器外部的CPU、外設和設備,如傳感器。支持I2C、CAN、SPI、Flash、USB、UART等外設。Renode比QEMU更注重嵌入式。到目前為止,它對嵌入式目標的支持要好得多。
模擬技術2:關注應用程序代碼
嵌入式軟件架構是兩種架構的故事。第一個是高級業務邏輯,提供客戶功能,不關心底層硬件。第二個是與硬件交互的實時代碼,它并不關心那里有什么硬件。
當你想要模擬你的嵌入式應用程序時,你應該確定是否需要模擬該硬件相關的代碼。大多數客戶只關心他們交互的功能。如果是這樣的話,模擬你的應用程序代碼比低級代碼更重要。如果你能在硬件準備就緒之前開發并運行你的應用程序代碼,你就可以更快地將其提供給客戶。如果你在客戶面前獲得代碼,你可以獲得他們的反饋并盡早進行調整。你越早做出改變,你花在這些改變上的錢就越少,這些改變花費的時間就越少。
在主機上模擬應用程序代碼通常只不過是為該主機添加一個構建目標。例如,如果你用C或C++編寫,你將調用為編譯應用程序代碼而設置的主機構建目標。然后你可以運行生成的可執行文件。你可能認為這給使用RTOS的系統帶來了問題。通常不會。許多RTOS供應商提供可以在Windows、Linux和MacOS上編譯的RTOS版本。這意味著你可以在你選擇的RTOS上運行你的應用程序代碼!你會發現你可以添加代碼來可視化系統行為,將數據轉儲到數據庫等。
你應該問自己的問題是你是否需要模擬底層代碼。如果沒有,請集中精力模擬你的應用程序代碼。你會發現,這樣做,你也可以自然地編寫與硬件無關的代碼。結果是更加可重用、可移植和可擴展的軟件。
模擬技術3:利用指令集模擬器
另一種可以用來在主機上測試代碼的模擬器是指令集模擬器。這些模擬器允許你運行應用程序代碼和固件。它們通過在IDE中直接運行處理器和外設的低級指令來實現這一點。你會在Keil MDK,、IAR EWARM、MPLAB X等ide中找到這些模擬器。
這些模擬器的功能往往各不相同。例如,你可能會發現可以模擬處理器內核,但不支持外設。你可以驗證指令是否正確運行、算法結果等,但無法證明與外設的交互是否有效。雖然這可能不是最佳選擇,但它可以讓你脫離目標運行代碼,并在沒有獨特工具的情況下在更高級別的代碼上取得快速進展。
結論
利用模擬是一項偉大的現代技術,可以幫助你更快地開發固件。偏離目標的工作越多,效率就越高,因為你可以避免那些漫長的編譯、編程和調試周期。你會發現寫單元測試和在模擬中運行代碼會迫使你編寫更具可移植性和可重用性的代碼。脫離目標運行迫使你編寫抽象出硬件的解耦代碼。結果是一個更清晰、可擴展和可測試的軟件實現,你可以在構建硬件之前對其進行驗證。