如何在Keil和IAR环境编译生成的bin文件添加CRC校验值

之前写过一篇文章介绍过 CRC 的原理和应用。在程序升级的情况下,我们可以在烧录下载的 bin 文件添加 CRC 校验值,以校验我们获取的bin文件是否正确。

下面我打算使用 APM32F407 的工程代码,介绍下如何在 Keil 环境和 IAR 环境对编译生成的 bin 文件添加 CRC 校验值。

准备:

1、首先你得准备一个可以正常编译运行的 Keil 和 IAR 工程。

1. 基于IAR环境

IAR软件自带了 IAR ELF Tool 这个工具,它可以把编译生成的bin文件添加CRC校验码,所以使用起来也比较简单就能获得CRC的校验码。只要修改下选项配置还有配合修改下链接文件就可以了。

对于如何在bin文件添加CRC校验码,IAR官方网站也有相关介绍,如下:

https://www.iar.com/knowledge/support/technical-notes/general/calculate-crc32-as-in-stm32-hardware-v.5.50-and-later/

1.1 修改Options配置界面

1.1.1 Checksum选项配置

因为是是要把CRC校验码链接到我们编译生成的bin文件,所以肯定是要配置链接相关的参数的。

在这里插入图片描述

该页面有两部分配置。

第一部分是Flash的起始和结束地址,介绍地址要留出4字节的大小存放CRC校验值。然后剩余的Flash空间用0xFF填充。一般来说我们可以把CRC校验值存放在Flash空间的结束地址,这样在查找bin文件的CRC值时比较容易找到。

第二部分是生成CRC校验码的参数配置,我们要配置为和自己使用的CRC模型一致的配置,对于MCU自动的硬件CRC来说,大多数都是CRC32的模型。

该界面CRC参数的一些配置解释:

  • 1、Checksum size:CRC校验值的大小,4字节

  • 2、Alignment:指定校验值的对齐方式,4字节

  • 3、Algorithm:指定算法。CRC32 (0x4C11DB7)

  • 4、Complement:是否进行补码运算。as is 选择保留原样

  • 5、Bit order:位顺序。MSB优先

  • 6、Reverse byte order within word:反转字内的字节顺序

  • 7、Initial value:初始值。0xFFFFFFFF

  • 8、Checksum unit size:指定校验和进行迭代时的单元大小

1.1.2 Extra Options添加一条命令

在配置好 Checksum 选项是,我编译程序是发现并没有把CRC校验值添加值Bin文件指定的位置。网上找了好久,说需要添加 –keep __checksum 这条命令,然后可以防止IAR优化掉CRC变量值。

在这里插入图片描述

1.1.3 生成bin文件

如果还需要bin文件的画卷,选择下面的选项配置。

在这里插入图片描述

1.2 修改IAR链接文件

我们找到对应MCU的 .icf 文件(一般在对应的IAR安装目录下 .\arm\config\linker ),然后复制一份到自己的工程目录下进行修改。主要其实就是根据前面的 Checksum 配置,把CRC值存放的地址,在 .icf 文件要对应修改链接进代码里面。

place at address mem:0x0803FFFC {
    
     readonly section .checksum };

只要在 .icf 文件添加上面的语句就行。但是 0x0803FFFC 这个地址要与 Checksum 界面的配置要一致。

然后在配置界面,选择这个 icf 文件作为IAR链接文件,如下:

在这里插入图片描述

1.3 验证IAR生成的bin文件CRC值是否正确

我们可以写代码测试一下,使用IAR在bin文件生成的这个CRC值,是否正确。

首先我们可以使用芯片自带的CRC硬件计算(当然也可以使用软件CRC),从 0x08000000 起始地址开始读取,直到 0x0803FFFC 这个地址结束,读取这个区间Flash的内容,然后计算出来的结果,与IAR软件计算出来的结果进行比较是否相等。如果相等那么说明IAR生成的bin文件CRC值时正确的。

主要代码如下:

extern uint32_t __checksum;

/* Calculate bin file CRC value */
uCRCValue = CRC_CalculateBlockCRC((uint32_t *)0x08000000, (0x40000 - 4) / 4);
LOG_Print("CalculateBlockCRC = 0x%08X, IAR_CRC_CheckVal = 0x%08X \r\n", uCRCValue, __checksum);   

if (uCRCValue == __checksum)
{
    
    
    LOG_Print("IAR CRC32 successful\r\n");
    APM_MINI_LEDOn(LED2);
}
else
{
    
    
    LOG_Print("IAR CRC32 error\r\n");
    APM_MINI_LEDOn(LED3);
}

__checksum 这个变量,其实就是IAR软件生成CRC校验值的一个内部变量,使用这个值与我们读取Flash的数据计算出来的值进行比较,测试两者是否相等。

2. 基于Keil环境

Keil平台,是没有像IAR平台那样,自身带有一个工具可以为bin文件生成CRC校验值。所以,要在Keil环境中添加CRC校验码,就需要借助第三方的工具。

下面我 srecord 这个工具生成 CRC 校验码,然后再使用 hex2bin 工具把具有CRC校验码的 hex 文件转换为bin文件。

srecord 工具官网:

https://srecord.sourceforge.net/

hex2bin 工具下载:

https://sourceforge.net/projects/hex2bin/

2.1 工具配置

把之前下载好的 srecord 工具包,其中的一个 srec_cat.exe 工具,放到keil的工程t同级目录下面。

在这里插入图片描述

然后 hex2bin 工具也是,放到keil的工程同级目录下。

2.2 编写 .bat 命令脚本

我们编写一份 .bat 文件的命令脚本,以供 keil 调用 srecordhex2bin 工具去生成bin文件。

我自己编写名为 hex_crc.bat 文件,其内容如下:

srec_cat.exe .\out\CRC_Calculation_Bin_CRC.hex -intel -crop 0x08000000 0x0803FFFC -fill 0xFF 0x08000000 0x0803FFFC -STM32_Little_Endian 0x0803FFFC -o .\output_crc_mdk.hex -intel

hex2bin .\output_crc_mdk.hex

第一条命令就是使用 srec_cat 这个工具,生成带有 CRC 校验码的hex文件。然后再把这个hex文件,使用 hex2bin 工具生成bin文件。

2.3 Keil配置

然后keil里面配置,编译完代码之后,执行刚刚的哪个 .bat 文件就可以生成带有CRC校验码的hex文件和bin文件了。

在这里插入图片描述

2.4 测试验证

Keil环境生成的CRC校验码的bin文件,验证方法和IAR环境生成的也是一样的。都是计算 0x08000000~0x0803FFFC 之间的CRC校验值,然后和Keil环境生成的bin文件的CRC值进行对比,验证是否相等。

代码思路也是一样的,如下:

uint32_t MDK_CRC_CheckVal = *((uint32_t *) 0x0803FFFC);

/* Calculate bin file CRC value */
uCRCValue = CRC_CalculateBlockCRC((uint32_t *)0x08000000, (0x40000 - 4) / 4);
LOG_Print("\r\nCalculateBlockCRC = 0x%08X, MDK_CRC_CheckVal = 0x%08X \r\n", uCRCValue, MDK_CRC_CheckVal);   

if (uCRCValue == MDK_CRC_CheckVal)
{
    
    
    LOG_Print("MDK CRC32 Check successful\r\n");
    APM_MINI_LEDOn(LED2);
}
else
{
    
    
    LOG_Print("MDK CRC32 Check error\r\n");
    APM_MINI_LEDOn(LED3);
}

然后可以通过J-Flash工具烧写bin文件,查看运行结果如下。

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/luobeihai/article/details/133525879
今日推荐