涉及 lwip 库文件及 ZYNQ 配置相关可参考以下文章:
【ZYNQ】裸机 PS + PL 双网口实现之 LWIP 库文件修改
【ZYNQ】裸机 PS + PL 双网口实现之 ZYNQ 配置
工程配置
- 启动 SDK ,创建模板工程,配置 BSP。
- 勾选 lwip141 库。
- 对 lwip 做如下配置,如没有此选项请先参考【ZYNQ】裸机 PS + PL 双网口实现之 lwip 库文件修改。
将
use_axieth_on_zynq
和use_emaclite_on_zynq
设为 0。将use_gmii2rgmii_core_on_eth1
设置为true
,GMII to RGMII IP 核对应的 PHY 地址为 8,即gmii2rgmii_core_address_on_eth1
设为 8。ETH0 不使用 EMIO,因此use_gmii2rgmii_core_on_eth0
为false
,gmii2rgmii_core_address_on_eth0
无需进行设置。
程序设计
-
添加定时器,用来调用 tcp 服务,其中,250ms 和 500ms 是必须的。相关代码如下:
-
main.c
/**
* Copyright (c) 2022-2023,HelloAlpha
*
* Change Logs:
* Date Author Notes
*/
#include "platform_config.h"
#include "service/timer/app_timer.h"
#define USING_ULOG
#include "ulog.h"
#define _EXPORT_FUNC(function) \
do \
{ \
extern int function(void); \
function(); \
} while (0)
int lwip_tcp_init(void);
int app_timer_init(void);
int func_doing_always(void)
{
static timer_flag_t *_timer_flag = &g_timer_flag;
#ifdef USING_ETHERNET_TCP
_EXPORT_FUNC(tcp_func_always);
#endif
if(_timer_flag->timer_flag_250ms == 1)
{
_timer_flag->timer_flag_250ms = 0;
#ifdef USING_ETHERNET_TCP
_EXPORT_FUNC(tcp_func_per_250ms);
#endif
}
if(_timer_flag->timer_flag_500ms)
{
_timer_flag->timer_flag_500ms = 0;
#ifdef USING_ETHERNET_TCP
_EXPORT_FUNC(tcp_func_per_500ms);
#endif
}
if(_timer_flag->timer_flag_1s == 1)
{
_timer_flag->timer_flag_1s = 0;
#ifdef USING_ETHERNET_TCP
_EXPORT_FUNC(tcp_func_per_1s);
#endif
}
return 0;
}
int main(void)
{
ULOG("\r\n------ Main Function Running ------\r\n");
app_timer_init();
#ifdef USING_ETHERNET_TCP
_EXPORT_FUNC(lwip_tcp_init);
#endif
while(1)
{
func_doing_always();
}
return 0;
}
-
基于 LWIP 创建网卡,这里配置为静态 IP,代码如下:
-
lwip_tcp.c
/**
* Copyright (c) 2022-2023,HelloAlpha
*
* Change Logs:
* Date Author Notes
*/
#include "tcp_config.h"
#ifdef USING_ETHERNET_TCP
#include "lwip/init.h"
#include "lwip/err.h"
#include "netif/xadapter.h"
#define USING_ULOG
#include "ulog.h"
err_t accept_callback(void *arg, struct tcp_pcb *newpcb, err_t err);
static void print_ip(char *msg, struct ip_addr *ip)
{
kprintf(msg);
kprintf("%d.%d.%d.%d\r\n", ip4_addr1(ip), ip4_addr2(ip),
ip4_addr3(ip), ip4_addr4(ip));
}
void tcp_node_printf(char *tcp_node_name, tcp_node_t *tcp_node)
{
kprintf("------------- %s -------------\r\n", tcp_node_name);
print_ip("local addr: ", &(tcp_node->local_addr));
kprintf("local port: %d \r\n" ,tcp_node->local_port);
print_ip("target addr: ", &(tcp_node->target_addr));
kprintf("remote port: %d \r\n", tcp_node->remote_port);
kprintf("-------------------------------------\r\n");
}
static void print_app_header()
{
kprintf("\n\r----- lwIP TCP ------\r\n");
}
/**
* @brief
*
* @return err_t
*/
err_t start_tcp_application(tcp_node_t *tcp_node)
{
err_t err;
if(!tcp_node)
{
ULOG("TCP node is empty!\r\n");
return ERR_ARG;
}
/* create pcb */
tcp_node->pcb_obj = tcp_new();
if (!tcp_node->pcb_obj)
{
ULOG("Error creating PCB. Out of Memory!\r\n");
return ERR_MEM;
}
/* bind to specified @port */
err = tcp_bind(tcp_node->pcb_obj, &(tcp_node->local_addr), tcp_node->local_port);
if (err != ERR_OK)
{
ULOG("Unable to bind to port %d: err = %d!\r\n", tcp_node->local_port, err);
return ERR_ABRT;
}
/* we do not need any arguments to callback functions */
tcp_arg(tcp_node->pcb_obj, NULL);
/* listen for connections */
tcp_node->pcb_obj = tcp_listen(tcp_node->pcb_obj);
if (!tcp_node->pcb_obj)
{
ULOG("Out of memory while tcp_listen!\r\n");
return ERR_MEM;
}
/* specify callback to use for incoming connections */
tcp_accept(tcp_node->pcb_obj, accept_callback);
return err;
}
#ifdef USING_ETHERNET0
static int ethernet0_init(void)
{
err_t err;
struct netif *echo_netif0 = &server_netif0;
struct ip_addr ipaddr0, netmask0, gw0;
/* the mac address of the board. this should be unique per board */
unsigned char mac_ethernet_address0[] = { 0x00, 0x0a, 0x35, 0x00, 0x01, 0x02 };
/* initliaze IP addresses to be used */
IP4_ADDR(&ipaddr0, 192, 168, 6, 10);
IP4_ADDR(&netmask0, 255, 255, 255, 0);
IP4_ADDR(&gw0, 192, 168, 1, 1);
/* Add network interface to the netif_list, and set it as default */
if (!xemac_add(echo_netif0, &ipaddr0, &netmask0,
&gw0, mac_ethernet_address0,
PLATFORM_EMAC_BASEADDR))
{
kprintf("ENET0 Error adding N/W interface!\r\n");
return -1;
}
netif_set_default(echo_netif0);
/* specify that the network if is up */
netif_set_up(echo_netif0);
/* initialize TCP0 node */
tcp_node_t *tcp0_node = &g_tcp0_node;
/* local IP */
tcp0_node->local_addr.addr = ipaddr0.addr;
/* local port */
tcp0_node->local_port = DEFAULT_PORT0;
/* target IP */
IP4_ADDR(&(tcp0_node->target_addr), 192,168,6,81);
/* target port */
tcp0_node->remote_port = 8080;
/* clear the connection flag */
tcp0_node->connected_flag = 0;
/* start the application */
err = start_tcp_application(tcp0_node);
if(err != ERR_OK)
{
kprintf("Start TCP0 application failed!\r\n");
return -1;
}
else
{
tcp_node_printf("TCP0 Node", tcp0_node);
}
return 0;
}
#endif
#ifdef USING_ETHERNET1
static int ethernet1_init(void)
{
err_t err;
struct netif *echo_netif1 = &server_netif1;
struct ip_addr ipaddr1, netmask1, gw1;
/* the mac address of the board. this should be unique per board */
unsigned char mac_ethernet_address1[] = { 0x00, 0x0a, 0x35, 0x00, 0x01, 0x03 };
/* initliaze IP addresses to be used */
IP4_ADDR(&ipaddr1, 192, 168, 6, 20);
IP4_ADDR(&netmask1, 255, 255, 255, 0);
IP4_ADDR(&gw1, 192, 168, 1, 1);
if (!xemac_add(echo_netif1, &ipaddr1, &netmask1,
&gw1, mac_ethernet_address1,
PLATFORM_EMAC1_BASEADDR))
{
kprintf("ENET1 Error adding N/W interface!\r\n");
return -1;
}
netif_set_default(echo_netif1);
/* specify that the network if is up */
netif_set_up(echo_netif1);
/* initialize TCP1 node */
tcp_node_t *tcp1_node = &g_tcp1_node;
/* local IP */
tcp1_node->local_addr.addr = ipaddr1.addr;
/* local port */
tcp1_node->local_port = DEFAULT_PORT1;
/* target IP */
IP4_ADDR(&(tcp1_node->target_addr), 192,168,6,81);
/* target port */
tcp1_node->remote_port = 8081;
/* clear the connection flag */
tcp1_node->connected_flag = 0;
/* start the application */
err = start_tcp_application(tcp1_node);
if(err != ERR_OK)
{
kprintf("Start TCP1 application failed!\r\n");
return -1;
}
else
{
tcp_node_printf("TCP1 Node", tcp1_node);
}
return 0;
}
#endif
int lwip_tcp_init(void)
{
print_app_header();
lwip_init();
#ifdef USING_ETHERNET0
ethernet0_init();
#endif
#ifdef USING_ETHERNET1
ethernet1_init();
#endif
return 0;
}
#endif
-
tcp_service.c 主要实现一些功能服务。
-
tcp_service.c
/**
* Copyright (c) 2022-2023,HelloAlpha
*
* Change Logs:
* Date Author Notes
*/
#include "tcp_config.h"
#ifdef USING_ETHERNET_TCP
#include "lwip/err.h"
#include <string.h>
#define USING_ULOG
#include "ulog.h"
#ifdef USING_ETHERNET0
static tcp_node_t *tcp0_node = &g_tcp0_node;
#endif
#ifdef USING_ETHERNET1
static tcp_node_t *tcp1_node = &g_tcp1_node;
#endif
/**
* @brief TCP data sending function
*
* @return err_t
*/
err_t tcp_transfer_data(struct tcp_pcb *tpcb, const uint8_t *pData, int plen)
{
err_t err;
static struct pbuf *tcp_pbuf = NULL;
static int tcp_len = 0;
/* If parameter length bigger than tcp_len, reallocate memory space */
if(plen > tcp_len)
{
if(tcp_pbuf)
{
/* free pbuf */
pbuf_free(tcp_pbuf);
}
tcp_len = plen;
/* allocate memory space to pbuf */
tcp_pbuf = pbuf_alloc(PBUF_TRANSPORT, tcp_len, PBUF_RAM);
if(!tcp_pbuf)
{
ULOG("pbuf_alloc %d fail!\r\n", tcp_len);
tcp_len = 0;
return ERR_BUF;
}
}
/* copy data to pbuf payload */
memcpy(tcp_pbuf->payload, pData, plen);
tcp_pbuf->len = plen;
tcp_pbuf->tot_len = plen;
/* Start to send udp data */
err = tcp_write(tpcb, (tcp_pbuf->payload), (tcp_pbuf->len),
TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE);
if (err != ERR_OK)
{
ULOG("Error on tcp_write: %d!\r\n", err);
return err;
}
err = tcp_output(tpcb);
if (err != ERR_OK)
{
ULOG("Error on tcp_output: %d!\r\n", err);
return err;
}
return err;
}
/**
* @brief TCP data sending function
*
* @return err_t
*/
err_t tcp_send(tcp_node_t *tcp_node, tcp_msg_t *tcp_msg)
{
err_t err;
if(!tcp_node)
{
ULOG("Empty TCP node!\r\n");
return ERR_ARG;
}
else if(!tcp_msg)
{
ULOG("Empty TCP message!\r\n");
return ERR_ARG;
}
else if(!tcp_node->connected_flag)
{
ULOG("TCP%d is not currently connected!\r\n",
(tcp_node->local_port == DEFAULT_PORT0) ? 0 : 1);
tcp_msg->tx_vflag = 0;
return ERR_CONN;
}
else if(!tcp_msg->tx_vflag)
{
ULOG("Flag indicates message is not ready!\r\n");
return ERR_ARG;
}
else
{
err = tcp_transfer_data(tcp_node->pcb_obj,
(uint8_t *)tcp_msg->tx_pdata, tcp_msg->tx_plen);
tcp_msg->tx_vflag = 0;
}
return err;
}
/**
* @brief close the TCP connection
*
* @return int
*/
static int tcp_connection_close(struct tcp_pcb *tpcb)
{
tcp_close(tpcb);
tcp_arg(tpcb, NULL);
tcp_recv(tpcb, NULL);
tcp_sent(tpcb, NULL);
tcp_poll(tpcb, NULL, 0);
tcp_err(tpcb, NULL);
#ifdef USING_ETHERNET0
if(tpcb->local_port == DEFAULT_PORT0)
{
if(tcp0_node->connected_flag == 1)
{
/* reset the connection flag */
tcp0_node->connected_flag = 0;
}
}
#endif
#ifdef USING_ETHERNET1
if (tpcb->local_port == DEFAULT_PORT1)
{
if(tcp1_node->connected_flag == 1)
{
/* reset the connection flag */
tcp1_node->connected_flag = 0;
}
}
#endif
return ERR_OK;
}
/**
* @brief TCP data receiving callback function
*
* @return err_t
*/
static err_t recv_callback(void *arg, struct tcp_pcb *tpcb,
struct pbuf *p_rx, err_t err)
{
/* do not read the packet if we are not in ESTABLISHED state */
if (!p_rx)
{
tcp_connection_close(tpcb);
return ERR_OK;
}
/* indicate that the packet has been received */
tcp_recved(tpcb, p_rx->len);
/* the data is processed here. */
{
#ifndef USING_TCP_LOOKBACK
#ifdef USING_ETHERNET0
static tcp_msg_t *tcp0_msg = &g_tcp0_msg;
if(tpcb->local_port == DEFAULT_PORT0)
{
if(!tcp0_msg->rx_vflag)
{
tcp0_msg->rx_pdata = tcp0_msg->rx_pdata_buf;
memcpy(tcp0_msg->rx_pdata, (char *) p_rx->payload, p_rx->len);
tcp0_msg->rx_plen = p_rx->len;
tcp0_msg->rx_vflag = 1;
}
}
#endif
#ifdef USING_ETHERNET1
static tcp_msg_t *tcp1_msg = &g_tcp1_msg;
if(tpcb->local_port == DEFAULT_PORT1)
{
if(!tcp1_msg->rx_vflag)
{
tcp1_msg->rx_pdata = tcp1_msg->rx_pdata_buf;
memcpy(tcp1_msg->rx_pdata, (char *) p_rx->payload, p_rx->len);
tcp1_msg->rx_plen = p_rx->len;
tcp1_msg->rx_vflag = 1;
}
}
#endif
#else
char TcpSend[] = "> LookBack Test Running... \r\n> Rec Data: ";
tcp_transfer_data(tpcb, (uint8_t *)TcpSend, strlen(TcpSend));
/* echo back the payload */
/* in this case, we assume that the payload is < TCP_SND_BUF */
if (tcp_sndbuf(tpcb) > p_rx->len)
{
err = tcp_write(tpcb, p_rx->payload, p_rx->len, 1);
}
else
{
ULOG("No space in tcp_sndbuf...\n\r");
}
#endif
}
/* free the received pbuf */
pbuf_free(p_rx);
return ERR_OK;
}
/**
* @brief TCP Callback function for successful TCP data sending
*
* @return err_t
*/
static err_t tcp_sent_callback(void *arg, struct tcp_pcb *tpcb, u16_t len)
{
#ifdef USING_ETHERNET0
static uint32_t tcp0_trans_cnt = 0;
if(tpcb->local_port == DEFAULT_PORT0)
{
ULOG("TCP0 Send Success Count: %d \r\n", tcp0_trans_cnt++);
}
#endif
#ifdef USING_ETHERNET1
static uint32_t tcp1_trans_cnt = 0;
if (tpcb->local_port == DEFAULT_PORT1)
{
ULOG("TCP1 Send Success Count: %d \r\n", tcp1_trans_cnt++);
}
#endif
return ERR_OK;
}
static err_t tcp_poll_callback(void *arg, struct tcp_pcb *tpcb)
{
/* it is executed every 500ms */
#ifdef USING_ETHERNET0
if(tpcb->local_port == DEFAULT_PORT0)
{
tcp0_node->connected_count++;
}
#endif
#ifdef USING_ETHERNET1
if(tpcb->local_port == DEFAULT_PORT1)
{
tcp1_node->connected_count++;
}
#endif
return ERR_OK;
}
static void tcp_err_callback(void *arg, err_t err)
{
LWIP_UNUSED_ARG(err);
ULOG("TCP error: %x \r\n", (uint32_t)arg);
if(NULL != arg)
{
}
}
/**
* @brief When TCP is in LISTEN state, listen for a new connection
* and execute this function
*
* @return err_t
*/
err_t accept_callback(void *arg, struct tcp_pcb *newpcb, err_t err)
{
static int connection = 1;
/* set the receive callback for this connection */
tcp_recv(newpcb, recv_callback);
/* set the sent callback for this connection */
tcp_sent(newpcb, tcp_sent_callback);
tcp_poll(newpcb, tcp_poll_callback, 1);
tcp_err(newpcb, tcp_err_callback);
{
ULOG("\r\n----- TCP Connection -----\r\n");
ULOG(" Local IP: %d.%d.%d.%d, Local Port: %d \r\n",
(newpcb->local_ip.addr) & 0xff, (newpcb->local_ip.addr >> 8) & 0xff,
(newpcb->local_ip.addr >> 16) & 0xff, (newpcb->local_ip.addr >> 24) & 0xff,
newpcb->local_port);
ULOG(" Remote IP: %d.%d.%d.%d, Remote Port: %d \r\n",
(newpcb->remote_ip.addr) & 0xff, (newpcb->remote_ip.addr >> 8) & 0xff,
(newpcb->remote_ip.addr >> 16) & 0xff, (newpcb->remote_ip.addr >> 24) & 0xff,
newpcb->remote_port);
#ifdef USING_ETHERNET0
if(newpcb->local_port == DEFAULT_PORT0)
{
if(tcp0_node->connected_flag == 0)
{
/* set the connection flag */
tcp0_node->connected_flag = 1;
tcp0_node->pcb_obj = newpcb;
}
}
#endif
#ifdef USING_ETHERNET1
if (newpcb->local_port == DEFAULT_PORT1)
{
if(tcp1_node->connected_flag == 0)
{
/* set the connection flag */
tcp1_node->connected_flag = 1;
tcp1_node->pcb_obj = newpcb;
}
}
#endif
}
/* just use an integer number indicating the connection id as the
callback argument */
tcp_arg(newpcb, (void*)(UINTPTR)connection);
/* increment for subsequent accepted connections */
connection++;
return ERR_OK;
}
#ifdef USING_TCP_STATUS
#ifdef USING_ETHERNET0
static int tcp0_check_connect_status(void)
{
static uint32_t last_tcp0_count = 0;
static uint8_t tcp0_status = 0;
if(tcp0_node->connected_count > last_tcp0_count)
{
if(tcp0_status == 0)
{
tcp0_status = 1;
ULOG("Tcp0 Connected!\r\n");
}
if(tcp0_node->connected_count > 65530)
{
tcp0_node->connected_count = 1;
}
last_tcp0_count = tcp0_node->connected_count;
}
else
{
tcp0_node->connected_flag = 0;
if(tcp0_status == 1)
{
tcp0_status = 0;
ULOG("Tcp0 Disconnected!\r\n");
}
}
return 0;
}
#endif
#ifdef USING_ETHERNET1
static int tcp1_check_connect_status(void)
{
static uint32_t last_tcp1_count = 0;
static uint8_t tcp1_status = 0;
if(tcp1_node->connected_count > last_tcp1_count)
{
if(tcp1_status == 0)
{
tcp1_status = 1;
ULOG("Tcp1 Connected!\r\n");
}
if(tcp1_node->connected_count > 65530)
{
tcp1_node->connected_count = 1;
}
last_tcp1_count = tcp1_node->connected_count;
}
else
{
tcp1_node->connected_flag = 0;
if(tcp1_status == 1)
{
tcp1_status = 0;
ULOG("Tcp1 Disconnected!\r\n");
}
}
return 0;
}
#endif
/**
* @brief Check TCP connect status
*
*/
int tcp_check_connect_status(void)
{
#ifdef USING_ETHERNET0
tcp0_check_connect_status();
#endif
#ifdef USING_ETHERNET1
tcp1_check_connect_status();
#endif
return 0;
}
#endif
#endif
-
tcp_config.h 实现了一些定义及配置。
-
tcp_config.h
/**
* Copyright (c) 2022-2023,HelloAlpha
*
* Change Logs:
* Date Author Notes
*/
#ifndef __TCP_CONFIG_H__
#define __TCP_CONFIG_H__
#include "xparameters.h"
/**
* TCP config begin
* @{
*/
#define USING_ETHERNET_TCP
#if defined USING_ETHERNET_TCP
#define USING_ETHERNET0
#define USING_ETHERNET1
#define USING_TCP_STATUS
//#define USING_TCP_LOOKBACK
//#define USING_TCP_PRINT_MSG
//#define USING_TCP_TEST_CMD
#endif
#ifdef USING_ETHERNET0
#define PLATFORM_EMAC_BASEADDR XPAR_XEMACPS_0_BASEADDR
#endif
#ifdef USING_ETHERNET1
#define PLATFORM_EMAC1_BASEADDR XPAR_XEMACPS_1_BASEADDR
#endif
/**@}*/
#ifdef USING_ETHERNET_TCP
#include "lwip/tcp.h"
/* default IP port */
#define DEFAULT_PORT0 7
#define DEFAULT_PORT1 8
#define MAX_SEND_LEN 64
#define TCP_MSG_MSG_LEN 256
struct tcp_msg
{
char rx_pdata_buf[TCP_MSG_MSG_LEN];
char *rx_pdata;
uint16_t rx_plen;
uint8_t rx_vflag;
char tx_pdata_buf[TCP_MSG_MSG_LEN];
char *tx_pdata;
uint16_t tx_plen;
uint8_t tx_vflag;
};
typedef struct tcp_msg tcp_msg_t;
struct tcp_node
{
struct tcp_pcb *pcb_obj;
struct ip_addr local_addr;
uint16_t local_port;
struct ip_addr target_addr;
uint16_t remote_port;
uint8_t connected_flag;
struct tcp_msg *msg;
uint32_t connected_count;
};
typedef struct tcp_node tcp_node_t;
#ifdef USING_ETHERNET0
struct netif server_netif0;
/* definition TCP node */
tcp_node_t g_tcp0_node;
/* definition TCP message node*/
tcp_msg_t g_tcp0_msg;
#endif
#ifdef USING_ETHERNET1
struct netif server_netif1;
/* definition TCP node */
tcp_node_t g_tcp1_node;
/* definition TCP message node*/
tcp_msg_t g_tcp1_msg;
#endif
err_t tcp_transfer_data(struct tcp_pcb *tpcb, const uint8_t *pData, int plen);
err_t tcp_send(tcp_node_t *tcp_node, tcp_msg_t *tcp_msg);
void tcp_node_printf(char *tcp_node_name, tcp_node_t *tcp_node);
int lwip_tcp_init(void);
#endif
#endif
-
tcp_cmd.c 实现了 tcp 的功能调用等。
-
tcp_cmd.c
/**
* Copyright (c) 2022-2023,HelloAlpha
*
* Change Logs:
* Date Author Notes
*/
#include "tcp_config.h"
#ifdef USING_ETHERNET_TCP
#include "netif/xadapter.h"
#define USING_ULOG
#include "ulog.h"
/* defined by each RAW mode application */
void tcp_fasttmr(void);
void tcp_slowtmr(void);
#ifdef USING_TCP_STATUS
int tcp_check_connect_status(void);
#endif
#ifdef USING_TCP_PRINT_MSG
void tcp_print_msg(void)
{
#ifdef USING_ETHERNET0
static tcp_msg_t *tcp0_msg = &g_tcp0_msg;
if(tcp0_msg->rx_vflag == 1)
{
kprintf("> Eth0 Rec: \r\n");
kprintf("> Data: %s\r\n", tcp0_msg->rx_pdata);
kprintf("> Size: %d\r\n", tcp0_msg->rx_plen);
tcp0_msg->rx_vflag = 0;
}
#endif
#ifdef USING_ETHERNET1
static tcp_msg_t *tcp1_msg = &g_tcp1_msg;
if(tcp1_msg->rx_vflag == 1)
{
kprintf("> Eth1 Rec: \r\n");
kprintf("> Data: %s\r\n", tcp1_msg->rx_pdata);
kprintf("> Size: %d\r\n", tcp1_msg->rx_plen);
tcp1_msg->rx_vflag = 0;
}
#endif
}
#endif
#ifdef USING_TCP_TEST_CMD
int tcp_test_cmd(void)
{
static uint16_t count = 0;
static char tcp_buff[32];
count++;
sprintf(tcp_buff, "Hello! TCP Count: %d \r\n", count);
kprintf("size: %d data: %s", strlen(tcp_buff), tcp_buff);
#ifdef USING_ETHERNET0
static tcp_node_t *tcp0_node = &g_tcp0_node;
static tcp_msg_t *tcp0_msg = &g_tcp0_msg;
if(tcp0_msg->tx_vflag == 0)
{
tcp0_msg->tx_pdata = tcp_buff;
tcp0_msg->tx_plen = strlen(tcp_buff);
tcp0_msg->tx_vflag = 1;
kprintf("TCP0 tcp_send: %d \r\n", tcp_send(tcp0_node, tcp0_msg));
}
#endif
#ifdef USING_ETHERNET1
static tcp_node_t *tcp1_node = &g_tcp1_node;
static tcp_msg_t *tcp1_msg = &g_tcp1_msg;
if(tcp1_msg->tx_vflag == 0)
{
tcp1_msg->tx_pdata = tcp_buff;
tcp1_msg->tx_plen = strlen(tcp_buff);
tcp1_msg->tx_vflag = 1;
kprintf("TCP1 tcp_send: %d \r\n", tcp_send(tcp1_node, tcp1_msg));
}
#endif
return 0;
}
#endif
int tcp_func_per_250ms(void)
{
tcp_fasttmr();
return 0;
}
int tcp_func_per_500ms(void)
{
tcp_slowtmr();
return 0;
}
int tcp_func_per_1s(void)
{
#ifdef USING_TCP_STATUS
tcp_check_connect_status();
#endif
#ifdef USING_TCP_TEST_CMD
tcp_test_cmd();
#endif
return 0;
}
int tcp_func_always(void)
{
/* receive and process packets */
#ifdef USING_ETHERNET0
static struct netif *echo_netif0 = &server_netif0;
xemacif_input(echo_netif0);
#endif
#ifdef USING_ETHERNET1
static struct netif *echo_netif1 = &server_netif1;
xemacif_input(echo_netif1);
#endif
#ifdef USING_TCP_PRINT_MSG
tcp_print_msg();
#endif
return 0;
}
#endif
功能验证
- 创建网卡
- ping 指令测试
- 回环测试
tcp_config.h 中定义使用 tcp 回环测试
使用网络调试助手连接网络
进行回环测试
源码获取
相关代码也可以从此处获取 GitHub。