2、诊断会话控制(0x10服务):会话切换机制、默认/扩展/编程会话的区别、会话超时处理

各位好,我是老张。今天咱们聊聊诊断会话控制,也就是0x10服务。这个服务在刷写流程里,可以说是第一道门槛。你连会话都切不过去,后面啥也干不了。

我记得刚入行那会儿,有个同事在产线上折腾了一下午,刷写总是失败。最后发现,他压根没切到编程会话。嗯,这种低级错误,咱们得避免。

2.1 会话切换机制:说白了就是敲门

诊断会话控制,说白了就是ECU在跟你说:「你是谁?你想干嘛?」。ECU平时处于一个默认状态,只有你发送了正确的0x10服务请求,它才会切换到对应的模式。

请求格式很简单:

请求:0x10 + 子功能(会话类型)
响应:0x50 + 子功能 + 会话超时时间(可选)

举个例子,我想切到编程会话:

请求:02 10 02
响应:06 50 02 00 0E 10 00

这里0x02就是编程会话的ID。响应里的00 0E 10 00,表示超时时间。我习惯把这个时间换算成秒,方便调试。

小技巧: 实际项目中,我建议你在发送切换请求后,立即启动一个定时器。如果超过2秒没收到响应,就该考虑重试了。别傻等。

2.2 三种会话的区别:默认、扩展、编程

这三种会话,就像ECU的三个工作模式。咱们一个一个说。

会话类型 子功能ID 主要用途 可用的诊断服务
默认会话 0x01 日常通信、读取基本数据 0x10, 0x3E, 0x22, 0x2E(部分)
扩展会话 0x03 读写参数、执行例程 默认会话 + 0x2F, 0x31, 0x34等
编程会话 0x02 刷写、解锁、安全访问 扩展会话 + 0x34, 0x36, 0x37, 0x31等

默认会话(0x01): 这是ECU上电后的初始状态。说白了,就是「待机模式」。你只能读读VIN码、看看故障码。想干点别的?不行。

扩展会话(0x03): 这个模式我用的比较多。它允许你执行一些例程,比如读取特定数据、写入配置参数。我在调试标定参数时,经常切到这个会话。

编程会话(0x02): 刷写的核心会话。只有在这个模式下,你才能执行0x34(请求下载)、0x36(数据传输)、0x37(退出传输)这些服务。注意,编程会话通常需要先通过安全访问(0x27服务)的验证。

注意: 我曾经遇到过一个坑:有些ECU在编程会话下,会禁用某些通信功能。比如CAN报文发送频率会降低。你想想看,如果你在刷写过程中还想着读取实时数据,很可能导致刷写超时。所以,刷写期间尽量别做其他操作。

2.3 会话超时处理:别让ECU等你太久

会话超时,是很多新手容易忽略的问题。ECU不会永远等你。如果你切到编程会话后,超过一定时间没做任何操作,它会自动跳回默认会话。

这个超时时间,由ECU在响应中告诉你。比如上面例子里的00 0E 10 00,换算一下:

00 0E 10 00 = 0x000E1000 = 921600 个时间单位
时间单位通常是 0.1ms,所以超时时间 = 921600 * 0.1ms = 92160ms ≈ 92秒

嗯,大约一分半钟。看起来挺长,但刷写过程中,如果你在传输数据时卡住了,这个时间很快就过去了。

我个人的习惯是:

  • 在刷写开始前,先发一个0x3E(待机)服务,保持会话活跃。
  • 每传输完一个数据块,再发一次0x3E。
  • 如果刷写过程中需要暂停(比如等待用户确认),我会在暂停前发一个0x3E,确保会话不会超时。
避坑指南: 我曾经在量产项目中,遇到一个ECU的编程会话超时时间只有30秒。而我们的刷写文件有2MB,传输时间超过了40秒。结果每次刷到一半,会话就断了。后来我加了一个心跳机制,每传输完一个数据块就发一次0x3E,问题才解决。

2.4 实际项目中的会话切换策略

说了这么多,咱们总结一下实际项目中怎么用。

  1. 先切到扩展会话: 我习惯先切到扩展会话,读取一些基本信息,比如ECU的硬件版本、软件版本。确认无误后,再切到编程会话。
  2. 安全访问验证: 编程会话下,必须先通过安全访问(0x27服务)。否则,刷写服务(0x34等)会直接拒绝。
  3. 保持会话活跃: 刷写过程中,定期发送0x3E服务。我一般设置一个定时器,每10秒发一次。
  4. 异常处理: 如果会话超时了,不要慌。重新发送0x10服务,切回编程会话即可。但要注意,有些ECU在超时后,会清空之前的安全访问状态。你需要重新做一次安全访问验证。

你想想看,这些步骤虽然繁琐,但每一步都是为了确保刷写的稳定性和安全性。我见过太多因为忽略会话管理而导致的刷写失败案例了。

好了,关于诊断会话控制,今天就聊到这儿。下一节,咱们聊聊安全访问服务(0x27),这可是刷写过程中的「守门员」。到时候见。