zynq 裸核 以太网通信 Ethernet echo 代码简化版(小白福利)

zynq 裸核echo 代码简化原因

zynq实例代码中echo、tcp_client、tcp_server都非常复杂,对新手非常不友好,所以我对zynq echo代码进行了改进

zynq echo代码给了一个基于tcp协议回传代码,但是代码结构复杂,涉及好几份文件,包括小项目中不需要的tcp_fasttmr(); tcp_slowtmr();所以我将这个项目重新修改一下

以下代码只要放在hello.c或者main.c里面即可,不要其他文件,相比于zynq官方实例代码简单很多很多

作者使用是黑金的zynq7020的开发板卡

化简之后代码

#include "xparameters.h"
#include "xparameters_ps.h"	/* defines XPAR values */
#include "xil_cache.h"
#include "xscugic.h"

#include "lwip/netif.h"
#include "lwip/inet.h"
#include "lwip/err.h"
#include "lwip/tcp.h"

#define INTC_DEVICE_ID			XPAR_SCUGIC_SINGLE_DEVICE_ID
#define PLATFORM_EMAC_BASEADDR 	XPAR_XEMACPS_0_BASEADDR


static struct netif server_netif;
struct netif *echo_netif;


err_t accept_callback(void *arg, struct tcp_pcb *newpcb, err_t err);
err_t recv_callback(void *arg, struct tcp_pcb *tpcb,struct pbuf *p, err_t err);

int main()
{
	/*********************xil_exception********************************/
	//这部分代码是初始化以太网相关中断,源代码中初始化了timer中断和以太网中断
	Xil_ExceptionInit();

	XScuGic_DeviceInitialize(INTC_DEVICE_ID);

	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,
			(Xil_ExceptionHandler)XScuGic_DeviceInterruptHandler,
			(void *)INTC_DEVICE_ID);

	Xil_ExceptionEnable();

	/*********************create netif********************************/
	//这部分代码设置netif,可以将此理解为pcb的底层
	
	ip_addr_t ipaddr, netmask, gw;
	IP4_ADDR(&ipaddr,  192, 168,   1, 10);
	IP4_ADDR(&netmask, 255, 255, 255,  0);
	IP4_ADDR(&gw,      192, 168,   1,  1);

	unsigned char mac_ethernet_address[] = {0x00, 0x0a, 0x35, 0x00, 0x01, 0x02 };

	echo_netif = &server_netif;


	/* initialize lwIP */
	lwip_init();

	/* Add network interface to the netif_list, and set it as default */
	if (!xemac_add(echo_netif, &ipaddr, &netmask,&gw, mac_ethernet_address,PLATFORM_EMAC_BASEADDR))
	{
		xil_printf("Error adding N/W interface\n\r");
		return -1;
	}


	netif_set_default(echo_netif);
	netif_set_up(echo_netif);

	/*********************create pcb********************************/
	//初始化pcb
	
	struct tcp_pcb *pcb;
	err_t err;
	unsigned port = 7;

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

	/* bind to specified @port */
	err = tcp_bind(pcb, IP_ANY_TYPE, port);
	if (err != ERR_OK)
	{
		xil_printf("Unable to bind to port %d: err = %d\n\r", port, err);
		return -2;
	}

	/* we do not need any arguments to callback functions */
	tcp_arg(pcb, NULL);

	/* listen for connections */
	pcb = tcp_listen(pcb);
	if (!pcb)
	{
		xil_printf("Out of memory while tcp_listen\n\r");
		return -3;
	}

	/* specify callback to use for incoming connections */
	tcp_accept(pcb, accept_callback);


	tcp_recv(pcb, recv_callback);

	xil_printf("TCP echo server started @ port %d\n\r", port);



	/*********************死循环********************************/
	//xemacif_input函数不断运行,保证整个协议工作
	while (1)
	{
		usleep(1000);
		xemacif_input(echo_netif);
	}
    return 0;
}




/*********************client和zynq对接上之后该函数运行****************************/

err_t accept_callback(void *arg, struct tcp_pcb *newpcb, err_t err)
{
 	tcp_arg(newpcb, NULL);
	tcp_recv(newpcb, recv_callback);
 	tcp_err(newpcb, NULL);

	return ERR_OK;
}



/*********************client和zynq通信之后该函数运行****************************/

err_t recv_callback(void *arg, struct tcp_pcb *tpcb,
                               struct pbuf *p, err_t err)
{
	/* do not read the packet if we are not in ESTABLISHED state */
	if (!p) {
		tcp_close(tpcb);
		tcp_recv(tpcb, NULL);
		return ERR_OK;
	}

	/* indicate that the packet has been received */
	tcp_recved(tpcb, p->len);

	/* echo back the payload */
	/* in this case, we assume that the payload is < TCP_SND_BUF */
	if (tcp_sndbuf(tpcb) > p->len)
	{
		err = tcp_write(tpcb, p->payload, p->len, 1);
	} else
		xil_printf("no space in tcp_sndbuf\n\r");

	/* free the received pbuf */
	pbuf_free(p);

	return ERR_OK;
}
  • 1
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值