OTA更新利用CRC保证程序的完整性

引子

在对STM32利用4G模块进行远程升级时,如何保证下载下来的bin文件是完整没有丢失的呢?

有两种方式:

1. 分包打校验,接收一包校验一包
2. 整包打校验,接收完毕后整体校验

为快速实现,采用第二种方式

校验方式

选择简单常见的CRC校验,

为了降低难度,参考安富莱电子的教程,使用keil在编译时生成整个程序包的crc校验

keil支持用户定义的命令,如下图在User标签页选择编译后执行的脚本CopyHex_Flash.bat

OTA更新利用CRC保证程序的完整性_第1张图片

该脚本文件中主要利用srec_cat文件对编译生成的hex做crc校验,对于本次实现的OTA更新具体有两种方式:

方式1:在指定位置存放crc

srec_cat.exe .\FLS-B100\FLS-B100.hex -intel -crc32-l-e  0x0803FFFC  -o .\BIN\output-crc.hex -intel  -Output_Block_Size=16

hex2bin .\BIN\output-crc.hex
  • srec_cat.exe .\FLS-B100\FLS-B100.hex -intel 以intel格式读取 hex文
  • -crc32-l-e 0x0800FFFC 在 0x0800FFFC 存放之前文件的crc校验
  • -o .\BIN\output-crc.hex -intel -Output_Block_Size=16 输出操作完毕后的hex文件
  • hex2bin .\BIN\output-crc.hex 生成bin文件

这种方式的优点是: 适合在单片机端做校验,程序可直接定义变量指向该位置,如下:

uint32_t crc_res __attribute__((at(0x0800FFFC)));

代码中可以使用变量crc_res来获取编译时计算的crc结果,然后和单片机计算的结果进行对比

缺点是占用空间,比如程序总大小并没有达到0x0800FFFC ,那么在程序最大末尾段到 0x0800FFFC会自动填充,导致生成的bin文件过大,不适合OTA传输。

方式2:在hex文件末尾存放crc

srec_cat.exe .\FLS-B100\FLS-B100.hex -intel -crc32-l-e  -maximum-address .\FLS-B100\FLS-B100.hex -intel  -o .\BIN\output-crc.hex -intel  -Output_Block_Size=16

hex2bin .\BIN\output-crc.hex
  • -crc32-l-e -maximum-address .\FLS-B100\FLS-B100.hex -intel 在 .\FLS-B100\FLS-B100.hex最大地址也就是最末尾生成 crc校验 以intel格式

这种方式的优点是生成的bin文件小,适合OTA传输

缺点是难以在STM32程序中把变量指向生成的crc所在的位置(因为脚本中设置crc存放与程序的最 末端,而最末端的地址单片机不能向前一种方式直接确定)。为解决这一问题,可以借助EC20做HTTP请求bin文件时返回文件大小来辅助定位crc结果存放的位置。

最终我选择第二种方式,为确保无误,首先手动验证是否能给通过长度计算出crc位置。

1.编译完成后的bin大小:

OTA更新利用CRC保证程序的完整性_第2张图片

2.STM32利用EC20通过HTTP下载bin文件时返回的文件大小
OTA更新利用CRC保证程序的完整性_第3张图片

3.查看bin文件中crc位置

OTA更新利用CRC保证程序的完整性_第4张图片

如图中红色字体注释,验证结果为:可以通过bin文件大小减去4字节得到crc的的结果。这样的话就能最小化固件体积。

实操校验

校验要在bootloader程序中完成,下载bin文件写入到flash后,利用STM32自带的硬件CRC校验 (bin字节总大小-4 )个字节,然后将得到的结果与存放于相对于APP起始位置偏移(bin文件总大小-4)的CRC值进行对比,如果一致,说明程序完整,否则不完整,从而进一步处理。

你可能感兴趣的:(单片机,STM32,OTA)