第4章:Eth模块详解:以太网驱动抽象层、EthCtrl与EthTrcv配置、MII/RMII接口配置

好,咱们进入以太网协议栈里最核心的一层——Eth模块。说实话,很多工程师一上来就对着EB tresos或者Vector DaVinci的配置界面发懵,因为Eth模块下面还挂着EthCtrl和EthTrcv,再加上MII/RMII的引脚配置,确实容易搞混。

我个人习惯把Eth模块看作一个「交通指挥中心」。它不直接干活,但它知道下面谁在干活、怎么干。今天我就带你把这个指挥中心的内部结构彻底捋清楚。

4.1 以太网驱动抽象层:Eth模块的定位

Eth模块在AUTOSAR架构里属于BSW(基础软件层)的一部分,具体来说是通信栈的底层驱动抽象。它的主要职责是:

  • 向上层(比如TcpIp模块)提供统一的API接口
  • 向下管理一个或多个EthCtrl控制器实例
  • 处理中断、DMA传输、缓冲区管理等硬件相关操作

说白了,上层应用不需要知道底层用的是STM32的MAC还是NXP的MAC,Eth模块把差异全给屏蔽了。我在做第一个量产项目时,就因为没理解这层抽象,直接在应用层操作了MAC寄存器,结果换芯片平台时代码几乎重写——嗯,从那以后我再也不敢绕过Eth模块了。

4.2 EthCtrl配置:控制器的核心参数

每个Eth模块下可以挂多个EthCtrl,每个EthCtrl对应一个实际的以太网MAC控制器。配置EthCtrl时,有几个关键参数你必须搞清楚:

配置项 说明 典型值
EthCtrlIndex 控制器索引,从0开始 0, 1, 2
EthCtrlMode 工作模式:全双工/半双工 FULL_DUPLEX
EthCtrlSpeed 速率:10M/100M/1000M 100MBIT
EthCtrlRxBufferSize 接收缓冲区大小 2048字节
EthCtrlTxBufferSize 发送缓冲区大小 2048字节
注意:EthCtrlMode和EthCtrlSpeed必须与PHY芯片协商的结果一致。我曾经遇到过一个诡异的问题:EthCtrl配了100M全双工,但PHY芯片只支持100M半双工,结果网络时通时断,排查了两天才发现是这里不匹配。

另外,EthCtrl还有一个重要的配置项叫EthCtrlWakeUpCapability,用于网络唤醒功能。如果你的项目需要支持AUTOSAR的NM(网络管理)远程唤醒,这个必须配成TRUE。

4.3 EthTrcv配置:收发器的关键参数

EthTrcv对应的是PHY芯片(物理层收发器)。你想想看,MAC负责协议处理,PHY负责把数字信号变成模拟信号在网线上跑。EthTrcv的配置直接决定了物理层能不能正常工作。

配置EthTrcv时,我建议重点关注以下几点:

  • EthTrcvPhyAddress:PHY地址,通常由硬件引脚决定,常见值为0x00~0x1F
  • EthTrcvPhyId:PHY芯片的型号ID,用于驱动匹配
  • EthTrcvLinkDetection:链路检测方式,有轮询和中断两种
  • EthTrcvAutoNegotiation:是否开启自动协商,建议开启
小技巧:如果你用的是TI的DP83822或Microchip的LAN8720,记得把EthTrcvAutoNegotiation配成TRUE。但有些工业以太网场景要求固定速率和双工模式,这时候就要关掉自动协商,手动指定EthCtrlMode和EthCtrlSpeed。

我记得有一次调试,PHY芯片死活link不上。我查了硬件、查了驱动,最后发现是EthTrcvPhyAddress配错了——硬件上PHY地址是0x01,我配成了0x00。这种低级错误,嗯,犯过一次就再也不会忘了。

4.4 MII/RMII接口配置:引脚与时钟

MII(Media Independent Interface)和RMII(Reduced MII)是MAC和PHY之间的标准接口。配置这部分时,说白了就是配引脚和时钟。

4.4.1 MII接口信号

MII接口需要16根数据线(4位数据收发各4根,再加上控制信号),引脚占用较多。主要信号包括:

  • TXD[3:0]:发送数据线
  • RXD[3:0]:接收数据线
  • TX_CLK:发送时钟(25MHz for 100M,2.5MHz for 10M)
  • RX_CLK:接收时钟
  • TX_EN:发送使能
  • RX_DV:接收数据有效
  • CRS、COL:载波检测和冲突检测(半双工用)

4.4.2 RMII接口信号

RMII接口把数据线缩减到2位,总共只需要7~8根线。信号如下:

  • TXD[1:0]:发送数据线
  • RXD[1:0]:接收数据线
  • REF_CLK:50MHz参考时钟(由外部晶振或MAC提供)
  • TX_EN:发送使能
  • RX_DV:接收数据有效

为什么会有RMII?说白了就是为了省引脚。很多MCU引脚资源紧张,RMII就成了首选。但要注意,RMII要求REF_CLK必须是50MHz,而且MAC和PHY必须使用同一个时钟源。

关键配置:在EthCtrl的配置中,有一个EthCtrlInterfaceType参数,你需要根据硬件设计选择MII或RMII。同时,对应的GPIO引脚也要在Port模块中配置为复用功能。

4.5 配置实战:一个典型的EthCtrl+EthTrcv组合

假设我们用的是NXP S32K344芯片,外接TI DP83822 PHY,采用RMII接口。配置思路大致如下:

// EthCtrl配置示例(伪代码)
EthCtrl_0:
  EthCtrlIndex = 0
  EthCtrlMode = FULL_DUPLEX
  EthCtrlSpeed = 100MBIT
  EthCtrlInterfaceType = RMII
  EthCtrlRxBufferSize = 2048
  EthCtrlTxBufferSize = 2048
  EthCtrlWakeUpCapability = FALSE

// EthTrcv配置示例
EthTrcv_0:
  EthTrcvPhyAddress = 0x01
  EthTrcvPhyId = 0x2000A231  // DP83822 ID
  EthTrcvLinkDetection = INTERRUPT
  EthTrcvAutoNegotiation = TRUE
  EthTrcvSpeed = 100MBIT
  EthTrcvDuplex = FULL_DUPLEX

这里有个细节:EthTrcv的Speed和Duplex配置,在开启自动协商时其实会被PHY芯片自动协商的结果覆盖。但为什么还要配?因为有些PHY芯片在协商失败时会回退到这些默认值,所以最好配成你期望的最低保障值。

4.6 避坑指南:我踩过的几个坑

做以太网驱动配置这些年,我总结了几条血泪教训:

  • 时钟源必须一致:RMII的REF_CLK必须由同一个时钟源提供,否则MAC和PHY的时钟不同步,数据会错位。我曾经用示波器量过,两个时钟差了几个纳秒,结果丢包率高达30%。
  • PHY地址别冲突:如果板子上有多个PHY芯片,每个的地址必须唯一。我见过一个项目,两个PHY都配了0x00,结果只有一个能工作。
  • 中断引脚要配对:EthTrcvLinkDetection如果用中断模式,中断引脚必须连接到MCU的GPIO,并且在Eth模块配置中正确映射。否则链路状态变化时,上层根本不知道。
  • 缓冲区大小别抠门:EthCtrlRxBufferSize建议至少配到2048字节,因为标准以太网帧最大是1518字节,加上VLAN标签和头部,2048刚好够用。配小了会丢包。

嗯,这些坑我基本都踩过一遍。你想想看,如果能在配置阶段就避开这些问题,调试时间至少能省一半。

4.7 小结

Eth模块的配置,说白了就是三件事:配好EthCtrl的MAC参数、配好EthTrcv的PHY参数、配好MII/RMII的引脚和时钟。这三者缺一不可,任何一个环节出问题,以太网都跑不起来。

下一章我会讲Eth模块的运行时行为,包括发送接收流程、中断处理、以及如何调试。到时候咱们再细聊。