你們好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給你們分享的是在IAR開發環境下爲工程開啓CRC完整性校驗功能的方法。算法
CRC校驗在嵌入式領域裏的應用很是廣,好比在通訊領域,CRC檢驗值能夠做爲數據包的一部分,用於檢查一包數據傳輸過程當中是否發生了比特錯誤,若是CRC校驗失敗,那麼接收方能夠通知發送方要求該包數據從新傳輸,這樣能大大增長數據傳輸的可靠性。同時CRC在應用程序完整性驗證方面也有普遍應用,相比和檢驗,CRC校驗糾錯能力更強;相比簽名校驗,CRC校驗在速度方面又佔優點,所以它是一個各方面比較均衡的完整性驗證手段。微信
IAR是個很是老牌的嵌入式開發集成環境,它的功能很是強大,有不少寶藏功能值得咱們去發掘。痞子衡自畢業以後就一直在使用IAR,算是一路看着它從古典畫風的v6.50.x升級到如今潮流的v8.50.x,對於經典的CRC校驗功能的支持,IAR固然不會放過,今天痞子衡就來介紹IAR下如何使用其自帶的CRC校驗功能。app
IAR安裝目錄下有很是多的命令行小工具,這些小工具其實就是IAR的核心,集成開發環境界面只是提供人機交互,其背後的不少功能都是經過調用這些命令行小工具來實現的。其中用於實現CRC校驗的功能就包含在ielftool.exe工具裏:ide
ielftool.exe工具跟CRC相關的一共兩個參數選項,一是--fill用於填充,二是--checksum用於設置算法,具體參數使用細節詳見 \IAR Systems\Embedded Workbench 8.50.6\arm\doc\EWARM_DevelopmentGuide.ENU手冊裏的Checksum calculation for verifying image integrity小節。函數
此處痞子衡僅舉一個簡單例子,以下命令表示在源可執行文件sourceFile.out中計算範圍__checksum_begin - __checksum_end之間的CRC結果,最終校驗值__checksum長度爲4字節、固定CRC32算法、計算單元爲1字節、指定CRC初始值爲0xffffffff,其他設置默認,並將結果放在目標可執行文件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並非任意可執行文件都行的,其必須包含必要的__checksum_begin、__checksum_end、__checksum的定義。假設咱們代碼中並無實際使用CRC,那麼咱們須要在生成sourceFile.out文件的IAR工程選項裏作以下設置:post
注意:__checksum_begin、__checksum_end符號、__checksum變量、.checksum段四個名字,用戶均可以自定義的,這裏命名成這樣主要是爲了和IAR默認定義相統一。ui
讓咱們隨便找一個嵌入式IAR工程按上面設置生成源hello_world.out文件,並使用ielftool工具執行一次命令看看,能夠看到產生了__checksum值,新生成的hello_world_1.out文件裏包含了正確的CRC校驗結果。.net
IAR界面裏有兩種使用ielftool來生成CRC校驗值的方法,痞子衡一一介紹:命令行
第一種是直接在IDE界面裏配置,咱們隨便打開一個嵌入式工程,好比 \SDK_2.8.2_FRDM-K64F\boards\frdmk64f\demo_apps\hello_world\iar\,在工程選項Linker/Checksum下面,勾選Fill unused code memory和Generate checksum便使能了CRC校驗,藍色框裏的兩個地址用於設置CRC計算範圍,綠框裏的參數用於設置CRC算法細節,具體每一個配置什麼意義能夠查看 \IAR Systems\Embedded Workbench 8.50.6\arm\doc\EWARM_DevelopmentGuide.ENU手冊裏的Checksum一節,痞子衡在這裏不予展開。
下圖示例配置中有兩點要說明:1、算法選擇了CRC32,其多項式係數其實固定爲0x04C11BD7;若是想自定義CRC32多項式係數值,可選CRC polynomial;2、由於地址設置的是 0x0 - 0x400,一共1025個字節(包含0x400),因此checksum unit size此處僅能選8-bit,由於IDE強制要求地址對齊。
設置好以後從新編譯工程,此時會報錯「ielftool error: The string '__checksum' was not found in the string table 」,由於在程序代碼裏,咱們徹底沒有任何CRC相關的引用,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的位置。
第二種方式是利用IDE裏的Post-build功能,在第一節的基礎上,在工程選項Linker/Extra Options裏把ielftool命令加進去,這樣在編譯工程的時候,IAR會自動跑這個命令:
$TOOLKIT_DIR$\bin\ielftool --fill="0xFF;__checksum_begin-__checksum_end" --checksum="__checksum:4,crc32:p,0xffffffff;__checksum_begin-__checksum_end" --verbose "$TARGET_PATH$" "$TARGET_PATH$"
上述命令與第一節中命令基本一致,只是用"$TARGET_PATH$" "$TARGET_PATH$"替代了sourceFile.out destinationFile.out,而且加了--verbose顯示執行操做信息:
IAR生成的CRC校驗值在應用程序裏的使用就比較簡單了,見以下代碼,其中calc_crc()函數需與咱們以前在IAR配置的CRC算法參數相一致,此外代碼中的數據類型也是與具體CRC配置有關的。
另外還有兩個注意點:1、CRC計算範圍不該包含__checksum存放位置;2、CRC計算範圍若是沒有按照算法對齊要求,那麼實際計算時要相應補上0(使用IDE配置生成是強制對齊的,可是使用命令行沒有強制對齊)。
extern uint32_t const __checksum; extern int32_t __checksum_begin; extern int32_t __checksum_end; void TestChecksum() { uint32_t calc = 0; // 根據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開發環境下爲工程開啓CRC完整性校驗功能的方法痞子衡便介紹完畢了,掌聲在哪裏~~~
文章會同時發佈到個人 博客園主頁、CSDN主頁、知乎主頁、微信公衆號 平臺上。
微信搜索"痞子衡嵌入式"或者掃描下面二維碼,就能夠在手機上第一時間看了哦。