使用 GCC 生成连续的 Hex 文件

标签 c gcc stm32 bootloader hex-file

我有一个 STM32F427 的 Hex 文件,该文件是使用 GCC(gcc-arm-none-eabi) 版本 4.6 构建的,具有连续的内存地址。我编写了引导加载程序来加载该十六进制文件,并添加了校验和功能以确保在启动应用程序之前十六进制文件正确。 十六进制文件片段:

:1005C80018460AF02FFE07F5A64202F1D00207F5F9 :1005D8008E4303F1A803104640F6C821C2F2000179 :1005E8001A460BF053F907F5A64303F1D003184652 :1005F8000BF068F907F5A64303F1E80340F6FC1091 :10060800C2F2000019463BF087FF07F5A64303F145 :10061800E80318464FF47A710EF092FC07F5A643EA :1006280003F1E80318460EF03DFC034607F5A64221 :1006380002F1E0021046194601F0F2FC07F56A5390

如您所见,所有地址都是连续的。然后我们将编译器更改为 4.8 版本,我得到了相同类型的 Hex 文件。

但是现在我们使用编译器版本6.2,生成的Hex文件不连续。有点像这样:

:10016000B9BC0C08B9BC0C08B9BC0C08B9BC0C086B
:10017000B9BC0C08B9BC0C08B9BC0C08B9BC0C085B
:08018000B9BC0C08B9BC0C0865
:1001900081F0004102E000BF83F0004330B54FEA38
:1001A00041044FEA430594EA050F08BF90EA020FA5

正如您所看到的,在 0188 之后,它从 0190 开始,意味着其余 8 个字节(0189 到 018F)都是 0xFF,因为它们没有闪烁。

现在引导加载程序有点愚蠢,我们只传递起始地址和字节数来计算校验和。

有没有办法像编译器 4.6 和编译器 4.8 那样以连续的方式制作十六进制文件?这三次的代码都是相同的。

最佳答案

如果可以选择对十六进制文件进行后处理,则可以考虑使用 IntelHex python 库。这使您可以操作十六进制文件数据(即忽略“标记”;记录类型、地址、校验和等)而不是作为行,例如将使用正确的行校验和创建输出。

启动并运行此程序的快速方法可能是使用捆绑的便利脚本 hex2bin.pybin2hex.py :

python hex2bin.py --pad=FF noncontiguous.hex tmp.bin
python bin2hex.py tmp.bin contiguous.hex

第一行将输入文件 noncontigously.hex 转换为二进制文件,在没有数据的地方用 FF 填充。第二行将二进制文件转换回十六进制文件。

结果是

:08018000B9BC0C08B9BC0C0865

变成了

:10018000B9BC0C08B9BC0C08FFFFFFFFFFFFFFFF65

如您所见,在输入没有任何数据的地方添加填充字节,相当于将输入文件写入设备并将其读回。输入文件中的字节保持相同 - 并且位于相同的地址。 校验和也是正确的,因为将长度字节从 0x08 更改为 0x10 可以补偿额外的 0xFF 字节。如果您用其他内容填充,IntelHex 将输出正确的校验和

您可以通过管道传输这些内容来跳过临时文件的创建:在第一行中省略 tmp.bin 并在第二行中将其替换为 -:

python hex2bin.py --pad=FF noncontiguous.hex | python bin2hex.py - contiguous.hex

另一种方法可能是拥有一个包含所有 FF 的基本文件,并使用 hexmerge.py 便捷脚本将 gcc 的输出与 -- 合并到该文件上重叠=替换

更长、更灵活的方法是使用 IntelHex API 实现您自己的工具。我在与您类似的情况下使用了此方法,效果良好 - 调整十六进制文件以满足更改成本高昂的工具,但仅按照编写工具时的方式处理十六进制文件。

关于使用 GCC 生成连续的 Hex 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49901363/

相关文章:

c - 知道初始地址的指针的地址

C 预处理器 - 标记粘贴 - 令人困惑的结果。这是为什么?

stm32 - 如何在没有 STLINK 的情况下刷机

c - 根据内存位置的特定值定义值

c - 执行c程序时出现段错误

c - dup2 是在 linux 终端中模拟命令序列行为的正确方法吗?

c - mingw32 显示对所有 gtk 函数的 undefined reference

c++ - gcc 和 cpp 中的 "foreach values"宏

c - GCC 标准优化行为

c++ - stm32f4-eval2板的keil中的printf