☰
以太网通信必知:MAC与PHY及MII/RMII/GMII/RGMII接口详解
2026/10/5 10:05:13 网站建设 项目流程

搞嵌入式这些年,以太网是绕不开的一关。不管是STM32外接PHY芯片做网络通讯,还是FPGA做三速以太网,甚至Linux驱动里配置MAC,总会碰到同一串名词:MAC、PHY、MII、RMII、GMII、RGMII。我最早调网络驱动的时候,被这几个词绕晕过很久——网线插上去灯亮了,但就是ping不通;代码翻来覆去改,最后才发现是MAC和PHY之间的接口配置不对。后来自己画板子、调PHY寄存器、用抓包工具定位问题,才把这条链路彻底理顺。

这篇文章是系列的第一篇,先把基础概念讲透:MAC和PHY各自干什么、MII/RMII/GMII/RGMII有什么区别、实际项目中怎么选型。适合刚接触以太网的MCU开发者、FPGA工程师,也适合做硬件但想搞清接口定义的电路工程师。后续我会接着写PHY寄存器配置、时序约束、三速以太网实现这些更深的坑,这篇先把地基打好。

1. 先搞懂分工:MAC和PHY在以太网链路里各管什么

1.1 用快递系统理解以太网分层

很多人第一次看以太网框架图,容易被一堆模块缩写吓住。其实这事可以用快递打个比方。

你在网上下单买了个东西,商家把货交给快递公司,快递公司分拣后装车,司机开车送到你家附近,最后快递员把包裹交给你。在这个过程中,快递单号、收件人地址、签收流程属于“逻辑规则”,而货车走哪条路、发动机怎么运转、轮胎怎么抓地属于“物理实现”。

以太网也类似。MAC(Media Access Control,介质访问控制)就是快递公司负责分拣和派单的调度中心,它关注的是数据帧的格式、目标MAC地址、校验和这些逻辑规则;PHY(Physical Layer,物理层)则是那辆货车和司机,它负责把数据变成能在网线里跑的电信号,再在接收端把电信号还原成数据。

所以一条完整的以太网链路,MAC管“说什么”,PHY管“怎么把话传过去”。MAC和PHY之间需要一个接口交换数据,这就是MII家族的MII/RMII/GMII/RGMII存在的意义。你可以把它们理解成调度中心和货车之间的交接窗口——交接窗口的宽度和工作方式,决定了单位时间能传多少货。

1.2 分清了MAC和PHY,很多疑难杂症就有方向了

这个划分不是纯理论,它直接决定调试思路。我见过太多人遇到网络不通就疯狂改代码,其实问题出在物理层;也见过有人反复换网线、换变压器,结果问题出在MAC配置。

举个典型例子:网线插上后,交换机或者对端网卡的Link灯不亮,说明PHY和PHY之间没建立起物理连接,问题大概率在物理层——供电、时钟、网线、变压器、自协商这些。如果Link灯正常亮,但数据发不出去或者收不到,那就是MAC和PHY之间或者MAC上层协议栈的问题。

链路层和物理层,就是最粗粒度的二分法。后面所有排查都可以沿着这个思路走。所以别嫌基础概念啰嗦,这一刀切清楚了,排错效率直接翻倍。

2. 拆开MAC和PHY,看看各自要做的事

2.1 MAC:数据链路层的“调度中心”

MAC在以太网体系里的位置,对应OSI模型的数据链路层下半部分。它干的事主要围绕以太网帧展开。

一个标准的以太网帧长这样:

字段长度说明
前导码7字节连续0x55,用于接收端时钟同步
帧起始符SFD1字节0xD5,表示帧正式开始
目的MAC地址6字节接收方地址
源MAC地址6字节发送方地址
类型/长度2字节0x0800表示IPv4,0x0806表示ARP,也可表示长度
数据载荷46~1500字节上层协议数据
FCS帧校验4字节CRC32校验,覆盖目的MAC到载荷末尾

MAC要做的事很清晰:组装帧的时候,自动加前导码和SFD,自动计算并追加CRC;收帧的时候,检查CRC、目的MAC地址是否匹配、帧长是否合法,过滤掉坏帧和发给别人的帧。另外还要管帧间隔IFG(Inter-Frame Gap),以太网规定两帧之间至少有96 bit时间的间隔,防止收发双方节奏错乱。

半双工模式下,MAC还要实现CSMA/CD(载波侦听多路访问/冲突检测),检测到碰撞就停下来,等随机退避时间再重发。现在的网络基本全双工了,这部分在很多芯片里已经降级为兼容模式,但MAC的设计里仍然保留了相关逻辑。

除了这些,MAC还负责流控。全双工下靠PAUSE帧——当接收缓冲区快满时,发一个PAUSE帧给对方,让对方暂停发送一段时间。这个机制在MAC里是自动完成的,但很多协议栈也会留出软件控制的开关。

2.2 PHY:物理层的“信号翻译官”

PHY是离网线最近的那颗芯片,它解决的问题是:怎么把MAC发过来的一堆0和1,变成能在双绞线上稳定传输的模拟信号。

这里有几个关键点很多人第一次接触时容易懵:以太网不是直接把0和1对应的电平扔到网线上传输的。100BASE-TX用的是4B/5B编码加MLT-3电平调制;1000BASE-T更复杂,用4对线同时传,每对线上用PAM5五电平调制,一个符号能带2比特多信息。PHY芯片内部有编码器、解码器、串并转换器、时钟恢复电路、自适应均衡器等一堆模块,共同完成“数据←→信号”的双向翻译。

PC上插的百兆网卡抓包时,看到的其实是PHY解码后交给MAC的数字信号。PHY在接收路径上还有自适应均衡:网线长度不同、质量不同,信号衰减和畸变程度也不同,PHY要动态调整增益和滤波参数,把眼图“打开”,才能正确恢复数据。这个均衡过程是靠PHY内部的DSP完成的,可能很多人没意识到。

PHY还要管自协商(Auto-Negotiation)。两台设备插上网线后,PHY会在底层互相发配置脉冲,协商出双方都支持的最高速率和工作模式——10M半双工、100M全双工、1000M全双工等等。这也是为什么Link灯闪几下才稳定下来:自协商需要几百毫秒。

2.3 MDIO/MDC管理通道,MAC和PHY之间的“控制通道”

除了数据接口,MAC和PHY之间还有一条管理通道——MDIO(Management Data Input/Output)和MDC(Management Data Clock)。这条通道用于MAC读取和配置PHY的寄存器。

MDIO是串行双工接口,时序上类似I2C但更简单。一次读操作的基本格式是:32位前导1 + 2位起始码 + 2位操作码 + 5位PHY地址 + 5位寄存器地址 + 2位转换状态 + 16位数据。MDC时钟一般不超过2.5MHz(部分PHY支持更高)。

PHY的寄存器空间是标准化的,前16个寄存器基本上各家一致,比如:

  • 寄存器0(BMCR):配置自协商开关、速率、双工模式、回环等
  • 寄存器1(BMSR):读取自协商能力、Link状态、是否支持全双工等
  • 寄存器4/5(ANAR/ANLPAR):自协商通告能力和对端能力

实际调试时,能不能通过MDIO读到PHY芯片的ID寄存器,是判断MAC和PHY之间硬件连接是否正常的金标准。如果读不到,要么MDC/MDIO引脚接错,要么PHY没正常复位或供电。

3. MII家族接口逐个拆解

3.1 MII:百兆时代的标准接口

MII(Media Independent Interface,介质无关接口)是IEEE 802.3规定的标准接口,设计目标很清晰:让MAC不关心底层物理介质,通过统一接口连接各种PHY(双绞线、光纤都可以)。名字里的“介质无关”就是这个意思。

MII的数据位宽是4比特,收发各4根数据线,再加控制信号和时钟,一共16根左右。几个关键信号:

信号方向作用
TXD[3:0]MAC→PHY发送数据
TX_ENMAC→PHY发送使能
TX_CLKPHY→MAC发送时钟,100M时25MHz,10M时2.5MHz
RXD[3:0]PHY→MAC接收数据
RX_DVPHY→MAC接收数据有效
RX_CLKPHY→MAC接收时钟,100M时25MHz,10M时2.5MHz
CRSPHY→MAC载波侦听,介质忙时拉高
COLPHY→MAC冲突检测,半双工时才有意义

第一次看MII时序的人最容易犯的错:以为时钟是MAC给的。实际上MII的TX_CLK和RX_CLK都是PHY产生的。MAC在TX_CLK的上升沿把TXD数据放进总线,PHY在RX_CLK的上升沿采样RXD。

MII在100M速率下,4比特数据配合25MHz时钟,刚好达到100Mbps的吞吐。10M模式时数据宽度不变,时钟降到2.5MHz。这个设计保证了不管10M还是100M,接口逻辑是一样的,只是时钟频率变了。

3.2 RMII:省引脚的折中方案

MII用了16根线,对于引脚紧张的MCU来说太奢侈了。RMII(Reduced MII,精简MII)就是为此出现的,它把数据线从4根减到2根,去掉CRS和COL,控制信号也合并,总共只要7根左右。

RMII的巧妙之处在于:数据位宽减半,但时钟提到50MHz,所以实际速率不降。100M模式下,2比特数据配50MHz时钟,一个周期送2比特,每秒5000万个周期乘以2比特,正好100Mbps。

信号方向作用
TXD[1:0]MAC→PHY发送数据
TX_ENMAC→PHY发送使能
RXD[1:0]PHY→MAC接收数据
CRS_DVPHY→MAC载波侦听+接收数据有效合并信号
REF_CLKPHY/MAC→双方50MHz参考时钟

RMII有个大坑:REF_CLK必须同源。也就是说MAC和PHY必须用同一个50MHz时钟源,不能各用各的,否则收发时序会出现漂移导致丢包。通常做法是让PHY的50MHz时钟输出给MAC,或者由MAC输出给PHY,两边同步。

很多PHY芯片把RMII的REF_CLK配置成可由内部生成或外部输入,上电时要通过strap引脚拉对电平。我在这踩过坑:STM32F407接某款国产PHY,RMII模式一直收不到数据,排查半天发现REF_CLK配置成PHY内部输出,但STM32要求由外部时钟输入,两边时钟不同源。这个问题的排查方法后面单独讲。

3.3 GMII:千兆并行接口

进入千兆时代,MII的4比特带宽不够了。GMII(Gigabit MII)把数据位宽翻倍到8比特,时钟提升到125MHz,8×125M=1000Mbps,刚好跑满千兆。

GMII的引脚数量接近24根。注意它的时钟设计和MII有个重要区别:GMII多了个GTX_CLK,由MAC发给PHY,用于千兆模式下的发送时钟;而TX_CLK只在10M/100M模式下用,由PHY回给MAC。也就是说,同一个发送方向,千兆和百兆用的时钟引脚不同。

信号千兆模式时钟百兆/十兆模式时钟
GTX_CLKMAC→PHY,125MHz不用
TX_CLK不用PHY→MAC,25MHz/2.5MHz
RX_CLKPHY→MAC,125MHzPHY→MAC,25MHz/2.5MHz

GMII在FPGA上用得很多,芯片引脚也够用。但对很多MCU来说,24根引脚实在太多了,所以在SoC和MCU里,RGMII逐渐取代了GMII的地位。

3.4 RGMII:双沿采样,千兆接口的主流

RGMII(Reduced GMII)是现在最主流的千兆MAC-PHY接口,把GMII的8根数据线砍一半变成4根,控制信号合并成TX_CTL和RX_CTL,总共约12根引脚。它靠的是双沿采样(DDR):在125MHz时钟的上升沿和下降沿各送4比特,一个时钟周期送8比特,仍然达到1000Mbps。

信号方向作用
TXD[3:0]MAC→PHY发送数据,上升沿送低4位,下降沿送高4位
TX_CTLMAC→PHY上升沿代表TX_EN,下降沿代表TX_EN异或TX_ER
GTX_CLKMAC→PHY125MHz(千兆),25MHz/2.5MHz(百兆/十兆)
RXD[3:0]PHY→MAC接收数据,同样双沿采样
RX_CTLPHY→MAC上升沿代表RX_DV,下降沿代表RX_DV异或RX_ER
RX_CLKPHY→MAC125MHz(千兆),25MHz/2.5MHz(百兆/十兆)

RGMII最麻烦的是时序。因为数据在时钟的双沿都变化,对建立时间和保持时间要求很苛刻,PCB走线稍微长一点或者不等长,就可能采样出错。很多PHY芯片在内部集成了发送路径的延迟补偿,可以给GTX_CLK加一个大约2ns的延时,让数据在时钟中心对齐;FPGA工程里也经常在IOB里加IDELAY来调整接收采样点。

我还在调试阶段踩过RGMII的坑:一个千兆PHY默认不开启TX延时,而FPGA侧也没有配置时钟延时,结果Link正常但数据全错。后来在PHY寄存器里把TX clock delay打开,再配合FPGA的rx delay调整,数据才稳定。这个细节如果你用的PHY是RGMII,务必确认一下。

3.5 顺带认识SGMII、100BASE-T1和车载以太网

除了并行接口,还有串行接口SGMII(Serial GMII)。它用一对SerDes差分线,速率1.25Gbps,把MAC和PHY之间变成类似光纤的串行链路。SGMII的优势是引脚极少、抗干扰强、能跑更长距离,常在Intel/AMD的网卡、交换芯片、FPGA里出现。

用FPGA做SGMII时容易踩一个配置坑:SGMII IP核和PHY芯片连接时,有一方要配置成MAC模式,另一方配置成PHY模式,角色不能搞反。比如FPGA里的三速以太网IP配置为SGMII MAC模式时,外接PHY自然对应PHY模式;如果把两侧都配成MAC模式,自协商链路根本建不起来。这个细节在Xilinx和Intel的IP手册里都会强调,但刚开始接触时特别容易忽略。

车载以太网也值得提一句。像100BASE-T1,物理层改用单对双绞线加PAM3编码,传输距离能到15米级别,没有传统网口的变压器。但关键是:PHY芯片的MAC侧接口依然是标准MII/RMII/SGMII,MAC根本感知不到介质变化。这也是MII“介质无关”设计的价值所在——下层怎么折腾,上层接口不变。

4. 实际项目里怎么选:各种组合方案与接口对比

4.1 MCU内置MAC + 外接PHY,最普遍的组合

STM32F4、F7、H7系列,以及很多Cortex-A系列处理器,内部都集成了MAC,但没有PHY。你要做的就是选一颗外部PHY芯片,通过MII或RMII连上去。

这类方案的典型拓扑是:MCU内置MAC → MII/RMII → PHY芯片 → 网络变压器 → RJ45座。选择MII还是RMII,主要看引脚预算。如果MCU的GPIO紧张,RMII只需7根线,但要求50MHz时钟同源;如果引脚富裕,MII时序更宽松,而且PHY芯片可选范围更大。

功耗和成本方面,百兆项目常用国产PHY方案,比如裕太微的YT8512系列等。现在国产百兆PHY芯片已经非常成熟,基本可以替代进口型号,价格也低。选型时重点核对几项:工作电压是3.3V还是2.5V、MDIO地址是几(靠strap引脚配置)、是否支持25MHz晶振直驱还是必须外部时钟。

4.2 FPGA + PHY芯片,灵活的平台

FPGA做以太网,灵活性最高也最考验功力。你可以用FPGA内部的软核或硬核MAC,再外接PHY,接口可选GMII、RGMII、SGMII。

FPGA的引脚多,GMII也是常见选择,尤其是做三速以太网的时候。三速以太网IP核通常支持10/100/1000M自适应,接口可以配成GMII、RGMII或者SGMII。如果选RGMII,必须处理时钟延时;选GMII则更直接,不用考虑双沿采样,时序分析简单很多。

FPGA还能跳过MAC直接实现裸协议,比如用状态机做以太网收发器,控制帧的组装和解析。这种玩法通常配合GMII或者RGMII,在高速数据采集、工业控制里很常见。不过裸协议没有协议栈,TCP/IP还是要在外部CPU或者内部软核上跑。

4.3 一体化MAC+PHY芯片,什么时候用

有些芯片把MAC和PHY做进同一个封装里,比如W5500、DM9000A、CH395等。这类芯片对单片机来说非常省事:MCU只通过SPI或并行总线跟它通信,它自己承担了MAC、PHY甚至部分TCP/IP协议栈。

W5500适合对网络吞吐要求不高、又不想被协议栈折腾的场合,它硬件实现了TCP/IP,MCU只要发指令就行。DM9000A则只是MAC+PHY,不带TCP/IP,需要MCU跑协议栈,通过ISA-like并行总线访问。

有同学问过我一类问题:既然W5500这么方便,为什么还要学MAC和PHY?我的看法是,当你项目需要千兆、需要底层控制(比如时间戳、VLAN)、需要自己写驱动时,W5500那类方案就不行了。基础概念决定了你能走多远,后面的系列文章也会围绕底层展开。

4.4 接口对比速查表

接口数据位宽时钟速率引脚数典型场景
MII4bit25MHz/2.5MHz10/100Mbps16MCU百兆,时序宽松
RMII2bit50MHz10/100Mbps7MCU百兆,省引脚
GMII8bit125MHz/25MHz/2.5MHz10/100/1000Mbps24FPGA千兆,引脚充足
RGMII4bit DDR125MHz/25MHz/2.5MHz10/100/1000Mbps12MCU/FPGA千兆主流
SGMII1对差分1.25Gbps10/100/1000Mbps引脚极少交换芯片、高速SoC

综合来看,百兆项目优先RMII,千兆项目优先RGMII,FPGA引脚宽裕或追求时序简单时可以选GMII,对引脚数敏感又要求高速时考虑SGMII。

5. 实际调试经验:常见问题与排查实录

5.1 网线插上灯都不亮,先别碰代码

Link灯不亮意味着PHY没有和对端建立起物理通路。这时候先查最基础的东西:PHY供电是否正常、主时钟是否起振、复位引脚是不是一直被拉在复位状态。

依我的经验,很多PHY芯片对复位有要求,比如上电后必须拉低至少几毫秒,再释放;释放后还要等内部PLL锁定才能操作MDIO。有些人裸机代码上电立刻读PHY寄存器,读不到就想当然以为I2C时序错了,其实只是PHY还没准备好。

接下来查网线。百兆PHY只用到1、2、3、6四根线,千兆才用到全部8根。网线质量差或者只接了四根芯,Link灯闪烁或干脆不亮很正常。现在大部分PHY支持自动翻转MDI/MDIX,所以交叉线不再是必需,但有些老设备仍需注意。

变压器也是一个盲区。网口带不带内置变压器?中心抽头怎么接?部分PHY要求中心抽头接电源或者通过电阻接电源,接错会导致信号完全发不出去。自己画板时尤其要核对PHY数据手册里的参考电路。

5.2 Link灯亮但ping不通,问题在哪一层

Link亮说明PHY已经自协商成功,物理层通了。此时还ping不通,就要按“MAC—PHY接口—协议栈”顺序排查。

先读PHY寄存器。比如寄存器1的bit2是Link状态,bit5是自协商完成标志。如果自协商没完成,Link灯可能闪烁;如果寄存器读出来一切正常,说明MDIO通路没问题,PHY也活着。

然后抓数据。如果你用的是STM32,可以先做一个最简单的loopback测试:MAC发送一个帧,从PHY的loopback模式环回来,看能否收到。如果MAC收到的正是自己发的,说明MAC→PHY→MAC的路径基本畅通。如果收不到,问题很可能出在MAC和PHY的接口时序上——RGMII尤其常见。

MAC地址也不要忽略。有些PHY没有MAC地址,MAC地址由主控设置。如果MAC地址全是0或者重复,交换机可能丢弃帧,导致ping不通。

5.3 RGMII时钟延时的坑,能卡一整天

RGMII双沿采样的时序窗口很窄,PCB走线只要有一点不等长,或者PHY/MAC内部延时配置不对,就会出现“偶尔通、经常丢包”的诡异现象。这是RGMII调试里最折磨人的问题。

典型的解决思路是:先确认PHY侧是否开启了TX delay。多数RGMII PHY有这个寄存器位,通常是把GTX_CLK延迟约2ns,使数据在时钟中心稳定。FPGA侧则用IO delay调整接收路径采样点,找到眼图中间位置。

有个快速验证方法:在PHY的loopback模式下做连续收发测试,统计误码率。如果开loopback正常,接网线就不正常,那多半是物理层信号质量问题;如果loopback本来就不对,优先查接口时序。拿千兆测试时,强烈建议先强制成百兆模式,降低双沿采样带来的时序压力,定位链路是否基本可用,再切回千兆细调。

5.4 用wireshark从PC侧看数据,验证到底发没发

调试嵌入式以太网时,一个特别实用的办法是:让开发板和PC直连,在PC上开wireshark,从抓包里判断开发板发出的帧是否正确。

用wireshark看嵌入式板卡数据时,重点看几个字段:源MAC地址是不是板子配置的,目的MAC是不是PC的网卡地址,帧里的载荷内容是不是你要发的数据。这样可以确认MAC层组帧对不对,也能判断开发板到底有没有发出数据。

比如你在PC上抓到开发板发的ARP包,说明PHY发送通路是通的;如果板子IP配置成192.168.1.10,在wireshark里过滤:

# 只看特定源MAC的帧 eth.src == xx:xx:xx:xx:xx:xx # 只看ARP协议 eth.type == 0x0806 # 只看某个IP发的包 ip.src == 192.168.1.10

这种验证方式比自己一遍遍看寄存器高效得多。如果wireshark什么都抓不到,再看板子侧;如果抓到了但ping不通,问题就在更上层的IP、路由或者防火墙。

有个细节:wireshark默认抓包时会把4字节FCS帧校验剥掉,所以你看不到CRC字段。另外很多网卡驱动会丢错帧,抓包接口本身也可能会丢包,判断时要留点余地,不要因为一帧丢了就断定链路故障。

5.5 排查清单,直接抄作业

现象排查方向常用手段
Link灯不亮PHY供电、时钟、复位、网线、变压器示波器测时钟、电压表测供电、更换网线
Link灯亮但ping不通MAC-PHY接口、自协商、MAC地址、协议栈MDIO读BMSR、loopback测试、wireshark抓包
偶发丢包RGMII时钟延时、电源纹波、PCB走线调整TX/RX delay、检查电源、降低速率测试
速率协商成百兆不符合预期自协商通告、PHY strap配置读ANAR/ANLPAR寄存器、检查硬件配置
MDIO读不到PHY引脚接错、复位时序、PHY地址不对核对原理图、量复位波形、确认strap地址

写在最后

以太网这几层接口看着名词多,捋清楚后其实就是“MAC管帧、PHY管信号、中间接口管交接”。刚开始接触别求快,把每个接口的时钟方向、位宽、采样方式弄明白,比背一堆寄存器管用得多。

我个人的体会是,调试以太网最怕的就是糊里糊涂试,最好的方式是分层排查:先确认物理层通不通,再确认MAC和PHY接口正不正常,最后才去查协议栈。这篇先聊到这,后面我会接着写PHY寄存器配置的完整流程、三速以太网的FPGA实现、RMII时钟同源问题的详细排查方法,都是我实际搞过的项目里沉淀下来的东西。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询