📦 S19 文件格式分析


📌 一、概述

S19 文件,也叫 Motorola S-record 文件,是一种使用 ASCII 文本表示程序代码和数据的文件格式。

它常用于:

  • 单片机程序下载
  • Flash 烧写
  • BootLoader 升级
  • 不同平台之间传输程序代码和数据

很多 Freescale / NXP 系列 MCU 工程在编译后,会生成类似:

*.s19
*.asb.s19

这样的文件。


🧱 二、S19 整体结构

S19 文件由多行 S Record 组成。

每一行都是一条记录,基本结构如下:

Sx LL AAAA... DD...DD CC

其中:

字段大小说明
Record Type2字符记录类型,如 S0 / S1 / S2 / S3 / S9
Record Length1 Byte后续字节数
Address2 / 3 / 4 Bytes数据写入的起始地址
Data0 ~ N Bytes代码或数据内容
Checksum1 Byte校验和

🧩 三、字段详解

1. Record Type

Record Type 用于描述当前记录的用途。

例如:

S1
S2
S3
S9

其中 S 是固定起始字符,后面的数字表示记录类型。


2. Record Length

Record Length 表示当前记录中剩余的字节数。

计算方式:

Record Length = Address字节数 + Data字节数 + Checksum字节数

注意:

Record Length 本身不参与长度统计
Record Type 也不参与长度统计


3. Address

Address 表示数据应该写入 MCU / Flash 的起始地址。

不同记录类型的 Address 长度不同:

类型Address长度
S12 Bytes
S23 Bytes
S34 Bytes
S74 Bytes
S83 Bytes
S92 Bytes

4. Data

Data 表示真正需要写入 Flash / ROM 的数据。

特点:

  • 每 1 Byte 数据用 2 个十六进制字符表示
  • Data 长度由 Record Length 和 Address 长度反推
  • S0 / S5 / S7 / S8 / S9 通常不需要下载到 MCU

5. Checksum

Checksum 是 1 Byte 校验和。

计算方式:

Checksum = 0xFF - (Record Length + Address + Data 的所有字节之和的低8位)

也可以理解为:

Record Length + Address + Data + Checksum 的低8位 = 0xFF

注意:校验的是实际二进制字节,不是 ASCII 字符本身。


🗂 四、Record Type 类型表

类型Address长度作用是否下载到 MCU
S02 Bytes文件头 / 文件名 / 注释信息
S12 Bytes数据记录,16-bit 地址
S23 Bytes数据记录,24-bit 地址
S34 Bytes数据记录,32-bit 地址
S52 BytesS1 / S2 / S3 记录数量统计
S74 Bytes程序入口地址,结束记录
S83 Bytes程序入口地址,结束记录
S92 Bytes程序入口地址,结束记录

📝 五、S0 文件头记录

作用

S0 通常是 S19 文件的第一条记录,用于保存文件名、路径或注释信息。

它不需要下载到 MCU。


结构

S0 LL AAAA DATA CC
字段说明
S0文件头记录
LL后续字节数
AAAA通常为 0000
DATA文件名 / 路径 / 注释
CC校验和

示例

S01F0000443A5C50726F6A6563745F335C62696E5C50726F6A6563742E61627371

解析:

字段说明
TypeS0文件头
Length1F后续 31 Bytes
Address0000未使用
Data443A5C…616273ASCII 字符串
Checksum71校验和

Data 转 ASCII 后大致表示:

D:\Project_3\bin\Project_3.abs

💾 六、S1 数据记录

作用

S1 是数据记录,地址长度为 2 Bytes。

适合 16-bit 地址空间。


结构

S1 LL AAAA DATA CC
字段大小说明
S12字符记录类型
LL1 Byte后续字节数
AAAA2 Bytes起始地址
DATAN Bytes数据
CC1 Byte校验和

示例

S123C000CF2100C6055B134A800BFE4A8000FE0000C015C031000000000000000000000092

解析:

字段说明
TypeS116-bit 地址数据记录
Length23后续 0x23 Bytes
AddressC000写入起始地址
DataCF2100…00000000需要写入的数据
Checksum92校验和

数据会从地址:0xC000 开始连续写入。


💾 七、S2 数据记录

作用

S2 是数据记录,地址长度为 3 Bytes。

适合 24-bit 地址空间。


结构

S2 LL AAAAAA DATA CC
字段大小说明
S22字符记录类型
LL1 Byte后续字节数
AAAAAA3 Bytes起始地址
DATAN Bytes数据
CC1 Byte校验和

示例

S218FE8020F2FEC013EC31270BED31180A30700434F920F10A0B

解析:

字段说明
TypeS224-bit 地址数据记录
Length18后续 0x18 Bytes
AddressFE8020写入起始地址
DataF2FEC013EC31270BED31180A30700434F920F10A数据内容
Checksum0B校验和

数据写入起始地址:0xFE8020


💾 八、S3 数据记录

作用

S3 是数据记录,地址长度为 4 Bytes。

适合 32-bit 地址空间。


结构

S3 LL AAAAAAAA DATA CC
字段大小说明
S32字符记录类型
LL1 Byte后续字节数
AAAAAAAA4 Bytes起始地址
DATAN Bytes数据
CC1 Byte校验和

地址计算

S3 记录不需要像 Intel HEX 那样依赖扩展线性地址记录。

它本身就包含完整 32-bit 地址:

实际写入地址 = Address + DataIndex

🔢 九、S5 记录数量统计

作用

S5 用于记录前面 S1 / S2 / S3 数据记录的数量。

它不是必须存在的记录。


结构

S5 LL CCCC CC
字段说明
S5记录数量统计
LL通常为 03
CCCC数据记录数量
CC校验和

注意:

S5 只是校验辅助信息

不表示程序结束不需要写入

MCU不是每个 S19 文件都有


🚀 十、S7 / S8 / S9 程序入口记录

S7 / S8 / S9 都表示文件结束,同时指定程序入口地址。

区别在于入口地址长度不同。


类型区别

类型Address长度常用于
S74 Bytes对应 S3 数据记录
S83 Bytes对应 S2 数据记录
S92 Bytes对应 S1 数据记录

S7 结构

S7 LL AAAAAAAA CC

表示 32-bit 程序入口地址。


S8 结构

S8 LL AAAAAA CC

表示 24-bit 程序入口地址。


S9 结构

S9 LL AAAA CC

表示 16-bit 程序入口地址。


示例

S9030000FC

解析:

字段说明
TypeS9结束记录
Length03Address 2 Bytes + Checksum 1 Byte
Address0000程序入口地址
ChecksumFC校验和

含义:

程序入口地址 = 0x0000文件结束

🧮 十一、Checksum 校验示例

以 S2 记录为例:

S218FE8020F2FEC013EC31270BED31180A30700434F920F10A0B

取出需要参与计算的字节:

18 FE 80 20 F2 FE C0 13 EC 31 27 0B ED 31 18 0A 30 70 04 34 F9 20 F1 0A

计算:

sum = 所有字节相加checksum = 0xFF - (sum & 0xFF)

最终得到:0B


🧠 十二、开发时怎么解析 S19

解析步骤:

1. 逐行读取
2. 判断是否以 'S' 开头
3. 读取 Record Type
4. 读取 Record Length
5. 根据 Type 判断 Address 长度
6. 解析 Address
7. 根据 Length 反推出 Data 长度
8. 解析 Data
9. 校验 Checksum
10. 根据 Type 决定是否写入 Flash

Data 长度计算

DataLength = RecordLength - AddressLength - 1

其中:

1 = Checksum长度

🛠 十三、写 Flash 时注意事项

1. Flash 需要先擦除再写入

已经写入过的 Flash 地址,通常不能直接覆盖。

正确流程:

擦除 Sector / Page↓写入数据↓校验数据

2. 不要把所有记录都写入 Flash

需要写入 Flash 的通常只有:S1 / S2 / S3

不应写入:S0 / S5 / S7 / S8 / S9


3. 调试器窗口不一定可靠

有时候内存监视窗口不能实时显示 Flash 状态。

可以通过指针读取目标地址,确认是否写入成功:

uint8_t value = *(volatile uint8_t*)address;

4. 注意芯片锁定问题

在某些 Freescale / NXP MCU 上,通过自定义 BootLoader 或串口下载 S19 后,可能导致芯片进入安全锁定状态。

如果被锁定,需要执行:

Unsecure

之后才能再次通过 BDM 或串口下载。


📌 十四、S19 与 Intel HEX 对比

对比项S19Intel HEX
厂商来源Motorola / FreescaleIntel
行起始符Sx:
地址长度由 S1/S2/S3 决定依赖记录类型扩展
数据记录S1/S2/S3Type 00
结束记录S7/S8/S9Type 01
校验方式0xFF 补码0x100 补码
常见场景Freescale / NXP MCUSTM32 / AVR / 通用 MCU

✅ 十五、快速记忆

最常见组合

S0  文件头S1/S2/S3  数据记录S7/S8/S9  结束与入口地址

真正要写入 Flash 的记录

S1 / S2 / S3

校验公式

Checksum = 0xFF - (sum & 0xFF)

数据长度公式

DataLength = RecordLength - AddressLength - 1

写入地址

实际地址 = Address + DataIndex

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注