1. 问题现象
客户反馈在STM32H5中通过代码读取UID时,会触发Hardfault。
2. 问题重现及分析
我手动通过STM32CubeMx生成一个基于STM32H563的测试工程。运行在NUCLEOH563RE板上。在代码中写了一个读取UID函数:
uint32_t deviceserial0, deviceserial1, deviceserial2;
void ReadUIDTest(void)
{
deviceserial0 = HAL_GetUIDw0();
deviceserial1 = HAL_GetUIDw1();
deviceserial2 = HAL_GetUIDw2();
}然后在main函数中调用这个ReadUIDTest()函数,发现正如客户所说,触发了hardfault。Keil的Call Stack如下所示:

▲ 图1 读取UID时触发了Hardfault
这个问题能100%重现问题,于是在Keil调试下查看故障报告窗口:

▲ 图2 故障报告
上图信息解析如下:
当前触发了Bus Fault中断,由于此中断在代码中并未使能,所以才升级为hardfault。触发Bus Fault中断的原因是数据访问导致的,此数据地址为:0x08FFF800。
通过代码中的宏定义:
#define UID_BASE (0x08FFF800UL) /*!< Unique device ID register base address */
可知,这个地址0x08FFF800刚好是芯片的UID地址。
那么问题来了,为什么读取UID地址就会触发hardfault呢?
查看芯片对应的参考手册RM0481(Rev 4),在第7.3.2节看到如下内容:

UID所在FLASH区域为RO区域,它默认不支持Cacheable特性的,而在代码中若激活了ICache(通过STM32CubeMx生成的工程默认会默认提示用户开户I-Cache以提高代码效率),那么代码访问AHB存储范围内的所有地址默认都是缓存的,也就是说,这种缓存机制跟UID所在特殊区域的缓存特性冲突。要解决这种冲突,得借助MPU来改变局部区域(UID的在地址)的缓存策略才行。
知道了问题所在,那么对应的解决代码如下所示:
/**
* @brief Configures the main MPU regions.
* @param None
* @retval None
*/
void MPU_Config(void)
{
MPU_Region_InitTypeDef MPU_InitStruct;
MPU_Attributes_InitTypeDef MPU_AttributesInit;
/* Disable MPU */
HAL_MPU_Disable();
/* Define cacheable memory via MPU */
MPU_AttributesInit.Number = 0;
MPU_AttributesInit.Attributes = MPU_NOT_CACHEABLE;
HAL_MPU_ConfigMemoryAttributes(&MPU_AttributesInit);
/* Configure UID region as Region Number 0 */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x08FFF800;
MPU_InitStruct.LimitAddress = 0x08FFFFFF;
MPU_InitStruct.AccessPermission = MPU_REGION_ALL_RO;
MPU_InitStruct.AttributesIndex = MPU_ATTRIBUTES_NUMBER0;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Enable MPU (any access not covered by any enabled region will cause a fault) */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}在代码访问UID之前,先用MPU将UID所在地址区域的缓存属性关闭,如此,即可解决问题。
除UID之外,EData,OTP区域也有类似问题,且这种问题在以前传统的MCU中并不会遇到的,这也是STM32H5比较特别的地方之一,大家需要注意这一点。
来源:STM32
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。