crc32
Posted: Tue Aug 12, 2025 1:30 pm
根据官方资料,esp32和stm32h7的硬件crc32使用了同一个多项式。但是我实际测试发现,比如一个uint32_t类型的数组,需要把每个uint32_t数据先byteswap,然后再使用crc32_be api,两者才能算得一致的结果,而且esp32的初始值和结果还需要位反转(~),具体的,比如stm32上
到了esp32-c3上代码要改成这样:
其中BE版本的输出结果才和stm32一致。而如下这个软实现版本,则无论在stm32还是esp32上,结果都和stm32的crc api结果一致。
请问stm32和esp32的硬件crc能不通过byteswap每个32bit word得到同样的结果吗?我需要在通讯中使用这个crc32校验数据包,不大可能考虑全部copy再byteswap的方式来实现这个校验。
Code: Select all
static uint32_t chunk[5] =
{ 0x12345678, 0x9ABCDEF0, 0x12345678, 0x00000000, 0xffffffff };
printf("[0x00000000]: 0x%08lx\r\n", HAL_CRC_Calculate(&hcrc, &chunk[3], 1));
printf("[0xffffffff]: 0x%08lx\r\n", HAL_CRC_Calculate(&hcrc, &chunk[4], 1));
printf("[0x12345678]: 0x%08lx\r\n", HAL_CRC_Calculate(&hcrc, &chunk[0], 1));
printf("[0x9ABCDEF0]: 0x%08lx\r\n", HAL_CRC_Calculate(&hcrc, &chunk[1], 1));
printf("[0x12345678,0x9ABCDEF0]: 0x%08lx\r\n",
HAL_CRC_Calculate(&hcrc, &chunk[0], 2));
printf("[0x9ABCDEF0,0x12345678]: 0x%08lx\r\n",
HAL_CRC_Calculate(&hcrc, &chunk[1], 2));
Code: Select all
/* USER CODE BEGIN StartTestTask */
uint32_t crc = 0xffffffff;
// static uint32_t chunk[5] = {0x12345678, 0x9ABCDEF0, 0x12345678, 0x00000000, 0xffffffff};
static uint32_t chunk[5] = {0x78563412, 0xF0DEBC9A, 0x78563412, 0x00000000, 0xffffffff};
printf("=== crc test ===\r\n");
// printf("[0x00000000]: 0x%08lx\r\n", HAL_CRC_Calculate(&hcrc, &chunk[3], 1));
ESP_LOGI("crc_test", "[0x00000000]: 0x%08lx\r\n", ~esp_rom_crc32_be(~crc, (const uint8_t *)&chunk[3], 4));
ESP_LOGI("crc_test", "[0x00000000]: 0x%08lx\r\n", ~esp_rom_crc32_le(~crc, (const uint8_t *)&chunk[3], 4));
// printf("[0xffffffff]: 0x%08lx\r\n", HAL_CRC_Calculate(&hcrc, &chunk[4], 1));
ESP_LOGI("crc_test", "[0xffffffff]: 0x%08lx\r\n", ~esp_rom_crc32_be(~crc, (const uint8_t *)&chunk[4], 4));
ESP_LOGI("crc_test", "[0xffffffff]: 0x%08lx\r\n", ~esp_rom_crc32_le(~crc, (const uint8_t *)&chunk[4], 4));
// printf("[0x12345678]: 0x%08lx\r\n", HAL_CRC_Calculate(&hcrc, &chunk[0], 1));
ESP_LOGI("crc_test", "[0x12345678]: 0x%08lx\r\n", ~esp_rom_crc32_be(~crc, (const uint8_t *)&chunk[0], 4));
ESP_LOGI("crc_test", "[0x12345678]: 0x%08lx\r\n", ~esp_rom_crc32_le(~crc, (const uint8_t *)&chunk[0], 4));
// printf("[0x9ABCDEF0]: 0x%08lx\r\n", HAL_CRC_Calculate(&hcrc, &chunk[1], 1));
ESP_LOGI("crc_test", "[0x9ABCDEF0]: 0x%08lx\r\n", ~esp_rom_crc32_be(~crc, (const uint8_t *)&chunk[1], 4));
ESP_LOGI("crc_test", "[0x9ABCDEF0]: 0x%08lx\r\n", ~esp_rom_crc32_le(~crc, (const uint8_t *)&chunk[1], 4));
// printf("[0x12345678,0x9ABCDEF0]: 0x%08lx\r\n", HAL_CRC_Calculate(&hcrc, &chunk[0], 2));
ESP_LOGI("crc_test", "[0x12345678,0x9ABCDEF0]: 0x%08lx\r\n", ~esp_rom_crc32_be(~crc, (const uint8_t *)&chunk[0], 8));
ESP_LOGI("crc_test", "[0x12345678,0x9ABCDEF0]: 0x%08lx\r\n", ~esp_rom_crc32_le(~crc, (const uint8_t *)&chunk[0], 8));
// printf("[0x9ABCDEF0,0x12345678]: 0x%08lx\r\n", HAL_CRC_Calculate(&hcrc, &chunk[1], 2));
ESP_LOGI("crc_test", "[0x9ABCDEF0,0x12345678]: 0x%08lx\r\n", ~esp_rom_crc32_be(~crc, (const uint8_t *)&chunk[1], 8));
ESP_LOGI("crc_test", "[0x9ABCDEF0,0x12345678]: 0x%08lx\r\n", ~esp_rom_crc32_le(~crc, (const uint8_t *)&chunk[1], 8));
Code: Select all
static uint32_t SW_CRC_Calculate(uint32_t init, const uint32_t pBuffer[], uint32_t wordLength)
{
uint32_t crc32 = init;
for (int k = 0; k < wordLength; k++)
{
crc32 = crc32 ^ pBuffer[k];
for (int i = 0; i < 32; i++)
{
if (crc32 & 0x80000000)
crc32 = (crc32 << 1) ^ 0x04C11DB7;
else
crc32 = (crc32 << 1);
}
}
return crc32;
}