1. 程式人生 > >痞子衡嵌入式:一次利用IAR自帶CRC完整性校驗功能的實踐(為KBOOT加BCA)

痞子衡嵌入式:一次利用IAR自帶CRC完整性校驗功能的實踐(為KBOOT加BCA)

----   大家好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給大家分享的是**利用IAR自帶CRC完整性校驗功能的一次實踐(為KBOOT加BCA)**。   痞子衡之前寫過兩篇關於IAR中自帶CRC校驗功能的文章 [《在IAR開發環境下為工程開啟CRC完整性校驗功能的方法》](https://www.cnblogs.com/henjay724/p/14042538.html)、[《探析開啟CRC完整性校驗的IAR工程生成.out和.bin檔案先後順序》](https://www.cnblogs.com/henjay724/category/1170736.html),算是把這個功能細節介紹得比較清楚了,但是俗話說得好,理論懂得再多,不能用於實踐那等於沒學。今天痞子衡就利用這個功能來解決一個實際需求: ### 一、KBOOT中BCA填入CRC校驗需求   說起這個需求,記得那是2014年的第一場雪,那時候痞子衡正在飛思卡爾軟體組參與Kinetis Bootloader專案(簡稱KBOOT)的研發,痞子衡為這個專案寫過一些文章,詳見 [《飛思卡爾Kinetis系列MCU開發那些事》](https://www.cnblogs.com/henjay724/p/9305876.html) 裡的啟動篇系列,Kinetis是飛思卡爾當時主推的Cortex-M微控制器,KBOOT就是為Kinetis設計的全功能Bootloader,這可能是嵌入式世界裡第一個精心設計的通用架構Bootloader。這個Bootloader包含一個使用者配置功能(BCA),簡單說就是在使用者Application的偏移0x3c0 - 0x3ff這16個word存放一些Bootloader配置,當Bootloader執行時會先嚐試從Application區域讀出這16個word,獲取使用者配置(超時時間、外設型別、id、速度選項等),然後根據使用者配置再去啟動或升級使用者Application。   CRC完整性校驗功能佔據了BCA裡的12個byte,是一個很重要的Bootloader特性,其完整功能詳見 [《KBOOT特性(完整性檢測)》](https://www.cnblogs.com/henjay724/p/9355642.html),今天痞子衡要說的需求就是直接在Application工程編譯時生成包含正確CRC相關引數的BCA,而不是像以前那樣在最終binary檔案裡二次編輯新增。   我們以MK64FN1M這顆晶片為例,下載它的軟體包,軟體包裡有KBOOT及其示例Application,找到 \SDK_2.8.2_FRDM-K64F\boards\frdmk64f\bootloader_examples\demo_apps\led_demo_freedom_a000\iar 下的Application工程,工程原始檔 startup_MK64F12.s 裡定義了__bootloaderConfigurationArea,但是CRC區域是全0xFF(即沒有使能),編譯生成的bin檔案裡CRC區域也是全0xFF,我們要做的就是填入正確的CRC。 ![](http://henjay724.com/image/cnblogs/IAR_CRCPractice_KBOOT_user_app_default.PNG) ### 二、開始動手實踐 #### 2.1 確定匹配的CRC演算法引數設定   在KBOOT使用者手冊裡可以找到其CRC具體演算法,它使用的是比較主流的CRC32-MPEG2分支,具體引數如下表所示: ![](http://henjay724.com/image/cnblogs/Kinetis_Boot_ImageCRC_mpeg2_characteristics.PNG)   為了方便核對結果,痞子衡找了一個線上CRC計算的網站,利用這個網站,設定與KBOOT一致的CRC引數(下圖紅色框內),然後我們選取led_demo_freedom_a000.bin的前16個位元組(下圖藍色框內)作為測試資料輸入,點選Calculate CRC按鈕生成結果0x8D96BDF0(下圖紫色框內)。 ```text 線上網站: http://www.sunshine2k.de/coding/javascript/crc/crc_js.html ``` ![](http://henjay724.com/image/cnblogs/IAR_CRCPractice_KBOOT_crc_js_web_test.PNG)   我們現在回到led_demo_freedom_a000工程,在Linker/Checksum下,使能CRC功能,為了與上述測試一致,CRC計算範圍設為 0xa000 - 0xa00f(因為程式起始連結地址是0xa000,所以也就是最終.bin裡的前16個位元組)。查閱IAR development手冊,做了如下CRC演算法引數設定,編譯工程得到結果也是0x8D96BDF0,因此CRC設定是匹配的。 ![](http://henjay724.com/image/cnblogs/IAR_CRCPractice_KBOOT_iar_checksum_test.PNG) #### 2.2 填充BCA的首次嘗試   確認了CRC設定,現在就是修改原始碼了,在BCA的CRC區域裡將初始的0xFF值全部更換為真實的CRC設定值__checksum、__checksum_begin、__checksum_end,程式碼簡單修改如下。重編工程後檢視.bin檔案,發現起止範圍兩個引數是對的,但是CRC校驗值並不對,填成了0x0000a7fc,檢視map檔案得知這是__checksum的連結地址,並不是__checksum的值。想想也是,CRC校驗值是連結生成bin後才計算的,但原始檔是在連結前編譯的,不可能在編譯時得到連結後的結果。 ![](http://henjay724.com/image/cnblogs/IAR_CRCPractice_KBOOT_iar_first_try.PNG) #### 2.3 填充BCA的最終方案   首次嘗試失敗,事情遠沒有想象得那麼簡單,我們需要在工程連結檔案上動心思,要直接把__checksum連結到BCA裡的具體偏移位置。因此startup_MK64F12.s 裡__bootloaderConfigurationArea從crcExpectedValue及其之後全部去掉,並且__FlashConfig也實際不需要(僅對於連結在0地址才有效,這是Kinetis特性)。   然後我們需要重新在main.c裡定義一個bca常量陣列,把除crcExpectedValue之外缺失的BCA資料全部放進去。 ```C const uint32_t bca[16] @ ".bca_left" = {0x1388ffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}; ```   最後我們需要修改連結檔案MK64FN1M0xxx12_application_0xA000.icf如下: ```text //place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec, readonly section .noinit }; //place in FLASH_region { block ApplicationFlash }; place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; place at address mem:0xa3cc { ro section .checksum }; place at address mem:0xa3d0 { ro section .bca_left }; place in FLASH_region { readonly section .noinit, block ApplicationFlash }; ```   經過這麼一番操作,讓我們重新編譯工程再看bin裡結果,哈哈,這次BCA果然是正確的CRC校驗值了(這次值是0xf62ce2b6,發生了變化,因為原始碼的改動,bin前16個位元組內容也相應變化了),大功告成。底下的事情就簡單了,在CRC設定介面裡調整想要的CRC計算範圍即可。 ![](http://henjay724.com/image/cnblogs/IAR_CRCPractice_KBOOT_iar_final_solution.PNG)   至此,利用IAR自帶CRC完整性校驗功能的一次實踐(為KBOOT加BCA)痞子衡便介紹完畢了,掌聲在哪裡~~~ ### 歡迎訂閱 文章會同時釋出到我的 [部落格園主頁](https://www.cnblogs.com/henjay724/)、[CSDN主頁](https://blog.csdn.net/henjay724)、[知乎主頁](https://www.zhihu.com/people/henjay724)、[微信公眾號](http://weixin.sogou.com/weixin?type=1&query=痞子衡嵌入式) 平臺上。 微信搜尋"__痞子衡嵌入式__"或者掃描下面二維碼,就可以在手機上第一時間看了哦。 ![](http://henjay724.com/image/github/pzhMcu_qrcode_258x