3、诊断会话控制(0x10):默认会话、编程会话、扩展会话的切换逻辑、会话状态机、实际项目中的会话管理策略
3.1 会话控制到底在解决什么问题?
各位工程师朋友,咱们直接切入正题。
诊断会话控制,服务ID是0x10。说白了,它就是ECU的“工作模式切换器”。
你想想看,一辆车上几十个ECU,每个ECU都有不同的功能。有些功能是日常用的,比如读取车速、发动机转速。有些功能是维修时才用的,比如写入配置、刷写固件。还有些功能是出厂前才用的,比如标定参数。
如果所有功能都开放,那安全性怎么保证?
所以,UDS协议定义了三种会话:默认会话、编程会话、扩展会话。ECU根据当前会话,决定允许哪些诊断服务。
我在项目中遇到过,有同事把扩展会话和编程会话搞混了,结果刷写时一直报错。嗯,这里面的门道,咱们慢慢聊。
3.2 三种会话的“人设”
3.2.1 默认会话(Default Session)
这是ECU上电后的默认状态。说白了,就是“日常模式”。
在这个模式下,ECU只开放最基础的服务。比如:
- 0x22(读取数据)—— 读个故障码、读个版本号
- 0x14(清除故障码)—— 清一下历史故障
- 0x19(读取故障码信息)—— 查查当前有啥问题
但像0x2E(写入数据)、0x31(例程控制)、0x34(请求下载)这些“危险操作”,默认会话是不允许的。
3.2.2 扩展会话(Extended Session)
扩展会话,你可以理解为“维修模式”。
当车辆进4S店维修时,诊断仪会发送0x10 03,让ECU进入扩展会话。这时候,ECU会开放更多服务:
- 0x2E(写入数据)—— 比如修改VIN码、配置参数
- 0x31(例程控制)—— 比如执行某个自检程序、复位某个模块
- 0x2F(输入输出控制)—— 比如强制某个执行器动作
注意,扩展会话不能进行刷写。刷写需要更高级的权限。
我记得有一次,客户反馈说ECU无法写入配置。我一看日志,发现诊断仪发送的是0x10 01(默认会话),然后直接发0x2E。这当然不行。先切到扩展会话,再写数据,问题就解决了。
3.2.3 编程会话(Programming Session)
编程会话,就是“刷写模式”。
这是权限最高的会话。只有在这个会话下,才能执行:
- 0x34(请求下载)
- 0x36(数据传输)
- 0x37(请求退出传输)
- 0x31(刷写相关的例程,比如擦除、校验)
进入编程会话后,ECU通常会关闭一些非必要的通信,比如CAN报文、网络管理。这是为了保证刷写过程的稳定性和安全性。
3.3 会话状态机:切换逻辑与规则
会话切换不是随意的,它有一套严格的状态机。我画个简化的图给你看:
+----------------+ 0x10 02 +------------------+
| 默认会话 | ----------------> | 编程会话 |
| (Default) | | (Programming) |
+----------------+ +------------------+
| |
| 0x10 03 | 0x10 01 或 0x10 03
v v
+----------------+ +------------------+
| 扩展会话 | | 默认会话 |
| (Extended) | <---------------- | (Default) |
+----------------+ 0x10 01 +------------------+
核心规则就三条:
- 从默认会话可以切换到任何会话。 这是最灵活的起点。
- 从扩展会话只能切换到默认会话。 不能直接跳到编程会话。必须先回默认,再进编程。
- 从编程会话可以切换到默认会话或扩展会话。 刷写完成后,通常切回默认会话。
为什么这样设计?
你想想看,如果扩展会话能直接切到编程会话,那万一诊断仪在维修时误操作,直接发起刷写,后果很严重。所以UDS协议强制要求:编程会话必须从默认会话进入。这算是一道安全屏障。
我个人的经验是,在开发诊断栈时,一定要把状态机实现得滴水不漏。有些ECU的协议栈实现有bug,允许从扩展会话直接切到编程会话。这在OEM的测试中,是会被一票否决的。
3.4 实际项目中的会话管理策略
理论说完了,咱们聊聊实战。
3.4.1 会话超时与保持
ECU不会永远待在扩展会话或编程会话里。它有一个会话超时定时器(S3定时器)。
通常,OEM会规定:
- 扩展会话超时:5秒(如果5秒内没有诊断请求,自动切回默认会话)
- 编程会话超时:10秒(刷写过程中,通常由Tester持续发送请求来保持会话)
我在项目中遇到过,某诊断仪在刷写时,每发送一个数据块后,等待ECU的响应,然后再发下一个。但中间间隔超过了10秒,结果ECU自动切回了默认会话。刷写当然失败了。
解决方案?诊断仪需要定期发送0x3E(Tester Present)服务,告诉ECU:“我还活着,别切回去。”
3.4.2 安全访问与会话的关系
很多工程师会问:会话和安全访问(0x27)是什么关系?
简单说:会话决定“能不能做”,安全访问决定“谁来做”。
举个例子:
- 你想写入VIN码。首先,ECU必须在扩展会话下(会话权限)。
- 然后,诊断仪必须通过安全访问的种子-密钥验证(安全权限)。
- 两者都满足,才能执行0x2E写入。
我见过一个项目,OEM要求:在扩展会话下,如果安全访问失败,ECU必须立即切回默认会话。这是一种安全策略,防止暴力破解。
3.4.3 多ECU场景下的会话协调
现在的车,网关、域控制器、多个ECU协同工作。诊断时,会话管理就更复杂了。
比如,你想刷写网关。但网关同时负责路由诊断报文到其他ECU。如果你把网关切到编程会话,它可能无法正常路由了。
怎么办?
有些OEM的做法是:网关在编程会话下,仍然保留路由功能。但会降低优先级,或者只路由特定的报文。
我个人习惯是,在项目早期就和OEM确认好:编程会话下,ECU的哪些功能要保留,哪些要关闭。这个决策会影响整个诊断架构的设计。
3.5 总结与避坑清单
好了,会话控制的内容就讲到这里。我帮你整理一个避坑清单:
| 常见问题 | 原因 | 解决方案 |
|---|---|---|
| 刷写时ECU无响应 | 会话超时,自动切回默认会话 | 定期发送0x3E保持会话 |
| 写入配置失败 | 未切换到扩展会话 | 先发0x10 03,再发0x2E |
| 从扩展会话直接切编程会话失败 | UDS协议不允许 | 先切回默认,再切编程 |
| 编程会话下总线冲突 | ECU未关闭非诊断报文 | 编程会话中禁用网络管理报文 |
最后说一句:会话控制是诊断的基础。基础不牢,地动山摇。希望今天的分享,能帮你少踩几个坑。