加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入
  • 正文
    • 一、KBOOT 中 BCA 填入 CRC 校驗(yàn)需求
    • 二、開始動手實(shí)踐
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請入駐 產(chǎn)業(yè)圖譜

一次利用IAR自帶CRC完整性校驗(yàn)功能的實(shí)踐

2020/12/07
410
閱讀需 11 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

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

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

?

一、KBOOT 中 BCA 填入 CRC 校驗(yàn)需求

說起這個(gè)需求,記得那是 2014 年的第一場雪,那時(shí)候痞子衡正在飛思卡爾軟件組參與 Kinetis Bootloader 項(xiàng)目(簡稱 KBOOT)的研發(fā),痞子衡為這個(gè)項(xiàng)目寫過一些文章,詳見 《飛思卡爾 Kinetis 系列 MCU 開發(fā)那些事》 里的啟動篇系列,Kinetis 是飛思卡爾當(dāng)時(shí)主推的 Cortex-M 微控制器,KBOOT 就是為 Kinetis 設(shè)計(jì)的全功能 Bootloader,這可能是嵌入式世界里第一個(gè)精心設(shè)計(jì)的通用架構(gòu) Bootloader。這個(gè) Bootloader 包含一個(gè)用戶配置功能(BCA),簡單說就是在用戶 Application 的偏移 0x3c0 - 0x3ff 這 16 個(gè) word 存放一些 Bootloader 配置,當(dāng) Bootloader 運(yùn)行時(shí)會先嘗試從 Application 區(qū)域讀出這 16 個(gè) word,獲取用戶配置(超時(shí)時(shí)間、外設(shè)類型、id、速度選項(xiàng)等),然后根據(jù)用戶配置再去啟動或升級用戶 Application。

CRC 完整性校驗(yàn)功能占據(jù)了 BCA 里的 12 個(gè) byte,是一個(gè)很重要的 Bootloader 特性,其完整功能詳見 《KBOOT 特性(完整性檢測)》,今天痞子衡要說的需求就是直接在 Application 工程編譯時(shí)生成包含正確 CRC 相關(guān)參數(shù)的 BCA,而不是像以前那樣在最終 binary 文件里二次編輯添加。

我們以 MK64FN1M 這顆芯片為例,下載它的軟件包,軟件包里有 KBOOT 及其示例 Application,找到 SDK_2.8.2_FRDM-K64Fboardsfrdmk64fbootloader_examplesdemo_appsled_demo_freedom_a000iar 下的 Application 工程,工程源文件 startup_MK64F12.s 里定義了 __bootloaderConfigurationArea,但是 CRC 區(qū)域是全 0xFF(即沒有使能),編譯生成的 bin 文件里 CRC 區(qū)域也是全 0xFF,我們要做的就是填入正確的 CRC。

?

二、開始動手實(shí)踐

2.1 確定匹配的 CRC 算法參數(shù)設(shè)置

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

為了方便核對結(jié)果,痞子衡找了一個(gè)在線 CRC 計(jì)算的網(wǎng)站,利用這個(gè)網(wǎng)站,設(shè)置與 KBOOT 一致的 CRC 參數(shù)(下圖紅色框內(nèi)),然后我們選取 led_demo_freedom_a000.bin 的前 16 個(gè)字節(jié)(下圖藍(lán)色框內(nèi))作為測試數(shù)據(jù)輸入,點(diǎn)擊 Calculate CRC 按鈕生成結(jié)果 0x8D96BDF0(下圖紫色框內(nèi))。

在線網(wǎng)站:http://www.sunshine2k.de/coding/javascript/crc/crc_js.html

我們現(xiàn)在回到 led_demo_freedom_a000 工程,在 Linker/Checksum 下,使能 CRC 功能,為了與上述測試一致,CRC 計(jì)算范圍設(shè)為 0xa000 - 0xa00f(因?yàn)槌绦蚱鹗兼溄拥刂肥?0xa000,所以也就是最終 .bin 里的前 16 個(gè)字節(jié))。查閱 IAR development 手冊,做了如下 CRC 算法參數(shù)設(shè)置,編譯工程得到結(jié)果也是 0x8D96BDF0,因此 CRC 設(shè)置是匹配的。

?

2.2 填充 BCA 的首次嘗試

確認(rèn)了 CRC 設(shè)置,現(xiàn)在就是修改源代碼了,在 BCA 的 CRC 區(qū)域里將初始的 0xFF 值全部更換為真實(shí)的 CRC 設(shè)置值 __checksum、__checksum_begin、__checksum_end,代碼簡單修改如下。重編工程后查看 .bin 文件,發(fā)現(xiàn)起止范圍兩個(gè)參數(shù)是對的,但是 CRC 校驗(yàn)值并不對,填成了 0x0000a7fc,查看 map 文件得知這是 __checksum 的鏈接地址,并不是 __checksum 的值。想想也是,CRC 校驗(yàn)值是鏈接生成 bin 后才計(jì)算的,但源文件是在鏈接前編譯的,不可能在編譯時(shí)得到鏈接后的結(jié)果。

  • Note: 上圖中有筆誤,左邊匯編代碼第 306 行應(yīng)更改為(__checksum_end - __checksum_begin + 1),因?yàn)檫@是 crcByteCount,下同。

2.3 填充 BCA 的最終方案

首次嘗試失敗,事情遠(yuǎn)沒有想象得那么簡單,我們需要在工程鏈接文件上動心思,要直接把 __checksum 鏈接到 BCA 里的具體偏移位置。因此 startup_MK64F12.s 里 __bootloaderConfigurationArea 從 crcExpectedValue 及其之后全部去掉,并且 __FlashConfig 也實(shí)際不需要(僅對于鏈接在 0 地址才有效,這是 Kinetis 特性)。

然后我們需要重新在 main.c 里定義一個(gè) bca 常量數(shù)組,把除 crcExpectedValue 之外缺失的 BCA 數(shù)據(jù)全部放進(jìn)去。

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 };

經(jīng)過這么一番操作,讓我們重新編譯工程再看 bin 里結(jié)果,哈哈,這次 BCA 果然是正確的 CRC 校驗(yàn)值了(這次值是 0xf62ce2b6,發(fā)生了變化,因?yàn)樵创a的改動,bin 前 16 個(gè)字節(jié)內(nèi)容也相應(yīng)變化了),大功告成。底下的事情就簡單了,在 CRC 設(shè)置界面里調(diào)整想要的 CRC 計(jì)算范圍即可。

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

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

碩士畢業(yè)于蘇州大學(xué)電子信息學(xué)院,目前就職于恩智浦(NXP)半導(dǎo)體MCU系統(tǒng)部門,擔(dān)任嵌入式系統(tǒng)應(yīng)用工程師。痞子衡會定期分享嵌入式相關(guān)文章