
问题描述 客户反馈,使用 STM32H563 的 data flash(high-cycle data flash),在还没有写入任何数据之前去读取 data flash, 会触发 hardfault 异常。
1> 系统启动后,初始化系统时钟。 2> 配置 OB, 将 FLASH bank1 的最末尾的 8 个 sector 配置为 high-cycle flash.如下红框所示 :
图1. 配置末尾 8 个 sector 为 data flash 3> 擦除所有 8 个 high-cycle data flash 扇区 4> 往 8 个 data flash 扇区写入数据 0xAA55(半字). 5> 最后读出 8 个 data flash 扇区的数据进行检查 这里有一个细节,每次编程只写半字数据,为什么是半字呢?那是因为 data flash 区域每16bit 对应一个 6 位的 ECC 校验。当然你要是写一个 32bit 的字也是可以的。 为了模拟客户的问题,我们将第 4>步骤跳过,即在擦除扇区后,直接读取扇区内数据。最终重现了问题 :
图2. 触发了 NMI 异常 此时查看 FLASH 的 FLASH_ECCDETR 寄存器 :
图3. FLASH_ECCDETR 寄存器 从寄存器内容可看出,此时触发了 EDATA_ECC double error 错误。刚擦除了 data flash不能立即读取吗?于是在参考手册上找到如下对应内容:
如上图参考手册内容所描述,当 data flash 为 virgin word 时(比如刚擦除完,还未写入任何数据), 此时若去访问它,当触发 ECC 错误,只有编程后(no more virgin), ECC 错误才会消失。 至于读取 data flash 时,触发 ECC 错误时,寄存器中显示的内容为什么是 0xf000? 这个在参考手册中也能找到对应内容:
可见,FLASH_ECCDETR 寄存器的 ADDR_ECC 中显示的地址并不是简单地将 flash 地址直接显示,而是有一定的规则。代码中访问的是 0x09000000U 位置就触发了 data flash ECCD 错误,它对应的是 Data area sector 7 的起始位置,如上表所示,对应 0xF000, 此扇区对 ECC 错误记录范围为 0xF000~0xF1FF.
1> 确保代码中每次读取 data flash 之前必须先写入数据。 2> 屏蔽 ECC 错误 在读取 data flash 之前,执行如下代码: __HAL_RCC_SBS_CLK_ENABLE(); HAL_SBS_FLASH_DisableECCNMI(); 如此一来,虽 ECC 错误仍然存在(已忽略),但不再触发 NMI 中断。
另外,对于 data flash,访问它要关闭其对应的缓存属性。这个在示例中也有相关代码,比如:
若不如此做,则当访问 data flash 时,将触发 hardfault 中断。
图4. 若不关闭缓存属性,访问 data flash 将触发 hardfault 与这个类似的还有 OTP, 和 readonly data(比如芯片 UID). 若对应地址没关闭缓存直接读取也会触发 hardfault. ————————————————
原文链接:https://blog.csdn.net/2501_92678806/article/details/150844924 |
经验分享 | 创建在 PC 上验证 X-Cube-AI 算法的工程
STM32H5 的 PB14 引脚被意外拉低的问题解析
经验分享 | 利用TIMER测量信号周期及占空比的精度话题
经验分享 | Flash 全片自检过程中巧用 Linker 自定义变量
经验分享 | 一个 STM32U5 SBSFU SecureFault 问题定位与分析
经验分享 | 高精度定时器如何实现 PWM 零满占空比的连续切换
经验分享 | STM32G474 勘误手册中 SRAM Write Error 详解
经验分享 | 定时器触发ADC时可能遇到的几种情形
实战经验 | 1小时在STM32MPU上运行YOLOv8——训练篇
经验分享 | STM32CubeMX 生成时钟获取函数的分析