1. 诊断会话控制基础:UDS协议概述、会话状态机、默认会话与扩展会话
1.1 UDS协议到底是什么?
先聊聊UDS。全称是Unified Diagnostic Services,统一诊断服务。说白了,它就是汽车ECU之间、或者诊断仪和ECU之间沟通的“官方语言”。
我最早接触UDS是在做OBD项目的时候。那时候觉得协议栈好复杂,后来发现,你只要抓住几个核心状态机,整个框架就清晰了。UDS定义在ISO 14229标准里,它不关心底层是CAN还是以太网,只管“你说什么话,ECU怎么回”。
UDS的核心特点:
- 请求-响应模型:诊断仪发请求,ECU给响应。就这么简单。
- 服务ID(SID):每个功能对应一个ID,比如0x10是诊断会话控制,0x27是安全访问。
- 子功能:同一个SID下可以细分,比如0x10下面有01、02、03等子功能。
嗯,这里要注意:UDS不是万能的。它只管诊断,不管刷写时的底层传输。刷写通常还要靠ISO 15765-2(CAN上的传输层)来分包。
1.2 会话状态机——ECU的“工作模式”
ECU不是一直处于诊断模式的。你想想看,如果ECU随时都在监听诊断报文,那正常跑车的时候性能肯定受影响。所以UDS定义了一套会话状态机。
我个人习惯把会话状态机理解成ECU的“工作模式切换器”。默认情况下,ECU在默认会话里跑。只有当你发0x10服务,它才会切换到其他会话。
状态机的基本流转:
- 默认会话(Default Session):上电后的初始状态。只支持最基本的诊断服务,比如读取DTC(故障码)。
- 扩展会话(Extended Session):需要主动切换。支持更多诊断功能,比如读写数据、例程控制。
- 编程会话(Programming Session):刷写固件时用的。这个会话下,ECU会关闭大部分应用功能,专心接收刷写数据。
我曾经在项目里踩过一个坑:ECU在扩展会话下执行刷写,结果刷到一半超时了,ECU自动切回默认会话,刷写直接失败。后来我加了个会话保持机制,每500ms发一次0x3E(Tester Present)才解决。
1.3 默认会话——ECU的“待机模式”
默认会话是ECU上电后的默认状态。在这个状态下,ECU主要做两件事:
- 正常运行应用层功能(比如发动机控制、ABS控制)。
- 响应有限的诊断请求(比如读取VIN码、读取DTC)。
说白了,默认会话就是ECU的“正常工作模式”。你想想看,如果每次上电ECU都进入诊断模式,那车还怎么开?
默认会话下支持的服务很有限。通常只有:
- 0x10(诊断会话控制)——用于切换到其他会话
- 0x14(清除DTC)
- 0x19(读取DTC信息)
- 0x22(读取数据标识符)——部分支持
- 0x3E(Tester Present)——保持会话
我建议你在做测试的时候,先确认ECU在默认会话下到底支持哪些服务。有些ECU厂商会阉割一部分,比如不允许在默认会话下读某些敏感数据。
1.4 扩展会话——解锁更多功能
扩展会话,顾名思义,就是扩展了诊断能力的会话。你需要通过0x10服务,子功能0x02来切换。
举个例子:
请求:02 10 02 00 00 00 00 00
响应:02 50 02 00 00 00 00 00
这里0x10是服务ID,0x02是子功能(扩展会话)。响应里的0x50表示成功。
扩展会话下,ECU会开放更多服务:
- 0x2E(写入数据标识符)——可以修改ECU内部参数
- 0x31(例程控制)——执行自检、校准等操作
- 0x27(安全访问)——解锁安全等级
- 0x34/0x36(请求下载/数据传输)——刷写前置步骤
嗯,这里有个关键点:扩展会话通常有超时机制。如果一段时间内没有收到任何诊断请求,ECU会自动切回默认会话。超时时间一般是5秒左右,具体看厂商定义。
1.5 会话切换的底层逻辑
会话切换不是简单的“发个请求就完事”。ECU内部有一套状态机逻辑:
- 每个会话都有对应的会话ID(SID + 子功能)。
- 切换时,ECU会检查当前会话是否允许切换到目标会话。
- 如果允许,ECU会保存当前会话的上下文,然后初始化目标会话。
- 切换成功后,ECU会启动目标会话的超时计时器。
我见过一个奇葩案例:某ECU在扩展会话下执行了安全访问解锁,然后切到编程会话,结果编程会话下安全访问状态被重置了。后来查手册才发现,编程会话有自己的安全访问机制,和扩展会话不共享。
所以,我的建议是:不要假设会话切换后任何状态会保留。安全访问、会话超时、DTC状态等,都可能被重置。每次切换后,最好重新确认一下当前状态。
1.6 实际项目中的经验总结
最后分享几个我在项目中踩过的坑:
- 会话超时:默认会话和扩展会话都有超时。如果你在做自动化测试,记得定期发0x3E保持会话。
- 会话切换失败:有些ECU要求必须先进入扩展会话,才能进入编程会话。直接跳转会被拒绝。
- 安全访问与会话绑定:安全访问解锁状态通常与会话绑定。切回默认会话后,解锁状态就丢了。
- 多ECU协同:如果你同时诊断多个ECU,每个ECU的会话状态是独立的。别指望一个ECU的会话保持能影响另一个。
好了,这一章就到这里。下一章我们会深入安全访问机制,聊聊0x27服务的种子-密钥算法和常见坑点。