将Objcopy的elf文件转换为bin文件

9
我有一块STM32F404开发板,正在尝试进行烧录。我正在遵循这个教程:tutorial
在这个项目的Makefile中。
$(PROJ_NAME).elf: $(SRCS)
    $(CC) $(CFLAGS) $^ -o $@ 
    $(OBJCOPY) -O ihex $(PROJ_NAME).elf $(PROJ_NAME).hex
    $(OBJCOPY) -O binary $(PROJ_NAME).elf $(PROJ_NAME).bin

burn: proj
    $(STLINK)/st-flash write $(PROJ_NAME).bin 0x8000000

该bin文件是使用OBJCOPY生成的,然后使用Make目标burn进行刷写。

我的问题:

问题1:在这种情况下,OBJCOPY=arm-none-eabi-objcopy是什么意思。我打开了man,但我没有完全理解,有人能简单地解释一下吗?

问题2:刷写bin文件会得到预期的结果(LED闪烁)。然而,通过刷写elf文件$(STLINK)/st-flash write $(PROJ_NAME).elf 0x8000000,LED不会闪烁,为什么?

2个回答

14
问题1:在这种情况下,OBJCOPY=arm-none-eabi-objcopy是什么意思?我查看了手册,但我没有完全理解,请问有人能简单解释一下吗?
它将值"arm-none-eabi-objcopy"分配给"make"变量"OBJCOPY"。
当"make"执行此命令时:
$(OBJCOPY) -O binary $(PROJ_NAME).elf $(PROJ_NAME).bin

实际运行的命令是actual

arm-none-eabi-objcopy -O binary tim_time_base.elf tim_time_base.bin
问题2: 刷写bin文件会得到预期结果(LED灯闪烁),但是刷写elf文件$(STLINK)/st-flash write $(PROJ_NAME).elf 0x8000000后,LED灯不闪烁,为什么? tim_time_base.elf是一个ELF文件--它带有元数据。运行arm-none-eabi-readelf -h tim_time_base.elf查看其中一些元数据。
当处理器在复位后跳转到位置0x8000000时,它希望找到可执行的指令,而不是元数据。当它发现它不理解的“垃圾”时,可能会停止。它肯定找不到让灯闪烁的指令。

谢谢@Employed Russian,关于问题1,问题的目的是更详细地解释objcopy的工作原理。 - Mouin
objcopy 如何将此元数据转换为二进制文件中的内容? - Mouin
@Mouin 通常情况下不需要。它对程序的执行没有必要性,因此会被丢弃。 - Lennon McLean
这对我非常有效!如果您使用Windows,这是下载objcopy的链接:https://www.pemicro.com/blog/index.cfm?post_id=35 - Spencer McDonough

1
如果有人想要使用DFU(“固件升级”)功能,本教程将教您如何在STM32使用USB Host(或者说OTG)操作时通过二进制文件加载来使用USB。

STM32 USB training - 11.3 USB MSC DFU host labs

这个教程是一系列视频的一部分,强烈建议程序员观看,以更好地了解STM32 USB端口的工作和使用方式(这些视频由STM32制造商提供,我建议程序员观看该频道上的所有视频)。

MOOC - STM32 USB training

注意:STM32教程中的示例代码可在视频描述中获得。
可以通过同事Employed Russian解释的命令来获取二进制文件(*.bin),并且该命令也可以适应生成包含CRC使用比较值的文件,有关详细信息请参见以下帖子。

实践:CRC 校验和生成

Srec_cat 可以用于生成 CRC 校验和并将其放入 HEX 文件中。为了简化流程,请将 srec_cat.exe 放置在项目文件夹的根目录中。

关于 CRC 使用的一些提示和解决方案(Windows/Linux)

不幸的是,代码量太大了,无法直接在这里发布,但我会在下面留下与其他答案相关的代码:

arm-none-eabi-objcopy -O ihex "${BuildArtifactFileBaseName}.elf" "${BuildArtifactFileBaseName}.hex" && ..\checksum.bat ${BuildArtifactFileBaseName}.hex

checksum.bat 文件的内容:

#!/bin/bash

# Windows [Dos comment: REM]:
#..\srec_cat.exe %1 -Intel -fill 0xFF 0x08000000 0x080FFFFC -STM32 0x080FFFFC -o ROM.hex -Intel

# Linux [Linux comment: #]:
srec_cat $1 -Intel -fill 0xFF 0x08000000 0x080FFFFC -STM32 0x080FFFFC -o ROM.hex -Intel

注意:在这种情况下,要写入的文件是ROM.hex(您需要配置STM32CubeIDE才能执行此操作,IDE使用*.elf文件,请参见上面的提示了解如何执行此操作)
另一个教程涉及使用具有*.DFU扩展名的文件: DFU - DfuSe DFU Bootloader的主要优点是:无需特定工具,如JTAG、ST-LINK或USB-to-UART电缆。通过USB在新组装的板上编程“空”STM32设备的能力。并且可以在开发或预生产期间轻松升级STM32固件。
使用HEX文件的需求简化了实现带有CRC值生成的ROM.hex文件的操作,几乎是连续的:
您必须从.HEX或.S19文件生成.DFU文件,以执行此操作,请使用DFU文件管理器。
但是看起来使用*.DFU文件并不像使用*.BIN文件那样独立,因此我找到了另一段代码,它将带有CRC的HEX文件转换为*.BIN文件,可以按照本答案开头引用的教程(11.3 USB MSC DFU host)使用USB闪存驱动器:

objcopy --input-target=ihex --output-target=binary code00.hex code00.bin

来源

听起来有点混乱,但我们可以按照以下步骤进行操作:

1- STM32CubeIDE生成*.elf文件。

2- 编译后,*.elf文件被转换为*.hex文件。

3- 通过srec_cat应用程序在*.hex文件中添加CRC值。

4- 现在将*.hex文件转换为*.bin文件。

5- 然后将BIN文件存储在USB闪存驱动器上。

6- STM32使用USB闪存驱动器文件更新固件。

要使用*.BIN文件,必须先将STM32编程加载BIN文件。如果未编程(STM32为空、未烧录或程序未制作为加载BIN文件),则需要使用St-Link或其他编程器,或者可能需要使用上述教程中描述的DFU方法(DFU-DfuSe)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接