内存使用链接器映射

时间:2012-01-05 23:11:06

标签: gcc linker embedded ld memory-mapping

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

int name __attribute__ ((section ("name_of_section")));

然后在链接器脚本中:

 SECTIONS
 {
   ...
   . = 0x8100000;
   .data : { name_of_section }
   ...
 }

我想使用类似的地图来映射uC端口。 但有些事情不匹配,我不知道我犯了什么错误。 (我从来没有使用过链接器脚本,如果我写了一些非常愚蠢的东西,那就很抱歉。)

3 个答案:

答案 0 :(得分:3)

通常这是在没有链接描述文件的情况下完成的。

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

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

如果必须使用链接描述文件,则它将特定于编译器和/或芯片。你能告诉我们你正在使用什么芯片和工具链吗?

答案 1 :(得分:1)

感谢您的所有建议!现在它正在运作。 .ld文件:

SECTIONS
{
...
   .data: {
   ...
   }
   ...
   var_name = 0x40010CA0;
}

.c文件:

extern volatile int var_name;

在我上面链接的研究文档(输入部分示例)之后,我尝试了类似的东西: .ld文件:

.hrd_map 0x40010CA0 : 
{       
    main.o(.b_section)  
}

其中.b_section是一个具有属性的全局变量:

int b __attribute__((section(".b_section")));

但它不起作用,我遇到了这样的错误:`main'的多重定义。 我认为那是因为早先在.ld文件中我有其他的对齐方式:.data:{...} .bss .text。 也许有人知道如何解决这个问题,或者如何在不使用 section 属性的情况下获取某些变量。我试图在main.o文件中查找变量的符号,但我没有看到任何看起来像变量的符号名称,除了.b_section我使用 section 属性和其他创建的(默认创建) ?)。data .bss .text等。

@Dan你说得对,我这样做是为了学习,我同意你的观点。但另一方面,我认为这个代码将是非常便携的,因为每个芯片都需要.ld和Startup文件以及端口的定义也包含在库中。

答案 2 :(得分:0)

我建议不要使用链接器访问硬件寄存器。如果明确编写地址代码,您的代码将更容易理解和维护。在包含文件中收集所有特定于设备的寄存器信息是个好主意。对于复杂的外设,通常最好键入一个与外设相关的寄存器块的结构,特别是当器件支持特定外设的多个实例时。然后使用Luke的答案中的技术来获取代码中的寄存器或寄存器块。并且在访问硬件寄存器时应始终使用volatile关键字。