这是我自己经常采用的的一种方法,如觉得有效,欢迎支持,如有任何需要,欢迎站短。
设有两个int32值crc32Value和crc32Value2存放在FLASH存储空间的最末尾
这篇文章面向于以下几个情境:
1. 无bootloader,裸程序运行,程序运行前进行自检
2. 有bootloader,bootloader为预先由开发人员(你)烧写到MCU里,复位后先运行bootloader,bootloader进行应用程序的完整性检查,完整性检查失败后,进行bootloader操作。否则,跳转至应用程序
3. 有bootloader,或者无bootloader,原始程序里面有加密的字节,根据MCU唯一ID计算出来的校验值。为表述方便,设这个校验值为CheckValue,类型为int32。对于这种情况
> 原始程序里有一个setCheckValue()的程序,
> 一个erase_setCheckValue()的程序,
> 和一个setCRC32Value2()的程序。
编译时,CheckValue的初始值为0xFFFFFF。程序第一次运行时,setCheckValue()根据MCU的唯一ID计算出一个值,FLASH在线烧写到CheckValue的地址,并且之后,erase_setCheckValue()将setCheckValue()所在地址的程序擦除,然后调用setCrc32Value2()计算新的CRC32值,FLASH在线烧写到crc32Value2。之后程序进入正常运行阶段,在程序的正常运行阶段,校验CheckValue和MCU唯一ID值的关系来确定程序合法性。
对于第1、2种情况,程序的完整性校验实现起来很简单,因为程序代码在运行时不改变,因而只需要一个crc32Value即可。
对于第3种情况,程序在第一次运行前,需要完整性检查,使用crc32Value即可。程序在第一次运行后,程序本身的代码发生了变化,需要使用另一个值crc32Value2进行检查。
总结第1、2、3种情况,检查过程可以统一为,检查crc32Value的值是否正确,若不正确,检查crc32Value2的值是否正确。若都不正确,则程序错误,进行bootloader错误处理阶段。
使用Keil MDK时,我们为了方便,需要自动生成crc32Value,下面主要说明编译器的设置,单片机代码端的上述逻辑的处理是比较方便的,以后再说
首先,在options里面添加一项
这项指定编译完成后,执行autocalcrc32.bat批处理程序
其中第一条,调用fromelf文件,生成二进制程序镜像.bin
第二条,调用crc32.exe生成文件authorization_auto_generated.c,393216为bin文件的大小。.c文件内容为
变量program_crc32_chk_value_original为编译时的CRC32值
变量program_crc32_chk_value_reserved为crc32Value2作用的值
其中crc32.exe为我自己编译的程序,如下为文件crc32.c:
编译工具采用VC,命令行调用compile crc32.c进行编译
其中compile.bat为
crc32.c可以根据需要修改。这里计算略去了最后的八个字节,因为是program_crc32_chk_value_original和program_crc32_chk_value_reserved的保留空间。并且文件大小需要整字大小。
Keil编译完后,会调用autocalcrc32.bat,计算出CRC32的值之后,更改文件authorization_auto_generated.c中的program_crc32_chk_value_original
之后需要重新手动编译一遍Keil,使得新的program_crc32_chk_value_original编译到最终的二进制文件里
以上是编译起部分的操作。主要实现的功能是自动生成程序的CRC32校验值,希望对大家有所帮助。
PS:我尝试了许多个CRC32计算的网站,发现应该选择 http://www.zorc.breitbandkatze.de/crc.html 如下的设定,和我的CRC校验结果一直
测试结果如下,可以发现结果一致:
CRC32选项:
CRC32.exe运行结果
其中text.txt为
设有两个int32值crc32Value和crc32Value2存放在FLASH存储空间的最末尾
这篇文章面向于以下几个情境:
1. 无bootloader,裸程序运行,程序运行前进行自检
2. 有bootloader,bootloader为预先由开发人员(你)烧写到MCU里,复位后先运行bootloader,bootloader进行应用程序的完整性检查,完整性检查失败后,进行bootloader操作。否则,跳转至应用程序
3. 有bootloader,或者无bootloader,原始程序里面有加密的字节,根据MCU唯一ID计算出来的校验值。为表述方便,设这个校验值为CheckValue,类型为int32。对于这种情况
> 原始程序里有一个setCheckValue()的程序,
> 一个erase_setCheckValue()的程序,
> 和一个setCRC32Value2()的程序。
编译时,CheckValue的初始值为0xFFFFFF。程序第一次运行时,setCheckValue()根据MCU的唯一ID计算出一个值,FLASH在线烧写到CheckValue的地址,并且之后,erase_setCheckValue()将setCheckValue()所在地址的程序擦除,然后调用setCrc32Value2()计算新的CRC32值,FLASH在线烧写到crc32Value2。之后程序进入正常运行阶段,在程序的正常运行阶段,校验CheckValue和MCU唯一ID值的关系来确定程序合法性。
对于第1、2种情况,程序的完整性校验实现起来很简单,因为程序代码在运行时不改变,因而只需要一个crc32Value即可。
对于第3种情况,程序在第一次运行前,需要完整性检查,使用crc32Value即可。程序在第一次运行后,程序本身的代码发生了变化,需要使用另一个值crc32Value2进行检查。
总结第1、2、3种情况,检查过程可以统一为,检查crc32Value的值是否正确,若不正确,检查crc32Value2的值是否正确。若都不正确,则程序错误,进行bootloader错误处理阶段。
使用Keil MDK时,我们为了方便,需要自动生成crc32Value,下面主要说明编译器的设置,单片机代码端的上述逻辑的处理是比较方便的,以后再说
首先,在options里面添加一项
这项指定编译完成后,执行autocalcrc32.bat批处理程序
其中第一条,调用fromelf文件,生成二进制程序镜像.bin
第二条,调用crc32.exe生成文件authorization_auto_generated.c,393216为bin文件的大小。.c文件内容为
变量program_crc32_chk_value_original为编译时的CRC32值
变量program_crc32_chk_value_reserved为crc32Value2作用的值
其中crc32.exe为我自己编译的程序,如下为文件crc32.c:
编译工具采用VC,命令行调用compile crc32.c进行编译
其中compile.bat为
crc32.c可以根据需要修改。这里计算略去了最后的八个字节,因为是program_crc32_chk_value_original和program_crc32_chk_value_reserved的保留空间。并且文件大小需要整字大小。
Keil编译完后,会调用autocalcrc32.bat,计算出CRC32的值之后,更改文件authorization_auto_generated.c中的program_crc32_chk_value_original
之后需要重新手动编译一遍Keil,使得新的program_crc32_chk_value_original编译到最终的二进制文件里
以上是编译起部分的操作。主要实现的功能是自动生成程序的CRC32校验值,希望对大家有所帮助。
PS:我尝试了许多个CRC32计算的网站,发现应该选择 http://www.zorc.breitbandkatze.de/crc.html 如下的设定,和我的CRC校验结果一直
测试结果如下,可以发现结果一致:
CRC32选项:
CRC32.exe运行结果
其中text.txt为
详细请参考http://www.amobbs.com/thread-5592908-1-1.html