2. DoIP消息结构:DoIP消息头格式、Payload类型详解、路由激活与诊断消息、车辆发现与声明

好,咱们进入正题。DoIP协议说白了就是一套“车联网上的对话规则”。你想想看,诊断仪和ECU之间要通信,总得有个统一的格式吧?不然你说东它听西,那不乱套了。

我个人习惯,在讲任何协议之前,先看它的“信封”长什么样。DoIP的消息结构,核心就是那个固定的消息头。搞懂了它,后面的Payload类型、路由激活、车辆发现,其实都是在这个信封里装不同的信纸而已。

2.1 DoIP消息头格式

先看消息头。DoIP的头部是固定的8个字节,不多不少。我刚开始接触时也觉得奇怪,为什么是8字节?后来发现,这8字节刚好能把“谁发的、发给谁、多长、什么类型”说清楚。

字段 长度(字节) 说明
协议版本 1 当前固定为0x02(ISO 13400-2:2012)
逆协议版本 1 取反,用于校验,0xFD
Payload类型 2 标识消息用途,比如0x0001是车辆声明
Payload长度 4 后面跟着的数据总长度,单位字节

嗯,这里要注意。逆协议版本这个字段,很多人会忽略。我曾经在项目联调时,发现诊断仪死活收不到ECU的响应。查了半天,原来是ECU发的逆协议版本算错了。说白了,这就是个简单的校验,但少了它,协议栈直接就把包丢了。

核心要点: 消息头的前4个字节是固定的,后4个字节告诉你Payload有多长。解析时,先读8字节头,再根据Payload长度读后面的数据。

2.2 Payload类型详解

消息头里的Payload类型字段,决定了后面跟着的数据是什么。我把它分成三大类,你记牢了:

  • 通用DoIP消息(0x0000 - 0x3FFF):包括车辆发现、路由激活、诊断消息等核心功能。
  • 诊断消息(0x8001 - 0x8002):UDS诊断请求和响应就走这里。
  • 其他扩展类型:比如0x4000用于事件通知,0x6xxx用于安全相关。

举个例子,Payload类型0x0001是“车辆声明消息”。当ECU上电后,它会主动广播这个消息,告诉网络上的诊断仪:“我在这儿,这是我的VIN码和逻辑地址。” 说白了,就是ECU在喊:“我来了,快来连我!”

我的经验: 调试时,我习惯先抓包看Payload类型。如果类型不对,后面的数据解析全是错的。比如你收到一个0x8002,却按0x0001去解析,那结果肯定是一团乱麻。

2.3 路由激活与诊断消息

路由激活,是DoIP里最关键的握手过程。为什么需要它?因为诊断仪和ECU之间,不能上来就发诊断请求。你得先告诉ECU:“我要激活你,给我一个逻辑地址。”

流程是这样的:

  1. 诊断仪发送路由激活请求(Payload类型0x0005)。
  2. ECU收到后,检查源地址是否合法。
  3. 如果合法,ECU返回路由激活响应(Payload类型0x0006),并分配一个逻辑地址。
  4. 之后,诊断仪就可以用这个逻辑地址发送诊断消息了。

我记得有一次,客户反馈说诊断仪连不上ECU。我抓包一看,路由激活请求发过去了,但ECU返回了0x06(未知源地址)。原来是诊断仪用的源地址和ECU配置的不一致。说白了,就是“门牌号对不上”。

避坑指南: 我曾经遇到过,路由激活成功后,诊断仪直接发了诊断请求,但ECU没响应。为什么?因为路由激活后,ECU会启动一个“激活定时器”。如果超时没有后续诊断消息,它会自动断开。所以,路由激活后要尽快发诊断请求,别磨蹭。

诊断消息本身,Payload类型是0x8001(诊断请求)和0x8002(诊断响应)。数据部分就是标准的UDS报文。比如你要读ECU的DTC,就发一个0x19 0x02的UDS请求,封装在DoIP的Payload里。

2.4 车辆发现与声明

车辆发现,是DoIP里最“热闹”的部分。想象一下,你拿着诊断仪走进停车场,怎么知道哪辆车支持DoIP?靠的就是“车辆发现”机制。

具体流程:

  • 车辆声明(0x0001):ECU上电后,主动广播一条消息,包含VIN码、逻辑地址、EID(实体ID)等信息。诊断仪收到后,就知道这辆车在哪儿了。
  • 车辆识别请求(0x0002):诊断仪也可以主动发一个广播,问“谁在?” 符合条件的ECU会回复车辆声明。
  • 车辆识别响应(0x0003):针对特定VIN或EID的查询,ECU会单播回复。

我个人觉得,车辆声明是最实用的。你想想看,如果每辆车都要诊断仪去轮询,那效率多低。ECU主动广播,诊断仪被动接收,这才是“车联网”该有的样子。

实战技巧: 调试车辆发现时,我建议用Wireshark抓UDP广播包。如果看不到0x0001的车辆声明,先检查ECU的网络配置。我曾经遇到过,ECU的IP地址和诊断仪不在同一个子网,广播包根本过不来。说白了,网络基础没打好,上层协议再牛也白搭。

好了,DoIP的消息结构就这些。消息头是骨架,Payload类型是血肉,路由激活和车辆发现是灵魂。搞懂了这些,你就能看懂DoIP的每一帧数据了。下一章,咱们聊聊怎么用Python把这些消息发出去。