简介:这是一款面向嵌入式开发者的BIN与HEX文件互转合并工具,基于对话框程序实现,适合需要处理单片机固件格式转换的工程师使用。工具支持BIN转HEX、HEX转BIN以及HEX文件合并三类操作,并针对实际使用中的典型问题做了持续修正:20230205版本将转HEX时输入的A~F字符统一为大写,避免Keil使用出错;20230215版本修复了BIN文件超过64K时数据错乱的问题;20230709版本解决了C8051所用Keil编译的HEX文件转BIN时的错误。资源包共22个文件,包含5个h头文件、4个cpp源文件、2个exe可执行程序以及txt说明文档、rc资源脚本、ico图标等,压缩包约654KB,源码结构清晰,可直接编译或运行。目前已有3664人学习下载,适合需要快速完成固件格式转换、排查转换异常或参考对话框程序实现的开发者自取使用。
1. 烧录前的格式焦虑:BIN 和 HEX 到底谁在管地址
做嵌入式烧录的人多半遇到过这种场景:从产线拿回来一个.bin,想用仿真器下载,结果工具只认.hex;或者从 IDE 导出一个.hex,想丢给量产工具批量刷写,对方偏偏只吃.bin。两个文件明明描述的是同一段固件,却因为格式不同卡在门口。BIN 和 HEX 的互转与合并,就是解决这类"格式不对口"的基础操作,也是固件打包、OTA 差分、多区固件拼接绕不开的一环。它适合刚接触 MCU 烧录的新手,也适合需要把 bootloader、app、参数区拼成一个镜像的熟手。这篇就把转换和合并的规则、命令、参数和坑一次讲透,让你拿到任意一种格式都能自己动手处理。
2. 先搞懂 BIN 与 HEX 的地址模型:为什么不能直接拼接
2.1 BIN 是纯字节流,地址靠外部约定
BIN 文件本质上就是一段连续的二进制字节,文件里不包含任何地址信息。第 0 个字节对应哪个 Flash 地址,完全由烧录工具或链接脚本约定。常见做法是:烧录时手动指定起始地址,比如0x08000000,工具就从这里开始把字节一个个写进去。
这带来一个直接后果:两个 BIN 文件不能简单用cat拼在一起。因为拼接后第二个文件的起始地址变成了第一个文件的结束地址,而你真正想要的往往是第二个文件落在另一个固定地址(比如参数区0x08080000)。所以 BIN 的"合并"必须先知道每段的加载地址,再按地址填充空隙,而不是首尾相接。
2.2 HEX 自带地址记录,天然支持多段
HEX 文件(Intel HEX 格式)是文本文件,每行是一条记录,格式大致是:
:LLAAAATT[DD...]CCLL:本行数据字节数AAAA:16 位地址TT:记录类型,00数据、01结束、02扩展段地址、04扩展线性地址DD:实际数据CC:校验和
关键在TT=04的扩展线性地址记录,它把地址高 16 位抬起来,于是 HEX 能表达 32 位地址空间,并且允许数据在地址上不连续。也就是说,一个 HEX 里可以同时存在0x08000000的 bootloader 和0x08080000的参数区,中间的空洞不需要填充。这正是 HEX 适合多区固件的原因,也是它转 BIN 时必须处理空洞的原因。
2.3 转换方向决定了你要不要补 0xFF
理解了两者模型,转换的难点就清楚了:
- HEX 转 BIN:要把地址不连续的部分用填充字节补齐,否则 BIN 里两个区会挨在一起,烧进去地址全错。
- BIN 转 HEX:要告诉工具这段 BIN 的起始地址,工具才能生成正确的地址记录。
- 合并:HEX 合并可以直接按地址叠加;BIN 合并必须先转成带地址的中间形态,或者用工具指定每段的偏移。
填充字节通常是0xFF,因为 Flash 擦除后的状态就是全 1,用0xFF填充不会破坏未写区域。这一点在后面的命令里会反复出现。
3. 用 srec_cat 做转换与合并:一条命令覆盖四种场景
3.1 工具选型:为什么优先 srec_cat
能处理 BIN/HEX 的工具不少,比如objcopy、hex2bin、各家 IDE 自带的小工具。但如果要同时做转换和合并,srec_cat是最省事的:它属于 SRecord 工具集,跨平台,命令行参数清晰,支持 Intel HEX、Motorola S-record、BIN、甚至带地址的文本格式。常见做法是用它做固件打包流水线里的格式归一化。
安装方式按平台来,Linux 下一般包管理器直接装:
# Debian/Ubuntu 系 sudo apt-get install srecord # macOS brew install srecord # Windows 可从官网下载预编译包,解压后把目录加入 PATH装完执行srec_cat --version能打印版本就说明可用。下面所有命令都基于这个工具。
3.2 HEX 转 BIN:指定输出格式和填充值
最基础的转换:
# 把 input.hex 转成 output.bin # -o 指定输出文件,-binary 声明输出为纯二进制 srec_cat input.hex -intel -o output.bin -binary逻辑说明:input.hex -intel告诉工具输入是 Intel HEX 格式;-o output.bin -binary指定输出为二进制。工具会自动扫描 HEX 里的地址范围,从最低地址到最高地址输出,中间不连续的部分默认用0x00填充。
这里就是第一个坑:默认填充是0x00,不是0xFF。如果你的 Flash 擦除态是0xFF,用0x00填充会在空洞区域写入 0,烧录后可能影响未使用区域的读取。正确做法是显式指定填充值:
# -fill 0xFF 指定空洞填充字节 # 后面跟的是填充范围的起止地址,通常覆盖整个地址空间 srec_cat input.hex -intel -fill 0xFF 0x00000000 0xFFFFFFFF -o output.bin -binary参数说明:-fill 0xFF 0x00000000 0xFFFFFFFF表示在0x00000000到0xFFFFFFFF范围内,凡是 HEX 没覆盖到的地址都填0xFF。实际使用时把范围收窄到你的 Flash 实际地址区间更稳妥,避免生成超大文件。
3.3 BIN 转 HEX:必须显式给起始地址
BIN 没有地址信息,所以转换时必须告诉工具这段数据从哪开始:
# 把 input.bin 当作从 0x08000000 开始的数据,转成 Intel HEX srec_cat input.bin -binary -offset 0x08000000 -o output.hex -intel逻辑说明:input.bin -binary声明输入是纯二进制;-offset 0x08000000是关键,它把 BIN 的第 0 字节映射到地址0x08000000;-o output.hex -intel输出 Intel HEX。
参数说明:-offset的值必须和你的链接脚本或烧录地址一致。如果 BIN 是从0x08004000开始的 app 区,这里就要写0x08004000。写错了烧进去就是跑飞,而且这种错误在 HEX 里看不出来,只有烧录后才暴露。
3.4 合并多段固件:按地址叠加而不是首尾相接
假设你有 bootloader 在0x08000000,app 在0x08004000,参数区在0x08080000,想把它们合成一个 HEX:
# 三段 BIN 按各自地址合并成一个 HEX srec_cat \ boot.bin -binary -offset 0x08000000 \ app.bin -binary -offset 0x08004000 \ param.bin -binary -offset 0x08080000 \ -o merged.hex -intel逻辑说明:srec_cat支持多个输入段,每段用-offset指定自己的加载地址,工具会按地址把它们放到同一个地址空间里,重叠部分会报错,空洞部分在输出 HEX 时不填充(因为 HEX 允许地址不连续)。
参数说明:如果两段地址有重叠,srec_cat默认会报错并退出,这是好事,能防止你无意中覆盖数据。如果确实需要后一段覆盖前一段,可以加-contradictory选项,但一般不建议,因为覆盖行为容易埋雷。
如果输入本身就是 HEX,合并更简单,不需要-offset:
# 两个 HEX 直接按地址合并 srec_cat boot.hex -intel app.hex -intel -o merged.hex -intel3.5 合并后转 BIN:注意空洞填充和文件体积
合并成 HEX 后如果要转 BIN 给量产工具:
# 合并后转 BIN,空洞填 0xFF srec_cat merged.hex -intel -fill 0xFF 0x08000000 0x080FFFFF -o merged.bin -binary这里要特别注意填充范围。如果范围写成0x00000000到0xFFFFFFFF,生成的文件会大到无法处理。正确做法是填你的 Flash 实际区间,比如0x08000000到0x080FFFFF,这样文件大小就是 Flash 容量,量产工具能正确识别。
4. 避坑与排查:转换合并里最容易翻车的五件事
4.1 转出来的 BIN 比预期大很多
现象:一个几十 KB 的 HEX 转成 BIN 后变成几 MB。
原因:HEX 里存在高地址的零散记录(比如配置字在0x1FFFF800),srec_cat从最低地址到最高地址输出,中间全部填充,文件自然膨胀。
解决:用-fill限定填充范围,或者先用-crop裁掉不需要的地址段:
# 只保留 0x08000000 到 0x0807FFFF 范围 srec_cat input.hex -intel -crop 0x08000000 0x0807FFFF -o output.bin -binary4.2 烧录后程序跑飞,地址对不上
现象:转换后的文件烧进去,MCU 不运行或 HardFault。
原因:BIN 转 HEX 时-offset写错,或者 HEX 转 BIN 时没指定起始地址,烧录工具按默认地址写入。
解决:核对链接脚本里的FLASH ORIGIN,确保-offset和它一致。烧录前用srec_info查看 HEX 的地址范围:
# 查看 HEX 文件的地址分布 srec_info input.hex -intel输出会列出每段的起止地址,对照链接脚本确认无误再烧。
4.3 合并时提示地址重叠
现象:srec_cat报错contradictory或地址冲突。
原因:两段固件的地址范围有交集,常见于 app 区大小算错,或者 bootloader 预留空间不够。
解决:先用srec_info分别查看各段的地址范围,确认没有交集。如果确实需要覆盖,检查是不是链接脚本的区间划分有问题,而不是急着加-contradictory掩盖。
4.4 填充值用了 0x00 导致参数区异常
现象:合并后的固件烧录,参数区读出来全是 0,而不是默认值。
原因:HEX 转 BIN 时默认填充0x00,把本该是0xFF的擦除态写成了 0。
解决:所有转 BIN 的命令都显式加-fill 0xFF,并且填充范围覆盖整个 Flash 区间。这是血泪经验,默认值坑过不少人。
4.5 Windows 下路径和换行符问题
现象:在 Windows 命令行里执行srec_cat报找不到文件,或者生成的 HEX 在某些工具里解析失败。
原因:路径里有空格没加引号,或者输出 HEX 的换行符是\n而某些老工具只认\r\n。
解决:路径统一加引号;如果遇到换行符问题,可以在srec_cat输出后用一个简单脚本转换,或者直接用支持\n的烧录工具。常见做法是在流水线里统一用 Linux 环境处理,避免这类平台差异。
5. 进阶技巧:用脚本把转换合并串成可复现的流水线
单次转换用命令行就够了,但如果你经常要处理多区固件,手动敲命令迟早会出错。我一般会写一个打包脚本,把地址配置抽成变量,转换和校验一步到位。下面是一个可复现的模板:
#!/bin/bash # firmware_pack.sh - 多区固件打包脚本 set -e # 任何一步失败就退出,避免生成半成品 # 地址配置,按实际链接脚本修改 BOOT_ADDR=0x08000000 APP_ADDR=0x08004000 PARAM_ADDR=0x08080000 FLASH_START=0x08000000 FLASH_END=0x080FFFFF # 输入文件 BOOT_BIN=boot.bin APP_BIN=app.bin PARAM_BIN=param.bin # 第一步:合并成 HEX,按地址叠加 srec_cat \ "$BOOT_BIN" -binary -offset $BOOT_ADDR \ "$APP_BIN" -binary -offset $APP_ADDR \ "$PARAM_BIN" -binary -offset $PARAM_ADDR \ -o merged.hex -intel # 第二步:转成量产用的 BIN,空洞填 0xFF srec_cat merged.hex -intel \ -fill 0xFF $FLASH_START $FLASH_END \ -o merged.bin -binary # 第三步:打印地址信息,人工核对 echo "=== merged.hex 地址分布 ===" srec_info merged.hex -intel echo "=== 输出文件 ===" ls -lh merged.hex merged.bin逻辑说明:脚本用set -e保证任何一步失败立即停止,不会留下半成品。地址全部抽成变量放在开头,换项目只改这几行。第三步用srec_info打印地址分布,是最后一道人工核对,确认每段落在预期地址再交付。
参数说明:FLASH_START和FLASH_END决定最终 BIN 的大小,填成实际 Flash 容量即可。如果 Flash 是 512KB,FLASH_END就是0x0807FFFF;1MB 则是0x080FFFFF。这个值写错会导致 BIN 过大或截断。
再补一个校验习惯:转换完成后,把生成的 BIN 再转回 HEX,和原始 HEX 做地址范围对比。如果两者地址分布一致,说明转换没有丢数据或错位。这个反向验证花不了几秒,但能挡住大部分低级错误。
从那以后我每次打包固件,都强制走一遍"合并 → 转 BIN → 反向转 HEX → 对比地址"的流程,再急也不跳过。希望帮到你。
本文还有配套的精品资源,点击获取