前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ZYNQ 裸机lwip 双网口注意事项

ZYNQ 裸机lwip 双网口注意事项

作者头像
用户9736681
发布2024-03-06 14:09:14
1150
发布2024-03-06 14:09:14
举报
文章被收录于专栏:嵌入式随笔嵌入式随笔

本例子使用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 增加如下:

代码语言:javascript
复制
#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如下:

代码语言:javascript
复制
//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连接状态

代码语言:text
复制
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 down\r\n");
 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 up\r\n");
 }
 break;
 }
// xil_printf("net0_link_state %d\r\n",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 down\r\n");
 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 up\r\n");
 }
 break;
 }
 }

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

区分不同网口:

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

代码语言:text
复制
 if(netif == xxx_netif){
 if (link_speed == XST_FAILURE) {
 eth_link_status = ETH_LINK_DOWN;
 xil_printf("Assert due to phy setup failure \n\r",__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 \n\r",__func__);
 } else {
 eth_link_status1 = ETH_LINK_UP;
 }
 }

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

3.3 增加新的网口检测

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

代码语言:javascript
复制
 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 修改:

代码语言:javascript
复制
#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

增加最大长度

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-02-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 嵌入式随笔 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 增加宏定义 vivado自带的问题,生成的时候少宏定义。
  • 2 路由相关设置
    • 2.2 增加路由功能宏定义
      • 2.3 修改路由相关函数
      • 3 热插拔相关
        • 3.1 修改连接状态检测
          • 3.2 修改初始化时候的连接状态
            • 3.3 增加新的网口检测
            • 4 修改长帧可能遇到的问题
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档