诊断为啥走上了以太网?DoIP一次讲透

发布时间:2026/10/14 19:34:14
诊断为啥走上了以太网?DoIP一次讲透
前年跟一个网关项目刷写一台域控制器120MB左右的固件挂在500kbps的CAN上跑。工具栏里的进度条挪得比蜗牛还慢刷完花了四十多分钟中途还断了一次重头再来。那天我就一个念头诊断这条路再这么走下去OTA根本没法玩。后来项目切到DoIP同样的包几十秒就过去了。不是CAN突然变差了是车里要传的东西变多了多到CAN装不下了。CAN装不下的不只是刷写一辆车里的CAN大多跑在500kbps。日常收发报文、跑用例够用。麻烦出在两个地方。一是刷写和OTA固件几十MB起步有的域控上百MB按有效带宽粗算CAN要半小时以上以太网100BASE-T1理论上100Mbps同样的数据量级是分钟级甚至秒级差距是数量级的。二是数据量本身摄像头、激光雷达、域控之间的同步数据CAN根本接不住。CAN FD把速率抬到2Mbps、5Mbps解了燃眉之急但离刷写和大数据还有距离。于是车里分工变了控制类实时信号继续走CAN、LIN诊断、刷写、大数据走以太网。DoIP就是诊断走上以太网的那座桥。DoIP到底是个啥把UDS装进以太网包里DoIP全称Diagnostics over Internet Protocol标准是ISO 13400。它不是一套新的诊断服务而是一种传输方式把原来跑在CAN上的UDS诊断数据搬到以太网上传。UDS本身一点没变变的只是“快递公司”。以前是DoCANISO 15765负责把UDS报文拆成CAN帧送过去现在是DoIP负责把UDS报文装进TCP包送过去。物理接口上DoIP用UDP 13400端口做车辆发现用TCP 13400端口传诊断数据。诊断仪接上车先在UDP上喊一嗓子找车拿到车辆信息再用TCP建连接做诊断。先看报文8字节头 诊断内容DoIP报文结构很好记前面8字节固定头后面是负载。头里有四样东西协议版本固定0x02、反码0xFD用来校验版本字节有没有传错、负载类型2字节告诉对方后面是什么消息、负载长度4字节。负载类型是最常用的识别位0x0001是车辆识别请求0x0004是车辆识别响应0x0005是路由激活请求0x0006是路由激活响应0x0007/0x0008是存活检查请求/响应0x4001是诊断消息0x4002/0x4003是诊断消息的肯定/否定确认。拿Wireshark抓包先看这2字节就知道这条报文在干嘛。诊断消息的负载也固定源地址2字节 目标地址2字节 UDS报文。比如诊断仪0x0E00向网关0x1000发读VINUDS部分是22 F1 90整条DoIP诊断消息就是0x0E00、0x1000、22 F1 90。网关回的肯定响应里UDS部分是62 F1 90 17字节VIN。UDS那套请求响应原封不动只是外面多了一层DoIP的皮。路由激活诊断开始前先敲门DoIP诊断不是连上TCP就能发22了得先过路由激活这一关。流程分三步。第一步诊断仪发车辆识别请求网关回车辆识别响应带VIN、逻辑地址这些信息确认找对了车。第二步诊断仪发路由激活请求负载类型0x0005带上自己的源地址比如0x0E00和激活类型一般是0x00默认类型。网关收到后查表这个源地址认不认连接数满没满有没有别的设备占着第三步网关回路由激活响应0x0006带一个响应码0x00是成功可以开始诊断0x01是未知源地址0x02是连接数已满0x03是这个源地址已经注册了。拿到0x00诊断会话才算真正建立。之后双方还要靠存活检查Alive Check维持连接网关定时发0x0007问一句“还在吗”诊断仪回0x0008长时间不回连接就释放。这个机制在测试里经常出问题诊断仪脚本跑完忘记关连接占着名额下一个设备再连就报0x02查半天以为是网关坏了。DoIP和UDS别再混着叫新手最容易把这两个词混着用。记住一句话UDS是“说什么”DoIP是“怎么送”。UDSISO 14229定义诊断服务0x22读数据、0x27安全访问、0x19读DTC、0x14清DTC请求长什么样、响应怎么回、否定响应码什么意思都归它管。DoIPISO 13400只管把UDS报文在以太网上送达找车、建连、路由、确认、保活。它和DoCAN是平级关系DoCAN管CAN上的运输DoIP管以太网上的运输。画协议栈最直观最上面是UDS应用层中间是DoIP下面是TCP/UDP再下面是IP、以太网。测试时分层定位也按这个来UDS否定响应码不对查UDS层路由激活被拒绝、TCP连不上查DoIP层。混在一起查越查越乱。测试DoIP盯住这几个点实测DoIP检查项不用拉很长盯住这几处就行。路由激活用合法地址、非法地址、重复地址各连一次看响应码是不是0x00、0x01、0x03连接占满后新连是不是报0x02。报文头协议版本是不是0x02反码是不是0xFD负载长度和实际长度对不对得上错一个字节网关就该回否定确认。存活检查拔掉诊断仪看连接是不是按超时释放反过来网关不回存活检查诊断仪有没有重连。并发两个诊断仪同时连网关怎么处理。还有一层容易漏的网关收到DoIP诊断消息后要路由到内网CAN总线上的目标ECUDoIP-CAN网关这条链路不通诊断仪这边看到的就是超时问题却在网关路由表里。抓包时养成习惯先看DoIP层通没通再看UDS层对不对分层看省一半时间。一句话收尾车里数据量上去了诊断就得换条更宽的路DoIP就是UDS在以太网上的走法。报文结构、路由激活、和UDS的分工这三处摸透DoIP测试就立得住了。动手DoIP报文解析小工具Python可直接跑光看报文结构容易记混下面这段小工具只依赖标准库把Wireshark里复制出的整条DoIP报文贴进去就能拆出头和负载。先拆请求再拆响应最后故意把反码改错一位看校验怎么拦。# DoIP 报文解析小工具只依赖标准库抓包复制十六进制就能跑# 约定输入是 Wireshark 里复制出的整条 DoIP 报文十六进制空格分隔PAYLOAD_TYPE{0x0001:车辆识别请求,0x0004:车辆识别响应,0x0005:路由激活请求,0x0006:路由激活响应,0x0007:存活检查请求,0x0008:存活检查响应,0x4001:诊断消息,0x4002:诊断肯定确认,0x4003:诊断否定确认,}ROUTING_RESP{0x00:成功可以开始诊断,0x01:未知源地址,0x02:连接数已满,0x03:这个源地址已经注册了}defparse_doip(hex_str):rawbytes.fromhex(hex_str)# 空格分隔的十六进制转字节assertlen(raw)8,报文短于 8 字节头ver,inv,ptyperaw[0],raw[1],int.from_bytes(raw[2:4],big)plenint.from_bytes(raw[4:8],big)# 头校验版本固定 0x02反码是版本按位取反长度要和实际对得上assertver0x02,f协议版本不对{ver:#04x}assertinv(ver^0xFF),f反码不对{inv:#04x}应为{ver^0xFF:#04x}assertplenlen(raw)-8,f负载长度{plen}与实际{len(raw)-8}对不上payloadraw[8:]out{协议版本:f{ver:#04x},负载类型:f{ptype:#06x}({PAYLOAD_TYPE.get(ptype,未知)})}ifptype0x4001:# 诊断消息源地址 2 字节 目标地址 2 字节 UDS 报文out[源地址]f{int.from_bytes(payload[0:2],big):#06x}out[目标地址]f{int.from_bytes(payload[2:4],big):#06x}out[UDS]payload[4:].hex( ).upper()returnout# 实跑演示正文里那条 22 F1 90 读 VIN一来一回req02 FD 40 01 00 00 00 07 0E 00 10 00 22 F1 90resp(02 FD 40 01 00 00 00 18 10 00 0E 00 62 F1 90 4C 56 53 48 43 41 4D 45 38 50 46 31 32 33 34 35 36)print(parse_doip(req))print(parse_doip(resp))vinbytes.fromhex(parse_doip(resp)[UDS].replace( ,))[3:].decode()print(VIN ,vin)# 反码被改错一位网关就该回否定确认先在本地把这种错帧拦下来bad02 FE 40 01 00 00 00 07 0E 00 10 00 22 F1 90try:parse_doip(bad)exceptAssertionErrorase:print(校验失败,e)上面两段报文都是按正文数据拼的逐个数一遍请求帧头02 FD 40 01 00 00 00 07负载长度 7 源地址 2 目标地址 2 UDS22 F1 903响应帧头02 FD 40 01 00 00 00 18负载长度 24 2 2 UDS62 F1 90 17 字节 VIN20。响应里源地址和目标地址对调了网关 0x1000 发给诊断仪 0x0E00VIN 的十六进制解出来是LVSHCAME8PF123456。实跑输出{协议版本: 0x02, 负载类型: 0x4001(诊断消息), 源地址: 0x0e00, 目标地址: 0x1000, UDS: 22 F1 90} {协议版本: 0x02, 负载类型: 0x4001(诊断消息), 源地址: 0x1000, 目标地址: 0x0e00, UDS: 62 F1 90 4C 56 53 48 43 41 4D 45 38 50 46 31 32 33 34 35 36} VIN LVSHCAME8PF123456 校验失败 反码不对0xfe应为 0xfd下期预告CANoe和CANalyzer到底啥区别这里是车软学堂每天一篇汽车电子测试干货。明天见。 往期推荐第一次打开CANoe先看懂这3个窗口汽车电子测试工程师每天到底在干啥五大质量工具之FMEA失效模式分析刚入行做汽车电子测试先搞懂这5个概念DoIP诊断实战——以太网时代的UDS怎么调视觉通用智能来了一篇论文重新思考AGI未来的AI可能首先要“看懂世界”啃完这本开源教材大模型的底层逻辑我算是理清了从零开始用ComfyUI跑MiniMaxH3本地安装、云端和视频工作流搞懂UDS诊断从这篇开始——测试应用层工程师实战指南