【STM32CubeIDE】将变量定义到指定地址

使用Keil

在使用Keil编写程序的时候我们可以很轻松的将变量定义到指定地址

uint8_t array[1024] __attribute__((at(0x20010000)));

使用STM32CubeIDE

由于编译器不同,STM32CubeIDE中是不支持 __attribute__((at()))这一属性的,所以需要另辟蹊径。在网上查找到的资料说可以使用__attribute__((section()))属性

//将array放到地址空间0x20010000中
uint8_t array[1024] __attribute__((section(".RAM_Array")));

配合修改链接文件stm32Fxxx_FLASH.ld

...
MEMORY
{
	CCMRAM    (xrw)    : ORIGIN = 0x10000000,   LENGTH = 64K
	RAM    (xrw)    : ORIGIN = 0x20000000,   LENGTH = 128K
	RAM_Array_Addr    (xrw)    : ORIGIN = 0x20010000,   LENGTH = 1K
	FLASH    (rx)    : ORIGIN = 0x8000000,   LENGTH = 1024K
}
...
SECTIONS
{
...
...
 .RAM_Array (NOLOAD):	//注意这里的 NOLOAD !
 {
   . = ALIGN(4);
   *(.RAM_Array)	//这是与.c文件中声明变量时的段对应的符号
   . = ALIGN(4);
 } >RAM_Array_Addr
...
...
}

这样做确实可以将array定义到内存地址0x20010000中去,但是需要注意一个问题,这个坑也是促使我第一次写博文的重要原因:

说问题之前先普及一下知识点:

我们的源码经过GCC编译器编译链接之后会生成一个 .elf 文件和一个 .bin 文件,二者都是二进制文件,但是 elf 文件包含符号表、汇编等信息,它的执行需要有操作系统支持,例如Linux,而bin 文件是elf 文件经过压缩,仅提取了其中的代码段 .text 和数据段.data 以及一些自定义的段(如 .RAM_Array)来做成的内存镜像,所以可以直接由机器运行,也就是我们要下载到STM32的FLASH中的东西。

我们的源码编译后会默认的生成三个段 .text 代码段、.data数据段以及 .bss存放未初始化变量的段,还有一些自定义的段 .RAM_Array。这些段的地址等属性由MEMORY{...}中的内容控制。

.text:代码段,存放代码
.data:数据段,存放已经初始化的变量
.bss:存放未初始化或初始化为零的变量,在编译时会直接清空这部分内存,以压缩输出文件
同时输出的bin 文件中只包含.text段和.data段以及自定义段。

我在自定义的段中定义了一个32M的大数组,放到了SDRAM中,但是未初始化,编译时内存炸了。千辛万苦找出原因发现是.bss段是在RAM中的,尝试将.bss段放到SDRAM中,但是SDRAM需要初始化,于是又失败了。所以大数组不能放到.bss段中,于是乎初始化为1,编译通过!赶紧下载试试,咦?怎么进度条一直不动呢?千辛万苦找出原因发现输出的bin文件直接 2.9G!?没错,你没看错,我也没打错,就是2.9个G!好家伙!玩呢!我一个32M的大数组愣是给我编译出了2.9G?于是乎又宣布失败。于是乎开始学习ld链接文件的语法,终于有心人天不负,让我发现了NOLOAD这个属性,就是在链接时告诉编译器,这个段我不要加载,你也别给我输出到bin文件中去了,我的小心脏受不了!,于是乎一个40KB的bin文件出来了,烧录,成功!好家伙!

– - - - - - - - - - - - - - - - - - - - - - - - - - - - -想做就没有做不成的事 - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  • 19
    点赞
  • 73
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值