【文末送STM32N6570-DK】STM32N6访问TCM时产生Hard Fault的原因与解决方法 LAT1554
关键字:STM32N6,TCM,FLEXRAM,HardFault
1. 引言
客户在使用STM32N6开发的过程中,遇到了访问DTCM时产生Hard Fault的问 题。在本文中,我们使用IAR V9.40.2对STM32N6 FSBL工程进行测试,复现问题,解 释原因并给出了解决办法,供遇到该问题的客户参考。另外请注意STM32N6 BootROM 是安全启动,意味着其跳转的FSBL总是安全的,文中的内存地址(DTCM, ITCM)使用 的均是安全地址。
2. DTCM 访问Hard Fault
2.1. 复现问题
STM32N6 中DTCM基础区的安全地址为0x3000 000。下面是一段简单的测试程 序。在一个简单的FSBL工程的main.c文件中,声明pDTCMData,unsigned int32 数 据指针,指向DTCM内存首地址,用来访问DTCM,32位数据访问可以避开由于数据未 对齐产生Hardfault问题。代码如下:
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint32_t *pDTCMData = (uint32_t*)0x30000000;
uint16_t nCnt = 0;
uint32_t dDTCM;
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
… …
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
for (nCnt = 0; nCnt < 32*1024; nCnt++)
{
dDTCM = *pDTCMData++;
#直接访问DTCM,产生HardFault.
}
测试过程中,当读取DTCM数据时,很容易产生Hard Fault中断。当Hard Fault中 断产生时,查看Cortex-M55内核寄存器AFSR(Auxiliary Fault Status Register,见下 图1),可以看到PECC(17位)为1,查阅手册PM0273(STM32 Cortex®-M55 MCUs programming manual),该位的解释为“Precise fault caused by uncorrectable ECC error”类型为RO, 即读取内存(TCM)时产生了ECC校验错误。
图1. STM32N6 Cortex-M55 内核寄存器AFSR

STM32N6 Cortex-M55 TCM管理接口中, DTCM基础区与ITCM基础区都带有ECC 校验,这正是我们测试时产生Hard Fault的原因。在上电复位时,DTCM基础区和 ITCM基础区中的数据是随机的,未做数据清除或数据初始化,直接读取时,不可纠正 ECC 错误是有极大概率发生的,并由此引发Hard Fault中断。内存访问造成Hard Fault 的原因可能还有其它方面,比方内存对齐错误,我们的测试并非这种情况。除此之外,需 要注意的一种场景是PPOISON @AFSR标志位为1的情况,也是由于内存访问硬件错误 造成的。有关更多AFSR状态寄存器的信息,可以参考ARM 官方资料:Arm Cortex M55 Processor Technical Reference Manual r0p2
2.2. 解决办法
在“\EWARM\startup_stm32n657xx_fsbl.s中添加下面代码(黄色部分), 用于清零DTCM,注意STM32N6手册中,DTCM基础区的大小为128K Bytes。
Reset_Handler LDR LR, =0xFFFFFFFF LDR R0, =sfb(CSTACK) MSR MSPLIM, R0 ; Set Stack Pointer Limit LDR SP, =sfe(CSTACK) ; Set Stack Pointer ; 清零DTCM ~ LDR R0, =0x30000000 ; DTCM 地址为0x30000000 LDR R1, =128*1024 ; 清零字节数 LDR R2, =0x0 BL Clear_DTCM ; 调用清零函数Clear_DTCM LDR R0, =SystemInit BLX R0 LDR R0, =__iar_program_start BX R0 PUBWEAK NMI_Handler SECTION .text:CODE:NOROOT:REORDER(1) Clear_DTCM ;用于清零DTCM ~ STR R2, [R0] ADD R0, R0, #4 CMP R0, R1 BCC Clear_DTCM NMI_Handler B NMI_Handler
使用如上代码,对DTCM进行清零(或初始化)后,main函数中的DTCM访问正常,可读可写,多次测试,Hard Fault问题得以消除。
2.3. TCM
除了DTCM,STM32N6的ITCM基础区同样带ECC校验,其安全地址为0x1000 0000, 大小为64K Bytes,访问前也需要先初始化它。STM32N6使用的是 Cortex-M55 内核,该内核的TCM 接口包括一个 39 位(32 个有效数据位 + 7 个 ECC 保护位)ITCM 和四个并行 39 位 DTCM接口。STM32N6中内嵌的RAM(AXI访问)的前半部分中的 FlexRAM(400KB)可以灵活扩展为ITCM和DTCM,见下图2(图中的地址是非安全地 址,FSBL中访问时需要变换为安全地址,扩展DTCM的起始地址为0x3002 0000,扩展 ITCM的开始地址为0x1001 0000)。如果将FlexRAM扩展为ITCM和DTCM,由于内 核接口是带ECC的接口,在读取这两部分TCM扩展区时,也需要注意内存访问硬件故障 问题,即需要对其进行初始化(可以参考HAL API HAL_RAMCFG_StartECC了解 扩展 TCM ECC的使用)。
图2. STM32N6 FelxRAM 扩展

3. 小结
本文介绍了STM32N6 TCM访问时产生内存访问硬件故障并引发Hard Fault中断的 原因与解决方法,需要注意的还包括FlexRAM 的扩展TCM情况。由于STM32N6中 Cortex-M55 内核TCM接口为39位接口(32 个有效数据位 + 7 个 ECC 校验位),上 电复位后TCM数据随机性会造成直接读取时的ECC错误,因此需要在读取TCM前进行 初始化,请使用时加以注意。
【留言活动】
你是否了解意法半导体STM32N6?你期待用STM32N6开发哪些应用?文末留言,随机抽取一位已关注粉丝送“STM32N6570-DK”一块。
活动日期:至2025年10月31日。
意法半导体公司及其子公司 (“ST”)保留随时对 ST 产品和 / 或本文档进行变更的权利,恕不另行通知。买方在订货之前应获取关于 ST 产 品的最新信息。 ST 产品的销售依照订单确认时的相关 ST 销售条款。 买方自行负责对 ST 产品的选择和使用, ST 概不承担与应用协助或买方产品设计相关的任何责任。 ST 不对任何知识产权进行任何明示或默示的授权或许可。 转售的 ST 产品如有不同于此处提供的信息的规定,将导致 ST 针对该产品授予的任何保证失效。 ST 和 ST 徽标是 ST 的商标。若需 ST 商标的更多信息,请参考 www.st.com/trademarks。所有其他产品或服务名称均为其 各自所有者的财 产。 本文档是ST中国本地团队的技术性文章,旨在交流与分享,并期望借此给予客户产品应用上足够的帮助或提醒。若文中内容存有局限或与ST 官网资料不一致,请以实际应用验证结果和ST官网最新发布的内容为准。您拥有完全自主权是否采纳本文档(包括代码,电路图等)信息, 我们也不承担因使用或采纳本文档内容而导致的任何风险。 本文档中的信息取代本文档所有早期版本中提供的信息。 © 2020 STMicroelectronics - 保留所有权利
