3. 生产文件与固件交付物
在 Silicon Labs 器件的量产环节,烧录工位真正“吃进去”的不是源代码,也不是 .out 调试文件,而是一组经过格式转换、地址裁剪、版本标识和校验确认的生产文件。理解这些文件的内部结构,是判断“烧录失败到底是文件问题还是硬件问题”的前提。本节围绕四种最常见的交付格式展开,并给出可直接落地的版本管理与交付包规范。
一、四种格式的本质差异:记录方式与地址表达
HEX、S37、BIN、GBL 的差别,核心只有两点:是否携带地址信息,以及是否携带校验与元数据。
- BIN(Raw Binary):纯粹的字节流,没有任何地址、长度、校验字段。烧录时必须由工具额外指定起始地址(如
0x00000000或 Bootloader 应用区偏移)。优点是体积最小、解析最快;缺点是地址信息完全依赖外部约定,一旦偏移填错,固件会被写到错误区域且工具不会报错。 - HEX(Intel HEX):ASCII 文本,按行组织,每行以
:开头,包含字节数、16 位地址、记录类型(00 数据 / 01 结束 / 02 扩展段地址 / 04 扩展线性地址 / 05 起始线性地址)和校验和。地址是自描述的,因此可以表达非连续段(如 Flash 主体 + 用户信息区 + 校准页)。 - S37(Motorola S-Record):同样是 ASCII 文本,记录以
S0/S1/S2/S3(数据,地址宽度递增)、S7/S8/S9(结束)标识。S3 支持 32 位地址,在 EFR32 这类大地址空间器件上比 S1/S2 更常用。与 HEX 相比,S37 的地址字段更直观,但工具链支持度略低。 - GBL(Gecko Bootloader File):Silicon Labs 自有格式,本质是带 GBL 头 + 应用信息区(App Info)+ 加密/签名封装的容器。它面向 OTA 与 Bootloader 升级场景,头部包含版本、类型(Application / Bootloader / 加密密钥等)、签名算法标识,因此 GBL 不只是“数据搬运”,还承担了版本识别与安全校验职责。
下面这张图对比了四种格式在“地址自描述、校验能力、版本元数据、典型使用场景”四个维度上的差异,可作为选型时的快速参照。
二、从 .out 到生产文件的转换与地址裁剪
以 Simplicity Studio / GCC 工具链为例,编译产物通常是 .out(ELF)。转换为生产文件时,关键动作是按区域裁剪,而不是整片导出。EFR32 典型 Flash 布局中,Bootloader 占 0x00000000 起的一段,应用从 0x00004000 或更高偏移开始,用户信息区(User Data / MFG 区)位于 Flash 末尾附近。
# 生成 HEX(保留地址信息,便于多段烧录)
arm-none-eabi-objcopy -O ihex app.out app.hex
# 生成 BIN(必须指定应用区起始地址)
arm-none-eabi-objcopy -O binary app.out app.bin
# 生成 S37(S3 记录,32 位地址)
arm-none-eabi-objcopy -O srec --srec-forceS3 app.out app.s37
# 生成 GBL(使用 Simplicity Commander,需指定应用信息与签名密钥)
commander gbl create app.gbl --app app.bin --sign key.pem
这里有一个极易踩坑的点:BIN 的起始地址必须与链接脚本中的 FLASH_ORIGIN 一致。若链接脚本把应用放在 0x00004000,而烧录脚本按 0x00000000 写入 BIN,结果是 Bootloader 被应用覆盖,设备上电后无法进入升级流程,且烧录工具会显示“成功”。因此产线脚本中,BIN 的烧录地址应作为参数显式配置,并与版本包中的 flash_map.json 对应。
三、固件版本管理:让每一片板子可追溯
版本管理不是给文件改个名字,而是建立“版本号 → 源码提交 → 构建产物 → 烧录记录”的链路。推荐做法:
- 版本号采用
主版本.次版本.修订号+构建号,例如1.4.2+20240612,构建号可用 Git 短哈希或日期。 - 在应用信息区(App Info)或固定 Flash 地址写入版本结构体,包含版本号、构建时间、Git 哈希、硬件兼容型号。GBL 的 App Info 天然支持这一机制,OTA 时 Bootloader 可据此拒绝降级或拒绝不匹配的硬件版本。
- 每次发布生成唯一的
manifest.json,记录各文件的 SHA-256,产线烧录后回读校验,比对哈希值。
四、生产文件包内容与交付规范
一个可直接交付给产线或代工厂的生产包,应包含以下内容,且目录结构固定、命名可解析:
| 文件/目录 | 作用 | 关键要求 |
|---|---|---|
app.hex / app.bin / app.s37 | 应用固件本体 | 三者内容一致,仅格式不同;BIN 需配套地址说明 |
bootloader.hex | Bootloader 固件 | 与应用区地址不重叠 |
app.gbl | OTA 升级包 | 签名密钥与设备内公钥匹配 |
mfg_data.hex | 制造信息区(序列号、校准值) | 按工位动态生成,不可预先固化 |
flash_map.json | 各区域起始地址与长度 | 与链接脚本、烧录脚本三方一致 |
manifest.json | 版本号、哈希、构建信息 | 含 SHA-256,供回读校验 |
README.txt | 烧录顺序与工具版本 | 注明 Commander / 烧录器固件版本 |
交付规范上还有三条硬性约定:其一,文件包只读冻结,发布后不得原地修改,任何变更必须升版本号重新出包;其二,禁止交付 .out 或含调试符号的 ELF,避免源码信息与调试接口被滥用;其三,GBL 与 BIN 不可混用同一烧录脚本,GBL 需经 Bootloader 解析,直接按 BIN 方式写入会导致头部被当作代码执行。
0x00000000 烧录,导致 Bootloader 被覆盖。防范措施是在 README 中明确“BIN 仅用于应用区,起始地址 0x00004000”,并在 manifest 中标注每个文件的适用烧录地址。把格式、地址、版本、校验四件事在交付包里一次性说清楚,产线才能做到“拿到包就能烧、烧完能验证、出问题能追溯”。这也是后续烧录工位脚本设计与测试治具开发的基础输入。