4、DoIP协议入门:ISO 13400 标准,TCP/UDP 端口分配,车辆发现与路由激活

好,咱们今天聊聊DoIP。说实话,这个协议在车载网络里算是比较“年轻”的,但它的地位越来越重要。为什么?因为现在的车联网功能越来越多,OTA升级、远程诊断,这些都得靠它来打通“最后一公里”。

DoIP的全称是Diagnostic over Internet Protocol,说白了就是“基于IP协议的诊断”。它遵循的是ISO 13400标准。我个人习惯把DoIP理解为“给汽车装了个网线接口”,让诊断工具能像访问服务器一样去访问车上的ECU。

4.1 ISO 13400 标准概览

ISO 13400这个标准,其实是一套完整的“游戏规则”。它定义了诊断数据怎么在TCP/IP网络上传输。你想想看,传统的诊断用的是CAN总线,速度有限,而且距离也受限。DoIP就不一样了,它跑在以太网上,速度可以到100Mbps甚至更高。

我在项目中遇到过一个问题:客户要求远程升级一个网关的固件,文件大小有几十兆。如果用CAN总线,那得传几个小时,而且中间还不能断。后来改用DoIP,几分钟就搞定了。这就是它的核心优势——高带宽、远距离。

ISO 13400主要规定了几个方面:

  • 网络层和传输层:怎么建立连接,怎么保证数据可靠传输。
  • 协议数据单元(PDU):数据包的格式,就像信封一样,有头有尾。
  • 车辆发现机制:诊断工具怎么找到车上的ECU。
  • 路由激活:怎么让ECU“开门”接受诊断请求。

核心要点:DoIP不是简单的“把CAN报文封装成IP包”,它有自己的会话管理和安全机制。嗯,这里要注意,很多新手容易把DoIP和UDS(统一诊断服务)搞混。UDS是应用层的诊断命令,DoIP是传输层的“快递员”。

4.2 TCP/UDP 端口分配

DoIP用到了两个传输层协议:TCP和UDP。它们分工明确,各司其职。

UDP端口:13400

这个端口主要用于车辆发现。为什么用UDP?因为UDP是无连接的,可以广播。诊断工具发一个广播包,所有支持DoIP的车辆都能收到。这就像你在停车场喊一声“谁的车能诊断?”,然后符合条件的车就会回应你。

TCP端口:13400

这个端口用于实际的诊断通信。一旦车辆被发现,诊断工具就会和它建立TCP连接。TCP是可靠的,能保证数据不丢包、不乱序。这对于诊断命令和响应来说至关重要。

我记得有一次调试,发现诊断工具总是连不上车辆。查了半天,原来是防火墙把UDP 13400端口给封了。所以,在实际项目中,一定要确保这两个端口是开放的。

协议 端口号 用途 特点
UDP 13400 车辆发现、车辆公告 无连接、广播
TCP 13400 诊断通信、路由激活 面向连接、可靠

避坑指南:我曾经在一个项目中,为了省事,把UDP和TCP的端口都设成了同一个。结果发现,车辆发现没问题,但建立TCP连接时总是超时。后来才意识到,虽然端口号可以相同,但协议不同,操作系统会分别处理。所以,建议还是严格按照标准来,别自己“创新”。

4.3 车辆发现机制

车辆发现,说白了就是“找车”。DoIP提供了两种方式:主动发现和被动发现。

主动发现(Vehicle Discovery Request)

诊断工具发送一个UDP广播包,目标端口是13400。这个包的内容很简单,就是一个“谁在?”的请求。所有支持DoIP的车辆收到后,会回复一个“我在”的响应包,里面包含车辆的IP地址、VIN码(车辆识别号)、逻辑地址等信息。

被动发现(Vehicle Announcement)

车辆上电后,或者网络状态发生变化时,会自动发送一个UDP广播包,告诉所有诊断工具“我在这里”。这种方式的好处是,诊断工具不需要主动去问,车辆自己会“报备”。

你想想看,这两种方式结合起来,诊断工具就能快速找到网络上的所有车辆。我在实际测试中,一般会先用主动发现扫描一遍,然后监听被动发现,确保没有遗漏。

车辆发现响应包的结构大致如下:

| 字节偏移 | 字段名          | 长度(字节) | 描述                     |
|----------|-----------------|--------------|--------------------------|
| 0        | 协议版本        | 1            | 当前DoIP协议版本         |
| 1        | 反向协议版本    | 1            | 用于兼容性检查           |
| 2-3      | 负载类型        | 2            | 0x0004(车辆发现响应)   |
| 4-7      | 负载长度        | 4            | 后续数据的长度           |
| 8-24     | VIN码           | 17           | 车辆识别号               |
| 25       | 逻辑地址        | 2            | 车辆的DoIP实体逻辑地址   |
| 27       | EID(实体ID)   | 6            | 硬件唯一标识             |
| 33       | GID(组ID)     | 6            | 组标识,用于分组管理     |
| 39       | 进一步动作标志  | 1            | 指示是否需要进一步操作   |
| 40       | 保留            | 4            | 保留字段                 |

注意事项:车辆发现响应包中的VIN码是明文传输的。虽然DoIP本身没有加密,但在实际应用中,建议在应用层对敏感信息进行加密处理。我曾经见过一个项目,因为VIN码泄露,导致车辆被非法克隆。所以,安全这根弦,任何时候都不能松。

4.4 路由激活

车辆发现了,TCP连接也建立了,接下来就是“路由激活”。这一步很关键,它相当于给诊断工具发了一张“通行证”。

为什么需要路由激活?因为DoIP实体(通常是网关)可能连接着多个ECU。诊断工具想访问某个ECU,必须先告诉网关:“我要访问这个ECU,请给我开个通道。” 网关收到请求后,会检查诊断工具的权限,然后决定是否激活路由。

路由激活的流程是这样的:

  1. 诊断工具发送一个路由激活请求,里面包含自己的逻辑地址和要访问的ECU的逻辑地址。
  2. 网关收到请求后,进行权限验证。比如,检查诊断工具是否在白名单里。
  3. 验证通过后,网关回复一个路由激活响应,状态码为0x10(成功)。
  4. 之后,诊断工具就可以通过这个路由,向目标ECU发送诊断请求了。

我个人习惯在路由激活这一步,加上一个超时机制。如果网关在5秒内没有响应,就认为激活失败,重新发起请求。这样可以避免因为网络延迟导致的死等。

路由激活请求的格式:

| 字节偏移 | 字段名          | 长度(字节) | 描述                     |
|----------|-----------------|--------------|--------------------------|
| 0        | 协议版本        | 1            | 0x02(ISO 13400-2)      |
| 1        | 反向协议版本    | 1            | 0xFE                     |
| 2-3      | 负载类型        | 2            | 0x0005(路由激活请求)   |
| 4-7      | 负载长度        | 4            | 0x00000007               |
| 8-9      | 源逻辑地址      | 2            | 诊断工具的逻辑地址       |
| 10-11    | 目标逻辑地址    | 2            | 目标ECU的逻辑地址        |
| 12       | 激活类型        | 1            | 0x00(默认)             |
| 13-14    | 保留            | 2            | 保留字段                 |

路由激活响应的状态码:

状态码 含义 说明
0x10 成功 路由已激活,可以开始诊断
0x11 拒绝 诊断工具没有权限
0x12 冲突 目标ECU已被其他诊断工具占用
0x13 未知目标 目标ECU不存在或不可达

实战经验:我曾经遇到过一个奇怪的问题,路由激活总是返回0x12(冲突)。排查了半天,发现是诊断工具的逻辑地址和另一个工具重复了。所以,在项目初期,一定要规划好逻辑地址的分配,避免冲突。另外,有些网关会限制同时激活的路由数量,比如最多支持4个。如果超过这个数量,新的激活请求就会被拒绝。

好了,关于DoIP的入门知识,咱们就聊到这里。总结一下:ISO 13400定义了DoIP的框架,TCP/UDP 13400端口是通信的“大门”,车辆发现让你能找到车,路由激活让你能进到车里。掌握了这些,你就已经迈出了DoIP实战的第一步。