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