笔记
同事以前的工程,有个bug : 网线掉了之后,再也访问不到了,插上也没用, 只能重启设备。 但是那个工程用的F1/F4的固件库.
现在用STM32CubeMX6.3.0 + ETH + LWIP的HAL库框架代码,可以很方便做这个处理。 可以应对网线在启动前被拔掉,启动后拔掉又插上的情况。不管啥时候插上网线,都能正常进行网络操作。
首先ETH要配置好,试验已经做好了(test STM32F407 ETH RMII)
在LWIP配置时,将网络接口选项(Network interfaces Options)中的3个状态指示回调都勾上。 用CubeMX生成框架后,修改ethernetif_set_link(),加入2句网卡上线和网卡下线调用就可以了。
void ethernetif_set_link(void const *argument)
{
uint32_t regvalue = 0;
struct link_str *link_arg = (struct link_str *)argument;
for(;;)
{
HAL_ETH_ReadPHYRegister(&heth, PHY_BSR, ®value);
regvalue &= PHY_LINKED_STATUS;
if(!netif_is_link_up(link_arg->netif) && (regvalue))
{
netif_set_link_up(link_arg->netif);
netif_set_up(link_arg->netif);
}
else if(netif_is_link_up(link_arg->netif) && (!regvalue))
{
netif_set_link_down(link_arg->netif);
netif_set_down(link_arg->netif);
}
osDelay(200);
}
}
为啥加这2句呢? 因为ethernetif_set_link()只是网络接口的状态变化指示,原有的框架代码,只是标记了网卡是否插上或被拔掉。这里肯定要加一句是网卡生效或失效的代码,那该填啥代码呢?框架工程中总能找到线索吧?e.g. 网卡初始化或LWIP初始化的地方找找。 我在 MX_LWIP_Init() 中找到了疑似代码,试试,好使,就这样。
void MX_LWIP_Init(void)
{
IP_ADDRESS[0] = 192;
IP_ADDRESS[1] = 168;
IP_ADDRESS[2] = 0;
IP_ADDRESS[3] = 100;
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] = 0;
GATEWAY_ADDRESS[3] = 1;
tcpip_init( NULL, NULL );
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]);
netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, ðernetif_init, &tcpip_input);
netif_set_default(&gnetif);
if (netif_is_link_up(&gnetif))
{
netif_set_up(&gnetif);
}
else
{
netif_set_down(&gnetif);
}
netif_set_link_callback(&gnetif, ethernetif_update_config);
osSemaphoreDef(Netif_SEM);
Netif_LinkSemaphore = osSemaphoreCreate(osSemaphore(Netif_SEM) , 1 );
link_arg.netif = &gnetif;
link_arg.semaphore = Netif_LinkSemaphore;
osThreadDef(LinkThr, ethernetif_set_link, osPriorityBelowNormal, 0, configMINIMAL_STACK_SIZE * 2);
osThreadCreate (osThread(LinkThr), &link_arg);
}
|