加入星计划,您可以享受以下权益:

  • 创作内容快速变现
  • 行业影响力扩散
  • 作品版权保护
  • 300W+ 专业用户
  • 1.5W+ 优质创作者
  • 5000+ 长期合作伙伴
立即加入
  • 正文
  • 推荐器件
  • 相关推荐
  • 电子产业图谱
申请入驻 产业图谱

ZYNQ 裸机lwip 双网口注意事项

02/21 11:10
4821
阅读需 25 分钟
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

本例子使用zynq7000系列的ps带的两个mac,一个通过mio引出,一个通过emio引出。如下图:

由于lwip通常不使用双网口,有部分需要注意修改。有以下注意事项:

1 增加宏定义

vivado自带的问题,生成的时候少宏定义。

xxx_bsp/ps7_cortexa9_0/include/xparameters.h 增加宏定义:

#define XPAR_GMII2RGMIICON_0N_ETH1_ADDR  5

xxx_bsp/ps7_cortexa9_0/libsrc/lwip202_v1_2/src/contrib/ports/xilinx/netif/xemacpsif_physpeed.c 增加宏定义

#define  XPAR_GMII2RGMIICON_0N_ETH1_ADDR 6

此数据5应与ip核设置为相同

2  路由相关设置

使能路由,并且由于双网口可能处于相同网段需要进行适度修改。

2.1 使能lwip的路由功能

xxx_bsp/ps7_cortexa9_0/libsrc/lwip202_v1_2/src/contrib/ports/Xilinx/include/lwipopts.h

#define IP_FORWARD 1  使能路由

2.2 增加路由功能宏定义

xxx_bsp/ps7_cortexa9_0/libsrc/lwip202_v1_2/src/lwip-2.0.2/src/include/lwip/ip4.h

#define LWIP_HOOK_IP4_ROUTE_SRC

2.3 修改路由相关函数

xxx_bsp/ps7_cortexa9_0/libsrc/lwip202_v1_2/src/lwip202_v1_2/src/include/lwip/netif.h  增加如下:

#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 */

xxx_bsp/ps7_cortexa9_0/libsrc/lwip202_v1_2/src/lwip-2.0.2/src/core/ipv4/ip4.c

修改ip4_route_src如下:

//struct netif *

//ip4_route_src(const ip4_addr_t *dest, const ip4_addr_t *src)

//{

// if (src != NULL) {

// /* when src==NULL, the hook is called from ip4_route(dest) */

// struct netif *netif = LWIP_HOOK_IP4_ROUTE_SRC(dest, src);

// if (netif != NULL) {

// return netif;

// }

// }

// return ip4_route(dest);

//}


struct netif *

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;

}

 

3 热插拔相关

原来的检测都是针对单网口的,需要适度修改

3.1 修改连接状态检测

xxx_bsp/ps7_cortexa9_0/libsrc/lwip202_v1_2/src/contrib/ports/Xilinx/netif/xadapter.c 截取PHY连接状态

void eth_link_detect(struct netif *netif)

{

u32_t link_speed, phy_link_status;

struct xemac_s *xemac = (struct xemac_s *)(netif->state);


#if defined(XLWIP_CONFIG_INCLUDE_GEM)

xemacpsif_s *xemacs = (xemacpsif_s *)(xemac->state);

XEmacPs *xemacp = &xemacs->emacps;

#elif defined(XLWIP_CONFIG_INCLUDE_AXI_ETHERNET)

xaxiemacif_s *xemacs = (xaxiemacif_s *)(xemac->state);

XAxiEthernet *xemacp = &xemacs->axi_ethernet;

#elif defined(XLWIP_CONFIG_INCLUDE_EMACLITE)

xemacliteif_s *xemacs = (xemacliteif_s *)(xemac->state);

XEmacLite *xemacp = xemacs->instance;

#endif


if(netif == xxx_netif){

if ((xemacp->IsReady != (u32)XIL_COMPONENT_IS_READY) ||

(eth_link_status == ETH_LINK_UNDEFINED))

return;

phy_link_status = phy_link_detect(xemacp, phyaddrforemac);

net0_link_state = phy_link_status;

if ((eth_link_status == ETH_LINK_UP) && (!phy_link_status))

eth_link_status = ETH_LINK_DOWN;


switch (eth_link_status) {

case ETH_LINK_UNDEFINED:

case ETH_LINK_UP:

return;

case ETH_LINK_DOWN:

netif_set_link_down(netif);

eth_link_status = ETH_LINK_NEGOTIATING;

xil_printf("Ethernet Link downrn");

netif->dhcp_bind_state = 0;

break;

case ETH_LINK_NEGOTIATING:

if (phy_link_status &&

phy_autoneg_status(xemacp, phyaddrforemac)) {


/* Initiate Phy setup to get link speed */

#if defined(XLWIP_CONFIG_INCLUDE_GEM)

link_speed = phy_setup_emacps(xemacp,

phyaddrforemac);


XEmacPs_SetOperatingSpeed(xemacp, link_speed);

#elif defined(XLWIP_CONFIG_INCLUDE_AXI_ETHERNET)

link_speed = phy_setup_axiemac(xemacp);

XAxiEthernet_SetOperatingSpeed(xemacp,

link_speed);

#endif

netif_set_link_up(netif);

eth_link_status = ETH_LINK_UP;

xil_printf("Ethernet Link uprn");

}

break;

}

// xil_printf("net0_link_state %drn",net0_link_state);

}

if(netif == xxx_netif1){

if ((xemacp->IsReady != (u32)XIL_COMPONENT_IS_READY) ||

(eth_link_status1 == ETH_LINK_UNDEFINED))

return;

phy_link_status = phy_link_detect(xemacp, phyaddrforemac);

net1_link_state = phy_link_status;

if ((eth_link_status1 == ETH_LINK_UP) && (!phy_link_status))

eth_link_status1 = ETH_LINK_DOWN;


switch (eth_link_status1) {

case ETH_LINK_UNDEFINED:

case ETH_LINK_UP:

return;

case ETH_LINK_DOWN:

netif_set_link_down(netif);

eth_link_status1 = ETH_LINK_NEGOTIATING;

xil_printf("Ethernet1 Link downrn");

netif->dhcp_bind_state = 0;

break;

case ETH_LINK_NEGOTIATING:

if (phy_link_status &&

phy_autoneg_status(xemacp, phyaddrforemac)) {


/* Initiate Phy setup to get link speed */

#if defined(XLWIP_CONFIG_INCLUDE_GEM)

link_speed = phy_setup_emacps(xemacp,

phyaddrforemac);


XEmacPs_SetOperatingSpeed(xemacp, link_speed);

#elif defined(XLWIP_CONFIG_INCLUDE_AXI_ETHERNET)

link_speed = phy_setup_axiemac(xemacp);

XAxiEthernet_SetOperatingSpeed(xemacp,

link_speed);

#endif

netif_set_link_up(netif);

eth_link_status1 = ETH_LINK_UP;

xil_printf("Ethernet1 Link uprn");

}

break;

}

}

3.2 修改初始化时候的连接状态

区分不同网口:

void init_emacps(xemacpsif_s *xemacps, struct netif *netif)修改:

if(netif == xxx_netif){

if (link_speed == XST_FAILURE) {

eth_link_status = ETH_LINK_DOWN;

xil_printf("Assert due to phy setup failure nr",__func__);

} else {

eth_link_status = ETH_LINK_UP;

}

}

if(netif == xxx_netif1){

if (link_speed == XST_FAILURE) {

eth_link_status1 = ETH_LINK_DOWN;

xil_printf("Assert due to phy setup failure nr",__func__);

} else {

eth_link_status1 = ETH_LINK_UP;

}

}

增加另一个网口的状态判断。

3.3 增加新的网口检测

xxx/src/platform_zynq.c   中的定时检测

if (DetectEthLinkStatus == ETH_LINK_DETECT_INTERVAL) {

eth_link_detect(xxx_netif);

eth_link_detect(xxx_netif1);

DetectEthLinkStatus = 0;

}

增加一个网口的状态检测。

4 修改长帧可能遇到的问题

不同设备定义的MUT含义可能不一样,将长度适当放开。

xxx_bsp/ps7_cortexa9_0/libsrc/lwip202_v1_2/src/contrib/ports/xilinx/netif/xemacpsif_dma.c 修改:

#ifdef ZYNQMP_USE_JUMBO

max_fr_size = MAX_FRAME_SIZE_JUMBO - 18;

max_fr_size = MAX_FRAME_SIZE_JUMBO - 4;//仅是减去crc的4个字节

#else

max_fr_size = XEMACPS_MAX_FRAME_SIZE - 18;

max_fr_size = XEMACPS_MAX_FRAME_SIZE - 4;//仅是减去crc的4个字节

#endif

增加最大长度

推荐器件

更多器件
器件型号 数量 器件厂商 器件描述 数据手册 ECAD模型 风险等级 参考价格 更多信息
ABM3-10.000MHZ-D2Y-T 1 Abracon Corporation CRYSTAL 10.0000MHZ 18PF SMD

ECAD模型

下载ECAD模型
$1.1 查看
ASE-50.000MHZ-L-R-T 1 Abracon Corporation CMOS Output Clock Oscillator, 50MHz Nom, ROHS COMPLIANT, SMD, 4 PIN
$2.75 查看
LTC6990HDCB#TRMPBF 1 Analog Devices Inc TimerBlox: Voltage Controlled Silicon Oscillator
暂无数据 查看

相关推荐

电子产业图谱