一文带你搞懂S19文件

发布时间:2026/7/10 22:05:42
一文带你搞懂S19文件 一文带你搞懂S19文件S-record之前做过UDS诊断上位机的开发做过ECU的Bootloader刷写相关的工作。想来把知识积累一下以便后人翻阅学习。可以关注我之后还会分享HEX文件的解析以及相关的示例代码。一、概述S19文件也常被称为S-Record、SREC或Motorola S-record是一种由摩托罗拉推出的ASCII文本格式主要用于表示二进制数据。它最早被应用于嵌入式系统中的固件传输与存储在微控制器编程、EEPROM烧录以及调试场景中尤为常见。这种格式以可读的文本方式编码二进制信息并内嵌地址、数据和校验码从而保证数据传输的可靠性。Motorola S-record诞生于20世纪70年代中期最初是为Motorola 6800处理器而设计。配套的开发工具会将可执行代码和数据输出为该格式随后程序员将其读取并烧录到嵌入式系统中的PROM或EPROM里。此外还有一种常见的十六进制格式叫Intel HEX简称Hex是由英特尔定义的。二、S19文件是什么S19文件示例在正式讲解之前我们先来看一段真实的S19文件示例。如下边的文件所示这是一个非常常见的S19文件片段, 我们在UDS中通过34、 36、 37 服务刷写的就是像这样的数据。S309000080040000812CC5S31900008008000000000000000000000008000080080000800846S3190000801C000001240000812C0000812C0000023C00009000FDS309000081200000000055S31900008138D0012C00D101780000757060E0021C63762C00930BS3190003B51CFFFF0000454452495645000000000000533135306CS3190003B53030312E3030360000564355303200000000000089我们使用VSCode打开S19文件并添加S19 HighLight插件即可像如下图所示有代码块高亮可以快速查看每一个部分在哪里。建议每个汽车工程师都下载该插件。S19文件的生成方式S19文件通常由以下工具生成编译器/链接器如GCC、IAR、Keil等在编译代码后生成。转换工具通过objcopyGNU工具链将ELF或BIN文件转换为S19格式。S19文件的具体生成过程假设你有这样的C代码voidAppMain(void);编译后AppMain这个函数被放在 Flash 的 0x00008000地址上S19 文件里有一行 S3 09 00008000 … …那么以下4种东西本质上是同一个地址视角表示S19 文件00008000C 语言void AppMain(void)CPUPC 0x00008000Flash第0x8000字节开始CPU 并不关心这是函数还是数据它只看到地址那里的二进制内容如果内容是合法指令就执行如果内容是数据就当作数据读严格上来讲如果你拿到别人的完整S19文件你可以将其反编译为汇编代码。继续反编译为C代码会很困难再举一个例子上述的文件示例中S19文件实际上是保存的《S15001.006.s19》这个文件文件名S15001.006就是该编译后的软件的软件版本号。我们使用UDS的34、36、37服务刷写之后再使用22服务去读取0xF195这个DID就可以读取到刚才刷进去这个软件版本号。我们逆向思考既然我们刷写之后可以通过22服务读取到更新后的0xF195的DID值那么说这个刷写进去的S19文件中一定是完整保存了刚才这个字符串的。我们将这个字符串格式的S15001.006软件版本号按照ASCII码表转换为字节数组5331353030312E303036, 再拿着这个到S19文件中去找你可以找到刚才这段字节数组。S3190003B51CFFFF0000454452495645000000000000533135306CS3190003B53030312E3030360000564355303200000000000089我们的程序就是以这样的方式躺在S19文件里。S19 / HEX 里的地址就是 CPU 指令指针、C 语言指针在 Flash 上的投影Flash 里直接躺着二进制化的函数和变量CPU 通过地址总线把这些二进制当成指令或当成数据来使用。S19文件的应用场景固件烧录通过编程器将S19文件写入MCU的Flash或EEPROM。我们的Bootloader正是通过CAN总线 UDS的方式将S19格式的程序烧录进车身的控制器中。调试调试器通过解析S19文件定位代码和数据地址。数据校验校验和机制确保数据传输过程中无错误。三、S19文件格式结构如第二节所示一个S19文件由一些相似的行组成我们称之为记录每条记录代表一段二进制数据或控制信息。每一行都分为6个部分我用不同颜色区分开来了。每条记录的结构如下以S3190003B51CFFFF0000454452495645000000000000533135306C为例起始符Start Code固定字符 S记录类型Type如 S3 中的 3字节数Byte Count如 19地址Address如 00008120数据Data如 FFFF000045445249564500000000000053313530校验和Checksum如 6C下边我会详细展开讲每一个字段。四、S19行字段说明起始符Start Code[!NOTE]固定字符 S 标识一条记录的开始。记录类型Type[!NOTE]1位数字表示记录类型0-9常用类型包括S0文件头通常包含文件名或描述信息。S116位地址的数据记录地址范围0x0000–0xFFFF。S224位地址的数据记录地址范围0x000000–0xFFFFFF。S332位地址的数据记录地址范围0x00000000–0xFFFFFFFF。S5记录计数可选表示S1/S2/S3记录的数量。S7/S8/S9终止记录表示程序入口地址或文件结束。S0记录文件头[!NOTE]用途文件标识或描述信息。示例S00600004844521BS0类型为S0。06总字节数为6地址4字节 数据0字节 校验和1字节。0000地址字段通常为0。484452ASCII数据“HDR”。1B校验和。S1/S2/S3记录数据记录[!NOTE]用途存储实际的二进制数据及其地址。示例 S3190003B51CFFFF0000454452495645000000000000533135306CS3类型为S332位地址。19总字节数为 0x19 25地址 4 字节 数据 20 字节 校验和 1 字节。0003B51C地址为0x0003B51C。FFFF00004544524956450000000000005331353020字节数据。6C校验和。S5记录记录计数[!NOTE]用途统计S1/S2/S3记录的数量可选。示例S5030003FAS5类型为S5。03总字节数为3地址 0 字节 数据 2 字节 校验和 1 字节。0003表示有3条数据记录。FA校验和。S7/S8/S9记录终止记录[!NOTE]用途标识文件结束并可能包含程序入口地址。示例 S7050000812455S7类型为S7终止记录。05总字节数为5地址 0 字节 数据5字节 校验和1字节。00008124程序入口地址通常由系统忽略。55校验和。字节数Byte Count[!NOTE]2位十六进制数表示后续字段地址 数据 校验和的总字节数。以 S3190003B51CFFFF0000454452495645000000000000533135306C 为例对应我们的程序文件 S319 就表示后边跟的是4字节一个int的地址并且有0x19 25个字节的数据。0003B51C 就是这个4字节的地址后边跟了20个数据FFFF000045445249564500000000000053313530然后最后是一个校验位6C总共就是4 20 1 25计算正确。地址Address[!NOTE]根据记录类型确定长度S12字节16位地址S23字节24位地址S34字节32位地址以 S3190003B51CFFFF0000454452495645000000000000533135306C 为例S3 就表示这是一个32位的地址也就是一个int而 0003B51C 就是这个地址。数据Data[!NOTE]可变长度的二进制数据以十六进制ASCII编码表示。以下边两段记录为例S309000080040000812CC5S31900008008000000000000000000000008000080080000800846S3190000801C000001240000812C0000812C0000023C00009000FD例如 0x00008008 - 0x00008004 等于0x4下一行的地址减去上一行的地址得到4。就是说上一行一共传输了 4 个字节的数据数一下确实是 4 字节数据:0000812CC5其中C5是校验位。通常一次最多传输 20 个字节的数据。0x0000801C - 0x00008008 28 - 8 20 表示上一行有 20 个数据。一行27个字节前2个表示数据头后4个表示数据地址最后一个是校验位所以 数据段的长度 27 - 2 - 4 - 1 20个。数一下确实是20字节数据。校验和Checksum1字节用于验证记录的完整性。计算方法为[!NOTE]校验和 0xFF - (字节数 地址高位到低位 数据所有字节) 的低8位。即计数值、地址场和数据场的若干字符以两个字符为一对 将它们相加求和和的溢出部分不计(掩码)只保留最低两位字符 NN (补码)checksum 0xFF - 0xNN。有关详细的校验和示例请参见示例部分。校验和计算示例 S10FCAC00C0C0C0C0C0C0C007F400000530F 表示后边的 地址 数据 校验 一共15个字节。 CAC0 表示地址。被解码以显示校验和值是如何计算的如下所示累加 0F CA C0 0C 0C 0C 0C 0C 0C 0C 00 7F 40 00 00 2AChex掩码保留最低有效字节 AChex 1010 1100bin补码计算最低有效字节的补码; checksum 0xFF - 0xNN 即 0xFF - 0xAC 0x53 和预期值相比正确总结本文介绍了 S19S-Record文件的基本结构记录类型、字节数、地址、数据和校验和五大字段以及 S0/S1/S2/S3/S5/S7/S8/S9 各类型的具体含义。掌握了这些看懂 S19 文件、编写解析器或刷写工具就不再是问题。后续我会继续更新 HEX 文件的解析以及相关的 Python / C# 示例代码方便大家直接拿来用。如果本文对你有帮助欢迎关注一起学习交流。参考链接MCU刷写——S19S-Record文件格式详解及Python代码【VCU】详解S19文件S-record