从Wireshark抓包到FPGA调试:一次完整的以太网ARP通信实战排错记录

张开发
2026/4/16 11:26:55 15 分钟阅读

分享文章

从Wireshark抓包到FPGA调试:一次完整的以太网ARP通信实战排错记录
从Wireshark抓包到FPGA调试一次完整的以太网ARP通信实战排错记录当你在FPGA项目中实现以太网通信时最令人沮丧的莫过于硬件设计看似完美代码仿真一切正常但上板后却发现设备无法与PC建立连接。这种最后一公里的通信问题往往让开发者陷入困境——既看不到数据包的去向也找不到握手失败的根源。本文将带你经历一次真实的ARP通信排错过程展示如何通过Wireshark抓包与FPGA波形分析的双剑合璧快速定位并解决这类隐蔽的网络层问题。1. 问题复现与初步诊断上周在调试一个基于Xilinx Artix-7的以太网项目时我遇到了典型的ARP无响应问题FPGA开发板能发送ARP请求但PC端毫无反应。通过示波器观察PHY芯片的指示灯可以确认物理层链路正常问题显然出在网络协议栈的交互层面。关键排查步骤确认PC端IP配置192.168.1.100/24需与FPGA设计中的目标IP匹配检查FPGA的MAC地址设置00:11:22:33:44:55验证ARP模块的时钟频率125MHzGMII接口标准频率在Vivado中运行行为仿真时ARP状态机转换完全符合预期// 仿真片段ARP请求发送状态机 always (posedge clk) begin case(state) IDLE: if(arp_tx_en) next_state PREAMBLE; PREAMBLE: if(cnt 7) next_state ETH_HEAD; // ...其他状态转换 endcase end但上板后用Wireshark抓包却只看到FPGA发出的广播请求没有PC端的应答包。这种单向通信现象暗示可能存在以下问题目标IP地址不匹配以太网帧校验错误ARP协议字段填充错误2. Wireshark抓包深度分析打开Wireshark设置混杂模式过滤ARP流量arp过滤器捕获到的异常请求包如下No. Time Source Destination Protocol Length Info 1 0.000000 00:11:22:33:44:55 ff:ff:ff:ff:ff:ff ARP 42 Who has 192.168.1.100? Tell 192.168.1.10右键选择协议首选项-ARP/RARP勾选所有字段显示后发现两个可疑点硬件类型字段显示为0x0001以太网但协议类型却是0x0800IP操作码为1请求但目标MAC地址全零不符合ARP规范通过对比RFC 826标准正常的ARP请求包结构应为字段偏移字段名标准值实际捕获值0-1硬件类型0x00010x00012-3协议类型0x08000x08004硬件地址长度0x060x065协议地址长度0x040x046-7操作码0x0001请求0x00018-13发送端MAC开发板MAC00:11:22:33:44:5514-17发送端IP开发板IP192.168.1.1018-23目标MAC全零00:00:00:00:00:0024-27目标IPPC端IP192.168.1.100虽然大部分字段正确但目标MAC地址异常会导致部分网络设备拒绝响应。回到FPGA代码检查ARP发送模块// 问题代码片段ARP数据组装 always (posedge clk) begin if(cnt 18 cnt 24) arp_data[cnt] 8h00; // 错误目标MAC被强制清零 else if(cnt 24) arp_data[cnt] DES_IP[31:24]; // 目标IP高位 // ...其他字段赋值 end3. FPGA波形与协议栈联调在Vivado中设置ILA抓取GMII接口信号对比正常ARP请求的时序要求前导码阶段连续7个0x55 1个0xD5帧头阶段6字节目标MAC广播为全FF 6字节源MAC类型字段0x0806ARP捕获到的实际波形显示两个关键异常目标MAC地址在以太网帧头部分正确为FF-FF-FF-FF-FF-FF但在ARP数据段却变成全零帧间隔IFG只有8个时钟周期低于标准的12个周期这解释了为什么Wireshark能识别帧头但拒绝解析ARP载荷。修改后的发送状态机应确保// 修正后的ARP数据组装 always (posedge clk) begin case(state) ARP_DATA: begin if(cnt 18 cnt 24) gmii_txd des_mac[ (23-cnt)*8 : 8 ]; // 动态切片目标MAC // ...其他字段处理 end endcase end4. 系统验证与性能优化代码修正后重新综合上板测试捕获到的Wireshark报文显示完整交互流程No. Time Source Destination Protocol Length Info 1 0.000000 00:11:22:33:44:55 ff:ff:ff:ff:ff:ff ARP 60 Who has 192.168.1.100? Tell 192.168.1.10 2 0.002143 00:50:b6:12:34:56 00:11:22:33:44:55 ARP 60 192.168.1.100 is at 00:50:b6:12:34:56为进一步提升可靠性我们添加了以下增强措施CRC校验重试机制当检测到CRC错误时自动重发动态超时设置根据网络拥塞情况调整ARP缓存时间双缓冲设计避免发送过程中修改ARP表最终优化的状态机结构如下module arp_tx_fsm ( input wire clk, input wire rst_n, // ...其他接口 ); // 状态定义 typedef enum logic [2:0] { IDLE, PREAMBLE, ETH_HEADER, ARP_PAYLOAD, CRC, WAIT_ACK } state_t; // 状态寄存器 state_t current_state, next_state; always (posedge clk or negedge rst_n) begin if(!rst_n) current_state IDLE; else current_state next_state; end // 状态转移逻辑 always (*) begin case(current_state) IDLE: next_state arp_tx_en ? PREAMBLE : IDLE; PREAMBLE: next_state (cnt 7) ? ETH_HEADER : PREAMBLE; // ...其他状态转移 WAIT_ACK: next_state ack_received ? IDLE : WAIT_ACK; default: next_state IDLE; endcase end endmodule5. 高级调试技巧与工具链整合当面对更复杂的网络问题时可以组合使用以下工具Scapy脚本定制ARP包注入测试from scapy.all import * def arp_test(): pkt Ether(dstff:ff:ff:ff:ff:ff)/ARP(pdst192.168.1.100) sendp(pkt, ifaceeth0)Tcl脚本自动化批量执行Vivado仿真launch_simulation run all close_simPython数据分析解析Wireshark捕获文件import pyshark cap pyshark.FileCapture(arp.pcapng) for pkt in cap: if ARP in pkt: print(pkt.arp.src_proto_ipv4, pkt.arp.src_hw_mac)通过这次排错我深刻体会到硬件网络调试的关键在于协议分析工具与硬件信号的时空对齐。只有将Wireshark的时间戳与FPGA波形窗口同步观察才能发现那些隐藏在协议栈各层之间的微妙不一致性。

更多文章