rt-thread通过TCP连接(网络+shell)方式调用list_if()导致网络断开的问题分析
2015-01-31 23:03
866 查看
1.平常我们都是用串口的方式通过rt-thread的finish来调试,但是在遇到串口不够用或者板子没有焊串口。我们就需要通过网络+finish的方式来调试板子。但是在调试板子的时候发现通过通过TCP连接方式调用list_if()的时候,网络出现挂掉。现像是ping不通。
2.原因分析:后面查看list_if()的代码发现有这么一个代码:
从上面的代码,我们看到了有两处屏蔽的地方是进入临界段和出临界段被屏蔽了,如果打开这两处。当我们通过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的更新。
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的更新。
相关文章推荐
- 关于ip_conntrack跟踪连接满导致网络丢包问题的分析
- 关于ip_conntrack跟踪连接满导致网络丢包问题的分析
- ICMP Redirect 报文导致TCP连接建立不起来的问题分析...
- 关于ip_conntrack跟踪连接满导致网络丢包问题的分析
- php通过exec调用shell命令导致乱码问题
- ICMP Redirect 报文导致TCP连接建立不起来的问题分析...
- ***套接字连接已中止。这可能是由于处理消息时出错或远程主机超过接收超时或者潜在的网络资源问题导致的
- C#调用斑马打印机打印条码标签(支持COM、LPT、USB、TCP连接方式和ZPL、EPL、CPCL指令)
- 检测TCP非正常断开连接 SO_KEEPALIVE 使用缺陷分析
- WCF 套接字连接已中止。这可能是由于处理消息时出错或远程主机超过接收超时或者潜在的网络资源问题导致的
- 解决PCoIP连接View 5.0虚拟桌面超时断开导致无法再次登录的问题
- 【WCF】 套接字连接已中止。这可能是由于处理消息时出错或远程主机超过接收超时或者潜在的网络资源问题导致的。本地套接字超时是“00:00:56.9810000”。
- 通过hibernate session.connection()获得数据库连接时,导致的查询缓慢甚至假死机问题
- TCP 连接断开问题剖析
- 分析C++方式构造函数调用虚函数的问题
- Windows XPSP3通过网络级身份验证方式连接Windows Server 2008远程桌面
- 检测TCP非正常断开连接 SO_KEEPALIVE 使用缺陷分析
- 解决PCoIP连接View 5.0虚拟桌面超时断开导致无法再次登录的问题
- 检测TCP非正常断开连接 SO_KEEPALIVE 使用缺陷分析
- .net WCF 套接字连接中断,可能是由于消息处理错误,或者远程宿主接受超时引起,或者是底层网络资源问题导致,本地套接字时间