如何强制链接器将我的一些变量放到内存中的特定位置。例如,我想在0x8100000中分配整数 name 。如果我没有理解我可以使用:
int name __attribute__ ((section ("name_of_section")));
然后在链接器脚本中:
SECTIONS
{
...
. = 0x8100000;
.data : { name_of_section }
...
}
我想使用类似的地图来映射uC端口。 但有些事情不匹配,我不知道我犯了什么错误。 (我从来没有使用过链接器脚本,如果我写了一些非常愚蠢的东西,那就很抱歉。)
答案 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关键字。