我有一个 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.py和 bin2hex.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/