保證代碼的完整性是嵌入式軟件開發中非常重要的一項任務。代碼的完整性檢查主要可以用于以下場合:
1. 在產線生產的時候,通過讀取相關軟件代碼版本號和相應的校驗碼來保證燒錄到MCU中的軟件是正確的;
2. 在通過Bootloader升級Application的時候,可以計算Application對應的校驗碼并和之前存取的Application的校驗碼進行比較,保證Application升級的正確性;
3. 在運行過程中,可以計算Application對應的校驗碼并和之前存取的Application校驗碼進行比較,保證Application在沒有損壞的情況下運行。(注意:根據需求的不同,在運行過程中可以分為上電檢查一次和運行過程中周期性地檢查)。
代碼的完整性檢查一般是通過計算對應代碼區域的校驗碼,并和之前存儲的校驗碼進行比較,若二者一致,說明對應代碼區域的完整性是好的,否則說明對應代碼區域數據被損壞。當然,完整性檢查準確率跟校驗碼有很大的關系,業界比較常用的是CRC。(注意:本文不對CRC原理進行詳細說明,想了解更多關于CRC的內容,請參考相關文獻。) IAR Embedded Workbench中內嵌了ielftool,可以在Link的時候生成對應代碼區域的校驗碼并存儲在指定的地址。 目前越來越多的MCU中內嵌了CRC硬件模塊,可以用于快速計算對應代碼區域的校驗碼。(本文以STM32 MCU為例介紹,方法同樣適用于其它帶CRC硬件模塊的MCU。)
本文主要介紹如何在IAR Embedded Workbench中生成對應代碼區域的校驗碼并存儲在指定的地址,然后利用MCU中內嵌的CRC硬件模塊計算對應代碼區域的校驗碼,并和之前存儲的校驗碼進行比較來檢查代碼的完整性。
在IAR Embedded Workbench中生成對應代碼區域的校驗碼并存儲在指定的地址
下面的選項使用CRC-32/MPEG-2為例生成對應代碼區域的校驗碼: 在IAR Embedded Workbench工程選項(Options)里面Linker選項里面生成Checksum 1. 勾選“Fill unused code memory”, Fill pattern里面填充相應的值(關于填充值請參考往期文章:“填充沒有使用的ROM來提高系統的健壯性”) 2. Start address和End address輸入對應代碼區域的地址(注意:不能包括存放Checksum的地址區域。比如,Checksum存放與0x080FFFFC ~ 0x080FFFFF, End address需要輸入0x080FFFFB)
3. 勾選“Generate Checksum”:
· Checksum Size: 選擇 “4 bytes”,
· Alignment: 輸入 “4”,
· Algorithm: 選擇 “CRC32”
· Complement: 選擇 “As is”,
· Initial value: 輸入“0xFFFFFFFF”,不要勾選“Use as input”
· Bit order: 選擇 “MSB first”
· 不要勾選 “Reverse byte order within word”
· Checksum unit size: 選擇 “32-bit”
在ICF文件中輸入相應命令將Checksum放置指定的地址(這里是將checksum放置到Flash的最后):
place at end of FLASH_region { section .checksum };構建(Build)并查看相關Log信息和map文件
構建(Build)成功之后,在Build窗口會顯示對應代碼區域的Checksum相關信息(Build窗口中的Filter Level要為All):
查看生成的map文件:
__checksum:存放于地址0x80f'fffc ~ 0x80f'ffff (Size: 4 bytes)
__checksum_begin: Checksum計算的起始地址:0x800'0000
__checksum_end: Checksum計算的結束地址:0x80f'fffb
在代碼中調用CRC硬件模塊計算對應代碼區域的校驗碼并和之前存儲的校驗碼進行比較
首先需要在代碼中聲明Checksum相關的變量:
/* Linker generated symbols */ extern uint32_t const __checksum; extern uint32_t __checksum_begin; extern uint32_t __checksum_end;
然后在代碼中計算對應代碼區域的校驗碼并和之前存儲的校驗碼進行比較(注意:每次重新計算之前需要Reset CRC模塊):
/* Resets the CRC calculation unit */ CRC->CR = 0x01; /* Calculate the code flash using CRC calculation unit */ CrcValue = HAL_CRC_Accumulate(&hcrc, (uint32_t *)&__checksum_begin, (((uint32_t)&__checksum_end - (uint32_t)&__checksum_begin + 1u)/4u)); /* Compare the calculated CRC with the previously stored CRC */ if(__checksum == CrcValue) { RomTst_Result = true; } else { RomTst_Result = false; }
調試
調試發現,通過CRC硬件模塊計算出來的校驗碼和之前存儲的校驗碼是一致的,說明檢查代碼區域的完整性是好的:
總結
本文主要介紹了如何在IAR Embedded Workbench中配置在Link時生成對應代碼區域的校驗碼并存儲于指定地址,然后在運行過程中使用MCU內嵌的CRC硬件模塊計算對應代碼區域的校驗碼,并和之前存儲的校驗碼進行比較來檢查對應代碼區域的完整性。
審核編輯:湯梓紅
-
mcu
+關注
關注
146文章
17319瀏覽量
352650 -
嵌入式
+關注
關注
5092文章
19177瀏覽量
307680 -
IAR
+關注
關注
5文章
354瀏覽量
36780 -
Embedded
+關注
關注
0文章
44瀏覽量
22266
原文標題:使用IAR Embedded Workbench和MCU的CRC模塊來檢查代碼的完整性
文章出處:【微信號:IAR愛亞系統,微信公眾號:IAR愛亞系統】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論