市面上很多基于單片機的產品都具有在線或離線升級功能,為了防止升級過程出現(xiàn)意外,一般我們都會對Flash程序數(shù)據進行校驗,常見的就是添加 CRC 校驗信息。
本文給大家講述一下Keil和IAR中計算CRC值的方法。
Flash自檢的流程
Flash的自檢一般分為啟動時自檢和程序運行時自檢兩個階段。不管是哪種自檢,其思路都是:
在程序編譯完成后,計算整個程序的CRC值,然后將這個CRC值添加到可執(zhí)行文件末尾,再將帶有CRC校驗值的可執(zhí)行文件燒錄到MCU中。程序啟動后,由程序中的自檢代碼重新根據當前Flash內容(不包括預存的CRC校驗值)計算一次CRC值,再與之前預先計算并燒錄到Flash中的CRC校驗值進行比較,如果一致就通過檢測。
這兩個自檢階段的區(qū)別就是:
程序啟動自檢是一次性對整個實際Flash代碼范圍計算出最終的CRC值;而運行時的自檢,為了不影響其他程序模塊的運行,計算CRC的過程是分步進行的,每次計算一部分,分多次計算出最終的CRC值。圍繞Flash的自檢所發(fā)生的問題可以歸為兩大類,一類是預先計算CRC值時和上電后計算CRC值的Flash范圍設置是否一致;第二類就是預先計算CRC時和上電后計算CRC采用的CRC算法是否一致。
如何添加CRC值
下面我們主要介紹如何添加CRC校驗值到可執(zhí)行文件。
1、基于IAR環(huán)境
如果你使用IAR,那么添加CRC值的配置相對比較簡單。通過配置IAR的CRC計算參數(shù),自動對整個FLASH空間進行CRC計算,并將計算結果放到FLASH的末尾。
1. 修改Link文件,指定CRC值的存放位置
在Link文件中增加下面語句,指定checksum在FLASH中的存儲位置。(可點擊圖片放大查看)
該語句指定將CRC的值放在FLASH的末尾位置,是整個FLASH空間的末尾,不是應用程序的代碼末尾。這樣,CRC值的位置就是固定的。不會隨代碼大小而變化。
在自檢代碼中,可以通過__checksum讀取Flash中保存的CRC校驗值來與重新計算的CRC值進行比較。
2. 配置Checksum頁面的參數(shù)
在link文件中指定了checksum的存儲位置后,還要在工程配置菜單中,配置計算CRC值的范圍和參數(shù)。見下圖(可點擊圖片放大查看):
IAR的checksum頁面分為兩個部分。
第一部分,也就是紅線圈出的部分。定義了FLASH中需要計算CRC的范圍和空閑字節(jié)填充值。這里注意要留出flash末尾存儲CRC值的位置。
剩下的部分,就是對checksum計算參數(shù)的設定部分。
Checksum size:?選擇checksum的大小(字節(jié)數(shù))
Alignment:?指定checksum的對齊方式。一般,處理器不支持非對齊訪問時有用,不填的話默認1字節(jié)對齊。
Algorithm:?選擇checksum的算法
Complement:?是否需要進行補碼計算。選擇“As is”就是不進行補碼計算。
Bit order:?位輸出的順序。MSB first,每個字節(jié)的高位在前。LSB first,每個字節(jié)的低位在前。
Reverse byte order within word:?對于輸入數(shù)據,在一個字內反轉各個字節(jié)的順序。
Initial value:?checksum計算的初始化值
Checksum unit size:?選擇進行迭代的單元大小,按8-bit,16-bit還是32-bit進行迭代。
3. STM32CRC外設的配置
與上圖IARchecksum的配置對應,STM32 CRC外設可以按以下配置:
聚= 0x4C11DB7(CRC32)
Initial_Crc = 0Xffffffff
輸入/輸出數(shù)據不反轉
輸入數(shù)據:根據實際Flash范圍設定,留出CRC校驗值的位置
CRC外設初始化及計算代碼(可點擊圖片放大查看):
2、基于Keil環(huán)境
KEIL沒有提供直接生成CRC值的功能,所以需要借助外部的工具計算CRC值,然后添加到可執(zhí)行文件的末尾。 在X-CUBE-CLASSB軟件中提供了bat文件,它會利用外部工具Srecord來生成整個Flash的CRC校驗碼并放在文件末尾。 這個工具同樣也可以和標準外設庫的ClassB庫一起用。 下面我們就來看看如何在KEIL工程中利用Srecord工具來添加CRC值。
1. 安裝Srecord工具
下載Srecord 工具(http://srecord.sourceforge.net )。 將srec_cat.exe,srec_cmp.exe,srec_info.exe拷貝到C:\SREC(自己新建)目錄下。
2. 添加crc_gen_keil.bat及crc_load.ini文件到KEIL工程同級目錄下
打開X-CUBE-CLASSB軟件包中的任意KEIL工程目錄,將其中crc_gen_keil.bat及crc_load.ini文件拷貝到自己的KEIL工程目錄下。
crc_gen_keil.bat:利用外部工具Srecord來生成整個Flash的CRC校驗碼并放在文件末尾。
crc_load.ini:這個文件調試時有用,用來配置調試時導入帶CRC校驗碼的HEX,避免對FLASH檢測失敗導致程序無法正常運行。
這兩個文件中的內容也需要根據新工程路徑進行修改:
將crc_gen_keil.bat中的TARGET_NAME和TARGET_PATH改成跟新工程一致。 否則不能成功的自動生成帶CRC校驗值的HEX文件。
Crc_load.ini文件中的路徑和文件也要和實際的一致
3. 添加定義CRC校驗碼存儲區(qū)域
(可點擊圖片放大查看)
在分散加載文件中將CHECKSUM指定在代碼的末尾。和IAR不同的是,通過在分散加載文件中+last指定checksum的位置,它不是將其固定放在整個flash地址的末尾,而是放在實際代碼的末尾。
(可點擊圖片放大查看)
4. 添加外部命令讓KEIL在編譯結束后,自動生成一個帶CRC校驗值的HEX文件
定義debug和flash download使用的HEX文件路徑,使用帶CRC校驗值的HEX文件。
5. STM32CRC外設的配置
這里需要注意,從X-CUBE-CLASSB的軟件包里拷貝出的crc_gen_keil.bat文件,里面的BYTE_SWAP設為1,也就是它在計算CRC值的時候,輸入的數(shù)據,在一個字內按字節(jié)顛倒順序。
所以直接用HAL_CRC_Calculate函數(shù)進行計算結果是不對的??梢詤⒖枷旅娴拇a來初始化及進行計算:
(可點擊圖片放大查看)
或者,將crc_gen_keil.bat文件,里面的BYTE_SWAP改為0, 就可以直接調用HAL_CRC_Calculate函數(shù)進行計算了。
總結
本文介紹了基于IAR及ARM KEIL中如何添加CRC校驗值的過程。在X-CUBE-CLASSB軟件包中,也都可以找到對應的例程。如果在調試中,遇到FLASH CRC校驗出錯,也不用急。
可以從計算CRC值的范圍設置是否一致和采用的CRC算法是否一致這兩個方面去找原因。一定要調試看看代碼實際執(zhí)行的情況,比如要測試的地址范圍和實際代碼執(zhí)行時計算的地址范圍是否一樣,防止因為coding錯誤造成檢測不通過。
審核編輯:湯梓紅
評論
查看更多