4、诊断会话控制(0x10):会话切换与超时管理
诊断会话控制,服务ID是0x10。说白了,它就是ECU的“工作模式切换器”。
你想想看,ECU平时在车上跑,不可能一直开着诊断功能。那样不安全,也浪费资源。所以UDS定义了三种基本会话:默认会话、编程会话和扩展会话。它们各有各的权限,各有各的用途。
4.1 三种会话,各司其职
| 会话类型 | 子功能ID | 主要用途 | 典型权限 |
|---|---|---|---|
| 默认会话 (Default) | 0x01 | ECU上电后的初始状态 | 只读诊断数据,读取DTC |
| 编程会话 (Programming) | 0x02 | 刷写Bootloader或应用程序 | 允许内存写入,禁止非安全操作 |
| 扩展会话 (Extended) | 0x03 | 高级诊断、标定、配置 | 读写参数,执行例程,IO控制 |
我个人习惯把默认会话比作“待机模式”。ECU刚上电,或者诊断超时后,都会回到这里。在这个模式下,你只能看看故障码,读读版本号。想干点别的?不行,得先切换。
扩展会话是“调试模式”。我当年做ADAS控制器标定时,天天跟它打交道。在这个会话下,你能做IO控制、读写参数、执行例程。说白了,就是给工程师用的“后门”。
编程会话是“刷写模式”。这个最敏感。你想想,刷写过程中要是出了岔子,ECU可能就变砖了。所以进入编程会话前,通常需要先做安全解锁(0x27服务)。
4.2 会话切换机制
切换会话,就是发一条0x10服务请求。请求格式很简单:
请求: 0x10 + 子功能ID
响应: 0x50 + 子功能ID + 会话超时时间
举个例子,我想从默认会话切换到扩展会话:
请求: 02 10 03
响应: 06 50 03 00 0B B8
响应里的 00 0B B8 是超时时间,单位是毫秒。换算一下,0x0BB8 = 3000ms,也就是3秒。这意味着,如果3秒内没有收到任何诊断请求,ECU会自动跳回默认会话。
这里有个坑,我踩过。有一次,我在做Bootloader开发,发现刷写总是中途失败。查了半天,原来是超时时间设得太短。刷写一包数据要200ms,但超时只有100ms。结果ECU以为通信断了,自己切回了默认会话。嗯,从那以后,我每次都会仔细检查超时参数。
4.3 会话状态机
会话切换不是乱来的。它有一套严格的状态机。我画了一张图,你看一眼就明白了。
从图里你能看到,默认会话是“根”。所有会话超时后,都会回到这里。扩展和编程之间可以直接切换,但编程会话的门槛更高——通常需要先做安全解锁。
我遇到过一种情况:有些ECU设计得比较“死板”,从默认会话直接切编程会话,它直接拒绝。你必须先切到扩展,再切到编程。为什么?因为扩展会话里可以做安全解锁,解锁完了再进编程,流程更安全。你想想看,是不是这个理?
4.4 超时管理
超时管理是会话控制里最容易出问题的地方。我见过太多开发者在超时参数上栽跟头。
ECU在响应0x10服务时,会返回一个超时时间(P2_Server_max)。这个时间告诉Tester:你必须在这么长时间内发下一条请求,否则我就切回默认了。
超时时间不是固定的。不同ECU、不同会话,超时时间可能不一样。一般来说:
- 默认会话: 超时时间通常较长,5-10秒。
- 扩展会话: 超时时间中等,3-5秒。
- 编程会话: 超时时间最短,1-3秒。因为刷写时通信频率高,超时时间短一点更安全。
但要注意,超时时间不是越长越好。你想想,如果超时时间设成1分钟,那Tester断开后,ECU要等1分钟才能回到默认。这期间,其他诊断设备就没办法连上来了。
4.5 会话切换的NRC处理
会话切换不是总能成功的。ECU可能会返回否定响应码(NRC)。常见的NRC有:
| NRC | 含义 | 常见原因 |
|---|---|---|
| 0x12 | 子功能不支持 | 你发的子功能ID不在ECU支持列表里 |
| 0x22 | 条件不满足 | 当前有正在执行的服务,或者没做安全解锁 |
| 0x13 | 消息长度错误 | 请求格式不对,比如少了子功能ID |
| 0x31 | 请求超出范围 | 子功能ID有效,但当前状态下不允许切换 |
我遇到过最坑的一次,是0x22。当时我在调试一个ECU,想从默认切到编程。发了0x10 02,结果返回0x22。查了半天,发现是ECU的Bootloader正在后台运行一个自检程序。自检没完成,就不让切会话。嗯,后来我等到自检结束,再发请求,就成功了。
所以,遇到NRC别慌。先看看ECU当前在干什么,再对症下药。
4.6 小结
诊断会话控制,说白了就是ECU的“权限管理”。默认会话是基础,扩展会话是调试,编程会话是刷写。切换时要遵守状态机规则,注意超时时间,处理好NRC。
我个人觉得,会话控制是UDS协议里最基础,但也最容易出错的部分。很多刷写失败、诊断中断的问题,根源都在会话管理上。你只要把状态机和超时搞明白了,后面学Bootloader设计就会轻松很多。