加入星計劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入
  • 正文
  • 推薦器件
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請入駐 產(chǎn)業(yè)圖譜

ZYNQ 裸機(jī)lwip 雙網(wǎng)口注意事項

02/21 11:10
4790
閱讀需 25 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

本例子使用zynq7000系列的ps帶的兩個mac,一個通過mio引出,一個通過emio引出。如下圖:

由于lwip通常不使用雙網(wǎng)口,有部分需要注意修改。有以下注意事項:

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

此數(shù)據(jù)5應(yīng)與ip核設(shè)置為相同

2 ?路由相關(guān)設(shè)置

使能路由,并且由于雙網(wǎng)口可能處于相同網(wǎng)段需要進(jìn)行適度修改。

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 修改路由相關(guān)函數(shù)

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 熱插拔相關(guān)

原來的檢測都是針對單網(wǎng)口的,需要適度修改

3.1 修改連接狀態(tài)檢測

xxx_bsp/ps7_cortexa9_0/libsrc/lwip202_v1_2/src/contrib/ports/Xilinx/netif/xadapter.c 截取PHY連接狀態(tài)

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 修改初始化時候的連接狀態(tài)

區(qū)分不同網(wǎng)口:

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;

}

}

增加另一個網(wǎng)口的狀態(tài)判斷。

3.3 增加新的網(wǎng)口檢測

xxx/src/platform_zynq.c ? 中的定時檢測

if (DetectEthLinkStatus == ETH_LINK_DETECT_INTERVAL) {

eth_link_detect(xxx_netif);

eth_link_detect(xxx_netif1);

DetectEthLinkStatus = 0;

}

增加一個網(wǎng)口的狀態(tài)檢測。

4 修改長幀可能遇到的問題

不同設(shè)備定義的MUT含義可能不一樣,將長度適當(dāng)放開。

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個字節(jié)

#else

max_fr_size = XEMACPS_MAX_FRAME_SIZE - 18;

max_fr_size = XEMACPS_MAX_FRAME_SIZE - 4;//僅是減去crc的4個字節(jié)

#endif

增加最大長度

推薦器件

更多器件
器件型號 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊 ECAD模型 風(fēng)險等級 參考價格 更多信息
NRF52840-QIAA-R7 1 Nordic Semiconductor Telecom Circuit, 1-Func, PBGA73, AQFN-73
$7.48 查看
CM7V-T1A-LOW-ESR-32.768KHZ-7PF-20-TA-QC 1 Micro Crystal AG Parallel - Fundamental Quartz Crystal,

ECAD模型

下載ECAD模型
$3.02 查看
AT27C512R-45JU-T 1 Microchip Technology Inc OTP ROM, 64KX8, 45ns, CMOS, PQCC32

ECAD模型

下載ECAD模型
$2.23 查看

相關(guān)推薦

電子產(chǎn)業(yè)圖譜