尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
S19转HEX全攻略:从记录结构到srec_cat验证避坑
简介嵌入式固件交付中S19与HEX格式互转常被误以为只是改扩展名实则涉及地址扩展、校验和算法与启动地址等关键差异。Intel HEX以冒号开头、用04记录扩展64KB以上地址校验和采用二进制补码SRECS19则靠S1/S2/S3类型区分地址宽度校验和采用反码。理解这些底层原理才能安全使用srec_cat或hexview完成转换。实际场景中从产测线批量烧录到OTA打包转换后不验证就写入轻则数据错位重则固件不启动。本文梳理S19到HEX的四步转换流程结合srec_info识别、srec_cmp对比、启动地址核对等验证手段帮助嵌入式工程师建立一套可靠的固件交付检查习惯。1. hexview 不只是查看器S19 转 HEX 是嵌入式固件的日常必修课拿到一份 .s19 后缀的固件烧录器、量产夹具或 OTA 打包脚本却只认 .hex——这是嵌入式固件交付里经常卡住的一步。hexview 这类工具的价值正好卡在这里既能打开 HEX 文件按地址逐字节核对数据和启动地址也能把 S19SREC记录转换成 Intel HEX。很多人以为这只是换个扩展名实际上地址宽度、校验和算法、启动地址三处都容易翻车转完不验证就烧录板子可能直接不启动。下面从两种格式的记录结构讲起给出 srec_cat 转换的四步流程再拆开解析失败、启动地址丢失、64KB 地址错位几个高频坑。适合刚接手固件交付的嵌入式工程师也适合在产测线上被 S19 和 HEX 混用逼疯的同学。看完你能独立完成一次带验证的转换并在出问题时知道先查哪一行。2. 先看穿两种固件格式Intel HEX 与 S19 的记录差异2.1 Intel HEX 的记录行冒号、类型 00/01/04 和二进制补码校验和Intel HEX 是纯文本格式每行一条记录以冒号开头。除去冒号依次是字节数1 字节、地址2 字节、记录类型1 字节、数据N 字节、校验和1 字节。记录类型里最关键的是 00数据、01文件结束、04扩展线性地址、05启动线性地址。为什么需要 04 类型因为数据记录的地址字段只有 16 位最多表达 64KB。固件地址一旦超过 0xFFFF就必须先用一条 04 记录声明高 16 位地址后续数据记录里的 16 位地址才表示完整地址的低 16 位。所以 32 位地址空间的固件HEX 文件里每隔一段就会出现:02000004XXXXCC这样的行这是判断一个 HEX 文件是否完整支持高地址的关键特征。校验和用的是二进制补码把字节数、地址、类型、数据逐字节相加取累加和的低 8 位再用 0x100 减去这个值。换句话说整行所有字节含校验和相加后低 8 位应该等于 0。下面这条记录是地址 0x0000 处 16 字节数据的完整例子最后的校验和 0x68 可以用上面的算法手工核对一遍就明白所谓补码校验是怎么回事了。:100000000102030405060708090A0B0C0D0E0F10682.2 S19 的记录行S0/S1/S3/S9 的地址宽度和反码校验和S19SREC同样是一行一条记录的文本格式但以字母 S 开头后跟一位类型符。类型符决定了这条记录里地址占几个字节这是它与 Intel HEX 最本质的差异记录类型地址宽度用途S0无文件头通常带文件名或注释S12 字节16 位地址的数据记录S23 字节24 位地址的数据记录S34 字节32 位地址的数据记录S5无前面数据记录条数的计数S9 / S8 / S72 / 3 / 4 字节启动执行地址同样 16 字节数据在 S19 里对应一条 S1 记录S11300000102030405060708090A0B0C0D0E0F1064。类型符后的 0x13 是字节数它把地址、数据和校验和都算进去了所以数据长度要用 0x13 减去 2 字节地址再减 1 字节校验和得到 16。跟着是 4 位地址 0000然后 32 位十六进制数据最后 0x64 是校验和。S19 校验和与 Intel HEX 不同用的是反码把字节数、地址、数据逐字节累加对累加和的低 8 位取反。两种算法对同一条数据会得到不同结果这也是有人手工验算时老对不上的原因——拿 Intel HEX 的补码逻辑去套 S19怎么算都不对。2.3 转换的难点地址扩展记录和启动地址在两边写法不同对照两种格式可以总结出转换真正的难点。第一地址表达方式不同S19 直接用记录类型区分 16/24/32 位地址Intel HEX 靠 04 记录动态切换高 16 位。转换时必须根据 S1/S2/S3 的地址宽度生成对应的 04 记录否则下游工具会把所有数据当成低 64KB 地址处理。第二启动地址写法不同S19 的 S7/S8/S9 记录存放程序入口地址Intel HEX 里对应的是 03段地址和 05线性地址记录。不少简化转换工具会把数据行搬过来却把启动地址丢在一边表现就是烧录成功但不跑。第三校验和不能跨格式复用转换工具必须按目标格式重新计算而不是把原文件校验和照搬。理解了这三点后面用命令转换时你就知道该检查哪些输出特征了。3. 转换前先选对工具srec_cat、hexview 和格式识别3.1 三条路线怎么选命令行批处理 / 图形查看 / 自写脚本处理 S19 转 HEX 常见有三条路线。第一条是命令行工具 srec_cat它是最常用的格式转换命令支持几十种格式互转还带 -offset、-crop、-fill 这类地址操作。我一般优先用它因为可以直接嵌进 Makefile 或 CI 脚本输入输出稳定出错时有明确的行号提示。第二条是图形界面的 hexview 工具。它适合打开看一眼查看某段地址的数据、比对两个文件、确认启动地址。但用图形界面做批量转换不太顺手而且部分图形界面的另存为功能只做格式换壳不处理地址扩展转完 32 位文件往往跑不了。所以我的习惯是图形界面负责看命令行负责转。第三条是自写脚本。只有当手头机器装不了工具、或者要做的转换带特殊过滤逻辑比如只要某段地址区间时才值得写。常见做法是按 2.2 节的记录结构解析 S19再按 Intel HEX 规则拼行。这条路线最大的坑是容易漏掉 04 记录和启动地址后文避坑章节会细说。3.2 用 srec_info 识别文件类型和地址范围拿到 S19 文件先别急着转第一步应该确认它里面到底有哪些记录类型。srec_cat 的配套识别命令 srec_info 可以快速列出文件概况srec_info firmware.s19 -Multi这条命令会输出固件包含的记录类型清单、地址范围、数据长度和启动地址。参数说明firmware.s19是输入文件-Multi表示识别文件中的所有格式记录而不是遇到第一个不认识的记录就停下。如果这里显示的地址范围和你预期的芯片 Flash 地址段对不上先回去查编译链接配置不要带着错误地址往下转。读数时重点看两样一是地址范围是不是覆盖了预期区间二是 Execution Start Address 有没有值。启动地址为空转换后大概率也会丢入口后面烧录就会踩坑。另外要留个心眼偶尔会收到把二进制文件直接改名成 .s19 的文件srec_info 一读就报错这时候别硬转先让对方确认原始导出格式。3.3 hexview 打开固件后第一眼该检查什么用 hexview 打开 HEX 或 S19 文件后我一般按三个顺序检查。先看地址列地址是否按十六进制连续递增有没有跳变或回绕。再看十六进制数据区和编译输出的 map 文件比对关键段中断向量、CRC 值是否一致。最后看文件末尾Intel HEX 应该有一条:00000001FF结束记录S19 应该有 S7/S8/S9 启动记录。这三个检查能在 30 秒内暴露大部分转换问题。比如 32 位地址的固件数据却总是落在 0x0000xxxx 区间而 04 记录一条都没有那这份文件转出来基本是坏的。hexview 的窗口查看不修改文件适合在转换前和转换后各做一次快速目检。需要看某个具体地址时常见做法是在地址栏直接输入 0x08000000 这类完整地址定位光标会跳到对应行数据对不对一眼见分晓。4. S19 转 HEX 的四步流程从确认地址到批量脚本4.1 第一步确认 S19 记录类型与目标地址空间转换前用 srec_info 确认输入文件的记录构成srec_info firmware.s19 -Multi看输出里的记录类型如果全是 S116 位地址说明固件地址没超过 64KB转换最简单出现 S2 是 24 位地址常见于带中间层引导的工程S3 是 32 位地址对应大容量 Flash 芯片。地址范围决定目标 HEX 文件里 04 记录出现的频率也决定下游烧录工具按什么模式解析。同时确认目标地址空间。比如某芯片的内部 Flash 映射在 0x08000000那 S19 里的数据地址应该落在这个区间。如果看到地址从 0x00000000 开始且长度异常先回编译工程查链接脚本别急着转换。这一步花不了两分钟却能避免后面整条链路用错地址。4.2 第二步执行 srec_cat 转换命令与参数说明确认无误后执行转换最小命令只有一行srec_cat firmware.s19 -o firmware.hex -Intel参数说明firmware.s19是输入文件-o firmware.hex指定输出文件名-Intel声明输出格式为 Intel HEX。srec_cat 会自动按 S19 各记录类型解析地址宽度生成对应的 04 扩展记录并重新计算 Intel HEX 校验和这两处正是手工转换最容易错的地方。如果固件地址需要整体搬移比如量产工具只认 0 基地址要把 0x08000000 开头的地址平移到 0x00000000加一个 -offset 参数srec_cat firmware.s19 -offset -0x08000000 -o firmware_0000.hex -Intel注意 -offset 的符号目标地址减当前地址得到负值说明向左搬符号不能搞反。搬完后照例用 3.3 节的目检方法确认地址区间落在预期范围同时注意启动地址也需要重新核对。4.3 第三步转换后用 srec_cmp 做逐字节对比转换不等于完成验证才是。srec_cmp 可以对两个文件做逐字节比较返回 0 表示内容一致非 0 则打印差异位置srec_cmp firmware.s19 firmware.hex echo $?第一行执行比较第二行用echo $?查看退出码。srec_cmp 比较的是在各自地址上的数据内容所以即使两个文件格式不同、记录行组织方式完全不同只要每个地址上的字节一致就返回 0。这正是转换要保证的语义固件内容没丢。如果不方便用 srec_cmp退而求其次的做法是把两个文件都转成纯二进制再 diffsrec_cat firmware.s19 -o a.bin -Binary srec_cat firmware.hex -o b.bin -Binary cmp a.bin b.bin三行命令分别把两个格式转成二进制cmp逐字节比较。注意这个做法只能比较数据区启动地址信息在转二进制时已经不在文件里了所以仅凭 cmp 通过还不能断定完整仍需要看 srec_info 输出的启动地址。4.4 第四步批量转换整个目录的 shell 脚本产测场景里往往一次拿到几十个 S19 文件用循环脚本最省事for f in *.s19; do srec_cat $f -o ${f%.s19}.hex -Intel srec_info ${f%.s19}.hex -Intel | grep Execution Start || echo WARN: $f no start address done这段脚本对目录下所有 .s19 执行转换然后检查每个输出 HEX 的启动地址缺失就打印警告。参数说明${f%.s19}是 shell 的取后缀语法把firmware.s19换成firmware再加.hexgrep 那行把 srec_info 输出里的启动地址行筛出来||表示没匹配到就执行后面的警告输出。把这段存成 convert.sh配合 Makefile 的 target固件交付流程就能固定下来。文件上百个时还可以换成xargs -P并行跑但要注意输出文件名不能冲突。5. 转换避坑手册四个翻车现场的现象、原因与解法5.1 现象一srec_cat 报解析错误但文件在文本编辑器里正常现象执行 srec_cat 时报错提示某一行无法解析或校验和不对但用文本编辑器打开同一份 S19肉眼看着每一行都很规整。原因最常见的有三个文件是 Windows 换行CRLF混合了 Unix 换行LF文件开头带 UTF-8 BOMBOM 字符被当成记录第一个字符文件里混入了非 S 开头的调试输出行。srec_cat 对格式较真肉眼看不出来的 BOM命令一眼就拒收。解决先用file firmware.s19看编码再用dos2unix firmware.s19统一换行并去掉 BOM。如果文件里确实混了注释行常见做法是先过滤再转grep ^S firmware.s19 firmware_clean.s19 srec_cat firmware_clean.s19 -o firmware.hex -Intelgrep 只保留以 S 开头的行把杂质全部滤掉。注意这一步会丢弃 S0 头记录里的文件信息但不影响数据内容。处理完再跑一次转换通常就通过了。5.2 现象二转换成功但固件烧录后不启动现象转换命令执行成功对比命令也通过烧录器提示写入完成但板子不跑复位后没有任何反应。原因这类问题十有八九是启动地址丢了。当转换路径里经过二进制中间格式或者用了只搬运数据行的简化工具时S7/S8/S9 里的程序入口就没了bootloader 跳转不到正确位置。srec_cmp 比对的是地址上的数据内容启动地址这类元信息不一定能被它发现所以对比通过不能完全证明入口还在。解决转换后必查启动地址命令还是 srec_infosrec_info firmware.hex -Intel | grep -i Execution Start有输出说明入口还在没输出就要回到原始 S19 上确认入口并改用能保留入口的转换路径。srec_cat 直接做 S19 到 HEX 的转换会保留入口并写成 05 记录所以这个坑大多出现在走中间格式或手写转换的流程里。5.3 现象三地址超过 64KB 后数据错位高地址段全挤在低地址现象原本 32 位地址的固件转换后的 HEX 打开一看高地址空间的数据全都落在 0x0000~0xFFFF 这一段后面的数据把前面覆盖了。原因Intel HEX 的数据记录地址只有 16 位超过部分必须靠 04 扩展记录切换。转换工具如果没有为 S3 段生成 04 记录或者把 32 位地址直接截断成低 16 位就会发生数据全部挤进 64KB的错位。自己写脚本转换时最容易犯这个错因为肉眼检查数据行看不出地址被截断。解决检查输出文件里有没有 04 记录grep -c :02000004 firmware.hex输出 0 说明一条扩展记录都没有这个文件基本是坏的。正常的 32 位固件 HEX 里04 记录出现的次数取决于固件跨越了几个 64KB 块。确认缺少后改用 srec_cat 重新转换别手工修补——补 04 记录的同时要重算每条后续记录的位置关系非常容易二次出错。5.4 现象四多个 S19 合并后地址重叠烧录时校验失败现象把引导程序、应用、配置参数三份 S19 用 srec_cat 合并成一个 HEX转换没报错烧录时校验和却在某个地址段反复失败。原因三份文件各自定义了地址段如果两份文件的段有交叠合并后的 HEX 在同一地址出现两份不同数据。srec_cat 在合并时对重叠地址的处理策略和警告方式不同有的直接报错有的默默保留后写入的很容易漏过去。解决合并前先用 srec_info 分别看三份文件的地址范围确认没有交叠。需要裁剪时用 -crop 限定区间srec_cat app.s19 -crop 0x08000000 0x0801FFFF \ config.s19 -crop 0x08020000 0x08020FFF \ -o merged.hex -Intel-crop 起始 结束把输入限制在指定地址区间内两段区间不重叠就安全了。注意 -crop 的半开区间语义结束地址本身不包含在内写边界时留出 1 字节余量更稳妥。合并后照例跑一遍对比命令确认数据和原始文件一致。6. 最后一公里反向转换与启动地址核对确认固件没丢数据转完、坑也排完交付前我固定会跑一组反向验证。做法是把刚生成的 HEX 再转回 S19和原始 S19 做一遍对比srec_cat firmware.hex -o firmware_roundtrip.s19 -Motorola srec_cmp firmware.s19 firmware_roundtrip.s19第一次执行 srec_cmp 若返回 0说明正向转换和反向转换两条链路对每个地址上的字节都一致如果返回非 0它会打印第一个差异地址和两边该地址的值直接定位到是哪一段出了问题。这个来回能同时兜住 04 记录生成、校验和重算、数据截断几类最隐蔽的问题比单独看一遍文件内容可靠得多。启动地址的核对单独走一条命令。srec_cat 把 S7/S8/S9 转成 Intel HEX 时32 位入口对应的是 05 记录grep :04000005 firmware.hex有输出且值等于芯片复位入口地址入口就保住了没匹配到行回头查转换路径里是不是经过了二进制中间格式。04 记录和 05 记录一个管地址扩展、一个管程序入口转换后这两类行各确认一次固件才算真正搬好家。这两条命令我固定放在 Makefile 的 convert target 尾部每次换固件交付自动执行验证失败就中断整个流程。养成这个习惯后已经很久没再收到转换后板子不跑的反馈。转换不是换扩展名而是带着校验和与入口地址的一次搬运验证过了才算完成希望帮到你。本文还有配套的精品资源点击获取
RELATED

相关推荐

基于STM32的智能农业大棚控制系统:从需求到落地

基于STM32的智能农业大棚控制系统:从需求到落地

做农业大棚控制系统这件事,我最早是接到一个很实际的需求才入的坑。那会儿有个做蔬菜种植的朋友,承包了几亩地的连栋大棚,每天最头疼的事情就是半夜气温骤降没人去手动掀膜,或者夏天中午棚内温度飙到四十多度才发现风机没开。他一…

📅 2026/10/20 7:14:35
Go并发编程核心:从Goroutine调度到GMP模型与高并发实践

Go并发编程核心:从Goroutine调度到GMP模型与高并发实践

如果你写过一段时间 Go,一定对go关键字不陌生。一个go func()丢进去,函数就跑起来了,程序看起来确实“并发”了。但 Goroutine 到底凭什么能支撑几十万、上百万级别的并发,为什么有人用它写并发代码会频繁死锁,为什么一…

📅 2026/10/20 7:14:35
RK3576 NPU边缘部署实战:图像分类模型量化、性能与工程优化全解析

RK3576 NPU边缘部署实战:图像分类模型量化、性能与工程优化全解析

做边缘端模型部署的朋友应该都有同感:模型在服务器上精度再高,到了芯片上跑不动或者掉点严重,一切都白搭。这次记录的是我在 RK3576 平台上做的一组主流图像分类模型部署实验,从模型选型、量化转换、精度对比到多核调度和工程化改…

📅 2026/10/20 7:14:35
MORE NEWS

更多资讯

📰

财务数据统计分析报告PPT模板:从数据到汇报的最后一公里

简介:这是一套面向财务、会计从业者及企业数据分析人员的微立体风格统计分析报告PPT模板,适用于月度经营汇报、季度财务复盘、年度数据总结等场景,帮助使用者快速搭建结构清晰、视觉专业的演示文稿,无需从零设计版式。压缩包共3个…

📰

我用 Dify + 本地大模型搭了个发票识别 Agent:开发过程全记录 + 完整文件分享

摘要:本文完整记录了一个基于 Dify 工作流 Ollama 本地视觉模型(qwen2.5vl:7b)搭建的增值税发票识别 Agent 的开发全过程。全本地运行、不联网、不上传、零 API 成本,输出结构化 JSON 并附带自动校验报告。文章详细拆解了 8 节点…

📰

Axure交付级原型元件库:毕设课设高效产出与答辩高分指南

简介:本资源是一套面向Axure RP产品设计师与交互原型开发者的高实用性元件库合集,适用于Web端、移动端中高级原型设计场景,可显著提升低保真与高保真原型搭建效率,降低重复绘图与交互配置成本。压缩包共732个文件,涵盖…

📰

Axure生产级元件库:容器-控件-行为三层解耦设计

简介:本资源是一套面向Axure RP用户的产品原型设计高效赋能工具包,特别适合交互设计师、产品经理及UI/UX初学者快速构建高保真原型。合集整合了732个即用型元件资源,涵盖400个PNG格式图标与控件切图、85个HTML页面模板、86个CSS样式表&#x…

📰

Axure生产级原型元件库:支持变量/中继器/动态面板的可交互组件集合

简介:本资源是一套面向Axure RP用户的产品原型设计高效赋能工具包,特别适合交互设计师、产品经理及UI/UX初学者快速构建高保真原型。合集整合了732个即用型元件资源,涵盖400个PNG格式图标与控件切图、85个HTML页面模板、86个CSS样式表&#x…

📰

kubeadm部署Kubernetes V1.21.1集群:从零搭建到故障排查全指南

接手过各种规模的K8s环境,从单机实验到生产集群都踩过一遍坑之后,我必须说:kubeadm依然是现阶段部署 Kubernetes 最省心、最不容易把自己绕晕的路径,尤其是 2021 年发布的 V1.21.1 这个版本,处于容器运行时切换的关键过…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬