[STM32H5] 实战经验 | 读取STM32H5 Data Flash触发NMI的问题解析

[复制链接]
296|3
STM新闻官 发表于 2025-10-24 02:41 | 显示全部楼层 |阅读模式
1. 问题描述
客户反馈,使用STM32H563的data flash(high-cycle data flash),在还没有写入任何数据之前去读取data flash,会触发hardfault异常。2. 问题分析
我们尝试在NUCLEO-H563ZI板上重现问题,直接使用STM32CubeH5包内的示例工程:STM32Cube_FW_H5_V1.4.0\Projects\NUCLEOH563ZI\Examples\FLASH\FLASH_EDATA_EraseProgram。此示例代码的大体流程如下:1> 系统启动后,初始化系统时钟。2> 配置OB,将FLASH bank1的最末尾的8个sector配置为high-cycle flash。如下红框所示:
2271468fa76196cc16.png

图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>步骤跳过,即在擦除扇区后,直接读取扇区内数据。最终重现了问题:

1447468fa7630c9162.png

▲ 图2. 触发了NMI异常

此时查看FLASH的FLASH_ECCDETR寄存器:
5917568fa7649d01cc.png

▲ 图3. FLASH_ECCDETR寄存器

从寄存器内容可看出,此时触发了EDATA_ECC double error错误。刚擦除了data flash不能立即读取吗?于是在参考手册上找到如下对应内容:
5050268fa7661d5f98.png

如上图参考手册内容所描述,当data flash为virgin word时(比如刚擦除完,还未写入任何数据),此时若去访问它,当触发ECC错误,只有编程后(no more virgin),ECC错误才会消失。
至于读取data flash时,触发ECC错误时,寄存器中显示的内容为什么是0xf000?这个在参考手册中也能找到对应内容: 4085368fa766fb3907.png
可见,FLASH_ECCDETR寄存器的ADDR_ECC中显示的地址并不是简单地将flash地址直接显示,而是有一定的规则。代码中访问的是0x09000000U位置就触发了data flash ECCD错误,它对应的是Data area sector 7的起始位置,如上表所示,对应0xF000,此扇区对ECC错误记录范围为0xF000~0xF1FF。
3. 解决方法知道了原因,再去解决就比较容易了。解决方法有两个:1> 确保代码中每次读取data flash之前必须先写入数据。2> 屏蔽ECC错误在读取data flash之前,执行如下代码:如此一来,虽ECC错误仍然存在(已忽略),但不再触发NMI中断。
4. 其它与data flash具体类似特性的还有OTP,它也是若写任何数据前就去读取其内容也会触发ECCD错误,从而导致NMI异常。另外,对于data flash,访问它要关闭其对应的缓存属性。这个在示例中也有相关代码,比如:
  1. /** * [url=/u/brief]@brief[/url] Configure the MPU attributes as non-cacheable for Flash high-cycle data area * [url=/u/NOTE]@NOTE[/url] The Base Address is Flash high-cycle data area * @param None * @retval None */static void MPU_Config(void){ MPU_Attributes_InitTypeDef attr; MPU_Region_InitTypeDef region; /* Disable MPU before perloading and config update */ HAL_MPU_Disable(); /* Define cacheable memory via MPU */ attr.Number = MPU_ATTRIBUTES_NUMBER0; attr.Attributes = 0 ; HAL_MPU_ConfigMemoryAttributes(&attr); /* BaseAddress-LimitAddress configuration */ region.Enable = MPU_REGION_ENABLE; region.Number = MPU_REGION_NUMBER0; region.AttributesIndex = MPU_ATTRIBUTES_NUMBER0; region.BaseAddress = EDATA_USER_START_ADDR; region.LimitAddress = EDATA_USER_END_ADDR; region.AccessPermission = MPU_REGION_ALL_RW; region.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; region.IsShareable = MPU_ACCESS_NOT_SHAREABLE; HAL_MPU_ConfigRegion(®ion); /* Enable the MPU */ HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);}
若不如此做,则当访问data flash时,将触发hardfault中断。
5640868fa76bfccb70.png
▲ 图4. 若不关闭缓存属性,访问data flash将触发hardfault
与这个类似的还有OTP,和readonly data(比如芯片UID)。若对应地址没关闭缓存直接读取也会触发hardfault。
点击按钮下载《读取STM32H5 Data Flash触发NMI的问题解析》原文档。
点击下载

 楼主| STM新闻官 发表于 2025-10-24 02:42 | 显示全部楼层
 楼主| STM新闻官 发表于 2025-10-24 02:42 | 显示全部楼层
huangcunxiake 发表于 2025-10-25 08:47 | 显示全部楼层
真详细
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:意法半导体(中国)投资有限公司
简介:您的嵌入式应用将得益于意法半导体领先的产品架构、技术、多源产地和全方位支持。意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器。

1398

主题

1716

帖子

25

粉丝
快速回复 在线客服 返回列表 返回顶部