调试环境搭建:硬件平台准备与软件工具链

做 PHY 调试,环境搭不对,后面全白费。这话听起来有点,但我在项目里确实见过不少同事,拿着示波器对着眼图发愣,最后发现是驱动没装对。嗯,咱们先把这些坑填上。

硬件平台准备

你需要三样东西:一块带 PHY 芯片的开发板(或者 FPGA 板卡),一台 PC,以及连接它们的线缆。说白了,就是让信号能发出、能收回来,还能被抓到。

我个人习惯把硬件准备分成两步看:

  • PHY 芯片载体:可能是现成的评估板,也可能是你自己画的板子。建议新手先用官方评估板——我当年图省事直接上了自研板,结果焊错一颗电阻,眼图烂了两周。
  • 连接链路:确保串口、JTAG、网口都能通。不要小看这条网线,我遇到过一根交叉线导致协商失败,折腾一整个下午。

避坑指南:我曾经在一块 FPGA 开发板上调试 10G BASE-R,焊了 SMA 接头后 S参数没测,结果回损太大,寄存器读出来全是错误。所以,上电前务必检查物理层链路的完整性。

表 1 列出了常见 PHY 调试硬件及其用途:

硬件典型型号举例主要用途
PHY 评估板TI DP83822、Marvell 88E1111寄存器读写、环回测试、眼图观察
FPGA 开发板Xilinx VCU118、Altera Arria 10集成 PHY IP、SerDes 调试
PC 主机标准 x86 笔记本/台式机运行调试工具、采集日志
万用表+示波器Fluke 15B+、Keysight DSOX1204检查电源、信号质量

你想想看,如果板子供电不稳,PHY 内部 PLL 锁不住,后面所有调试都是在猜谜。所以硬件准备阶段,建议先给开发板配上独立稳压电源,别用 USB 供电——我踩过这个坑。

软件工具链

硬件就位后,软件是另一条腿。这里我重点讲两类东西:驱动和寄存器访问工具。

PHY 驱动

驱动承担着两件事:初始化 PHY 芯片、提供寄存器读写接口。常见做法是在 Linux 内核里配好 phylib 驱动,或者用裸机驱动直接操作 MDIO 总线。

表 2 总结了主流 PHY 驱动框架:

驱动类型适用场景示例文件
Linux phylib嵌入式 Linux 系统drivers/net/phy/realtek.c
U-Boot PHY 驱动Bootloader 阶段调试drivers/net/phy/phy.c
裸机 MDIO 驱动FPGA 或 MCU 裸机环境自定义 hal_phy.c

我记得有一次项目里 PHY 初始化总报 Link Down,读复位寄存器却是正常的。后来发现是 phylib 的时序配置和硬件实际延时没对齐。你如果遇到类似情况,不妨先手动写一段 MDIO 读写验证。

下面是一段通过 MDIO 读取 PHY 寄存器 0(控制寄存器)的裸机代码示例:

// 准备 MDIO 帧:前导码 + 起始 + 操作码 + PHY地址 + 寄存器地址 + 数据
uint16_t mdio_read(uint8_t phy_addr, uint8_t reg_addr) {
    uint16_t data = 0;
    // 发送读命令(操作码 0x2 = 读)
    mdio_send_frame(0xFFFFFFFF, 0x1, 0x2, phy_addr, reg_addr);
    // 读取数据(32周期后返回)
    data = mdio_shift_read(16);
    return data;
}

重点:MDIO 时序非常敏感,我建议在驱动初始化前先抓一段波形,确保时钟和数据线极性正确。否则读到的不全是 0 就是全 1,毫无意义。

寄存器访问工具

光有驱动还不够,调试时你得能快速、交互地读写寄存器。推荐以下方案:

  • mdio-tool(Linux 命令行):运行 mdio-tool eth0 phy_addr 0x0 就可以读。
  • devmem2:直接操作内存映射的 PHY 寄存器空间。
  • Bus Pirate / JTAG:硬件级读写,适合裸板。

我个人偏爱写个 Python 脚本包装一下,批量读取关键寄存器做对比。这样一次就能看出哪些寄存器值异常。

警告:千万不要在芯片还在复位时就写配置寄存器。我曾经手快,在 PHY 复位期间写进了 AN 配置,结果 AN 状态机直接跑飞,调试了两天才发现是时序窗口问题。

调试环境核心流程

整一个调试环境,说到底就是下图这个逻辑。你可以把它当作一块检查表:

PHY 调试环境搭建流程 ① 硬件连接 ② 上电检查 ③ 驱动安装 ④ 寄存器工具验证 ⑤ 链路环回测试 🔍 核查要点: 1. 驱动加载后,dmesg 是否有 PHY ID 打印? 2. mdio-tool 能否正确读出 PHY 寄存器 0(控制寄存器)?

照着这个流程走一遍,基本上调试环境就算搭稳了。后面遇到问题,你至少知道是工具链的锅还是硬件的锅,不至于摸黑。

实战检查清单

最后分享一份我自己的清单,每次换项目我都会对着做一遍:

  1. 硬件:开发板供电正常(万用表测电压),SMA/网线连接可靠,PHY 芯片可触摸到发热(常温约 40-50℃)。
  2. 驱动:Linux 下 ls /sys/bus/mdio_bus/devices/ 能看到 PHY 节点;裸机下能通过 MDIO 读出 PHY ID 寄存器(一般前两个字节是 0x2000 或 0x0141)。
  3. 工具:mdio-tool 或 devmem2 能读写至少三个关键寄存器:控制寄存器、状态寄存器、自动协商控制寄存器。
  4. 环回:配置 PHY 为内部环回模式(寄存器 0 的 bit 14=1),然后写/读数据,看是否一致。

注意:千万不要跳过环回测试就直接连远端设备。我就有一次跳过这一步,结果连上去死机,发现是 MDC 布线太长导致时钟畸变。环回能帮你把问题限定在本端。