☰
RK3568百兆以太网RMII接口设备树DTS配置实战教程
2026/10/5 6:06:33 网站建设 项目流程

1. 先说清楚:RK3568上RMII百兆以太网到底难在哪

做嵌入式开发的朋友应该都有同感,RK3568这个芯片在国产SoC里算是非常“亲民”的了——四核A55、自带NPU、接口齐全,从工控机到边缘计算盒子都在用它。但真的拿它来做项目的时候,以太网这块往往会卡住一批人,尤其是像我这样习惯把底板一改、网口一换就开始调的人,第一次在这个芯片上碰RMII百兆接口时,还是被结结实实地上了一课。

很多人会问:RK3568不是自带千兆GMAC吗?怎么还要配RMII百兆?这里就牵扯到实际项目里的硬件成本问题。GMAC(Ethernet Media Access Controller)是芯片内部集成的一个以太网MAC控制器,RK3568的GMAC同时支持RGMII和RMII两种接口模式。RGMII是千兆常用接口,数据位宽8位,时钟跑到125MHz;而RMII只需要4根数据线,时钟50MHz,引脚少、布线简单、对PCB设计要求更低,很多百兆场景直接用RMII可以省不少功夫。更关键的是,很多便宜的PHY芯片本身就是RMII接口的,比如IP101GRI、LAN8710A这类,你没法绕开。

那为什么说“难”?因为RK3568这颗芯片的以太网控制器,它的工作模式和引脚复用都靠设备树来配置,设备树错了网口压根不起来,起来了也可能只link不传输,或者速度协商成10M。DTS节点里那几十个属性,每个都有讲究,官方SDK给的默认配置又经常是千兆RGMII的,照着板子型号一换,百兆RMII就翻车。我自己第一次配的时候,网口灯是亮了,但是ifconfig看不到eth0,折腾了整整一下午,最后发现是PHY的reset引脚没配置对。所以这篇教程就是把我自己踩过的坑和验证过的配置路径,完整地梳理出来,给后面要在这颗芯片上做百兆以太网的朋友们一个可以直接参考的模板。

这个教程适合谁?正在用RK3568做板子的人,或者SDK刚下载下来不知道从哪里下手的新手,还有那些从全志、NXP平台转过来、对瑞芯微设备树风格不熟的老手。不管你是哪种,只要跟着这篇文章把原理图和设备树对上号,配置RMII百兆网口这件事实测下来是可以稳稳拿下的。

2. 动手前的准备工作:确认硬件方案和引脚

2.1 先看原理图,别急着翻DTS

不少朋友拿到一块新板子,第一件事就是打开SDK里的dts一顿搜“gmac”“ethernet”,看到节点就改,改完编译烧录发现不行,又回头查原理图,效率太低。正确顺序是——先看原理图,把硬件方案彻底搞明白,再对着设备树改,这样每一步都有依据。

原理图需要确认的核心信息有三个:

  • PHY芯片型号和地址:PHY芯片是IP101GRI还是LAN8710A?它的SMI/MDIO地址是靠硬件上下拉配置的,常见值是0x01、0x04、0x07。这个地址后面要填进DTS里的phy-id或phy-handle相关属性,填错了PHY直接探测不到。
  • RMII接口的引脚连接:RK3568的MAC侧TX、RX数据线分别接到PHY的哪个引脚,时钟是MAC提供还是PHY提供,有没有REFO_CLK信号,方向是什么。
  • PHY的Reset引脚接到SoC的哪个GPIO:很多PHY在复位状态下MDIO是读不到的,DTS里必须把reset引脚的GPIO编号和延时配置好,让内核在初始化PHY之前先正确释放复位。

这三个信息没搞清楚,后面配置DTS就是盲人摸象。

2.2 RK3568的GMAC0/GMAC1差异

RK3568实际上有两个以太网控制器,SDK里通常叫gmac0和gmac1(或者gmac2io和gmac2mac,不同SDK版本命名稍有差异)。一般来说gmac0走的是SoC内部的MAC,gmac1走的是IO扩展出来的MAC,两者在引脚复用和节点命名上都不一样。你得先确认硬件上用的是哪个控制器,再去找对应的DTS节点。

以我手头这块板子为例,用的是gmac0,PHY接在RMII接口上。打开SDK里的rk3568-evb.dtsi或对应的板级dts文件,找到gmac0节点,先看看默认配置是什么。如果你用的是正点原子这类开发板,它们的SDK里通常已经有参考配置,但板子型号不一样,引脚定义、PHY地址可能都有差异,不能盲目照抄。

2.3 准备好编译环境和工具链

配置DTS需要重新编译内核(或者至少编译dtb),所以一套能用的编译环境是前提。建议直接用SDK自带的编译脚本,或者交叉编译工具链也要装好。我自己的习惯是先在SDK根目录跑一次./build.sh确认能完整编译通过,再改DTS,这样排查问题的时候就不用怀疑是编译环境的问题了。哦对,确认一下你用的是哪个内核版本,RK3568的SDK有Linux 4.19和Linux 5.10两套主流版本,DTS的写法会有细微差别,别拿4.19的写法直接往5.10上套,会有坑。

工具方面还有一个建议:准备一根USB转串口线(调试用)、一根网线、一台能上网的电脑。网口配置好之后测试,我一般是把开发板和电脑直连,静态IP互ping,这样不会受路由器影响,问题定位也快。

3. 保姆级实操:手把手编写RMII DTS节点

3.1 定位并打开正确的DTS文件

这一节进入核心操作。先说明一点:我把实际项目里验证过的一段完整DTS配置放在下面,但你必须结合自己的硬件进行裁剪。RK3568的DTS通常会层层包含,一般板级dts文件会#include一个SoC级dtsi,再包含一些公共的dtsi。你要改的“板级dts”(比如rk3568-myboard.dts)通常在kernel/arch/arm64/boot/dts/rockchip/目录下。

打开需要修改的DTS之后,先搜索gmac0或gmac1,看节点是否存在。有些SDK默认把status = "disabled"关掉了,你需要改成"okay",同时把phy模式、引脚复用、时钟配置全部调整成RMII百兆的模式。请注意:如果你的dtsi里已经有&gmac0引用,也可以在板级dts里用&gmac0 { ... }覆盖属性值,这是设备树的标准做法,比直接改公共dtsi更安全,也方便后续维护。

3.2 配置GMAC节点:从RGMII切到RMII

下面是一段在我板子上验证通过的gmac0节点配置(以Linux 4.19内核SDK为例),我加上了详细的注释:

&gmac0 { status = "okay"; phy-mode = "rmii"; // 核心:接口模式切到RMII百兆 clock_in_out = "input"; // 50MHz REF时钟由外部PHY提供,input方向 snps,reset-gpio = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>; // PHY复位引脚 snps,reset-active-low; // 复位电平:低有效复位 snps,reset-delays-us = <0 50000 100000>; // 复位延时:复位前0us,拉低50ms,释放后100ms assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>; assigned-clock-parents = <&cru SCLK_GMAC0_RMII_SPEED>; // 选择RMII时钟源 assigned-clock-rates = <0>, <50000000>; // 50MHz pinctrl-names = "default"; pinctrl-0 = <&gmac0_rgmii_pins>; // 等下要细说,这一行的引脚组必须切到RMII对应的组 phy-handle = <&phy0>; mdio0: mdio { compatible = "snps,dwmac-mdio"; #address-cells = <1>; #size-cells = <0>; phy0: ethernet-phy@1 { reg = <1>; // PHY的MDIO地址,以原理图实际配置为准 reset-gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>; reset-assert-us = <50000>; reset-deassert-us = <100000>; }; }; };

逐行解释几个关键属性:

  • phy-mode = "rmii":这行告诉GMAC驱动按RMII模式初始化。如果这里写成rgmii,驱动会按125MHz的时钟去跑,RMII PHY根本没法协商。
  • clock_in_out = "input":这行非常关键,表示50MHz的REF_CLK是由PHY芯片产生的,MAC侧是输入方向。另一种是"output",表示时钟由MAC提供输出给PHY。具体用哪种,看原理图里REF_CLK是从MAC吹向PHY还是从PHY吹向MAC。很多RMII PHY(比如IP101GRI)支持从XI引脚接外部50MHz晶振,把50MHz时钟再输出给MAC;也有方案是用SoC的CLKO脚直接给PHY供时钟,那DTS就要配合改成对应的时钟树。方向反了,网口100%起不来。
  • assigned-clocks和assigned-clock-parents:这两行指定CRU(Clock and Reset Unit)里GMAC0的时钟源。RMII模式下,TX/RX时钟必须是50MHz,且父时钟要选SCLK_GMAC0_RMII_SPEED。很多RMII配不好的情况就是这里没改,还停留在RGMII的125MHz时钟配置上,PHY收到的时钟频率完全不对,自然link不上。
  • snps,reset-*和phy0里的reset-*:这是两个层面的复位配置。一个在GMAC节点,一个在PHY子节点,实际效果有重叠,但建议都配上。原因是GMAC框架的复位操作和PHY驱动层的复位时机不完全一样,有的SDK版本只认其中一个。我踩过的坑就是只配了snps,reset-gpio,结果PHY probe阶段读不到PHY ID,加上reset-gpios之后才稳定。

提示:关于PHY地址reg = <1>,务必以原理图上MDIO地址为准。如果PHY地址是0,这里就写reg = <0>,写错会导致PHY探测超时,内核日志直接报no PHY found。

3.3 引脚复用:RMII和RGMII不是一套Pins

这是RMII配置最容易翻车的重灾区。RK3568的GMAC0引脚非常多,RGMII要用到TXD0~TXD3、RXD0~RXD3、TX_CLK、RX_CLK、TX_CTL、RX_CTL总共12根信号线,而RMII只需要TXD0~TXD1、RXD0~RXD1、TX_EN、RX_DV、REF_CLK这7根信号线。问题来了——RK3568在SoC内部,这些RMII信号往往复用了一部分RGMII的引脚,但设备树里如果不指定正确的pinctrl,内核可能就把引脚保持在RGMII的复用状态,实际波形完全不对。

看SDK里的SoC级dtsi(比如rk3568-pinctrl.dtsi),里面通常定义了gmac0_rgmii_pins、gmac0_miim_pins、gmac0_clkinout_pins这些引脚组。RMII模式下,你需要组合出合适的引脚组。有些SDK直接提供了gmac0_rmii_pins,有些则需要自己组合gmac0_miim_pins+gmac0_rx_bus2_pins+gmac0_tx_bus2_pins+gmac0_clkinout_pins。

以我的手头SDK为例,缺少现成的RMII引脚组,我在板级dts里自己定义了一个:

&pinctrl { gmac0_rmii_pins: gmac0-rmii-pins { mux { function = "gmac0"; groups = "gmac0_miim", // MDIO/MDC "gmac0_rx_bus2", // RXD0 RXD1 "gmac0_tx_bus2", // TXD0 TXD1 "gmac0_clkinout"; // REF_CLK }; drive { // 如果信号质量有问题,可以调整IO驱动强度 bias-disable; }; }; };

然后在&gmac0节点里把pinctrl-0指向这个自定义组:

pinctrl-names = "default"; pinctrl-0 = <&gmac0_rmii_pins>;

有的朋友可能会问,这组引脚和官方SDK里gmac0_rgmii_pins差在哪?RGMII下的引脚组会把4位TXD/RXD全部配置上,且时钟引脚按125MHz的RGMII时钟复用;RMII引脚组只配置2位数据线,时钟按50MHz方向配置。如果你偷懒没改pinctrl,就算phy-mode改成rmii,引脚复用状态还是错的,信号根本到不了PHY。这一点真的非常隐蔽,因为编译不会报错,板子也不会崩溃,就是网口link不上。

3.4 核对时钟方向的完整链路

RMII的50MHz REF_CLK,是理解整个链路的核心。很多工程师在DTS里改来改去都起不来,就是因为时钟方向没吃透。我画个逻辑图解释一下:

  • 如果clock_in_out = "input":REF_CLK由PHY输出给SoC。此时PHY必须有时钟源,要么在PHY的XI/XO引脚接25MHz晶振(PHY内部PLL倍频到50MHz输出),要么由SoC的GPIO输出50MHz给PHY。
  • 如果clock_in_out = "output":SoC的GMAC产生50MHz时钟,经REF_CLK引脚输出给PHY。

DTS里还需要配合assigned-clock-parents指定SCLK_GMAC0_RMII_SPEED。以IP101GRI为例,它支持两种时钟模式:一种是PHY自带25MHz晶振,从CLK_OUT引脚输出50MHz给MAC;另一种是MAC提供50MHz到PHY的XI引脚。实际项目里第一种最常见,因为PHY自己生成时钟,时序最简单。DTS就配成clock_in_out = "input"。

但这里有个坑:如果你用的PHY(比如某些国产PHY)不支持输出50MHz,它只能接收外部50MHz输入,那你就必须让SoC输出时钟。此时DTS要改成clock_in_out = "output",并且CRU的时钟方向和PHY的接法必须一致。否则网口状态很奇怪——有时能link上但ping不通,有时时不时掉线。

我的排查技巧:用示波器(没有示波器就用万用表频率档)测REF_CLK引脚,看有没有50MHz的方波。如果有且幅值在1.8V/2.5V/3.3V范围内正常,时钟方向基本就对了一半。测完之后再测PHY的TXD信号,ping包的时候应该有数据翻转。这种物理层的排查,比盯着内核日志猜要快得多。

3.5 完整DTS片段放在一起

上面这些配置点比较散,我把最小可用的RMII百兆DTS改法完整贴出来,方便你直接对照修改:

/ { model = "My RK3568 Board"; compatible = "rockchip,rk3568"; }; &pinctrl { gmac0_rmii_pins: gmac0-rmii-pins { mux { function = "gmac0"; groups = "gmac0_miim", "gmac0_rx_bus2", "gmac0_tx_bus2", "gmac0_clkinout"; }; }; }; &gmac0 { status = "okay"; phy-mode = "rmii"; clock_in_out = "input"; snps,reset-gpio = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>; snps,reset-active-low; snps,reset-delays-us = <0 50000 100000>; assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>; assigned-clock-parents = <&cru SCLK_GMAC0_RMII_SPEED>; assigned-clock-rates = <0>, <50000000>; pinctrl-names = "default"; pinctrl-0 = <&gmac0_rmii_pins>; phy-handle = <&phy0>; mdio0: mdio { compatible = "snps,dwmac-mdio"; #address-cells = <1>; #size-cells = <0>; phy0: ethernet-phy@1 { reg = <1>; reset-gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>; reset-assert-us = <50000>; reset-deassert-us = <100000>; }; }; };

这段配置有一个前提:硬件上PHY的MDIO地址是1,复位引脚是GPIO3_B4。你的板子不一样,需要改的就是reset-gpio、reset-gpios、reg这三处,以及引脚组里实际复用的IO。其他属性无论换什么PHY,只要走RMII,基本可以保持不变。

4. 编译、烧录与验证:你的百兆口真的通了吗

4.1 编译设备树:只需要dtb还是整个内核?

DTS改动之后,如果只是修改了板级DTS,最省事的方式是单独编译dtb,然后用fastboot或者SD卡升级dtb分区。但很多SDK的编译脚本比较一体化,./build.sh会自动构建boot.img,里面包含dtb。我自己习惯直接重编boot.img,因为这样kernel和dtb版本能对齐,减少排查变量。

以瑞芯微SDK常用的./build.sh为例:

cd <sdk根目录> source build/envsetup.sh lunch rk3568-userdebug ./build.sh -A kernel 2>&1 | tee build_kernel.log

如果只改DTS不涉及内核代码,上面的命令足够了。编译完在kernel/resource.img或kernel/boot.img目录下能看到dtb已经被打包进去。注意,瑞芯微的DTS在编译时是使用DTC(Device Tree Compiler)把所有引用解析、合并之后的,如果你的dts里引用了不存在的节点或属性,编译器会给出warning甚至error。遇到warning不要忽视,比如unused dtc node这种警告,很可能就是你在dts里写了一个没有任何地方引用的自定义节点,或者拼错了&gmac0导致整个节点不起作用。

4.2 烧录后的第一眼:日志里有什么

烧录完成后,串口启动日志是你判断成败的第一现场。用dmesg | grep -i eth或者直接看串口输出,关键信息有这些:

  • stmmaceth驱动加载成功,打印MAC地址和phy-mode。
  • MDIO总线上成功扫描到PHY,打印类似MDIO bus: probed。
  • PHY ID识别成功,比如IP101GRI会显示0x02430c54。
  • 网络接口名字出现,比如eth0: Link is Up - 100Mbps/Full - flow control rx/tx。
  • 如果卡在Waiting for PHY...或者报No PHY found,说明MDIO读写失败,优先查PHY地址、复位引脚、MDIO引脚复用。

有一个很常见的情况:日志里出现了eth0: PHY ID 0x00000000,然后反复重试。这基本就是复位时序或者MDIO上拉电阻问题。你可以先查一下硬件上MDIO和MDC引脚的上下拉是否正常(RMII模式下,MDIO通常需要4.7kΩ上拉),如果硬件没问题,再把DTS里reset-assert-us和reset-deassert-us调大,比如拉到100ms和200ms。有些PHY芯片上电后需要的时间比较长,50ms不够用。

4.3 应用层验证三步走

DTS配置没问题、PHY也识别到了,接下来用软件实测。我习惯按这个顺序验证:

  1. ifconfig -a:确认eth0存在,eth0: <NO-CARRIER>说明物理层没link;如果有RUNNING且UP字样,说明链路起来了。
  2. ethtool eth0:看Speed: 100Mb/s、Duplex: Full是不是预期值。如果显示10Mb/s或者Half,说明协商出问题了,优先怀疑时钟频率不对或者TXD/RXD接线有误。
  3. 静态IP互ping:开发板设静态IP,电脑直连,比如开发板192.168.1.10、电脑192.168.1.20,互ping丢包率应为0%。ping大包和连续ping几百次也有必要做,能暴露潜在的时钟稳定性问题。

这里要强调一点:ping通不代表时钟完全稳定。我曾经遇到一个板子,RMII模式下,ping小包(64字节)完全不丢包,但是ping大包(1400字节)掉包率极高,最后查下来是PHY和MAC之间的REF_CLK信号质量差,摆率不够,导致数据采样出错。这种问题在DTS层面可以通过调整IO驱动强度来缓解(在pinctrl里配置drive-stength)。如果硬件已经定型不能改板,可以试试把PHY侧的时钟延迟或MAC侧的rx-internal-delay-ps之类的属性加上,有时能救回来。

4.4 抓包确认数据在走

如果ping都通了,但业务层面的收发数据异常,建议直接用tcpdump或者wireshark抓包确认。开发板上使用tcpdump:

tcpdump -i eth0 -n -c 20

如果能看到ARP请求和ICMP echo请求正常发出和回收,说明MAC、PHY、DMA链路全部正常。如果只有发出的包没有收到的包,多半是RX方向数据通路问题,重点检查RXD0/RXD1引脚、RX_DV信号和PHY到MAC的时钟方向。

我遇到过一个诡异问题:TXD方向数据完全正常,能发出ARP,但收不到任何报文。用示波器量PHY的RXD引脚,发现RXD0上有信号,但RXD1始终为低,查原理图发现是PCB上RXD1走线串了0欧电阻,料没贴,虚焊导致的。这不是DTS能解的,但如果你真的按上面步骤排查,能很快把问题从软件层排除到硬件层,这就是配置验证流程的意义。

5. 实战中踩过的坑:RMII配置常见问题速查

我把实际项目中遇到过的、以及帮同事排查过的RMII问题整理成一个速查表,方便你对照排查。

现象大概率原因排查与修改方向
ifconfig看不到eth0GMAC节点的status不是okay,或者节点被某层dtsi关闭在板级dts显式加status = "okay",确认引用节点名与SDK一致
PHY不识别,日志No PHY foundPHY地址错误、MDIO引脚复用错误、复位未释放核对原理图phy地址和MDIO上下拉;DTS里phy节点的reg、reset-gpios
PHY ID读到0xffffffff复位时序太短,或MDIO没有上拉增大reset延时;硬件上MDIO加上拉电阻
link协商成10M或速度不稳定REF_CLK的50MHz没有正确产生,或时钟方向反了示波器测REF_CLK;核对clock_in_out和CRU配的时钟父源
link正常但ping不通(尤其大包)时钟信号质量差、IO驱动强度不足、差分/单端信号存在干扰调整pinctrl驱动强度;加延迟;查PCB走线和PHY匹配电阻
只有一个方向通(只能收或只能发)TX/RX数据线接反虚焊、引脚复用错位示波器逐一测量RXD/TXD引脚,对照原理图
重启后偶尔link不上reset时序不够,PHY初始化时序不满足把reset-deassert-us加大到200ms以上;检查PHY电源时序

再补充几个DTS层面容易踩的细节:

  • 不要同时使能gmac0和gmac1(如果你只用一个网口)。有些SDK默认把两个节点都开成okay,如果你用了一个gmac,另一个没有实际硬件但状态是okay,驱动初始化时会影响另一个节点,特别是MDIO总线冲突时,能导致两个网口都不工作。
  • MDIO子节点的地址位宽:#address-cells = <1>; #size-cells = <0>;这是标准写法,别漏了。漏了之后PHY子节点的reg解析会乱套。
  • reset-gpio的GPIO号要换算对:<&gpio3 RK_PB4>在RK3568的GPIO bank里,GPIO3的基地址是按组排列的。如果GPIO编号写错到另一个bank,内核不会报错,只会控制一个无关的引脚,PHY永远处于复位状态。交叉验证方法:在板子上直接量PHY的RESET引脚电平,正常配置下应该为高,如果为低,那就是复位没释放。
  • 升级内核5.10后的差异:5.10内核的设备树绑定里,phy-mode有些变更为phy-connection-type,但瑞芯微SDK大多保留了兼容。如果你用主线内核,遇到PHY模式不生效,可以搜索phy-connection-type并且同时保留phy-mode,两个都写同样值,实测是不冲突的。
  • stmmac的RX/TX delay属性:RMII模式下,rx-internal-delay-ps、tx-internal-delay-ps通常不需要配置(那是RGMII为了调整时钟相位用的)。如果你从RGMII配置模板里抄了这些属性,或者SDK默认带了,有时反而会让数据采样窗口错位,导致连接不稳定。RMII模式下建议先去掉。

6. 进阶扩展:RMII之后还能玩什么

6.1 从百兆RMII到工业实时以太网EtherCAT

如果你配RMII百兆是为了低成本工控场景,可能很快会接触EtherCAT。EtherCAT和普通以太网的最大区别在于它走的是专用的实时数据通路,对MAC和DMA的实时性要求很高。RK3568的GMAC配合EtherCAT从站方案(比如使用LAN9252这类从站控制器)时,PHY多半会用RMII接口(EtherCAT本身就是百兆全双工,RMII完全够用),DTS配置思路和这篇教程里说的完全一致。

区别点在于:EtherCAT从站模式下,网口不在Linux里作为普通网口使用,你可能要把eth0从linux网络栈里“摘掉”,交给实时以太网协议栈处理。这涉及驱动层面的改动,DTS只是保证PHY物理层正常工作。这块后续可以单独写一篇,但你先确保RMII百兆普通收发是通的,再往上叠加EtherCAT才谈得上。

6.2 换一颗PHY芯片,DTS怎么跟

网络热词里那条“rk3568如何合入yt6801”其实就是这个问题的典型。YT6801是国产PHY芯片(裕太微电子),支持RMII。如果你板子上用的是国产PHY,DTS配置还是那套路数:phy-mode = "rmii"、phy地址、reset腳位、MDIO总线属性。不同的PHY可能对CLK方向要求不同,所以最关键仍然是看原理图确认时钟是input还是output。

换PHY芯片时,除了DTS,还要注意内核的PHY驱动是否支持这颗芯片。好在绝大多数RMII百兆PHY都兼容通用的ethernet-phy-id-*或compatible = "ethernet-phy-ieee802.3-c22",内核可以按通用方式枚举。如果内核不识别具体型号,也可以强制指定PHY ID,例如:

ethernet-phy@1 { reg = <1>; compatible = "ethernet-phy-id0243.0c54"; // IP101GRI的PHY ID };

这样的话,内核会跳过auto-probe,直接按指定ID加载驱动。这个方法在你用一颗很新、内核PDB里没有收录的PHY时非常有用。

6.3 双网口:一个千兆RGMII + 一个百兆RMII

如果项目需要双网口,RK3568就很舒服了——一个GMAC走RGMII千兆,另一个GMAC走RMII百兆。两个节点独立设置,互不干扰。需要注意的点是MDIO总线的分配:有些设计会让两个PHY共用一条MDIO总线,这时两个gmac的mdio子节点会引用同一组MDIO引脚,DTS里要防止两个节点各自初始化MDIO导致冲突。常见做法是主网口初始化MDIO,从网口通过phy-handle直接引用主网口MDIO总线下的PHY节点,或者干脆用一个MDIO节点统一管理所有PHY。

RK3568在双网口场景下还有一个特殊的坑:两个gmac的引脚复用非常容易冲突,尤其是RMII和RGMII都要用到某些通用GPIO口时。建议还是先把原理图吃透,在pinctrl里精确控制每个引脚的function,不要依赖SDK里的默认引脚配置。

6.4 百兆口的性能预期

最后说一句实话:RMII百兆网口的理论瓶颈是100Mbps,实际测试吞吐大概在90~95Mbps左右,这受限于RMII接口本身4位数据线的带宽和SoC的DMA效率。如果你要跑iperf测试,用iperf3 -s(板子端)和iperf3 -c 192.168.1.10(电脑端),数值能到90Mbps以上就算正常。如果只有50Mbps甚至更低,就要查是不是CPU被中断打满了,或者DMA的burst没配置好。

最后分享一点真实体会

这篇文章里所有的DTS配置思路,都是我在不同板子上反复验证过的。RK3568的RMII配置说难也难,说简单也简单,核心就是三件事:时钟方向、引脚复用、PHY复位。只要这三件事都在设备树里表达对了,网口基本一次就能跑起来。我见过很多人卡在网口起不来,十个里有八个是时钟方向搞反了,剩下的就是GPIO复位没配对。所以如果你第一次配不成功,不用怀疑自己没天赋,按照上面的顺序一步步排查,一定能揪出问题。

另外提醒一句,设备树这个东西,不同SDK版本的差异真的非常大——同样是RK3568,Linux 4.19和Linux 5.10的时钟命名、引脚组定义都可能不一样。抄配置的时候,宁可多花十分钟在dtsi里搜索确认一下,也不要盲目复制。最后再分享一个小操作:配置完成后,把dmesg | grep stmmac的输出和ethtool eth0的结果保存下来,跟这篇教程里的正常输出做对比,你会发现排查问题快得多。

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

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

立即咨询