• <noframes id="6fok0"><bdo id="6fok0"><listing id="6fok0"></listing></bdo>
    <ruby id="6fok0"></ruby>

    <progress id="6fok0"></progress>
  • <progress id="6fok0"></progress>
    <ruby id="6fok0"><table id="6fok0"></table></ruby>
  • <progress id="6fok0"><u id="6fok0"><form id="6fok0"></form></u></progress>

    24小時(shí)聯(lián)系電話(huà):18217114652、13661815404

    中文

    您當前的位置:
    首頁(yè)>
    電子資訊>
    技術(shù)專(zhuān)題>
    單片機開(kāi)發(fā)功能安全中...

    技術(shù)專(zhuān)題

    單片機開(kāi)發(fā)功能安全中的編譯器


    在各個(gè)領(lǐng)域,功能安全領(lǐng)域對開(kāi)發(fā)人員提出了新要求。功能上安全的代碼必須包括防御性代碼,以防御各種原因引起的意外事件。例如,由于編碼錯誤或宇宙射線(xiàn)事件而導致的內存損壞可能導致執行根據代碼邏輯不可能的代碼路徑。高級語(yǔ)言,特別是CC ++,包含數量眾多的功能,這些功能的行為不是代碼所遵循的語(yǔ)言規范所規定的。這種不確定的行為可能導致意外的結果和潛在的災難性后果,而這在功能安全的應用程序中是無(wú)法接受的。出于這些原因,標準要求應用防御性編碼,可測試的編碼,有可能整理足夠的編碼覆蓋率,

    代碼還必須實(shí)現高級別的代碼覆蓋率,在某些領(lǐng)域(尤其是汽車(chē)領(lǐng)域),設計通常需要復雜的外部診斷,校準和開(kāi)發(fā)工具。出現的問(wèn)題是,防御性編碼和外部數據訪(fǎng)問(wèn)等實(shí)踐并不屬于編譯器認可的領(lǐng)域。例如,CC ++都沒(méi)有為內存損壞留出任何余地,因此,除非在沒(méi)有這種損壞的情況下可以訪(fǎng)問(wèn)旨在防止內存損壞的代碼,否則在對代碼進(jìn)行優(yōu)化時(shí)可以將其忽略。因此,如果不優(yōu)化防御性代碼,則必須在語(yǔ)法和語(yǔ)義上都可以實(shí)現。

    未定義行為的實(shí)例也會(huì )引起意外。很容易建議應避免使用它們,但通常很難識別它們。如果存在它們,就不能保證已編譯的可執行代碼的行為將符合開(kāi)發(fā)人員的意圖。對調試工具使用的數據的后門(mén)訪(fǎng)問(wèn)代表了該語(yǔ)言不允許的另一種情況,因此可能會(huì )帶來(lái)意想不到的后果。

    編譯器優(yōu)化可能對所有這些領(lǐng)域產(chǎn)生重大影響,因為它們都不屬于編譯器供應商的職責范圍。優(yōu)化可能會(huì )導致在與不可行相關(guān)聯(lián)時(shí),即在存在于無(wú)法通過(guò)任何可能的輸入值進(jìn)行測試和驗證的路徑上存在的情況下,顯然消除了防御性代碼。更令人震驚的是,在構建系統可執行文件時(shí),很可能會(huì )消除在單元測試期間顯示的防御代碼。僅僅因為在單元測試期間已經(jīng)實(shí)現了防御性代碼的覆蓋范圍,因此并不能保證其已存在于完整的系統中。

    在功能安全這個(gè)陌生的領(lǐng)域,編譯器可能超出了其要素。這就是為什么目標代碼驗證(OCV)代表了對任何與故障相關(guān)的后果都有嚴重后果的系統的最佳實(shí)踐,甚至對于只有最佳實(shí)踐就足夠好的任何系統都代表了最佳實(shí)踐。

    編譯前后

    功能安全性,安全性和編碼標準(例如IEC 61508,ISO 26262,IEC 62304,MISRA CC ++)提倡的驗證和確認做法非常強調顯示在基于需求的測試中使用了多少應用程序源代碼。

    經(jīng)驗向我們表明,如果已證明代碼可以正確執行,則現場(chǎng)失敗的可能性會(huì )大大降低。但是,由于這種值得稱(chēng)贊的努力的重點(diǎn)是高級源代碼(無(wú)論使用哪種語(yǔ)言),所以這種方法使編譯器具有創(chuàng )建目標代碼的能力,這些目標代碼可以準確地再現開(kāi)發(fā)人員的能力,這使人們深信不疑預期的。在最關(guān)鍵的應用程序中,該隱含假設無(wú)法成立。

    不可避免的是,目標代碼的控制和數據流不會(huì )完全是源代碼的鏡像,因此證明所有源代碼路徑都可以可靠地行使并不能證明目標代碼是同一件事。 。鑒于目標代碼和匯編器之間存在11的關(guān)系,因此可以比較源代碼和匯編代碼??紤]一下圖1所示的示例,其中右邊的匯編代碼是從左邊的源代碼生成的(使用禁用了優(yōu)化的TI編譯器)。


    圖1:右邊的匯編代碼是從左邊的源代碼生成的,顯示了源代碼和匯編代碼之間的明顯對比

    如下所述,當編譯此源代碼時(shí),生成的匯編代碼的流程圖與源代碼的流程圖完全不同,因為CC ++編譯器遵循的規則允許它們以自己喜歡的任何方式修改代碼,前提是二進(jìn)制表現為好像是一樣的。

    在大多數情況下,該原則是完全可以接受的-但存在異常情況。編譯器優(yōu)化基本上是數學(xué)上的變換,可應用于代碼的內部表示。如果假設不成立,這些轉換就會(huì )出錯”-例如,在代碼庫包含未定義行為的實(shí)例的情況下,這種情況經(jīng)常發(fā)生。

    只有航空航天業(yè)中使用的DO-178C才將重點(diǎn)放在開(kāi)發(fā)人員意圖與可執行行為之間潛在的危險不一致的可能性上,即使如此,仍不難找到具有明顯潛能的解決方法的倡導者,以免發(fā)現那些不一致之處。但是,可以原諒此類(lèi)方法,但事實(shí)是,源代碼和目標代碼之間的差異可能在任何關(guān)鍵應用程序中造成毀滅性后果。

    開(kāi)發(fā)人員意圖與可執行行為

    盡管源代碼流和目標代碼流之間存在明顯差異,但它們并不是主要問(wèn)題。編譯器通常是高度可靠的應用程序,盡管可能會(huì )像其他任何軟件一樣存在錯誤,但編譯器的實(shí)現通常會(huì )滿(mǎn)足其設計要求。問(wèn)題在于這些設計要求并不總是反映功能安全系統的需求。

    簡(jiǎn)而言之,可以假定編譯器在功能上符合其創(chuàng )建者的目標。但這可能并不完全是期望或期望的結果,如下面的圖2所示,其中包括一個(gè)使用CLANG編譯器進(jìn)行編譯的示例。


    圖2顯示了使用CLANG編譯器進(jìn)行的編譯

    顯然,在匯編代碼中并未表達對錯誤功能的防御性呼吁。

    僅在初始化“ state”對象時(shí)以及在“ S0”“ S1”情況下修改“ state”對象,因此編譯器可以推斷出賦予“ state”的唯一值是“ S0”“ S1”。編譯器得出結論,不需要默認值,因為假設沒(méi)有損壞,狀態(tài)將永遠不包含任何其他值-實(shí)際上,編譯器所做的正是這一假設。

    編譯器還決定,由于實(shí)際對象(1323)的值未在數字上下文中使用,因此它將僅使用01的值在狀態(tài)之間切換,然后使用異或更新?tīng)顟B(tài)值。二進(jìn)制文件遵循好像義務(wù),并且代碼快速緊湊。在其職權范圍內,編譯器做得很好。

    此行為對使用鏈接器內存映射文件間接訪(fǎng)問(wèn)對象的校準工具以及通過(guò)調試器直接訪(fǎng)問(wèn)內存有影響。同樣,這些考慮因素也不屬于編譯器的職責范圍,因此在優(yōu)化和/或代碼生成期間不會(huì )考慮。

    現在假設代碼保持不變,但是在呈現給編譯器的代碼中其上下文發(fā)生了微小的變化,如圖3所示。


    圖3:代碼保持不變,但是提供給編譯器的代碼中的上下文略有變化

    現在有一個(gè)附加函數,該函數以整數形式返回狀態(tài)變量的值。這次,絕對值1323在提交給編譯器的代碼中很重要。即使這樣,這些值也不會(huì )在更新函數中進(jìn)行操作(保持不變),并且僅在新的“ f”函數中可見(jiàn)。

    簡(jiǎn)而言之,編譯器繼續(正確地)對應該使用1323的值進(jìn)行價(jià)值判斷,并且絕不會(huì )將它們應用于可能的所有情況。

    如果更改了新功能以返回指向我們狀態(tài)變量的指針,則匯編代碼將發(fā)生重大變化。由于現在存在通過(guò)指針進(jìn)行別名訪(fǎng)問(wèn)的可能性,因此編譯器無(wú)法再推斷出狀態(tài)對象正在發(fā)生的情況。如下圖4所示,它不能得出1323的值不重要的結論,因此現在可以在匯編器中明確表示它們。


    圖4:如果將新函數更改為返回指向我們的狀態(tài)變量的指針,則匯編代碼將發(fā)生重大變化。它不能得出結論13和23的值并不重要,因此它們現在已在匯編程序中明確表示

    對源代碼單元測試的影響

    現在,在虛構的單元測試工具的上下文中考慮示例。由于需要一種工具來(lái)訪(fǎng)問(wèn)被測代碼,因此會(huì )操縱狀態(tài)變量的值,因此默認值不會(huì )被優(yōu)化。這種方法在沒(méi)有與源代碼其余部分相關(guān)的上下文并且需要使所有內容都可訪(fǎng)問(wèn)的測試工具中是完全合理的,但是,其副作用是,它可以掩蓋編譯器對防御性代碼的合法遺漏。

    編譯器認識到已通過(guò)指針將任意值寫(xiě)入狀態(tài)變量,并且不能再次得出1323的值不重要的結論。因此,它們現在在匯編器中明確表示。在這種情況下,不能得出結論:S0S1代表狀態(tài)變量的唯一可能值,這意味著(zhù)默認路徑可能可行。如圖5所示,狀態(tài)變量的操作達到了目的,并且在匯編器中現在可以明顯看到對錯誤函數的調用。


    圖5:狀態(tài)變量的操作已達到其目的,并且錯誤函數的調用現在在匯編程序中顯而易見(jiàn)

    但是,這種操作不會(huì )出現在產(chǎn)品內隨附的代碼中,因此對error()的調用實(shí)際上不在整個(gè)系統中。

    目標代碼驗證的重要性

    為了說(shuō)明目標代碼驗證如何幫助解決這個(gè)難題,請再次考慮第一個(gè)示例代碼片段,如圖6所示:


    圖6:這說(shuō)明了目標代碼驗證如何幫助解決錯誤提示在整個(gè)系統中的作用

    通過(guò)一次調用,可以證明此C代碼實(shí)現了100%的源代碼覆蓋率,因此:

    f_while40,3;

    可以將代碼重新格式化為每行單個(gè)操作,并在流程圖上表示為基本塊節點(diǎn)的集合,每個(gè)節點(diǎn)都是一系列直線(xiàn)代碼?;緣K之間的關(guān)系在圖7中使用節點(diǎn)之間的有向邊表示。


    圖7:使用節點(diǎn)之間的有向邊顯示基本塊之間的關(guān)系

    編譯代碼后,結果如下所示(圖8)。流程圖的藍色元素表示調用f_while40,3尚未執行的代碼。

    通過(guò)利用目標代碼與匯編代碼之間的一對一關(guān)系,此機制可以揭示目標代碼的哪些部分未被執行,從而促使測試人員設計其他測試并實(shí)現完整的匯編代碼覆蓋范圍,從而實(shí)現目標代碼驗證。


    圖8:顯示了編譯代碼后的結果。流程圖的藍色元素表示調用f_while4(0,3)尚未執行的代碼

    顯然,目標代碼驗證無(wú)權阻止編譯器遵循其設計規則,并無(wú)意中繞開(kāi)了開(kāi)發(fā)人員的最佳意圖。但這確實(shí)可以并且確實(shí)會(huì )引起任何此類(lèi)失配,引起粗心的人的注意。

    現在,在前面的錯誤提示示例的上下文中考慮該原理。當然,完整系統中的源代碼將與在單元測試級別上證明的源代碼相同,因此,將其進(jìn)行比較不會(huì )發(fā)現任何問(wèn)題。但是,將目標代碼驗證應用于完整的系統對于確?;拘袨榘凑臻_(kāi)發(fā)人員的意圖進(jìn)行表達將具有極大的價(jià)值。

     

    請輸入搜索關(guān)鍵字

    確定
    色鲁99热99re超碰精品_91精品一区二区三区无码吞精_亚洲国产欧洲综合997久久_一级a性色生活片久久无
  • <noframes id="6fok0"><bdo id="6fok0"><listing id="6fok0"></listing></bdo>
    <ruby id="6fok0"></ruby>

    <progress id="6fok0"></progress>
  • <progress id="6fok0"></progress>
    <ruby id="6fok0"><table id="6fok0"></table></ruby>
  • <progress id="6fok0"><u id="6fok0"><form id="6fok0"></form></u></progress>