Gcc 使用链接器映射内存

Gcc 使用链接器映射内存,gcc,linker,embedded,ld,memory-mapping,Gcc,Linker,Embedded,Ld,Memory Mapping,如何强制链接器将一些变量放到内存中的特定位置。例如,我想在0x8100000中分配整数名。如果我没有错过了解,我可以使用: int name __attribute__ ((section ("name_of_section"))); 然后在链接器脚本中: SECTIONS { ... . = 0x8100000; .data : { name_of_section } ... } 我想为uC端口使用类似的映射。 但有些东西不匹配,我不知道我在哪里犯了错误。(我

如何强制链接器将一些变量放到内存中的特定位置。例如,我想在0x8100000中分配整数名。如果我没有错过了解,我可以使用:

int name __attribute__ ((section ("name_of_section")));
然后在链接器脚本中:

 SECTIONS
 {
   ...
   . = 0x8100000;
   .data : { name_of_section }
   ...
 }
我想为uC端口使用类似的映射。
但有些东西不匹配,我不知道我在哪里犯了错误。(我从来没有使用过链接器脚本,如果我写了一些非常愚蠢的东西,那么很抱歉)。

通常这是在没有链接器脚本的情况下完成的

int volatile * const portA = 0x8100000;  //portA is a constant pointer to a volatile int
...

*portA = 53;  //write value 53 to output port

如果您必须使用链接器脚本,那么它将是特定于编译器和/或芯片的。您能告诉我们您使用的是什么芯片和工具链吗?

我建议不要使用链接器访问硬件寄存器。如果显式地对地址进行编码,代码将更易于理解和维护。最好将所有特定于设备的寄存器信息收集到包含文件中。对于复杂的外围设备,通常最好为与外围设备相关联的寄存器块键入定义结构,尤其是当设备支持特定外围设备的多个实例时。然后使用Luke答案中的技巧获取代码中的寄存器或寄存器块。访问硬件寄存器时应始终使用volatile关键字。

谢谢您的建议!现在它开始工作了。 .ld文件:

SECTIONS
{
...
   .data: {
   ...
   }
   ...
   var_name = 0x40010CA0;
}
.c文件:

extern volatile int var_name;
在研究了我上面链接的文档(输入部分示例)之后,我还尝试了类似的方法: .ld文件:

.hrd_map 0x40010CA0 : 
{       
    main.o(.b_section)  
}
其中.b_部分是具有以下属性的全局变量:

int b __attribute__((section(".b_section")));
但它不起作用,我犯了这样的错误:“main”的多重定义。 我想这是因为在前面的.ld文件中,我还有其他类似于:.data:{…}.bss.text的功能。 也许有人知道如何解决这个问题,或者如何在不使用section属性的情况下获取一些变量。我试图在main.o文件中查找变量的符号,但除了使用section属性和other(默认情况下创建的?).data.bss.text等创建的.b_节外,我没有看到任何类似变量符号名称的内容


@丹:你是对的,我这样做是为了学习,我同意你的看法。但另一方面,我认为这段代码将是非常可移植的,因为每个芯片都需要.ld和启动文件,并且库中还包括端口的定义

谢谢你的回答。我知道这个解决方案,但我想用linker来做这个。这是给STM32大学的。我正在将eclpis与Sourcery G++Lite一起使用。如果您需要访问设备寄存器或特定内存位置的其他内容,我建议您这样做(并可能添加
volatile
,以确保它正常工作)。如果您只想将数据放在一般区域,那么我认为上面的链接器脚本片段就可以了。关于你的问题,你将不得不说得更多,而不是“有些东西不匹配”。@ams-对不起,我忘了这个词。我现在来解决这个问题。我知道这取决于芯片,我提到的地址只是一个例子。我通过使用与您类似的技术实现了内存映射,它工作正常,但现在我想通过使用链接器脚本实现它,我不知道如何正确地实现它。我试图在这里找到一些示例:但我没有看到任何将adress设置为特定变量的示例。我知道我可以在gcc编译器中使用'section'属性。然后我尝试在链接器脚本中使用它,但我认为我做错了什么。您可以在链接器脚本中定义变量(嗯,标签)。请参阅链接到的文档中的“简单工作分配”。我想,您需要在C源代码中将变量声明为
extern
。谢谢,我一直在寻找这个。我不明白所有反对这样做的建议。我在商业产品中见过这种情况。我不同意“您的代码将更容易理解和维护等”。那是没有根据的。无论如何,每个目标micro都有不同的链接器脚本。我觉得这个解决方案相当优雅。