3、诊断会话控制(0x10):默认会话、编程会话、扩展会话的切换逻辑与安全策略
大家好,我是老张。今天咱们聊聊诊断会话控制,也就是0x10服务。这个服务在OTA刷写里,可以说是「开门」的动作。门开不对,后面的事全白搭。
我个人习惯把会话切换理解成「权限升级」。你想想看,车上的ECU平时跑得好好的,不能谁发个报文就能改程序吧?那不乱套了。所以UDS定义了三种会话状态,每种状态能做的事不一样。
3.1 三种会话状态
先看一张表,把三种会话说清楚:
| 会话类型 | SID | 子功能 | 主要用途 | 典型超时时间 |
|---|---|---|---|---|
| 默认会话 | 0x10 | 0x01 | 正常通信、读取故障码 | 5000ms |
| 编程会话 | 0x10 | 0x02 | 刷写、下载、上传数据 | 5000ms(可协商) |
| 扩展会话 | 0x10 | 0x03 | 读写参数、执行例程、标定 | 5000ms |
嗯,这里要注意:默认会话是ECU上电后的初始状态。说白了,就是「啥也没干」的状态。在这个状态下,你只能读读VIN码、看看故障码,想干点别的?不行。
编程会话,才是OTA刷写的核心战场。只有进入编程会话,才能执行34(请求下载)、36(传输数据)、37(退出传输)这些刷写相关的服务。
扩展会话呢?我经常把它叫做「调试模式」。你在产线上做EOL(下线检测)时,或者售后做参数标定时,用的就是它。它比默认会话权限高,但比编程会话低。
3.2 会话切换逻辑
切换逻辑其实不复杂,但有几个坑。我一个个说。
3.2.1 切换方向
三种会话之间可以互相切换。但有个潜规则:从低权限往高权限切,通常需要安全访问(0x27)配合。从高权限往低权限切,直接发报文就行。
举个例子:
- 默认会话 → 编程会话:需要先做安全解锁(0x27),再发0x10 02
- 编程会话 → 默认会话:直接发0x10 01,ECU就回去了
- 扩展会话 → 编程会话:也需要安全解锁
为什么会这样?你想想看,如果谁都能随便切到编程会话,那刷写岂不是毫无安全可言?
3.2.2 会话保持与超时
这里有个关键点:会话不是永久的。ECU内部有个定时器,叫S3Server。默认是5000ms。如果在这个时间内没有收到任何诊断请求,ECU会自动跳回默认会话。
3.2.3 会话切换的报文格式
发一个0x10服务请求,格式很简单:
请求:02 10 02 00 00 00 00 00
↑ ↑ ↑
| | └─ 子功能:02 = 编程会话
| └─ SID:0x10
└─ 数据长度:2字节
ECU正常响应:
响应:02 50 02 00 00 00 00 00
↑ ↑ ↑
| | └─ 子功能:02(请求成功)
| └─ 响应SID:0x50 = 0x10 + 0x40
└─ 数据长度:2字节
如果ECU不支持切换,或者当前状态不允许,会返回否定响应码(NRC)。常见的NRC有:
- 0x12:子功能不支持(你发的会话类型ECU没实现)
- 0x22:条件不满足(比如没做安全解锁就想切编程会话)
- 0x78:请求正确,但正在处理,请稍候重试
3.3 安全策略
会话切换的安全策略,说白了就是「谁可以做什么」。我总结了几条核心原则:
3.3.1 安全访问(0x27)是门槛
从默认会话切到编程会话,必须先过安全访问这一关。安全访问的流程是:
- Tester发请求种子(0x27 01)
- ECU返回一个随机种子
- Tester用密钥算法计算密钥,发回去(0x27 02)
- ECU验证通过,解锁成功
我曾经见过一个项目,安全访问的密钥算法写死了,所有ECU的密钥都一样。结果呢?刷写工具被逆向,密钥泄露,整车厂的刷写安全形同虚设。所以,密钥算法一定要差异化,最好每台ECU、每次上电都不同。
3.3.2 会话切换的「单向性」
默认会话 → 编程会话:需要安全解锁
编程会话 → 默认会话:不需要解锁
扩展会话 → 编程会话:需要安全解锁
编程会话 → 扩展会话:不需要解锁
这个设计很有意思。你想想看,一旦进入了编程会话,ECU就认为你是「可信的」。你主动降级到低权限会话,ECU不会拦你。但反过来,从低权限往高权限走,必须验明正身。
3.3.3 超时自动降级
这是最后一道防线。如果Tester在编程会话中突然断连,或者刷写过程中出现异常,ECU的S3Server定时器会触发,自动跳回默认会话。这时候,任何刷写相关的服务都无法执行了。
3.4 实际项目中的避坑指南
最后,分享几个我踩过的坑:
- 坑1: 有些ECU在编程会话中,会禁用部分通信功能(比如CAN的某些报文)。如果你在刷写过程中还想读其他数据,可能会失败。所以,刷写前确认好ECU的行为。
- 坑2: 安全访问的种子和密钥,长度要匹配。我见过一个项目,种子是4字节,密钥算法却只用了2字节,结果暴力破解只需要65536次尝试。嗯,这跟没锁门差不多。
- 坑3: 会话切换的响应时间。有些ECU处理0x10请求很慢,尤其是从编程会话切回默认会话时,要释放资源、保存状态。如果Tester发完切换请求后立刻发下一条,可能会收到NRC 0x78。所以,建议加一个100ms的延时。
好了,关于诊断会话控制,今天就聊这么多。记住一句话:会话切换是OTA刷写的「门禁系统」。门开对了,后面的事才顺。下一章,咱们聊聊安全访问(0x27)的细节,那才是真正的「锁」。