C++ GNU LD链接器-无法在闪存中的地址处获取变量

C++ GNU LD链接器-无法在闪存中的地址处获取变量,c++,c,linker,ld,stm32,C++,C,Linker,Ld,Stm32,我正在使用STM32F072,需要在Flash中的特定位置添加一个结构。但当地址为0x0801F800时,该结构不会编程为闪存 我在命名空间范围中声明一个实例: const Memory ConfigData __attribute__ ((section (".ConfigData"))) __attribute__ ((__used__)){ 2u, 1.0f, 0.1f, 1.0f, 12.0f, 2.5f }; 要在我使用的特定内存位置插入上述内容,请执行以下操作: _ConfigSt

我正在使用STM32F072,需要在Flash中的特定位置添加一个结构。但当地址为0x0801F800时,该结构不会编程为闪存

我在命名空间范围中声明一个实例:

const Memory ConfigData __attribute__ ((section (".ConfigData"))) __attribute__ ((__used__)){ 2u, 1.0f, 0.1f, 1.0f, 12.0f, 2.5f };
要在我使用的特定内存位置插入上述内容,请执行以下操作:

_ConfigStart = 0x0801F800;
.ConfigData _ConfigStart :
{
    KEEP(*(.ConfigData));
} > FLASH
但是,上述代码不起作用,当_ConfigStart地址为0x0800F800时,它确实起作用。但我需要它在flash的最后一页(0x0801F800),所以这不是一个可行的选项

我可以使用STLINK-V2手动编程我想要的页面,我也可以使用我自己的flash库来完成,但我需要链接器包含它

此时没有链接器错误

链接器文件: mem.ld:

MEMORY
{
  RAM (xrw)     : ORIGIN = 0x20000000, LENGTH = 16K
  CCMRAM (xrw)  : ORIGIN = 0x00000000, LENGTH = 0
  FLASH (rx)    : ORIGIN = 0x08000000, LENGTH = 128K
  FLASHB1 (rx)  : ORIGIN = 0x00000000, LENGTH = 0
  EXTMEMB0 (rx) : ORIGIN = 0x00000000, LENGTH = 0
  EXTMEMB1 (rx) : ORIGIN = 0x00000000, LENGTH = 0
  EXTMEMB2 (rx) : ORIGIN = 0x00000000, LENGTH = 0
  EXTMEMB3 (rx) : ORIGIN = 0x00000000, LENGTH = 0
  MEMORY_ARRAY (xrw)  : ORIGIN = 0x00000000, LENGTH = 0
}
sections.ld(为了简洁起见,有些东西被删掉了):

ConfigData显示在此处的.map文件中,地址为0x0800f800:

 .igot.plt      0x20000078        0x0 c:/program files (x86)/gnu tools arm embedded/7 2017-q4-major/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/lib/thumb/v6-m\libstdc++_nano.a(new_op.o)

.ConfigData     0x0800f800       0x18
 *(.ConfigData)
 .ConfigData    0x0800f800       0x18 C:\Users\David\AppData\Local\Temp\cc10vcUe.ltrans0.ltrans.o

.rel.dyn        0x0800f818        0x0
并在分配给0x0801f800时显示为获取大小:

.igot.plt       0x20000078        0x0 load address 0x080090c8
 .igot.plt      0x20000078        0x0 c:/program files (x86)/gnu tools arm embedded/7 2017-q4-major/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/lib/thumb/v6-m\libstdc++_nano.a(new_op.o)

.ConfigData     0x0801f800       0x18
 *(.ConfigData)
 .ConfigData    0x0801f800       0x18 C:\Users\David\AppData\Local\Temp\ccIUhOBG.ltrans0.ltrans.o

.rel.dyn        0x0801f818        0x0
 .rel.iplt      0x0801f818        0x0 c:/program files (x86)/gnu tools arm embedded/7 2017-q4-major/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/lib/thumb/v6-m\libstdc++_nano.a(new_op.o)
我也试着把它放在自己的块中:

.ConfigData :
    {
        KEEP(*(.ConfigData));
    } > CONFIG
对于mem.ld:

MEMORY
{
  RAM   (xrw)   : ORIGIN = 0x20000000,      LENGTH = 16K
  FLASH (rx)    : ORIGIN = 0x08000000,      LENGTH = 128K - 0x800
  CONFIG(R)     : ORIGIN = ORIGIN(FLASH) +  LENGTH(FLASH),  LENGTH = 0x800
}
没有运气,这次真的输了

编辑

这个问题实际上是这个微控制器和程序员的一个奇怪的怪癖。编程器拒绝编程超出闪存大小寄存器指定的闪存范围,但闪存扩展到128K(不是64K)。我已经写入了地址范围之外的各种地址,没有问题,我认为这样做是可以的,因为STLINK实用程序允许我查看该内存范围

这个问题是专门针对STM32F072C8的,我不是唯一一个有这种困惑的人:


您是否也可以添加地图文件?查看
.ConfigData
部分的设置位置可能非常有趣。我在映射文件中添加了包含ConfigData的部分,我对其进行了修改,将ConfigData稍微移到了部分文件的开头。为了保持一致性,将其移回原来的位置。这不是很清楚。你的意思是,无论映射到什么地址,节都在映射文件中,而不是变量吗?是的,似乎地址在那里,大小在那里,但它不会转换为十六进制或bin文件。
MEMORY
{
  RAM   (xrw)   : ORIGIN = 0x20000000,      LENGTH = 16K
  FLASH (rx)    : ORIGIN = 0x08000000,      LENGTH = 128K - 0x800
  CONFIG(R)     : ORIGIN = ORIGIN(FLASH) +  LENGTH(FLASH),  LENGTH = 0x800
}