嵌入式軟體生命週期常達數年甚至十年,前期捷徑將導致後期指數級成本。以下十大鐵律源自資深嵌入式工程師 Timothy Stapko 實戰總結,針對嵌入式特有約束(資源受限、硬體耦合、長期演進)量身打造。
除非極端平台(如低端 PIC)或極少數效能熱點,否則優先用 C/C++。組合語言難除錯、難移植、難理解。若必須用:逐行註解、塊註解寫偽碼、單塊不超過 5-6 條指令。
代碼變更時必須同步更新註解。將註解寫在函數內部而非上方,或用分隔線明確界定註解歸屬範圍,防止插入新函數導致註解與代碼分離。
先寫正確、清晰、簡單的代碼,通過完整測試後,再用分析工具(gprof, VTune)定位瓶頸針對性優化。隨意優化製造難讀代碼且往往無效。
ISR 只做:讀取硬體資料 → 放入環狀緩衝區 → 置標誌位通知主迴圈。所有業務邏輯移至主迴圈/任務。異步特性使 ISR 除錯極難,簡單即可靠。
開發期加入的 printf、LED 閃爍、斷言等除錯碼,發布構建時必須移除。推薦:條件編譯(#ifdef DEBUG)或隔離到獨立模組/庫,構建時不鏈接。預留除錯介面供維護期復用。
勿在業務邏輯中直接操作暫存器/呼叫廠商 API。自建薄封裝層(巨集/內聯函數),所有硬體相關操作集中於此。移植新平台時只需重寫 HAL 層,業務碼零修改。
嵌入式代碼常與硬體功能單元對應。將函數拆分至「單一硬體功能」粒度為宜,單一呼叫鏈深度控制在 5-6 層以內。過度拆分增加呼叫開銷與除錯難度。
避免濫用:goto、三元運算子控制流、短路求值副作用、複雜模板元編程、繼承濫用。明確的 if-else 勝過巧妙的單行技巧。代碼審查標準:「新成員 15 分鐘能看懂嗎?」
常數、巨集、條件編譯開關、記憶體映射地址、版本號集中放在 config.h / defs.h / build_config.h 等少數檔案。分散在各處的魔術數字是維護噩夢。
| # | 檢查項 | 違規典型徵兆 |
|---|---|---|
| 1 | 無非必要組語 | .s/.asm 檔案超過 1 個或超過 50 行 |
| 2 | 註解同步 | 註解描述已刪除功能 |
| 3 | 無過早優化 | 未測試即出現手動展開迴圈、位運算技巧 |
| 4 | ISR < 20 行 | ISR 中呼叫非重入函數/動態分配 |
| 5 | Release 0 除錯碼 | 二進位含 "DEBUG" 字串 |
| 6 | HAL 層完整 | 業務 .c 中出現暫存器名稱 |
| 7 | 呼叫深度 ≤ 6 | 堆疊追蹤超過 8 層 |
| 8 | 文檔同倉庫 | Wiki/SharePoint 獨立於代碼倉 |
| 9 | 無花俏技巧 | 出現 a^=b^=a^=b 交換變數 |
| 10 | 定義集中 | 同一常數在 3+ 檔案定義 |
遵循這十條鐵律,不保證零 Bug,但能確保系統在 5 年後仍可被理性維護、移植、擴展——這正是嵌入式工程師的核心價值。