2、诊断会话基础:会话状态机、非默认会话、默认会话、编程会话、扩展会话

好,咱们正式开始聊诊断会话。说实话,这是UDS协议里最基础、也最容易踩坑的一块。很多新手工程师一上来就想着发诊断请求,结果发现ECU根本不搭理你——为什么?因为会话没切对。

我个人习惯把诊断会话理解成ECU的“工作模式”。就像手机有飞行模式、静音模式、正常模式一样,ECU也有几种不同的会话状态。每种状态下,它能干的事儿不一样,能访问的服务也不一样。

2.1 会话状态机:ECU的“门禁系统”

先说说状态机。你想想看,ECU上电后,它不可能一上来就允许你刷写程序或者做安全访问。它得有个“门禁系统”,这就是会话状态机。

UDS标准里定义了三种默认会话,以及若干非默认会话。ECU上电后,自动进入默认会话(Default Session)。这是最基础的状态,只允许你做一些“人畜无害”的操作,比如读取VIN码、读取故障码。想干点别的?对不起,请先切换会话。

我记得有一次,客户反馈说ECU无法响应0x22服务(读取数据)。我排查了半天,最后发现是ECU处于默认会话,而客户想读的那个DID(数据标识符)在默认会话下根本不可用。嗯,这就是典型的会话没切对。

核心要点:会话状态机决定了ECU当前能做什么、不能做什么。每个会话都有自己支持的“服务列表”和“子功能列表”。

2.2 默认会话:ECU的“待机模式”

默认会话,说白了就是ECU上电后的初始状态。在这个状态下,ECU只开放最基本的诊断服务。比如:

  • 0x10(诊断会话控制)—— 允许你切换到其他会话
  • 0x22(读取数据)—— 但只能读一部分DID
  • 0x19(读取故障码)—— 这个一般开放
  • 0x3E(测试仪在线)—— 保持连接

我刚开始做UDS开发时,总觉得默认会话“没啥用”。后来在项目里遇到一个问题:ECU在默认会话下,如果收到非法的诊断请求,会直接回复NRC(否定响应码)0x78(请求正确接收,但响应待定)。这个设计其实是为了防止ECU被恶意攻击。你想想看,如果任何人在任何状态下都能刷写ECU,那车还安全吗?

避坑指南:我曾经在默认会话下尝试发送0x2E服务(写入数据),结果ECU回复了NRC 0x7F(服务不支持)。后来查规范才知道,0x2E服务在默认会话下根本不允许使用。所以,写代码前一定要先确认当前会话支持哪些服务。

2.3 非默认会话:ECU的“高级模式”

非默认会话,就是除了默认会话以外的所有会话。UDS标准里定义了两种非默认会话:编程会话(Programming Session)扩展会话(Extended Session)。当然,OEM也可以自定义一些会话,但最常用的就是这两个。

非默认会话有个特点:它们都有“超时机制”。如果ECU在非默认会话下,一段时间内没有收到任何诊断请求,它会自动切回默认会话。这个超时时间一般是5秒左右,具体看OEM定义。

我记得有个项目,测试工程师抱怨说“ECU总是莫名其妙地切回默认会话”。我一看代码,发现是测试仪发送诊断请求的间隔超过了5秒。嗯,这就是典型的超时问题。解决方案很简单:要么缩短请求间隔,要么在空闲时发送0x3E服务(测试仪在线)来“续命”。

2.4 编程会话:ECU的“刷写模式”

编程会话,说白了就是用来刷写ECU固件的。在这个会话下,ECU会开放一些“高危”服务,比如:

  • 0x34(请求下载)
  • 0x36(传输数据)
  • 0x37(请求退出传输)
  • 0x31(例程控制)—— 用于擦除Flash等操作

进入编程会话前,通常需要先做安全访问(Security Access)。这个咱们后面会详细讲。简单说,就是ECU会问你“密码是多少”,你答对了才能进入编程会话。

我遇到过最坑的一个问题:某次刷写过程中,ECU突然断电了。重新上电后,ECU进入了“半砖”状态——既不能正常启动,也无法再次刷写。后来查原因,是因为刷写过程中,Flash的某个扇区被擦除了,但新数据还没写进去。嗯,这就是为什么刷写流程里一定要有“校验”和“回滚”机制。

警告:编程会话下,ECU的很多功能会暂停。比如,发动机控制ECU在编程会话下,可能不会响应油门踏板信号。所以,刷写时一定要确保车辆处于安全状态(比如熄火、挂P挡)。

2.5 扩展会话:ECU的“调试模式”

扩展会话,你可以把它理解成ECU的“调试模式”。在这个会话下,ECU会开放一些“高级诊断”服务,比如:

  • 0x2F(输入输出控制)—— 可以强制控制某个执行器
  • 0x31(例程控制)—— 用于执行一些特殊功能
  • 0x22(读取数据)—— 可以读取更多DID

扩展会话常用于产线终检、售后维修等场景。比如,在4S店,技师可以用诊断仪进入扩展会话,然后强制打开某个电磁阀,检查它是否工作正常。

我个人习惯在开发阶段,直接让ECU进入扩展会话。因为在这个会话下,我能访问到几乎所有诊断服务,调试起来特别方便。但要注意,扩展会话下做的某些操作可能会影响车辆安全。比如,强制控制制动系统的执行器,如果操作不当,可能会造成危险。

2.6 会话切换的“潜规则”

最后,聊几个会话切换的“潜规则”。这些是我在实际项目中总结出来的,规范里不一定写得那么细。

  1. 会话切换需要“权限”:从默认会话切换到非默认会话,通常不需要安全访问。但从一个非默认会话切换到另一个非默认会话,有些ECU会要求重新做安全访问。
  2. 会话切换会“重置”某些状态:比如,你在扩展会话下做了安全访问,然后切到编程会话,安全访问的状态可能会被重置。也就是说,你需要重新做一次安全访问。
  3. 会话切换的“响应时间”:ECU切换会话需要时间,一般是几十毫秒到几百毫秒。如果你连续发送切换请求,ECU可能会回复NRC 0x78(请求正确接收,但响应待定)。

我记得有一次,测试仪连续发送了两次0x10 03(切换到扩展会话),结果ECU回复了NRC 0x22(条件不满足)。后来查代码,发现是ECU在第一次切换还没完成时,收到了第二次请求。嗯,这就是典型的“并发问题”。解决方案很简单:在发送下一个请求前,先等待上一个请求的响应。

总结一下:诊断会话是UDS协议的基础。默认会话是“待机模式”,编程会话是“刷写模式”,扩展会话是“调试模式”。切换会话时,要注意超时、权限、状态重置等问题。下一章,咱们聊聊安全访问——怎么让ECU相信你是“自己人”。