由于嵌入式系統行業的快速發展,嵌入式設備的代碼質量成為首要關注的問題之一。考慮到嵌入式系統開發的特殊性(調試困難、出錯成本高等),開發人員需要使用專門的工具來提升自己的代碼質量。
靜態代碼分析器就是這些工具之一。本文描述了靜態分析以及它如何在嵌入式系統中受益。
靜態代碼分析
首先,讓我們弄清楚靜態代碼分析器是什么以及它們可以執行哪些功能。
靜態代碼分析器是分析程序而不實際執行它的軟件。靜態分析工具比編譯器對源代碼進行更深入的檢查。通常,編譯器只發現語法錯誤。
靜態分析工具的工作原理:
分析器的輸入數據是源代碼(最好是可編譯的)
分析器將源代碼轉換為特殊模型以供進一步分析(AST、語義模型等);
分析器通過對模型應用一組診斷規則來搜索缺陷。診斷規則基于各種方法;
分析儀以方便您的格式保存所有發出的警告;
開發人員只需要研究報告并修復所有缺陷;
利潤!
靜態分析儀可以執行廣泛的任務。讓我們介紹分析器最常見的任務:
程序代碼中的錯誤檢測。在這種情況下,靜態分析極大地補充了代碼審查。它允許您在您和您的同事開始繁瑣的代碼審查之前發現并解決許多問題;
廣義上的代碼質量增強。代碼質量可以包括可讀性、可維護性、代碼復雜性、內聚程度以及可以直接或間接影響錯誤數量的其他方面。因此,靜態分析器有助于遵循編碼標準(在公司內接受并普遍接受);
代碼分析作為 CI/CD 中質量門機制的一部分。分析器不僅可以警告代碼中的潛在錯誤,還可以作為一種保護機制。如果代碼質量水平不符合規定的要求,他們就會停止持續交付。如果檢測到錯誤或不符合標準的代碼片段,此類代碼分析器會擴展編譯器行為并阻止構建;
項目指標的收集、統計數據的收集、反映項目“總體健康狀況”的圖形和圖表結構。
實施效益
靜態分析器已被證明對嵌入式軟件非常有用。讓我們看看靜態分析最明顯的積極方面。
首先,靜態分析的使用減少了昂貴的(如果不是不可能的話)已經發布的設備“閃爍”的可能性。
嵌入式系統軟件中的錯誤非常麻煩。問題是一旦開始大規模生產,這些錯誤就不可能或幾乎不可能糾正。假設一家公司已經生產了數千臺洗衣機并將其交付給商店。但是,結果機器在某種模式下無法正常工作。公司應該怎么做?一般來說,這個問題是修辭性的,有兩種實際選擇:
順其自然,在各個網站上收到負面的客戶反饋,破壞聲譽。當然,公司可以發布并發送手動添加說“不要這樣做”。然而,這是一個“弱”的選擇;
退出銷售機器并開始更新固件。這是一個昂貴的選擇。
發布多少設備并不重要。修復錯誤可能有問題,甚至為時已晚。火箭墜毀——錯誤被發現,但為時已晚。患者死亡——錯誤被檢測到,但它不會讓人們回來。導彈防御系統的目標精度損失- 檢測到錯誤,但損壞已經造成。汽車休息不起作用- 檢測到錯誤,但這無助于車禍受害者。程序錯誤的代價是可怕的,不是嗎?
結論很簡單:嵌入式設備的代碼應該盡可能徹底地測試。特別是如果錯誤可能導致人員傷亡或巨大的經濟損失。
靜態代碼分析是檢測錯誤的過程,但它不保證會發現代碼中的所有錯誤。但是,開發人員應該利用任何機會額外檢查代碼的正確性。靜態分析器可以指出即使在多次代碼審查之后仍然存在的各種錯誤。
如果靜態分析可以幫助減少設備代碼中的錯誤數量,那就太棒了。也許這些特殊錯誤的發現將防止生命損失。或者,也許這些公司不會浪費很多錢,也不會因為客戶投訴而失去良好的聲譽。
其次,靜態代碼分析器顯著降低了軟件測試和調試過程的成本。
靜態分析允許您在編碼期間或夜間構建期間發現錯誤。結果,大多數錯誤的搜索和修復可以便宜得多。
可能每個開發人員都嘗試過“刷新”設備,但沒有成功。例如,在此過程中,設備沒有設置正確的電壓或完全燒壞。發生了什么,您在哪里尋找問題?畢竟,不僅僅是軟件錯誤可能是問題的根源。也可能是硬件本身的錯誤或質量差的布局。因此,發現錯誤的過程可能需要很長時間。
最悲傷的場景:
開發人員 100% 確定他編寫的代碼是正確的;
電路工程師和其他負責硬件的同事參與了該項目;
尋找問題的過程緩慢而費力;
開發人員再次查看代碼并突然發現 - 一個錯字;
超級低效浪費隊友的精力和時間;
這很尷尬和不愉快。
由于以下原因,可能會彈出此類錯誤。在正在進行的項目中,開發人員使用了他的舊做法,他需要至少適應項目。例如,他可以編寫以下代碼片段:
uchar Arr[3];
。..。
for (uchar idx = 0; idx != 4; idx++)
avg += Arr[idx];
avg /= 3;
這個錯誤的背景如下。開發人員以他之前的開發為基礎,代碼主要是使用復制粘貼方法編寫的。他沒注意,忘了把4換成3在一行。結果,他在訪問位于數組邊界之外的索引時出現了未定義的行為。這樣的代碼可能是陰險的。程序在調試過程中可以正常工作。但是,在實際情況下,當客戶端多次運行它時,它可能會崩潰。如果靜態分析器發現這樣的錯誤,那就太好了。
因此,為避免調試過程曲折而費力,在刷機之前盡可能多地檢測出缺陷位置非常重要。
第三,靜態分析的使用保證了沒有太多經驗的開發人員。
程序錯誤可以形象地分為兩種類型。開發人員知道第一種類型的錯誤。由于疏忽,這些錯誤意外地出現在代碼中。第二種錯誤出現在開發人員根本不知道不可能以這種方式編寫代碼的情況下。換句話說,他們可以隨心所欲地查看此類代碼,但仍然不會發現錯誤。
靜態分析器包含有關各種代碼模式的知識庫。在某些情況下,這些模式會導致錯誤。因此,他們可以指出開發人員自己不會發現的錯誤。一個例子是使用 32 位 time_t 類型,這可能會導致設備在2038之后無法正常工作。
另一個例子是程序的未定義行為,這是由于不當使用移位運算符《《/》》而發生的。這些運算符在微控制器的代碼中被廣泛使用。不幸的是,開發人員經常非常粗心地使用這些運算符。這使得程序不可靠并且依賴于編譯器的特定版本和設置。同時,程序可以運行,但這不是因為它的代碼寫得對,而是因為開發者很幸運。
使用靜態分析器,開發人員可以對沖許多此類不愉快的情況。此外,您可以使用分析器來控制整體代碼質量。當項目的團隊正在成長或變化時,這一點很重要。換句話說,分析器有助于跟蹤初學者是否開始編寫糟糕的代碼。
第四,現代靜態分析器不僅能發現代碼錯誤和漏洞,還支持嵌入式系統的編碼標準。這些標準提高了程序的安全性、可移植性和可靠性水平。
C 和 C++ 被稱為嵌入式系統的流行編程語言。MISRA C、MISRA C++ 和 AUTOSAR C++ 等標準是為這些語言開發的。每個標準都有相當多的規則和建議(MISRA C:143,MISRA C++:228,AUTOSAR C++:超過 350)。在沒有靜態代碼分析器的情況下編碼時,根本不可能遵守這么多的規則和建議。這些規則是開發人員需要避免的編碼模式,從而減少出錯的可能性。目前,所有主要的靜態分析參與者(Coverity、Klockwork、PVS-Studio,。..)都在努力盡可能地增加標準的覆蓋范圍。
編碼標準
MISRA 的歷史始于很久以前。回到 90 年代初,“安全 IT”英國政府計劃為各種與電子系統安全相關的項目提供資金。MISRA(汽車工業軟件可靠性協會)項目本身的成立是為了創建用于開發陸地車輛微控制器軟件的指南 - 主要是汽車。
MISRA(作為一個組織)是一個由來自各種汽車和飛機行業的利益相關者組成的社區。
賓利汽車;
福特汽車公司;
捷豹路虎;
德爾福柴油系統;
堀場米拉;
千變萬化電氣;
偉世通工程服務;
利茲大學;
英國里卡多;
采埃孚天合。
非常強大的市場參與者,不是嗎?毫不奇怪,他們的第一個與語言相關的標準 MISRA C 在關鍵嵌入式系統的開發人員中獲得了廣泛的認可。不久之后,出現了 MISRA C++。逐漸地,標準的版本已經更新和修訂,以涵蓋語言的新功能。目前,當前版本是 MISRA C: 2012 和 MISRA C++: 2008。
MISRA 最顯著的特點是其對細節的難以置信的關注和在確保安全和安保方面的極度細致。作者不僅將所有 C 和 C++ 缺陷集中在一個地方(例如 CERT 的作者)。他們還仔細制定了這些語言的國際標準,并寫出了所有可能出錯的方法。之后,他們添加了關于代碼可讀性的規則和建議。畢竟,在簡單易讀的代碼中更難出錯,在 Code-Review 期間更容易發現錯誤。
通常,第一次遇到 MISRA 的人會覺得該標準的目的是“禁止這個和禁止那個”。事實上,確實如此,但只是部分如此。
該標準確實有許多禁止某些行為的規則。但是,這并不是要全面禁止,而是要列出所有可能導致安全漏洞的方式。對于大多數規則,您自己選擇是否需要遵守它們。讓我更詳細地解釋一下。
MISRA C 規則分為三個主要類別:強制、必需和建議。在任何情況下都不得違反強制性規則。例如,本節包括規則:“不要使用未啟動變量的值”。所需的規則不那么嚴格。它們允許偏差的可能性。但是開發人員需要以書面形式證明這些偏差的合理性并詳細記錄它們。其余規則屬于咨詢類別——它們是非強制性的。
MISRA C++ 有點不同:沒有 Mandatory 類別,大部分規則屬于Required 類別。因此,事實上,您有權違反任何規則——只是不要忘記記錄偏差。還有文檔類別。它包括與一般實踐相關的強制性規則(不允許有偏差),例如“必須記錄匯編程序的每次使用”或“包含的庫必須符合 MISRA C++”。
該標準既包含對問題問題的描述,也包含在承擔某項任務之前必須了解的提示:如何根據 MISRA 設置開發流程;如何使用靜態分析器檢查代碼的合規性;一個人必須維護哪些文件,如何填寫它們等等。
目前,MISRA 不斷發展。例如,MISRA 在 2019 年初發布了《MISRA C:2012 第三版(第一次修訂)》。這是 MISRA C:2012 版更新和擴展了新規則。同時,即將發布的《MISRA C: 2012 Amendment 2 – C11 Core”公布,這是 2012 年的修訂標準。
MISRA C++ 也不會停滯不前。如您所知,MISRA C++ 的最后一個標準可以追溯到 2008 年,因此它所涵蓋的語言的最新版本是 C++03。正因為如此,還有一個類似于MISRA的標準,它的名字叫AUTOSAR C++。它最初旨在作為 MISRA C++ 的延續,并旨在涵蓋該語言的更高版本。與其策劃者不同,AUTOSAR C++ 每年更新兩次,目前支持 C++14。新的 C++17 和 C++20 更新尚未到來。
結論
在本文中,我想說明使用靜態分析器對任何嵌入式項目都絕對有用。使用靜態分析將幫助您:
減少查找和修復錯誤所需的時間;
減少嚴重錯誤的可能性;
減少對固件更新的需求;
監控整體代碼質量;
監控新團隊成員的表現;
嚴格遵守一定的軟件開發標準;
監控第三方模塊/庫的代碼質量。
審核編輯:郭婷
-
嵌入式
+關注
關注
5094文章
19178瀏覽量
307730 -
C++
+關注
關注
22文章
2114瀏覽量
73859 -
代碼
+關注
關注
30文章
4828瀏覽量
69061
發布評論請先 登錄
相關推薦
評論