如果不使用const,则在RAM中进行不需要的分配,尽管放置在Flash绝对地址处

问题描述 投票:5回答:1

我正在使用GCC。我通过.ld链接器文件在Flash中创建了一个SECTION,我在那里放置了一些带有指令__attribute__((section...的数据(704字节)数据似乎在flash中,但如果我在声明时没有使用const关键字,则会在RAM中分配相同的空间数据。

如果我使用const RAM没有使用 - 但我注意到闪存的使用增加,因为它被分配了两次!

链接文件:

FLASH (rx)      : ORIGIN = 0x8000000, LENGTH = 14K
USER_DATA_FLASH (rx)      : ORIGIN = 0x8003800, LENGTH = 2K
}

SECTIONS
{ /* placing my named section at given address: */
  .my_block 0x8003800 :
 {
  KEEP(*(.UserDataSector)) 
 } > USER_DATA_FLASH
}

数组声明有初始值设定项:

mytab_type  __attribute__((section (".UserDataSector "))) progr16[16]=
{ 
    { {LIST1,LIST2....

在这种情况下,我没有使用const。假设progr16被迫在闪存中,实际上它看起来如果我在调试期间检查内存浏览器。但它似乎也占据了RAM

FLASH    RAM
text     data    bss   dec     
9268     772     1948  11988    

如果我添加const关键字:

FLASH    RAM
text     data    bss    dec 
9972     68      1948   11988

好的,RAM中的704字节数据被保存,但是为什么相同数量的字节会增加Flash的使用,如果这个值已经存在于Flash中(因为初始化器)?

c gcc attributes const stm32
1个回答
-1
投票

我没有机会真正建立和建立一个独立的项目,就像我打算做的那样,彻底测试这个,但是添加NOLOAD,如下工作?

SECTIONS
{ 
    .my_block (NOLOAD) :
    {
        KEEP(*(.UserDataSector));
    } >USER_DATA_FLASH
}

以下是我在“NOLOAD”的v2.32 ld PDF用户手册中所做的一些注意事项:enter image description here

这似乎是你可能需要的。

此外,我通常将属性说明符放在变量之后,如许多官方gcc示例(例如the ones under "section" here)中所示,尽管我不确定是否严格要求(请参阅official syntax documentation here)。

即:

static my_type my_array_name[] __attribute__((section(".UserDataSector"))) =
{
    // member 1,
    // member 2,
    // member 3,
    // etc
};

另外,你的问题中的格式(空格,对齐,缩进等)不是很好,我必须说,并且沿着这些不注重细节的行,我在你的section属性中看到你有一个额外的空间at结束:".UserDataSector "而不是".UserDataSector",它应该是,所以这可能也是问题。

还有一些说明:

  1. 请注意,您应该清理格式,缩进等,以使您的问题中的代码更易于阅读。
  2. 我不认为KEEP在这里是必要的,但它不会伤害任何我想不到的东西。
  3. 您应该学习并阅读官方GNU链接脚本(LD)手册。它以html格式在线提供,在这里:https://sourceware.org/binutils/docs/ld/。最新版本是v2.32。 但是,我认为在PDF中学习更容易,因此您可以输入,突出显示,标记,一次搜索等等。构建LD pdf用户手册,然后使用Foxit Reader(跨平台,和免费)研究和标记手册。 如何构建链接描述文件(LD)PDF用户手册: 下载源代码:https://www.gnu.org/software/binutils/ 例如:在这里获取最新的binutils版本(目前为binutils-2.32.tar.xz):https://ftp.gnu.org/gnu/binutils/ 解压缩它(右键单击并转到Linux Ubuntu中的“Extract Here”)。 进入文件夹:cd binutils-2.32 然后配置并制作: ./configure make make pdf 完成!这是现在的PDF文件(与find | grep '\.pdf'一起找到): binutils-2.32/libiberty/libiberty.pdf binutils-2.32/bfd/doc/bfd.pdf binutils-2.32/ld/ld.pdf <----- THE MAIN ONE I WANT! binutils-2.32/gprof/gprof.pdf binutils-2.32/gas/doc/as.pdf binutils-2.32/binutils/doc/binutils.pdf 保存并使用ld.pdf,它现在是我上面链接的HTML 2.32 binutils手册的PDF版本。
  4. 您可能需要阅读您的启动文件,看看它是否做了任何奇怪的事情。

就像我说的那样,我想在发布之前全面测试这个答案,但现在没有机会。在过去的几周里,我在链接器脚本中花了很多时间,所以有一些新鲜的想法,我认为这会有所帮助。

其他链接器脚本的问题

  1. Is accessing the "value" of a linker script variable undefined behavior in C?
  2. How to get value of variable defined in ld linker script from C
© www.soinside.com 2019 - 2024. All rights reserved.