写在开篇

上回说到,郭靖搞清楚了19服务(看病历)和14服务(擦病历)------疾病潜藏祸患多,杏林郎中手段多。
这天,郭靖开着那辆国产智能网联新车,感觉有点不对劲------踩油门反应迟钝,中控屏偶尔闪一下。
突然,中控屏上弹出一行字:
"大侠,您有新的软件版本需要更新,请点击更新!"
郭靖吓了一跳:"蓉儿!这车成精了?还会主动跟我说话?"
黄蓉凑过来看了一眼,咬了口糖葫芦:"靖哥哥,这不是成精,是车里的T-Box检测到新固件了,提醒你该刷软件了。"
郭靖挠挠头:"那......点是还是不点?"
黄蓉白了他一眼:"你想继续开这'老年痴呆'版的车,还是想试试'重获新生'版?"
郭靖一咬牙:"点!"
于是,小两口又驱车直奔4S店而来------因为郎中说过,OTA虽好,但第一次还是得来店里看着刷,万一变砖了好抢救。
一、郎中的诊断:软件该升级了
郎中拿着诊断仪插上OBD口,敲了几下键盘,屏幕上跳出一行字:
当前固件版本:V1.0 最新固件版本:V2.0
"郭大侠,您这车不是吃错药,是脑子里的'操作系统'太老了。就像您用降龙十八掌打苍蝇------力气够,姿势不对。中控屏都看不下去了,主动催您更新。"
郭靖:"那赶紧刷呗!"
郎中捋着胡子:"不急。刷固件是最高风险操作,一步错,ECU变砖。UDS里有十几个服务配合干活,环环相扣,丝滑配合,缺一不可。"
二、刷固件涉及的主要服务
郎中用笔在白板上写下刷固件要用到的服务:
| 服务 | 大名 | 干啥的 | 顺序 |
|---|---|---|---|
| 10 03 | 扩展会话 | 告诉ECU"我要升级了,准备干活" | 第1步 |
| 31 D0 03 | 检查刷写条件 | 电压、车速、发动机状态对不对 | 第2步 |
| 85 02 | 关闭DTC记录 | 刷写期间别乱记故障码 | 第3步 |
| 28 03 | 关闭非诊断通信 | 关掉闲杂人等,别干扰刷写 | 第4步 |
| 10 02 | 编程会话 | 告诉ECU"我要动真格的了,给最高权限" | 第5步 |
| 27 05/06 | 安全访问(级别3) | 对暗号,证明你是授权的人 | 第6步 |
| 2E F15A | 写指纹 | 记录谁刷的、什么时候刷的 | 第7步 |
| 31 FF 00 | 擦除内存 | 把旧的软件擦掉 | 第8步 |
| 34 | 请求下载 | 告诉ECU"我要发数据了" | 第9步 |
| 36 | 传输数据 | 一包一包发新软件 | 第10步 |
| 37 | 退出传输 | 告诉ECU"发完了" | 第11步 |
| 31 D0 02 | 校验内存 | 检查下载的数据对不对 | 第12步 |
| 31 FF 01 | 兼容性检查 | 新软件和硬件匹不匹配 | 第13步 |
| 31 D0 05 | 安装 | 让新软件生效 | 第14步 |
| 10 01 | 默认会话 | 退回到游客模式 | 第15步 |
| 11 01 | 复位 | ECU重启,新软件跑起来 | 第16步 |
黄蓉数了数:"十六步?刷个固件比降龙十八掌还复杂!"
郎中点头:"环环相扣展奇功,丝滑配合更新中------顺序不能乱,一步都不能少。"
三、温故而知新:DoIP报文格式
在开始看刷写报文之前,郎中回头在白板上写下了DoIP头部的格式:
| 字节偏移 | 字段 | 说明 | 本例中的值 |
|---|---|---|---|
| 0 | Protocol Version | DoIP协议版本(0x03=ISO 13400-2:2019) | 0x03 |
| 1 | Inverse Version | 版本取反(~0x03=0xFC) | 0xFC |
| 2-3 | Payload Type | 负载类型(0x8001=诊断消息) | 0x80 0x01 |
| 4-7 | Payload Length | 负载长度(后面UDS数据的字节数) | 可变 |
| 8... | UDS数据 | 真正的诊断命令 | 看具体服务 |
"记住了:03 FC 80 01 是DoIP的'信封',告诉对方'这是诊断消息'。后面的00 00 00 xx告诉对方'后面跟了xx字节的UDS数据'。再后面才是UDS命令。"
郭靖点头:"嗯,我这记性,还真多亏郎中帮复习一下,不然忘的速度都超过了学的速度,现在清爽多了!"
四、预编程阶段:准备工作不能省
① 10 03(扩展会话)
"第一步先切扩展会话,不能直接切编程会话。就像去桃花岛,得先当弟子,不能从大门口直接闯密室。"
03 FC 80 01 00 00 00 02 10 03
| 部分 | 值 | 说明 |
|---|---|---|
| DoIP头部 | 03 FC 80 01 |
版本3,暗号对上了,诊断消息 |
| 负载长度 | 00 00 00 02 |
2字节 |
| UDS命令 | 10 03 |
切扩展会话 |
03 FC 80 01 00 00 00 02 50 03
| 部分 | 值 | 说明 |
|---|---|---|
| DoIP头部 | 03 FC 80 01 |
同上 |
| 负载长度 | 00 00 00 02 |
2字节 |
| UDS响应 | 50 03 |
正响应(0x10+0x40=0x50) |
② 31 D0 03(检查刷写条件)
"刷写前,ECU要检查三个条件:"
| 条件 | 要求 | 不满足时 |
|---|---|---|
| 电压 | 9V - 16V | 无法进入编程会话 |
| 车速 | ≤ 5km/h | 拒绝刷写 |
| 发动机转速 | 不限制(但必须能读到) | 读不到时按"满足"处理 |
03 FC 80 01 00 00 00 03 31 D0 03
| 部分 | 值 | 说明 |
|---|---|---|
| DoIP头部 | 03 FC 80 01 |
诊断消息 |
| 负载长度 | 00 00 00 03 |
3字节 |
| UDS命令 | 31 D0 03 |
31服务,RID=D003(检查刷写条件) |
03 FC 80 01 00 00 00 04 71 D0 03 00
| 部分 | 值 | 说明 |
|---|---|---|
| 负载长度 | 00 00 00 04 |
4字节 |
| UDS响应 | 71 D0 03 00 |
正响应,状态码0x00=条件满足 |
③ 85 02(关闭DTC记录)
"刷写期间ECU会被擦除、重写,中间肯定会有各种'异常'。如果不关DTC记录,ECU会疯狂往病历本上记假故障码。"
03 FC 80 01 00 00 00 02 85 02
| 部分 | 值 | 说明 |
|---|---|---|
| 负载长度 | 00 00 00 02 |
2字节 |
| UDS命令 | 85 02 |
关闭DTC记录 |
03 FC 80 01 00 00 00 02 85 02
| 部分 | 值 | 说明 |
|---|---|---|
| 负载长度 | 00 00 00 02 |
2字节 |
| UDS响应 | 85 02 |
正响应(0x85的响应也是0x85,特殊) |
④ 28 03(关闭非诊断通信)
"车上的中控屏、音响、T-Box还在叽叽喳喳发消息。这些消息会干扰刷写过程,28服务就是'请勿打扰'模式。"
03 FC 80 01 00 00 00 02 28 03
| 部分 | 值 | 说明 |
|---|---|---|
| 负载长度 | 00 00 00 02 |
2字节 |
| UDS命令 | 28 03 |
关闭非诊断通信 |
03 FC 80 01 00 00 00 02 68 03
| 部分 | 值 | 说明 |
|---|---|---|
| 负载长度 | 00 00 00 02 |
2字节 |
| UDS响应 | 68 03 |
正响应(0x28+0x40=0x68) |
五、刷写阶段:核心操作
⑤ 10 02(编程会话)
"准备工作做完,正式进编程会话------岛主模式。"
03 FC 80 01 00 00 00 02 10 02
| 部分 | 值 | 说明 |
|---|---|---|
| 负载长度 | 00 00 00 02 |
2字节 |
| UDS命令 | 10 02 |
切编程会话 |
03 FC 80 01 00 00 00 02 50 02
| 部分 | 值 | 说明 |
|---|---|---|
| 负载长度 | 00 00 00 02 |
2字节 |
| UDS响应 | 50 02 |
正响应 |
⑥ 27 05/06(安全访问级别3)
"进编程会话后,得对暗号证明身份。用级别3的种子密钥。"
03 FC 80 01 00 00 00 02 27 05
| 部分 | 值 | 说明 |
|---|---|---|
| 负载长度 | 00 00 00 02 |
2字节 |
| UDS命令 | 27 05 |
请求种子(级别3) |
03 FC 80 01 00 00 00 06 67 05 12 34 56 78
| 部分 | 值 | 说明 |
|---|---|---|
| 负载长度 | 00 00 00 06 |
6字节 |
| UDS响应 | 67 05 12 34 56 78 |
返回种子0x12345678 |
03 FC 80 01 00 00 00 06 27 06 9A BC DE F0
| 部分 | 值 | 说明 |
|---|---|---|
| 负载长度 | 00 00 00 06 |
6字节 |
| UDS命令 | 27 06 9A BC DE F0 |
发送密钥 |
03 FC 80 01 00 00 00 02 67 06
| 部分 | 值 | 说明 |
|---|---|---|
| 负载长度 | 00 00 00 02 |
2字节 |
| UDS响应 | 67 06 |
验证通过 |
⑦ 2E F15A(写指纹)
"记录谁刷的、什么时候刷的------刷写日期、维修店代码。"
03 FC 80 01 00 00 00 0D 2E F1 5A 25 05 07 00 00 00 00 00 00 00
| 部分 | 值 | 说明 |
|---|---|---|
| 负载长度 | 00 00 00 0D |
13字节 |
| UDS命令 | 2E F1 5A |
写DID F15A(指纹) |
| 后续数据 | 25 05 07 00... |
2025年5月7日 + 维修店代码 |
03 FC 80 01 00 00 00 03 6E F1 5A
| 部分 | 值 | 说明 |
|---|---|---|
| 负载长度 | 00 00 00 03 |
3字节 |
| UDS响应 | 6E F1 5A |
正响应 |
⑧ 31 FF 00(擦除内存)
"把旧的软件彻底擦掉,准备放新的。"
03 FC 80 01 00 00 00 0F 31 01 FF 00 44 00 00 00 00 00 00 00 00 00 00
| 部分 | 值 | 说明 |
|---|---|---|
| 负载长度 | 00 00 00 0F |
15字节 |
| UDS命令 | 31 01 FF 00 |
启动例程 RID=FF00(擦内存) |
| 参数 | 44 00 00 00 00 00 00 00 00 00 |
4字节地址+4字节长度 |
03 FC 80 01 00 00 00 06 71 01 FF 00 00 00
| 部分 | 值 | 说明 |
|---|---|---|
| 负载长度 | 00 00 00 06 |
6字节 |
| UDS响应 | 71 01 FF 00 00 00 |
正响应,状态00=成功 |
⑨ 34服务(RequestDownload)
"告诉ECU总共有多少数据要传。"
03 FC 80 01 00 00 00 0B 34 00 44 00 00 00 00 00 00 27 10
| 部分 | 值 | 说明 |
|---|---|---|
| 负载长度 | 00 00 00 0B |
11字节 |
| UDS命令 | 34 00 |
请求下载,不压缩不加密 |
| 地址格式 | 44 |
4字节地址+4字节长度 |
| 地址 | 00 00 00 00 |
起始地址 |
| 长度 | 00 00 27 10 |
10000字节 |
03 FC 80 01 00 00 00 05 74 20 00 00 00
| 部分 | 值 | 说明 |
|---|---|---|
| 负载长度 | 00 00 00 05 |
5字节 |
| UDS响应 | 74 20 00 00 00 |
正响应,maxBlockLength=0x2000=8192字节 |
⑩ 36服务(TransferData)
"一包一包传数据。"
03 FC 80 01 00 20 02 00 36 01 55 AA 55 AA ...
| 部分 | 值 | 说明 |
|---|---|---|
| 负载长度 | 00 00 20 02 |
8194字节(0x2000数据+2字节头) |
| UDS命令 | 36 01 |
传输数据,块序号=1 |
| 数据 | 55 AA... |
固件数据(最大8192字节) |
03 FC 80 01 00 00 00 02 76 01
| 部分 | 值 | 说明 |
|---|---|---|
| 负载长度 | 00 00 00 02 |
2字节 |
| UDS响应 | 76 01 |
确认收到第1包 |
⑪ 37服务(RequestTransferExit)
"告诉ECU:数据发完了。"
03 FC 80 01 00 00 00 02 37 00
| 部分 | 值 | 说明 |
|---|---|---|
| 负载长度 | 00 00 00 02 |
2字节 |
| UDS命令 | 37 00 |
退出传输 |
03 FC 80 01 00 00 00 02 77 00
| 部分 | 值 | 说明 |
|---|---|---|
| 负载长度 | 00 00 00 02 |
2字节 |
| UDS响应 | 77 00 |
正响应 |
⑫ 31 D0 02(校验内存)
"检查下载的数据对不对。"
03 FC 80 01 00 00 00 03 31 D0 02
| 部分 | 值 | 说明 |
|---|---|---|
| 负载长度 | 00 00 00 03 |
3字节 |
| UDS命令 | 31 D0 02 |
校验内存(RID=D002) |
03 FC 80 01 00 00 00 04 71 D0 02 00
| 部分 | 值 | 说明 |
|---|---|---|
| 负载长度 | 00 00 00 04 |
4字节 |
| UDS响应 | 71 D0 02 00 |
状态00=校验通过 |
⑬ 31 FF 01(兼容性检查)
"新软件和硬件匹不匹配?"
03 FC 80 01 00 00 00 03 31 FF 01
| 部分 | 值 | 说明 |
|---|---|---|
| 负载长度 | 00 00 00 03 |
3字节 |
| UDS命令 | 31 FF 01 |
兼容性检查 |
03 FC 80 01 00 00 00 04 71 FF 01 00
| 部分 | 值 | 说明 |
|---|---|---|
| 负载长度 | 00 00 00 04 |
4字节 |
| UDS响应 | 71 FF 01 00 |
状态00=兼容 |
⑭ 31 D0 05(安装)
"让新软件正式生效。"
03 FC 80 01 00 00 00 03 31 D0 05
| 部分 | 值 | 说明 |
|---|---|---|
| 负载长度 | 00 00 00 03 |
3字节 |
| UDS命令 | 31 D0 05 |
开始安装 |
03 FC 80 01 00 00 00 04 71 D0 05 01
| 部分 | 值 | 说明 |
|---|---|---|
| 负载长度 | 00 00 00 04 |
4字节 |
| UDS响应 | 71 D0 05 01 |
状态01=开始安装 |
六、后编程阶段:收尾工作
⑮ 10 01(默认会话)
"刷完了,退回到默认会话------从岛主变回游客。"
03 FC 80 01 00 00 00 02 10 01
| 部分 | 值 | 说明 |
|---|---|---|
| 负载长度 | 00 00 00 02 |
2字节 |
| UDS命令 | 10 01 |
切默认会话 |
03 FC 80 01 00 00 00 02 50 01
| 部分 | 值 | 说明 |
|---|---|---|
| 负载长度 | 00 00 00 02 |
2字节 |
| UDS响应 | 50 01 |
正响应 |
⑯ 11 01(复位)
"ECU重启,新软件正式跑起来。"
03 FC 80 01 00 00 00 02 11 01
| 部分 | 值 | 说明 |
|---|---|---|
| 负载长度 | 00 00 00 02 |
2字节 |
| UDS命令 | 11 01 |
硬复位 |
03 FC 80 01 00 00 00 02 51 01
| 部分 | 值 | 说明 |
|---|---|---|
| 负载长度 | 00 00 00 02 |
2字节 |
| UDS响应 | 51 01 |
正响应(然后ECU重启) |
七、这些坑,靖哥哥替你先踩了
| 坑 | 真相 |
|---|---|
| 以为刷固件就是发36 | 34和37也得发,三兄弟缺一不可 |
| 以为直接切10 02就行 | 得先切10 03,检查条件、关通信、关DTC,才能切编程会话 |
| 以为擦Flash含在34里 | 擦Flash是31 FF 00的活,得单独发 |
| 以为刷完就能用 | 还得过签名校验、兼容性检查、安装、复位 |
| 以为OTA和店里刷不一样 | 底层都是这套UDS流程,OTA只是多了个下载环节 |
| 以为DoIP报文就是UDS命令 | DoIP头部03 FC 80 01是信封,负载长度告诉你有多少UDS数据,别搞混 |
八、下步目标
郭靖长叹:
"十六步!从车里弹提示到刷完重启,中间十六步------切会话、查条件、关通信、关DTC、对暗号、写指纹、擦内存、发数据、校验、兼容性检查、安装、复位......环环相扣展奇功,丝滑配合更新中 。每一步的报文我都看懂了,
03 FC 80 01是信封,00 00 00 xx是负载长度,后面才是UDS命令。"
郎中笑着点头:
"UDS常用服务14个------10、11、14、19、22、27、28、2E、31、34、36、37、3E、85------咱们全部过了一遍。从读VIN到刷固件,从看病历到擦病历,从对暗号到写指纹,你都能自己上手了。"
黄蓉把最后一颗糖葫芦咬下来:
"靖哥哥,你学了这么多,以后车弹出'有更新',你心里就有底了------知道背后藏着16步江湖规矩。下一步是不是该实战演练一下?找个真ECU,拿诊断仪刷一次试试?"
郭靖憨憨一笑:"蓉儿说得对。下次OTA提醒,我就知道:哦,这是16步的'第一步'而已。理论学完了,该动手了!"
写在最后
这一篇最大的收获:
刷固件不是只有34/36/37三兄弟,而是十六步连环:预编程阶段(10 03→31 D0 03→85 02→28 03)、刷写阶段(10 02→27→2E→31 FF 00→34→36→37→31 D0 02→31 FF 01→31 D0 05)、后编程阶段(10 01→11 01)。环环相扣,丝滑配合,缺一不可。
温故而知新:DoIP头部
03 FC 80 01是诊断消息信封,00 00 00 xx是负载长度,后面才是UDS命令。
郭靖感叹:环环相扣展神奇,丝滑更新不迷离------刷固件如此,学技术亦如此。
886!