一、CRC校验的使用
STM32内置CRC计算单元,节约了软件计算的时间。在软件开发中,可以为firm追加4字节的CRC校验码到生成的BIN文件最后位置,这个CRC码就是全部代码区域数据的CRC校验值。
在代码执行之前,可以校验CRC是否通过,不通过则说明代码完整性出现错误。尤其在代码IAP升级应用中非常有用,用CRC校验来决定是否更新代码。
但是有一个问题是,常见的CRC校验的主要2个输入参数分别是数据指针和数据长度,这就要求一次把数据传给计算单元。但是代码BIN文件动辄几十KB到几百KB,对单片机来说,无法一次性把代码加载到RAM的buffer中,所以不能使用常规的CRC校验。
二、大文件分段CRC
CRC也是数据流运算,可以参考MD5通用源码,计算MD5主要有3个函数,init,update, final,三个函数分别负责初始化,然后计算每一包,最后扫尾输出计算结果。那么CRC也可以这么计算,这样一个几百kb的BIN文件就可以一次读取一小块数据,然后进行计算并且使用update 函数更新CRC计算结果,最后调用CRC32_Final输出最终的计算值。
CRC32_Init(); CRC32_Update(&ctx, crcBuff, length); CRC32_Final(&ctx, crc32);
CRC32算法使用如下的多项式生成(值04C11DB7h):
CRC32(x) =x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1
// Test-crc.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <stdio.h> #include <stdlib.h> #include "string.h" typedef struct { unsigned long crc; } CRC32_CTX; static unsigned long crc32_tbl[256] = { 0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL, 0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L, 0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L, 0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L, 0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL, 0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L, 0x136C9856L, 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL, 0x14015C4FL, 0x63066CD9L, 0xFA0F3D63L, 0x8D080DF5L, 0x3B6E20C8L, 0x4C69105EL, 0xD56041E4L, 0xA2677172L, 0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL,