rt-thread通过TCP连接(网络+shell)方式调用list_if()导致网络断开的问题分析

论坛 期权论坛 编程之家     
选择匿名的用户   2021-6-2 16:17   1194   0

1.平常我们都是用串口的方式通过rt-thread的finish来调试,但是在遇到串口不够用或者板子没有焊串口。我们就需要通过网络+finish的方式来调试板子。但是在调试板子的时候发现通过通过TCP连接方式调用list_if()的时候,网络出现挂掉。现像是ping不通。

2.原因分析:后面查看list_if()的代码发现有这么一个代码:

void list_if(void)
{
    rt_ubase_t index;
    struct netif * netif;

    //rt_enter_critical();//进入临界断,调用锁

    netif = netif_list;

    while( netif != RT_NULL )
    {
        rt_kprintf("network interface: %c%c%s\n",
                   netif->name[0],
                   netif->name[1],
                   (netif == netif_default)?" (Default)":"");
        rt_kprintf("MTU: %d\n", netif->mtu);
        rt_kprintf("MAC: ");
        for (index = 0; index < netif->hwaddr_len; index ++)
            rt_kprintf("%02x ", netif->hwaddr[index]);
        rt_kprintf("\nFLAGS:");
        if (netif->flags & NETIF_FLAG_UP) rt_kprintf(" UP");
        else rt_kprintf(" DOWN");
        if (netif->flags & NETIF_FLAG_LINK_UP) rt_kprintf(" LINK_UP");
        else rt_kprintf(" LINK_DOWN");
        if (netif->flags & NETIF_FLAG_DHCP) rt_kprintf(" DHCP");
        if (netif->flags & NETIF_FLAG_POINTTOPOINT) rt_kprintf(" PPP");
        if (netif->flags & NETIF_FLAG_ETHARP) rt_kprintf(" ETHARP");
        if (netif->flags & NETIF_FLAG_IGMP) rt_kprintf(" IGMP");
        rt_kprintf("\n");
        rt_kprintf("ip address: %s\n", ipaddr_ntoa(&(netif->ip_addr)));
        rt_kprintf("gw address: %s\n", ipaddr_ntoa(&(netif->gw)));
        rt_kprintf("net mask  : %s\n", ipaddr_ntoa(&(netif->netmask)));
        rt_kprintf("\r\n");

        netif = netif->next;
    }

#if LWIP_DNS
    {
        struct ip_addr ip_addr;

        for(index=0; index<DNS_MAX_SERVERS; index++)
        {
            ip_addr = dns_getserver(index);
            rt_kprintf("dns server #%d: %s\n", index, ipaddr_ntoa(&(ip_addr)));
        }
    }
#endif /**< #if LWIP_DNS */

    //rt_exit_critical();//出临界段,解锁
}

从上面的代码,我们看到了有两处屏蔽的地方是进入临界段和出临界段被屏蔽了,如果打开这两处。当我们通过TCP连接的方式通过finish调用list_if()函数的时候,一进list_if()函数,则马上调用锁,这时候调度被锁住了。但是我们TCP是发送的需要接收的,这时候可能导致没有正确的跑到解锁的位置,没有成功解锁,从而导致被锁住,线程没有办法正常调度。这样就导致网络死掉。解决办法,把list_if()函数的锁与解锁两处屏蔽掉,就可以正常使用了。【 [RealTouch例程]TCP/IP网络组件Lwip之telnet远程命令行交互】在没有关闭代码上面两处,也可以正常的list_if(),不会出现网络死掉的情况。

但是上面这个方法会导致另外一个问题发生,就是没有这个锁”rt_enter_critical();“可能会导致netif这个链表可能在这个过程中加入新的,或者某个netif被删除了。

这个BUG已经提交到rt-thread上面,最终解决方案以他们为准,希望大家可以关注下rt-thread的更新。

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP