C 和 C++ 在某種程度上是嵌入式軟件開發中使用最廣泛的語言。VDC 最近的研究表明,70% 的受訪嵌入式系統公司使用 C,42% 使用 C++。幾乎每個處理器都實現了 C。它提供了廣泛的資源和庫,并得到了廣泛的工具的支持。
尤其是 C 語言,允許開發人員做許多本質上不正確的事情。編寫符合語言標準的代碼太容易了,但會導致程序失敗(崩潰)或未定義的行為。常見的示例是導致訪問數組邊界之外的內存的代碼或導致整數溢出的算術運算。
編碼標準的哲學
業界接受的解決這些危害的方法是采用“編碼標準”。最簡單的編碼標準定義了一組一致的編碼實踐。盡管風格的統一性在軟件項目中可能很有價值,但它們并沒有解決軟件質量的重要屬性,例如可靠性、可移植性或可維護性。編碼標準更基本的作用是通過制定一組規則來定義編程語言的更安全的子集,以消除已知危險的編碼結構。
體現這一安全子設置原則的汽車工業軟件可靠性協會 (MISRA) 編碼指南現已在全球范圍內被公認為用 C 和 C++ 開發安全關鍵型軟件的基準。它們已被廣泛接受,因為它們簡潔易讀,并且專注于基本問題。最近一項針對 500 名受訪者的民意調查 (Ganssle, 2014) 揭示了一些關于編碼標準采用率的有趣數據[1]。主要發現表明,在使用的所有編碼標準中,約有 60% 是基于 MISRA 的。采用的嚴格性是另一個有趣的發現,基于 MISRA 的編碼規則集在開發團隊中實現了 75% 的一致性使用,而其他規則集的使用率不到 50%。
偏差原理
MISRA 編碼標準包含廣受推崇的 C 和 C++ 語言開發指南。這些指南側重于開發關鍵軟件系統時的重要問題。MISRA 還認識到,在某些情況下,遵守編碼指南是不合理甚至不可能的,并且有必要偏離某些規則。偏差說明了在特定情況下不遵守特定編碼規則的原因。它還提供了放寬特定規則的程度的理由和描述,并提供了一個適當構建的安全案例,包括減輕不遵守的影響。
但是,如果沒有仔細說明違規范圍,基本偏差工具可能會被誤解或濫用,并最終破壞指南的有效性。
限制偏差的使用
就像編碼標準本身需要客觀的創造和充分理解的理由一樣,偏離編碼規則的原因同樣需要一個共同的表達和商定的解釋以及它們的應用范圍。汽車行業是 MISRA 最初且仍處于領先地位的應用領域,它已面對這一要求。MISRA 本身和一個國家機構日本汽車制造商協會 (JAMA) 都已開始制定允許特定偏離完全 MISRA 合規性的條件的過程。
這項工作的主旨是定義一組嚴格限制范圍的規則偏差。一個重要的第一階段是對偏離規則不合規的廣泛原因進行分類。
分類偏差原因
通過將偏差分為以下幾類,合規的實際困難變得更加明顯。此外,這種分類可以防止不適當的偏差和編碼標準意圖的弱化。
表現
建議將性能作為不遵循良好編碼實踐的原因似乎很奇怪且不直觀,但以下現實生活中的情況證明了這種需要:
作為車輛發動機控制系統的一部分,需要定期累積正時變量。該代碼經過正確制定以符合 MISRA-C:2012 規則 10.6(不應分配給更廣泛類型的值),內容如下:
extern uint16_t 數量,time_step;uint32_t prod = (uint32_t) 數量 * (uint32_t) time_step;
強制轉換確保 16 位操作數不會在此編譯器的 32 位乘法中溢出。但是,編譯器使用長乘法的“移位和加法”模式而不是它配備的 IMUL(有符號乘法)模式來執行此操作。編譯器供應商已澄清 IMUL 模式僅發生在隱式轉換上,要求表達式讀?。?/p>
uint32_t 產品 = 數量 * 時間步長;// 偏離規則 10.6
通過在這種情況下允許隱式轉換,保證了單個時鐘周期的 IMUL 操作,而不是前者的約 100 個時鐘周期的最壞情況執行,從而證明了基于性能的受控偏差是合理的。
外部(第三方)代碼
此類別包括通用庫、自動生成的代碼和遺留的內部代碼模塊,甚至只是包含關鍵應用程序算法的復雜函數。公共領域庫的維護者,鑒于其廣泛的應用領域,很少有動力遵守 MISRA 或其他編碼標準。自動生成的代碼,除非符合 ISO 26262 等功能安全標準,否則可能包含固有的 MISRA 違規。遺留代碼可能早于項目采用 MISRA。為滿足 MISRA 規則而進行的可能重構的影響分析本身可能會引起關注。所有這些情況下的安全案例都是基于“使用合格”的依賴以及其他特定的質量措施。
構建配置
汽車供應商應用程序的一個特殊功能是根據客戶需要提供單個代碼庫的許多變體。不是對這種交付進行構建級控制,而是部署配置機制來控制每個變體的功能交付。因此,MISRA 合規性可能會在冗余代碼、表達式不變性和相關的全局問題方面受到影響。
訪問硬件
為了訪問寄存器、尋址絕對內存和控制中斷,嵌入式開發人員需要訪問特定于編譯器的 C 語言擴展,從而導致不符合 MISRA。安全案例通常需要仔細的單元測試覆蓋。
防御性編碼
鑒于 C 語言中缺乏強大的異常處理功能,防御性編碼實踐可能涉及例如對不可預見行為的編程防護。一個功能齊全的分析工具將正確檢測不變的條件和無法訪問的代碼。安全案例必須涉及這些路徑或條件的強制單元測試執行。
語言特點
使用“最近的”語言結構有有效的代碼質量原因,例如布爾或“long long”類型或內聯函數。但是,這些可能需要偏離舊版本的 MISRA。安全問題是即使有 15 年歷史的 C99 結構也不能保證得到所有編譯器的支持。
受控偏差的結構
對不同的基本原理進行分類是創建適當約束的偏差結構的第一步。這自然會導致按規則和類別詳細說明所有特定的已知偏差案例。MISRA 和 JAMA 都在行業參與的情況下記錄了一組規則范圍限制,每個限制都有詳細的理由和安全案例。
即使在汽車領域之外,這些舉措也很重要。MISRA 編碼標準最初是為汽車行業設計的,但從早期開始,它就被許多其他嵌入式環境所采用,從消費產品到醫療設備,從工業控制到 EDA。同樣,對于任何采用編碼標準的人來說,建立一個受控偏差結構都很重要。
自動化工具支持
沒有自動執行手段和豐富的審計和報告能力的編碼標準將很快成為書柜的裝飾品,很少被引用或遵循。一個稱職的自動化靜態分析工具的起點必須是其診斷輸出的準確性、對所提出的每個問題的清晰理解和解釋,以及針對軟件項目的每個版本的詳細報告。
但即使是自動化工具執行環境也需要了解和應用已批準的偏差政策,特別是因為這消除了完全合規的障礙。編碼規則和偏差策略都必須方便開發人員、領導和經理信任,并便于詳細的 QA 報告。
基本偏差系統會將規則抑制的每個實例與其支持偏差耦合,并在相關源代碼的生命周期內保持這種耦合(圖 1)。在處理受控偏差時,要求更加復雜。對相關編碼規則的任何壓制都必須遵守更嚴格的有效限制,并且在該受控偏差集之外不得進行壓制。在選擇要抑制報告診斷的特定代碼位置時,必須限制開發人員僅使用允許的受控偏差范圍進行抑制。
圖 1:受控偏差的工具執行。
關鍵系統的安全代碼
MISRA C 編碼標準是在許多嵌入式環境及其他環境中安全和防御性使用 C 的代名詞。由于在 C 語言的限制使用方面既全面又廣泛,控制偏差的系統現在被認為是必要的,正如各種行業和社區為指定這種縮減所做的努力所證明的那樣?,F在正在為工業用途制定合理的具體偏差原因。對受控偏差計劃的復雜和自動化工具支持以及報告和合規解決方案的其他元素今天可用。
審核編輯:郭婷
-
嵌入式
+關注
關注
5085文章
19137瀏覽量
305670 -
寄存器
+關注
關注
31文章
5355瀏覽量
120500 -
編譯器
+關注
關注
1文章
1634瀏覽量
49150
發布評論請先 登錄
相關推薦
評論