1

我正在尝试使用 Eclipse + CDT + yagarto (gnu toolchain) + OpenOCD 对 ARM 进行编程。在几个示例项目(例如来自 yagarto 站点)中,我发现了链接器脚本 (*.ld),其中指定了许多链接信息(以及节定义)。实际上我以前没有遇到过这些文件(IAR 不需要它们),我发现它们乍一看有点难以理解。所以我的问题是我是否可以在我的所有项目中为我的目标处理器(STR710FZ2T6)使用一个这样的脚本文件,或者我必须熟悉编写这些脚本并为每个项目编写它们。如果我可以为特定目标处理器的所有项目使用单个文件,请您建议我在哪里可以找到这样的通用文件。

4

2 回答 2

3

我的猜测是每三个人都有不同的脚本或解决方案。有许多问题需要解决,不同的链接器将以不同的方式解决这些问题。如果不是黑魔法,我认为 GNU 让它变得太难了。

对于嵌入式系统,您通常会使用闪存或 eeprom 或其他形式的只读存储器进行引导。与其他处理器一样,ARM 有一个向量表,可以基本上告诉它复位代码和中断等位置。所以该表必须位于特定位置,并且您必须告诉链接器将其放在该特定位置(首先) .

我喜欢使用的脚本之一是:

MEMORY
{
    bob (RX) : ORIGIN = 0x0000000, LENGTH = 32K
    joe (WAIL) : ORIGIN = 0x2000000, LENGTH = 256K
}

SECTIONS
{
    JANE : { startup.o } >bob
}

我通常使用 ram 和 rom 作为名称而不是 bob 和 joe,但在这里证明名称是什么并不重要,它们只是标签。

主题的另一个变体:

MEMORY
{
    rom(RX)   : ORIGIN = 0x00000000, LENGTH = 0x8000
    ram(WAIL) : ORIGIN = 0x20000000, LENGTH = 0x2000
}

SECTIONS
{
    .text : { *(.text*) } > rom
}

第一个允许您以任何顺序将文件放在链接器命令行上,但您必须在 startup.o 文件中有向量表。后者允许您使用任何文件名,但链接描述文件上的第一个文件需要具有向量表。

arm-thumb-elf-gcc -Wall $(COPS) vectors.o putget.o blinker2.c -T memmap -o blinker2.elf

或者直接用ld

arm-thumb-elf-ld vectors.o putget.o blinker2.o -T memmap -o blinker2.elf

RX 告诉链接器将读取和执行的内容放入该内存部分,而 WAIL 基本上就是其他所有内容。例如,如果您只有一个 ram,您可以将所有标志 RXWAIL 放在告诉 ram 在哪里的行上。在这种情况下,根据您的加载程序,您可以依靠 elf 文件告诉加载程序从哪里开始分支,或者您可以简单地将入口点设置为二进制文件的开头,加载程序可以更简单。手臂(不是 cortex-m3)有一个分支指令作为重置向量的第一个向量,因此您可以假装为 ram 解决方案构建一个向量表,并且可以正常工作。

该解决方案的许多问题不会打扰我。我在我的代码中初始化变量,而不是在声明期间。

int rx;

int main ( void )
{
  rx = 7;

代替

int rx=7;

int main ( void )
{

我也从不假设代码开始时变量为零,我总是在开始之前将其初始化为某个值。您的启动代码和链接器脚本作为一个团队可以一起工作,以便更容易地自动重置 bss 代码并在启动时将非零初始化数据从 rom 复制到 ram。(上面的 int rx=7; 需要一些代码从 rom 中的某个位置复制值 7 并将其写入为变量 rx 分配的 ram 中的内存位置,以便当 main() 启动时 7 就在那里。

由于这种方法,我的引导代码也非常简单:

.globl _start
_start:
    b reset
    b hang
    b hang
    b hang
    b hang
    b hang
    b hang
    b hang
    b hang
    b hang
    b hang
    b hang
    b hang
    b hang
    b hang

hang : b hang

reset:
    ldr sp,=0x10004000
    bl main
    b hang

您将看到或阅读有关允许启动代码和链接器脚本一起工作的解决方案,而不必对堆栈指针、堆空间等进行硬编码,同样您可以在复杂的启动代码和链接器中投入大量工作脚本来获得一些自动化,也许可以节省一些工作,也许不是。自动化,如果/何时工作可以并且将减少人为错误,这可能是一件好事,如果您经常更换芯片或尝试编写在一系列芯片中工作的代码,您可能也需要这种自动化.

我的底线是,您可以只使用一个链接器脚本来完成所有 ARM 工作。但是您必须根据该脚本调整您的工作。您可能不会找到适用于每个人的示例代码的脚本。脚本越复杂,借用就越困难。是的,我上面的脚本很可能可以在 ld 命令行上完成,但是当(gcc 2.95)我无法让它工作时,我开发了上面的最小脚本并从那时起一直在使用它们。出于某种原因不得不修改第二个脚本,但使用 4.xx,当然是 4.4.x,我可以使用其中任何一个。

于 2009-05-16T02:26:14.990 回答
0

没有通用的链接描述文件。这些脚本非常重要,因为它们定义了各种数据和程序部分在内存(RAM 或 ROM)中的放置位置。IAR 编译器中有一些等价的东西(如果我没记错的话是 xcl 文件)。到目前为止,您显然只使用了默认值。

有一个关于 STR7xx 的好文档,名为“Using Open Source Tools for STR7xx Cross Development”。您可以在 yagarto 主页中找到链接。我建议您看一下它并尝试了解链接器文件的工作原理。您还需要了解一些其他配置文件。

于 2008-11-05T07:36:42.627 回答