大家好,我是痞子衡,是正經(jīng)搞技術(shù)的痞子。今天痞子衡給大家分享的是在 IAR 開發(fā)環(huán)境下為工程開啟 CRC 完整性校驗功能的方法。
CRC 校驗在嵌入式領(lǐng)域里的應用非常廣,比如在通信領(lǐng)域,CRC 檢驗值可以作為數(shù)據(jù)包的一部分,用于檢查一包數(shù)據(jù)傳輸過程中是否發(fā)生了比特錯誤,如果 CRC 校驗失敗,那么接收方可以通知發(fā)送方要求該包數(shù)據(jù)重新傳輸,這樣能大大增加數(shù)據(jù)傳輸?shù)目煽啃浴M瑫r CRC 在應用程序完整性驗證方面也有廣泛應用,相比和檢驗,CRC 校驗糾錯能力更強;相比簽名校驗,CRC 校驗在速度方面又占優(yōu)勢,因此它是一個各方面比較均衡的完整性驗證手段。
IAR 是個非常老牌的嵌入式開發(fā)集成環(huán)境,它的功能非常強大,有很多寶藏功能值得我們?nèi)グl(fā)掘。痞子衡自畢業(yè)之后就一直在使用 IAR,算是一路看著它從古典畫風的 v6.50.x 升級到現(xiàn)在潮流的 v8.50.x,對于經(jīng)典的 CRC 校驗功能的支持,IAR 當然不會放過,今天痞子衡就來介紹 IAR 下如何使用其自帶的 CRC 校驗功能。
?
一、ielftool 命令行工具
IAR 安裝目錄下有非常多的命令行小工具,這些小工具其實就是 IAR 的核心,集成開發(fā)環(huán)境界面只是提供人機交互,其背后的很多功能都是通過調(diào)用這些命令行小工具來實現(xiàn)的。其中用于實現(xiàn) CRC 校驗的功能就包含在 ielftool.exe 工具里:
ielftool.exe 工具跟 CRC 相關(guān)的一共兩個參數(shù)選項,一是 --fill 用于填充,二是 --checksum 用于設置算法,具體參數(shù)使用細節(jié)詳見 IAR SystemsEmbedded Workbench 8.50.6armdocEWARM_DevelopmentGuide.ENU 手冊里的 Checksum calculation for verifying image integrity 小節(jié)。
此處痞子衡僅舉一個簡單例子,如下命令表示在源可執(zhí)行文件 sourceFile.out 中計算范圍 __checksum_begin - __checksum_end 之間的 CRC 結(jié)果,最終校驗值 __checksum 長度為 4 字節(jié)、固定 CRC32 算法、計算單元為 1 字節(jié)、指定 CRC 初始值為 0xffffffff,其余設置默認,并將結(jié)果放在目標可執(zhí)行文件 destinationFile.out 中。
ielftool --fill="0xFF;__checksum_begin–__checksum_end"
--checksum="__checksum:4,crc32:p,0xffffffff;__checksum_begin-__checksum_end"
sourceFile.out
destinationFile.out
從上面的命令你應該能知道,sourceFile.out 并不是任意可執(zhí)行文件都行的,其必須包含必要的 __checksum_begin、__checksum_end、__checksum 的定義。假設我們代碼中并沒有實際使用 CRC,那么我們需要在生成 sourceFile.out 文件的 IAR 工程選項里做如下設置:
注意:__checksum_begin、__checksum_end 符號、__checksum 變量、.checksum 段四個名字,用戶都可以自定義的,這里命名成這樣主要是為了和 IAR 默認定義相統(tǒng)一。
讓我們隨便找一個嵌入式 IAR 工程按上面設置生成源 hello_world.out 文件,并使用 ielftool 工具執(zhí)行一次命令看看,可以看到產(chǎn)生了 __checksum 值,新生成的 hello_world_1.out 文件里包含了正確的 CRC 校驗結(jié)果。
?
二、為工程添加 CRC 校驗
IAR 界面里有兩種使用 ielftool 來生成 CRC 校驗值的方法,痞子衡一一介紹:
?
2.1 利用 Checksum 功能
第一種是直接在 IDE 界面里配置,我們隨便打開一個嵌入式工程,比如 SDK_2.8.2_FRDM-K64Fboardsfrdmk64fdemo_appshello_worldiar,在工程選項 Linker/Checksum 下面,勾選 Fill unused code memory 和 Generate checksum 便使能了 CRC 校驗,藍色框里的兩個地址用于設置 CRC 計算范圍,綠框里的參數(shù)用于設置 CRC 算法細節(jié),具體每個配置什么意義可以查看 IAR SystemsEmbedded Workbench 8.50.6armdocEWARM_DevelopmentGuide.ENU 手冊里的 Checksum 一節(jié),痞子衡在這里不予展開。
下圖示例配置中有兩點要說明:一、算法選擇了 CRC32,其多項式系數(shù)其實固定為 0x04C11BD7;如果想自定義 CRC32 多項式系數(shù)值,可選 CRC polynomial;二、因為地址設置的是 0x0 - 0x400,一共 1025 個字節(jié)(包含 0x400),所以 checksum unit size 此處僅能選 8-bit,因為 IDE 強制要求地址對齊。
設置好之后重新編譯工程,此時會報錯“ielftool error: The string '__checksum' was not found in the string table ”,因為在程序代碼里,我們完全沒有任何 CRC 相關(guān)的引用,IAR 會忽略界面里使能的 CRC 功能,所以我們還需要將 __checksum 強行加入如下選項里(注意 __checksum 是 IAR 里默認定義的 CRC 檢驗值符號名)。
這時候再編譯工程就可以在生成的 .out 和 .map 文件里看到 CRC 信息了,__checksum 被鏈接器隨機放在了 0x2844 的位置,__checksum_begin 和 __checksum_end 是 IAR 默認記錄 CRC 計算范圍的符號變量名。
如果你想自己決定 __checksum 的鏈接位置,你可以在工程鏈接文件里添加放置 section .checksum,這個段便對應著 __checksum。比如我們試著將這個段放在 0x1000 的位置:
再一次編譯工程,查看 map 文件,這次 __checksum 被放在了我們指定的 0x1000 的位置。
?
2.2 利用 Post-build 功能
第二種方式是利用 IDE 里的 Post-build 功能,在第一節(jié)的基礎(chǔ)上,在工程選項 Linker/Extra Options 里把 ielftool 命令加進去,這樣在編譯工程的時候,IAR 會自動跑這個命令:
$TOOLKIT_DIR$binielftool --fill="0xFF;__checksum_begin-__checksum_end" --checksum="__checksum:4,crc32:p,0xffffffff;__checksum_begin-__checksum_end" --verbose "$TARGET_PATH$" "$TARGET_PATH$"
上述命令與第一節(jié)中命令基本一致,只是用"" ""替代了 sourceFile.out destinationFile.out,并且加了 --verbose 顯示執(zhí)行操作信息:
?
三、在工程中驗證 CRC 校驗
IAR 生成的 CRC 校驗值在應用程序里的使用就比較簡單了,見如下代碼,其中 calc_crc()函數(shù)需與我們之前在 IAR 配置的 CRC 算法參數(shù)相一致,此外代碼中的數(shù)據(jù)類型也是與具體 CRC 配置有關(guān)的。
另外還有兩個注意點:一、CRC 計算范圍不應包含 __checksum 存放位置;二、CRC 計算范圍如果沒有按照算法對齊要求,那么實際計算時要相應補上 0(使用 IDE 配置生成是強制對齊的,但是使用命令行沒有強制對齊)。
extern?uint32_t?const?__checksum;
extern?int32_t?__checksum_begin;
extern?int32_t?__checksum_end;
void?TestChecksum()
{
????uint32_t?calc?=?0;
????//?根據(jù) CRC 計算范圍重算新 CRC 校驗值
????calc?=?calc_crc(0xFFFFFFFF,
????????????????????(uint8_t?*)?&__checksum_begin,
????????????????????((uint8_t?*)?&__checksum_end?-?((uint8_t?*)?&__checksum_begin)?+?1));
????//?比對新 CRC 校驗值與 IAR 生成的 CRC 校驗值
????if?(calc?!=?__checksum)
????{
????????printf("Incorrect?checksum!n");
????}
}
至此,在 IAR 開發(fā)環(huán)境下為工程開啟 CRC 完整性校驗功能的方法痞子衡便介紹完畢了,掌聲在哪里~~~