本文讲述了作者在使用STM32的硬件CRC32校验进行在线升级时遇到的问题,发现与常规CRC32校验的不同之处在于大端校验和特定的校验标准。通过代码调整和解释,作者详细记录了解决方案,包括两端转换和创建MPEG-2校验方式。
摘要由CSDN通过智能技术生成
以前知道stm32存在硬件CRC32校验,但是没有使用过。我用在stm32使用CRC32校验的目的是为了在线升级,可是当今天使用的时候,发现stm32校验的值与常用的CRC检验的结果不一样,有点纳闷,心想,难道硬件CRC有问题。
排查故障,发现stm32硬件CRC校验正确的,只不过它的校验方式与常用的有区别:
1.stm32硬件校验的方式使用的是大端校验。
2.使用的CRC校验为CRC-32/MPEG-2.(与常用CRC32校验区别就是,输入和输出数据反转,同时校验后的CRC值的与0xFFFFFFFF异或)
所以根据以上的区别, 我们有几种方法:
1.在stm32上面修改stm32硬件的校验方式,大小端转换,输入和输出数据反转。
2.在电脑端修改为大端校验,除去输入和输出数据反转。
但是我两个都改了,为了少改代码。。。。。。
电脑端新增
CRC-32/MPEG-2方式,
stm32端
修改校验时的大小端转换,
我使用的查表法,表我就难得贴了
电脑端修改的代码:
在电脑上原来使用的:
#define CRC32_POLYNOMIAL 0x04C11DB7
#define CRC32_INITIAL_VAL 0xFFFFFFFF
#define CRC32_END_VAL 0xFFFFFFFF
#define CRC32_WIDTH 32
uint32_t CRC32(uint8_t *buf, uint32_t len)
uint32_t crc = CRC32_INITIAL_VAL;
for(uint32_t i = 0; i < len; i++)
crc = crc32_table[(uint8_t)(REVERSE_U8(buf[i]) ^ (crc >> (CRC32_WIDTH - 8)))] ^ (crc << 8);
crc ^= CRC32_END_VAL;
return REVERSE_U32(crc);
//REVERSE_U8(uint8_t buf); //输入数据反转
//REVERSE_U32(uint32_t buf);//输出数据反转
修改后,新增的
CRC-32/MPEG-2
校验方式:
#define CRC32_POLYNOMIAL 0x04C11DB7
#define CRC32_INITIAL_VAL 0xFFFFFFFF
#define CRC32_END_VAL 0xFFFFFFFF
#define CRC32_WIDTH 32
uint32_t CRC32_MPEG2(uint8_t *buf,uint32_t len)
uint32_t crc = CRC32_INITIAL_VAL;
for(uint32_t i = 0; i < len; i++)
crc = crc32_table[(uint8_t)((buf[i]) ^ (crc >> (CRC32_WIDTH - 8)))] ^ (crc << 8);
return crc;
两个相比减少了输入数据反转和输出数据反转
stm32修改的代码
使用的HAL库的代码,修改了一点,转换了下大小端。
uint32_t HAL_CRC_Calculate_Rev(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength)
uint32_t index; /* CRC input data buffer index */
uint32_t temp = 0U; /* CRC output (read from hcrc->Instance->DR register) */
/* Change CRC peripheral state */
hcrc->State = HAL_CRC_STATE_BUSY;
/* Reset CRC Calculation Unit (hcrc->Instance->INIT is
* written in hcrc->Instance->DR) */
__HAL_CRC_DR_RESET(hcrc);
/* Enter 32-bit input data to the CRC calculator */
for (index = 0U; index < BufferLength; index++)
hcrc->Instance->DR =__REV( pBuffer[index]);//这里转换了一下
temp = hcrc->Instance->DR;
/* Change CRC peripheral state */
hcrc->State = HAL_CRC_STATE_READY;
/* Return the CRC computed value */
return temp;
这就是修改的相关,这个是我认为改的最少的。。。。。
有问题,希望大家指出!
//STM32硬件CRC32 byte数据计算,将数据移到最高位,低位补上FF
u32 stm32_crc32_byte(u8 *pBuff, u32 len)
u32 i;
u8 buff[4];
u32 *p32 = (u3...
硬件平台
我使用的是STM32F103ZET6单片机,用cubeMX新建的工程(使能crc即可加载\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_crc.c文件)
CRC特性介绍(文档内容来自STM32中文参考手册)
CRC32详细介绍请查看文档
方法一:使用cubeMX初始化硬件CRC
方法二:手动添加文件并初始化硬件CRC
关于STM32F4xx的硬件CRC32校验
前段时间由于项目所需,要对MCU上某些数据进行CRC32校验,MCU选用的是STM32F4系列,以前看到过STM32有硬件CRC32校验功能,决定采用硬件CRC32校验,于是成功入坑。STM32硬件CRC32校验的结果跟预期的值并不一致,参考了大神的方法,校验成功。STM32硬件CRC使用相关资料在网上是相对较少的,所以这里做个总结。
环境:M...
使用前记得使能STM32 CRC时钟
//STM32硬件CRC32 byte数据计算,将数据移到最高位,低位补上FF
u32 stm32_crc32_byte(u8 *pBuff, u32 len)
u32 i;
u8 buff[4];
u32 *p32 = (u32 *)buff;
CRC->CR = 1; //复位CRC寄存器
constUINT32_Tcrc32Tab[256]=
0x00000000,0x04C11DB7,0x09823B6E,0x0D4326D9,0x130476DC,0x17C56B6B,0x1A864DB2,0x1E475005,
0x2608EDB8,0x22C9F00F,0x2F8AD6D6,0x2B4BC...
uint32_t vin =0x5A5AA5A5 ;
uint32_t crcv32 = crc32_sw((uint32_t)0,(uint8_t*)&vin, 4); /* result=0x4FA8A494*/
uint32_t crcv = Sys_Calc_Crc((uint8_t*)&vin, 4);
uint32_...