保证代码的完整性是嵌入式软件开发中非常重要的一项任务。代码的完整性检查主要可以用于以下场合:
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硬件模块计算对应代码区域的校验码,并和之前存储的校验码进行比较来检查对应代码区域的完整性。
捷捷微电:新型片式元器件项目基础建设已完成50%
详解CUTLASS的工作原理
大数据时代 安防云存储的特征盘点
微芯科技公布2024财年第三季度业绩,净销售额环比下降21.7%,净利润下滑
综合布线选择低烟无卤阻燃线缆的优势
使用IAR Embedded Workbench和MCU的CRC模块来检查代码的完整性
高空车电控,高空作业平台电控系统方案
科大讯飞与HANCOM集团双方签署了投资协议,共同构筑中韩A.I业务生态体系
首批Windows Phone 7系列手机图赏 让你的眼球目
Micro LED在手机市场初步应用,10年内或广泛应用
为什么不同品牌之间的空气净化器价格差别非常大
联发科未死 魅族将发布魅蓝Note6等10款机型搭载联发科P20/25为主
工业机器人产业链逐步完善,进口替代有望加速
2018年人工智能开支将达到191亿美元
利用夹层板和DragonBoard 410进行开发
SMT贴片转线/换线注意事项
GTC23 | NVIDIA 发布大型语言模型和生成式 AI 服务以推动生命科学研发
小米8日又将发神器口罩!跟帝都雾霾说拜拜!
用于粘液生理特性原位传感的无线微型生物传感器设计
用于研究单个纳米颗粒表面的显微光谱