调试环境搭建:硬件平台准备与软件工具链
做 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 状态机直接跑飞,调试了两天才发现是时序窗口问题。
调试环境核心流程
整一个调试环境,说到底就是下图这个逻辑。你可以把它当作一块检查表:
照着这个流程走一遍,基本上调试环境就算搭稳了。后面遇到问题,你至少知道是工具链的锅还是硬件的锅,不至于摸黑。
实战检查清单
最后分享一份我自己的清单,每次换项目我都会对着做一遍:
- 硬件:开发板供电正常(万用表测电压),SMA/网线连接可靠,PHY 芯片可触摸到发热(常温约 40-50℃)。
- 驱动:Linux 下
ls /sys/bus/mdio_bus/devices/能看到 PHY 节点;裸机下能通过 MDIO 读出 PHY ID 寄存器(一般前两个字节是 0x2000 或 0x0141)。 - 工具:mdio-tool 或 devmem2 能读写至少三个关键寄存器:控制寄存器、状态寄存器、自动协商控制寄存器。
- 环回:配置 PHY 为内部环回模式(寄存器 0 的 bit 14=1),然后写/读数据,看是否一致。
注意:千万不要跳过环回测试就直接连远端设备。我就有一次跳过这一步,结果连上去死机,发现是 MDC 布线太长导致时钟畸变。环回能帮你把问题限定在本端。