嵌入式開發(fā):C++在深度嵌入式系統(tǒng)中的應(yīng)用
深度嵌入式系統(tǒng)通常在C語言中實(shí)現(xiàn)。為什么會這樣?這樣的系統(tǒng)是否也能從C++中獲益?嵌入式開發(fā)人員在將廣泛、高效的深度嵌入式代碼庫從C轉(zhuǎn)換為C++方面的實(shí)踐經(jīng)驗(yàn)的貢獻(xiàn)。
嵌入式和深度嵌入式系統(tǒng)通常用C而不是C++實(shí)現(xiàn)。軟件開發(fā)人員必須放棄C++作為強(qiáng)類型系統(tǒng)、模板元編程(TMP)和面向?qū)ο缶幊?OOP)的優(yōu)勢。C++不用于嵌入式系統(tǒng),因?yàn)榍度胧较到y(tǒng)中的編譯器通常不支持較新版本的C++標(biāo)準(zhǔn)。另一個原因是對如何在這方面使用C++的知識不足,以及與C相比C++總是開銷較大的神話。
你可以使用C++嗎?
也許也沒有編譯器對你需要使用的目標(biāo)系統(tǒng)提供足夠的C++支持。至少對于基于武器的系統(tǒng)來說,情況已經(jīng)有了很大改善。例如,它基于Clang/LLVM,這是Arm版本6的編譯器工具鏈,因此支持C++14以及未來C++標(biāo)準(zhǔn)的更新版本。
嵌入式開發(fā)人員的經(jīng)驗(yàn)和開銷測量基于此工具鏈的使用。我們的應(yīng)用程序(根據(jù)IEC 62304開發(fā)助聽器固件)在具有以下功能的ASIC上運(yùn)行:Arm Cortex-M0 CPU,128 KB ROM和144 KB RAM。
為什么使用C++?
許多C開發(fā)人員想知道為什么他們應(yīng)該在嵌入式系統(tǒng)中使用C++。這是因?yàn)樗麄兛梢詮拿嫦驅(qū)ο缶幊?OOP)中獲益。許多C代碼庫已經(jīng)在嘗試“偽造”O(jiān)OP:使用包含“類成員”的結(jié)構(gòu),使用假裝為“成員函數(shù)”的函數(shù)(指針指向該結(jié)構(gòu)作為第一個參數(shù))。如果你在C++中正確使用基本OOP方法,這將為你帶來更多好處:
l 更易于應(yīng)用語法
l 編譯器檢查的變量/函數(shù)的公共/私有聲明
l 使用構(gòu)造函數(shù)/析構(gòu)函數(shù)控制成員變量的初始化/銷毀
更復(fù)雜的OOP概念(帶有虛擬函數(shù)),如繼承和多態(tài)性,也很難在C中維護(hù)。

嵌入式開發(fā)人員使用C++的另一個優(yōu)點(diǎn)是支持編譯時(shí)的優(yōu)化,例如模板元編程(TMP),以及編譯時(shí)對constexpr函數(shù)的求值。即使是最簡單的應(yīng)用程序也為我們提供了以下優(yōu)勢:
l C宏“常量”可以用正確類型的constexpr變量替換;
l C宏“函數(shù)”可以替換為模板函數(shù),這增加了類型安全性;此外,相同的函數(shù)定義不僅可以在編譯時(shí)使用,必要時(shí)也可以在運(yùn)行時(shí)使用;
l 與常規(guī)C枚舉相比,作用域枚舉(枚舉類)提供了額外的類型安全性;
l 類型轉(zhuǎn)換(在嵌入式系統(tǒng)中通常不可避免)可以隱藏在一個受控的、小型的類型安全模板實(shí)用程序函數(shù)庫后面。因此,(非庫)嵌入應(yīng)用程序代碼中禁止所有類型轉(zhuǎn)換。
模板也可用于優(yōu)化代碼大小。如果嵌入式開發(fā)人員用C語言實(shí)現(xiàn),代碼的可維護(hù)性就會降低。
C++用于混合內(nèi)存系統(tǒng)
在具有混合存儲器架構(gòu)(例如ROM/RAM/NVM)的系統(tǒng)中,C++可用于ROM修補(bǔ)。例如,你有一個MyLibClass類,它被編譯并存儲在ROM中。然后你有一個MyUserClass類,它使用MyLibClass并從RAM運(yùn)行,例如在引導(dǎo)期間從NVM加載之后。在取出ROM或甚至發(fā)布基于該ROM的產(chǎn)品后,你將發(fā)現(xiàn)MyLibClass中的一個錯誤,你希望為你的產(chǎn)品修復(fù)(即補(bǔ)丁)。
如果MyLibClass中的函數(shù)是虛擬的,這是可能的。然后,可以從MyLibClass類派生MyLibClassPatched類并覆蓋錯誤函數(shù)。MyLibClassPatched必須放在RAM中(因?yàn)镽OM不能再更改)?,F(xiàn)在嵌入式開發(fā)人員只需在MyUserClass中將MyLibClass更改為MyLibClassPatched。這修復(fù)了錯誤,無需在RAM中重新實(shí)現(xiàn)整個MyLibClass。