天天看點

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

痞子衡之前寫過兩篇關于IAR中自帶CRC校驗功能的文章,算是把這個功能細節介紹得比較清楚了,但是俗話說得好,理論懂得再多,不能用于實踐那等于沒學。今天痞子衡就利用這個功能來解決一個實際需求

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

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

一、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。

  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。

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

二、開始動手實踐

2.1 确定比對的CRC算法參數設定

  在KBOOT使用者手冊裡可以找到其CRC具體算法,它使用的是比較主流的CRC32-MPEG2分支,具體參數如下表所示:

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

  為了友善核對結果,痞子衡找了一個線上CRC計算的網站,利用這個網站,設定與KBOOT一緻的CRC參數(下圖紅色框内),然後我們選取led_demo_freedom_a000.bin的前16個位元組(下圖藍色框内)作為測試資料輸入,點選Calculate CRC按鈕生成結果0x8D96BDF0(下圖紫色框内)。

線上網站: http://www.sunshine2k.de/coding/javascript/crc/crc_js.html           
痞子衡嵌入式:一次利用IAR自帶CRC完整性校驗功能的實踐(為KBOOT加BCA)

  我們現在回到led_demo_freedom_a000工程,在Linker/Checksum下,使能CRC功能,為了與上述測試一緻,CRC計算範圍設為 0xa000 - 0xa00f(因為程式起始連結位址是0xa000,是以也就是最終.bin裡的前16個位元組)。查閱IAR development手冊,做了如下CRC算法參數設定,編譯工程得到結果也是0x8D96BDF0,是以CRC設定是比對的。

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

2.2 填充BCA的首次嘗試

  确認了CRC設定,現在就是修改源代碼了,在BCA的CRC區域裡将初始的0xFF值全部更換為真實的CRC設定值__checksum、__checksum_begin、__checksum_end,代碼簡單修改如下。重編工程後檢視.bin檔案,發現起止範圍兩個參數是對的,但是CRC校驗值并不對,填成了0x0000a7fc,檢視map檔案得知這是__checksum的連結位址,并不是__checksum的值。想想也是,CRC校驗值是連結生成bin後才計算的,但源檔案是在連結前編譯的,不可能在編譯時得到連結後的結果。

痞子衡嵌入式:一次利用IAR自帶CRC完整性校驗功能的實踐(為KBOOT加BCA)
  • 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)

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

歡迎訂閱

文章會同時釋出到我的 部落格園首頁、CSDN首頁、知乎首頁、微信公衆号 平台上。

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

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

  最後歡迎關注痞子衡個人微信公衆号【痞子衡嵌入式】,一個專注嵌入式技術的公衆号,跟着痞子衡一起玩轉嵌入式。

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

  衡傑(痞子衡),目前就職于恩智浦MCU系統部門,擔任嵌入式系統應用工程師。

  專欄内所有文章的轉載請注明出處:http://www.cnblogs.com/henjay724/

  與痞子衡進一步交流或咨詢業務合作請發郵件至 [email protected]

  可以關注痞子衡的Github首頁 https://github.com/JayHeng,有很多好玩的嵌入式項目。

  關于專欄文章有任何疑問請直接在部落格下面留言,痞子衡會及時回複免費(劃重點)答疑。

  痞子衡郵箱已被私信擠爆,技術問題不推薦私信,堅持私信請先掃碼付款(5元起步)再發。