1. UDS诊断协议概述:UDS协议栈、OSI七层模型映射、诊断会话与服务的概念

大家好,我是老张。做汽车电子这行十几年了,UDS诊断这块算是我的老本行。今天咱们聊聊UDS协议的基础概念。说实话,很多新手一上来就啃协议栈,结果越看越懵。我建议你先搞懂三个核心:协议栈长什么样、OSI模型怎么映射、会话和服务到底是什么。

1.1 UDS协议栈:从物理层到应用层

UDS的全称是Unified Diagnostic Services,统一诊断服务。它定义了一套标准化的诊断规则。你想想看,一辆车里有几十个ECU,每个厂家都有自己的协议,那维修厂不得疯掉?UDS就是为了解决这个乱象。

协议栈这东西,说白了就是分层。每一层只管自己的事,上层调用下层,下层服务上层。我习惯把它理解成「快递系统」:应用层是你要寄的东西,传输层是打包,网络层是规划路线,物理层就是那辆货车。

UDS协议栈的核心分层(从下往上):

  • 物理层:CAN总线、LIN总线、以太网等。嗯,这里要注意,现在主流还是CAN,但以太网正在崛起。
  • 数据链路层:负责帧的封装、错误检测。CAN 2.0或CAN FD都在这一层。
  • 网络层:ISO 15765-2(CAN上的网络层协议)。处理多帧传输、流控制。
  • 传输层:其实在UDS里,网络层和传输层经常合并讨论。它负责端到端的可靠传输。
  • 会话层:管理诊断会话的建立、维持和释放。
  • 表示层:数据编码、字节序。UDS里常用Intel格式或Motorola格式。
  • 应用层:ISO 14229-1。这就是我们常说的UDS服务,比如读取数据、写入数据、刷写程序。

我记得刚入行那会儿,总搞不清网络层和应用层的边界。有一次调试一个刷写失败的bug,查了三天,最后发现是多帧传输的流控制帧没处理好。嗯,从那以后我就养成了一个习惯:遇到问题先定位到具体层。

1.2 OSI七层模型映射:UDS是怎么落地的

OSI七层模型是理论框架,UDS是具体实现。很多人觉得这玩意儿太抽象,我换个说法:你打开手机导航,从北京到上海。OSI模型就是告诉你「要有路、要有车、要有导航规则」,而UDS就是那套「导航规则」本身。

咱们直接看映射关系:

OSI层 UDS对应协议/标准 我的理解
应用层(第7层) ISO 14229-1 诊断服务的定义,比如读数据、写数据、例程控制
表示层(第6层) ISO 14229-2 数据编码规则,字节序、符号扩展等
会话层(第5层) ISO 14229-2 会话状态机,默认会话、扩展会话、编程会话
传输层(第4层) ISO 15765-2 多帧传输、流控制、时间参数
网络层(第3层) ISO 15765-2 地址分配、路由、单帧/多帧判断
数据链路层(第2层) CAN 2.0 / CAN FD 帧结构、仲裁、错误处理
物理层(第1层) ISO 11898(CAN) 电平、线束、终端电阻

你可能会问:「为什么UDS不直接用TCP/IP那一套?」原因很简单——实时性和可靠性。CAN总线在物理层就有很强的错误检测机制,而且仲裁机制保证了高优先级报文不丢失。我在项目中遇到过用DoIP(基于以太网的诊断)的场景,虽然速度快,但丢包重传的机制比CAN复杂得多。

我的小技巧:调试UDS协议栈时,我习惯用CANalyzer或PCAN抓报文,然后对照ISO 15765-2的格式逐字节解析。别嫌麻烦,这是最快的学习方式。

1.3 诊断会话与服务的概念:ECU的「工作模式」

诊断会话,说白了就是ECU的几种工作模式。ECU不是什么时候都允许你干所有事的。比如你正在开车,突然有人要刷写程序,那不得出大事?所以UDS定义了不同的会话状态。

常见的三种会话:

  • 默认会话(Default Session):上电后的初始状态。只能做基本的诊断,比如读VIN码、读故障码。安全等级最低。
  • 扩展会话(Extended Session):需要发送10 03进入。可以做更多操作,比如读写参数、执行例程。但还不能刷写。
  • 编程会话(Programming Session):需要发送10 02进入。这是最高权限的会话,用于刷写程序、更新固件。

我曾经踩过一个坑:在编程会话下尝试读取某个DID(数据标识符),结果ECU返回了否定响应。查了半天协议才发现,有些DID只在扩展会话下才可读。所以,做诊断开发时,一定要搞清楚每个服务支持的会话范围。

诊断服务呢,就是ECU能执行的「命令」。每个服务都有一个SID(服务标识符),比如:

  • 10 服务:诊断会话控制(Diagnostic Session Control)
  • 22 服务:读取数据(Read Data By Identifier)
  • 2E 服务:写入数据(Write Data By Identifier)
  • 31 服务:例程控制(Routine Control)
  • 34/36/37 服务:刷写相关(Request Download, Transfer Data, Request Exit)
  • 19 服务:读取故障码(Read DTC Information)
  • 14 服务:清除故障码(Clear Diagnostic Information)

注意:不是所有ECU都支持所有服务。具体支持哪些,要看ECU的ODX文件或CDD文件。我建议你拿到项目后,第一件事就是导出支持的SID列表。

举个例子,你发送 22 F1 90 给ECU,意思是「读取标识符为F190的数据」。ECU会回复 62 F1 90 xx xx,其中xx xx就是数据内容。这个F190通常对应VIN码。你看,就这么简单。

但实际项目中,事情往往没那么顺利。我记得有一次,客户反馈刷写时总是超时。我抓了报文一看,原来是ECU在编程会话下,响应时间比默认会话慢了很多。后来查资料才知道,编程会话下ECU要处理Flash擦写,CPU负载高,响应延迟自然就大了。解决方案是调整应用层的超时参数,从默认的50ms放宽到500ms。

最后说一句,诊断会话和服务的关系,就像「门禁卡和房间」:会话决定你能进哪栋楼,服务决定你能动哪个房间里的东西。搞懂这个,你就掌握了UDS的钥匙。