3、诊断会话基础:默认会话、编程会话、扩展会话的概念与切换机制
各位同学,今天我们来聊聊诊断会话。说实话,这是UDS协议里最基础、也最容易踩坑的地方。我刚入行那会儿,就因为在会话切换上吃了亏,导致ECU刷写失败,整车差点返厂。嗯,咱们今天就把这块彻底讲透。
3.1 三种会话,三种身份
UDS定义了三种诊断会话,你可以把它们想象成ECU的三种工作模式。每种模式下,ECU愿意听你指挥的程度不一样。
| 会话类型 | SID (0x10子功能) | 典型用途 | 安全等级 |
|---|---|---|---|
| 默认会话 (Default Session) | 0x01 | 日常通讯、读取故障码 | 最低 |
| 编程会话 (Programming Session) | 0x02 | 刷写软件、更新固件 | 最高 |
| 扩展会话 (Extended Session) | 0x03 | 标定、配置、特殊功能 | 中等 |
你想想看,ECU上电后默认进入的是哪个?对,默认会话。这个状态下,ECU只开放最基础的服务,比如读取DTC、读取数据。说白了,就是让你看看车有没有毛病,但不让你动手修。
核心要点:默认会话是ECU的"待客之道"——客气但有限。所有诊断通讯都从默认会话开始。
3.2 切换机制:0x10服务
会话切换靠的是0x10服务,也叫DiagnosticSessionControl。它的报文结构很简单:
请求:0x10 + 子功能(目标会话类型)
响应:0x50 + 子功能 + 会话参数(可选)
举个例子,从默认会话切换到编程会话:
请求:02 10 02
响应:06 50 02 00 32 00 C8
响应里的00 32和00 C8是什么意思?0x0032是50ms,0x00C8是200ms。这两个参数告诉诊断仪:
- P2_Server_max:ECU处理单个请求的最大时间(50ms)
- P2*_Server_max:ECU处理连续请求的扩展时间(200ms)
我在项目中遇到过,有些ECU在编程会话下会把P2时间拉得很长,因为刷写时CPU很忙,响应慢是正常的。如果你用默认会话的P2时间去等,肯定会超时。
个人习惯:我每次切换会话后,都会先读一下ECU返回的P2/P2*参数,而不是用默认值。不同供应商的ECU,参数差异很大。
3.3 会话间的"潜规则"
会话切换不是你想切就能切的。有几个关键规则,我建议你记牢:
- 只能从低到高?不一定。 你可以从默认切到编程,也可以从编程切回默认。但有些ECU不允许从扩展直接切到编程,必须先回默认。
- 会话有超时机制。 如果ECU在编程会话或扩展会话下长时间(通常是5秒)没有收到任何诊断请求,它会自动跳回默认会话。这叫
S3Server定时器。 - 安全访问与会话绑定。 你切到编程会话后,如果之前做过安全解锁,解锁状态可能会丢失。我吃过这个亏——刷写到一半发现需要重新解锁,结果超时了。
避坑指南:我曾经在一个项目中,ECU在编程会话下执行了擦除操作,然后因为网络抖动,诊断仪没及时发送后续数据。ECU等了几秒后自动切回默认会话,但Flash里的程序已经被擦了一半...嗯,从那以后,我每次做刷写都会先禁用S3超时,或者用TesterPresent(0x3E)服务保持会话活跃。
3.4 实际项目中的会话管理策略
讲点实战经验。在量产诊断工具中,会话管理通常是这样设计的:
- 第一步:发送0x10 03切换到扩展会话,读取一些配置参数。
- 第二步:如果需要刷写,先切回默认会话(0x10 01),再切到编程会话(0x10 02)。
- 第三步:刷写完成后,主动切回默认会话,让ECU恢复正常工作状态。
为什么要先回默认再切编程?因为有些ECU在扩展会话下不允许执行编程会话的某些操作。说白了,这是ECU设计者给自己留的后门——防止你在错误的状态下搞破坏。
另外,我建议你在代码里加一个会话状态机。别小看这个,很多诊断工具出问题,都是因为会话状态乱了。比如:
// 伪代码示例
enum SessionState {
DEFAULT,
EXTENDED,
PROGRAMMING
};
void handleDiagnosticRequest(uint8_t* request) {
if (request[0] == 0x10) {
// 切换会话前,先检查当前状态是否允许
if (isTransitionAllowed(currentSession, request[1])) {
currentSession = request[1];
// 重置S3超时定时器
resetS3Timer();
sendPositiveResponse();
} else {
sendNegativeResponse(NRC_INVALID_SESSION);
}
}
}
这个状态机看起来简单,但实际项目中,你还要考虑多线程访问、网络中断、ECU复位等边界情况。我记得有一次,ECU在编程会话中突然复位,诊断仪这边还傻傻地以为会话还在,结果发了一堆请求全部被拒。后来我们加了一个心跳检测,每次通讯前先确认会话状态。
3.5 小结
三种会话,说白了就是ECU的三种权限等级。默认会话让你看,扩展会话让你调,编程会话让你改。切换靠0x10服务,但要注意超时、安全访问和状态机管理。
下一章我们会讲安全访问(0x27服务),到时候你会看到,会话和安全是怎么配合的。嗯,那又是一个容易踩坑的地方。