烧录文件格式:Hex、Bin、S19、ELF 的区别与适用场景
做量产烧录这么多年,我见过不少工程师在文件格式上栽跟头。有人拿错格式,烧进去一片黑;有人搞不清地址映射,程序跑飞了还找不到原因。说白了,选对文件格式,是量产烧录的第一步,也是最容易被忽视的一步。
今天咱们就把 Hex、Bin、S19、ELF 这四种格式掰开揉碎讲清楚。我会结合自己踩过的坑,告诉你什么场景该用什么格式。
一句话总结:量产烧录只认 Hex 和 Bin,S19 偶尔用,ELF 是开发调试用的,别直接拿去烧录。
1. Hex 格式(Intel HEX)
Hex 是我在量产中最常用的格式。它本质上是 ASCII 文本,每一行都包含地址、数据和校验和。你想想看,用记事本打开 Hex 文件,能看到一行行以冒号开头的记录,这就是它的特征。
Hex 最大的好处是:它自带地址信息。这意味着你可以只烧录某个地址段的数据,不用管其他区域。我在做 OTA 升级时特别喜欢用 Hex,因为可以只更新应用区,不动 Bootloader。
我的习惯:只要烧录器支持,我优先选 Hex。原因很简单——校验和能帮我提前发现文件损坏,省得烧进去一堆废数据。
看一个典型的 Hex 记录格式:
:10000000FF0102030405060708090A0B0C0D0E0F0F0
:10001000101112131415161718191A1B1C1D1E1F20
:00000001FF
解释一下:
- 冒号开头:每条记录的标志
- 10:本行数据长度(16字节)
- 0000:起始地址
- 00:记录类型(00=数据,01=文件结束)
- 后面32个字符:16字节的原始数据
- 最后2个字符:校验和
注意:Hex 文件体积比 Bin 大约大 2-3 倍。如果你的 MCU 存储空间很紧张,或者烧录速度要求极高,Hex 的解析开销可能会成为瓶颈。
2. Bin 格式(Binary)
Bin 文件,说白了就是芯片里存的原始数据,一个字节不差。没有地址、没有校验、没有格式包装——就是纯粹的二进制内容。
我遇到过一位同事,非要用 Bin 烧录一个需要分段的程序,结果地址全乱了。为什么?因为 Bin 文件不记录地址,烧录器只能从起始地址连续往下写。如果你的程序在 Flash 里有空洞(比如 Bootloader 和 App 之间有保留区),Bin 就搞不定。
Bin 的适用场景很明确:
- 整个 Flash 连续烧录,没有空洞
- 对烧录速度要求极高(Bin 解析最快)
- 存储空间有限,需要最小文件体积
- 配合烧录器地址偏移功能使用
经验之谈:如果你用 Bin 格式,一定要确认烧录器的起始地址设置正确。我曾经因为地址偏移设错了,烧了 1000 片才发现——那叫一个惨。
3. S19 格式(Motorola S-record)
S19 是 Motorola 搞出来的格式,和 Hex 类似,也是 ASCII 文本,也带地址和校验。区别在于记录格式不同——S19 用 S 开头,而不是冒号。
我在做老款飞思卡尔 MCU 项目时经常碰到 S19。说实话,现在新项目用 S19 的越来越少了,但如果你维护的是 10 年以上的老产品,很可能还得跟它打交道。
S19 的记录类型:
| 记录类型 | 说明 | 地址长度 |
|---|---|---|
| S0 | 文件头(通常包含文件名) | 2字节 |
| S1 | 数据记录(16位地址) | 2字节 |
| S2 | 数据记录(24位地址) | 3字节 |
| S3 | 数据记录(32位地址) | 4字节 |
| S5 | 记录计数 | 2字节 |
| S7/S8/S9 | 文件结束 | 4/3/2字节 |
小技巧:如果你的烧录器同时支持 Hex 和 S19,我建议优先用 Hex。因为 Hex 的校验算法更简单,出错的概率更低。S19 的校验和计算方式容易把人绕晕。
4. ELF 格式(Executable and Linkable Format)
ELF 是编译器直接生成的格式。它包含的信息太多了——符号表、调试信息、重定位表、段信息……这些对调试来说非常有用,但对量产烧录来说,全是冗余。
我见过有人直接把 ELF 扔给烧录器,结果烧录器报错。为什么?因为 ELF 不是为烧录设计的。它需要经过 objcopy 或类似的工具转换成 Hex 或 Bin,才能用于量产。
ELF 的正确用法:
- 开发调试:GDB 调试必须用 ELF
- 生成烧录文件:从 ELF 提取 Hex/Bin
- 分析内存布局:查看段信息、符号地址
千万别干这事:直接把 ELF 文件发给产线烧录。产线的烧录工具大多不支持 ELF,就算支持,解析 ELF 也比 Hex 慢得多,严重影响产能。
5. 四种格式对比一览
| 特性 | Hex | Bin | S19 | ELF |
|---|---|---|---|---|
| 是否文本 | 是(ASCII) | 否(二进制) | 是(ASCII) | 否(二进制) |
| 含地址信息 | ✅ | ❌ | ✅ | ✅(段地址) |
| 含校验和 | ✅ | ❌ | ✅ | ❌ |
| 文件体积 | 中等 | 最小 | 中等 | 最大 |
| 解析速度 | 中等 | 最快 | 中等 | 最慢 |
| 支持分段烧录 | ✅ | ❌ | ✅ | ✅(需转换) |
| 量产烧录适用 | ✅ 首选 | ✅ 常用 | ⚠️ 老项目 | ❌ 不适用 |
6. 实际项目中的选择策略
说了这么多,到底怎么选?我根据自己的经验,给你几个实用建议:
- 新项目量产:用 Hex。校验和能防文件损坏,地址信息能灵活分段。大部分烧录器对 Hex 支持最好。
- 追求极致速度:用 Bin。如果 Flash 是连续烧录,Bin 的解析速度比 Hex 快 30% 以上。但一定要确认地址连续。
- 老项目维护:看原厂用什么。飞思卡尔/恩智浦的老片子经常用 S19,别强行转 Hex,容易出兼容性问题。
- 开发调试阶段:保留 ELF。调试完了,用 objcopy 转成 Hex 发给产线。
我的标准流程:开发用 ELF 调试 → 发布用 Hex 归档 → 产线用 Hex 烧录。Bin 只在特殊情况下使用,比如烧录 SPI Flash 或者需要最小文件体积的场合。
嗯,格式选择其实没那么复杂。记住一句话:量产烧录,Hex 是万金油,Bin 是快刀手,S19 是老古董,ELF 是幕后英雄。搞清楚它们的定位,你的烧录流程就能少踩一半的坑。