当前位置:   article > 正文

FPGA通信第二篇--UDP_fpga udp

fpga udp

FPGA通信第二篇–UDP

本文通过对以太网通信中的UDP传输协议的理论学习,针对UDP实际应用中的丢包问题,提出一种人为的重发机制完成UDP稳定可靠的传输,并通过实验进行了验证。

1 以太网简介

以太网是一种产生较早,使用相当广泛的局域网。其最初是由Xerox(施乐)公司创建并由Xerox、Intel和DEC公司联合开发的基带局域网规范,后来被电气与电子工程师协会(IEEE)所采纳作为802.3的标准。

以太网的分类有标准以太网(10Mbit/s),快速以太网(100Mbit/s)和千兆以太网(1000Mbit/s)。随着以太网技术的飞速发展,市场上也出现了万兆以太网(10Gbit/s),它扩展了IEEE802.3协议和MAC规范,使其技术支持10Gbit/s的传输速率。然而在实际应用中,标准以太网和快速以太网已经能够满足我们的日常需求,对通信速率要求较高的场合,才会用到千兆以太网。

以太网通信离不开连接端口的支持,网络数据连接的端口就是以太网接口。以太网接口类型有RJ45接口,RJ11接口(电话线接口),SC光纤接口等。其中RJ45接口是我们现在最常见的网络设备接口(如:电脑网口),我们开发板使用的就是这种接口。
RJ45接口俗称“水晶头”,专业术语为RJ45连接器,由插头(接头、水晶头)和插座(母座)组成,属于双绞线以太网接口类型。RJ45插头只能沿固定方向插入,设有一个塑料弹片与RJ45插槽卡住以防止脱落,如图1.1所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dcgpNYdq-1655470298043)(/images/UDP/1.1.jpg " ")]
以太网是目前应用最广泛的局域网通讯方式,同时也是一种协议。以太网协议定义了一系列软件和硬件标准,从而将不同的计算机设备连接在一起。我们知道串口通信单次只传输一个字节,而以太网通信是以数据包的形式传输,其单包数据量达到几十,甚至成百上千个字节。


2 UDP协议

图2.1为以太网通过UDP(UserDatagramProtocol,用户数据报协议)传输单包数据的格式,从图中可以看出,以太网的数据包就是对各层协议的逐层封装来实现数据的传输。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LgOPv3m7-1655470298045)(/images/UDP/2.1.jpg " ")]

2.1以太网MAC帧格式

以太网技术的正式标准是IEEE802.3,它规定了以太网传输数据的帧结构,我们可以把以太网MAC层理解成高速公路,我们必须遵循它的规则才能在上面通行,以太网MAC层帧格式如图2.2所示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8lKgCusg-1655470298045)(/images/UDP/2.2.jpg " ")]
以太网传输数据时按照上面的顺序从头到尾依次被发送和接收,我们下面进一步解释各个区域。

(1)前导码(Preamble):为了实现底层数据的正确阐述,物理层使用7个字节同步码(0和1交替(0x55-0x55-0x55-0x55-0x55-0x55-0x55))实现数据的同步。

(2)帧起始界定符(SFD,StartFrameDelimiter):使用1个字节的SFD(固定值为0xd5)来表示一帧的开始,即后面紧跟着传输的就是以太网的帧头。

(3)目的MAC地址:即接收端物理MAC地址,占用6个字节。MAC地址从应用上可分为单播地址、组播地址和广播地址。单播地址:第一个字节的最低位为0,比如00-00-00-11-11-11,一般用于标志唯一的设备;组播地址:第一个字节的最低位为1,比如01-00-00-11-11-11,一般用于标志同属一组的多个设备;广播地址:所有48bit全为1,即FF-FF-FF-FF-FF-FF,它用于标志同一网段中的所有设备。

(4)源MAC地址:即发送端物理MAC地址,占用6个字节。

(5)长度/类型:图2.2中的长度/类型具有两个意义,当这两个字节的值小于1536(十六进制为0x0600)时,代表该以太网中数据段的长度;如果这两个字节的值大于1536,则表示该以太网中的数据属于哪个上层协议,例如0x0800代表IP协议(网际协议)、0x0806代表ARP协议(地址解析协议)等。

(6)数据:以太网中的数据段长度最小46个字节,最大1500个字节。最大值1500称为以太网的最大传输单元(MTU,MaximumTransmissionUnit),之所以限制最大传输单元是因为在多个计算机的数据帧排队等待传输时,如果某个数据帧太大的话,那么其它数据帧等待的时间就会加长,导致体验变差,这就像一个十字路口的红绿灯,你可以让绿灯持续亮一小时,但是等红灯的人一定不愿意的。另外还要考虑网络I/O控制器缓存区资源以及网络最大的承载能力等因素,因此最大传输单元是由各种综合因素决定的。为了避免增加额外的配置,通常以太网的有效数据字段小于1500个字节。

(7)帧检验序列(FCS,FrameCheckSequence):为了确保数据的正确传输,在数据的尾部加入了4个字节的循环冗余校验码(CRC校验)来检测数据是否传输错误。CRC数据校验从以太网帧头开始即不包含前导码和帧起始界定符。通用的CRC标准有CRC-8、CRC-16、CRC-32、CRC-CCIT,其中在网络通信系统中应用最广泛的是CRC-32标准。

在这里还有一个要注意的地方就是以太网相邻两帧之间的时间间隔,即帧间隙(IFG,InterpacketGap)。帧间隙的时间就是网络设备和组件在接收一帧之后,需要短暂的时间来恢复并为接收下一帧做准备的时间,IFG的最小值是96bit time,即在媒介中发送96位原始数据所需要的时间,在不同媒介中IFG的最小值是不一样的。不管10M/100M/1000M的以太网,两帧之间最少要有96bit time,IFG的最少间隔时间计算方法如下:
(1)10Mbit/s最小时间为:96100ns=9600ns;
(2)100Mbit/s最小时间为:96
10ns=960ns;
(3)1000Mbit/s最小时间为:96*1ns=96ns。


2.2 IP协议

IP协议是TCP/IP协议簇中的核心协议,也是TCP/IP协议的载体,IP协议规定了数据传输时的基本单元和格式。从前面介绍的图43.1.3中可以看出,IP协议位于以太网MAC帧格式的数据段,IP协议内容由IP首部和数据字段组成。所有的TCP、UDP及ICMP数据都以IP数据报格式传输,IP数据包格式如图2.3所示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vMcFWRBC-1655470298046)(/images/UDP/2.3.jpg " ")]
前20个字节和紧跟其后的可选字段是IP数据报的首部,前20个字节是固定的,后面可选字段是可有可无的,首部的每一行以32位(4个字节)为单位。
(1)版本:4位IP版本号(Version),这个值设置为二进制的0100时表示IPv4,设置为0110时表示IPv6,目前使用比较多的IP协议版本号是4。
(2)首部长度:4位首部长度(IHL,InternetHeaderLength),表示IP首部一共有多少个32位(4个字节)。在没有可选字段时,IP首部长度为20个字节,因此首部长度的值为5。
(3)服务类型:8位服务类型(TOS,Typeofservice),该字段被划分成两个子字段:3位优先级字段(现在已经基本忽略掉了)和4位TOS字段,最后一位固定为0。服务类型为0时表示一般服务。
(4)总长度:16位IP数据报总长度(TotalLength),包括IP首部和IP数据部分,以字节为单位。我们利用IP首部长度和IP数据报总长度,就可以知道IP数据报中数据内容的起始位置和长度。由于该字段长16bit,所以IP数据报最长可达65535字节。尽管理论上可以传输长达65535字节的IP数据报,但实际上还要考虑网络的最大承载能力等因素。
(5)标识字段:16位标识(Identification)字段,用来标识主机发送的每一份数据报。通常每发送一份报文它的值就会加1。
(6)标志字段:3位标志(Flags)字段,第1位为保留位;第2位表示禁止分片(1表示不分片0:允许分片);第3位标识更多分片(除了数据报的最后一个分片外,其它分片都为1)。
(7)片偏移:13位片偏移(FragmentOffset),在接收方进行数据报重组时用来标识分片的顺序。
(8)生存时间:8位生存时间字段,TTL(TimeToLive)域防止丢失的数据包在无休止的传播,一般被设置为64或者128。
(9)协议:8位协议(Protocol)类型,表示此数据报所携带上层数据使用的协议类型,ICMP为1,TCP为6,UDP为17。
(10)首部校验和:16位首部校验和(HeaderChecksum),该字段只校验数据报的首部,不包含数据部分;校验IP数据报头部是否被破坏、篡改和丢失等。
(11)目的IP地址:32位目的IP地址(DestinationAddress),即接收端的IP地址,如192.168.0.3。
(12)可选字段:是数据报中的一个可变长度的可选信息,选项字段以32bit为界,不足时插入值为0的填充字节,保证IP首部始终是32bit的整数倍。
以上内容是对IP首部格式的详细阐述,还需要补充的内容是IP首部校验和的计算方法,其计算步骤如下:
1、将16位检验和字段置为0,然后将IP首部按照16位分成多个单元;
2、对各个单元采用反码加法运算(即高位溢出位会加到低位,通常的补码运算是直接丢掉溢出的高位);
3、此时仍然可能出现进位的情况,将得到的和再次分成高16位和低16位进行累加;
4、最后将得到的和的反码填入校验和字段。
例如,我们使用IP协议发送一个IP数据报总长度为50个字节(有效数据为30个字节)的数据包,发送端IP地址为192.168.1.123,接收端IP地址为192.168.1.102,则IP首部数据如图2.4下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gBuNUa1k-1655470298046)(/images/UDP/2.4.jpg " ")]
按照上述提到的IP首部校验和的方法计算IP首部校验和,即:
1、0x4500+0x0032+0x0000+0x4000+0x4011+0x0000(计算时强制置0)
+0xc0a8+0x017b+0xc0a8+0x0166=0x24974
2、0x0002+0x4974=0x4976
3、0x0000+0x4976=0x4976(此种情况并未出现进位)
4、check_sum=~0x4976(按位取反)=0xb689


2.3 UDP协议

事实上数据是可以直接封装在IP协议里而不使用TCP、UDP或者其它上层协议的。然而在网络传输中同一IP服务器需要提供各种不同的服务,各种不同的服务类型是使用端口号来区分的,例如用于浏览网页服务的80端口,用于FTP(文件传输协议)服务的21端口等。TCP和UDP都使用两个字节的端口号,理论上可以表示的范围为0~65535,足够满足各种不同的服务类型。
然后是为什么不选择传输更可靠的TCP协议,而是UDP协议呢?TCP协议与UDP协议作为传输层最常用的两种传输协议,这两种协议都是使用IP作为网络层协议进行传输。下面是TCP协议与UDP协议的区别:
(1)TCP协议面向连接,是流传输协议,通过连接发送数据,而UDP协议传输不需要连接,是数据报协议;
(2)TCP为可靠传输协议,而UDP为不可靠传输协议。即TCP协议可以保证数据的完整和有序,而UDP不能保证;
(3)UDP由于不需要连接,故传输速度比TCP快,且占用资源比TCP少;
(4)应用场合:TCP协议常用在对数据文件完整性较高的一些场景中,如文件传输等。UDP常用于对通讯速度有较高要求或者传输数据较少时,比如对速度要求较高的视频直播和传输数据较少的QQ等。
首先使用FPGA实现TCP协议是完全没有问题的,但是,FPGA发展到现在,却鲜有成功商用的RTL级的TCP协议设计,大部分以太网传输都是基于比较简单的UDP协议。TCP协议设计之初是根据软件灵活性设计的,如果使用硬件逻辑实现,工程量会十分巨大,而且功能和性能无法得到保证,因此,TCP协议设计并不适合使用硬件逻辑实现。UDP协议是一种不可靠传输,发送方只负责数据发送出去,而不管接收方是否正确的接收。在很多场合,是可以接受这种潜在的不可靠性的,例如视频实时传输显示等。
UDP数据格式如图2.5所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u8ivfNxh-1655470298047)(/images/UDP/2.5.jpg " ")]
UDP首部共8个字节,同IP首部一样,也是一行以32位(4个字节)为单位。
(1)源端口号:16位发送端端口号,用于区分不同服务的端口,端口号的范围从0到65535。
(2)目的端口号:16位接收端端口号。
(3)UDP长度:16位UDP长度,包含UDP首部长度+数据长度,单位是字节(byte)。
(4)UDP校验和:16位UDP校验和。UDP计算校验和的方法和计算IP数据报首部校验和的方法相似,但不同的是IP数据报的校验和只检验IP数据报的首部,而UDP校验和包含三个部分:UDP伪首部,UDP首部和UDP的数据部分。伪首部的数据是从IP数据报头和UDP数据报头获取的,包括源IP地址,目的IP地址,协议类型和UDP长度,其目的是让UDP两次检查数据是否已经正确到达目的地,只是单纯为了做校验用的。在大多数使用场景中接收端并不检测UDP校验和,因此这里不做过多介绍。


2.4 以太网PHY芯片

PHY在发送数据的时候,接收MAC发过来的数据(对PHY来说,没有帧的概念,都是数据而不管什么地址,数据还是CRC),把并行数据转化为串行流数据,按照物理层的编码规则把数据编码转换为模拟信号发送出去,收数据时的流程反之。PHY还提供了和对端设备连接的重要功能并通过LED灯显示出自己目前的连接状态和工作状态。当我们给网卡接入网线的时候,PHY芯片不断发出脉冲信号来检测对端是否有设备,它们通过标准的“语言”交流,互相协商并确定连接速度、双工模式、是否采用流控等。通常情况下,协商的结果是两个设备中能同时支持的最大速度和最好的双工模式。这个技术被称为AutoNegotiation,即自动协商。以太网MAC和PHY之间有一个接口,常用的接口有MII和GMII等。
(1)MII(MediumIndependentInterface):MII支持10Mbps和100Mbps的操作,数据位宽为4位,在100Mbps传输速率下,时钟频率为25Mhz。
(2)GMII(GigabitMII):GMII接口向下兼容MII接口,支持10Mbps、100Mbps和1000Mbps的操作,数据位宽为8位,在1000Mbps传输速率下,时钟频率为125Mhz。


3 UDP通信实验

3.1 硬件连接

图3.1为FPGA与以太网PHY芯片连接示意图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wf8gREzf-1655470298047)(/images/UDP/3.1.jpg " ")]
图3.1中各引脚说明如表3.1所示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iieEDgh0-1655470298048)(/images/UDP/l3.1.jpg " ")]
注:PHY外部输入时钟一般由晶振提供,当没有晶振时可由FPGA提供


3.2 程序设计

通过前面介绍的以太网相关协议和GMII接口可知,我们只需要把数据封装成以太网包的格式通过GMII接口传输数据即可。整个UDP通信工程可分为接收模块、发送模块以及CRC校验模块。

3.2.1 接收模块

以太网的接收模块较为简单,因为我们不需要对数据做IP首部校验也不需要做CRC循环冗余校验,只需要判断目的MAC地址与开发板MAC地址、目的IP地址与开发板IP地址是否一致即可。接收模块的解析顺序是:前导码+帧起始界定符→以太网帧头→IP首部→UDP首部→UDP数据(有效数据)→接收结束。GMII接口数据为8位数据,IP数据报一般以32bit为单位,为了和IP数据报格式保持一致,所以要把8位数据转成32位数据,因此接收模块实际上是完成了8位数据转32位数据的功能。
整个接收模块的状态跳转图如图3.2所示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NzZLysey-1655470298048)(/images/UDP/3.2.jpg " ")]
接收模块使用三段式状态机来解析以太网包,从上图可以比较直观的看到每个状态实现的功能以及跳转到下一个状态的条件。这里需要注意的一点是,在中间状态如前导码错误、MAC地址错误以及IP地址错误时跳转到rx_end状态而不是跳转到rx_idle转态。因为中间状态在解析到数据错误时,单包数据的接收还没有结束,如果此时跳转到rx_idle状态会误把有效数据当成前导码来解析,所以状态跳转到rx_end。


3.2.2 发送模块

以太网发送模块和接收模块比较类似,但是多了IP首部校 验和和CRC循环冗余校验的计算。CRC的校验并不是在发送模块完成,而是在CRC校验模块 (crc32_d8)里完成的。发送模块的发送顺序是前导码+帧起始界定符→以太网帧头→IP首部 →UDP首部→UDP数据(有效数据)→CRC校验。输入的有效数据为32位数据,GMII接口为8位数 据接口,因此发送模块实际上完成的是32位数据转8位数据的功能。
整个流程状态机如图3.3所示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DSZDKl5x-1655470298048)(/images/UDP/3.3.jpg " ")]
发送模块和接收模块有很多相似之处,同样使用三段式状态机来发送以太网包,从图3.3可以比较直观的看到每个状态实现的功能以及跳转到下一个状态的条件。其中发送模块以数组存储以太网的帧头、IP首部以及UDP的首部信息,在复位时完成初始化。


3.2.3 CRC校验模块

CRC校验模块是对以太网发送模块的数据(不包括前导码和帧起始界定符)做校验,把校验结果值拼在以太网帧格式的FCS字段,如果CRC校验值计算错误或 者没有的话,那么电脑网卡会直接丢弃该帧导致收不到数据(有些网卡是可以设置不做校验的)。 CRC32校验在FPGA实现的原理是LFSR(Linear Feedback Shift Register,线性反馈移位寄存 器),其思想是各个寄存器储存着上一次CRC32运算的结果,寄存器的输出即为CRC32的值。
一个 IP 数据包的 CRC32 校验是在目标 MAC Address 开始计算的,一直计算到一个包的 最后一个数据为止。以太网的 CRC32 的 verilog 的算法和多项式可以在以下网站中直接生成:CRC Generation Tool - easics;参数设置如图3.4所示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N2KPzadE-1655470298049)(/images/UDP/3.4.jpg " ")]


3.3 实验验证

3.3.1通信参数设置

首先通过千兆网线连接电脑和FPGA电路板建立物理连接,接着进入计算机的网络设置“控制面板\网络和 Internet\网络连接”,选择以太网进行网络IP设置,具体操作如图3.5所示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GJ7Z8fSd-1655470298049)(/images/UDP/3.5.jpg " ")]
在完成IP设置后还需进行开发板的 IP 地址和 MAC 地址DE 绑定;在开始界面以管理员身份运行命令提示符,如图3.6所示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R1q2xjg8-1655470298050)(/images/UDP/3.6.jpg " ")]
在弹出的对话框内输入netsh i i show in查看以太网的id地址,再输入netsh -c i i add neighbors 2 192.168.0.2 00-0a-35-01-fe-c0,完成绑定;其中“2”为以太网的id号,“192.168.0.2”为FPGA板卡的IP地址,“00-0a-35-01-fe-c0”为FPGA板卡的MAC地址。


3.3.2 UDP通信测试

通过3.3.1节完成IP设置以及ARP绑定后,将代码下载至电路板中,此时FPGA会向PC端发送“Hello,Welcome to FPGA!”,当PC端向FPGA发送数据时,发送的数据会存入FPGA内部,之后FPGA会一直发送PC端发送的数据段,结果如图3.7所示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WC2n9N1D-1655470298050)(/images/UDP/3.7.jpg " ")]
注意:以太网的数据帧的传输有包长的要求,一般在46~1500字节。所以在发送以太网数据包的时候,数据帧的长度不能太短,不然会导致PC数据包发送而FPGA收不到数据包的情况。


3.3.3 自研重发机制下的UDP通信测试

针对UDP协议通信过程中会存在丢包的问题,通过对每个包作标记建立人为的重发机制,实现UDP的稳定可靠传输。
重发机制主模块主要由FIFO模块、RAM模块、UDP通信模块三部分组成。其中FIFO模块用于存放前端数据源;RAM模块主要用于存放即将发送的UDP包的包序号和数据;UDP模块负责发送数据和接收是否重发的指令;主模块负责根据接收到的指令来判断是否更新RAM中的数据,如果不需要重发,则通过将FIFO数据写入RAM中完成数据更新,反之,就不更新,整个重发机制流程图如图3.8所示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GxhfR0gR-1655470298051)(/images/UDP/3.8.jpg " ")]
将采集到的连续累加数(累加1)进行前后作差,如图3.9所示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-amRAVwhj-1655470298051)(/images/UDP/3.9.jpg " ")]
由图可以看出,无明显丢包现象。但是,在实际测试过程,上位机出现传输不稳定现象,需要在打开第三方抓包软件的帮助下才能保持数据传输稳定。

通过对抓包软件的原理分析,在自主编写的上位机中加入基于wincap的网卡监听功能,在摆脱第三方软件的情况下也能实现数据的稳定传输。


4 结论

目前,针对UDP丢包问题提出的重发机制方案可实现4MB/s的稳定可靠传输。后续可以在传输速率的提高方面深入研究或者直接采用FPGA软核的方式实现TCP通信的开发。


参考

[1] 关于UDP千兆以太网发送程序丢包的分析探讨

[2] 以太网教程调试说明以及上位机无法接收UDP报文原因分析

由于是直接拷贝我的个人博客的原文,所以文中图片连接存在问题,时间问题后续会进行修改,感兴趣的可以直接去我的个人博客
  • 1

[3] 个人博客地址


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/536181
推荐阅读
相关标签
  

闽ICP备14008679号