背景
在我准备使用32对U盘进行格式化时,其中涉及到分区表的CRC32校验值的填写,为了节约时间,我准备使用stm32上自带的CRC32校验单元;
但是在经过Demo测试后,发现32的CRC校验算法并非普通的CRC,而是CRC-32/MPEG-2算法
这两个算法的区别可以使用下面的网站自行测试
发现
这里探索一下他们加密的细节和区别
假设我们校验11223344,即0x44332211
使用网站测试:
CRC-32/MPEG-2网站测试为: B14257CC
CRC网站测试为: 77F29DD1
使用stm32测试:
//要校验的数据
uint8_t sector2[4] = {
0x11, 0x22, 0x33, 0x44,
};
//转换大端32位
uint32_t sector_uint32;
sector_uint32 = (sector2[0] << 24) | (sector2[1] << 16) | (sector2[2] << 8) | sector2[3];
//校验
uint32_t ret = HAL_CRC_Calculate(&hcrc , §or_uint32, 1);
//输出查看
printf("\r\n%02X\r\n", ret);
printf("\r\n%02X", ((uint8_t*)&ret)[0]);
printf("\r\n%02X", ((uint8_t*)&ret)[1]);
printf("\r\n%02X", ((uint8_t*)&ret)[2]);
printf("\r\n%02X", ((uint8_t*)&ret)[3]);
结果为
B14257CC
CC
57
42
B1
经过对比,可知,在字节数组中11,22,33,44的顺序,需要倒序后才能交给CRC校验处理,处理结果为正常的小端数据。
由此,我们重新对代码修改,将大小端转换优化,使用hal库自带的大小端转换
宏:_REV
此宏即可将32位的数据翻转
置于代码如下
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]); //添加了__REV将字翻转
}
temp = hcrc->Instance->DR;
/* Change CRC peripheral state */
hcrc->State = HAL_CRC_STATE_READY;
/* Return the CRC computed value */
return temp;
}
之后就不需要使用(sector2[0] << 24) | (sector2[1] << 16) | (sector2[2] << 8) | sector2[3];
来翻转了
结论:
虽然探索完了stm32硬件CRC但是这个校验方式与U盘分区的CRC校验完全不符,无法使用
本次作为学习记录
如有错误,敬请指正;