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,请给我开个通道。” 网关收到请求后,会检查诊断工具的权限,然后决定是否激活路由。
路由激活的流程是这样的:
- 诊断工具发送一个路由激活请求,里面包含自己的逻辑地址和要访问的ECU的逻辑地址。
- 网关收到请求后,进行权限验证。比如,检查诊断工具是否在白名单里。
- 验证通过后,网关回复一个路由激活响应,状态码为0x10(成功)。
- 之后,诊断工具就可以通过这个路由,向目标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实战的第一步。