[LWIP] 如何实现LWIP热插拔功能

LWIP 1.4.1

硬件stm32f429 HAL 1.8.1  UCOSIII

步骤如下

1、在lwip的opt.h中使能宏定义LWIP_NETIF_LINK_CALLBACK 链接发生变化时调用回调函数

 

2、在初始化结束后调用函数netif_set_link_callback,为网卡设置一个回调函数,回调参考代码如下

/**
  * @brief  Link callback function, this function is called on change of link status
  *         to update low level driver configuration.
* @param  netif: The network interface
  * @retval None
  */
void ethernetif_update_config(struct netif *netif)
{
  __IO uint32_t tickstart = 0;
  uint32_t regvalue = 0;
  
  if(netif_is_link_up(netif))
  { 
    /* Restart the auto-negotiation */
    if(heth.Init.AutoNegotiation != ETH_AUTONEGOTIATION_DISABLE)
    {
      /* Enable Auto-Negotiation */
      HAL_ETH_WritePHYRegister(&heth, PHY_BCR, PHY_AUTONEGOTIATION);
      
      /* Get tick */
      tickstart = HAL_GetTick();
      
      /* Wait until the auto-negotiation will be completed */
      do
      {
        HAL_ETH_ReadPHYRegister(&heth, PHY_BSR, &regvalue);
        
        /* Check for the Timeout ( 1s ) */
        if((HAL_GetTick() - tickstart ) > 1000)
        {     
          /* In case of timeout */ 
          goto error;
        }   
      } while (((regvalue & PHY_AUTONEGO_COMPLETE) != PHY_AUTONEGO_COMPLETE));
      
      /* Read the result of the auto-negotiation */
      HAL_ETH_ReadPHYRegister(&heth, PHY_SR, &regvalue);
      
      /* Configure the MAC with the Duplex Mode fixed by the auto-negotiation process */
      if((regvalue & PHY_DUPLEX_STATUS) != (uint32_t)RESET)
      {
        /* Set Ethernet duplex mode to Full-duplex following the auto-negotiation */
        heth.Init.DuplexMode = ETH_MODE_FULLDUPLEX;  
      }
      else
      {
        /* Set Ethernet duplex mode to Half-duplex following the auto-negotiation */
        heth.Init.DuplexMode = ETH_MODE_HALFDUPLEX;           
      }
      /* Configure the MAC with the speed fixed by the auto-negotiation process */
      if(regvalue & PHY_SPEED_STATUS)
      {  
        /* Set Ethernet speed to 10M following the auto-negotiation */
        heth.Init.Speed = ETH_SPEED_10M; 
      }
      else
      {   
        /* Set Ethernet speed to 100M following the auto-negotiation */ 
        heth.Init.Speed = ETH_SPEED_100M;
      }
    }
    else /* AutoNegotiation Disable */
    {
    error :
      /* Check parameters */
      assert_param(IS_ETH_SPEED(heth.Init.Speed));
      assert_param(IS_ETH_DUPLEX_MODE(heth.Init.DuplexMode));
      
      /* Set MAC Speed and Duplex Mode to PHY */
      HAL_ETH_WritePHYRegister(&heth, PHY_BCR, ((uint16_t)(heth.Init.DuplexMode >> 3) |
                                                     (uint16_t)(heth.Init.Speed >> 1))); 
    }

    /* ETHERNET MAC Re-Configuration */
    HAL_ETH_ConfigMAC(&heth, (ETH_MACInitTypeDef *) NULL);

    /* Restart MAC interface */
    HAL_ETH_Start(&heth);   
  }
  else
  {
    /* Stop MAC interface */
    HAL_ETH_Stop(&heth);
  }

  ethernetif_notify_conn_changed(netif);
}

 通知代码如下,可重新获取IP或者配置静态IP

/*插入网线的话重新获取IP操作*/
void ethernetif_notify_conn_changed(struct netif *netif)
{
    if(netif_is_link_up(netif) && !netif_is_up(netif))
    {
        netif_set_up(netif);
        extern err_t dhcp_start(struct netif *netif);
		dhcp_start(netif);
    }
}

GD32 LwIP是在GD32微控制器上实现的轻量级网络协议栈,它支持标准的TCP/IP协议。结合FreeRTOS,可以实现在一个实时操作系统上运行网络通信任务。网线热插拔是指在网络连接不稳定或意外断开后,无需关闭电源,重新插拔网线即可恢复网络连接的一种机制。 在GD32 LwIP和FreeRTOS的环境下实现网线热插拔,通常需要以下几个步骤: 1. 硬件支持:确保硬件设计支持网线热插拔功能。这通常涉及到网络变压器或PHY芯片的特定设计,使其能够在没有损害的情况下断开和重新连接。 2. 驱动层的配合:在操作系统的网络驱动层中实现网线连接状态的检测机制。这可能需要底层硬件(如PHY芯片)支持某种形式的状态报告功能,通过GPIO中断或者特定的寄存器读取来实现。 3. 网络协议栈的处理:在网络协议栈中,如LwIP,需要实现对网线状态变化的响应。一旦检测到连接断开,需要处理当前的网络连接,如关闭TCP连接,释放IP地址等。重新检测到连接后,需要重新进行网络配置和连接恢复。 4. 应用层通知:应用层需要有机制来接收来自网络层的热插拔事件通知,并作出相应的处理,比如重启网络服务,或者尝试重新连接。 实现网线热插拔需要各层软件的协同工作,并依赖于稳定的硬件设计。它能够提高系统的稳定性和可用性,特别是在网络环境不可靠或者网络设备经常被移动的场合。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值