3. 诊断会话控制(0x10):默认会话、编程会话、扩展会话、会话切换条件与超时处理
诊断会话控制,服务ID是0x10。说白了,它就是ECU的“工作模式切换器”。
ECU不可能永远处于同一个状态。你想想看,刷写程序时和读取故障码时,ECU需要的资源、权限、安全等级完全不一样。0x10服务就是干这个的——让诊断仪告诉ECU:“嘿,我要进哪个模式了,你准备好。”
3.1 三种标准会话:默认、编程、扩展
UDS标准定义了三种基础会话。我习惯把它们比作“三档位”:
| 会话类型 | SID + SubFunction | 典型用途 | 我见过的坑 |
|---|---|---|---|
| 默认会话 (Default Session) | 0x10 01 | 上电后的初始状态,只允许读取基本信息和故障码 | 很多工程师忘了退出其他会话,导致ECU不休眠 |
| 编程会话 (Programming Session) | 0x10 02 | 刷写Bootloader或应用程序,需要安全访问 | 刷写中掉电,ECU变砖——所以一定要有备份机制 |
| 扩展会话 (Extended Session) | 0x10 03 | 执行IO控制、写入配置、高级诊断 | 扩展会话超时后没及时重发,导致标定数据写一半失败 |
关键点:ECU上电后自动进入默认会话。如果你不主动切,它就一直待在默认会话里。很多刚入行的朋友以为ECU会“智能”地自己切到扩展会话——不会的,你得发0x10 03。
3.2 会话切换条件与流程
切换会话不是你想切就能切。ECU会检查几个条件:
- 当前会话是否允许切到目标会话——比如从编程会话切回默认会话,必须通过0x11 01(ECU复位)或0x10 01显式切换。
- 是否需要安全访问——从默认切到编程会话,通常需要先做0x27安全解锁。我遇到过一家供应商,切到扩展会话也要解锁,搞得我们排查了半天。
- 会话超时定时器是否在跑——如果当前会话的S3定时器还没超时,切换是允许的;超时了,ECU会自动跳回默认会话。
下面这张图是我自己画的会话切换逻辑,你一看就明白:
我的经验:实际项目中,很多ECU在编程会话下会关闭CAN通信的某些功能(比如网络管理报文)。如果你在刷写过程中想读个故障码,对不起,读不了。所以刷写前一定要确认好诊断仪的逻辑——先切会话,再发请求。
3.3 会话超时处理(S3定时器)
ECU不会永远待在非默认会话里。它有一个定时器,叫S3。这个定时器一旦超时,ECU就自动跳回默认会话。
S3定时器的行为:
- 进入非默认会话(编程或扩展)时,S3定时器启动。
- 每次收到任何有效的诊断请求(不仅仅是0x10),S3定时器都会重置。
- 如果S3超时,ECU自动切回默认会话,并且清空所有非默认会话下的临时状态(比如安全解锁状态)。
S3超时时间是多少?标准没有硬性规定,但常见值是:
| 应用场景 | 典型S3超时时间 | 说明 |
|---|---|---|
| 扩展会话 | 5秒 | 短超时,防止诊断仪断开后ECU一直处于高功耗模式 |
| 编程会话 | 5秒或10秒 | 刷写过程中诊断仪会持续发请求,超时时间可以稍长 |
| 某些OEM自定义会话 | 30秒甚至更长 | 用于产线标定,需要长时间保持会话 |
我曾经踩过的坑:有一次做刷写工具,我们没注意S3超时。刷写一个大文件时,中间有3秒没发任何诊断请求,结果ECU超时了,自动切回默认会话。安全解锁状态丢失,后续的刷写请求全部被拒绝。从那以后,我要求所有刷写工具必须每隔2秒发一个TesterPresent(0x3E)来保持会话。
3.4 实际项目中的会话管理策略
说了这么多理论,来点实际的。我总结了几条会话管理的“潜规则”:
- 不要频繁切换会话。每次切换都会触发ECU内部的状态机重置,有些ECU还会重新初始化硬件模块。频繁切换可能导致诊断响应变慢。
- 退出前记得清理。如果你在扩展会话下做了IO控制(比如驱动一个继电器),退出会话前最好把IO恢复到安全状态。否则ECU超时切回默认会话时,IO可能还保持在你设置的状态——这很危险。
- 编程会话下别做多余的事。刷写就是刷写,别在编程会话里读故障码、清故障码。有些ECU在编程会话下根本不会响应这些请求,反而会浪费S3定时器的时间。
- 用TesterPresent保活。0x3E服务就是干这个的。我习惯在扩展会话和编程会话下,每隔2-3秒发一次0x3E 00(零子功能,表示“我还活着”)。这样S3定时器永远不会超时。
一句话总结:会话控制是诊断通信的“门禁系统”。进错门、超时、没带钥匙(安全解锁),都会让你吃闭门羹。理解会话切换的条件和超时机制,是做好诊断开发的第一步。