STM32 + GCC将整个文件链接到指定内存段的方法

用GCC编译STM32工程时,想和在MDK中修改scatter文件的方式一样将某些代码的变量分配到外部SRAM中,搜索了一些方法发现都是用加变量属性__attribute__((section(xxx)))的方式,感觉每个变量都要加太麻烦,而且一些使用的第三方库(比如FatFs)并不想修改,所以研究了一下怎么能直接把整个文件链接到指定的内存中去。

首先要先修改.ld文件,在MEMORY中加入外部SRAM,如下:

/* Specify the memory areas */
MEMORY
{
RAM (xrw)       : ORIGIN = 0x20000000, LENGTH = 128K
CCMRAM (xrw)    : ORIGIN = 0x10000000, LENGTH = 64K
XRAM(xrw)       : ORIGIN = 0x6C000000, LENGTH = 1024K
FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 1024K
}

之后在SECTION中加入外部SRAM使用的.data段和.bss段,分别放在原.data段和.bss段之后,其中aaa.o和bbb.o为工程某路径下名为aaa和bbb的目标文件,ccc/*.o为子目录ccc下的所有文件。在xram对应段中指定了目标文件后,为避免重复,需要在内部RAM的对应段中使用EXCLUDE_FILE排除这些文件。

/* used by the startup to initialize data */
_sidata = LOADADDR(.data);

/* Initialized data sections goes into RAM, load LMA copy after code */
.data : 
{
  . = ALIGN(4);
  _sdata = .;        /* create a global symbol at data start */

  *(EXCLUDE_FILE(*aaa.o *bbb.o *ccc/*.o) .data .data*)

  . = ALIGN(4);
  _edata = .;        /* define a global symbol at data end */
} >RAM AT> FLASH

_sixdata = LOADADDR(.xdata);
/* XRAM data section 
*/
.xdata :
{
  . = ALIGN(4);
  _sxdata = .;       /* create a global symbol at xram data start */
  *(.xdata)
  *(.xdata*)

  *aaa.o(.data .data*)
  *bbb.o(.data .data*)
  *ccc/*.o(.data .data*)
    
  . = ALIGN(4);
  _exdata = .;       /* create a global symbol at xram data end */
} >XRAM AT> FLASH

/* Uninitialized data section */
.bss :
{
  . = ALIGN(4);
  /* This is used by the startup in order to initialize the .bss secion */
  _sbss = .;         /* define a global symbol at bss start */
  __bss_start__ = _sbss;

  *(EXCLUDE_FILE(*aaa.o *bbb.o *ccc/*.o) .bss .bss *)

  *(COMMON)

  . = ALIGN(4);
  _ebss = .;         /* define a global symbol at bss end */
  __bss_end__ = _ebss;
} >RAM

/* XRAM bss section 
*/
.xbss :
{
  . = ALIGN(4);
  _sxbss = .;       /* create a global symbol at xram bss start */
  *(.xbss)
  *(.xbss*)

  *aaa.o(.bss.bss*)
  *bbb.o(.bss.bss*)
  *ccc/*.o(.bss.bss*)
    
  . = ALIGN(4);
  _exbss = .;       /* create a global symbol at xram bss  end */
} >XRAM

修改完.ld文件后,还有修改启动文件,加入.xdata和.xbss的初始化指令,保证分配到这些段的变量能被正确初始化,首先在文件开头引入刚刚定义的段地址

/* start address for the initialization values of the .xdata section. 
defined in linker script */
.word  _sixdata
/* start address for the .xdata section. defined in linker script */  
.word  _sxdata
/* end address for the .xdata section. defined in linker script */
.word  _exdata
/* start address for the .xbss section. defined in linker script */
.word  _sxbss
/* end address for the .xbss section. defined in linker script */
.word  _exbss

之后在设置程序入口之前加入初始化代码

/* Copy the xdata segment initializers from flash to SRAM */  
  ldr r0, =_sxdata
  ldr r1, =_exdata
  ldr r2, =_sixdata
  movs r3, #0
  b LoopCopyXDataInit

CopyXDataInit:
  ldr r4, [r2, r3]
  str r4, [r0, r3]
  adds r3, r3, #4

LoopCopyXDataInit:
  adds r4, r0, r3
  cmp r4, r1
  bcc CopyXDataInit

/* Zero fill the xbss segment. */
  ldr r2, =_sxbss
  ldr r4, =_exbss
  movs r3, #0
  b LoopFillZeroxbss

FillZeroxbss:
  str  r3, [r2]
  adds r2, r2, #4

LoopFillZeroxbss:
  cmp r2, r4
  bcc FillZeroxbss

修改完成后编译就可以发现.map文件中对应的文件中的所有变量都已经被分配到了外部SRAM中了

参考资料:

Putting Code of Files into Special Section with the GNU Linker | MCU on Eclipse

链接脚本(Linker Scripts)语法和规则解析(自官方手册) - BSP-路人甲 - 博客园 (cnblogs.com)

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值