运行环境:系统RT-thread lwip2.0 mcu: GD32F470
问题描述:先插入网线后启动时以太网联网正常,但先启动,后插入网线时,无法入网。
原因:启动时若未插入网线,以太网初始化失败,虽然开启dhcp,但是无法分配dns及ip地址
解决办法:加入Link状态监测线程,关注网线link的变化,当检测到网线插入后,Link的状态未up,此时重新初始化emac。此时若dhcp开启,等待dhcp分配地址,分配到地址时,internet_state置为up。即可正常上网。
源码:
/*检测网线插入*/
#define LINK_CHECK_STACK_SIZE 256
#define LINK_CHECK_PRIORITY RT_THREAD_PRIORITY_MAX/2
#define LINK_CHECK_TIMESLICE 20
static rt_thread_t tid1 = RT_NULL;
void thread_linkCheck_start(void)
{
/* 初始化线程 thread_ptl_txt,名称是 ptltxt,入口是 thread_ptl_txt_entry */
tid1=rt_thread_create("phy",
eth_link_thread_entry,
RT_NULL,
LINK_CHECK_STACK_SIZE,
LINK_CHECK_PRIORITY,
LINK_CHECK_TIMESLICE);
if(tid1!=RT_NULL)
{
rt_thread_startup(tid1);
}
}
static int GET_PHY_LINKState(uint8_t *linkstate)
{
uint16_t phy_value = 0U;
enet_phy_write_read(ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BSR, &phy_value);
phy_value &= PHY_LINKED_STATUS;
*linkstate = phy_value>0? 1:0;
return (*linkstate);
}
//eth动态监测任务入口函数
static void eth_link_thread_entry(void* parameter)
{
uint8_t u8link_state_now = 0; uint8_t u8link_state = 0;
struct netif* pnetif = gd32_emac_device0.parent.netif;
if (GET_PHY_LINKState(&u8link_state) != RT_TRUE)
{
rt_kprintf("cant load link state\n");
}
if(u8link_state)
{
u8link_state_now = 1;
}
while(1)
{
if (GET_PHY_LINKState(&u8link_state) != RT_TRUE) //检测网线连接
{
// rt_kprintf("cant load link state\n");
}
//网线接入
if((u8link_state == 0)&&(u8link_state_now == 1))
{
u8link_state_now = 0;
eth_device_linkchange(&gd32_emac_device0.parent, RT_FALSE);
LOG_W("link break\n");
}
//网线断开
if((u8link_state == 1)&&(u8link_state_now == 0))
{
u8link_state_now = 1;
//重新配置MAC和DMA
// phy_reset();
gd32_emac_init((rt_device_t)&gd32_emac_device0);
#if !LWIP_DHCP
pnetif->ip_addr = inet_addr(RT_LWIP_IPADDR);
pnetif->gw = inet_addr(RT_LWIP_GWADDR);
pnetif->netmask = inet_addr(RT_LWIP_MSKADDR);
#else
IP4_ADDR(&(pnetif->ip_addr),0,0,0,0);
IP4_ADDR(&(pnetif->netmask),0,0,0,0);
IP4_ADDR(&(pnetif->gw),0,0,0,0);
#endif
//若开启了DHCP,会自动执行
eth_device_linkchange(&gd32_emac_device0.parent, RT_TRUE);
LOG_I("link on\n");
}
rt_thread_mdelay(1000);
}
}