• 正文
  • 相关推荐
申请入驻 产业图谱

STM32H5 Data Flash 读取触发 NMI 问题解析:ECC 校验机制与解决方案

11/20 11:38
1234
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

STM32H5 系列高循环 Data Flash 在未写入数据时直接读取,会触发非屏蔽中断(NMI),核心原因是 virgin word(未编程状态)触发 ECC 双错误保护。通过 “预先写入数据” 或 “屏蔽 ECC NMI 触发” 可快速解决,同时需注意缓存属性配置避免额外 HardFault 风险。

资料获取:实战经验 | 读取STM32H5 Data Flash触发NMI的问题解析

1. 问题复现:关键场景与现象

1.1 复现条件

  • 硬件:STM32H563(以 NUCLEO-H563ZI 开发板为例),配置 Bank1 末尾 8 个扇区为高循环 Data Flash(high-cycle data flash)。
  • 软件:基于 CubeH5 示例工程FLASH_EDATA_EraseProgram,跳过 “写入数据” 步骤,仅执行 “擦除扇区→直接读取” 流程。

1.2 异常现象

  • 读取操作触发 NMI 中断,程序暂停在NMI_Handler函数。
  • 查看 FLASH_ECCDETR 寄存器,显示EDATA_ECC=1(Data Flash ECC 错误)、ECCD=1(双错误),ADDR_ECC=0xF000(对应 Data Flash 扇区 7 的起始偏移)。

2. 根源分析:ECC 校验机制与 virgin word 特性

2.1 Data Flash 的 ECC 保护设计

STM32H5 高循环 Data Flash 采用 “16bit 数据 + 6bit ECC 校验” 的存储结构,支持 SECDED 算法(纠正单错误、检测双错误)。编程时,MCU 会自动生成 ECC 码并与数据一同存储;读取时,通过校验 ECC 码判断数据完整性。

2.2 virgin word 触发双错误的核心逻辑

  • 擦除后的 Data Flash 扇区处于 virgin word 状态(所有位为 1),此时无有效 ECC 码与之匹配。
  • 直接读取该状态数据时,ECC 校验模块检测到无法纠正的双错误,触发 NMI 中断(默认 ECC 错误绑定 NMI),对应寄存器FLASH_ECCDETRECCD=1(双错误标志)。

2.3 地址显示规则说明

寄存器ADDR_ECC显示的并非物理地址,而是 Data Flash 扇区的内部偏移。例如0xF000对应 Data Flash 扇区 7(地址范围 0xF000~0xF1FF),偏移值与扇区编号一一对应,可通过参考手册查表确认具体故障扇区。

3. 解决方案:两种高效解决路径

3.1 方案一:读取前预先写入数据(推荐,保证数据完整性)

在擦除 Data Flash 后、读取前,先写入任意有效数据(半字、字均可),使 virgin word 转为编程状态,ECC 码自动生成,避免校验错误。

  • 关键说明:Data Flash 支持 16bit 半字或 32bit 字写入,半字写入更贴合 ECC 校验的 16bit 数据粒度。
  • 示例代码(写入 0xAA55 半字):
// 假设Data Flash起始地址为EDATA_USER_START_ADDR
HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError); // 擦除扇区
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, EDATA_USER_START_ADDR, 0xAA55); // 预先写入数据
HAL_FLASH_Read(&readData, EDATA_USER_START_ADDR, 1); // 正常读取

3.2 方案二:屏蔽 ECC 错误的 NMI 触发(快速适配,无需改写数据流程)

若无需严格校验数据完整性,可通过 SBS 外设关闭 ECC 错误的 NMI 触发,仅保留错误标志(不中断程序)。

  • 示例代码:
__HAL_RCC_SBS_CLK_ENABLE(); // 使能SBS时钟
HAL_SBS_FLASH_DisableECCNMI(); // 屏蔽Data Flash ECC错误的NMI触发
// 后续可正常执行擦除→读取流程,ECC错误仅记录在寄存器中

4. 关键注意事项:避免 HardFault 风险

4.1 必须关闭 Data Flash 的缓存属性

STM32H5 的 Data Flash 区域默认不支持缓存,若未配置 MPU 关闭缓存属性,读取时会触发 HardFault 中断。

  • MPU 配置示例代码:
static void MPU_Config(void) {
  MPU_Region_InitTypeDef region;
  HAL_MPU_Disable(); // 关闭MPU配置
  // 配置Data Flash区域为非缓存
  region.Enable = MPU_REGION_ENABLE;
  region.BaseAddress = EDATA_USER_START_ADDR; // Data Flash起始地址
  region.LimitAddress = EDATA_USER_END_ADDR; // Data Flash结束地址
  region.AccessPermission = MPU_REGION_ALL_RW;
  region.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
  region.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
  HAL_MPU_ConfigRegion(&region);
  HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT); // 启用MPU
}

4.2 同类特性器件的处理

  • OTP 区域:与 Data Flash 特性一致,未写入数据时直接读取会触发 ECC 双错误 NMI,需采用相同解决方案。
  • 只读数据(如芯片 UID):访问时需同样关闭缓存属性,否则触发 HardFault。

STM32H5 Data Flash 的 NMI 触发本质是 ECC 校验的严格保护机制,针对 virgin word 场景,优先选择 “预先写入数据” 保证数据可靠性;若需简化流程,可通过HAL_SBS_FLASH_DisableECCNMI屏蔽 NMI。同时务必配置 MPU 关闭 Data Flash 缓存,避免叠加 HardFault 错误。

相关推荐

登录即可解锁
  • 海量技术文章
  • 设计资源下载
  • 产业链客户资源
  • 写文章/发需求
立即登录