最终要发送的是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次,中间就会丢失很多多次;
用指针的方法测试也是一样,次数少没有问题,次数一多就会丢失很多数据。
问题:
- 是因为UDP协议发送的时候会丢包?
- 数据量太大?
- 网络调试助手有问题?
- 如果用DMA方式传输会有这个问题吗?
- 如果用TCP协议传输会有这个问题吗?
- 如果用上位机软件会有这个问题吗?