3、车载以太网数据链路层:MAC地址、VLAN(802.1Q)、帧结构、MAC层过滤机制

各位工程师朋友,大家好。今天我们聊聊车载以太网的数据链路层。这一层在OSI模型里排第二,但在我眼里,它是整个通信的「地基」。你想想看,物理层把比特流送过来了,数据链路层就得负责把这些比特组织成帧,还要保证不出错、不丢包。说白了,它就是以太网的「交通警察」。

我个人习惯把数据链路层拆成两个子层:LLC(逻辑链路控制)和MAC(介质访问控制)。但在车载以太网里,我们最常打交道的其实是MAC子层。今天我就带大家把MAC地址、VLAN标签、帧结构,还有过滤机制,一个一个捋清楚。

3.1 MAC地址:设备的「身份证」

MAC地址,全称是Media Access Control Address。每个以太网设备出厂时都会烧录一个全球唯一的48位地址。嗯,这里要注意,我说的是「理论上唯一」。实际项目中,我遇到过两次MAC地址冲突的坑,后面会讲。

MAC地址长这样:00:1A:3F:12:34:56。前24位是OUI(组织唯一标识符),由IEEE分配,比如00:1A:3F就是某家芯片厂商的。后24位是厂商自己分配的序列号。

重要概念:车载网络中,MAC地址通常有三种类型:

  • 单播地址:第一个字节的最低位为0。发给单个设备。
  • 多播地址:第一个字节的最低位为1。发给一组设备。
  • 广播地址:全F,即FF:FF:FF:FF:FF:FF。发给所有设备。

我在做ADAS域控制器测试时,就碰到过一个奇葩问题。两个ECU的MAC地址居然一样——因为供应商烧录时搞错了。结果网络里疯狂丢包,抓包一看,ARP表一直在震荡。从那以后,我每次做集成测试,第一件事就是检查所有节点的MAC地址是否唯一。

避坑指南:我曾经在某个项目中,发现OEM要求所有ECU的MAC地址必须从某个特定OUI段分配。但供应商提供的芯片是消费级产品,OUI段不对。最后只能通过软件覆盖MAC地址。所以,选型时一定要确认芯片是否支持MAC地址重写。

3.2 VLAN(802.1Q):逻辑隔离的艺术

车载网络里,不同功能域的数据混在一起跑,是很危险的。比如,制动系统的报文和娱乐系统的报文,你肯定不希望它们互相干扰。这时候,VLAN就派上用场了。

VLAN的全称是Virtual Local Area Network。它通过给以太网帧打上一个标签(Tag),把物理网络切分成多个逻辑网络。802.1Q就是定义这个标签的标准。

一个标准的802.1Q标签有4个字节,插在MAC源地址和 EtherType 字段之间。结构如下:

字段 长度 说明
TPID 2字节 固定值0x8100,表示这是一个VLAN帧
PCP 3位 优先级,0-7,7最高。车载里常用3或5
DEI 1位 丢弃指示,1表示拥塞时可丢弃
VID 12位 VLAN ID,0-4095。0和4095保留,实际可用1-4094

我个人习惯把VLAN ID分配成:ADAS域用100,动力域用200,车身域用300,娱乐域用400。这样一眼就能看出报文属于哪个域。

小技巧:在测试时,可以用Wireshark的过滤表达式 vlan.id == 100 快速筛选出ADAS域的报文。我曾经用这个技巧,半小时就定位到了一个跨域通信的延迟问题。

你可能会问:「为什么不用IP子网隔离?」原因很简单——VLAN工作在二层,比三层IP转发快得多。车载网络对实时性要求高,VLAN的硬件转发延迟通常在微秒级,而IP路由可能要到毫秒级。说白了,VLAN就是给数据链路层加了个「门牌号」,交换机看到门牌号就知道该往哪个口送。

3.3 帧结构:从比特到报文

一个完整的以太网帧,从物理层开始,到MAC层结束,长这样:

+----------------+----------+----------+----------+----------------+------+
| 前导码 (7B)    | SFD (1B) | 目的MAC  | 源MAC    | EtherType/长度 | Payload | FCS (4B) |
| 0x55...55      | 0xD5     | (6B)     | (6B)     | (2B)           | (46-1500B)| CRC32  |
+----------------+----------+----------+----------+----------------+------+

咱们一个一个看:

  • 前导码(Preamble):7个字节的0x55,也就是二进制01010101...。作用是让接收端的时钟同步。说白了,就是告诉对方「我要发数据了,你准备好」。
  • SFD(Start Frame Delimiter):1个字节的0xD5,即10101011。最后两位是11,表示帧起始。我刚开始学的时候,老是把前导码和SFD搞混。其实记住一点:前导码是热身,SFD是起跑枪。
  • MAC头:包含目的MAC(6字节)、源MAC(6字节)、EtherType(2字节)。EtherType很重要,0x0800表示IPv4,0x8100表示VLAN,0x0806表示ARP。
  • Payload:数据部分,最小46字节,最大1500字节。如果数据不够46字节,要填充(Padding)。我在测试SOME/IP时,就经常看到小于46字节的报文被自动填充,抓包时要注意区分。
  • FCS(Frame Check Sequence):4字节的CRC32校验。接收端计算CRC,如果和发送端不一致,就丢帧。嗯,这里要注意,FCS只校验MAC头+Payload,不校验前导码和SFD。

避坑指南:我曾经在测试中,发现某个ECU总是丢包。抓包一看,FCS校验失败。查了半天,发现是PHY芯片的时钟抖动太大,导致CRC计算错误。最后换了晶振才解决。所以,物理层的稳定性直接影响数据链路层的可靠性。

3.4 MAC层过滤机制:只收该收的

MAC层过滤,说白了就是网卡决定「这个帧我要不要收」。如果不做过滤,网卡会把所有收到的帧都扔给上层,CPU直接跑满。所以,硬件过滤是必须的。

常见的过滤方式有三种:

  1. 单播过滤:网卡只收目的MAC等于自己MAC的帧。这是最基本的。
  2. 多播过滤:网卡维护一个多播地址列表,只收列表里的多播帧。车载里常用,比如AVB(音频视频桥接)就用多播。
  3. 混杂模式:来者不拒,所有帧都收。测试时用,比如Wireshark抓包就必须开混杂模式。

实际项目中,车载以太网控制器(比如NXP的S32K或瑞萨的R-Car)都支持硬件MAC过滤。你可以配置一个「白名单」,只允许特定MAC地址或VLAN ID的帧通过。我建议在量产代码里,一定要把混杂模式关掉,否则安全性和性能都会出问题。

实战经验:我在做T-Box项目时,发现4G模块的网卡默认开了混杂模式。结果CPU占用率一直居高不下,因为它在处理大量无关的广播帧。后来在驱动里加了一个过滤规则,只收目的MAC为T-Box自己的帧,CPU占用率直接从80%降到了5%。

还有一个容易被忽略的点:VLAN过滤。如果你的交换机配置了VLAN,但ECU的MAC层没做VLAN过滤,那ECU可能会收到其他VLAN的广播帧。我曾经在测试中,发现娱乐系统的VLAN广播帧居然跑到了ADAS域,导致ADAS控制器误触发了一个警告。排查下来,就是VLAN过滤没配好。

好了,数据链路层的内容就讲到这里。下一章我们聊聊网络层,IP地址和路由。到时候我会分享一个关于IP地址分配的血泪史,保证让你印象深刻。

课后思考:如果你在测试中,发现某个ECU能收到目的MAC不是自己的单播帧,可能是什么原因?提示:可以从交换机的MAC地址表、网卡的过滤模式、以及VLAN配置三个方向去排查。