1. 问题现象与初步排查
最近在使用正点原子RV1126开发板进行嵌入式开发时,遇到了一个棘手的网络连接问题。当我使用自己从SDK编译的内核镜像时,发现开发板与电脑之间的PING操作要么响应时间异常长(有时达到几百毫秒),要么干脆就无法连通。但奇怪的是,使用开发板出厂预装的demo镜像时,网络连接却完全正常。
这个现象立刻引起了我的注意,因为:
- 硬件完全相同,排除物理连接问题
- 只有自定义编译的内核出现异常
- 网络基础功能(如链路检测)正常,但通信质量差
通过ifconfig命令查看,网卡eth0能够正常获取IP地址,链路状态也显示为UP。这初步排除了驱动未加载或IP配置错误等基础问题。
提示:当遇到网络不通时,建议按以下顺序排查:
- 物理连接状态(网线、指示灯)
- 网卡驱动是否加载(lsmod | grep eth)
- IP地址配置(ifconfig)
- 路由表(route -n)
- 防火墙规则(iptables -L)
2. 网络协商问题深度分析
使用ethtool工具查看网卡详细参数时,发现了关键线索:
bash复制ethtool eth0
输出显示网卡工作在100Mbps全双工模式,但"Auto-negotiation"(自动协商)状态为on。尝试强制修改协商参数:
bash复制ethtool -s eth0 speed 100 duplex full autoneg off
执行后,PING测试立即恢复正常。这表明问题确实出在网卡的自协商机制上。
为什么自动协商会导致问题?
在RGMII(Reduced Gigabit Media Independent Interface)接口规范中:
- 时钟和数据信号的同步对时序要求极为严格
- 自动协商过程中,PHY芯片和MAC控制器需要反复调整参数
- 自定义内核可能缺少某些厂商特定的时序调优参数
3. 设备树配置关键修改
深入分析设备树源文件,发现原始配置存在优化空间。以下是关键修改部分:
dts复制&gmac {
phy-mode = "rgmii-id"; // 修改前为"rgmii"
clock_in_out = "input";
snps,reset-gpio = <&gpio3 RK_PA0 GPIO_ACTIVE_LOW>;
snps,reset-active-low;
/* Reset time is 20ms, 100ms for rtl8211f */
snps,reset-delays-us = <0 20000 100000>;
assigned-clocks = <&cru CLK_GMAC_SRC>, <&cru CLK_GMAC_TX_RX>, <&cru CLK_GMAC_ETHERNET_OUT>;
assigned-clock-parents = <&cru CLK_GMAC_SRC_M1>, <&cru RGMII_MODE_CLK>;
assigned-clock-rates = <125000000>, <0>, <25000000>;
pinctrl-names = "default";
pinctrl-0 = <&rgmiim1_miim &rgmiim1_bus2 &rgmiim1_bus4 &clkm1_out_ethernet>;
tx_delay = <0x2a>;
rx_delay = <0x1a>;
phy-handle = <&phy>;
status = "okay";
};
关键修改点解析:
-
phy-mode从"rgmii"改为"rgmii-id":- RGMII-ID表示PHY芯片内部集成延迟线
- 可避免PCB布线长度不匹配导致的时序问题
-
时序参数优化:
tx_delay和rx_delay根据实际硬件调整- 开发板设计通常需要补偿FR-4板材的信号延迟
-
复位时序配置:
- 特别针对RTL8211F PHY芯片延长复位时间
- 确保PHY芯片完全初始化完成
4. 完整解决方案实施步骤
4.1 临时解决方案(无需重新编译内核)
对于快速验证问题,可以直接在系统运行时修改网卡参数:
bash复制# 查看当前设置
ethtool eth0
# 强制设置100M全双工,关闭自协商
ethtool -s eth0 speed 100 duplex full autoneg off
# 使配置永久生效(根据发行版选择)
# 方法1:写入/etc/network/interfaces
echo "post-up /sbin/ethtool -s eth0 speed 100 duplex full autoneg off" >> /etc/network/interfaces
# 方法2:创建systemd服务单元
cat > /etc/systemd/system/fix-eth0.service <<EOF
[Unit]
Description=Fix eth0 configuration
After=network.target
[Service]
Type=oneshot
ExecStart=/sbin/ethtool -s eth0 speed 100 duplex full autoneg off
[Install]
WantedBy=multi-user.target
EOF
systemctl enable fix-eth0.service
4.2 永久解决方案(修改内核配置)
-
修改设备树源文件:
bash复制vi arch/arm64/boot/dts/rockchip/rv1126.dtsi找到gmac节点,按前文示例修改参数
-
重新编译设备树:
bash复制
make dtbs -
更新启动镜像:
bash复制cp arch/arm64/boot/dts/rockchip/rv1126.dtb /boot/ update-initramfs -u -k $(uname -r) -
重启验证:
bash复制
reboot
5. 常见问题与进阶调试
5.1 问题复现与诊断流程
当网络出现异常时,建议按以下步骤收集信息:
-
基础状态检查:
bash复制ifconfig eth0 ip link show eth0 -
物理层诊断:
bash复制
ethtool eth0 ethtool --show-ring eth0 -
数据包统计:
bash复制ethtool -S eth0 cat /proc/net/dev -
内核日志分析:
bash复制
dmesg | grep eth0 journalctl -k -f
5.2 典型错误与解决方案
| 错误现象 | 可能原因 | 解决方案 |
|---|---|---|
| PING时通时断 | 时钟不同步 | 检查clock_in_out配置 |
| 高延迟 (>10ms) | 缓冲区设置不当 | 调整tx_delay/rx_delay |
| 完全不通 | PHY未复位 | 检查reset-gpio和复位时序 |
| 速度不稳定 | 自协商异常 | 强制设置速度/双工模式 |
5.3 性能优化参数
对于需要高性能网络的应用,可以进一步调整:
bash复制# 增大环形缓冲区
ethtool -G eth0 rx 4096 tx 4096
# 启用GRO/GSO
ethtool -K eth0 gro on gso on
# 调整中断亲和性
echo 2 > /proc/irq/$(grep eth0 /proc/interrupts | awk -F: '{print $1}')/smp_affinity
6. 原理深入:RGMII接口时序分析
理解底层硬件原理对解决此类问题至关重要。RGMII接口的时序要求非常严格:
-
时钟-数据对齐:
- 发送方向:TX_CLK上升沿与数据对齐
- 接收方向:RX_CLK中心对齐数据眼图
-
典型延迟参数:
- PCB走线延迟:约180ps/inch(FR4板材)
- PHY芯片内部延迟:通常1-2ns
- 需要设备树中的delay值进行补偿
-
信号完整性考量:
- 阻抗匹配(通常50Ω)
- 避免过孔和锐角走线
- 等长布线(特别是时钟与数据线)
通过示波器测量实际信号可以帮助确定最佳delay值。在没有专业设备的情况下,可以按以下经验值调整:
- 每增加0x1的delay值 ≈ 0.5ns延迟
- 典型开发板范围:0x10-0x3f
- 先调整rx_delay,再微调tx_delay
我在实际调试中发现,RV1126开发板的最佳参数组合是tx_delay=0x2a,rx_delay=0x1a。这个配置在多种网络设备上测试都表现稳定。
