资讯动态

srec_cat合并HEX文件实战:从bootloader到固件烧录的完整方案

发布时间:2026/9/2 2:57:57 来源:尧图企业网站定制
简介srecord-1.65.0-win64是一款面向嵌入式与单片机开发者的HEX文件合并工具基于开源srecord项目为Windows 64位环境构建专门解决KEIL MDK等IDE生成多个HEX文件后需整合烧录的难题。软件支持地址冲突检测、重复数据处理、输出格式控制也适配跨平台工作流适合中高级嵌入式工程师在固件更新、项目部署时使用。资源包共2000个文件约17.91MB包含exe和dll可运行程序与运行库、h头文件与map映射辅助二次开发、html/js/css离线文档、png示意图、md5校验文件等目录结构完整便于查阅和集成。目前已有119人学习。解压后可直接在Windows 64位环境使用既能通过命令行高效批量合并工程模块也为需要深度定制或研究HEX处理流程的开发者提供了官方文档、源码头文件与示例资源可显著减少烧录时间并提高项目可维护性。1. 项目概述srecord 是干嘛的为什么偏偏要合并 HEX做嵌入式开发、单片机烧录、bootloader 调试免不了跟 HEX 文件打交道。ST 官网下的扩展包、Keil 编译出来的 .hex、IAR 导出的 .srec各有各的写法。项目一多合并、拆分、补数据、改校验就全都堆在眼前。srecord-1.65.0-win64 就是 Windows 下处理这类文件的利器这一版是官方打包好的 64 位可执行程序解压即用不需要装 Python不需要开虚拟机打开命令行就能干活。有人可能会问Keil 里不是能直接生成一个 hex 吗为什么还要单独合并我遇到最多的场景是 bootloader 和 app 分开编译。boot 区放在低地址app 区从高地址启动两段程序本来各自下载但生产线上想用一根串口线把整体固件烧进去就得先把两个 hex 拼成一个。还有的情况是多个驱动的初始化数据分散在不同的文件里烧录时需要按地址归拢到一起。这时候如果手动在文本编辑器里复制粘贴地址错一截就是玄学问题。srec_cat 一条命令解决稳定、可重复、能写进脚本。这篇文章不打算把手册翻译一遍只把平时用得最多的几个场景尤其是 HEX 合并一步步拆开讲。关于 srecord 套件里各个工具的分工先给你提个醒srec_cat 是主操作手负责合并、裁剪、填充、转换srec_cmp 用来比较文件srec_info 查看文件信息srec_print 直接把内容排成表格给你审查。学会 srec_cat 基本就能覆盖 80% 的需求。2. 环境准备把 srecord 当成普通软件一样装好2.1 下载与解压路径去 SourceForge 搜 srecord或者直接访问 srecord 官网的下载区找 1.65.0 版本对应的 win64 zip 包。下载下来就是一个压缩文件里面放着一堆 exe比如 srec_cat.exe、srec_info.exe、srec_cmp.exe。解压到一个固定目录比如 C:\tools\srecord-1.65.0-win64不用安装不用注册表。唯一要做的就是把这个目录加进系统 PATH或者每次用全路径调用。我习惯把解压目录里的文件夹打开确认里面有 srec_cat.exe。然后按 WinR输入 cmd回车切到工作目录后跑一句C:\tools\srecord-1.65.0-win64\srec_cat.exe -VERSION能看到版本号输出就说明能跑。如果不想每次敲那么长一串就在系统环境变量的 Path 里追加那个目录以后直接 srec_cat 就行。2.2 理解 srec_cat 的基本语法srec_cat 的语法是“输入文件 操作指令 输出文件”有点像管道左边喂进去中间处理右边吐出来。最简单的看文件信息srec_info.exe boot.hex它会列出文件类型Intel Hex、数据的起始地址、结束地址、数据块数量和总字节数。这个命令建议每次操作前先跑一下免得后面报错时还不知道地址范围。主要的合并操作就是这样srec_cat.exe boot.hex app.hex -o combined.hex这会把两个文件按地址从小到大整合成一个。要是两个文件地址没有重叠直接合并没有任何问题一旦重叠它默认会报错这是保护机制防止你无意中覆盖数据。3. 核心实操用 srec_cat 合并两个 HEX 文件3.1 最简单的双文件合并假设你有一个 bootloader地址范围 0x08000000 到 0x08003FFF一个 app从 0x08004000 开始。两段地址没有重叠那么直接一句srec_cat.exe boot.hex app.hex -o combined.hex得到 combined.hex里面数据被按地址排序S3 记录的类型也有可能发生变化。我实测过这样合并出来的大小基本是两者之和因为 Intel Hex 格式的数据记录会分成一行一行 16 字节或 32 字节合并时 srec_cat 会自己重新组织记录不会出现多余的空行。如果两个文件的地址重叠了比如 app 的起始地址和 boot 的末尾撞上了srec_cat 会拒绝执行并提示“record address is out of range”之类的错误。这其实是好事因为重叠往往意味着内存布局有错误。你要是确实想强制覆盖就得用 -overlap 参数但绝大多数场景里不应该这么干该调整地址就调整地址。3.2 有偏移地合并一个文件整体搬家很多情况下两个 hex 里的地址本来就不在同一个映射区间。比如一个文件指向 ARM Cortex M 的 0x00000000另一个则指向 0x08000000 的 Flash 地址。烧录时希望能把后者的地址整体挪到前面来。这种场景用 -offset 参数srec_cat.exe a.hex -offset -0x08000000 b.hex -o combined.hex这里 -offset -0x08000000 表示将 a.hex 的全部地址减去 0x08000000这样 0x08000000 就变成 0x00000000两个文件就对齐在同一片内存空间里了。注意的是偏移量可以是正数也可以是负数负号紧跟在参数后中间不能有空格。偏移后要是产生了地址为负的记录srec_cat 会拒绝输出。所以操作前一定要先用 srec_info 确认原文件的起始地址心算一遍再下手。我吃过一次亏写成了 -offset -0x8000000结果少输了一个零地址全偏了烧进去直接跑飞。后来习惯先打印一下合并后的文件信息用 srec_info 确认首尾地址合理再烧录。3.3 合并时同时填充空隙让整个 Flash 连续有时候 boot 和 app 之间的空隙在生产烧录时会被识别成“未擦除区域”导致校验失败。更稳妥的做法是主动用固定值填充空隙。srec_cat 提供了 -fill 参数。先用 0xFF 把 boot 结束地址到 app 起始地址之间的区域填满srec_cat.exe boot.hex app.hex -fill 0xFF -within boot.hex -range-padding 0x10 -o combined.hex这个语法看起来复杂我举个例子解释boot.hex 从 0x08000000 到 0x08003FFFapp.hex 从 0x08004000 到 0x08007FFF。直接用 -fill 0xFF 的话会填充整个文件范围内所有未定义的空隙。但如果你只想要 boot 和 app 之间的空隙被填而不是把 boot 内部没用到的小洞也填了就要用 -within 限定填充范围是“boot.hex 所在地址的范围内”再用 -range-padding 控制填充时对空洞的处理。我实际用的命令比较简单因为多数项目里每个文件内部的空洞本来就不多我会直接一次性填充整个 flash 映射范围srec_cat.exe boot.hex app.hex -fill 0xFF 0x08000000 0x08008000 -o combined.hex这里的 0x08008000 是 app 末尾之后的一个地址也可以直接填 flash 最大地址。填充后整个范围内的数据连续烧录完校验也顺带把空白区校验了生产上更放心。3.4 输出格式与校验检查combin.hex 的格式默认是 Intel Hex因为扩展名是 .hex。要是你想输出成 Motorola S-record直接把输出文件扩展名改成 .s19 或者 .srec 就行srec_cat.exe boot.hex app.hex -o combined.s19srec_cat 根据扩展名猜格式。也可以显式指定srec_cat.exe boot.hex app.hex -o string.bin -binary合并完之后用 srec_cmp 验证一下是否和手工预想的一致。比如你想核对 boot.hex 的地址段在合并后没有变化srec_cmp.exe boot.hex combined.hex如果 boot.hex 的数据全部出现在 combined.hex 里并且值一致它会静默结束什么都不输出。只有存在差异才会打印日志。所以看到命令行没有任何回显那就是通过了。我之前第一次用的时候还以为程序没跑后来查了文档才明白这个工具的默认行为就是“没消息就是好消息”。4. 实操中的高级用法拆分、转换、校验和提取数据4.1 按需求截取特定地址段解决“每隔2位hex取一个字符”有朋友在论坛上问怎么把 hex 文件里每隔两个字符的数据提取出来。他说的是想把一串 hex 字符串按字节还原成 ASCII 文本这其实就是在做字节提取。在 srec_cat 里用 -crop 就能指定地址范围srec_cat.exe a.hex -crop 0x08001000 0x0800101F -o segment.hex这样只保留 0x08001000 到 0x0800101F 这段。如果你想要一个连续的二进制文件srec_cat.exe a.hex -crop 0x08001000 0x0800101F -o segment.bin -binary拿到 bin 文件再用 xxd 或文本编辑器看就能看到每两个 hex 字符其实就是数据的一个字节。平时排查的时候我会先用 srec_cat 把可疑区域裁出来再配合 notepad 的十六进制插件看定位问题比看整个 hex 文本快得多。4.2 转换 hex 到 bin配合 PowerWriter 等烧录器搜索词里有一条“powerwriter烧录器 .hex文件转.pkg文件”。PowerWriter 是国产的一款支持多协议烧录的编程器它原生支持 .hex但有些固件保护功能或升级包格式需要 .pkg 文件。遇到这种需求srecord 能帮到的就是把 hex 转换成纯二进制srec_cat.exe firmware.hex -o firmware.bin -binary拿到 .bin 之后再用 PowerWriter 的上位机软件“打包”成 .pkg。这一步 srecord 做不了因为 .pkg 是厂商私有格式没有文档。但拆解一下你就明白.pkg 的核心数据就是 bin 文件加上固定头部和校验值。srecord 负责把 hex 里的地址信息剥离输出干净的数据后面的工作交给厂商工具就行。4.3 生成 MARS MIPS 模拟器可加载的 ASCII 显示文件有搜索词提到“mars mips ascii hex 显示”。MARS 是一款 MIPS 汇编模拟器经常在计算机体系结构课程里用到。它可以直接加载 .hex 文件作为初始内存。默认的 .hex 格式是每行一个地址和数据srecord 也一样能处理。如果你想生成 MARS 需要的格式可以直接用 srec_cat 输出为 Motorola S-record 或者 Intel Hex然后手动改名。更省事的办法是先用 srec_cat 把汇编器生成的二进制转换成纯 hex 文本srec_cat.exe program.hex -o mars_mem.hex输出的文件用文本编辑器打开每一行就是地址和数据。MARS 加载时按行解析直接用就可以。我当年给学生讲 MIPS 内存初始化时就是这么干的比手动在代码里构造字符串高效太多。4.4 文件头 hex 查看用 srec_print 或者转输出到 stdout排查问题的时候需要看某个地址区域里到底存了什么。srec_print 可以把整个文件的内容排成表格地址一列数据一列srec_print.exe firmware.hex输出会很长所以通常配合 -crop 先裁剪再用管道交给 findstr 过滤。比如就想看 0x08000000 开头的 16 字节srec_cat.exe firmware.hex -crop 0x08000000 0x08000010 -o temp.hex srec_print.exe temp.hex打印出来就是地址和数据的对照表。查看文件头一般是确认启动向量或者设备信息用这个办法比用 readelf 省事。4.5 合并后重新算校验和Intel Hex 文件的每一条记录最后都有一个字节的校验和srec_cat 在输出时会自己计算所以合并后一般不需要担心。但你要是合并多个文件后发现下载到板子上总是校验失败有可能是目标端的校验不是按 srecord 的输出方式算的。这种时候可以用 srec_cat 自带的校验算法生成一个结果记录srec_cat.exe combined.hex -Checksum_Positive_Big_Endian -o checked.hex这个操作会在数据末尾追加一条校验记录。具体用哪个算法得看烧录工具的要求常见的有 32 位 CRC 和求反校验。srec_cat 支持很多种我在官方文档里翻到过 -CRC16、-CRC32、-Checksum_Negative、-Checksum_Positive 等用法都类似。5. 常见问题与排查技巧实录5.1 合并时报地址重叠错误现象srec_cat 提示 “data record out of range” 或 “overlap”。原因两个输入文件的地址区间有交集。解决先用 srec_info 查看两个文件的地址范围确实有重叠就要用 -offset 把其中一个整体搬移或者用 -overlap 强制覆盖但生产环境用这个参数前一定要想清楚。我实际遇到过一次很隐蔽的情况两个文件地址区间不重叠但其中一个文件中间有一段地址重复定义srec_cat 认为是 overlap打印出来的错误信息定位又不够直接。后来我把两个文件分别裁剪成很小的区间再合并定位到是 app.hex 里两个地址段相同Keil 编译时把同一个 flash 页的初始化数据重复生成了。重新编译后解决不是 srec_cat 的锅。5.2 合并后文件大小异常现象combined.hex 比两个输入文件加起来大很多或者小很多。原因Intel Hex 格式的数据记录是按 16 字节对齐的填充一定空隙后会增加记录行数反过来如果两个文件地址紧挨着srec_cat 有可能把两条记录合并成一条文件反而变小。解决用 srec_info 查看合并后的字节总数是否等于两个文件里有效数据字节之和确认逻辑合理再烧录。5.3 “unexpected hex digit”解析错误有搜索词提到“证书申请失败 get xcodetoken unexpected hex digit”这个报错来自 Apple 开发工具链本来跟 srecord 无关但它提醒了我一个常见问题在任何程序里出现“unexpected hex digit”时十有八九是输入的 hex 字符串里混进了空格、换行符或非十六进制字符。在 srecord 的语境下如果你用文本编辑器手动改过 .hex 文件比如加了注释、把换行符弄成了 CRLFsrecord 仍能容忍大多数情况。但如果把 DOS 换行符去掉后再从串口工具里复制粘贴就可能出现空白字符。排查方法很简单用文本编辑器十六进制模式打开文件检查行尾是不是 0D 0A 或只有 0A。Windows 下建议把文件行尾统一成 CRLF 再喂给 srecord。5.4 输出 bin 后无法直接打开现象srec_cat 转出的 .bin 用 STM32CubeProgrammer 或 J-Flash 加载时报错。原因.bin 是纯数据没有地址信息。编程器需要知道基地址。你转换成 bin 时丢失了启动地址信息。解决转换到 bin 之前用 -offset 把地址调整到你想要的起点比如 0x08000000或者烧录时在软件里手动指定下载地址。5.5 合并后烧录校验失败我在一个批量生产项目里遇到过srec_cat 合并出的 hex 用 Keil 打开很正常但用烧录器下载后校验失败。排查了一圈最后发现烧录器校验的是文件末尾的 CRC而 srec_cat 在合并时把 boot 里的空余区域用 0x00 填充了但 app 区某些没用的地址在原始文件里是 0xFF导致 CRC 统计范围不对。后来用 -fill 0xFF 统一填充后再算 CRC 就解决了。遇到校验失败优先确认填充值、CRC 算法、校验范围三个方面的问题而不是怀疑工具损坏。5.6 常见问题速查表问题可能原因推荐排查命令合并报 overlap地址冲突srec_info 查看地址范围输出文件异常大填充空洞过多调整 -fill 的范围转 bin 后不能烧录缺少基地址转换前用 -offset校验失败校验算法不匹配用 srec_cmp 对照检查文件被非 ASCII 字符污染手工编辑过hex 编辑器查看行尾合并后程序跑飞偏移量算错用 -offset 后重新 srec_info6. 扩展用 srecord 在脚本和 CI 环境里跑合并6.1 用批处理脚本一键合并工程产物在实际工程里没人想每次打开命令行手动敲命令。我习惯在项目根目录放一个 merge.bat 或者 PowerShell 脚本内容就是几行 srec_cat 调用。比如echo off srec_cat.exe ..\build\boot.hex ..\build\app.hex -fill 0xFF 0x08000000 0x08040000 -o ..\output\merged.hex -line-length32 echo merged.hex generated这样打包发布固件时双击脚本固件就自动融合好了。srec_cat 的执行速度很快几百 KB 的 hex 在毫秒级就能处理完完全满足流水线需求。6.2 在 GitHub Actions 或 Jenkins 里使用如果 CI 环境是 Windows Runner直接把 srecord 的 win64 zip 下载解压然后调用 exe 就行。Linux Runner 则可以跑apt-get install srecord或者用容器镜像。我常用的一个流程是Keil 构建 → srec_cat 合并 → srec_cmp 校验 → 上传产物。这样每次提交代码都会生成一份严格的合并固件发现问题能在 merge 阶段直接红叉。在脚本里加一个校验步骤特别重要srec_cmp.exe expected.hex merged.hex if errorlevel 1 exit /b 1这样生产时不会出现“我以为合了其实没合”的尴尬。6.3 自动化处理多个文件的常见技巧如果一次要合并五个文件可以连续叠加输入srec_cat.exe part1.hex part2.hex part3.hex part4.hex part5.hex -o all.hex只要没有重叠srec_cat 会一次性处理。如果每个文件都要偏移不同的地址就分别带 -offset 参数。这种写法在整理出厂固件时非常方便所有的分区数据都能一次打包。最后再分享一个我自己的习惯每次合并前我会在命令行里先跑一遍 srec_cat用 -o 输出到一个临时文件然后用 srec_info 看看结果确认地址范围符合预期后再正式输出。很多奇怪的问题靠这一眼就能在烧录前发现并规避。工具不复杂但配合上这些操作习惯日常开发里的 HEX 文件处理就能变成一件很省心的事。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价