1. DoIP协议概述
1.1 DoIP协议背景
各位工程师朋友,咱们今天聊聊DoIP。说实话,我第一次接触这个协议是在2018年,当时一个客户要求我们新平台必须支持DoIP诊断。我心想,这不就是UDS over IP嘛,能有多复杂?结果一上手才发现,坑还真不少。
先说说背景。传统汽车诊断用的是CAN总线,速度最高也就1Mbps。你想想看,现在一辆车动辄几十上百个ECU,每个ECU的软件动辄几十MB。用CAN刷写一个ECU,有时候得等半小时。我记得有个项目,客户要求OTA升级必须在15分钟内完成全车刷写。用CAN?门儿都没有。
为什么会这样?因为CAN的带宽瓶颈摆在那里。随着智能网联汽车的发展,车载网络的数据量呈指数级增长。高清地图、自动驾驶数据、车载娱乐系统...这些都需要高带宽。以太网自然就成了最佳选择。100BASE-T1、1000BASE-T1这些车载以太网标准,带宽从100Mbps到1Gbps,刷个软件分分钟的事。
DoIP(Diagnostic over Internet Protocol)就是在这样的背景下诞生的。说白了,就是把传统的UDS诊断协议搬到以太网上来跑。它继承了UDS的诊断服务,但底层传输从CAN换成了IP网络。
核心要点:DoIP不是新造一套诊断协议,而是让UDS在以太网上跑得更快、更远、更灵活。
1.2 DoIP协议在车载网络中的定位
DoIP在车载网络中的定位,我习惯用三个角色来理解:
- 诊断通道:它是外部诊断工具与车内ECU之间的通信桥梁
- 网关接口:通常部署在中央网关或域控制器上,负责协议转换
- 刷写通道:OTA升级时,DoIP是主要的软件传输通道
你想想看,一辆车有多个域:动力域、底盘域、车身域、信息娱乐域、自动驾驶域。每个域内部可能还是CAN、LIN、FlexRay这些传统总线。DoIP网关就站在以太网和这些总线之间,一边用DoIP和外部工具通信,一边用CAN等协议和内部ECU通信。
我在项目中遇到过一个问题:某款车的DoIP网关同时要处理诊断请求和OTA刷写,结果在刷写高峰期,诊断响应超时了。后来怎么解决的?我们给DoIP网关配置了优先级队列,诊断请求走高优先级通道,刷写数据走低优先级通道。嗯,这里要注意,DoIP协议本身并没有规定优先级机制,这是工程实现上的考量。
| 网络层级 | 典型协议 | DoIP的角色 |
|---|---|---|
| 应用层 | UDS (ISO 14229) | 诊断服务载体 |
| 传输层 | TCP/UDP | 可靠/快速传输 |
| 网络层 | IPv6 (推荐) | 地址分配与路由 |
| 数据链路层 | 100BASE-T1 / 1000BASE-T1 | 物理传输 |
1.3 DoIP协议标准ISO 13400介绍
ISO 13400是DoIP的官方标准,全称是"Road vehicles — Diagnostic communication over Internet Protocol (DoIP)"。这个标准分了好几个部分,我挑重点说:
- ISO 13400-1:通用信息和用例定义。说白了就是告诉你DoIP能干啥,不能干啥。
- ISO 13400-2:传输层和网络层要求。这是最核心的部分,定义了报文格式、连接管理、路由激活等。
- ISO 13400-3:基于IEEE 802.3的有线以太网物理层。针对车载环境做了特殊规定。
- ISO 13400-4:基于IEEE 802.11的无线以太网物理层。这个部分还在完善中。
- ISO 13400-5:一致性测试。用来验证你的DoIP实现是否符合标准。
个人建议:如果你刚开始做DoIP开发,先把ISO 13400-2啃透。这部分定义了DoIP报文的结构,包括版本号、类型、长度这些字段。我曾经见过一个团队,因为版本号字段填错了,导致诊断工具死活连不上ECU。查了两天才发现是版本号不匹配。
ISO 13400标准里定义了几种核心的DoIP报文类型:
- 0x0000:Generic DoIP header negative acknowledge - 通用否定应答
- 0x0001:Vehicle identification request - 车辆识别请求
- 0x0002:Vehicle identification request with EID - 带EID的车辆识别请求
- 0x0003:Vehicle identification request with VIN - 带VIN的车辆识别请求
- 0x0004:Vehicle announcement message - 车辆声明消息
- 0x0005:Routing activation request - 路由激活请求
- 0x0006:Routing activation response - 路由激活响应
- 0x8001:Diagnostic message (UDS payload) - 诊断消息
这里要注意,DoIP的报文头是固定8字节的。我刚开始做的时候,总以为报文头长度会变,结果写代码时踩了坑。后来养成了习惯,每次解析DoIP报文,先检查前8个字节的合法性。
避坑指南:我曾经在项目里遇到一个诡异的问题——DoIP连接总是超时。查了三天,最后发现是TCP的Keep-Alive参数没配置好。DoIP标准要求TCP连接空闲超过一定时间后,必须发送Keep-Alive报文。如果你的实现没做这个,连接就会被网关自动断开。
ISO 13400还定义了DoIP实体的状态机。一个典型的DoIP实体有以下几个状态:
- 未初始化:上电后的初始状态
- 监听:等待TCP连接或UDP报文
- 已连接:TCP连接建立成功
- 已激活:路由激活成功,可以收发诊断消息
- 已关闭:连接正常关闭
每个状态之间的转换都有严格的条件。比如从"已连接"到"已激活",必须经过路由激活流程。这个流程包括:客户端发送路由激活请求,服务端验证客户端的身份(通过逻辑地址),然后返回路由激活响应。
说到逻辑地址,ISO 13400规定每个DoIP实体都有一个唯一的逻辑地址。诊断工具的逻辑地址通常是0x0E00,ECU的逻辑地址由OEM自行分配。我见过有些OEM把逻辑地址和VIN码绑定在一起,这样诊断工具就能通过VIN码找到对应的ECU。
嗯,最后说一句。ISO 13400标准虽然看起来厚厚一本,但真正核心的内容其实不多。我建议你从报文格式和状态机入手,先把这两个搞明白,其他的都是锦上添花。