本帖最后由 ChangjiangSZ 于 2023-12-15 17:05 编辑
AC7840有对应的CRC模块,可以用于计算对应数据的CRC。
IAR中的linker可以计算对应地址范围的checksum并放到指定的地址,参考IAR的技术文章“使用IAR Embedded Workbench和MCU的CRC模块来检查代码的完整性”:
https://www.iar.com/cn/knowledge/support/technical-notes/general/verifying-integrity-by-iar-embedded-workbench-and-crc/
汽车电子中Application的checksum很多地方都需要用到:
1. 在产线生产的时候,通过读取相关软件代码版本号和相应的校验码来保证烧录到MCU中的软件是正确的;
2. 在通过Bootloader升级Application的时候,可以计算Application对应的校验码并和之前存取的Application的校验码进行比较,保证Application升级的正确性;
3. 在运行过程中,可以计算Application对应的校验码并和之前存取的Application校验码进行比较,保证Application在没有损坏的情况下运行。(注意:根据需求的不同,在运行过程中可以分为上电检查一次和运行过程中周期性地检查)。
下面介绍如何在IAR Embedded Workbench中生成对应Application的checksum并利用AC7480内部的CRC模块在运行过程中计算对应Application的checksum,然后和之前存取的Application的checksum进行比较,来检查对应Application的完整性。
1. 打开SDK里面的01_CRC_Sample工程:
2. 将调试器设置为I-jet:
3. 修改crc.c文件里面对应的CRC32配置为CRC-32/MPEG-2:
CRCConfig.finalXOR = 0; /* 对读到的数据不进行异或运算 */
CRCConfig.poly = 0x4C11DB7; /* CRC-32 Poly: 0x4C11DB7 */
CRCConfig.readTransposeType = CRC_TRANSPOSE_NONE; /* 读转置配置 */
CRCConfig.seed = 0xFFFFFFFF; /* 种子32位为: 0xFFFFFFFF*/
CRCConfig.writeBytesNumOnce = CRC_WRITE_4_BYTE_ONCE; /* CRC一次写一个字节 */
CRCConfig.writeTransposeType = CRC_TRANSPOSE_NONE; /* 写字节转置配置 */
4. 下载调试工程,对应0x1234567的CRC-32/MPEG-2结果为0xDF8A8A2B:
与https://crccalc.com/计算结果一致:
5. 在IAR Embedded Workbench中使用CRC-32/MPEG-2计算AC740x Flash的checksum并放到指定的地址
Project > Options > Linker > Checksum > Generate checksum:
在ICF里面添加下面的命令将__checksum放到Flash的最末尾处:
place at end of IROM1_region { section .checksum };
在crc.c文件里面添加对应的测试代码
下面的代码是声明checksum相关的symbols(linker生成):
/* Linker generated symbols */
extern uint32_t const __checksum;
extern uint32_t __checksum_begin;
extern uint32_t __checksum_end;
下面的代码是周期性地使用AC7840内部的CRC模块计算对应Flash区域的checksum,并与之前的checksum进行比较(注意:每次重新计算之前需要重新初始化CRC,确保数据寄存器里面的初始值是0xFFFFFFFF): while (1)
{
CRC_DRV_Init(0, &CRCConfig); /* 初始化CRC */
/* Calculate the code flash using CRC calculation unit */
CRC_DRV_WriteData(0, (uint8_t const*)&__checksum_begin,
((uint32_t)&__checksum_end - (uint32_t)&__checksum_begin + 1u));
/* Compare the calculated CRC with the previously stored CRC */
if(__checksum == CRC_DRV_GetCrcResult(0))
{
printf("CRC is OK\r\n");
}
else
{
printf("CRC is NOK\r\n");
}
}
编译工程,查看对应Build Log里面checksum的相关信息:
对应checksum的起始地址和结束地址分别是:0x0和0xFFFFB,计算出来的checksum的值是0xdce57890,同时计算出来的checksum放在地址0xFFFFC:
查看MAP文件中checksum相关的symbol:
下载调试:
可以看到CRC模块计算出来的checksum结果是0xdce57890,跟之前保存的checksum是一致的:
注意:
1. 一定要保证IAR Embedded Workbench的checksum配置和AC7840里面的CRC模块配置一致,才能确保二者计算出的checksum是一致的,更多关于IAR Embedded Workbench中checksum的配置,可以参考IAR的技术文章“在IAR Embedded Workbench中选择对应Checksum的CRC算法来匹配MCU的CRC模块”:
https://www.iar.com/cn/knowledge/support/technical-notes/linker/iar-embedded-workbench-checksum-crc/
2. 由于checksum计算需要花费比较长的时间,在实际运行过程中,一般将checksum的比较放到最低优先级的任务当中,这样就不会影响高优先级任务的运行。
至此在IAR Embedded Workbench中生成对应Application的checksum,然后在运行过程中使用AC7840的CRC模块计算对应地址区域的checksum,并与之前保存的checksum进行比较就介绍到这里,希望对大家有所帮助。
|