You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32+Keil环境下外部SDRAM中初始化数组出现随机值问题

STM32 Keil uVision下SDRAM中const数组初始化失败的解决方案

问题根源

你遇到的核心问题是:const修饰的全局数组被指定到外部SDRAM段后,Keil默认启动流程不会自动将Flash中的初始化数据复制到SDRAM。启动代码仅处理内部RAM的段初始化,外部SDRAM的初始化逻辑需要手动添加。

具体解决步骤

1. 调整分散加载文件,指定初始化数据的Flash存储地址

修改你的分散加载脚本,明确将数组的初始化数据存放在Flash,运行时地址放在SDRAM:

; 定义SDRAM运行时区域,指定起始地址和大小
SDRAM_ACQ_HARDCODED_AV 0xD0643000 0x141000 {
    ; 指定该段的初始化数据存储在Flash的空闲区域(替换0x080XXXXX为实际可用的Flash地址)
    LOAD_FLASH 0x080XXXXX {
        *(.sdram_acq_hardcoded_av)
    }
}

注意:Flash地址需选择未被代码占用的区域,大小需大于等于数组字节数(14592×2=29184字节)。

2. 添加手动复制初始化数据的代码

在SDRAM初始化完成后(比如main()函数开头,或SDRAM初始化函数末尾),添加代码将Flash中的初始化数据复制到SDRAM对应段:

// 声明分散加载生成的段地址符号
extern uint32_t Image$$SDRAM_ACQ_HARDCODED_AV$$Base;    // SDRAM段起始地址
extern uint32_t Image$$SDRAM_ACQ_HARDCODED_AV$$Limit;   // SDRAM段结束地址
extern uint32_t Image$$SDRAM_ACQ_HARDCODED_AV$$RO$$Base;// Flash中初始化数据起始地址

void copy_sdram_const_data(void)
{
    uint8_t* src = (uint8_t*)&Image$$SDRAM_ACQ_HARDCODED_AV$$RO$$Base;
    uint8_t* dest = (uint8_t*)&Image$$SDRAM_ACQ_HARDCODED_AV$$Base;
    uint32_t size = (uint32_t)&Image$$SDRAM_ACQ_HARDCODED_AV$$Limit - (uint32_t)&Image$$SDRAM_ACQ_HARDCODED_AV$$Base;

    // 逐字节复制初始化数据
    while (size--)
    {
        *dest++ = *src++;
    }
}

在SDRAM初始化完成后调用copy_sdram_const_data()即可完成数组初始化。

3. 额外排查点

  • 确认SDRAM初始化逻辑正确:可在复制前向SDRAM写入测试值并读取验证,排除硬件或初始化配置错误。
  • 确认Keil工程已启用分散加载文件:在Options for Target -> Linker中勾选Use scatter file并指定你的脚本路径。

内容的提问来源于stack exchange,提问作者igtu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 07:47:20