在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            博客專欄

            EEPW首頁 > 博客 > CRC校驗 | 程序如何檢查自身完整性?(1)

            CRC校驗 | 程序如何檢查自身完整性?(1)

            發(fā)布人:魚鷹談單片機 時間:2021-08-12 來源:工程師 發(fā)布文章

            在一些比較嚴格的行業(yè)里面,不是說你的程序能完成必要功能就可以,還需要添加一些額外的功能,比如最常見的看門狗功能,它可以在程序死機時完成重啟,但也僅僅如此而已。很多異常它是無法檢查的,比如程序偶然跑飛,ram 異常、flash異常等其他問題,只有程序hardfault或者其他嚴重問題導(dǎo)致程無法喂狗時才能起作用。

            所以有些產(chǎn)品為了保障安全,會增加安規(guī)代碼,保證程序能夠正常運行(UL/CSA/IEC 60730-1/60335-1 B類認證)。

            自檢內(nèi)容

            MCU 安全檢查一般包括以下幾個方面:

            1、CPU 自測(寄存器測試)

            2、系統(tǒng)時鐘頻率測量(保證時鐘正常工作,不快也不慢,GD 芯片在短路晶振后,程序暫停運行,無法檢查,但是 ST 芯片會自動切換到內(nèi)部時鐘,可以由程序檢查這種異常)

            3、RAM 自檢

            4、FLASH 存儲器完整性檢查

            5、獨立看門狗、窗口看門狗檢查

            6、安全相關(guān)變量檢查

            7、中斷檢查

            8、I/O 口檢查

            9、棧檢查

            10、程序流程控制

            11、AD 口檢查

            你會發(fā)現(xiàn)真要完成這份安規(guī)代碼,難度不是一般的大,不過一般芯片廠商會提供相關(guān)參考例程和相關(guān)文檔,但不是說有了這些資料就完全沒有問題了。

            比如 ST 提供了一個參考例子,但是它使用的 HAL 庫(事實上它還有標準庫,當時不知道),如果原本程序用的標準庫,那么就需要進行移植,這個工作量也不是一般大(首先要能理解程序,才能進行正確移植,而里面的邏輯還是很復(fù)雜的)。如果你不想移植,還有一個辦法是使用 lib 庫,就是將相關(guān)功能打包成一個庫,雖然程序會大一些(畢竟很多底層代碼和原來的重復(fù)了),但確實是比較簡單的方法(前提是 flash 夠大)。

            魚鷹走的是第一條路,移植,并且將相關(guān)的底層代碼提供了接口,這樣不管是用標準庫還是 HAL 庫,只要自己實現(xiàn)這這些特定的接口即可完成。

            另外,參考例子只是實現(xiàn)了一個最基本的功能,在真正的產(chǎn)品不一定能適用。比如你的程序負載大,而里面為了測量時鐘頻率,幾百微秒時間就要進入一次中斷(即使是分頻后),如果剛好在中斷產(chǎn)生時,其他程序禁用了中斷,運行這些代碼有可能就會出現(xiàn)問題,很容易錯過中斷而導(dǎo)致復(fù)位。

            在我一開始移植的時候就是如此,在一個簡單的程序里面可以正常運行很長時間,但是移植到產(chǎn)品工程里面,時不時出現(xiàn)時鐘檢查不通過的時候,導(dǎo)致程序不停重啟,最終魚鷹通過 DMA 傳輸?shù)姆绞浇鉀Q了這個問題,再也不會因為時鐘檢查不通過導(dǎo)致重啟了。

            另外一個難點是對 .sct (分散加載)文件的理解,這個會在后面介紹。

            安規(guī)相關(guān)的內(nèi)容實在是太多,要寫的話可以寫成一個系列了,如果各位道友感興趣的話,多多轉(zhuǎn)發(fā)支持一下魚鷹,如果效果不錯,魚鷹會考慮完成后續(xù)的其它部分。(這里有一份比較全面但簡單一些的參考文章可以看看 http://news.eeworld.com.cn/mp/STM32/a80041.jspx,只介紹如何做,沒怎么介紹為什么這么做)

            資料

            ST 相關(guān)資料可以查看以下內(nèi)容(www.st.com,下載時需要注冊郵箱才行,魚鷹公眾號后臺提供了部分資料,可自行領(lǐng)?。?/p>

            《AN4435 應(yīng)用筆記》中文版,《AN277》(ROM Self-Test)

            STM8-SafeCLASSB

            https://www.st.com/en/embedded-software/stm8-safeclassb.html

            STM32-CLASSB-SPL(基于標準外設(shè)庫)

            https://www.st.com/en/embedded-software/stm32-classb-spl.html#tools-software

            X-CUBE-CLASSB(基于HAL庫)

            https://www.st.com/en/embedded-software/x-cube-classb.html(不同版本有不同芯片,比如 2.2.0 版本的是 Fx 相關(guān)的,2.3.0 是H7、G0 相關(guān)的)

            當然國產(chǎn)芯片也一般會提供例程。

            1.png

            本篇筆記只介紹其中一個內(nèi)容,即 FLASH 檢查,換句話說就是程序完整性檢查。

            FLASH 檢查

            我們以比較復(fù)雜的 boot + app + rtos ,開發(fā)環(huán)境 keil 、stm32f103 為例介紹相關(guān)知識。

            一般 boot 和 app 部分是用不同工程管理的,所以 app 部分代碼只能檢查自身的完整性,而不能檢查 boot 部分。

            并且 app 的 flash 區(qū)也不是完全檢查的,有一小部分是也沒法檢查的,但這并不影響它的功能(既然已經(jīng)跳轉(zhuǎn)到 app 里面了,那么 boot 部分 flash 即使在運行時有問題也不影響功能,而如果變量初始值的flash有問題就是關(guān)鍵變量檢查的問題了)。

            2.png

            現(xiàn)在就是如何檢查的問題了。

            如何檢查 | 基本原理

            校驗手段有很多,比如 和校驗、MD5 校驗、CRC 校驗,這里我們使用 CRC,因為一般芯片內(nèi)部會內(nèi)置該外設(shè)硬件計算(如果沒有,可以純 CPU 計算)。

            然后我們需要了解完整性檢查的基本原理。

            所謂程序完整性檢查,就是在下載代碼前,先用工具把要校驗的部分通過計算公式計算出一個值,保存在某個地方(flash),然后程序在運行的時候,自己也去讀取要校驗的 flash 部分,通過同樣的計算公式計算出一個值,然后將這個值和保存在 flash 里面的值進行比較,就可以看出代碼是否存在異常了,有異常及時處理,沒有異常就繼續(xù)重新檢查。

            而檢查分成兩個步驟:

            1、開機時,一次性完成所有計算,保證運行前完整。

            2、正常運行時,定時計算,每次計算一個小塊,當計算完最后一塊時才比較結(jié)果,成功就重新繼續(xù)計算,失敗則終止程序運行,周而往復(fù)(計算需要較長的時間,分時計算可以不影響程序正常功能),這樣可以保證程序在運行時也能檢查 FLASH 的完整性,防止 FLASH 運行過程中破壞掉。

            現(xiàn)在有個問題,CRC 保存在何處才是合適的?

            隨便保存在一個地方肯定是不行的。假設(shè)這個位置在要校驗代碼部分的里面,那么當工具計算這個值時,又會篡改掉校驗部分里面的數(shù)據(jù)(因為你把 CRC 值放到里面了),那么你的程序校驗時,肯定不通過,因為你讀了一個被改變的 CRC 值。所以這個值一定要放在代碼的最后面才行。

            另外前面說過,運行時會一小塊一小塊,所以要保證你的 CRC 值存放位置應(yīng)該在小塊大小的邊界位置上。比如一次計算 16 字節(jié),那你存放的位置應(yīng)該是 16 的倍數(shù)才是正常的。

            所以,CRC 存放位置存在這兩個限制。

            另外,如何提前計算好 CRC 的值呢?IAR 內(nèi)置該功能,而 KEIL 我們可以借助強大的開源工具 SRecord《功能強大的 HEX 開源轉(zhuǎn)換工具,你值得擁有》(一轉(zhuǎn)眼,這篇文章差不多鴿了四個多月了)幫助我們計算。

            基本知識都了解的差不多了,接下來就是如何操作的問題。

            實操

            1、固定 CRC 位置。

            我們可以在啟動文件的最后加入以下代碼(END 前)

            這里默認是 0x3D334398,但會在后續(xù)修改成正確的 CRC 值

            ;*******************************************************************************
            ; User Checksum - must be placed at the end of memory
            ;*******************************************************************************
                            AREA    CHECKSUM, DATA, READONLY, ALIGN=6
                            EXPORT  __Check_Sum
            ; Alignement here must correspond to the size of tested block at FLASH run time test (16 words ~ 64 bytes)!!!
                            ALIGN
            __Check_Sum     DCD     0x3D334398;                  ; Check sum computed externaly

            這里保證了 __Check_Sum 的地址是 2 ^ 6 大小對齊,所以你的計算小塊可以這個大小,當然也可以小一些,比如 2 ^ 5 等。這樣就可以將檢查部分分成固定的小塊,不會多,也不會少,剛剛好(必須)。

            那么如何將這個地址固定在代碼最后呢?這個時候就需要我們的 .sct 文件發(fā)揮作用了

            (ClassB_stm32F10x.sct)。
            ER_IROM1 0x08000000 0x10000  {  ; load address = execution address
                  *.o (RESET, +First)
                  *(InRoot$$Sections)
                  .ANY (+RO)
                  *.o (CHECKSUM, +Last) ;放置在最后
                }

            我們用了 +Last 將其放置在代碼的最后部分,你想把它放置在 bin 文件最后面?暫時魚鷹還沒想到怎么做,有知道的道友可以告訴魚鷹(通過 sct 的方式)。

            2、CRC 計算腳本

            在 windows 叫批處理,.bat ,我們可以在參考例程中找到。crc_gen_keil.bat

            我們需要需改三個位置

            3.png

            第一個是你的計算工具的路徑,里面應(yīng)該要有計算工具。

            4.png

            第二個就是你的工程名字,我們通過下面位置確定(魚鷹用的 Main):

            5.png

            最后是工程路徑。一般在 Objects 文件夾里面,而 map 文件一般在 Listings 文件夾里面。

            說白了,這些變量就是為了讓腳本能夠找到 map、hex 文件和工具。但一般默認工程,這兩個文件可能不在一個文件夾里面,所以我們可以對例子中的批處理文件 crc_gen_keil.bat 進行適當修改。

            6.png

            map 文件的作用是為了讓腳本能夠搜索到 __Check_Sum 的地址,然后就可以計算 CRC 并修改 HEX 里面這個值了。

            另外還有新增了一個變量 HEX_ADRR,當我們的計算位置不是從 0x08000000 開始時(比如 app 起始地址在 0x08009000),我們就可以修改這個變量值。還有我們希望在計算完并修改 CRC 后可以自己生成 bin 文件方便我們更新固件,還需要加入轉(zhuǎn)化成 bin 的命令。

            其中為了下載修改(CRC)后的 HEX 文件,我們還需要簡單修改一下,用于判斷工具是否存在,不存在,直接刪除 hex 和 axf 文件(防止下載未修改的文件)。

            %xxx% 類似腳本中的 $xxx

            if not exist %SREC_PATH% (
                echo %SREC_PATH% is not exit, exit
                echo ----------------------------------------del %INPUT_HEX% -- %AXF_FILE% ---------------
                del %INPUT_HEX% %AXF_FILE%
                exit
            )


            *博客內(nèi)容為網(wǎng)友個人發(fā)布,僅代表博主個人觀點,如有侵權(quán)請聯(lián)系工作人員刪除。

            斷路器相關(guān)文章:斷路器原理


            高壓真空斷路器相關(guān)文章:高壓真空斷路器原理
            漏電斷路器相關(guān)文章:漏電斷路器原理


            關(guān)鍵詞: 單片機

            相關(guān)推薦

            技術(shù)專區(qū)

            關(guān)閉