C源代码中使用的链接器变量的“未定义引用”

时间:2014-10-13 18:01:07

标签: c linker arm linker-errors undefined-reference

我正在ST ARM微控制器上进行一些编程,而对于部分内容,我需要将一些数据存储在闪存中,这些数据将在启动时保持不变。

为了整个项目的一致性,我想在我的链接器脚本中定义这些数据的位置,然后在我的代码中使用这个变量。我已经完成了这项工作(针对两个不同的地区)。

我的链接描述文件的相关部分:

MEMORY
{
    flash :             org = 0x08000000, len = 60k     /* Standard boot - No bootloader */
    flash_config_info : org = 0x0801F800, len = 1k      /* Location for config info storage */
    flash_boot_info :   org = 0x0801FC00, len = 1k      /* Location for boot info storage */
    ram :               org = 0x20000000, len = 20k  
}

我的启动信息部分的标题:

#ifndef BOOTLOADER_H_
#define BOOTLOADER_H_

#include <stdint.h>

extern uint32_t flash_boot_info;
#define BOOT_INFO_PAGE_ADDRESS (&flash_boot_info)

//...

#endif

配置信息部分的标题:

#ifndef INFO_H_
#define INFO_H_

#include <stdint.h>

extern uint32_t flash_config_info;
#define INFO_CONFIG_PAGE_ADDRESS (&flash_config_info)

//...

#endif

我的问题:我得到&#34;未定义的引用&#34;链接时flash_boot_info变量的错误。我没有收到flash_config_info的相同错误。重要的是要注意,如果我切换变量的名称,则错误会跟随引用的位置,而不是变量(当{{1}引用它时,我会得到flash_config_info的错误应该是)。

有没有人知道为什么会出现这样的错误?我发现引用变量的方式没有任何区别,但我会非常感谢您对我所看到的内容的一些了解。

谢谢!

1 个答案:

答案 0 :(得分:0)

同样的事情可以通过使用section节中的分区来完成。例如,

MEMORY
{
    flash : org = 0x08000000, len = 64k
    ram :   org = 0x20000000, len = 20k  
}
SECTIONS
{
   .text {
      boot.o(.text);
      *(.text);
      *(.rodata);
   } > flash
   .data {
      *(.data);
   } > ram AT>flash
   . = ADDR(.text) + 0x1F800; /* to config position */
   .config { *(.config); } > flash
   . = ADDR(.text) + 0x1FC00; /* to boot position */
   .boot { *(.boot); } > flash
   .bss { *(.bss); } > ram
}

要解决的主要问题是 ld 希望将所有内容放在一个内存区域中。这是因为您需要将图像(二进制)刻录到一个设备。实际上,我认为你只有一个闪存设备而只想分割闪存。为此目的,最好使用位置计数器(.)。

您可以预处理链接描述文件和/或使用常量使值 1f800 1fc00 更具可读性。使用内存区域看起来更好,但我认为使用部分进行此分区会有更好的体验。