第2章 UDS 服务详解(上):诊断会话控制 (0x10)、ECU 复位 (0x11)、安全访问 (0x27)、通信控制 (0x28)、测试仪在线 (0x3E)

好,咱们直接进入正题。这一章我打算把UDS里最基础、也最常用的几个服务掰开揉碎了讲。你想想看,诊断这事儿,说白了就是测试仪和ECU之间的一场对话。而这场对话怎么开始、怎么切换模式、怎么让对方重启、怎么上锁解锁、怎么保持连接——就是这几个服务要干的事。

我个人习惯,每次讲课时都会先问学员一个问题:“你们觉得,ECU最怕什么?” 答案其实很简单——怕乱来。所以UDS设计了会话状态机,就是为了防止测试仪在不合适的时机发送不合适的指令。嗯,咱们就从会话控制开始。

2.1 诊断会话控制 (0x10)

这个服务,是所有诊断通信的起点。ECU上电后默认处于一个会话状态,通常是默认会话 (Default Session)。在这个状态下,很多功能是被限制的,比如刷写、读写某些敏感数据。为什么?安全考虑。

0x10服务的请求格式很简单:

请求: 0x10 + 子功能 (会话类型)
响应: 0x50 + 子功能 + 可选参数 (如P2ServerMax, P2*ServerMax)

常见的子功能有:

子功能 (Hex) 会话名称 典型用途
0x01 默认会话 基本通信,功能受限
0x02 编程会话 刷写ECU固件
0x03 扩展会话 解锁高级诊断功能

关键点:ECU在收到0x10请求后,会切换会话状态,并返回当前会话下的超时参数。P2ServerMax是服务响应的最大等待时间,P2*ServerMax是扩展等待时间。这两个参数直接影响你的测试脚本设计。

我在项目中遇到过一个问题:某ECU在扩展会话下,P2ServerMax设成了50ms,但实际响应需要80ms。结果测试仪一直报超时。后来发现是ECU的计时器配置有偏差。所以啊,一致性测试不只是测功能,还得测时间参数

2.2 ECU 复位 (0x11)

这个服务,说白了就是让ECU重启。你可能会想:“重启有什么好讲的?” 嗯,这里面的坑可不少。

0x11服务支持三种复位类型:

  • 0x01:硬复位 (Hard Reset) —— 模拟断电再上电,ECU完全重新初始化。
  • 0x02:钥匙复位 (Key Off/On Reset) —— 模拟点火开关关闭再打开,部分状态保留。
  • 0x03:软复位 (Soft Reset) —— 仅重启应用层软件,不重启底层驱动。

注意:复位后,ECU会回到默认会话。如果你在编程会话中发送复位,那刷写就中断了。我曾经见过一个案例,测试脚本在刷写完成后忘记发送复位,结果ECU一直卡在编程会话里,下次诊断连不上。嗯,这就是典型的“忘记收尾”。

另外,复位响应里通常会包含一个powerDownTime参数,表示ECU需要多长时间才能完成复位。这个时间如果太短,ECU可能还没准备好就收到了新请求,导致通信失败。我建议你在做一致性测试时,至少等待2倍powerDownTime再发下一条指令

2.3 安全访问 (0x27)

这个服务,是UDS里最“刺激”的一个。为什么?因为它涉及种子和密钥的交换。说白了,就是ECU给你出一道题,你得答对了才能解锁高级功能。

流程是这样的:

  1. 测试仪发送 请求种子 (Request Seed),子功能通常是奇数 (如0x01, 0x03)。
  2. ECU返回一个种子 (Seed),通常是4字节或8字节的随机数。
  3. 测试仪根据种子计算密钥 (Key),发送 发送密钥 (Send Key),子功能是偶数 (如0x02, 0x04)。
  4. ECU验证密钥,如果正确,返回肯定响应;否则返回否定响应 (NRC 0x35)。

避坑指南:我曾经遇到过ECU的种子生成算法有bug,每次请求都返回相同的种子。这导致密钥很容易被破解。所以一致性测试里,一定要验证种子的随机性。另外,安全访问失败次数过多,ECU会锁定一段时间,这个时间通常是几十秒到几分钟。测试时别连续失败太多次,否则你得等很久才能继续。

这里有个常见的误解:很多人以为安全访问只用于刷写。其实不是。很多ECU的扩展会话下的诊断服务也需要先解锁安全访问。比如读写某些标定数据、执行某些特殊功能。所以,安全访问是UDS里的一道“门禁”。

2.4 通信控制 (0x28)

这个服务,用来控制ECU的通信行为。你想想看,有时候你正在刷写ECU,不希望它往外发一堆报文干扰总线,怎么办?用0x28把通信关掉。

0x28服务有三个主要子功能:

  • 0x00:使能通信 (Enable Communication) —— 恢复ECU的正常通信。
  • 0x01:禁用通信 (Disable Communication) —— 停止ECU发送和接收应用报文。
  • 0x02:禁用发送 (Disable Transmission) —— 只停止发送,但可以接收。
  • 0x03:禁用接收 (Disable Reception) —— 只停止接收,但可以发送。

实际应用:在刷写过程中,通常先发送0x28 0x01禁用通信,然后进行刷写,刷写完成后发送0x28 0x00恢复通信。这样可以避免ECU在刷写过程中响应其他报文,导致刷写出错。

我记得有一次,测试时发现ECU在禁用通信后,仍然在发送某个周期报文。查了半天,发现是ECU的通信栈实现有bug,没有完全禁用所有类型的报文。所以一致性测试里,一定要验证禁用通信后,ECU确实不再发送任何应用报文

2.5 测试仪在线 (0x3E)

这个服务,俗称“心跳包”。它的作用很简单:告诉ECU“我还活着,别断开连接”。

为什么需要这个?因为ECU有会话超时机制。如果在一定时间内没有收到任何诊断请求,ECU会自动回到默认会话。这个时间就是前面提到的S3Server参数,通常是几秒钟。

0x3E服务只有一个子功能:

请求: 0x3E 0x00
响应: 0x7E 0x00

就这么简单。但它的重要性不容忽视。尤其是在刷写过程中,如果刷写时间较长,你需要定期发送0x3E来保持会话。否则ECU一旦超时回到默认会话,刷写就会中断。

我的经验:发送0x3E的频率,建议是S3Server时间的一半。比如S3Server是5秒,那你就每2.5秒发一次。别太频繁,也别太稀疏。太频繁浪费总线带宽,太稀疏容易超时。另外,0x3E不会重置P2Server计时器,所以别指望用它来延长单次服务的等待时间。

嗯,这一章的内容就到这里。这几个服务是UDS的基石,你掌握了它们,后面的高级服务才能玩得转。下一章咱们继续讲剩下的几个常用服务,包括数据读取、写入和例程控制。到时候见。