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

STM32下ARM GCC链接脚本:实现RAM内.data区重复初始化

解决方案:ARM GCC链接脚本修改实现RAM内.data初始值复制

1. 调整MEMORY区域定义

确保RAM区域有足够空间容纳程序(.text)、.data初始值区(.data_init)、实际.data区以及.bss区。以STM32F4系列芯片为例,RAM配置示例如下:

MEMORY
{
  RAM (xrw)  : ORIGIN = 0x20000000, LENGTH = 128K  // 根据实际芯片RAM大小调整
}

2. 定义独立的.data初始值段

在SECTIONS块中,先创建.data_init段专门存放.data变量的初始值(驻留RAM独立区域),再定义实际运行的.data段,通过加载地址(LMA)关联到.data_init,同时导出启动代码需要的关键符号:

SECTIONS
{
  /* 程序代码段,放在RAM起始位置 */
  .text :
  {
    . = ALIGN(4);
    KEEP(*(.isr_vector))            /* 中断向量表 */
    *(.text)                        /* 程序代码 */
    *(.text*)                       /* 其他代码段 */
    *(.glue_7)                      /* 链接器生成的代码 */
    *(.glue_7t)
    . = ALIGN(4);
    _etext = .;                     /* 程序代码结束地址 */
  } >RAM

  /* .data变量的初始值存储段,放在.text之后的RAM区域 */
  .data_init :
  {
    . = ALIGN(4);
    _sidata = .;                    /* 初始值区起始地址 */
    *(.data)                        /* 将.data的初始值存入此段 */
    *(.data*)
    . = ALIGN(4);
    _eidata = .;                    /* 初始值区结束地址 */
  } >RAM

  /* 实际运行的.data段,放在.data_init之后的RAM区域 */
  .data : AT(_sidata)               /* 指定加载地址为.data_init的起始 */
  {
    . = ALIGN(4);
    _sdata = .;                     /* .data段运行时起始地址 */
    *(.data)                        /* 运行时变量的实际存储位置 */
    *(.data*)
    . = ALIGN(4);
    _edata = .;                     /* .data段结束地址 */
  } >RAM

  /* BSS段,未初始化变量,放在.data之后 */
  .bss :
  {
    . = ALIGN(4);
    _sbss = .;
    *(.bss)
    *(.bss*)
    *(COMMON)
    . = ALIGN(4);
    _ebss = .;
  } >RAM

  /* 栈和堆的定义,按需调整预留空间 */
  _estack = ORIGIN(RAM) + LENGTH(RAM);
  _heap_start = _ebss;
  _heap_end = _estack - 0x400;      /* 预留栈空间,可根据需求修改 */
}

3. 验证启动代码的复制逻辑

启动文件中的.data复制逻辑无需修改,因为核心逻辑仍是从_sidata复制数据到_sdata直到_edata,只是现在两个地址都位于RAM的不同区域:

/* 启动代码中的.data复制片段示例 */
uint32_t *pSrc = &_sidata;
uint32_t *pDest = &_sdata;
while(pDest < &_edata)
{
  *pDest++ = *pSrc++;
}

关键说明

  • .data_init与.data段同属RAM但地址不重叠:前者存初始值,后者是运行时变量的实际存储区;
  • 通过AT(_sidata)指定.data段的加载地址,链接器会自动将.data变量的初始值打包到.data_init段;
  • 需确保RAM总容量能容纳所有段:.text + .data_init + .data + .bss + 栈 + 堆的总和不能超过芯片RAM的实际大小。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 23:40:21