4、UDS会话管理:默认会话、编程会话、扩展会话与超时处理

会话管理,说白了就是ECU的“工作模式切换”。你想想看,一辆车在正常行驶时,ECU肯定不能随便让你刷写固件或者修改标定参数,对吧?UDS协议里定义了三种标准会话,再加上一些厂商自定义的会话,用来控制不同诊断服务的访问权限。

我个人习惯把会话管理比作“门禁系统”。默认会话是普通员工卡,能进大门但进不了核心机房;扩展会话是技术主管卡,能进调试间;编程会话是超级管理员卡,能进固件烧录室。嗯,这个比喻虽然简单,但很贴切。

4.1 三种标准会话

ISO 14229-1里明确定义了三种会话状态,咱们一个一个说。

4.1.1 默认会话(Default Session)

ECU上电后,默认进入的就是默认会话。这是最基础的工作模式。在这个模式下,只有少数几个诊断服务是可用的,比如:

  • 0x10(诊断会话控制)—— 用来切换到其他会话
  • 0x3E(Tester Present)—— 保持连接活跃
  • 0x14(清除诊断信息)—— 清故障码
  • 0x19(读取诊断信息)—— 读故障码
  • 0x22(读取数据标识符)—— 读一些基本数据

我在项目中遇到过,有些OEM要求默认会话下连0x22都不让用,只能做会话切换和Tester Present。说白了,默认会话就是个“待机状态”,能做的事非常有限。

4.1.2 编程会话(Programming Session)

编程会话,也叫Bootloader模式。这个模式下的核心任务是刷写固件。你想想看,如果ECU在运行应用软件时去擦写Flash,那肯定出大问题。所以编程会话通常会:

  • 停止应用软件运行
  • 切换到Bootloader
  • 开放0x34(请求下载)、0x36(传输数据)、0x37(请求退出传输)等服务
  • 关闭大部分非必要的通信和功能
⚠️ 重要提醒: 编程会话下,ECU的响应时间要求通常更严格。我记得有一次,客户要求编程会话下的物理响应时间必须小于50ms,而默认会话下是500ms。这个差异在设计时一定要考虑进去。

4.1.3 扩展会话(Extended Session)

扩展会话是给工程师做标定、调试、特殊测试用的。它比默认会话开放更多服务,比如:

  • 0x2E(写入数据标识符)—— 修改标定参数
  • 0x2F(输入输出控制)—— 强制控制执行器
  • 0x31(例程控制)—— 执行特殊功能
  • 0x27(安全访问)—— 解锁受保护的功能

说白了,扩展会话就是给工程师开的“后门”。但要注意,扩展会话下修改的参数通常是掉电丢失的,除非你专门做了NVRAM存储。

4.2 会话切换条件

会话切换是通过0x10服务(DiagnosticSessionControl)来完成的。请求格式很简单:

请求:0x10 + 子功能(会话ID)
响应:0x50 + 子功能 + P2_Server_Max + P2*_Server_Max

会话ID定义:
0x01 — 默认会话(Default)
0x02 — 编程会话(Programming)
0x03 — 扩展会话(Extended)
0x40~0x5F — 厂商自定义会话

举个例子,从默认会话切换到扩展会话:

请求:02 10 03
响应:06 50 03 00 32 00 1E

响应里的00 32是P2_Server_Max(50ms),00 1E是P2*_Server_Max(30ms)。这两个时间参数很重要,后面会细说。

会话切换的规则

  • 从任何会话都可以切换到默认会话 —— 这是最安全的退路
  • 从默认会话可以切换到任何会话 —— 前提是ECU支持
  • 从扩展会话可以切换到编程会话 —— 但通常需要先做安全访问
  • 从编程会话不能直接切换到扩展会话 —— 必须先回默认会话
  • 同会话切换 —— 相当于重置该会话的超时定时器
💡 个人经验: 我曾经踩过一个坑,在编程会话下直接发0x10 03想切到扩展会话,结果ECU直接返回NRC 0x12(子功能不支持)。后来查规范才发现,编程会话只能切回默认会话。这个限制是为了防止刷写过程中意外进入调试模式。

4.3 超时处理机制

超时处理是会话管理里最容易出问题的地方。我见过不少项目,因为超时参数没配好,导致诊断通信频繁中断。

4.3.1 S3 Server 超时

每个非默认会话都有一个S3 Server定时器。如果在这个时间内没有收到任何诊断请求(包括Tester Present),ECU会自动切回默认会话。S3 Server的典型值是5秒,但OEM可以自定义。

为什么会这样?你想想看,如果诊断仪突然断开了,ECU还留在扩展会话里,那多危险。所以超时自动回退是个安全机制。

4.3.2 P2 Server 和 P2* Server 超时

这两个参数是在会话切换响应里带出来的:

  • P2_Server_Max:ECU处理一个请求的最大时间。如果超过这个时间还没响应,诊断仪可以认为请求失败。
  • P2*_Server_Max:ECU发送NRC 0x78(待处理响应)后,完成实际处理的最大时间。
会话类型 典型P2_Server_Max 典型P2*_Server_Max
默认会话 50ms 5000ms
扩展会话 50ms 5000ms
编程会话 50ms 5000ms

嗯,这里要注意,编程会话下的P2*_Server_Max通常设得比较大,因为刷写Flash本身就很耗时。

4.3.3 超时处理的实现建议

在AUTOSAR架构里,会话管理是由Dcm模块负责的。我个人习惯在Dcm配置里这样设置:

/* 伪代码示例 */
Dcm_ConfigType DcmConfig = {
  .DcmSessionCtrl = {
    .S3Server = 5000,    /* 5秒超时 */
    .P2ServerMax = 50,   /* 50ms */
    .P2StarServerMax = 5000 /* 5秒 */
  },
  .DcmSessions = {
    { .SessionId = 0x01, .S3Timer = 0 },      /* 默认会话不超时 */
    { .SessionId = 0x02, .S3Timer = 5000 },    /* 编程会话5秒超时 */
    { .SessionId = 0x03, .S3Timer = 5000 }     /* 扩展会话5秒超时 */
  }
};
🔧 避坑指南: 我曾经遇到过一个bug,扩展会话的S3 Server设成了0,结果ECU永远不回默认会话。后来排查发现,配置工具里把0解释成了“禁用超时”。所以一定要确认你的配置工具对0值的处理逻辑。

4.4 会话切换的NRC处理

会话切换请求可能返回的否定响应码:

  • 0x12(子功能不支持)—— 请求的会话ID未定义
  • 0x22(条件不满足)—— 比如在编程会话下请求切到扩展会话
  • 0x13(消息长度错误)—— 请求格式不对
  • 0x7F(服务不支持)—— 0x10服务本身被禁用

我记得有一次,客户反馈说ECU在编程会话下无法切回默认会话。我查了半天,发现是Bootloader里把0x10服务给屏蔽了。嗯,这种低级错误其实挺常见的。

4.5 总结与建议

会话管理看似简单,但实际项目中踩坑的地方不少。我建议你在设计诊断栈时,重点关注以下几点:

  1. 超时参数要合理 —— 别设得太短,也别设得太长。5秒是个不错的起点。
  2. 会话切换路径要清晰 —— 画个状态机图,确保所有路径都覆盖到。
  3. 安全访问与会话绑定 —— 通常扩展会话和编程会话需要先做安全解锁。
  4. 测试要覆盖边界条件 —— 比如在超时前一毫秒发Tester Present,看看能不能续命。

好了,会话管理这块就聊到这儿。下一章咱们聊聊安全访问,那可是诊断栈里最容易出幺蛾子的地方。