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


  你們好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給你們分享的是利用IAR自帶CRC完整性校驗功能的一次實踐(爲KBOOT加BCA)javascript

  痞子衡以前寫過兩篇關於IAR中自帶CRC校驗功能的文章 《在IAR開發環境下爲工程開啓CRC完整性校驗功能的方法》《探析開啓CRC完整性校驗的IAR工程生成.out和.bin文件前後順序》,算是把這個功能細節介紹得比較清楚了,可是俗話說得好,理論懂得再多,不能用於實踐那等於沒學。今天痞子衡就利用這個功能來解決一個實際需求:html

1、KBOOT中BCA填入CRC校驗需求

  提及這個需求,記得那是2014年的第一場雪,那時候痞子衡正在飛思卡爾軟件組參與Kinetis Bootloader項目(簡稱KBOOT)的研發,痞子衡爲這個項目寫過一些文章,詳見 《飛思卡爾Kinetis系列MCU開發那些事》 裏的啓動篇系列,Kinetis是飛思卡爾當時主推的Cortex-M微控制器,KBOOT就是爲Kinetis設計的全功能Bootloader,這多是嵌入式世界裏第一個精心設計的通用架構Bootloader。這個Bootloader包含一個用戶配置功能(BCA),簡單說就是在用戶Application的偏移0x3c0 - 0x3ff這16個word存放一些Bootloader配置,當Bootloader運行時會先嚐試從Application區域讀出這16個word,獲取用戶配置(超時時間、外設類型、id、速度選項等),而後根據用戶配置再去啓動或升級用戶Application。java

  CRC完整性校驗功能佔據了BCA裏的12個byte,是一個很重要的Bootloader特性,其完整功能詳見 《KBOOT特性(完整性檢測)》,今天痞子衡要說的需求就是直接在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。數組

2、開始動手實踐

2.1 肯定匹配的CRC算法參數設置

  在KBOOT用戶手冊裏能夠找到其CRC具體算法,它使用的是比較主流的CRC32-MPEG2分支,具體參數以下表所示:微信

  爲了方便覈對結果,痞子衡找了一個在線CRC計算的網站,利用這個網站,設置與KBOOT一致的CRC參數(下圖紅色框內),而後咱們選取led_demo_freedom_a000.bin的前16個字節(下圖藍色框內)做爲測試數據輸入,點擊Calculate CRC按鈕生成結果0x8D96BDF0(下圖紫色框內)。架構

在線網站: http://www.sunshine2k.de/coding/javascript/crc/crc_js.html

  咱們如今回到led_demo_freedom_a000工程,在Linker/Checksum下,使能CRC功能,爲了與上述測試一致,CRC計算範圍設爲 0xa000 - 0xa00f(由於程序起始連接地址是0xa000,因此也就是最終.bin裏的前16個字節)。查閱IAR development手冊,作了以下CRC算法參數設置,編譯工程獲得結果也是0x8D96BDF0,所以CRC設置是匹配的。app

2.2 填充BCA的首次嘗試

  確認了CRC設置,如今就是修改源代碼了,在BCA的CRC區域裏將初始的0xFF值所有更換爲真實的CRC設置值__checksum、__checksum_begin、__checksum_end,代碼簡單修改以下。重編工程後查看.bin文件,發現起止範圍兩個參數是對的,可是CRC校驗值並不對,填成了0x0000a7fc,查看map文件得知這是__checksum的連接地址,並非__checksum的值。想一想也是,CRC校驗值是連接生成bin後才計算的,但源文件是在連接前編譯的,不可能在編譯時獲得連接後的結果。dom

  • Note: 上圖中有筆誤,左邊彙編代碼第306行應更改成(__checksum_end - __checksum_begin + 1),由於這是crcByteCount,下同。

2.3 填充BCA的最終方案

  首次嘗試失敗,事情遠沒有想象得那麼簡單,咱們須要在工程連接文件上動心思,要直接把__checksum連接到BCA裏的具體偏移位置。所以startup_MK64F12.s 裏__bootloaderConfigurationArea從crcExpectedValue及其以後所有去掉,而且__FlashConfig也實際不須要(僅對於連接在0地址纔有效,這是Kinetis特性)。測試

  而後咱們須要從新在main.c裏定義一個bca常量數組,把除crcExpectedValue以外缺失的BCA數據所有放進去。

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以下:

//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計算範圍便可。

  至此,利用IAR自帶CRC完整性校驗功能的一次實踐(爲KBOOT加BCA)痞子衡便介紹完畢了,掌聲在哪裏~~~

歡迎訂閱

文章會同時發佈到個人 博客園主頁CSDN主頁知乎主頁微信公衆號 平臺上。

微信搜索"痞子衡嵌入式"或者掃描下面二維碼,就能夠在手機上第一時間看了哦。

相關文章
相關標籤/搜索