2. 汽车诊断基础
在嵌入式诊断开发中,工程师最常遇到的困惑不是“协议怎么写”,而是“这些标准到底谁管谁”。OBD-II、ISO 14229、ISO 15765、DoIP 并不是并列的四套协议,而是分别处在法规层、应用层、传输层和网络层的不同位置。理解它们的层次关系,才能正确划分诊断节点(ECU)与诊断仪(Tester)的角色,进而设计出可移植、可测试的诊断软件。
一、标准分层:从法规到物理链路
汽车诊断标准可以按“法规要求—应用语义—传输承载—物理网络”四层来理解。OBD-II 是法规驱动的排放与基础诊断要求,它规定了诊断座、故障码(DTC)读取、冻结帧、就绪状态等最小集合;ISO 14229(UDS)是应用层协议,定义了诊断服务、数据标识符、例程控制、安全访问等语义;ISO 15765(DoCAN)负责把 UDS 报文分段、流控并承载在 CAN 总线上;DoIP(ISO 13400)则把 UDS 承载到以太网/IP 之上,用于高带宽场景如刷写、大数据读取。
换句话说,UDS 是“说什么”,ISO 15765 和 DoIP 是“怎么送”,OBD-II 是“法规要求必须能说什么”。诊断节点是服务端(Server),诊断仪是客户端(Client),二者通过请求—响应模型交互。
二、诊断节点与诊断仪的角色划分
在 UDS 通信模型中,诊断仪始终是客户端,主动发起请求;诊断节点是服务端,被动接收并返回响应。这个角色划分决定了嵌入式软件的设计方式:诊断节点不需要主动轮询,而是维护一个诊断状态机,等待请求到达后解析服务标识符(SID),执行对应服务,再按格式返回肯定响应或否定响应。
诊断节点内部通常包含四个关键模块:传输层收发、UDS 服务分发、会话与安全状态管理、数据存储(DTC/DID)。诊断仪则负责构造请求、管理超时与重试、解析响应,并把结果呈现给测试人员或上位机脚本。
核心记忆点:UDS 是应用层语义,ISO 15765 和 DoIP 是承载方式,OBD-II 是法规最小集合。诊断仪是 Client,诊断节点是 Server,请求—响应模型贯穿始终。
三、典型场景:一次 0x22 读数据的完整链路
假设诊断仪要读取诊断节点的软件版本号,DID 为 0xF189。在 CAN 场景下,请求报文经过 ISO 15765 分段后发送;在以太网场景下,请求被封装为 DoIP 消息。诊断节点收到后,由 UDS 服务层处理 0x22 服务,返回肯定响应 0x62 加数据。
请求:22 F1 89
肯定响应:62 F1 89 01 02 03 04
否定响应示例:7F 22 31 (requestOutOfRange)
如果诊断节点尚未进入扩展会话,某些服务可能返回 7F 加 NRC 0x7F(serviceNotSupportedInActiveSession)。这说明会话状态管理是诊断节点软件的核心逻辑之一,不能只实现服务分发而忽略状态约束。
四、标准关系速查表
| 标准 | 层次 | 核心内容 | 典型承载 |
|---|---|---|---|
| OBD-II | 法规层 | 排放 DTC、冻结帧、就绪状态、诊断座 | CAN / K-Line / PWM |
| ISO 14229 UDS | 应用层 | 服务、DID、例程、安全访问、会话 | 由下层承载 |
| ISO 15765 DoCAN | 传输层 | 分段、流控、重组、寻址 | CAN / CAN FD |
| ISO 13400 DoIP | 网络层 | 车辆发现、路由激活、以太网承载 | Ethernet / IP |
五、常见误区与复盘
- 误区一:把 UDS 当成传输协议。UDS 只定义应用层语义,实际发送必须依赖 ISO 15765 或 DoIP。写代码时要把服务层与传输层解耦。
- 误区二:认为 OBD-II 就是 UDS。OBD-II 是法规要求的最小诊断集合,UDS 是更完整的应用层协议,二者有交集但不等同。
- 误区三:诊断节点主动上报。UDS 是请求—响应模型,诊断节点不应主动发送诊断响应,除非使用特定事件通知机制。
- 误区四:忽略会话与安全状态。很多服务在不同会话下行为不同,安全访问未解锁时也会返回否定响应,状态机必须完整实现。
开发建议:在诊断节点软件中,把“传输层适配”和“UDS 服务处理”分成两个独立模块。这样同一套 UDS 服务代码可以同时跑在 CAN 和 DoIP 之上,移植成本最低。
理解标准分层与角色划分,是后续实现诊断服务、配置诊断描述文件(CDD/ODX)以及搭建自动化测试环境的基础。只有先分清“谁定义语义、谁负责传输、谁发起请求、谁返回响应”,才能在嵌入式诊断开发中少走弯路。