STM32 移植LwIP 实现网线插拔自动恢复

STM32 移植LwIP 之后,能正常联网通讯,但是发现2个问题,
1、上电初始化前,未插入网线,之后就无法获取到IP地址(DHCP)
2、正常通讯过程中,拔掉网线,然后插回去,不知道如何复位

先看一下LWIP初始化代码

/**
  * LwIP initialization function
  */
int MX_LWIP_Init()
{	

   /* Initilialize the LwIP stack with RTOS */

		tcpip_init( NULL, NULL );


   
		/* IP addresses initialization with DHCP (IPv4) */
		ipaddr.addr = 0;
		netmask.addr = 0;
		gw.addr = 0;

	 printf("netif add\r\n");
		/* add the network interface (IPv4/IPv6) with RTOS */
		netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, &ethernetif_init, &tcpip_input);
		
		printf("check netif status\r\n");
		/* Registers the default network interface */
		netif_set_default(&gnetif);

	

		if (netif_is_link_up(&gnetif))
		{
			printf("netif is link up\r\n");
			/* When the netif is fully configured this function must be called 当netif完全配置时,必须调用此函数*/
			netif_set_up(&gnetif);

		}
		else
		{
			printf("netif set down\r\n");
			/* When the netif link is down this function must be called 当netif链接断开时,必须调用这个函数*/
			netif_set_down(&gnetif);

		}		



  /* Set the link callback function, this function is called on change of link status 设置链接回调函数,当链接状态改变时调用该函数*/
  netif_set_link_callback(&gnetif, ethernetif_update_config);

  /* create a binary semaphore used for informing ethernetif of frame reception 创建一个二进制信号量,用于通知ethernetif接收帧*/
  Netif_LinkSemaphore = osSemaphoreNew(1, 1, NULL);

  link_arg.netif = &gnetif;
  link_arg.semaphore = Netif_LinkSemaphore;
  /* Create the Ethernet link handler thread */
/* USER CODE BEGIN OS_THREAD_NEW_CMSIS_RTOS_V2 */
  memset(&attributes, 0x0, sizeof(osThreadAttr_t));
  attributes.name = "LinkThr";
  attributes.stack_size = INTERFACE_THREAD_STACK_SIZE;
  attributes.priority = osPriorityBelowNormal;
  osThreadNew(ethernetif_set_link, &link_arg, &attributes);
/* USER CODE END OS_THREAD_NEW_CMSIS_RTOS_V2 */

dhcp_start(&gnetif);

/* USER CODE BEGIN 3 */
	return 1;
/* USER CODE END 3 */
}

其中
netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, &ethernetif_init, &tcpip_input);
是添加了网卡,并调用了ethernetif_init初始化ETH

if (netif_is_link_up(&gnetif))
这个函数可以知道网线的插拔状态

netif_set_link_callback(&gnetif, ethernetif_update_config);
这个函数,设置了一个回调函数,在网线状态变化时会调用ethernetif_update_config

而ethernetif_update_config函数,最终会调用
__weak void ethernetif_notify_conn_changed(struct netif *netif)
我们在ethernetif_notify_conn_changed函数内加入以下内容,实现网线插拔的处理

__weak void ethernetif_notify_conn_changed(struct netif *netif)
{
  /* NOTE : This is function could be implemented in user file
            when the callback is needed,
  */
	
	//以下自己添加的
	  printf("*** netif changed");
	
		if (netif_is_link_up(netif))
		{
			printf("netif is link up\r\n");
			/* When the netif is fully configured this function must be called 当netif完全配置时,必须调用此函数*/
			netif_set_up(netif);

		}
		else
		{
			printf("netif set down\r\n");
			/* When the netif link is down this function must be called 当netif链接断开时,必须调用这个函数*/
			netif_set_down(netif);

		}		
}

上电若未插网线就执行DHCP,将无法获取到IP
dhcp_start(&gnetif);

我们要做的是,增加一个判断,将dhcp_start(&gnetif);改为:

	while(1)  //等待网线插上了再开始DHCP
	{
		if (netif_is_link_up(&gnetif))
		{
			dhcp_start(&gnetif);
			break;
		}	
		osDelay(1000);	
    printf("Wait for the cable to be plugged in...\r\n");	
	}

这样,网线插上后,才会执行dhcp_start(&gnetif),可以解决第一个问题。

解决第二个问题的方法是,创造2个状态的读取,让应用程序知道网线是否断开了,执行重连操作

//这个函数可以知道,目前IP是否已经获取到了
int IP_Get_Ok()
{
	if(ip_addr_cmp(&(gnetif.ip_addr),&ipaddr))
	{
		return 0;
	}
	else
		return 1;
}


//这个函数可以知道当前网线是否插着
int Cable_Is_Plugged_In()
{
	if (netif_is_link_up(&gnetif))
	{
		return 1;
	}
	else
		return 0;

}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值