🚗 面向 ECU 刷写/升级工程师的“一文吃透”版本:从协商、传输到收尾,含报文结构、典型 NRC、时序要点与实操清单。
一、它们是什么(What)
-
0x34 RequestDownload:与 ECU 协商下载会话——声明数据格式、目标地址与总大小;ECU 返回最大块长度等关键参数,为后续传输作准备。 -
0x36 TransferData:按块(block)传输实际数据,带blockSequenceCounter;每块大小不得超过 0x34 返回的上限。 -
0x37 RequestTransferExit:传输结束后的收尾/校验与资源释放;ECU 可返回结果参数(如校验信息)。
🧭 记忆法:34 定契约 → 36 搬数据 → 37 做验收。
二、典型应用(Scenes)
-
生产/售后刷写:全量镜像、分区升级、Bootloader/应用/数据分区更新 -
OTA/远程升级:压缩/加密格式协商、断点续传(与上层策略配合) -
研发开发:小块试写、校验算法迭代、写保护策略验证
💡 与 0x31(RoutineControl)与 0x2F(IO 控制)的关系:刷写链专注数据搬运与一致性;例程/IO 更偏控制与流程动作。
三、报文结构(必须会写/会读)
1) 0x34 — RequestDownload(请求)
#1 SID = 0x34
#2 dataFormatIdentifier (DFI) ← 高4位=压缩方式,低4位=加密方式;0x00=无压缩无加密
#3 addressAndLengthFormatIdentifier ← 高4位=Length字段字节数;低4位=Address字段字节数
#4.. memoryAddress [m bytes] ← m = ALFID低半字节
#?.. memorySize [k bytes] ← k = ALFID高半字节
肯定响应(0x74):包含 ECU 可接受的最大块长度等参数(常以“长度格式标识 + maxNumberOfBlockLength”形式返回,厂商定义为准)。
2) 0x36 — TransferData(数据块传输)
#1 SID = 0x36
#2 blockSequenceCounter ← 1 字节计数器,常 0x01 开始递增(溢出回卷)
#3.. blockDataRecord [≤ MaxBlockLen] ← 单块数据,不得超过 0x34 协商的上限
肯定响应(0x76):回显 blockSequenceCounter 或相关确认字段(视实现)。
3) 0x37 — RequestTransferExit(收尾/校验)
#1 SID = 0x37
#2.. transferRequestParameterRecord(可选,视项目定义)
肯定响应(0x77):
#1 SID_Pos = 0x77
#2.. transferResponseParameterRecord(如校验信息、写入摘要等,厂商定义)
🧩 以上三个服务无 sub-function 字段;参数区的具体编码(例如校验类型、压缩/加密定义)需在项目文档中固定。
四、全流程时序(文字版)
-
会话/安全:切到允许刷写的诊断会话,完成SecurityAccess 解锁;必要时执行预处理例程(关看门狗、切电压/频率等)。 -
0x34 协商:传入 DFI/ALFID/Address/Size;ECU 返回最大块长度(决定 0x36 的分片策略)。 -
0x36 传输:按最大块长切片; blockSequenceCounter连续递增;大块计算校验可边传边滚动。 -
0x37 收尾:请求退出;ECU 完成完整性校验/落盘/切换映像等动作;成功则肯定响应。 -
后处理/复位:必要时执行后处理(清 DTC、软复位、切回默认会话等)。
⏱️ 过程较慢时,ECU 可能以 0x78(ResponsePending) 延迟答复,主机侧应实现合适的超时与重试策略。
五、典型 NRC(负响应码)速查表
|
|
|
|
|
|
|---|---|---|---|---|
|
|
0x13 | 0x13 | 0x13 |
|
|
|
0x31 | 0x31 | 0x31 |
|
|
|
0x24 | 0x24 | 0x24 |
|
|
|
0x7E/0x7F | 0x7E/0x7F | 0x7E/0x7F |
|
|
|
|
0x72 | 0x72 |
|
|
|
0x22/0x21 | 0x22/0x21 | 0x22/0x21 |
|
✅ 建议把内部错误码与 NRC 关联打印(含块序号、地址范围),现场定位会非常快。
六、关键参数与实现细节
1) DFI(DataFormatIdentifier)
-
0x00= 无压缩/无加密;其他取值的压缩/加密算法由 OEM/供应商定义。 -
若使用压缩:需定义memorySize 语义(压缩前/压缩后),并与 0x37 校验逻辑保持一致。
2) ALFID(Address & Length Format)
-
高 4 位 = Length 字节数;低 4 位 = Address 字节数(如 0x44→ 4B 地址 + 4B 大小)。 -
注意大小端:UDS 通常MSB 在前。
3) 最大块长度(MaxNumberOfBlockLength)
-
由 0x34 肯定响应返回;决定单块数据上限与工具的分片大小。 -
可随链路/会话动态调整(DoCAN/DoIP 的 MTU、ECU 缓冲限制等)。
4) blockSequenceCounter(BSC)
-
典型 1 字节,0x01 起步递增,溢出按实现回卷;ECU 应检查连续性。 -
错序/重复可能导致 0x31/0x24,甚至中止会话。
5) 校验与收尾(0x37)
-
常见做法:总量比对 + CRC/校验和;也可返回 digest/签名摘要。 -
失败应给出 0x72 并保留足够的错误上下文(最后通过的块序号、最后写入地址、期望与实际的校验值)。
七、标准化示例
条件:Ign=ON, Eng=OFF, V=0;ECU 支持 ALFID=0x33(Addr 3B + Size 3B);DFI=0x00。
Step 1:0x34 请求协商
34 00 33 00 20 00 00 10 00
SID DFI AL └addr(0x002000) └size(0x001000)
→ 0x74 肯定响应(示例)
74 00 81
^ ^ └ MaxBlockLen(示例语义:1字节块号 + 0x80 字节数据)
| └ 长度/参数格式标识(示意)
└ POS SID
Step 2:0x36 传输(两块示例)
# Block 1
36 01 <... up to MaxBlockLen bytes ...>
→ 76 01
# Block 2
36 02 <...>
→ 76 02
Step 3:0x37 退出/校验
37
→ 77 <transferResponseParameterRecord, e.g. CRC>
八、工程落地清单
-
前置开关:限定允许刷写的会话/安全级别;不满足即拒绝(避免误写)。 -
契约固定:把 DFI/ALFID/Address/Size/MaxBlockLen写入项目接口规范;明确 Size 语义 与 CRC 类型。 -
分片策略一致:工具与 ECU 对 最大块长、BSC 起点与回卷达成一致;越界要有清晰 NRC。 -
健壮性:大镜像支持 0x78;断线/掉电重试策略;日志留块号+地址范围与校验上下文。 -
安全与签名:若有加密/签名,定义密钥更新、证书有效期、异常回滚与安全计数器。 -
回归用例:长度/格式、地址越界、顺序错误、BSC 乱序、尾块边界、校验失败、掉线恢复等。
九、FAQ(常被问到)
Q1:DFI 一定是 0x00 吗? 不是。0x00 仅表示“无压缩/无加密”;其他值由项目定义压缩/加密组合。
Q2:ALFID=0x33 表示什么? 表示 3B 地址 + 3B 长度;写错将触发 0x13/0x31。
Q3:BSC 从 0x00 还是 0x01 开始? 通常从 0x01 开始;若使用其他起点,请在两端一致并在文档声明。
Q4:memorySize 是压缩前还是压缩后大小? 标准不强制,项目必须明确;并与 0x37 的校验逻辑对齐。
Q5:0x37 一定返回 CRC 吗? 不一定;也可返回其他摘要或仅返回成功。以厂商定义为准。
🔚 一屏总结
-
三步曲:0x34 定协商 → 0x36 传数据 → 0x37 做校验/收尾 -
三关键:DFI/ALFID 解析、最大块长与分片/BSC 一致性、0x37 的完整性校验 -
三习惯:标准 NRC 化失败点、日志打印“块号+地址+内部码+期望/实际校验”、支持 0x78 与断点恢复

