lwip eth插拔网线自动维护接口状态

硬件连线就是将dp83848的INT脚连到STM32的某个中断脚上,这里是PB14

PB14的中断处理函数中,会释放一个信号量,这里只是发生链路状态改变中断(网线插上或拔下)

 1 void EXTI15_10_IRQHandler(void)
 2 {
 3   portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
 4   
 5   if(EXTI_GetITStatus(ETH_LINK_EXTI_LINE) != RESET)
 6   {
 7   /* Give the semaphore to wakeup LwIP task */
 8   xSemaphoreGiveFromISR( ETH_link_xSemaphore, &xHigherPriorityTaskWoken ); 
 9   }
10    /* Clear interrupt pending bit */
11    EXTI_ClearITPendingBit(ETH_LINK_EXTI_LINE);
12   
13     /* Switch tasks if necessary. */    
14   if( xHigherPriorityTaskWoken != pdFALSE )
15   {
16     portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
17   }
18 }

该信号量在eth_bsp.c中定义,在ETH_BSP_Config中创建,同时,启动一个Eth_Link_IT_task任务,阻塞在信号量上,侦听链路状态,

 1 xSemaphoreHandle ETH_link_xSemaphore = NULL;
 2 
 3 void ETH_BSP_Config(void)
 4 {
 5   
 6   if (ETH_link_xSemaphore == NULL)
 7   {
 8     /* create binary semaphore used for ETH_link handling */
 9     vSemaphoreCreateBinary( ETH_link_xSemaphore );
10   }
11 
12   /* create the task that handles the ETH_link */
13   xTaskCreate(Eth_Link_IT_task, (signed char*) "E_link", ETH_LINK_TASK_STACK_SIZE, (void *)DP83848_PHY_ADDRESS,
14               ETH_LINK_TASK_PRIORITY,NULL);
15 }

在Eth_Link_IT_task任务中,会读取以太网寄存器,进一步判断链路状态变化的类型,是通还是断,网线插上了还是拔下了,

然后,将网络接口的链路状态设置为up或down。此处,在eth_bsp中引用xnetif有点别扭。。。由于需要读取PHY寄存器,所以,放在这儿了,是不是可以封装一下,由上面调用。。。

 1 void Eth_Link_IT_task( void * pvParameters )
 2 {
 3   uint32_t pcPHYAddress;
 4   
 5   pcPHYAddress = ( uint32_t  ) pvParameters;
 6   
 7   for(;;)
 8   {
 9     if (xSemaphoreTake( ETH_link_xSemaphore, emacBLOCK_TIME_WAITING_ETH_LINK_IT)==pdTRUE)
10     {
11       /* Check whether the link interrupt has occurred or not */
12       if(((ETH_ReadPHYRegister((uint16_t) pcPHYAddress, PHY_MISR)) & PHY_LINK_STATUS) != 0)
13       {
14         if((ETH_ReadPHYRegister((uint16_t) pcPHYAddress, PHY_SR) & 1))
15         {
16           netif_set_link_up(&xnetif);
17         }
18         else
19         {
20           netif_set_link_down(&xnetif);
21         }
22       }
23     }
24   }
25 }

之后,netif_set_link_up里会调用用户挂接的link up down回调函数,该函数也在eth_bsp中,是ETH_link_callback,挂接是在netconf中创建xnetif的时候。

在ETH_link_callback中,

  如果是up,会启动MAC(不知道启动的什么?),设置netif up(是接口up,不是link up);

  如果是down,会停止MAC,设置netif down。

 1 void ETH_link_callback(struct netif *netif)
 2 {
 6   if(netif_is_link_up(netif))
 7   {
 8     /* Restart MAC interface */
 9     ETH_Start();
10 
11     /* When the netif is fully configured this function must be called.*/
12     netif_set_up(&xnetif);    15   }
16   else
17   {
18     ETH_Stop();
19 
20     /*  When the netif link is down this function must be called.*/
21     netif_set_down(&xnetif);24   }
25 }

上面的注释提到,link up down之后,netif up down必须调用,

因为,有些协议,比如arp和nd6,都是在netif down之后,清理arp缓存,nd的前缀、邻居信息的。

猜你喜欢

转载自www.cnblogs.com/yanhc/p/8970551.html