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

Die*_*mbo 5 c attributes gcc const stm32

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

如果我不使用constRAM,则不会使用-但我注意到增加了对Flash的使用,因为它被分配了两次!

链接器文件:

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
}
Run Code Online (Sandbox Code Playgroud)

数组声明具有初始化程序:

mytab_type  __attribute__((section (".UserDataSector "))) progr16[16]=
{ 
    { {LIST1,LIST2....
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我没有使用const。假设这progr16被强制放在闪存中,并且如果在调试过程中我使用内存浏览器检查的话,它看起来确实在那里。但它似乎也占用RAM

FLASH    RAM
text     data    bss   dec     
9268     772     1948  11988    
Run Code Online (Sandbox Code Playgroud)

如果我添加const关键字:

FLASH    RAM
text     data    bss    dec 
9972     68      1948   11988
Run Code Online (Sandbox Code Playgroud)

好的,在RAM中保存了704个字节的数据,但是如果该值已经在Flash中的任何位置(由于初始化程序),那么为什么相同数量的字节会增加Flash的使用呢?

Gab*_*les -1

我还没有机会像我计划的那样实际设置和构建一个独立的项目来彻底测试它,但是添加NOLOAD如下内容是否有效?

SECTIONS
{ 
    .my_block (NOLOAD) :
    {
        KEEP(*(.UserDataSector));
    } >USER_DATA_FLASH
}
Run Code Online (Sandbox Code Playgroud)

以下是我在 v2.32 ld PDF 用户手册中针对“NOLOAD”所做的一些注释: 在此输入图像描述

这似乎是您可能需要的。

另外,我通常将属性说明符放在变量后面,如许多官方 gcc 示例中所示(例如此处“section”下的示例),尽管我不确定这是严格要求的(请参阅此处的官方语法文档)。

IE:

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

另外,我必须说,您问题中的格式(空格、对齐、缩进等)不是很好,并且沿着这些不密切关注细节的路线,我在您的部分属性中看到您有一个额外的空格最后:".UserDataSector "而不是像".UserDataSector"它应该的那样,所以这也可能是问题所在。

另外,还有一些注意事项:

  1. 请注意,您应该稍微清理一下格式、缩进等,以使问题中的代码更易于阅读。
  2. 我认为KEEP这里没有必要,但我也不认为这有什么坏处。
  3. 您应该研究并阅读官方的 GNU 链接器脚本 (LD) 手册。它可以在线获取 html 格式,网址为:https: //sourceware.org/binutils/docs/ld/。最新版本是v2.32。

    1. 然而,我认为在 PDF 中学习要容易得多,这样你就可以输入内容、突出显示它、标记它、一次性搜索等等。构建 LD pdf 用户手册,然后使用Foxit Reader(跨平台、并且免费)来学习和标记手册。
    2. 如何构建链接描述文件 (LD) PDF 用户手册:
    3. 下载源代码: https: //www.gnu.org/software/binutils/
      1. 例如:在此处获取最新的 binutils 版本(当前为binutils-2.32.tar.xz):https: //ftp.gnu.org/gnu/binutils/
    4. 解压它(例如,在 Linux Ubuntu 中右键单击并转到“Extract Here”)。
    5. cd 进入文件夹:cd binutils-2.32
    6. 然后配置并制作:

      ./configure
      make
      make pdf
      
      Run Code Online (Sandbox Code Playgroud)
    7. 完毕!现在是 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
      
      Run Code Online (Sandbox Code Playgroud)
    8. 保存并使用ld.pdf,它现在是我上面链接的 HTML 2.32 binutils 手册的 PDF 版本。

  4. 您可能需要阅读启动文件以查看它是否做了任何奇怪的事情。

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

其他值得注意的链接描述文件问题

  1. 访问链接器脚本变量的“值”在 C 中是未定义的行为吗?
  2. 如何从 C 中获取 ld 链接描述文件中定义的变量值