C++ GNU LD链接器-无法在闪存中的地址处获取变量
我正在使用STM32F072,需要在Flash中的特定位置添加一个结构。但当地址为0x0801F800时,该结构不会编程为闪存 我在命名空间范围中声明一个实例: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
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
}