RAM部分是二进制固件的一部分

时间:2019-01-07 18:05:41

标签: gcc linker ld linker-scripts

我正在尝试使用自定义RAM部分,以便能够在重新引导期间传递信息。此部分在启动时不会被删除,因此放置在此部分中的变量将在重新启动后保留(当然,如果没有营养损失)。

我使用GNU工具链和Cortex-M0(STM32)MCU

所以我在链接描述文件中在RAM之前添加了一个新的存储区:

RAM_PERSIST (xrw) : ORIGIN = 0x20000000, LENGTH = 0x0040
RAM (xrw)         : ORIGIN = 0x20000040, LENGTH = 0x0FD0

然后进入其中的一段:

.pds :
{
  KEEP(*(.pds))
} >RAM_PERSIST

最后在C代码中,我在本节中声明一些数据:

data_t __attribute((section(".pds")) data;

我确实进行了编译,但是无法将生成的二进制文件上传到目标计算机上。使用objdump,我发现我的固件从0x20000000开始有一个新部分“ .sec2”:

> (...)/arm-none-eabi-objdump -s ./obj/firmware.hex | tail
 8006d20 f8bc08bc 9e467047 f8b5c046 f8bc08bc  .....FpG...F....
 8006d30 9e467047 e9000008 c1000008 00127a00  .FpG..........z.
 8006d40 19000000 e0930400 409c0000 400d0300  ........@...@...
 8006d50 c0c62d00 30750000 ffffffff 01000000  ..-.0u..........
 8006d60 04000000                             ....
Contents of section .sec2:
 20000000 00000000 00000000 00000000 00000000  ................
 20000010 00000000 00000000 00000000 00000000  ................
 20000020 00000000 00000000 00000000 00000000  ................
 20000030 00000000 00000000 00000000 00000000  ................

所以我想我必须告诉链接器,此部分不在闪存中,因此不能成为固件的一部分。

我是对的吗?如果是这样,该怎么做?

多谢。

2 个答案:

答案 0 :(得分:1)

MEMORY
{
    rom : ORIGIN = 0x00000000, LENGTH = 0x40000
    ram : ORIGIN = 0x20000000, LENGTH = 0x4000
}

SECTIONS
{
    .text : { *(.text*) } > rom
    .rodata : { *(.rodata*) } > rom
    .bss : { *(.bss*) } > ram
}

当我停止在内存定义中使用xrw等时,我有了更多的控制/成功,而是对.text,.bss,.data等进行了控制,如果您进一步想要在某个地方添加特定对象,则可以添加。等等...

答案 1 :(得分:1)

I did achieve what I wanted by adding NOLOAD attibute to my custom section :

.pds (NOLOAD): { KEEP(*(.pds)) } >RAM

Here is the NOLOAD description (gcc documentation) :

(NOLOAD) The (NOLOAD) directive will mark a section to not be loaded at run time. The linker will process the section normally, but will mark it so that a program loader will not load it into memory. For example, in the script sample below, the ROM section is addressed at memory location 0 and does not need to be loaded when the program is run. The contents of the ROM section will appear in the linker output file as usual.

SECTIONS {
  ROM  0  (NOLOAD)  : { ... }
  ...
}

I found a similar post which helped me, I add a link here for reference : GCC (NOLOAD) directive loads memory into section anyway