zcu106 lwip搭建以太网配置寄存器

news2024/11/26 22:50:25

文章目录

        • 实验一
          • 1.配置网口GEM3
          • 2.导出xsa文件,在vitis中创建工程,选择freertos10_xilinx的操作系统来使用
          • 3.配置lwip211,选择SOCKET API的模式
          • 4.创建工程 选择FreeRTOS Iwip TCP Perf Server模板
          • 5.代码分析
            • main.c
            • freertos_tcp_perf_server.c
            • freertos_tcp_perf_server.h
          • 6.流程梳理
          • 7.网络测试
        • 实验二
          • 1.配置block design
          • 2.配置conf_list核,存放在lwip_tcp.ipdef/conf_reg_list下面
          • 3.vitis开发
            • conf_list.h
            • conf_list.c
            • freertos_tcp_perf_server.c
          • 4.实验结果

实验一

1.配置网口GEM3

image-20221130154415671

2.导出xsa文件,在vitis中创建工程,选择freertos10_xilinx的操作系统来使用

image-20221130190131167

3.配置lwip211,选择SOCKET API的模式

image-20221130161930948

4.创建工程 选择FreeRTOS Iwip TCP Perf Server模板

image-20221130163247489

5.代码分析
main.c

配置服务器端的ip地址 掩码 网关

#define DEFAULT_IP_ADDRESS "192.168.137.11"  //IP
#define DEFAULT_IP_MASK "255.255.255.0"    //掩码
#define DEFAULT_GW_ADDRESS "192.168.1.1"   //网关

main函数使用sys_thread_new新建了一个线程调用了main_thread,使用vTaskStartScheduler启动任务调度。

int main()
{
	main_thread_handle = sys_thread_new("main_thread", main_thread, 0,
			THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
	vTaskStartScheduler();
	while(1);
	return 0;
}

main_thread函数调用其他线程network_thread

void main_thread(void *p)
{
#if ((LWIP_IPV6==0) && (LWIP_DHCP==1))
	int mscnt = 0;
#endif

#ifdef XPS_BOARD_ZCU102
	IicPhyReset();
#endif
	/* initialize lwIP before calling sys_thread_new */
	lwip_init();   /* 初始化lwip */

	/* any thread using lwIP should be created using sys_thread_new */
	sys_thread_new("nw_thread", network_thread, NULL,
			THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
	/* 申请线程network_thread  */
	/* Suspend Task until auto-negotiation is completed */
	if (!complete_nw_thread)
		vTaskSuspend(NULL);

#if LWIP_IPV6==0
#if LWIP_DHCP==1   /* 默认不开启DHCP */
	while (1) {
		vTaskDelay(DHCP_FINE_TIMER_MSECS / portTICK_RATE_MS);
		if (server_netif.ip_addr.addr) {
			xil_printf("DHCP request success\r\n");
			break;
		}
		mscnt += DHCP_FINE_TIMER_MSECS;
		if (mscnt >= 10000) {
			xil_printf("ERROR: DHCP request timed out\r\n");
			assign_default_ip(&(server_netif.ip_addr),
						&(server_netif.netmask),
						&(server_netif.gw));
			break;
		}
	}

#else
	assign_default_ip(&(server_netif.ip_addr), &(server_netif.netmask),
				&(server_netif.gw));
#endif

	print_ip_settings(&(server_netif.ip_addr), &(server_netif.netmask),
				&(server_netif.gw));   /* 打印IP的有关信息 */
#endif /* LWIP_IPV6 */

	xil_printf("\r\n");

	/* print all application headers */
	print_app_header();  /* 打印连接的端口,打印提示*/
	xil_printf("\r\n");

	/* start the application*/
	start_application(); /* 运行应用 */

	vTaskDelete(NULL);
	return;
}

network_thread函数配置lwip网络连接

void network_thread(void *p)
{
#if ((LWIP_IPV6==0) && (LWIP_DHCP==1))
	int mscnt = 0;
#endif

	/* the mac address of the board. this should be unique per board */
	u8_t mac_ethernet_address[] = { 0x00, 0x0a, 0x35, 0x00, 0x01, 0x02 };
	/* 配置MAC地址 */

	xil_printf("\n\r\n\r");
	xil_printf("-----lwIP Socket Mode TCP Server Application------\r\n");

	/* Add network interface to the netif_list, and set it as default */
	if (!xemac_add(&server_netif, NULL, NULL, NULL, mac_ethernet_address,
		PLATFORM_EMAC_BASEADDR)) {
		xil_printf("Error adding N/W interface\r\n");
		return;
	}
	/* 将mac地址加入netif_list */

#if LWIP_IPV6==1
	server_netif.ip6_autoconfig_enabled = 1;
	netif_create_ip6_linklocal_address(&server_netif, 1);
	netif_ip6_addr_set_state(&server_netif, 0, IP6_ADDR_VALID);
	print_ipv6("\n\rlink local IPv6 address is:",&server_netif.ip6_addr[0]);
#endif /* LWIP_IPV6 */

	netif_set_default(&server_netif);

	/* specify that the network if is up */
	netif_set_up(&server_netif);   /* 设置为默认的network */

	/* start packet receive thread - required for lwIP operation */
	sys_thread_new("xemacif_input_thread",
			(void(*)(void*))xemacif_input_thread, &server_netif,
			THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);

	/* 开启packet的接受线程xemacif_input_thread */
	complete_nw_thread = 1;

	/* Resume the main thread; auto-negotiation is completed */
	vTaskResume(main_thread_handle);
	/* 恢复主线程,自动协商恢复 */

#if ((LWIP_IPV6==0) && (LWIP_DHCP==1))
	dhcp_start(&server_netif);
	while (1) {
		vTaskDelay(DHCP_FINE_TIMER_MSECS / portTICK_RATE_MS);
		dhcp_fine_tmr();
		mscnt += DHCP_FINE_TIMER_MSECS;
		if (mscnt >= DHCP_COARSE_TIMER_SECS*1000) {
			dhcp_coarse_tmr();
			mscnt = 0;
		}
	}
#else
	vTaskDelete(NULL);
#endif
}
freertos_tcp_perf_server.c

start_application函数是执行时的数据传输

void start_application(void)
{
	int sock, new_sd;
#if LWIP_IPV6==1
	struct sockaddr_in6 address, remote;
#else
	struct sockaddr_in address, remote;
#endif /* LWIP_IPV6 */
	int size;

	/* set up address to connect to */
        memset(&address, 0, sizeof(address));
#if LWIP_IPV6==1
	if ((sock = lwip_socket(AF_INET6, SOCK_STREAM, 0)) < 0) {
		xil_printf("TCP server: Error creating Socket\r\n");
		return;
	}
	address.sin6_family = AF_INET6;
	address.sin6_port = htons(TCP_CONN_PORT);
	address.sin6_len = sizeof(address);
#else
	if ((sock = lwip_socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		xil_printf("TCP server: Error creating Socket\r\n");
		return;
	}
	address.sin_family = AF_INET;
	address.sin_port = htons(TCP_CONN_PORT);
	address.sin_addr.s_addr = INADDR_ANY;
	/* 设置socket的套接字网络连接 */
#endif /* LWIP_IPV6 */

	if (bind(sock, (struct sockaddr *)&address, sizeof (address)) < 0) {
		xil_printf("TCP server: Unable to bind to port %d\r\n",
				TCP_CONN_PORT);
		close(sock);
		return;
	}
	/* bind函数 */

	if (listen(sock, 1) < 0) {
		xil_printf("TCP server: tcp_listen failed\r\n");
		close(sock);
		return;
	}
	/* listen监听函数实现 */

	size = sizeof(remote);

	while (1) {
		if ((new_sd = accept(sock, (struct sockaddr *)&remote,
						(socklen_t *)&size)) > 0)
			sys_thread_new("TCP_recv_perf thread",
				tcp_recv_perf_traffic, (void*)&new_sd,
				TCP_SERVER_THREAD_STACKSIZE,
				DEFAULT_THREAD_PRIO);
			/* accept函数接受客户端网络连接,开启一个新的线程*/
	}
}

tcp_recv_perf_traffic函数执行数据传输

/* thread spawned for each connection */
void tcp_recv_perf_traffic(void *p)
{
	char recv_buf[RECV_BUF_SIZE];
	int read_bytes;
	int sock = *((int *)p);

	server.start_time = sys_now() * portTICK_RATE_MS;
	server.client_id++;
	server.i_report.last_report_time = 0;
	server.i_report.start_time = 0;
	server.i_report.total_bytes = 0;
	server.total_bytes = 0;

	print_tcp_conn_stats(sock);  /* 打印TCP*/

	while (1) {
		/* read a max of RECV_BUF_SIZE bytes from socket */
		if ((read_bytes = lwip_recvfrom(sock, recv_buf, RECV_BUF_SIZE,
						0, NULL, NULL)) < 0) {
			u64_t now = sys_now() * portTICK_RATE_MS;
			u64_t diff_ms = now - server.start_time;
			tcp_conn_report(diff_ms, TCP_ABORTED_REMOTE);
			break;
		}
		/* lwip_recvfrom接受1500字节的数据*/

		/* break if client closed connection */
		if (read_bytes == 0) {
			u64_t now = sys_now() * portTICK_RATE_MS;
			u64_t diff_ms = now - server.start_time;
			tcp_conn_report(diff_ms, TCP_DONE_SERVER);
			xil_printf("TCP test passed Successfully\n\r");
			break;
		}
		/* 如果接受数据大小为0,说明TCP测试已经通过了 */

		if (REPORT_INTERVAL_TIME) {
			u64_t now = sys_now() * portTICK_RATE_MS;
			server.i_report.total_bytes += read_bytes;
			if (server.i_report.start_time) {
				u64_t diff_ms = now - server.i_report.start_time;

				if (diff_ms >= REPORT_INTERVAL_TIME) {
					tcp_conn_report(diff_ms, INTER_REPORT);
					server.i_report.start_time = 0;
					server.i_report.total_bytes = 0;
				}
			} else {
				server.i_report.start_time = now;
			}
		}
		/* Record total bytes for final report */
		/* 记录接受的总数据量大小 */
		server.total_bytes += read_bytes;
	}

	/* close connection */
	close(sock);
	vTaskDelete(NULL);
}
freertos_tcp_perf_server.h

服务器端使用的端口号是5001

/* server port to listen on/connect to */
#define TCP_CONN_PORT 5001
6.流程梳理
main_thread_handle
-> main_thread(lwip_init) 
	-> network_thread
	-> start_application
		->lwip_socket(bind listen accept)
			-> tcp_recv_perf_traffic
				->lwip_recvfrom
7.网络测试
ping 192.168.137.11 -t  //循环ping目标

iperf -c 192.168.137.10 -p 5001 -i 5 -t 30 -w 2M
-c 客户端连接服务器的ip
-p 服务端的端口号
-i 打印带宽的时间间隔
-t 测试带宽时间为30s
-w 使用的包窗口大小

image-20221130185725992

从图中可见,网速大小可以达到85Mbits/sec左右,大概是百兆以太网的速度大小,可以在lwip那里修改一些参数去调大它。

实验二

1.配置block design

AXI_HPM0 FPD interface 32位

image-20221130215724334

image-20221130221234812

2.配置conf_list核,存放在lwip_tcp.ipdef/conf_reg_list下面

在这里插入图片描述

conf_list_v1_0_S00_AXI.v

(
		// Users to add ports here
        output reg[31:0] hdmi_bit_sel,
        output reg[31:0] img_width,
        output reg[31:0] img_high,
		// User ports ends
		// Do not modify the ports beyond this line
// Add user logic here
    always @(posedge S_AXI_ACLK) begin
         if ( S_AXI_ARESETN == 1'b0 ) begin
            hdmi_bit_sel <= 0;
            img_width <= 0;
            img_high <= 0;
         end
         else begin
            hdmi_bit_sel <= slv_reg0;
            img_width <= slv_reg1;
            img_high <= slv_reg2;
         end
     end
	// User logic ends

conf_list_v1_0.v

// Users to add ports here
        output wire[31:0] hdmi_bit_sel,
        output wire[31:0] img_width,
        output wire[31:0] img_high,
		// User ports ends
		// Do not modify the ports beyond this line
// Instantiation of Axi Bus Interface S00_AXI
	conf_list_v1_0_S00_AXI # ( 
		.C_S_AXI_DATA_WIDTH(C_S00_AXI_DATA_WIDTH),
		.C_S_AXI_ADDR_WIDTH(C_S00_AXI_ADDR_WIDTH)
	) conf_list_v1_0_S00_AXI_inst (
	    .hdmi_bit_sel(hdmi_bit_sel),
	    .img_width(img_width),
	    .img_high(img_high),
		.S_AXI_ACLK(s00_axi_aclk),
3.vitis开发

lwip_send(int s, const void* dataptr, size_t size,int flags)

其中s是socket,dataptr是数据,size是数据大小,flag默认为0

需要判断收到的数据的前8位都是55,然后把对应地址的数据取出来放到对应的IP里面

conf_list.h
#include "Xil_io.h"

#define CONF_LIST_mWriteReg(BaseAddress, RegOffset, Data) \
Xil_Out32((BaseAddress) + (RegOffset), (u32)(Data))

#define CONF_LIST_mReadReg(BaseAddress, RegOffset) \
Xil_In32((BaseAddress) + (RegOffset))

void write_conf_list(u32 BaseAddr, u32 RegAddr, u32 Data);
u32 read_conf_list(u32 BaseAddr, u32 RegAddr);

conf_list.c
#include "conf_list.h"

void write_conf_list(u32 BaseAddr, u32 RegAddr, u32 Data)
{
	CONF_LIST_mWriteReg(BaseAddr, RegAddr<<2,Data); //RegAddr*4
}

u32 read_conf_list(u32 BaseAddr, u32 RegAddr)
{
	return CONF_LIST_mReadReg(BaseAddr, RegAddr<<2); //RegAddr*4
}

freertos_tcp_perf_server.c
#include "conf_list.h"
#include "Xil_io.h"
#define REGBASEADDR 0X00A0000000

u32 imagewidth;
u32 imagehigh;
u32 readback; //0表示写,1表示读

void tcp_recv_perf_traffic(void *p) {
    
//lwip_send(sock, recv_buf, 14, 0);
		if(recv_buf[0] == 0x55 && recv_buf[1] == 0x55 && recv_buf[2] == 0x55 && recv_buf[3] == 0x55 && recv_buf[4] == 0x55 && recv_buf[5] == 0x55 && recv_buf[6] == 0x55 && recv_buf[7] == 0x55)
		{
		    u32 regaddr;
		    u8 rwnflag;
		    u32 regdata;
		    regaddr = recv_buf[8];
		    rwnflag = recv_buf[9];
		    if(rwnflag == 0) {
		        //write register
		        regdata = recv_buf[10]<<24;
		        regdata |= recv_buf[11]<<16;
		        regdata |= recv_buf[12]<<8;
		        regdata |= recv_buf[13]<<0;
		        if(regaddr == 1)
		            imagewidth = regdata;
		        else if(regaddr == 2)
		            imagehigh = regdata;
		        else if(regaddr == 3)
		            readback = regdata;
		        write_conf_list(REGBASEADDR, regaddr, regdata);
		        regdata = read_conf_list(REGBASEADDR, regaddr);
		        recv_buf[10] = (regdata>>24) & 0XFF;
		        recv_buf[11] = (regdata>>16) & 0XFF;
		        recv_buf[12] = (regdata>>8) & 0XFF;
		        recv_buf[13] = (regdata>>0) & 0XFF;
		        if(lwip_send(sock,recv_buf,read_bytes,0) < 0)
		        {
		            xil_printf("%s: Send Error!\r\n", sock);
		        }
		    }
		    else {
		        //read register
		        regdata = read_conf_list(REGBASEADDR, regaddr);
		        recv_buf[10] = (regdata>>24) & 0XFF;
		        recv_buf[11] = (regdata>>16) & 0XFF;
		        recv_buf[12] = (regdata>>8) & 0XFF;
		        recv_buf[13] = (regdata>>0) & 0XFF;
		        if(lwip_send(sock,recv_buf,read_bytes,0) < 0)
		        {
		            xil_printf("%s: Send Error!\r\n", sock);
		        }
		    }
		}
if(read_byte == 0)
4.实验结果

image-20221201170040853

能够通过网口去修改hdmi_bit_sel,img_width以及img_high。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/51878.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于yolov5n的轻量级MSTAR遥感影像目标检测系统设计开发实战

做过很多目标检测类的项目了&#xff0c;最近看到一个很早之前用过的数据集MSTAR&#xff0c;之前老师给的任务是基于这个数据集来搭建图像识别模型&#xff0c;殊不知他也是可以用来做目标检测的&#xff0c;今天正好有点时间就想着基于这个数据集来做一下目标检测实践。 首先…

利用车载摄像头了解道路语义的鸟瞰图

以下内容来自从零开始机器人SLAM知识星球 每日更新内容 点击领取学习资料 → 机器人SLAM学习资料大礼包 #论文##开源代码# Understanding Bird’s-Eye View of Road Semantics using an Onboard Camera 论文地址&#xff1a;https://arxiv.org/abs/2012.03040 作者单位&#…

自助建站工具

每用一次自助建站工具&#xff0c;就有一个程序员失业。 作为企业老板的你&#xff0c;要为公司的获客&#xff0c;企业推广发愁&#xff0c;但是预算有限&#xff0c;招人也很困难&#xff0c;不仅要面试程序员&#xff0c;后续还要检验这个程序员的功力&#xff0c;实在是太…

CentOS升级python3版本

介绍 本文将详细介绍在CentOS7.9系统的服务器将自带的python3.6.8版本升级到3.8.0版本的过程。 在升级前CentOS7.9中已经同时存在两个python版本分别是2.7.5和3.6.8。 查看CentOS版本命令&#xff1a; cat /etc/centos-release这是我升级后的python版本&#xff08;python3升…

Minio设置文件永久访问和下载

1. docker pull minio/mc 2. docker run -it --entrypoint/bin/sh minio/mc 3. mc config host add <ALIAS> <YOUR-S3-ENDPOINT> <YOUR-ACCESS-KEY> <YOUR-SECRET-KEY> [--api API-SIGNATURE] mc ls minio ALIAS: 别名就是给你的云存储服务起了一个…

2021-02-01

oracle设置定期修改密码 --通过如下sql查询用户密码有效期配置 SELECT username,PROFILE FROM dba_users; --上述sql查询结果一般为default --使用如下sql可以查询到default的默认值 select * from dba_profiles where profile DEFAULT and resource_name PASSWORD_LI…

HTML+CSS大作业【传统文化艺术耍牙15页】学生个人网页设计作品

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

MES系统中生产计划模块的重要作用

MES系统中的“生产调度”支持从“工单管理”中收到的作业队列&#xff0c;根据生产目标&#xff08;时间和数量&#xff09;&#xff0c;必须考虑到人员、设备、材料的可用性等限制和生产过程中的各种中断&#xff0c;生成一个作业时间表&#xff0c;即生产作业计划。MES系统“…

iOS 接入firebase简易步骤

接入准备 去firebase官网注册应用并下载配置文件GoogleService-Info.plist 接入步骤 1.通过cocopods导入以下两个依赖 pod Firebase/Analytics pod Firebase/Core 2.导入成功后将配置文件GoogleService-Info.plist拖入项目中 3.代码支持 引入#import <Firebase/Firebas…

【云原生系列】第五讲:Knative Eventing 下

目录 序言 1.Parallel介绍 1.1 Parallel Spec ​编辑 2.Sequence 2.1.Sequence Spec 2.2适用场景 2.3 Broker/Trigger 2.4 代码示例 3.投票 序言 三言两语&#xff0c;不如细心探索。 今天整理了一下Eventing 相关知识点 ParallelSequence希望此文&#xff0c;能帮…

C#正则表达式总结

推荐一个专门用于编写正则表达式的网站&#xff1a; regex101: build, test, and debug regex 参考文档&#xff1a; https://zh.wikipedia.org/wiki/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F 特殊字符的意义&#xff1a; ^ : 表示字符串的开头 例子&#xff1a; …

局域网的网络硬件主要包括有什么

一、网络服务器 是计算机局域网的核心部件。 网络操作系统是在网络服务器上运行的&#xff0c;网络服务器的效率直接影响整个网络的效率。 因此&#xff0c;一般要用高档计算机或专用服务器计算机作为网络服务器。 二、网络工作站 网络工作站是通过网络接口卡连接到网络上的…

银行软件测试:基于互联网金融平台的测试框架设计与分析

目前互联网金融火的一塌糊涂&#xff0c;基于互联网金融平台的自动化测试的项目也是如火如荼的进行。笔者手头上负责一个p2p项目的测试框架开发&#xff0c;因此如何设计一套有效的测试框架也成为工作所需和互相交流测试经验的必须。进入》软件测试社群学习交流 这个网站的后台…

科研绘图配色方案

科研绘图配色方案 在撰写论文的时候&#xff0c;美观&#xff0c;大气&#xff0c;上档次的图表能够很好地给自己的论文加分。但是在绘制图表的时候往往会面临色彩搭配的问题&#xff0c;选择合适的色彩搭配能够有效地展示自己的方法&#xff0c;但是色彩搭配选择不当的话往往…

Go学习之路:并发(DAY 3)

文章目录前引并发1、Go协程/简单创建2.1、信道/简单创建信道2.2、信道/限制了大小的信道2.3、信道/range close信道3.1、Select语句前引 听了会歌 一看了下今天已经下午2&#xff1a;50了 我们学校也好像开始放学生们回家了 那今天最后就愉快愉快的把我们的 A Tour Of Go 最后…

申报高新技术企业需要哪些条件?

高新技术企业是在国家重点支持的高新技术领域中持续进行科研开发和技术成果转化&#xff0c;形成企业核心自主知识产权&#xff0c;并以此为基础开展生产经营活动的企业。成为高新技术企业以后会减免40%的所得税。 申报高新技术企业需要哪些条件&#xff1f; 第一点&#xff…

回收站不见了怎么恢复?一招把回收站的图标找回来!

有时我们会有这样的烦恼&#xff0c;明明回收站里面的东西还没被删除或者是还在回收站里面&#xff0c;但是回收站的图标就是看不到了。其实&#xff0c;这正是我们所说的电脑回收站不显示图标导致。因为我们关闭回收站位置以后&#xff0c;电脑系统都会自动把回收站置为“已删…

TPM零知识学习四 —— tpm2-tss源码安装

tpm2-tss包的的安装方法参考&#xff1a; tpm2-tss/INSTALL.md at master tpm2-software/tpm2-tss GitHub 1. 源码下载 $ git clone https://github.com/tpm2-software/tpm2-tss.git 下载完成后&#xff0c;源码内容如下所示&#xff1a; $ ls afl-fuzzing CHANGELOG.m…

基于ssm的小区物业管理系统

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下&#xff0c;你想解决的问…

mac下安装nodejs跟vscode

1.打开官网 Node.js 2.点击下载 3.下载完成&#xff0c;根据提示下一步安装&#xff0c;安装完成后&#xff0c;在vscode中新建一个js文件&#xff0c;执行node test.js