28、车载以太网与DoIP:车载以太网架构(AVB、TSN);DoIP(Diagnostics over IP)协议;以太网诊断应用开发;车载以太网测试。

说实话,车载以太网这个话题,我当年刚接触的时候也是一头雾水。以前做CAN、LIN开发,觉得那才是“正经”的车载总线。直到有一次,一个项目需要刷写一个几十兆的固件包,用CAN刷了整整一个下午还没完……嗯,从那以后,我就彻底倒向了以太网。

今天咱们聊聊车载以太网和DoIP。这玩意儿现在已经是高端车型的标配了,你想想看,自动驾驶、高清地图、OTA升级,哪个离得开高带宽?

车载以太网架构:AVB与TSN

车载以太网和咱们办公室用的以太网,底层都是IEEE 802.3标准。但车载环境有个特殊要求——实时性。你踩刹车的时候,信号延迟1毫秒可能就出大事了。所以就有了AVB和TSN。

AVB(Audio Video Bridging)

AVB最初是为了解决音视频同步问题。我在做车载音响系统时遇到过,导航提示音和音乐播放不同步,用户体验极差。AVB通过精确时间同步(IEEE 802.1AS)和流量整形(IEEE 802.1Qav)来保证数据按时到达。

  • gPTP(广义精确时间协议):同步精度能达到亚微秒级。说白了,就是让车上所有节点都“对表”。
  • 流预留协议(SRP):提前申请带宽,保证音视频流不被打断。
  • 信用整形器:控制数据发送速率,避免突发流量导致丢包。

TSN(Time-Sensitive Networking)

TSN是AVB的升级版,更强调确定性。我个人习惯把TSN理解为“给以太网装上红绿灯”。它通过时间感知整形器(TAS)和帧抢占机制,让关键数据在精确的时间窗口内传输。

核心区别:AVB适合音视频这种“软实时”场景,TSN适合控制类“硬实时”场景。比如转向、制动这类功能,必须用TSN。

下面这张图是我自己总结的车载以太网协议栈分层,你看一眼就明白了:

应用层:DoIP、SOME/IP、DDS、HTTP 传输层:TCP、UDP 网络层:IPv4、IPv6 数据链路层:IEEE 802.1Q(VLAN)、802.1AS(gPTP) 物理层:100BASE-T1、1000BASE-T1 注:AVB/TSN主要工作在数据链路层和物理层

DoIP(Diagnostics over IP)协议

DoIP,说白了就是把传统的UDS诊断协议搬到以太网上。为什么这么做?原因很简单——快!传统CAN诊断的速率顶天了1Mbps,而以太网轻松上100Mbps甚至更高。

我记得有一次做远程诊断功能,客户要求能在30秒内读取完所有ECU的故障码。用CAN根本不可能,换成DoIP后,10秒就搞定了。

DoIP协议栈

DoIP基于TCP/IP协议栈,使用端口号13400。它的核心机制包括:

  • 车辆发现:诊断仪发送广播消息,ECU回复自己的IP地址和逻辑地址。
  • 路由激活:建立诊断会话,有点像“握手”。
  • 诊断消息传输:封装UDS请求/响应,支持大块数据传输。

小技巧:在实际开发中,我建议把DoIP的“车辆发现”阶段做扎实。很多问题都出在这里——ECU没及时响应广播,导致诊断仪找不到设备。

DoIP报文格式

DoIP报文结构很简单,但有几个字段容易踩坑:

字段 长度(字节) 说明
协议版本 1 当前固定为0x02
逆协议版本 1 取反,用于校验
负载类型 2 0x0001=车辆发现,0x0005=诊断消息
负载长度 4 后续数据的字节数
负载数据 可变 UDS请求/响应或其他DoIP消息

注意:我曾经遇到过一个坑——负载长度字段是网络字节序(大端),但有些芯片默认是小端。如果没做转换,解析出来的长度就是错的,整个报文都会乱掉。

以太网诊断应用开发

开发DoIP应用,我一般分三步走:

  1. 搭建Socket通信:创建TCP/UDP socket,绑定端口13400。
  2. 实现DoIP协议栈:处理车辆发现、路由激活、诊断消息收发。
  3. 封装UDS服务:把DoIP报文里的数据解析成UDS请求(如0x22读取数据、0x2E写入数据)。

下面是一个简化的DoIP诊断消息发送示例(C语言风格伪代码):

// 构建DoIP诊断消息
uint8_t doip_msg[64];
doip_msg[0] = 0x02;                    // 协议版本
doip_msg[1] = 0xFD;                    // 逆协议版本
doip_msg[2] = 0x00;                    // 负载类型高字节
doip_msg[3] = 0x05;                    // 负载类型低字节(诊断消息)
// 负载长度(假设UDS请求为3字节)
doip_msg[4] = 0x00;
doip_msg[5] = 0x00;
doip_msg[6] = 0x00;
doip_msg[7] = 0x03;
// UDS请求:0x22 0xF1 0x90(读取VIN码)
doip_msg[8] = 0x22;
doip_msg[9] = 0xF1;
doip_msg[10] = 0x90;

// 发送到ECU的TCP连接
send(socket_fd, doip_msg, 11, 0);

嗯,这里要注意:实际项目中,UDS请求可能很长(比如刷写固件),需要分片传输。DoIP协议支持“诊断消息确认”和“诊断消息否定确认”,一定要处理好超时重传。

车载以太网测试

测试这块,我吃过不少亏。简单说说几个关键点:

  • 物理层测试:检查信号质量、眼图、抖动。100BASE-T1和普通以太网不一样,是单对差分线,测试设备要选对。
  • 协议一致性测试:用自动化测试工具(如Vector CANoe、Spirent)跑DoIP协议栈的测试用例。我建议重点测“车辆发现”和“路由激活”这两个场景。
  • 性能测试:测吞吐量、延迟、丢包率。特别是诊断刷写场景,要模拟高负载下的表现。
  • 互操作性测试:不同供应商的ECU混在一起,能不能正常通信?我遇到过某家ECU的DoIP实现不标准,导致诊断仪连不上。

避坑指南:我曾经在测试中发现,某个ECU在收到诊断请求后,回复的DoIP报文里“负载长度”字段算错了。排查了两天才找到原因——是协议栈里一个字节对齐的问题。所以,测试时一定要抓包看原始报文,别只看应用层日志。

车载以太网和DoIP,说白了就是给车装上“高速宽带”。AVB/TSN解决实时性问题,DoIP解决诊断效率问题。开发时多注意协议细节,测试时多抓包分析,基本就能搞定。


公众号:蓝海资料掘金营,微信deep3321