FPGA实现以太网,现象有些奇怪
扫描二维码
随时随地手机看文章
2022-9-23
最近某项目采用以太网通信,实践起来有些奇怪,好像设计成只能应答某类计算机的ICMP(ping)命令, 某类计算机指的是Windows特定系统,其他系统发送ping都不能正确识别。
其实不奇葩
白蔡:“吴哥,江湖救急!甲方爸爸的电路板寄过来好几天了,我一直搞不定它的以太网。”
甲方爸爸干系统集成的,要把我们两家产品打包售卖,甲方设计FPGA,我方设计嵌入式Linux,两块电路板采用以太网直连 方式通信。桌面上摆放的是双方的成熟产品,一根网线连接,简单到不能再简单了。
白蔡:“他们的产品很奇葩,FPGA的IP固定为192.168.1.6,我方的IP必须是192.168.1.7,以太网也必须千兆不协商。”
吴解两手撑着脸坐在白蔡工位:“有什么奇怪的,已发表论文都是怎么干的,FPGA--以太网--处理器,班内通信才这么搞定。没有省去路由协议,FPGA没必要设计复杂的协议栈应答模式,IP什么的仅为了填充协议栈,写死就写死,” 上挑眉毛,“说说你遇到的具体问题。”
白蔡:“奇怪的是我做如下三组实验,嵌入式Linux和FPGA好像没有应答, 当然,实验前桌面电脑和嵌入式Linux都已经设置成千兆不协商
三组对照实验如下:
-
桌面电脑ping FPGA,OK
-
桌面电脑ping 嵌入式Linux,OK
-
嵌入式Linux ping FPGA,无响应
对描述者保持怀疑
吴解:“3个步骤,你再演示一遍给我看。”怀疑白蔡没有正确描述现象。
白蔡在桌面电脑设置固定千兆速率:本地连接->属性->配置->高级->速度和双工->1.0 Gbps全双工。嵌入式也用ethtool设置固定千兆速率,重复3个步骤与所述一致。
确认网速
吴解扛来示波器,验证嵌入式Linux和FPGA通信速率是不是都真的工作在千兆模式。ethtool也不是所有网卡驱动都支持,虽然/sys/class/net/eth0/speed显示着1000,有可能显示和实际不一致。
FPGA的板子毕竟不是自己画的,不太好找。
示波器测试MAC和PHY之间的通信速率,如果是125MHz表明工作在千兆模式,结果显示均为125MHz。
检查线序
白蔡:“会不会是网线的问题呢?嵌入式Linux莫非不能同时兼容交叉线、直通线?嵌入式Linux和桌面电脑连接后,桌面电脑完成收发自动翻转,于是通信成功。”
吴解:“不能自动翻转线序的网卡我只在2010年前见过一次,负责线序翻转是网卡PHY的附加功能,目前市面上的PHY都具备。”
两人去库房借来另一块同型号的嵌入式Linux板卡,确认两块嵌入式Linux板卡所用的PHY是同型号的,毕竟近些年芯片之间的Pin to Pin替换解决方案挺多。并准备两根交叉线和直连线。
如果两块嵌入式Linux板卡接入任何一根网线都能ping通,则表明板载PHY支持自动翻转线序。实验证明与网线无关。
tcpdump抓包
吴解:“是挺邪门,光猜是猜不出来的,试试tcpdump能呈现些什么东西。”
打开tcpdump后更邪门的事情发生了,FPGA居然有回应ICMP包!不会是FPGA设计的协议栈阉割得太多了吧。
疑点1、两网卡连接后首先交互的是ARP协议,在没有完成ARP协议前不可能发送ICMP协议,既然嵌入式Linux能发送ICMP表明ARP协议已经交互完成;
疑点2、嵌入式Linux ping FPGA和桌面电脑的效果不一样,首先注意到ID值,正常情况下ID值应该与发送的一致;
吴解以前移植过ICMP协议,映像里ICMP协议实现起来很简单,ID用于表征对端回应的ICMP reply是哪一个,毕竟两机器之间间隔若干路由器,每个数据包可能选择两条不通的链路返回,后发送的ICMP reply可能比先发送的先被终端收到。
busybox源码的把ID号作为判断依据。
wireshark分析
不过奇怪的是,为什么桌面电脑ping却能正常响应呢?
吴解用tcpdump把抓包的内容保存成通用格式pcap,在自己的电脑上用wireshark打开。文件保存了两份,一份是桌面电脑与FPGA的数据,一份是嵌入式Linux与FPGA的数据。
FPGA返回给桌面电脑的ICMP replay数据里ID项是跟着request变化的,不是固定的1。
猛然间发现,request和reply的长度是不一样的,分别是98字节和74字节,点开数据区域观察到数据填充内容完全不同。FPGA返回的数据区域是“abcd”开头。
看着数据区的内容吴解预感找到现象原因了,随即用自己的桌面Linux系统ping FPGA板卡也没通。跑到白蔡的工位:“你有没有桌面电脑Ubuntu系统上测试过ping FPGA板卡?”
白蔡:“没有,现在没兴趣,emo了。”
白蔡有两台桌面电脑,一台Windows一台Ubuntu,演示时仅演示Windows系统,下意识的认为白蔡之前也在Ubuntu上测试过。
吴解:“问题找到了,甲方提供的FPGA板卡ICMP reply模仿Windows格式,Windows的request就是以abcd开头的。我猜测你如果用windows设置ping包大小,FPGA同样不会正确返回。”
白蔡来了精神,抓取Windows上的ICMP request数据,果真是“abcd”开头:“也就是说后续可以正常开发应用层协议,不必管ping吗?”
吴解:“是的。”
后来白蔡找甲方爸爸确认,他们的确是模仿Windows的reply包做的。