ZYNQ|LWIP协议栈之DDR学习(5)

本文详细描述了在ZYNQ-7000开发中如何使用DDR内存,包括内存空间划分、地址确定以及数据发送过程中遇到的调试问题,如网络数据格式、数据量限制和分包发送的稳定性。作者探讨了可能影响数据传输的因素,如UDP协议限制和潜在的协议选择影响。
摘要由CSDN通过智能技术生成

最终要发送的是DDR内存中的大量数据

一、DDR内存的使用

1、DDR内存空间在哪里?有多大?

首先看了一下DDR内存的使用,根据这篇博客【ZYNQ-7000开发之六】使用PS控制DDR3的读写_xil_in32读取ddr数据-CSDN博客

 我确认了DDR内存的起止地址:(这代表整个DDR的,但是这些内存里面有一部分是程序空间,有一部分才是我可以使用的内存)

在头文件"xparameters_ps.h"里面,关于DDR的宏定义如下:

在头文件 "xparameters.h"里面,关于DDR的定义是:

 在文件 "lscript.ld "当中,又有这一段,好像意思是程序空间是这么大:

 测试一下:

 把开始地址换成这两个的时候都能够正确接收

第一行那个肯定没问题,理论上从那个开始就已经不是程序空间了

第二个那个我猜测是虽然他被划分到程序空间,但是我实际的程序没有占用到这么多字节,所以暂时是空白的?

#define DDR_BASEARDDR      XPAR_DDR_MEM_BASEADDR + 0x3FF00000
#define DDR_BASEARDDR      XPAR_DDR_MEM_BASEADDR + 0x10000000

换成这个的时候就错了,他不回答我了,这个地址确实就是程序的开始地址

#define DDR_BASEARDDR      XPAR_DDR_MEM_BASEADDR + 0x00100000

总结:已知从0x100000开始是程序空间。如果只凭软件已经划分好了的部分,则可以使用的内存空间只有从0x3FF0 0000到0x3FFF FFFF这么多。

2、使用方法

DDR的使用和正常内存模块是一样的。

首先定义他的开始地址:(后面的数可以改变)

//设置DDR内存的开始地址
#define DDR_BASEARDDR      XPAR_DDR_MEM_BASEADDR + 0x3FF00000

 对DDR内存中具体位置的读写可以用下面的函数

//从某个地址读数据
u8 Xil_In8(INTPTR Addr);
u16 Xil_In16(INTPTR Addr);
u32 Xil_In32(INTPTR Addr);

//向某个地址写数据。
void Xil_Out8(INTPTR Addr, u8 Value);
void Xil_Out16(INTPTR Addr, u16 Value);
void Xil_Out32(INTPTR Addr, u32 Value);

 (1)写数据:我把可用的部分都填满,用数字0-9的循环

/* initialize data buffer being sent with same as used in iperf
 * 设置发送缓冲区的数据*/
for(i=0; i<0x100000; i++)
{
    Xil_Out8(DDR_BASEARDDR+i,i%10);
}

 (2)读数据:我把数据从DDR拿出来又放进了一个缓冲区。

for (i = 0; i < UDP_SEND_BUFSIZE; i++)
	{
		send_buf[i] = Xil_In8(DDR_BASEARDDR+j);		
	}

 或者不放在缓冲区里面也可以的 。

直接这么写:第二个参数的位置本来就是一个指针

if (count > 0)
{
	lwip_sendto(sock, DDR_BASEARDDR, UDP_SEND_BUFSIZE, 0,
			(struct sockaddr *)&from, fromlen);
}

 二、DDR数据发送的调试

感觉花了很多时间,犯了很多小错误

(1)网络调试助手的数据格式

        我先把DDR内存中的0x10000000个数据都写成了1,然后设定循环,每次发送其中的1024个数据,把DDR内存中的数据分块发送出来,就像一小包一小包传递一样。但是这样要重复发送0x40000次,非常多。

        但是,测试结果发现,发送出来的是一堆乱码。

         即使我改变数据的总量,一次发100个,发4次,也都是乱码。可惜板子的串口还有一些问题没有调通,要不然可以把这个数据打印出来看一下对不对。正当我怀疑,到底有没有正确地操作DDR内存空间的时候,我发现没有更改数据格式!要在发送之前就点击更改,中途有一次发完了我点了一下发现没用。

服了,搞了半天这个软件没有调整到HEX模式!

(2)数据量的问题

        一开始我写数据的时候,没有把整个0x100000个内存都写满,而是少写了两个0,也就是我只给内存中前面的4096个数据赋了值。我还为此测试了很多次,都是在4096个之后乱码。

把这个问题改正之后,数据不再出现乱码

但是,我开始更改数据包的大小,把它改成了0xFFFFF,数据很大的时候发现就没有回答了。

又是一阵酣畅淋漓的测试,最后发现测到65500的时候都有回答,但是65530的时候就没有了。

然后才开始怀疑是不是UDP数据包的大小是有限制的。

一查果然如下图:

UDP协议一次发送的最大数据量分析_udp传输速率-CSDN博客

我试了一下,当设置为65507的时候还是可以收到的,设置到65508就收不到了。

算是又学到了一个之前没有注意的知识点。

(3)数据分包发送的问题

实际要发送的数据是很多的,所以要分开发送,所以我还是采用的之前的循环方式。

当一个包的大小是65500的时候,我设定循环发送10次,只发了7次;设置16次,发了10次

在设定了16次的条件下不改变其他的地方,只是重新下载发送一次,发送的数据量也不同

有时候是11次,有时候是9次;

改变数据包的大小为1440,测试发送20次的时候没问题,但是设置为728次,中间就会丢失很多多次;

用指针的方法测试也是一样,次数少没有问题,次数一多就会丢失很多数据。

问题:

  1. 是因为UDP协议发送的时候会丢包?
  2. 数据量太大?
  3. 网络调试助手有问题?
  4. 如果用DMA方式传输会有这个问题吗?
  5. 如果用TCP协议传输会有这个问题吗?
  6. 如果用上位机软件会有这个问题吗?
  • 12
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Zynq是一种嵌入式处理器,具备高度可编程的特性。要实现TCP协议栈,需要在Zynq的硬件平台上设计和实现一套完整的网络协议堆栈。 首先,需要使用硬件描述语言(HDL)或者可编程逻辑门阵列(FPGA)设计和实现以太网控制器的硬件。这个以太网控制器负责物理层和数据链路层的操作,包括帧的发送和接收,MAC地址的解析,以及硬件的初始化和配置。 其次,需要在Zynq的处理器系统上运行一套网络协议栈的软件。这个软件可以使用开源的网络协议栈库,比如lwIP(lightweight IP)等。lwIP是一个轻量级的TCP/IP协议栈,适用于嵌入式系统。通过在软件层面实现网络协议栈,可以实现IP层、传输层和应用层的功能,包括IP数据包的路由、TCP连接管理、数据传输等。 通过在硬件和软件层面的协同工作,可以在Zynq平台上实现TCP协议栈。具体的实现过程包括:配置和初始化硬件以太网控制器,然后通过软件加载网络协议栈库,并进行必要的配置和初始化。接下来,可以通过对网络协议栈的API和接口进行编程,实现具体的应用逻辑和功能,如网络通信、数据传输、网络协议的处理等。 Zynq实现TCP协议栈的优势在于,它的硬件和软件资源可以高度定制和配置,可以根据具体的应用需求进行优化和扩展。同时,Zynq平台的可编程性使得实现和调试网络协议栈更加灵活和方便。然而,在实际应用中,还需要考虑到资源消耗、性能优化、网络安全等方面的问题,以确保整个系统的稳定性和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值