You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32H7硬件CRC与srec_cat生成的CRC32不匹配,求正确配置

STM32H755 Bootloader CRC32硬件校验与srec_cat结果不匹配问题

构建系统配置(Makefile片段)

# Convert ELF to BIN (fill up to 128KB - 4)
$(BIN): $(ELF) | $(BUILD_DIR)
    $(OBJCOPY) -O binary $< $(BUILD_DIR)/tmp.bin
    $(SREC_CAT) $(BUILD_DIR)/tmp.bin -binary -fill 0x00 0x0000 0x1FFFC -o $@ -binary

# Append CRC32 (little endian) at the last 4 bytes (0x1FFFC)
$(CRC_BIN): $(BIN) | $(BUILD_DIR)
    $(SREC_CAT) $< -binary -crc32-l-e 0x1FFFC -o $@ -binary

CRC32校验和以4字节小端格式存储在地址0x1FFFC处。


Bootloader端校验代码(简化版)

#define APPLICATION_ADDRESS     0x08040000U
#define APPLICATION_MAX_SIZE   (128 * 1024)  // 128 KB
#define APPLICATION_CRC_ADDRESS (APPLICATION_ADDRESS + APPLICATION_MAX_SIZE - 4)

static uint32_t verify_application_crc(uint32_t expected_crc)
{
    uint32_t data_size_bytes = APPLICATION_MAX_SIZE - 4;
    // Compute CRC on flash contents using hardware CRC
    uint32_t computed_crc = HAL_CRC_Calculate(&hcrc,
                              (uint32_t*)APPLICATION_ADDRESS,
                              data_size_bytes);

    if (computed_crc != expected_crc) {
        printf("CRC mismatch! HW=0x%08lX, Expected=0x%08lX\n",
               computed_crc, expected_crc);
        return -1;
    }
    return 0;
}

当前CRC外设配置

hcrc.Instance = CRC;
hcrc.Init.DefaultPolynomialUse    = DEFAULT_POLYNOMIAL_ENABLE;   // 0x04C11DB7
hcrc.Init.DefaultInitValueUse     = DEFAULT_INIT_VALUE_ENABLE;   // 0xFFFFFFFF
hcrc.Init.InputDataInversionMode  = CRC_INPUTDATA_INVERSION_NONE;
hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE;
hcrc.InputDataFormat              = CRC_INPUTDATA_FORMAT_BYTES;

问题现状

  • srec_cat -crc32-l-e生成的CRC32已通过第三方工具验证正确;
  • 自定义软件CRC32函数计算结果与srec_cat完全一致;
  • STM32硬件CRC外设计算结果始终不匹配,已尝试调整所有HAL CRC初始化参数(多项式、初始值、输入/输出反转、数据格式),仍无法匹配。

需求

需配置STM32H7硬件CRC模块,使其计算结果匹配srec_cat -crc32-l-e生成的标准CRC-32/ISO-HDLC(多项式0x04C11DB7,初始值0xFFFFFFFF,输入/输出反射,最终异或0xFFFFFFFF)。


解决方案

1. 正确的CRC外设初始化配置

STM32H7的硬件CRC模块支持输入/输出字节级反转,需匹配CRC-32/ISO-HDLC的要求,以下是正确的初始化代码:

hcrc.Instance = CRC;
hcrc.Init.DefaultPolynomialUse    = DEFAULT_POLYNOMIAL_ENABLE;   // 0x04C11DB7,符合CRC-32/ISO-HDLC标准
hcrc.Init.DefaultInitValueUse     = DEFAULT_INIT_VALUE_ENABLE;   // 0xFFFFFFFF,符合初始值要求
hcrc.Init.InputDataInversionMode  = CRC_INPUTDATA_INVERSION_BYTE; // 字节内位反转,对应输入反射要求
hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_ENABLE; // 整体位反转,对应输出反射要求
hcrc.InputDataFormat              = CRC_INPUTDATA_FORMAT_BYTES;  // 按字节处理数据

if (HAL_CRC_Init(&hcrc) != HAL_OK) {
    Error_Handler();
}

2. 硬件CRC计算后的补充处理

STM32硬件CRC模块不会自动执行最终异或0xFFFFFFFF的操作,需手动补充这一步:

static uint32_t verify_application_crc(uint32_t expected_crc)
{
    uint32_t data_size_bytes = APPLICATION_MAX_SIZE - 4;
    uint32_t computed_crc = HAL_CRC_Calculate(&hcrc,
                              (uint32_t*)APPLICATION_ADDRESS,
                              data_size_bytes);
    
    // 执行最终异或0xFFFFFFFF,匹配CRC-32/ISO-HDLC标准
    computed_crc ^= 0xFFFFFFFF;

    if (computed_crc != expected_crc) {
        printf("CRC mismatch! HW=0x%08lX, Expected=0x%08lX\n",
               computed_crc, expected_crc);
        return -1;
    }
    return 0;
}

3. 关键注意点

  • 输入反转模式:必须选择CRC_INPUTDATA_INVERSION_BYTE,对应每个字节内的8位按位反转,满足CRC-32/ISO-HDLC的输入反射要求;
  • 输出反转模式:必须开启CRC_OUTPUTDATA_INVERSION_ENABLE,对应硬件计算后的32位结果整体按位反转;
  • 最终异或:STM32硬件CRC无此默认操作,必须手动异或0xFFFFFFFF才能匹配标准结果;
  • 数据长度单位:HAL_CRC_Calculate的第三个参数长度单位由InputDataFormat决定:设置为CRC_INPUTDATA_FORMAT_BYTES时,长度为字节数,需与数据处理逻辑保持一致。

内容的提问来源于stack exchange,提问作者Shiddesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 07:13:16