作者:IAR 嵌入式系統在我們的日常生活中廣泛存在,從消費類(lèi)電子、醫療設備,到汽車(chē),工業(yè)控制,航空航天等,它們的存在已經(jīng)成為我們生活中不可分割的一部分。隨著(zhù)技術(shù)的不斷進(jìn)步和客戶(hù)需求的增加,嵌入式系統和軟件變得越來(lái)越復雜,同時(shí)產(chǎn)品的開(kāi)發(fā)周期變得越來(lái)越短。如何在短時(shí)間內開(kāi)發(fā)出高質(zhì)量的軟件對產(chǎn)品的成功起著(zhù)決定性的作用。 本文將介紹如何應用編碼標準和自動(dòng)化工具,提高代碼質(zhì)量。 關(guān)于代碼質(zhì)量 代碼質(zhì)量總體上是指為軟件編寫(xiě)的代碼的整體優(yōu)良水平,一般可以通過(guò)下面一些指標來(lái)評價(jià)代碼質(zhì)量: 可讀性:代碼應該易于閱讀和理解,即使是不熟悉項目的人也是如此。 可維護性:代碼應該有條理和模塊化,可以方便地修改和更新。 可移植性:代碼應該被設計易于在不同的平臺上使用。 可重用性:代碼應該是可重用的,可以在應用程序的其他部分使用。 可測試性:代碼應該是易于進(jìn)行單元測試和集成測試的。 安全性:代碼應該是安全的,保護敏感數據并防止惡意攻擊。 性能:代碼應該是高效的,專(zhuān)注于優(yōu)化性能,以最大限度地減少資源使用。 對于嵌入式系統,代碼質(zhì)量更加的重要。嵌入式系統經(jīng)常是處理執行關(guān)鍵任務(wù)功能的設備。 如果嵌入式軟件存在代碼質(zhì)量問(wèn)題,可能會(huì )導致硬件設備的故障或安全漏洞,嚴重影響系統的正常運行。 編碼標準是提高代碼質(zhì)量的最佳實(shí)踐 基于歷史原因,目前在嵌入式開(kāi)發(fā)中,主要還是使用C/C++高級編程語(yǔ)言,而C/C++是一種不安全的語(yǔ)言,包含大量未定義的行為,對于這些行為的不同解釋?zhuān)赡軙?huì )導致未知或不確定的副作用,其中一部分將會(huì )轉化為我們俗稱(chēng)的“Bug”。比如C語(yǔ)言標準庫中的一些輸入輸出函數,字符串函數導致的緩沖區溢出的問(wèn)題,指針未初始化風(fēng)險,重復釋放內存等等。 同時(shí),軟件開(kāi)發(fā)執行和實(shí)施的核心是“人”,也就是開(kāi)發(fā)人員,在實(shí)踐過(guò)程中,開(kāi)發(fā)人員可能會(huì )一次又一次無(wú)意地將相同類(lèi)型的錯誤寫(xiě)入到他們的源代碼中。這一結論來(lái)自各種權威機構,如NASA、貝爾實(shí)驗室和MITRE,它們進(jìn)行了多項調查和研究。這些研究的結果是給出了最佳編程實(shí)踐或推薦的編程實(shí)踐,它們可以有效識別有風(fēng)險和不良的編碼行為。 有許多指南和編碼實(shí)踐可用于檢查常見(jiàn)錯誤以及如何避免這些錯誤來(lái)提高代碼質(zhì)量,其中一些技術(shù)和實(shí)踐在實(shí)施過(guò)程中,成為眾所周知的編碼標準。編碼標準是編碼規則、指導方針和最佳實(shí)踐的集合,它可以識別語(yǔ)言中容易引起Bug的行為,防止你在源代碼中做可疑的事情,消除容易出現缺陷的代碼結構,幫助你快速提高代碼質(zhì)量。 在嵌入式系統中,MISRA-C/C++,CERT-C/C++,CWE等已經(jīng)成為事實(shí)標準。特別是在汽車(chē)、醫療和鐵路等安全關(guān)鍵型應用中,被IEC 61508、EN 50128和ISO 26262 等功能安全標準所要求。 很多大公司都有相應的代碼編程規范,尤其是針對C語(yǔ)言,但這些編程規范往往與業(yè)界的編程標準(比如MISRA C)的側重點(diǎn)不同。一般公司的編程規范更加注重代碼風(fēng)格,比如命名,縮進(jìn),括號的使用等,來(lái)提高可讀性,而業(yè)界的編程標準更偏重于代碼的可維護性,可移植性,可靠性和安全性。在具體實(shí)踐中,往往是需要這二者結合使用。 MISRA ![]() MISRA C由汽車(chē)工業(yè)軟件可靠性協(xié)會(huì )開(kāi)發(fā)。它的目的是提高嵌入式系統環(huán)境中的代碼安全性、可移植性和可靠性,特別是那些用 ISO C 編程的系統。 MISRA C標準的第一版“Guidelines for the use of the C language in vehicle based software”于1998年制定,正式名稱(chēng)為MISRA-C:1998。2004年進(jìn)行了一次更新“Guidelines for the use of the C language in critical systems”,正式名稱(chēng)為 MISRA-C:2004。從1998年的vehicle based software到2004年的critical systems,因為MISRA協(xié)會(huì )發(fā)現MISRA C不僅汽車(chē)行業(yè)需要,其他一些安全相關(guān)的行業(yè)也需要。最新的MISAR C標準是MISRA-C:2012。 關(guān)于MISRA C,很多開(kāi)發(fā)者都有一個(gè)誤解:MISRA C只適用于汽車(chē)電子嵌入式軟件開(kāi)發(fā)。對此,MISRA C的輪值主席Andrew Banks特意做了解釋說(shuō)明:雖然MISRA最開(kāi)始推出的時(shí)候主要是針對汽車(chē)行業(yè)的,但由于它本身其實(shí)是在C/C++語(yǔ)言的基礎上,加上了一些約束,去掉了一些讓人容易出錯的編程方法,保留了常用的寫(xiě)法,盡可能讓開(kāi)發(fā)者保持一致,提高可維護性和可移植性,從而提高安全性和可靠性,因此 MISRA 在飛機、機器人、無(wú)人機、醫療等其它的嵌入式行業(yè)也開(kāi)始流行起來(lái),成為了全球公認的嵌入式 C 編程標準。 CERT ![]() CERT C/C++由卡內基梅隆大學(xué)軟件工程研究所(SEI)的計算機緊急響應小組 (CERT)部門(mén)創(chuàng )建和發(fā)布,為C/C++編程語(yǔ)言的安全編碼提供規則和建議,這些規則和建議的目標是開(kāi)發(fā)安全、穩定和可靠的系統。 CWE ![]() CWE是基于社區開(kāi)發(fā)的一組影響信息安全的軟件和硬件缺陷列表。它用通用語(yǔ)言描述和討論軟件和硬件的缺陷,可以作為缺陷識別、緩解和預防工作的公共基線(xiàn)標準。因此,CWE可以幫助開(kāi)發(fā)人員和安全從業(yè)者檢查現有軟件和硬件產(chǎn)品的缺陷,評估針對這些缺陷的工具的覆蓋率等。 編碼標準的應用對提高代碼質(zhì)量有立竿見(jiàn)影的作用。在Dr. Dobbs所做的一項研究中(Code Quality Improvement | Dr Dobb's),引入編碼標準進(jìn)行符合性檢查后,缺陷注入率降低了41%,這節省了大量測試時(shí)間,既提高了代碼質(zhì)量,又縮短了工程時(shí)間,從而加速了產(chǎn)品上市。在這項研究中,每個(gè)月的缺陷注入率是相當穩定的,直到該組織引入編碼標準,然后缺陷率急速下降(見(jiàn)下圖)。 隨著(zhù)對標準遵從度的提高,質(zhì)量也隨之提高,偏差越來(lái)越少,缺陷率直線(xiàn)下降。 ![]() 自動(dòng)化工具是實(shí)施編碼標準的最佳路徑 有了編碼標準后,應用標準意味著(zhù)代碼除了需要遵守語(yǔ)言本身的規則外,還需要遵守成百上千條編碼標準所包含的規則和要求。理論上,我們可以通過(guò)人工來(lái)檢查每條編碼規則的實(shí)施情況,但對于日益復雜的軟件顯然是力不從心的。大量的實(shí)踐表明,應用自動(dòng)化工具是實(shí)施編碼標準,提高代碼質(zhì)量的最佳路徑。 自動(dòng)化工具中我們最熟悉的就是編譯器和鏈接器。高質(zhì)量的編譯器和鏈接器應支持現代編程語(yǔ)言,如最新的C和C++規范,報告每個(gè)構建步驟中可能出現的問(wèn)題,以便它生成懷疑的警告,例如易失性變量或內存訪(fǎng)問(wèn),其評估順序可能會(huì )影響應用程序的邏輯。警告是第一道靜態(tài)分析檢查,絕不能忽視,尤其是在功能安全設置中。最好的建議是通過(guò)更改編譯器設置將所有警告都視為錯誤來(lái)將警告轉化為錯誤。這將迫使開(kāi)發(fā)人員修復代碼中的所有歧義,因為所有的警告都將作為真正的問(wèn)題處理。 專(zhuān)用的靜態(tài)分析工具基于源代碼分析,可以在不執行程序的情況下發(fā)現潛在的問(wèn)題,比如 IAR 提供了與 IAR Embedded Workbench 無(wú)縫集成的靜態(tài)分析工具 C-STAT。這種類(lèi)型的工具可以幫助你找到代碼中最常見(jiàn)的缺陷來(lái)源,也可以幫助你找到開(kāi)發(fā)人員在試圖編寫(xiě)代碼時(shí)往往不會(huì )考慮的問(wèn)題,特別是當他們?yōu)榱俗屇承┕δ苓\行而加入支撐代碼時(shí)。靜態(tài)分析工具確實(shí)能幫助你開(kāi)發(fā)出更好的代碼,因為它們強制執行編碼標準。事實(shí)上,如果正在創(chuàng )建一個(gè)功能安全認證的應用,你可能會(huì )被建議,甚至強制要求使用靜態(tài)分析工具。 此外,嵌入式軟件在運行時(shí)仍然容易受到算術(shù)問(wèn)題、緩沖區溢出、邊界問(wèn)題、堆完整性和內存泄漏的影響。一個(gè)可行的方法是在可能發(fā)生潛在錯誤的所有地方插入特定的檢測代碼或斷言來(lái)檢測此類(lèi)錯誤。但是,手動(dòng)添加指令來(lái)檢測并以某種方式在運行時(shí)報告問(wèn)題是一項非常耗時(shí)的任務(wù)。因此,使用動(dòng)態(tài)或運行時(shí)分析工具來(lái)捕獲和觸發(fā)僅在運行時(shí)的缺陷和錯誤,是一個(gè)可以極大提高效率和生產(chǎn)力的方法。例如,在 IAR Embedded Workbench 中,開(kāi)發(fā)人員可以使用運行時(shí)分析工具插件 C-RUN。 綜上所述,編譯器和鏈接器可以報告在構建中可能出現的問(wèn)題,靜態(tài)分析工具擅長(cháng)發(fā)現一些未定義行為的缺陷,檢查編碼標準的符合性,而運行時(shí)分析工具擅長(cháng)發(fā)現只有在執行時(shí)才會(huì )觸發(fā)的缺陷。這些缺陷有時(shí)會(huì )有重疊,但有時(shí)只能在一個(gè)域或另一個(gè)域中檢測到。為了盡可能提高代碼質(zhì)量,以及發(fā)現問(wèn)題的效率,需要將幾者結合使用并盡可能與開(kāi)發(fā)和構建工具集成。下圖矩陣代表組合不同工具時(shí)的完整缺陷覆蓋率。 ![]() 總結 隨著(zhù)嵌入式系統的復雜性提高,對于嵌入式軟件的要求也越來(lái)越高,其中最核心最根本的是代碼質(zhì)量,而編碼標準是提高代碼質(zhì)量的最佳實(shí)踐。遵循編碼標準的最有效的方式是應用自動(dòng)化工具,包括靜態(tài)分析工具,運行時(shí)分析工具,這樣可以有效地在開(kāi)發(fā)過(guò)程中提高代碼質(zhì)量,既減少了項目的開(kāi)發(fā)時(shí)間和成本,又提高了產(chǎn)品的質(zhì)量和競爭力。 參考文獻 1.https://www.misra.org.uk/ 2.https://ldra.com/ldra-blog/misra ... utomotive-standard/ 3.http://www.cert.org/ 4.http://cwe.mitre.org/ 5.https://www.iar.com/knowledge/le ... -with-code-quality/ 6.https://www.iar.com/knowledge/le ... -with-code-quality/ |