



配置服务器端的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_ZCU102IicPhyReset();
#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;}}#elseassign_default_ip(&(server_netif.ip_addr), &(server_netif.netmask),&(server_netif.gw));
#endifprint_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==1server_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;}}
#elsevTaskDelete(NULL);
#endif
}
start_application函数是执行时的数据传输
void start_application(void)
{int sock, new_sd;
#if LWIP_IPV6==1struct sockaddr_in6 address, remote;
#elsestruct sockaddr_in address, remote;
#endif /* LWIP_IPV6 */int size;/* set up address to connect to */memset(&address, 0, sizeof(address));
#if LWIP_IPV6==1if ((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);
#elseif ((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);
}
服务器端使用的端口号是5001
/* server port to listen on/connect to */
#define TCP_CONN_PORT 5001
main_thread_handle
-> main_thread(lwip_init) -> network_thread-> start_application->lwip_socket(bind listen accept)-> tcp_recv_perf_traffic->lwip_recvfrom
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 使用的包窗口大小

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



conf_list_v1_0_S00_AXI.v
(// Users to add ports hereoutput 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 herealways @(posedge S_AXI_ACLK) beginif ( S_AXI_ARESETN == 1'b0 ) beginhdmi_bit_sel <= 0;img_width <= 0;img_high <= 0;endelse beginhdmi_bit_sel <= slv_reg0;img_width <= slv_reg1;img_high <= slv_reg2;endend// User logic ends
conf_list_v1_0.v
// Users to add ports hereoutput 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_AXIconf_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),
lwip_send(int s, const void* dataptr, size_t size,int flags)
其中s是socket,dataptr是数据,size是数据大小,flag默认为0
需要判断收到的数据的前8位都是55,然后把对应地址的数据取出来放到对应的IP里面
#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);
#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
}
#include "conf_list.h"
#include "Xil_io.h"
#define REGBASEADDR 0X00A0000000u32 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 registerregdata = 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 registerregdata = 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)

能够通过网口去修改hdmi_bit_sel,img_width以及img_high。
上一篇:MySQL——进阶