深入解读 DoIP 协议

读懂 DoIP 的报文格式、通信流程和网络架构,理解车载以太网诊断从握手到刷写的完整链路。

诊断瓶颈与 DoIP 的解法

单帧 8 字节,一个刷写包几 MB。CAN 诊断在汽车电子中服役二十年,带宽瓶颈已经压不住了——DoIP 就是解法:把诊断通道从 CAN 搬到车载以太网,用 TCP/IP 的带宽换取诊断效率的数量级提升。在 车载网络 从信号驱动向服务驱动演进的浪潮中,DoIP 承担的是诊断管道这一层。

DoIP 基于 车载诊断 体系中成熟的以太网和 TCP/IP 协议栈,支持高速车辆访问,还能通过路由功能实现 ECU 的并行刷新——这在 CAN 时代是不可想象的。要理解它,需要搞清楚三件事:网络中有哪些角色、它们怎么交互、报文长什么样。

网络架构与五种角色

doip-protocol-deep-dive-fig01.png650

车辆网络分为车内网和车外网,中间由 DoIP Edge Node Gateway 连接。两组线束承担不同职责:以太网线负责数据传输,激活线负责诊断功能的开关。激活线的设计出于两个考量——非诊断期间关闭诊断功能,一方面降低能耗,另一方面减少对网络带宽的占用,降低电磁干扰。

网络中有五种角色,理解它们的关系就理解了 DoIP 的拓扑骨架:

Edge Node Gateway 和 DoIP Gateway 的区别不在功能架构,而在部署分工。MPU 通常充当 Edge Node 处理复杂的连接管理和安全认证,MCU 充当 Gateway 做简单的协议路由。区分 Server 和 Client 身份的关键是数据流方向——收外部请求是 Server,向内转发是 Client。

通信流程与报文格式

六个阶段

doip-protocol-architecture-fig03.png650

DoIP 诊断不是 " 连上就能用 ",而是一套有严格顺序的握手流程。整个过程涉及 Actor、Client DoIP Entity、Server DoIP Entity 和 Vehicle Non-DoIP ECU 四个角色,依次经过六个阶段:

车辆发现(UDP 广播):诊断仪发送广播报文,所有 DoIP 实体回复自己的身份信息——VIN、EID、逻辑地址。诊断仪据此获知哪些 ECU 在线,并按车辆分组归类。

路由激活(TCP 连接建立后):诊断仪与 DoIP 节点建立 TCP 连接后,必须发送路由激活请求,经安全认证通过后才能进行诊断。ECU 开发人员可自定义认证算法,屏蔽非法诊断仪。这是 DoIP 安全模型的第一道门。

诊断仪在线监测:TCP 连接消耗内存资源,ECU 设计阶段就限定了最大并行连接数。在线监测机制定期向现有连接发送心跳请求,无响应的连接被复位释放,避免稀缺通道被无效占用。

节点信息查询:获取节点的关键属性——最大并行连接数、最大可接受报文长度、当前电源状态。这是诊断通信前的条件检查,确保后续操作不受干扰。

诊断通信:DoIP 的核心功能。诊断报文携带发送方逻辑地址(SA)、接收方逻辑地址(DA)和诊断数据。在 CAN 网络中通过 CAN ID 寻址,在 DoIP 中逻辑地址 DA 扮演了相同角色。

DoIP 基于应用层协议,传输层使用 TCP 和 UDP。每个 DoIP 实体支持 n+1 个 TCP socket 和 k+1 个 TLS socket(n、k 为并发连接数),TCP 端口 13400(非加密)和 3496(TLS 加密)用于诊断数据传输,UDP 端口 13400 用于车辆发现和节点状态查询。

报文格式与负载类型

doip-protocol-deep-dive-fig02.png600

每条 DoIP 报文由固定头部和数据区组成。头部 8 字节:协议版本号(1 字节)、版本号取反(1 字节)、负载类型(2 字节)、负载长度(4 字节),后面跟实际数据。

协议版本号标识报文遵循的规范版本:

版本号 对应标准
0x01 ISO 13400-2:2010
0x02 ISO 13400-2:2012
0x03 ISO 13400-2:2019
0xFF 车辆识别请求的默认版本号

版本号取反是对版本字段的校验——版本 0x03 对应取反值 0xFC,接收方据此快速判断报文格式是否正确。

负载类型分为三大类,对应不同功能域:

分类 类型值范围 功能
节点管理类 0x0000-0x0008 车辆发现、路由激活、在线检查
诊断类 0x8001-0x8003 诊断请求、肯定响应、否定响应
节点状态类 0x4001-0x4004 节点状态和电源模式查询

打个比方:把 DoIP 通信比作打电话,节点管理类是 " 拨号和接通 ",诊断类是 " 说话和回应 ",节点状态类是 " 确认对方手机有电 "。三类的具体报文明细:

节点管理类报文(UDP/TCP):

负载类型 名称 强制/可选 协议
0x0000 DoIP 首部否定响应 强制 UDP/TCP
0x0001 车辆识别请求 强制 UDP
0x0002 带 EID 的车辆识别请求 可选 UDP
0x0003 带 VIN 的车辆识别请求 强制 UDP
0x0004 车辆声明/识别响应 强制 UDP
0x0005 路由激活请求 强制 TCP
0x0006 路由激活响应 强制 TCP
0x0007 在线检查请求 强制 TCP
0x0008 在线检查响应 强制 TCP

诊断类报文(TCP):

负载类型 名称 强制/可选 协议
0x8001 诊断报文 强制 TCP
0x8002 诊断报文肯定应答 强制 TCP
0x8003 诊断报文否定应答 强制 TCP

节点状态类报文(UDP):

负载类型 名称 强制/可选 协议
0x4001 实体状态请求 可选 UDP
0x4002 实体状态响应 可选 UDP
0x4003 诊断电源模式请求 强制 UDP
0x4004 诊断电源模式响应 强制 UDP

真实报文解析

以下报文来自实际项目捕获,可用于对照上文的格式逐字节解读。

车辆发现:

req:  02 fd 00 01 00 00 00 00
resp: 02 fd 00 04 00 00 00 21 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 11 11 ff ff ff ff ff ff 00 00 00 00 00 00 00 00

02 fd 是版本号和取反校验(0x02 = ISO 13400-2:2012,取反 0xFD);00 01 是车辆识别请求;00 00 00 00 是负载长度为 0。响应的负载类型 00 04 是车辆声明,负载长度 00 00 00 21(33 字节)包含 VIN、逻辑地址和 EID 等身份信息。带 EID 和带 VIN 的请求只是多了目标标识,用于精确查找特定 ECU。

实体状态:

req:  02 fd 40 01 00 00 00 00
resp: 02 fd 40 02 00 00 00 07 00 01 00 00 00 00 05 dc

请求类型 40 01 是实体状态请求,响应类型 40 02 返回 7 字节数据,包含节点类型、最大并发连接数、当前连接数和最大数据大小(05 dc = 1500 字节)。

路由激活:

req:  02 fd 00 05 00 00 00 0b 0e 80 e2 00 00 00 00 ff ff ff ff
resp: 02 fd 00 06 00 00 00 0d 0e 80 11 11 10 00 00 00 00 00 00 00 00

请求中 00 05 是路由激活类型,0e 80 是诊断仪源地址,e2 00 是目标地址,ff ff ff ff 是认证字段(此处未使用)。响应中 10 00 表示路由激活成功。

诊断通信:

req:      02 fd 80 01 00 00 00 06 0e 80 12 30 10 03
resp ack: 02 fd 80 02 00 00 00 05 12 30 0e 80 00

80 01 是诊断报文类型,0e 80 是源地址,12 30 是目标地址,10 03 是 UDS 诊断数据。响应 80 02 是肯定应答,最后 00 是确认码。

AUTOSAR 中的实现

四个模块

AUTOSAR分层架构 中,DoIP 由四个模块协作实现:

网关的两种转发模式

DoIP Gateway to Classical Bus Systems:

doip-protocol-architecture-fig01.png500

传统总线(CAN/LIN)下,Gateway 维护 DoIP 逻辑地址到总线 ID 的映射表,将以太网诊断报文翻译为传统总线帧格式转发。以太网的高带宽使得 Gateway 可以并行刷新多个 ECU。

In-Vehicle Ethernet ECU Diagnostics

doip-protocol-architecture-fig02.png500

对于车内以太网 ECU 的诊断,ISO 13400 未明确规定实现方式,实践中存在两种模式:


DoIP 把诊断管道从 CAN 的 8 字节单帧换成了以太网的百兆带宽,但管道之上,诊断的本质没有变——仍然是 UDS 协议的请求 - 响应模式。真正值得思考的是:当车载以太网带宽足够充裕,诊断和刷新是否还必须是独立功能?它们会不会和 SOA 服务通信融合成同一条数据通道?