烧录文件格式:Hex、Bin、S19、ELF 的区别与适用场景

做量产烧录这么多年,我见过不少工程师在文件格式上栽跟头。有人拿错格式,烧进去一片黑;有人搞不清地址映射,程序跑飞了还找不到原因。说白了,选对文件格式,是量产烧录的第一步,也是最容易被忽视的一步。

今天咱们就把 Hex、Bin、S19、ELF 这四种格式掰开揉碎讲清楚。我会结合自己踩过的坑,告诉你什么场景该用什么格式。

一句话总结:量产烧录只认 Hex 和 Bin,S19 偶尔用,ELF 是开发调试用的,别直接拿去烧录。

四种烧录文件格式对比 烧录文件格式 Hex Bin S19 ELF Hex (Intel HEX) ASCII文本格式 含地址+校验和 可分段烧录 Bin (Binary) 纯二进制数据 无地址信息 体积最小 S19 (SREC) Motorola格式 含地址+校验和 老式MCU常用 ELF 调试/链接格式 含符号表+调试信息 不用于量产烧录 量产烧录首选:Hex 或 Bin Hex 适合分段/非连续地址;Bin 适合连续地址、追求最小体积

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. 实际项目中的选择策略

说了这么多,到底怎么选?我根据自己的经验,给你几个实用建议:

  1. 新项目量产:用 Hex。校验和能防文件损坏,地址信息能灵活分段。大部分烧录器对 Hex 支持最好。
  2. 追求极致速度:用 Bin。如果 Flash 是连续烧录,Bin 的解析速度比 Hex 快 30% 以上。但一定要确认地址连续。
  3. 老项目维护:看原厂用什么。飞思卡尔/恩智浦的老片子经常用 S19,别强行转 Hex,容易出兼容性问题。
  4. 开发调试阶段:保留 ELF。调试完了,用 objcopy 转成 Hex 发给产线。

我的标准流程:开发用 ELF 调试 → 发布用 Hex 归档 → 产线用 Hex 烧录。Bin 只在特殊情况下使用,比如烧录 SPI Flash 或者需要最小文件体积的场合。

嗯,格式选择其实没那么复杂。记住一句话:量产烧录,Hex 是万金油,Bin 是快刀手,S19 是老古董,ELF 是幕后英雄。搞清楚它们的定位,你的烧录流程就能少踩一半的坑。