Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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激活被拒绝——无可用SocketECU的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 Mbps100 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在诊断领域的复用方案应运而生。


本篇小结

  1. DoIP (ISO 13400) 是TCP/IP之上的UDS传输协议——它把UDS从CAN的8字节分段限制中解放出来,以100Mbps车载以太网的速度为刷写和大数据读取提供了100倍以上的带宽提升。

  2. DoIP的四大协议步骤——Vehicle Discovery(UDP广播)→Routing Activation(TCP握手)→Diagnostic Message Exchange(TCP流)→Alive Check(UDP)构成了一套完整的面向连接架构,每一步有精确的PayloadType标识。

  3. Vehicle Announcement中的VIN/EID/GID/Logical Address四个关键字段共同完成“车辆身份识别→ECU个体定位→逻辑地址绑定“的完整的网络自描述,诊断仪在插入网线后0.5秒内即可获取全车DoIP拓扑。

  4. DoIP和CAN不是竞争关系——轻型诊断(如读取DID、查询DTC)走CAN通路(轻量、无连接开销),重型数据(刷写固件、读回完整存储器镜像)走DoIP通路(高带宽、面向连接)。

  5. UDS应用层与传输层完全解耦——同一份0x22/0x2E/0x31等UDS服务实现逻辑不需要任何修改,Dcm栈通过CanTp或SoAd接口接收完全相同的UDS字节流。


【下集预告】:你现在有两条诊断通道:CAN(ISO 15765-2)和DoIP(ISO 13400)。一条轻快、一条高速;一条无连接随时能用、一条需要TCP先握手再激活。在一个真实的ECU上同时支持这两条通道,PDU Router怎么做仲裁?两路诊断请求同时到达怎么办?你面临的是真正的传输层对决——不是选谁赢,而是怎么协作共存。