诊断服务详解(上):诊断会话控制(0x10)、ECU复位(0x11)、安全访问(0x27)、通信控制(0x28)
各位好,今天我们聊聊诊断服务里最基础、也最常用的四个服务。说实话,搞诊断这么多年,我见过太多工程师在0x27安全访问上翻车,也见过不少人把0x28通信控制用错了场景。今天咱们就把这几个服务掰开揉碎了讲清楚。
一、诊断会话控制 (0x10)
这个服务,说白了就是告诉ECU:「我要开始跟你聊天了,你准备好没?」。ECU收到这个请求后,会切换到对应的会话模式。
我个人习惯把会话模式分成三类:
- 默认会话 (Default Session):上电后的初始状态,功能受限,只能做基本诊断
- 编程会话 (Programming Session):用于刷写软件,通信速率通常更高
- 扩展会话 (Extended Session):允许执行一些特殊功能,比如读写参数、执行例程
这里有个关键点——会话切换是有条件的。比如从默认切到编程会话,ECU内部会做一系列准备动作。我在项目中遇到过一个问题:某ECU在切换会话时没有正确处理正在进行的非诊断通信,结果导致CAN总线上的应用报文丢失。嗯,后来我们在会话切换逻辑里加了个「优雅退出」机制才解决。
重要提示:0x10服务的响应中,子功能参数会原样返回。比如你发02表示切到编程会话,ECU回复时也会带02。这是用来确认ECU正确识别了你的请求。
二、ECU复位 (0x11)
这个服务,你想想看,其实就是让ECU重启。但重启的方式有讲究:
| 子功能 | 含义 | 实际场景 |
|---|---|---|
| 0x01 | 硬复位 (Hard Reset) | 相当于断电重启,所有RAM数据丢失 |
| 0x02 | 钥匙关/开复位 (Key Off/On Reset) | 模拟点火开关动作,部分ECU会保留一些数据 |
| 0x03 | 软复位 (Soft Reset) | 仅复位软件,不重新初始化硬件 |
| 0x04 | 快速启动复位 (Enable Rapid Power Shutdown) | 用于支持快速启动的ECU |
我曾经踩过一个坑:用0x01硬复位一个正在刷写的ECU,结果导致Flash里写了一半的数据损坏,ECU直接变砖了。所以后来我定了个规矩——刷写过程中绝对不允许执行0x11服务,除非你想体验一下拆ECU的快乐。
避坑指南:复位后ECU会回到默认会话。如果你在扩展会话里做了些配置,复位后这些配置就没了。我曾经有个同事,调试时每次复位完都要重新发一遍配置命令,后来我建议他把配置参数存到NVRAM里,复位后自动恢复,省了不少事。
三、安全访问 (0x27)
这个服务,说白了就是ECU的「门禁系统」。你想执行一些敏感操作(比如写Flash、修改标定参数),必须先通过安全验证。
流程是这样的:
- 客户端发请求种子 (Seed) —— 子功能0x01/0x03/0x05等
- ECU返回一串随机数(种子)
- 客户端用种子计算密钥 (Key),发回去 —— 子功能0x02/0x04/0x06等
- ECU自己也算一遍,比对一致就解锁
这里有个细节很多人会忽略:种子是有时效性的。我见过一个设计,种子生成后如果30秒内没收到正确的Key,种子就失效了。而且每次请求种子,ECU都会生成新的,防止重放攻击。
我的经验:安全算法通常用AES或自定义的异或+移位算法。我个人建议用标准算法,因为自定义算法一旦被破解,整个产品线的安全防线就全垮了。我之前参与的一个项目,用的就是AES-128,虽然计算量大了点,但安全性有保障。
你可能会问:「为什么要有安全访问?」。其实很简单——防止误操作。你想啊,如果谁都能随便改ECU里的数据,那车还怎么开?我见过一个案例,有人用诊断仪误改了发动机的喷油脉宽,结果发动机直接爆震了。所以安全访问不是摆设,是保护线。
四、通信控制 (0x28)
这个服务,用来控制ECU的通信行为。说白了就是告诉ECU:「你现在可以/不可以发某些报文」。
子功能定义如下:
- 0x00:使能Rx/Tx(恢复正常通信)
- 0x01:使能Rx,禁用Tx(只能收,不能发)
- 0x02:禁用Rx,使能Tx(只能发,不能收)
- 0x03:禁用Rx/Tx(完全静默)
我记得有一次,在整车上做网络测试,需要单独测某个ECU的通信。其他ECU一直在发报文,干扰测试结果。这时候0x28就派上用场了——我把其他ECU的Tx都禁掉,只留被测ECU发报文,测试环境瞬间就干净了。
注意:0x28控制的是应用报文,不是诊断报文。也就是说,你禁了Tx,ECU照样能回复你的诊断请求。这个设计很巧妙,保证了诊断链路永远畅通。
另外,0x28还有一个隐藏用法——配合刷写使用。刷写时,ECU需要暂时停止发送应用报文,以免干扰刷写过程。刷写完成后,再用0x28恢复通信。我见过有些工程师直接用0x28的0x03子功能把ECU静默掉,结果刷完后忘了恢复,导致整车网络瘫痪。嗯,后来我们在刷写流程里加了个「恢复通信」的强制步骤,才彻底解决这个问题。
小结
这四个服务,是诊断的基石。0x10管会话,0x11管复位,0x27管安全,0x28管通信。搞懂了它们,后面的诊断服务就好理解了。
最后说一句:实际开发中,一定要考虑异常场景。比如0x27验证失败后,ECU应该怎么处理?是直接拒绝,还是允许重试?重试次数有没有限制?这些细节,标准里没说,但你的设计里必须有。
好了,今天就聊到这儿。下一节我们继续讲剩下的几个常用服务,到时候再跟大家分享一些实战经验。