抱歉,如果这可能偏离主题。
在使用avr-gcc或avr-ld生成.hex(Intel HEX格式)文件的过程中,输出(最终结果)有显着不同。作为最低限度的澄清,我讨论的是在生成对象文件之后生成 ELF 文件的步骤。
在我的第一次尝试中,我使用
avr-ld
来生成我的 ELF 文件。过程运行顺利,但在生成 HEX 文件并上传到我的主板后,它没有执行任何操作(如上传空白 HEX 文件)。
在第二次尝试时,我遵循了此处的建议:
链接时指定MCU类型很重要。编译器使用 -mmcu 选项来选择链接在一起的启动文件和运行时库。如果未指定此选项,编译器将默认使用 8515 处理器环境,这肯定是您不想要的。
果然如我所料。上传了十六进制文件,我的主板也相应更新了。
所以我的问题如下:
avr-ld
) 丢失了我正在使用的微控制器的信息。我以为MCU信息存储在Object文件中。avr-gcc
编译/生成 .o 文件,avr-ld
链接 .o 文件并生成 EFL 文件,以及 avr-objcopy
仅删除有用信息并更改文件的格式)文件 ELF -> HEX)?avr-ld
实现与使用 avr-gcc
生成 ELF 文件时相同的输出吗?
- 为什么链接器(avr-ld)丢失了我正在使用的微控制器的信息。我以为MCU信息存储在Object文件中。
链接器不会丢失该信息,它从一开始就没有提供过。 对象文件分别ELF 标头处于“模拟”级别,即像
-mmcu=arch
这样的粒度,其中 arch
是 avr2
、avr25
、avrxmega2
、avrtiny
等之一。
- 使用
编译/生成.o文件,avr-gcc
链接.o文件并生成ELF文件,avr-ld
仅删除有用信息并更改文件ELF→HEX的格式?avr-objcopy
avr-gcc
不是编译器,它只是一个驱动程序,根据提供的文件类型和选项调用其他程序,如编译器本身cc1
或cc1plus
、汇编器as
、链接器ld
。 驱动程序将为这些程序添加选项,这大大简化了它们的使用,其中许多选项在 specs-attiny25
中进行了描述(从 v5 开始)。
作为示例,采用一个简单的
main.c
,其主函数返回 0,并使用 对其进行处理
avr-gcc main.c -o main.elf -mmcu=attiny25 -save-temps -v -Wl,-v
-v
使驱动程序显示它正在发出的命令,-save-temps
存储中间文件,例如汇编。 对于 avr-gcc v8.5,链接过程从调用 collect2
: 开始
.../bin/../libexec/gcc/avr/8.5.0/collect2 -plugin .../bin/../libexec/gcc/avr/8.5.0/liblto_plugin.so -plugin-opt=.../bin/../libexec/gcc/avr/8.5.0/lto-wrapper -plugin-opt=-fresolution=main.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lm -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lattiny25 -mavr25 -o main.elf .../bin/../lib/gcc/avr/8.5.0/../../../../avr/lib/avr25/tiny-stack/crtattiny25.o -L.../bin/../lib/gcc/avr/8.5.0/avr25/tiny-stack -L.../bin/../lib/gcc/avr/8.5.0/../../../../avr/lib/avr25/tiny-stack -L.../bin/../lib/gcc/avr/8.5.0 -L.../bin/../lib/gcc -L.../bin/../lib/gcc/avr/8.5.0/../../../../avr/lib main.o -v --start-group -lgcc -lm -lc -lattiny25 --end-group
其中
...
代表安装工具的绝对路径。正如您所看到的,驱动程序添加了一些盐,例如它链接到启动代码crtattiny25.o
、标准库,如libc.a
、libm.a
、libgcc.a
。 collect2
收集构建启动代码所需的一些额外信息,然后回调编译器1,最后ld
。
提供给
ld
的选项看起来非常类似于提供给 collect2
的选项。唯一特定于设备的东西是:启动代码 crtattiny25.o
和设备库 libattiny25.a
。 许多其他特定于设备的内容已经编译到代码中,例如 SFR 地址、#ifdef __AVR_ATtiny25__
等。
- 有什么方法可以使用
实现与使用avr-ld
生成 ELF 文件时相同的输出吗?avr-gcc
您可以手动提供所有这些选项。 尽管 在几乎所有情况下,您都希望使用
avr-gcc
进行链接,以便所有这些血淋淋的选项都是正确且完整的。
1自
-flto
起,LTO(链接时优化)需要回调编译器。 链接器调用一个插件,该插件使用 LTO 字节码调用编译器,将其编译为使用 LTO 编译器 lto1
进行汇编,然后是 as
,然后是 ld
。 该工具的新版本在没有 lto 编译时始终使用链接器插件;可以 -fno-use-linker-plugin
这使得调用链和选项更加简单。