2. 诊断会话控制(0x10):会话切换失败排查、默认/扩展/编程会话的权限管理、超时机制
大家好,我是你们的讲师。今天我们来聊聊诊断会话控制,也就是0x10服务。这个服务在UDS开发里,可以说是最基础、也最容易出幺蛾子的地方。很多刚入行的朋友,甚至一些老手,都在这上面栽过跟头。我自己就见过不少因为会话切换失败,导致后续诊断流程全部卡死的案例。
说白了,0x10服务就是告诉ECU:“嘿,我要开始干活了,你准备好没?” 但ECU可不是随便就能切换状态的,它有自己的“脾气”和“规矩”。我们今天就把它彻底捋清楚。
2.1 会话切换失败排查:问题到底出在哪?
会话切换失败,是0x10服务最常见的故障现象。你发个10 02想切到编程会话,结果ECU回了个7F 10 12(子功能不支持)或者7F 10 22(条件不满足)。这时候怎么办?
我个人习惯,先看否定响应码(NRC)。不同的NRC,指向的问题完全不同。
- NRC 0x12(子功能不支持):这通常意味着ECU压根不认识你请求的这个会话。比如你发10 04,但ECU只支持默认(01)、扩展(02)和编程(03)会话。那04是什么?ECU一脸懵。检查一下你的诊断描述文件(CDD/ODX),看看支持的会话列表。
- NRC 0x22(条件不满足):这是个大坑。ECU告诉你:“我知道你想切,但现在不行。” 原因可能有一大堆。比如,你正在刷写程序,ECU不允许你切回默认会话;或者你之前没做安全解锁,就想切到编程会话。我在项目中遇到过,一个同事调了三天没搞定,最后发现是ECU要求切到编程会话前,必须先进入扩展会话。嗯,文档里写得很清楚,就是没仔细看。
- NRC 0x13(消息长度或格式错误):这个相对好查。检查一下你发的报文,数据长度对不对?比如10 03后面是不是多了一个字节?或者少了一个?
2.2 默认/扩展/编程会话的权限管理:谁该干什么?
UDS定义了三种标准会话:默认会话(Default Session, 0x01)、扩展会话(Extended Session, 0x02)和编程会话(Programming Session, 0x03)。它们就像三个不同权限的房间,能做的事情完全不一样。
| 会话类型 | 会话ID | 典型用途 | 可执行的服务示例 |
|---|---|---|---|
| 默认会话 | 0x01 | ECU上电后的默认状态,用于常规通信和读取基本数据 | 0x22(读取数据)、0x19(读取DTC) |
| 扩展会话 | 0x02 | 用于更复杂的诊断功能,如写入数据、执行例程 | 0x2E(写入数据)、0x31(例程控制) |
| 编程会话 | 0x03 | 用于ECU软件刷写、Bootloader操作 | 0x34(请求下载)、0x36(数据传输)、0x37(请求退出传输) |
你想想看,如果默认会话就能刷写程序,那岂不是乱套了?任何诊断仪都能随便改ECU的软件,安全性何在?所以,权限管理是必须的。
避坑指南: 我曾经见过一个项目,工程师在扩展会话里实现了刷写功能,结果被客户打回来重做。为什么?因为ISO 14229标准里,刷写相关的服务(0x34、0x36等)只能在编程会话下执行。扩展会话虽然权限比默认高,但也不能越俎代庖。所以,设计会话权限时,一定要严格遵循标准。
另外,会话切换是有“方向性”的。通常,从默认会话可以切到扩展或编程会话。但从编程会话切回默认会话,可能需要先经过扩展会话。这取决于ECU的具体实现。我建议,在开发初期就把会话状态机画清楚,避免后期逻辑混乱。
2.3 超时机制:别让ECU一直等着
超时机制是0x10服务里一个容易被忽视,但极其重要的部分。ECU不是无限期地等你发下一条指令的。如果超时了,它会自动切回默认会话。这其实是一种安全保护机制。
UDS标准里定义了三个关键的定时器:
- S3Server(默认会话超时):ECU在非默认会话(扩展或编程)下,如果超过这个时间没有收到任何诊断请求,就会自动切回默认会话。典型值是5000ms。
- S3Client(客户端超时):诊断仪(Tester)等待ECU响应的超时时间。如果ECU没在规定时间内回复,Tester会认为通信失败。
- P2Server(响应超时):ECU处理一个请求并给出响应的最大时间。如果处理时间超过P2Server,ECU必须先发一个NRC 0x78(请求正确接收,正在处理),然后再发最终的响应。
我记得有一次,一个同事在调试刷写流程时,总是刷到一半就失败。查了半天,发现是刷写时间超过了S3Server的5000ms。ECU在刷写过程中自动切回了默认会话,导致后续的数据传输全部被拒绝。解决方案很简单,在刷写循环里加一个定时发送3E 00的机制,问题就解决了。
嗯,这里要注意,S3Server的值不是固定的。有些ECU为了安全,会把编程会话的S3Server设得很短,比如1000ms。这就要求Tester的“保持激活”报文发送频率要足够高。否则,稍微一卡顿,会话就丢了。
- 会话切换失败,先看NRC,再查文档。
- 权限管理要严格遵循标准,默认、扩展、编程各司其职。
- 超时机制是安全底线,务必在Tester和ECU两端都实现好。
好了,关于0x10服务,我们就聊到这里。下一节,我们会深入探讨安全访问(0x27)服务,那又是一个充满“坑”的地方。到时候见。