抱歉,这可能是离题。
在使用avr-gcc或avr-ld生成.hex(英特尔HEX格式)文件的过程中,输出(最终结果)明显不同。作为最低限度的澄清,我谈论的是在生成对象文件后生成ELF文件的步骤。
在我的第一次尝试中,我使用avr-ld
来生成我的ELF文件。过程运行顺利,但在生成十六进制文件并上传到我的板上后,它什么也没做(就像上传一个空白的十六进制文件一样)。
在我第二次尝试时,我按照建议找到了here:
在链接时指定MCU类型是很重要的。编译器使用-mmcu选项来选择链接在一起的启动文件和运行库。如果没有指定这个选项,编译器默认为8515处理器环境,这肯定是你不想要的。
它正如我所期望的那样。上传了十六进制文件,我的板子也相应地更新了。
所以我的问题如下:
1.为什么链接器(avr-ld
)丢失了我正在使用的微控制器的信息。我以为MCU信息存储在对象文件中。
1.这种配置背后的逻辑是什么?我的思维方式是错误的吗(使用avr-gcc
编译/生成.o文件,使用avr-ld
链接.o文件并生成EFL文件,使用avr-objcopy
只剥离有用的信息并更改文件格式ELF -〉HEX)?
1.使用avr-ld
是否可以获得与使用avr-gcc
生成ELF文件时相同的输出?
1条答案
按热度按时间a9wyjsp71#
1.为什么链接器(avr-ld)丢失了我正在使用的微控制器的信息。我以为MCU信息存储在对象文件中。
链接器不会丢失该信息,因为它从来没有在第一个位置提供过。目标文件和ELF头文件都在“仿真”级别,即粒度类似于
-mmcu=arch
,其中arch
是avr2
、avr25
、avrxmega2
、avrtiny
等之一。1.使用
avr-gcc
编译/生成.o文件,使用avr-ld
链接.o文件并生成ELF文件,使用avr-objcopy
仅剥离有用信息并更改文件ELF → HEX的格式?avr-gcc
不是编译器,它只是一个驱动程序,根据提供的文件类型和选项调用其他程序,如编译器本身cc1
或cc1plus
、汇编器as
、链接器ld
。驱动程序将向这些程序添加选项,这大大简化了它们的使用,其中许多在X1 M14 N1 X中描述(从V5开始)。例如,以main函数返回0的简单
main.c
为例,使用avr-gcc main.c -o main.elf -mmcu=attiny25 -save-temps -v -Wl,-v
个-v
使驱动程序显示它发出的命令,-save-temps
存储中间文件,如汇编文件。对于avr-gcc v8.5,链接过程以collect2
的调用开始:其中
...
代表安装工具的绝对路径。正如您所看到的,驱动程序添加了一些salt,例如它链接到启动代码crtattiny25.o
,标准库,如libc.a
,libm.a
,libgcc.a
。collect2
收集了一些构建启动代码所需的额外信息,然后回调编译器1,最后回调ld
。提供给
ld
的选项看起来与提供给collect2
的选项非常相似。启动代码crtattiny25.o
和设备库libattiny25.a
。许多其他特定于设备的内容已经编译到代码中,如SFR地址、#ifdef __AVR_ATtiny25__
等。1.使用
avr-ld
是否可以获得与使用avr-gcc
生成ELF文件时相同的输出?您可以手动提供所有这些选项。
1自
-flto
起,LTO(链接时优化)需要回调编译器。链接器调用一个插件,该插件使用LTO字节码调用编译器,然后使用LTO编译器lto1
、as
、ld
将其编译为汇编。该工具的较新版本在没有LTO编译时始终使用链接器插件;可以使用X1 M38 N1 X,这使得调用链和选项稍微简单一些。