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

STM32N6 FSBL 大内存异常解决:AXISRAM3-6 必须手动使能,否则程序卡死

12/23 09:29
222
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

STM32N6 的 FSBL(第一阶段引导程序)使用大内存(如 AXISRAM3)时出现程序异常、调试器卡死,核心原因是AXISRAM3/4/5/6 复位后默认断电,需手动使能时钟并唤醒内存,仅 AXISRAM2 上电即可直接使用。

资料获取:开发经验 | LAT1570 STM32N6在FSBL中使用大内存时的异常问题

1. 问题背景:大内存使用触发的 FSBL 异常

客户基于 STM32N6 开发产品,核心需求是通过 XSPI DMA 向 QSPI LCD 传输 307K 数据,遇到关键问题:

  1. 异常现象:在 FSBL 工程中扩展 RAM 使用到 AXISRAM3 后,程序运行异常,IAR 调试器卡死,数据传输时间远超预期;
  2. 复现条件:仅使用 AXISRAM2 时功能正常,一旦变量定义到 AXISRAM3 及以上区域,立即触发异常;
  3. 工程环境:STM32N6 Nucleo 板、IAR 编译器,FSBL 工程未修改默认 RAM 配置。

2. 根源分析:AXISRAM 的默认上电状态差异

2.1 STM32N6 的 AXISRAM 架构特点

STM32N6 是无内部 Flash(flashless)架构,依赖外部 Flash 启动,其 AXISRAM 分为多个独立区域,复位后状态不同:

AXISRAM 区域 复位后默认状态 地址范围(示例) 核心用途
AXISRAM2 上电使能(可用) 0x24000000~ FSBL 默认使用的小内存区域
AXISRAM3-6 断电禁用(不可用) 0x24020000~ 等 扩展大内存,需手动唤醒

2.2 异常触发核心原因

  • 复位后,AXISRAM3-6 的SRAMSD位(RAMCFG_AXISRAMxCR寄存器bit20)默认 = 1,代表 “Shutdown(断电)” 状态,无法存储数据或执行代码;
  • STM32CubeMX 创建 FSBL 工程时,仅配置 AXISRAM2,未启用 AXISRAM3-6;
  • 直接将大内存变量(如 307K DMA 缓冲区)定义到 AXISRAM3,相当于访问未上电的无效内存,导致程序崩溃、调试器卡死。

3. 解决方案:3 步手动使能 AXISRAM3-6(以 AXISRAM3 为例)

核心逻辑:先使能对应 AXISRAM 的时钟,再清零SRAMSD位唤醒内存,且操作必须在变量初始化前完成(早于__iar_program_start)。

3.1 关键代码修改(SystemInit 函数中添加)

SystemInit函数中添加使能代码,确保 AXISRAM3 上电后再初始化变量:

void SystemInit(void) {
  #if defined(USER_VECT_TAB_ADDRESS)
    SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET;
  #else
    // 配置中断向量表地址
    SCB->VTOR = INTVECT_START;
  #endif /* USER_VECT_TAB_ADDRESS */

  /********** 手动使能AXISRAM3(核心代码)**********/
  // 1. 使能AXISRAM3的内存时钟
  __HAL_RCC_AXISRAM3_MEM_CLK_ENABLE();
  // 2. 使能RAMCFG外设时钟(控制AXISRAM电源状态)
  __HAL_RCC_RAMCFG_CLK_ENABLE();
  // 3. 清零SRAMSD位(bit20),唤醒AXISRAM3
  CLEAR_BIT(RAMCFG_SRAM3_AXI->CR, (0x1 << 20));
  /**********************************************/

  #if defined(USER_TZ_SAU_SETUP)
    // 安全相关配置(按需保留)
    TZ_SAU_Setup();
  #endif /* USER_TZ_SAU_SETUP */

  // FPU使能(原有代码,保留)
  #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
    SCB->CPACR |= ((3UL << 20U)|(3UL << 22U));  // 内核FPU全访问
    SCB_NS->CPACR |= ((3UL << 20U)|(3UL << 22U));// 非安全侧FPU全访问
  #endif
}

3.2 使能时机说明

  • 必须在__iar_program_start函数之前执行(该函数负责初始化 RAM 变量);
  • 推荐在SystemInit函数开头、中断向量表配置之后添加,确保内存唤醒后再进行变量初始化。

3.3 扩展:使能 AXISRAM4-6 的通用代码

若需使用 AXISRAM4-6,按以下格式扩展(仅修改对应的 RAM 编号):

// 使能AXISRAM4示例
__HAL_RCC_AXISRAM4_MEM_CLK_ENABLE();
CLEAR_BIT(RAMCFG_SRAM4_AXI->CR, (0x1 << 20));

// 使能AXISRAM5示例
__HAL_RCC_AXISRAM5_MEM_CLK_ENABLE();
CLEAR_BIT(RAMCFG_SRAM5_AXI->CR, (0x1 << 20));

4. 验证结果

  • 修改后,AXISRAM3 正常上电,307K DMA 缓冲区可正常存储数据;
  • XSPI DMA 传输数据到 QSPI LCD 无异常,传输时间恢复正常,IAR 调试器不再卡死;
  • 扩展使能 AXISRAM4-6 后,大内存变量定义到对应区域均能稳定运行。

5. 开发经验小结

  1. flashless 架构注意点:STM32N6 无内部 Flash,FSBL 默认仅启用小容量 AXISRAM2,大内存需求需手动使能 AXISRAM3-6;
  2. 使能顺序不可乱:必须先使能时钟(AXISRAM 内存时钟 + RAMCFG 时钟),再清零SRAMSD位,否则唤醒失败;
  3. 时机优先:使能操作需早于变量初始化,避免访问未上电内存;
  4. 通用适配:AXISRAM3-6 的使能方法完全一致,仅需替换对应的 RAM 编号和寄存器。

相关推荐