4、诊断会话控制(0x10):默认会话、编程会话、扩展会话切换逻辑与测试要点

各位工程师朋友,咱们今天聊聊诊断会话控制。这个服务,服务ID是0x10,说白了就是让ECU知道“我现在要以什么身份跟你说话”。

我刚开始做UDS测试时,觉得这玩意儿太简单了——不就是发个请求切个模式嘛。后来踩了几个坑才发现,会话切换背后的逻辑,远比想象中复杂。你想想看,ECU在不同的生命周期阶段,需要开放不同的权限。默认会话下只能读读数据,编程会话才能刷写固件,扩展会话则能执行一些特殊维护操作。

4.1 三种会话模式的定义

UDS标准定义了三种标准会话,咱们一个一个说。

会话模式 子功能ID 典型用途 我个人的理解
默认会话(Default Session) 0x01 常规诊断通信,只读操作 就像ECU的“待客区”,安全但功能有限
编程会话(Programming Session) 0x02 刷写固件、更新软件 ECU的“手术室”,权限最高
扩展会话(Extended Session) 0x03 特殊功能、标定、调试 ECU的“维修车间”,比默认多些权限

嗯,这里要注意:有些厂商还会自定义会话,比如0x40~0x5F是留给OEM自己定义的。我在项目中遇到过一家主机厂,他们用0x40做“产线终检会话”,专门用来做下线前的功能验证。

4.2 会话切换的逻辑规则

会话切换不是你想切就能切的。ECU内部有一套严格的状态机。我习惯用一张图来理解这个逻辑:

默认会话(0x01)
    |
    ├──→ 编程会话(0x02)  ←── 需要安全访问
    ├──→ 扩展会话(0x03)  ←── 可能需要安全访问
    └──→ 其他自定义会话

切换规则其实就三条:

  • 从默认会话可以切换到任何会话——但编程会话通常需要先做安全访问(0x27服务)
  • 非默认会话之间可以直接切换——比如从扩展会话切到编程会话,不需要先回默认
  • 任何会话都可以切回默认会话——这是最安全的操作,ECU收到0x10 0x01请求,必须无条件响应

为什么会这样设计?你想想看,如果刷写过程中出了异常,ECU必须能快速回到一个安全状态。默认会话就是那个“安全港湾”。

4.3 会话超时与保持

这个坑我踩过。ECU不会永远待在非默认会话里。它有一个定时器,叫S3Server定时器。如果在这个时间内没有收到任何诊断请求,ECU会自动切回默认会话。

标准规定S3Server的典型值是5秒。但实际项目中,我见过3秒的,也见过10秒的。我曾经在一个项目中,因为没注意客户把超时时间改成了2秒,结果刷写过程中频繁超时回退,折腾了两天才找到原因。

⚠️ 重要提醒:

测试时一定要确认S3Server的实际值。不要想当然用5秒。我曾经在测试报告中漏掉这个参数,被客户评审时当场指出来,场面一度非常尴尬。

保持会话活跃的方法很简单:在超时时间内,发送任意诊断请求(比如0x3E TesterPresent服务,或者周期性的读数据)。我个人习惯用0x3E,因为它不改变ECU状态,纯粹是“心跳包”。

4.4 测试要点与实战经验

好了,理论说完了,咱们聊聊测试。这部分我踩过的坑比较多,一个一个说。

4.4.1 基本功能测试

这是最基础的,但也是最容易出问题的。

  • 正向测试:从默认切到编程,再切回默认;从默认切到扩展,再切回默认。每个切换都要检查响应码是不是0x00(正响应)。
  • 负向测试:比如在编程会话下,尝试切到另一个编程会话(0x02→0x02),应该返回NRC 0x12(子功能不支持)。
  • 边界测试:发送0x10 0x00(无效子功能),应该返回NRC 0x12。
💡 我的小技巧:

测试时,我习惯用CANoe写一个自动化脚本,循环发送切换请求并检查响应。手动测太累了,而且容易漏掉边界情况。

4.4.2 会话超时测试

这个测试很关键,但很多工程师会忽略。

  1. 切到编程会话,然后停止发送任何请求
  2. 等待S3Server超时(比如5秒)
  3. 发送一个0x22读数据请求,检查ECU是否在默认会话下响应
  4. 如果ECU还在编程会话,说明超时逻辑有问题

我记得有一次测试,ECU的超时时间设成了30秒,但客户要求是5秒。这种问题如果不测出来,到了产线上就是批量事故。

4.4.3 安全访问与会话切换的联动测试

编程会话通常需要安全访问。测试时要验证:

  • 没有安全访问时,切到编程会话是否被拒绝(应该返回NRC 0x33)
  • 安全访问成功后,切到编程会话是否成功
  • 安全访问超时后,再切到编程会话是否被拒绝

我曾经遇到一个ECU,安全访问成功后切到编程会话,但编程会话里又要求重新做安全访问。这种“双重认证”的设计,说实话不太合理,但确实存在。

4.4.4 会话切换对正在进行的服务的影响

这个点比较隐蔽。假设你正在执行一个0x31 RoutineControl服务(比如擦除Flash),这时候突然切到默认会话,会发生什么?

标准规定:会话切换会终止当前正在执行的诊断服务。但实际项目中,有些ECU会继续执行完再切换,有些会立即中断。我建议测试时专门构造这种场景,看看ECU的行为是否符合预期。

重点总结:

  • 会话切换是UDS测试的基础,必须熟练掌握三种会话的切换逻辑
  • S3Server超时是常见坑点,测试时务必确认实际值
  • 安全访问与会话切换的联动测试不能跳过
  • 会话切换对正在执行的服务的影响,需要专项测试

好了,关于诊断会话控制,今天就聊这么多。下一章咱们聊聊安全访问服务(0x27),那个更刺激,各种加密算法和种子密钥的坑,够咱们喝一壶的。