2、DoIP协议基础:DoIP协议栈架构、物理层与传输层、TCP/UDP端口分配

好,咱们进入正题。DoIP,全称是Diagnostic over Internet Protocol。说白了,就是把传统的UDS诊断报文,封装到以太网帧里发出去。你想想看,以前修车用CAN线,一根线拖来拖去,现在直接插根网线,或者走无线,是不是方便多了?

我个人习惯,在讲任何协议之前,先看它的“骨架”——也就是协议栈架构。搞清楚了每一层干什么,后面遇到问题才知道去哪一层找原因。

2.1 DoIP协议栈架构

DoIP协议栈,其实就是在标准的TCP/IP四层模型上,加了一层DoIP特有的处理逻辑。我画个简图在脑子里:

+----------------------------+
|  应用层 (UDS诊断服务)       |  <- 你写的诊断逻辑
+----------------------------+
|  DoIP协议层                 |  <- 核心:报文封装、路由、流控
+----------------------------+
|  TCP/UDP 传输层             |  <- 端口分配、可靠/非可靠传输
+----------------------------+
|  IPv4/IPv6 网络层           |  <- IP地址、路由
+----------------------------+
|  以太网MAC/PHY 链路层       |  <- 网卡、网线、100BASE-TX
+----------------------------+

嗯,这里要注意,DoIP协议层是咱们诊断工程师最需要关心的。它负责把UDS的请求/响应,打包成DoIP特有的报文格式。我在项目中遇到过,有人直接把UDS报文塞进TCP流里,结果网关根本不认——因为少了DoIP的报文头标识。

核心要点:DoIP报文头包含版本号、类型标识、负载长度等字段。没有这个头,接收方不知道你发的是诊断数据还是心跳包。

2.2 物理层与传输层

物理层,说白了就是网线怎么接,信号怎么传。DoIP目前主流用的是100BASE-TX,也就是百兆以太网。为什么不是千兆?因为车载环境对成本敏感,百兆对于诊断数据(通常几百KB到几MB)完全够用了。

我建议你记住几个关键参数:

  • 连接器:标准RJ45,或者车载专用的H-MTD、MATEnet连接器。后者更抗振动,适合车规。
  • 线束:需要至少一对差分线(TX/RX),外加屏蔽层。别用普通网线,车上的电磁干扰很厉害。
  • 激活线:有些实现会有一条额外的激活线,用来唤醒ECU的以太网控制器。没有这条线,ECU可能处于休眠状态,你连都连不上。

传输层这块,DoIP同时用了TCP和UDP。为什么需要两个?我举个例子你就明白了:

  • TCP:用于传输诊断请求和响应。诊断数据必须可靠,丢一个字节都可能误诊。TCP的重传机制保证了这一点。
  • UDP:用于发现车辆和获取基本状态。比如你拿诊断仪扫描网段,发个广播UDP包,所有支持DoIP的ECU都会回复。这个过程不需要建立连接,速度快。

避坑指南:我曾经在调试时发现,诊断仪发送UDP广播后,有的ECU不回复。查了半天,原来是ECU的UDP socket只绑定了特定端口,没有监听广播地址。记得把socket设置为允许广播接收。

2.3 TCP/UDP端口分配

端口分配,这是DoIP协议里最“死”的部分,但也是最容易出错的地方。ISO 13400-2标准里规定得很清楚:

端口号 协议 用途 说明
13400 TCP DoIP诊断数据 所有诊断请求/响应走这个端口
13400 UDP DoIP车辆发现 诊断仪发广播,ECU回复
13401 UDP DoIP车辆公告 ECU主动上报状态(可选)

你看,TCP和UDP都用了13400端口。这其实不冲突,因为TCP和UDP是独立的协议栈。但要注意,同一个ECU上,TCP和UDP的13400端口必须同时开放。

我个人习惯,在代码里这样定义端口:

#define DOIP_TCP_PORT  13400
#define DOIP_UDP_DISCOVERY_PORT 13400
#define DOIP_UDP_ANNOUNCE_PORT  13401

为什么UDP要分两个端口?你想想看,车辆发现是诊断仪主动发起的,而车辆公告是ECU主动上报的。如果混用一个端口,ECU收到自己的公告包会怎么处理?嗯,容易产生环路。所以标准里把它们分开了。

注意事项:端口13400和13401是IANA分配给DoIP的专用端口。不要自作聪明改成其他端口,否则诊断仪可能找不到你的ECU。我在一个项目中见过有人用了8080端口,结果每次连接都要手动配置,非常麻烦。

最后,说一个实际经验。DoIP的TCP连接,通常由诊断仪主动发起。ECU作为服务端,监听13400端口。但有些ECU资源有限,只能同时处理少量TCP连接。标准建议最大连接数至少为2个(一个用于诊断,一个用于备用)。我建议你至少支持4个,因为现在很多诊断仪会同时开多个会话。

好了,DoIP协议基础就讲到这里。下一节我们会深入报文格式,看看DoIP头里到底藏了什么玄机。