使用的环境涉及的几个要素,ubuntu18.04,vivado2018.3,7z100芯片。
1、网口0直接从PS引出,网口1数据接口从pS引出,mdio和mdc从EMIO引出
2、lwip代码需要修改这几处
#if LWIP_SINGLE_NETIF
#define NETIF_FOREACH(netif) if (((netif) = netif_default) != NULL)
#else /* LWIP_SINGLE_NETIF */
/** The list of network interfaces. */
extern struct netif *netif_list;
#define NETIF_FOREACH(netif) for ((netif) = netif_list; (netif) != NULL; (netif) = (netif)->next)
#endif /* LWIP_SINGLE_NETIF */
struct netif *
my_ip4_route_src(const ip4_addr_t *dest,const ip4_addr_t *src)
{
#if !LWIP_SINGLE_NETIF
struct netif *netif;
//LWIP_ASSERT_CORE_LOCKED();
#if LWIP_MULTICAST_TX_OPTIONS
/* Use administratively selected interface for multicast by default */
if (ip4_addr_ismulticast(dest) && ip4_default_multicast_netif) {
return ip4_default_multicast_netif;
}
#endif /* LWIP_MULTICAST_TX_OPTIONS */
/* bug #54569: in case LWIP_SINGLE_NETIF=1 and LWIP_DEBUGF() disabled, the following loop is optimized away */
LWIP_UNUSED_ARG(dest);
/* iterate through netifs */
NETIF_FOREACH(netif) {
/* is the netif up, does it have a link and a valid address? */
if (netif_is_up(netif) && netif_is_link_up(netif) && !ip4_addr_isany_val(*netif_ip4_addr(netif))) {
/* network mask matches? */
// if (ip4_addr_netcmp(dest, netif_ip4_addr(netif), netif_ip4_netmask(netif))) {
if (ip4_addr_cmp(src, netif_ip4_addr(netif))) {
/* return netif on which to forward IP packet */
return netif;
}
/* gateway matches on a non broadcast interface? (i.e. peer in a point to point interface) */
if (((netif->flags & NETIF_FLAG_BROADCAST) == 0) && ip4_addr_cmp(dest, netif_ip4_gw(netif))) {
/* return netif on which to forward IP packet */
return netif;
}
}
}
#if LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF
/* loopif is disabled, looopback traffic is passed through any netif */
if (ip4_addr_isloopback(dest)) {
/* don't check for link on loopback traffic */
if (netif_default != NULL && netif_is_up(netif_default)) {
return netif_default;
}
/* default netif is not up, just use any netif for loopback traffic */
NETIF_FOREACH(netif) {
if (netif_is_up(netif)) {
return netif;
}
}
return NULL;
}
#endif /* LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF */
#ifdef LWIP_HOOK_IP4_ROUTE_SRC
netif = LWIP_HOOK_IP4_ROUTE_SRC(NULL, dest);
if (netif != NULL) {
return netif;
}
#elif defined(LWIP_HOOK_IP4_ROUTE)
netif = LWIP_HOOK_IP4_ROUTE(dest);
if (netif != NULL) {
return netif;
}
#endif
#endif /* !LWIP_SINGLE_NETIF */
if ((netif_default == NULL) || !netif_is_up(netif_default) || !netif_is_link_up(netif_default) ||
ip4_addr_isany_val(*netif_ip4_addr(netif_default)) || ip4_addr_isloopback(dest)) {
/* No matching netif found and default netif is not usable.
If this is not good enough for you, use LWIP_HOOK_IP4_ROUTE() */
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip4_route: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest)));
IP_STATS_INC(ip.rterr);
MIB2_STATS_INC(mib2.ipoutnoroutes);
return NULL;
}
return netif_default;
}
使用的main文件的代码如下
/*
* Copyright (C) 2009 - 2018 Xilinx, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
*/
#include <stdio.h>
#include "xparameters.h"
#include "netif/xadapter.h"
#include "platform.h"
#include "platform_config.h"
#if defined (__arm__) || defined(__aarch64__)
#include "xil_printf.h"
#endif
#include "lwip/tcp.h"
#include "xil_cache.h"
/* defined by each RAW mode application */
void print_app_header();
int start_application();
int transfer_data();
void tcp_fasttmr(void);
void tcp_slowtmr(void);
/* missing declaration in lwIP */
void lwip_init();
extern volatile int TcpFastTmrFlag;
extern volatile int TcpSlowTmrFlag;
static struct netif server_netif;
struct netif *echo_netif;
extern volatile int TcpFastTmrFlag1;
extern volatile int TcpSlowTmrFlag1;
static struct netif server_netif1;
struct netif *echo_netif1;
void
print_ip(char *msg, ip_addr_t *ip)
{
print(msg);
xil_printf("%d.%d.%d.%d\n\r", ip4_addr1(ip), ip4_addr2(ip),
ip4_addr3(ip), ip4_addr4(ip));
}
void
print_ip_settings(ip_addr_t *ip, ip_addr_t *mask, ip_addr_t *gw)
{
print_ip("Board IP: ", ip);
print_ip("Netmask : ", mask);
print_ip("Gateway : ", gw);
}
int main()
{
#if LWIP_IPV6==0
ip_addr_t ipaddr, netmask, gw;
ip_addr_t ipaddr1, netmask1, gw1;
#endif
/* the mac address of the board. this should be unique per board */
unsigned char mac_ethernet_address[] =
{ 0x00, 0x0a, 0x35, 0x00, 0x01, 0x02 };
unsigned char mac_ethernet_address1[] =
{ 0x00, 0x0a, 0x35, 0x00, 0x01, 0x03 };
echo_netif = &server_netif;
echo_netif1 = &server_netif1;
init_platform();
/* initliaze IP addresses to be used */
IP4_ADDR(&ipaddr, 192, 168, 0, 12);
IP4_ADDR(&netmask, 255, 255, 255, 0);
IP4_ADDR(&gw, 192, 168, 0, 1);
IP4_ADDR(&ipaddr1, 192, 168, 0, 14);
IP4_ADDR(&netmask1, 255, 255, 255, 0);
IP4_ADDR(&gw1, 192, 168, 0, 1);
print_app_header();
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);
/* now enable interrupts */
platform_enable_interrupts();
/* specify that the network if is up */
netif_set_up(echo_netif);
///
//second ethernet
/* Add network interface to the netif_list, and set it as default */
if (!xemac_add(echo_netif1, &ipaddr1, &netmask1,
&gw1, mac_ethernet_address1,
XPAR_XEMACPS_1_BASEADDR)) {
xil_printf("Error adding N/W interface\n\r");
return -1;
}
netif_set_default(echo_netif1);
/* now enable interrupts */
platform_enable_interrupts();
/* specify that the network if is up */
netif_set_up(echo_netif1);
print_ip_settings(&ipaddr, &netmask, &gw);
print_ip_settings(&ipaddr1, &netmask1, &gw1);
/* start the application (web server, rxtest, txtest, etc..) */
start_application();
/* receive and process packets */
while (1)
{
if (TcpFastTmrFlag)
{
tcp_fasttmr();
TcpFastTmrFlag = 0;
}
if (TcpSlowTmrFlag)
{
tcp_slowtmr();
TcpSlowTmrFlag = 0;
}
if (TcpFastTmrFlag1)
{
tcp_fasttmr();
TcpFastTmrFlag1 = 0;
}
if (TcpSlowTmrFlag1)
{
tcp_slowtmr();
TcpSlowTmrFlag1 = 0;
}
xemacif_input(echo_netif);
xemacif_input(echo_netif1);
transfer_data();
}
/* never reached */
cleanup_platform();
return 0;
}
从wireshark可以看到,两个网卡同时工作,并且路由是正确的