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