STM32 LWIP连接优化实验

问题描述

  在学习正点原子STM407探索者的网络实验时发现示例代码运行时要求上电前网线必须要接上,而且好像还存在连接后无法热插拔网线的问题。简单实验时没觉得奇怪,但是后来在应用中很多情况上电时我们不可能接着网线,而且无法热插拔也很麻烦。

  LWIP示例原代码中只检测了LWIP初始化时的网络连接状态,如正常网线正常连接,则正常初始化;如未连接网线则无法开启网络。原代吗在LWIP运行过程中也不再对网口状态进行检测,且不具备重启netif的功能,所以没有正常初始化则无法再次连接网络。

LWIP初始化代码

void MX_LWIP_Init(void)
{
  /* IP addresses initialization */
  IP_ADDRESS[0] = 192;
  IP_ADDRESS[1] = 168;
  IP_ADDRESS[2] = 1;
  IP_ADDRESS[3] = 30;
  NETMASK_ADDRESS[0] = 255;
  NETMASK_ADDRESS[1] = 255;
  NETMASK_ADDRESS[2] = 255;
  NETMASK_ADDRESS[3] = 0;
  GATEWAY_ADDRESS[0] = 192;
  GATEWAY_ADDRESS[1] = 168;
  GATEWAY_ADDRESS[2] = 1;
  GATEWAY_ADDRESS[3] = 1;

  /* Initilialize the LwIP stack without RTOS */
  lwip_init();

  /* IP addresses initialization without DHCP (IPv4) */
  IP4_ADDR(&ipaddr, IP_ADDRESS[0], IP_ADDRESS[1], IP_ADDRESS[2], IP_ADDRESS[3]);
  IP4_ADDR(&netmask, NETMASK_ADDRESS[0], NETMASK_ADDRESS[1] , NETMASK_ADDRESS[2], NETMASK_ADDRESS[3]);
  IP4_ADDR(&gw, GATEWAY_ADDRESS[0], GATEWAY_ADDRESS[1], GATEWAY_ADDRESS[2], GATEWAY_ADDRESS[3]);

  /* add the network interface (IPv4/IPv6) without RTOS */
  netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, &ethernetif_init, &ethernet_input);

  /* Registers the default network interface */
  netif_set_default(&gnetif);

  if (netif_is_link_up(&gnetif))
  {
    /* When the netif is fully configured this function must be called */
    netif_set_up(&gnetif);
  }
  else
  {
    /* When the netif link is down this function must be called */
    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 the Ethernet link handler thread */
}

原代码的LWIP并未检测网口状体,如果突然断开连接并无恢复或者提示机制
LWIP运行代码

void MX_LWIP_Process(void)
{
  ethernetif_input(&gnetif);
  /* Handle timeouts */
  sys_check_timeouts()}

解决方法

  针对上述问题,在基本的LWIP连接示例代码中增加网口检测代码,如此我们可以知晓网络状态依次随时调整LWIP的设置以保证网络的稳定。

1.网口状态读取

DP83848_ReadPHY为STM连接的PHY芯片寄存器读取函数,通过寄存器变化可以知道网线连接的状态。

//代码放初始化MX_LWIP_Init函数中的netif_is_link_up检测函数后,添加的这部分代码为物理层的检测。
//初始化时确定实际连接状态
RJ45state1=DP83848_ReadPHY(1)&PHY_LINKED_STATUS;
if(RJ45state1) //Check the network cable status after initialization
{
   StateMachine_IP=1; //network work
}
else
{ 
  StateMachine_IP=2; // No network cable needs to check
}
  

2.网口检测函数

按照图示流程去检测网络
在这里插入图片描述
函数对应的代码如下,该函数添加在LWIP运行代码中运行

void netcheck()
{
   if(StateMachine_IP==2 && netcheck_1s==1) //check net
   {
	 netcheck_1s=0;
     RJ45state1=DP83848_ReadPHY(1)&PHY_LINKED_STATUS;
     HAL_Delay(50);
     RJ45state2=DP83848_ReadPHY(1)&PHY_LINKED_STATUS;
     if((RJ45state1&RJ45state2)==PHY_LINKED_STATUS)
     {
         Reset_network();
         printf("network recovery\r\n");
         StateMachine_IP=1;	
     }
 }

3.网口重起函数

掉线或者初始化不成功都可以调用该函数重启网络

void Reset_network() //Allow active Settings
{
   IP4_ADDR(&ipaddr, IP_ADDRESS[0], IP_ADDRESS[1], IP_ADDRESS[2], IP_ADDRESS[3]);
   IP4_ADDR(&netmask, NETMASK_ADDRESS[0], NETMASK_ADDRESS[1] , NETMASK_ADDRESS[2], NETMASK_ADDRESS[3]);
   IP4_ADDR(&gw, GATEWAY_ADDRESS[0], GATEWAY_ADDRESS[1], GATEWAY_ADDRESS[2], GATEWAY_ADDRESS[3]);
   printf("静态IP地址........................%d.%d.%d.%d\r\n",IP_ADDRESS[0], IP_ADDRESS[1], IP_ADDRESS[2], IP_ADDRESS[3]);
   printf("子网掩码..........................%d.%d.%d.%d\r\n",NETMASK_ADDRESS[0], NETMASK_ADDRESS[1] , NETMASK_ADDRESS[2], NETMASK_ADDRESS[3]);
   printf("默认网关..........................%d.%d.%d.%d\r\n",GATEWAY_ADDRESS[0], GATEWAY_ADDRESS[1], GATEWAY_ADDRESS[2], GATEWAY_ADDRESS[3]);
   netif_set_down(&gnetif);
   
   netif_set_gw(&gnetif, &gw);//Reloading the IP
   netif_set_netmask(&gnetif, &netmask);
   netif_set_ipaddr(&gnetif, &ipaddr);
  
   netif_set_up(&gnetif);
   printf("Restarting the NIC\r\n");     
}

实验结果

初始化时无需接网线并且可以热插拔网线,基于该实验代码还可以实现IP地址的修改等功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

伊丽莎白鹅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值