深度嵌入式系統通常在C語言中實現。為什么會這樣?這樣的系統是否也能從C++中獲益?嵌入式開發人員在將廣泛、高效的深度嵌入式代碼庫從C轉換為C++方面的實踐經驗的貢獻。
嵌入式和深度嵌入式系統通常用C而不是C++實現。軟件開發人員必須放棄C++作為強類型系統、模板元編程(TMP)和面向對象編程(OOP)的優勢。C++不用于嵌入式系統,因為嵌入式系統中的編譯器通常不支持較新版本的C++標準。另一個原因是對如何在這方面使用C++的知識不足,以及與C相比C++總是開銷較大的神話。
你可以使用C++嗎?
也許也沒有編譯器對你需要使用的目標系統提供足夠的C++支持。至少對于基于武器的系統來說,情況已經有了很大改善。例如,它基于Clang/LLVM,這是Arm版本6的編譯器工具鏈,因此支持C++14以及未來C++標準的更新版本。
嵌入式開發人員的經驗和開銷測量基于此工具鏈的使用。我們的應用程序(根據IEC 62304開發助聽器固件)在具有以下功能的ASIC上運行:Arm Cortex-M0 CPU,128 KB ROM和144 KB RAM。
為什么使用C++?
許多C開發人員想知道為什么他們應該在嵌入式系統中使用C++。這是因為他們可以從面向對象編程(OOP)中獲益。許多C代碼庫已經在嘗試“偽造”OOP:使用包含“類成員”的結構,使用假裝為“成員函數”的函數(指針指向該結構作為第一個參數)。如果你在C++中正確使用基本OOP方法,這將為你帶來更多好處:
l 更易于應用語法
l 編譯器檢查的變量/函數的公共/私有聲明
l 使用構造函數/析構函數控制成員變量的初始化/銷毀
更復雜的OOP概念(帶有虛擬函數),如繼承和多態性,也很難在C中維護。
嵌入式開發人員使用C++的另一個優點是支持編譯時的優化,例如模板元編程(TMP),以及編譯時對constexpr函數的求值。即使是最簡單的應用程序也為我們提供了以下優勢:
l C宏“常量”可以用正確類型的constexpr變量替換;
l C宏“函數”可以替換為模板函數,這增加了類型安全性;此外,相同的函數定義不僅可以在編譯時使用,必要時也可以在運行時使用;
l 與常規C枚舉相比,作用域枚舉(枚舉類)提供了額外的類型安全性;
l 類型轉換(在嵌入式系統中通常不可避免)可以隱藏在一個受控的、小型的類型安全模板實用程序函數庫后面。因此,(非庫)嵌入應用程序代碼中禁止所有類型轉換。
模板也可用于優化代碼大小。如果嵌入式開發人員用C語言實現,代碼的可維護性就會降低。
C++用于混合內存系統
在具有混合存儲器架構(例如ROM/RAM/NVM)的系統中,C++可用于ROM修補。例如,你有一個MyLibClass類,它被編譯并存儲在ROM中。然后你有一個MyUserClass類,它使用MyLibClass并從RAM運行,例如在引導期間從NVM加載之后。在取出ROM或甚至發布基于該ROM的產品后,你將發現MyLibClass中的一個錯誤,你希望為你的產品修復(即補丁)。
如果MyLibClass中的函數是虛擬的,這是可能的。然后,可以從MyLibClass類派生MyLibClassPatched類并覆蓋錯誤函數。MyLibClassPatched必須放在RAM中(因為ROM不能再更改)。現在嵌入式開發人員只需在MyUserClass中將MyLibClass更改為MyLibClassPatched。這修復了錯誤,無需在RAM中重新實現整個MyLibClass。