zedboard(7)DMA lwip测试

参考米联客开发资料。

BD工程

在这里插入图片描述
AXI stream data FIFO的输入是PL端代码输入,通过DMA传入PS端DDR,然后网口将数据发送到PC。

采用TCP协议,网口的配置是client,所以PC要配置成server。

下面两步要设置,才能成功连接。
在这里插入图片描述
网络调试助手先打开,或者后打开,都行。
在这里插入图片描述

结果:
  连接成功后的返回函数中会打印连接成功的信息。
在这里插入图片描述

在这里插入图片描述
在测试网口时,我们通常使用lwip echo测试工程,个人一般使用putty进行连接,截图如下:
在这里插入图片描述

在这里插入图片描述

部分代码,留以后参考:

#include "dma_intr.h"
#include "timer_intr.h"
#include "sys_intr.h"
#include "xgpio.h"

#include "lwip/err.h"
#include "lwip/tcp.h"
#include "lwipopts.h"
#include "netif/xadapter.h"
#include "lwipopts.h"
#include "tcp_transmission.h"

static  XScuGic Intc; //GIC
static  XScuTimer Timer;//timer
XAxiDma AxiDma;
u16 	*RxBufferPtr[2];  /* ping pong buffers*/

volatile u32 RX_success;
volatile u32 TX_success;

volatile u32 RX_ready=1;
volatile u32 TX_ready=1;

#define TIMER_LOAD_VALUE    XPAR_CPU_CORTEXA9_0_CPU_CLK_FREQ_HZ / 8 //0.25S

static XGpio Gpio;

#define AXI_GPIO_DEV_ID	        XPAR_AXI_GPIO_0_DEVICE_ID

int init_intr_sys(void)
{
	DMA_Intr_Init(&AxiDma,0);//initial interrupt system
	Timer_init(&Timer,TIMER_LOAD_VALUE,0);
	Init_Intr_System(&Intc); // initial DMA interrupt system
	Setup_Intr_Exception(&Intc);
	DMA_Setup_Intr_System(&Intc,&AxiDma,0,RX_INTR_ID);//setup dma interrpt system
	Timer_Setup_Intr_System(&Intc,&Timer,TIMER_IRPT_INTR);
	DMA_Intr_Enable(&Intc,&AxiDma);

}

int main(void)
{

	int Status;
	struct netif *netif, server_netif;
	ip_addr_t ipaddr, netmask, gw;
	err_t err;

	/* the mac address of the board. this should be unique per board */
	unsigned char mac_ethernet_address[] = { 0x00, 0x0a, 0x35, 0x00, 0x01, 0x02 };

	/* Initialize the ping pong buffers for the data received from axidma */
	RxBufferPtr[0] = (u16 *)RX_BUFFER0_BASE;
	RxBufferPtr[1] = (u16 *)RX_BUFFER1_BASE;

	XGpio_Initialize(&Gpio, AXI_GPIO_DEV_ID);
	XGpio_SetDataDirection(&Gpio, 1, 0);
	init_intr_sys();
	TcpTmrFlag = 0;

	netif = &server_netif;

	IP4_ADDR(&ipaddr,  192, 168,   1,  10);
	IP4_ADDR(&netmask, 255, 255, 255,  0);
	IP4_ADDR(&gw,      192, 168,   1,  10);

	/*lwip library init*/
	lwip_init();
	/* Add network interface to the netif_list, and set it as default */
	if (!xemac_add(netif, &ipaddr, &netmask, &gw, mac_ethernet_address, XPAR_XEMACPS_0_BASEADDR)) {
		xil_printf("Error adding N/W interface\r\n");
		return -1;
	}
	netif_set_default(netif);
	/* specify that the network if is up */
	netif_set_up(netif);
	/* initialize tcp pcb */
	tcp_send_init();
	XGpio_DiscreteWrite(&Gpio, 1, 1);
	Timer_start(&Timer);
	while (1)
	{
		/* call tcp timer every 250ms */
		if(TcpTmrFlag)
		{
			if(request_pcb->state == CLOSED || (request_pcb->state == SYN_SENT && request_pcb->nrtx == TCP_SYNMAXRTX))
			{
				request_pcb = tcp_new();
				if (!request_pcb) {
					xil_printf("txperf: Error creating PCB. Out of Memory\r\n");
					return -1;
				}

				//ip_set_option(request_pcb, SOF_REUSEADDR);

				err = tcp_connect(request_pcb, &ipaddress, port, tcp_connected_callback);
				if (err != ERR_OK) {
					xil_printf("txperf: tcp_connect returned error: %d\r\n", err);
					return err;
				}
			}
			tcp_tmr();
			TcpTmrFlag = 0;
		}
		/*receive input packet from emac*/
		xemacif_input(netif);//将 MAC 队列里的 packets 传输到你的 LwIP/IP stack 里
		/* if connected to the server, start receive data from PL through axidma, then transmit the data to the PC software by TCP*/
		if(tcp_client_connected)
			send_received_data();
	}
	return 0;
}
#include <stdio.h>
#include <string.h>

#include "lwip/err.h"
#include "lwip/tcp.h"
#include "lwip/init.h"
#include "lwipopts.h"
#include "netif/xadapter.h"
#include "lwipopts.h"
#include "xaxidma.h"
#include "xil_cache.h"
#include "xil_printf.h"
#include "sleep.h"
#include "tcp_transmission.h"
#include "dma_intr.h"

void send_received_data()
{
#if __arm__
	int copy = 3;
#else
	int copy = 0;
#endif
	err_t err;
	int Status;
	struct tcp_pcb *tpcb = connected_pcb;

	/*initial the first axdma transmission, only excuse once*/
	if(!first_trans_start)
	{
		Status = XAxiDma_SimpleTransfer(&AxiDma, (u32)RxBufferPtr[0],
				(u32)(PAKET_LENGTH), XAXIDMA_DEVICE_TO_DMA);
		if (Status != XST_SUCCESS)
		{
			xil_printf("axi dma failed! 0 %d\r\n", Status);
			return;
		}
		/*set the flag, so this part of code will not excuse again*/
		first_trans_start = 1;
	}

	/*if the last axidma transmission is done, the interrupt triggered, then start TCP transmission*/
	if(packet_trans_done)
	{

		if (!connected_pcb)
			return;

		/* if tcp send buffer has enough space to hold the data we want to transmit from PL, then start tcp transmission*/
		if (tcp_sndbuf(tpcb) > SEND_SIZE)
		{
			/*transmit received data through TCP*/
			Xil_DCacheInvalidateRange((u32)RxBufferPtr[packet_index & 1], SEND_SIZE);
			err = tcp_write(tpcb, RxBufferPtr[packet_index & 1], SEND_SIZE, copy);
			if (err != ERR_OK) {
				xil_printf("txperf: Error on tcp_write: %d\r\n", err);
				connected_pcb = NULL;
				return;
			}
			err = tcp_output(tpcb);
			if (err != ERR_OK) {
				xil_printf("txperf: Error on tcp_output: %d\r\n",err);
				return;
			}

			packet_index++;
			/*clear the axidma done flag*/
			packet_trans_done = 0;

			/*initial the other axidma transmission when the current transmission is done*/
			Status = XAxiDma_SimpleTransfer(&AxiDma, (u32)RxBufferPtr[(packet_index + 1)&1],
						(u32)(PAKET_LENGTH), XAXIDMA_DEVICE_TO_DMA);
			if (Status != XST_SUCCESS)
			{
				xil_printf("axi dma %d failed! %d \r\n", (packet_index + 1), Status);
				return;
			}
		}
	}
}

/*this fuction just used to count the tcp transmission times*/
static err_t
tcp_sent_callback(void *arg, struct tcp_pcb *tpcb, u16_t len)
{

	err_t err;
	tcp_trans_done = 1;
	err = tcp_output(tpcb);
	if (err != ERR_OK) {
		xil_printf("txperf: Error on tcp_output: %d\r\n",err);
		return -1;
	}

	return ERR_OK;
}

err_t
tcp_connected_callback(void *arg, struct tcp_pcb *tpcb, err_t err)
{
	xil_printf("txperf: Connected to iperf server\r\n");

	/* store state */
	connected_pcb = tpcb;

	/* set callback values & functions */
	tcp_arg(tpcb, NULL);
	tcp_sent(tpcb, tcp_sent_callback);

	/* disable nagle algorithm to ensure
	 * the last small segment of a ADC packet will be sent out immediately
	 * with no delay
	 * */
	tcp_nagle_disable(tpcb);

	if(!tcp_nagle_disabled(tpcb))
		xil_printf("tcp nagle disable failed!\r\n");

	tcp_client_connected = 1;

	/* initiate data transfer */
	return ERR_OK;
}

int tcp_send_init()
{
	err_t err;

	/* create new TCP PCB structure */
	request_pcb = tcp_new();
	if (!request_pcb) {
		xil_printf("txperf: Error creating PCB. Out of Memory\r\n");
		return -1;
	}

	/* connect to iperf tcp server */
	IP4_ADDR(&ipaddress,  192, 168, 1, 209);		/* iperf server address */

	port = 5001;					/* iperf default port */

    tcp_client_connected = 0;
    first_trans_start = 0;
    packet_trans_done = 0;
    packet_index = 0;
    tcp_trans_done = 1;
    connected_pcb = NULL;

	err = tcp_connect(request_pcb, &ipaddress, port, tcp_connected_callback);
	if (err != ERR_OK) {
		xil_printf("txperf: tcp_connect returned error: %d\r\n", err);
		return err;
	}
	return 0;
}
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值