3.3 ISO 13400——DoIP协议
你插上网线的那一刻——等等,OBD口不是CAN的吗?
你的手指捏着一根标准的RJ45网线,愣了两秒。
面前的这辆2024年新款SUV的OBD-II诊断接口不再是传统的梯形16针插座里只有4号、5号接地、6号CAN-H、14号CAN-L那几根硬线。现在,它的第3针、第11针被指定为以太网激活线——你旁边那个崭新的诊断工具不是通过USB-CAN转换器连到D-Sub9口,而是直接插了一根网线——就像你用笔记本电脑插办公室交换机一样自然。
你打开诊断仪上的DoIP配置界面,输入广播地址224.0.0.1,端口13400。回车。半秒之内,屏幕上弹出了五个条目——五个ECU的VIN、逻辑地址、EID/GID——每一个都是车载以太网上的一个DoIP节点。你选择一个引擎控制器,点“连接“——路由激活成功——然后一条TCP流绑定完成。
接下来你测了一个0x22读取DID 0xF190(VIN)——响应在0.3毫秒内返回。同样的请求走你旁边的CAN线通过15765-2经过流控帧和块重组——至少需要2~4毫秒,取决于其他ECU的当前仲裁状态。
这就是DoIP——Diagnostics over IP(ISO 13400)——它把UDS从CAN的8字节小信封塞进了TCP/IP的巨幅画布上。
带宽革命——从90秒到0.7秒的物理鸿沟
让我们用数字对比一下这个差距。你要刷写一个4MB(4,194,304字节)的发动机ECU固件:
走CAN(500 kbps,ISO 15765-2分段传输):
CAN帧利用率分析:
每帧8字节 → 减去1字节PCI头(单帧SF无此)→ 但多帧CF每帧PCI占1字节
实际有效数据每帧 ≈ 7字节(CF格式)
每帧CAN开销 ≈ 帧ID+控制位+CRC+应答槽 ≈ 额外47位
总线上每7字节有效数据需约 47+8×8=111位时间
500 kbps -> 500位/毫秒 -> 每7字节 ≈ 0.222ms
4,194,304字节 ÷ 7 ≈ 599,186帧
考虑流控(FC)的延迟窗口、块间隔(STmin)、其他ECU的仲裁抢占:
实际刷写时间 ≈ 80~120秒
走DoIP(100 Mbps车载以太网,无分段):
以太网帧利用率:
每个TCP段可承载多达1460字节(标准以太网MTU 1500)
DoIP头部仅8字节 + UDS消息负载 = 全部4MB一次或分少数几段
100 Mbps -> 100,000,000位/秒 ≈ 12,500,000字节/秒
4,194,304字节 ÷ 12,500,000 ≈ 0.34秒(理论)
考虑DoIP头部、TCP握手、路由激活、ECU的Flash写入延迟:
实际刷写时间 ≈ 0.5~1秒
差距不是一点点——是100倍数量级的物理鸿沟。
核心洞察:DoIP的出现不是“CAN不够好“——CAN在1Mbps带宽下处理传感器和执行器的实时控制绰绰有余。问题出在诊断数据的“粒度配错“——UDS的诊断帧在CAN上被强制拆分成7字节一块,就像用注射器往静脉里注射营养液——能注射进去,但太慢了。DoIP给了诊断数据传输一条大动脉——不需要拆分、不需要流控、不需要等待对等方的CF帧——TCP只管源源不断地推字节,ECU只管收。这就是为什么DoIP是刷写和大数据读取的革命性改变——它消除了“运输成本“。
DoIP架构全景——不是替代,是扩展
DoIP不是CAN的替代品。同一辆车上,CAN总线和车载以太网并存。架构如下:
┌─────────────────────────────────┐
│ 诊断仪 (Tester) │
│ ┌──────────┐ ┌──────────┐ │
│ │ CAN口 │ │ 以太网口 │ │
│ └────┬─────┘ └────┬─────┘ │
└────────┼──────────────┼──────────┘
│ │
ISO 15765-2 │ │ DoIP (ISO 13400)
CAN 500kbps │ │ Ethernet 100Mbps
│ │
┌──────────────────┼──────┐ ┌───┴──────────────────────┐
│ OBD-II Connector │ │ OBD-II Ethernet Pins │
│ (Pin 6=CAN-H,14=CAN-L)│ │ (Pin 3=ETH+, 11=ETH-) │
└──────────────────┬──────┘ └───┬──────────────────────┘
│ │
┌────────────────────────────┼──────────────┼──────────────────────┐
│ 车内网络 (In-Vehicle Network) │
│ │ │ │
│ ┌─────────┐ ┌─────────┐ │ ┌───────────┴────────────┐ │
│ │ 发动机 │ │ 变速箱 │ │ │ DoIP 网关 ECU │ │
│ │ ECU(CAN)│ │ ECU(CAN)│ │ │ ┌─────────────────┐ │ │
│ │ 0x7E0 │ │ 0x7E1 │ │ │ │ 自带以太网PHY芯片 │ │ │
│ └────┬────┘ └────┬────┘ │ │ ├─────────────────┤ │ │
│ └──────┬─────┘ │ │ │ CAN控制器 (多路) │ │ │
│ │ │ │ │ → 内部CAN总线 │ │ │
│ CAN总线A │ 500kbps │ │ └────────┬────────┘ │ │
│ │ │ │ │ │ │
│ │ │ │ ┌───┐ ┌──┴──┐ ┌───┐│ │
│ │ │ │ │ABS│ │空调 │ │BMS││ │
│ │ │ │ │CAN│ │CAN │ │CAN││ │
│ │ │ │ └───┘ └─────┘ └───┘│ │
│ │ │ │ 内部CAN总线 B │ │
└──────────────┼─────────────┼──┼──────────────────────┼─────────┘
│ │
CAN路径直达引擎ECU DoIP路径到达网关后再进CAN
理解这个架构的关键点:DoIP网关是一台带有以太网PHY芯片和CAN控制器的ECU。诊断仪通过以太网把UDS请求发给网关,网关再把请求原封不动地转成CAN帧发到内部CAN总线上——目标ECU完全不知道这个请求是从以太网过来的。这叫“诊断路由“——网关充当了DoIP和CAN之间的协议翻译器。
DoIP的四大协议步骤——从发现到对话的完整握手
第一步:Vehicle Discovery(车辆发现)
你插上网线后诊断仪发出的第一个动作不是一个UDS请求——而是一个UDP广播包。诊断仪还不知道这个以太网线后面连着几个ECU、每个ECU叫什么名字、逻辑地址是多少。
诊断仪 (IP: 192.168.1.100) → UDP广播 224.0.0.1:13400
Vehicle Identification Request
┌────────────────────────────────┐
│ DoIP Header │
│ ProtocolVersion: 0x02 │
│ InverseProtocolVer: 0xFD │
│ PayloadType: 0x0001 │ — Vehicle Identification Request
│ PayloadLength: 0x00000000│
└────────────────────────────────┘
所有在线DoIP节点监听到这个广播后,各自通过UDP单播回一个Vehicle Announcement:
ECU (IP: 192.168.1.10) → 诊断仪 (IP: 192.168.1.100):13400 (UDP单播)
Vehicle Announcement
┌────────────────────────────────┐
│ DoIP Header │
│ ProtocolVersion: 0x02 │
│ InverseProtocolVer: 0xFD │
│ PayloadType: 0x0004 │ — Vehicle Announcement
│ PayloadLength: 0x00000...│
├────────────────────────────────┤
│ VIN: W0L0TGF67G1000001 │ — 17字节ASCII,全球唯一车辆标识
│ Logical Address: 0x0E80 │ — 双字节,此ECU在UDS网络中的逻辑地址
│ EID: 02:00:00:00:00:01 │ — 6字节实体ID(MAC地址/硬件ID)
│ GID: 01:02:03:04:05:06 │ — 6字节组ID(同型ECU组标识)
│ Further Action: 0x0A │ — 0x0A=No Further Action Required
│ VIN/GID Sync Status: 0x01 │ — 0x01=VIN/GID已同步
└────────────────────────────────┘
关键字段解释:
- VIN:你看到的熟悉的车架号——它让诊断仪的UI可以直接显示“这是哪辆车“而不用用户手动输入。
- EID (Entity ID):通常在ECU出厂时烧录到芯片的OTP区域——是ECU个体的硬件指纹——用于路由激活时指定“我要连这个具体的ECU(不是别的同型号ECU)“。
- GID (Group ID):同型号ECU共享的组标识——在刷写时可以批处理“同组所有ECU都更新“。
- Logical Address:这是最关键的一个字段——它就是UDS世界中此ECU在诊断网络里的地址(对应CAN诊断中的诊断CAN ID的源地址部分)。你后续发TCP上的UDS消息时,这个逻辑地址填在DoIP头部中——网关靠这个地址把消息路由到正确的内部CAN节点。
第二步:Routing Activation(路由激活)
你从五个回复的ECU中选择了发动机控制器(逻辑地址0x0E80)。现在你需要在这条TCP连接上建立诊断通道——DoIP称这个过程为“路由激活“。
诊断仪 → ECU (TCP SYN, port 13400):
三次握手——建立可靠TCP连接
诊断仪 → ECU (TCP data, port 13400):
Routing Activation Request
┌────────────────────────────────┐
│ DoIP Header │
│ ProtocolVersion: 0x02 │
│ InverseProtocolVer: 0xFD │
│ PayloadType: 0x0005 │ — Routing Activation Request
│ PayloadLength: 0x0000000B│ — 11字节
├────────────────────────────────┤
│ Source Address (SA): 0x0E00 │ — 诊断仪的逻辑地址(双字节)
│ Activation Type: 0x00 │ — 0x00=Default (标准诊断路由激活)
│ Reserved: 0x00000000│ — ISO 13400保留字段
│ OEM Specific: (可选字节...) │ — 整车厂自定义数据
└────────────────────────────────┘
ECU → 诊断仪 (TCP):
Routing Activation Response
┌────────────────────────────────┐
│ DoIP Header │
│ ProtocolVersion: 0x02 │
│ InverseProtocolVer: 0xFD │
│ PayloadType: 0x0006 │ — Routing Activation Response
│ PayloadLength: 0x00000009│
├────────────────────────────────┤
│ Tester Logical Address:0x0E00 │ — 回声诊断仪地址
│ Entity Logical Address:0x0E80 │ — 回声ECU地址
│ Activation Response Code:0x10 │ — 0x10=Routing Successfully Activated
│ Reserved OEM: 0x00000000 │
└────────────────────────────────┘
Response Code的关键值:
| Code | 含义 | 解释 |
|---|---|---|
| 0x10 | 路由激活成功 | TCP连接现在是诊断通道——可以发任意UDS消息 |
| 0x11 | 激活被拒绝——此时不需要 | 这个ECU已经被激活——不需要再激活 |
| 0x00 | 激活被拒绝——未知的源地址 | 诊断仪的SA不在ECU的白名单中 |
| 0x01 | 激活被拒绝——无可用Socket | ECU的TCP socket资源已耗尽 |
| 0x04 | 激活被拒绝——认证失败 | 需要TLS/安全认证但未通过 |
一旦收到0x10,这条TCP连接就变成了UDS运输管道——你后续在这条连接上发送的所有UDS报文,都会被ECU的Dcm栈正常接收、处理、返回正响应。
第三步:Diagnostic Message Exchange(诊断消息交换)
激活后的诊断消息通过DoIP payload承载,头部如下:
DoIP Diagnostic Message 帧结构:
┌──────────┬─────────────┬─────────────┬──────────────┬──────────────────┐
│ Protocol │ Inverse │ PayloadType │ PayloadLength│ UDS Message │
│ Version │ ProtocolVer │ (2 bytes) │ (4 bytes) │ (变长) │
│ (1 byte) │ (1 byte) │ │ │ │
├──────────┼─────────────┼─────────────┼──────────────┼──────────────────┤
│ 0x02 │ 0xFD │ 0x8001 │ 0x0000000A │ 源地址 目标地址 │
│ │ = 0xFF-0x02│ Diagnostic │ = 10字节 │ 源地址 目标地址 │
│ │ 版本校验 │ Message │ │ [UDS请求] │
└──────────┴─────────────┴─────────────┴──────────────┴──────────────────┘
PayloadType 枚举:
0x0000 = Generic DoIP Header NACK
0x0001 = Vehicle Identification Request
0x0004 = Vehicle Announcement
0x0005 = Routing Activation Request
0x0006 = Routing Activation Response
0x8001 = Diagnostic Message(负载中携带UDS请求/响应)
0x8002 = Diagnostic Message Positive ACK(肯定确认)
0x8003 = Diagnostic Message Negative ACK(否定确认——DoIP层错误,如未知目标地址)
ProtocolVersion和InverseProtocolVersion是一对校验搭档——InverseProtocolVersion必须是0xFF - ProtocolVersion。如果接收方收到这两个值不满足互补关系,直接丢弃——这是最简单的位翻转检测机制——防止一个比特位差错导致协议版本被错误识别。
第四步:Alive Check / Entity Status
TCP连接建立后诊断仪不会永久占用——DoIP规定诊断仪必须周期性地通过UDP查询ECU状态以确认通道仍然存活。如果超过一定时间没有Alive Check,ECU可以主动关闭TCP连接——释放socket资源。
诊断仪 → ECU (UDP 单播):
DoIP Header
PayloadType = 0x0003 — Entity Status Request
ECU → 诊断仪 (UDP 单播):
DoIP Header
PayloadType = 0x4003 — Entity Status Response
状态字节:当前Socket数、最大Socket数、激活的连接数...
和ISO 15765-2的正面对比——为什么分段逻辑完全不同
| 对比维度 | ISO 15765-2 (CAN) | ISO 13400 (DoIP) |
|---|---|---|
| 物理带宽 | 500 kbps 或 1 Mbps | 100 Mbps (或1000 Mbps) |
| 帧格式 | CAN 8字节帧,分SF/FF/FC/CF四种PCI格式 | TCP/IP流,无帧长度限制 |
| 数据段大小 | 单帧最多7字节有效数据,连续帧也如此 | TCP段1460字节(常用MTU),携带完整UDS报文 |
| 多帧机制 | FF发长度→ECU回FC(BS+STmin)→诊断仪推CF块 | 不需要——TCP保证顺序到达、不丢包、不分段(在IP层完成) |
| 流控 | 基于FC帧的Block Size和Separation Time | 基于TCP的窗口流量控制——由操作系统TCP栈自动管理 |
| 最大消息长度 | 4095字节(FF的12位长度字段上限) | 由PayloadLength字段的4字节限制=约4GB(实际受ECU RAM限制,通常设上限为几十MB) |
| 连接管理 | 不需要连接——CAN ID即连接(无连接协议) | 需要TCP三次握手+路由激活+Alive Check(面向连接) |
| 诊断仪硬件 | 几十元的USB-CAN适配器 | 标准以太网口(任何笔记本自带)+ DoIP协议栈软件 |
| 电磁干扰抗性 | 强——CAN的差分信号+位填充自带EMI鲁棒性 | 中等——以太网100BASE-T1(单对双绞线)在车载环境中已经证明可靠,但成本高于CAN收发器 |
| 时间确定性 | 实时——CAN仲裁保证高优先级帧准时到达 | 较弱的实时性——TCP重传会引入不可预测的延迟 |
核心洞察:CAN和DoIP在分段机制上的差异,本质上是“无连接 vs 面向连接“两个世界的碰撞。CAN的无连接特性让你可以随时发一个单帧80ms完成一次对话(如0x22读取DID)——这是轻量级的优势。DoIP需要先建立TCP连接再路由激活,额外开销大约50~100ms——对于小诊断请求显然是过重的。但对于4MB固件刷写——CAN的7字节/帧的离散传输让你付出100秒的代价,而DoIP的连续TCP流用半秒完成。它们的关系不是“谁取代谁“——而是“轻型诊断走CAN,重型数据走DoIP“的天然分工。
UDS报文在DoIP中的无摩擦旅行
DoIP和UDS的“分界“非常清晰——UDS消息在DoIP中是完整传递给ECU的,不需要做任何修改或转码:
UDS请求:"读取DID 0xF190 (VIN)
作为纯粹的字节数组: 0x22 0xF1 0x90
在 CAN 上的打包(ISO 15765-2 单帧):
┌──────┬──────┬──────┬──────┬───┬───┬───┐
│ PCI │ 0x22 │ 0xF1 │ 0x90 │Pad│Pad│...│ 需PCI头+填充
└──────┴──────┴──────┴──────┴───┴───┴───┘
CAN ID: 0x7E0 (物理寻址)
在 DoIP 上的打包(ISO 13400 Diagnostic Message):
┌──────────┬──────┬──────┬──────┐
│ DoIP Hdr │ 0x22 │ 0xF1 │ 0x90 │ 无填充,报文完整
└──────────┴──────┴──────┴──────┘
加上DoIP头部中的SA=0x0E00(诊断仪), TA=0x0E80(ECU)
ECU的Dcm层看到的:无论是哪条路径进来的,都是完全相同的字节流:
0x22 0xF1 0x90
ECU内部的Dcm栈不需要写两个版本——CAN路径的CanTp_RxIndication()和DoIP路径的SoAd_RxIndication()是PDU Router下的两个不同入口,但它们最终都调用同一个Dcm_ProcessRxMessage()。这就是AUTOSAR分层的威力——UDS服务实现与传输通道是正交的。
历史溯源:从KWP2000 on K-Line到UDS on CAN到UDS on DoIP
如果你回溯诊断通信的历史线:
1990s: KWP2000 (ISO 14230) on K-Line — 10.4 kbps
→ 刷写一块256KB ECU需要15分钟
→ 诊断仪通过专用串口卡连接——设备笨重、速度慢
2000s: UDS (ISO 14229) on CAN (ISO 15765-2) — 500 kbps
→ 刷写4MB ECU需要约90秒
→ 引入了分段传输(FF/FC/CF)、流控、多帧重组
→ 至今仍是最广泛部署的诊断通道
2010s: UDS on DoIP (ISO 13400:2011) — 100 Mbps
→ 刷写4MB ECU超过100倍提速——不到1秒
→ 2019年ISO 13400第2版发布——增加了TLS安全认证
→ 车载以太网芯片成本下降——DoIP从高端车型走向大众市场
2020s: UDS on CAN FD (ISO 15765-2扩展) — 5~8 Mbps
→ CAN FD帧支持64字节数据段——单帧效率大幅提高
→ 和DoIP并存——CAN FD处理中等数据量场景(几KB到几百KB)
→ DoIP处理巨量数据场景(几MB以上)
DoIP不是突然出现的——它是车载以太网整体架构在诊断领域的自然延伸。2010年以后,随着ADAS摄像头、激光雷达、以太网AVB音视频流等对带宽要求越来越高的应用进入汽车,车载以太网的交换机芯片和PHY收发器逐渐成熟——DoIP作为TCP/IP在诊断领域的复用方案应运而生。
本篇小结
-
DoIP (ISO 13400) 是TCP/IP之上的UDS传输协议——它把UDS从CAN的8字节分段限制中解放出来,以100Mbps车载以太网的速度为刷写和大数据读取提供了100倍以上的带宽提升。
-
DoIP的四大协议步骤——Vehicle Discovery(UDP广播)→Routing Activation(TCP握手)→Diagnostic Message Exchange(TCP流)→Alive Check(UDP)构成了一套完整的面向连接架构,每一步有精确的PayloadType标识。
-
Vehicle Announcement中的VIN/EID/GID/Logical Address四个关键字段共同完成“车辆身份识别→ECU个体定位→逻辑地址绑定“的完整的网络自描述,诊断仪在插入网线后0.5秒内即可获取全车DoIP拓扑。
-
DoIP和CAN不是竞争关系——轻型诊断(如读取DID、查询DTC)走CAN通路(轻量、无连接开销),重型数据(刷写固件、读回完整存储器镜像)走DoIP通路(高带宽、面向连接)。
-
UDS应用层与传输层完全解耦——同一份0x22/0x2E/0x31等UDS服务实现逻辑不需要任何修改,Dcm栈通过CanTp或SoAd接口接收完全相同的UDS字节流。
【下集预告】:你现在有两条诊断通道:CAN(ISO 15765-2)和DoIP(ISO 13400)。一条轻快、一条高速;一条无连接随时能用、一条需要TCP先握手再激活。在一个真实的ECU上同时支持这两条通道,PDU Router怎么做仲裁?两路诊断请求同时到达怎么办?你面临的是真正的传输层对决——不是选谁赢,而是怎么协作共存。