LWIP 是否可真的用在产品中呢?
不知道大家是否有真的使用LWIP在产品中。需要注意什么呢?
使用其他商业购买的TCP/IP的STACK的价格非常的昂贵。都是几万美金。这个价格真的吓人啊。如果产品的销售部是很多,用这个什么时候可以收回成本啊。
但是用LWIP作产品,还不知道是不是有真的产品在使用。
大家有了解吗? 在一个串口赚以太网的设备中用了,经过测试基本功能SCOKET 套接 收发数据 WEB 动态域名 ping 等功能大问题没有 “大问题没有” 就是说小问题还是有的了?
都是些什么样子的问题呢? 我想在未来的产品中使用
IP,TCP,UDP,HTTP,AUTOIP,SOCKET,DNS,SNTP等功能。
做控制器的通讯接口。 回复【1楼】SYOK_2001
在一个串口赚以太网的设备中用了,经过测试基本功能scoket 套接 收发数据 web 动态域名 ping 等功能大问题没有
-----------------------------------------------------------------------
这句话很容易被理解为大问题没有,但有小问题。
回复【楼主位】gpfrank
-----------------------------------------------------------------------
UDP应该是没有问题。TCP,很多高手都说有问题。 哦!谢谢!
UDP的应用是最少的应用,处于TCP的基于连接的通讯,是必须使用的。看来在产品中直接使用LWIP 还不行啊!
只能买NICHESTACK了,这个授权的费用真是贵啊,基本包固定CPU,固定操作系统,不固定产品名是20000$, 如果都不固定要80000$。
如果增加个SNTP,HTTP都要在增加费用,每个都是万刀起步。还不知道东西好用不好用。
真是难啊! 回复【5楼】gpfrank
哦!谢谢!
udp的应用是最少的应用,处于tcp的基于连接的通讯,是必须使用的。看来在产品中直接使用lwip 还不行啊!
只能买nichestack了,这个授权的费用真是贵啊,基本包固定cpu,固定操作系统,不固定产品名是20000$, 如果都不固定要80000$。
如果增加个sntp,http都要在增加费用,每个都是万刀起步。还不知道东西好用不好用。
真是难啊!
-----------------------------------------------------------------------
tcp部分可以参考一下rtt,里面有用到lwip,ffxz大侠做过改进。 LwIP TCP的改进还比较少。不过比其他自行移植的lwip会好一些,另外本打算加入的一个tcp datalink还没时间加,这个会在一些极端情况下导致TCP数据反复重发。
lwip在TCP方面确实还存在些小问题,不过如果在自己的代码设计上注意些应该能够避免大部分的情况。 对于lwip这块,如果大家比较担心,可以考虑让我们这边提供相应的技术支持(邮件方式,限于STM32、LM3S、lpc17xx平台)。当然前提是使用RT-Thread及配套的LwIP^-^ 回复【7楼】ffxz
lwip tcp的改进还比较少。不过比其他自行移植的lwip会好一些,另外本打算加入的一个tcp datalink还没时间加,这个会在一些极端情况下导致tcp数据反复重发。
lwip在tcp方面确实还存在些小问题,不过如果在自己的代码设计上注意些应该能够避免大部分的情况。
-----------------------------------------------------------------------
没有看很懂?是准备加入的tcp datalink会在一些极端情况下导致tcp数据反复重发么?另外,代码设计上注意点指的是什么?
曾经用过一个国外的商业化的TCPIP协议栈,反复刷新网页,偶尔也会死掉。 lwip在一些极端的情况下会出现数据反复重复的情况。为了解决这个问题打算加入TCP datalink的策略来改善。
代码设计上:
1. 不要试图一直保持TCP连接;用的时候建立,不用的时候拆掉。
2. 心跳可以采用UDP的方式传送。
3. 设置接收超时;
4. 管理好网络用的buffer。
... 如果还不放心就用W5100协议栈芯片 30多元 既方便有实惠 我在一个产品中用,但是最近一个客户反映机器死机,我们以前没有过,查代码也没看到我们程序卡死的地方(我们插叙没有看门狗),目前还不知道问题所在 回复【12楼】888888888888
-----------------------------------------------------------------------
是说在用LWIP出现了死机?
以前用过一个国外的商业化的TCPIP协议栈,反复刷新网页,偶尔也会死掉。 用过CMX的MICRO-NET的。刷网页一样会死的。
不过后来更改了,当打开后再有请求就不开连接。最后是不死了。不过后果是永远只有一台能远程HTTP配置产品。呵呵!
嵌入式的因为ROM,RAM的限制,服务器不可能做的很强壮,需要增加限制,软件上做一些对策。
就是CMX这种商用的BUG都很多的。上个项目用的CMX的,为了里面的BUG花了不少时间。 等RTT0.4.0版本。再在另一个产品中使用!到时候一并考虑RTT+lwip.不过还要找一个USB的STACK去。呵呵! 对于工控的需求,我们会有一个不大不小的以太网方案,可以留意下。这个方案同样的,寻求稳定性第一!(RT-Thread + LwIP,on AT91SAM7X256) 期待。因为作为工控类产品,可能控制板并不是很贵,但是控制的东西却贵,而且安全系数要求高。
另外就是网络类产品,属于远程控制类的,如果出现问题,对于客户来说其麻烦是非常大的。
我做的网络类产品,有些客户是防止在距离公司非常非常远的地方,通过GSM,GPRS,或3G来连接到中心的,
如果出现问题,到现场去更新,这个费用无论是供应商,还是最终用户都是无法忍受的。尤其是当使用量变大,分散到无数的地方的时候。这个给自己给客户都会带来无限的“痛苦”。
追求功能是一方面,不过质量也是必须的,因为质量是最终客户一直感受的。 回复【12楼】888888888888
我在一个产品中用,但是最近一个客户反映机器死机,我们以前没有过,查代码也没看到我们程序卡死的地方(我们插叙没有看门狗),目前还不知道问题所在
-----------------------------------------------------------------------
有结果了么? 我们已经运用到产品中好几年了!性能还不错!~~~ 回复【19楼】ljt8015
我们已经运用到产品中好几年了!性能还不错!~~~
-----------------------------------------------------------------------
有没有做过改进?有没有碰到过反复刷新网页,导致“死机”问题? 回复【18楼】eworker
回复【12楼】888888888888
我在一个产品中用,但是最近一个客户反映机器死机,我们以前没有过,查代码也没看到我们程序卡死的地方(我们插叙没有看门狗),目前还不知道问题所在
-----------------------------------------------------------------------
有结果了么?
-----------------------------------------------------------------------
加了狗后没有反馈问题,估计正常了 回复【21楼】888888888888
-----------------------------------------------------------------------
也可能是硬件的原因,导致“死机”。 肯定是可以的啦,实际上已经看到很多人(企业)在他们的产品中使用LwIP,也包括用RT-Thread + LwIP的组合来生产的。
总的来说,只要需求不是太变态,用lwip基本上能够满足。 回复【20楼】eworker
回复【19楼】ljt8015
我们已经运用到产品中好几年了!性能还不错!~~~
-----------------------------------------------------------------------
有没有做过改进?有没有碰到过反复刷新网页,导致“死机”问题?
-----------------------------------------------------------------------
没有呢,这个看你应用程序的设计了 回复【24楼】ljt8015
-----------------------------------------------------------------------
有没有对LWIP底层代码做过改进?
应用程序设计有哪些注意点? 我用lwip-1.3.1就发现接收数据速度问题,调用tcp_recved后 1秒多才开始收数据 速度问题应该是跟移植或驱动或应用有关,跟lwip本身应该没有关系。
我现在碰到的问题是在BSD socket基础上,server端应用层经常会收不到client端的断开信号,导致socket一直占用的情况。
现在lwip1.4.0的rc1出来了,还没测试,从changes上看是做了很大的修改,不知道是否还会有这个问题。 关注一下..... 回复【27楼】kanprin
速度问题应该是跟移植或驱动或应用有关,跟lwip本身应该没有关系。
我现在碰到的问题是在bsd socket基础上,server端应用层经常会收不到client端的断开信号,导致socket一直占用的情况。
现在lwip1.4.0的rc1出来了,还没测试,从changes上看是做了很大的修改,不知道是否还会有这个问题。
-----------------------------------------------------------------------
当没有数据发送时,TCP连接突然断掉,按照TCP协议的标准是没有通知机制的。所以,这个其实是无解。
比较可行的办法有:
* 打开LwIP内部的TCP live选项,使得能够相互通知。
* 上层应用自行做心跳以维持连接。
从mbbill的串口以太网转换器来看,测试下来也还好,也相应的进行了多次拔插网线的动作。 关注一下 值得关注啊 回复【29楼】ffxz
回复【27楼】kanprin
速度问题应该是跟移植或驱动或应用有关,跟lwip本身应该没有关系。
我现在碰到的问题是在bsd socket基础上,server端应用层经常会收不到client端的断开信号,导致socket一直占用的情况。
现在lwip1.4.0的rc1出来了,还没测试,从changes上看是做了很大的修改,不知道是否还会有这个问题。
-----------------------------------------------------------------------
当没有数据发送时,tcp连接突然断掉,按照tcp协议的标准是没有通知机制的。所以,这个其实是无解。
比较可行的办法有:
* 打开lwip内部的tcp live选项,使得能够相互通知。
* 上层应用自行做心跳以维持连接。
从mbbill的串口以太网转换器来看,测试下来也还好,也相应的进行了多次拔插网线......
-----------------------------------------------------------------------
我是通过keep alive实现的,隔3秒一个keep alive包,重复三次。业内一板这种转换器的keep alive都比较短,默认的7200秒太久了。
话说关于lwip我倒是做过一些比较暴力的测试,只有上次说的那种比较特殊的情况被我搞出问题来了,其他时候都挺稳定的。 回复【32楼】mbbill
-----------------------------------------------------------------------
在哪个帖子中有提到“上次说的那种比较特殊的情况”? 在官网论坛那边 回复【34楼】ffxz
在官网论坛那边
-----------------------------------------------------------------------
是rtt的官网么?是哪个帖子,没有找到? 回复【35楼】eworker
-----------------------------------------------------------------------
顶 回复【36楼】eworker
回复【35楼】eworker
-----------------------------------------------------------------------
顶
-----------------------------------------------------------------------
这个问题我这段时间会修复掉,不用着急找了 是下面帖子么?
搞死LWIP的方法
RT-Thread核心开发、使用讨论
版主: bernard
发表回复4 篇帖子 • 分页: 1 / 1
搞死LWIP的方法
由 mbbill » 2010年 4月 18日 03:29
lwip的netconn有一个缺陷,它的tcp window和输入缓冲区没有直接联系,输入的数据是以pbuf的形式存放在conn->recvmbox里面的,这个mbox尺寸是10,这个size和缓冲区的大小无关,只是数据包的数量。
现在假设TCP_WND是1024,网络端快速发过来几十个1字节的数据包,这时候上面的mbox就会很快溢出,溢出的第一个包在pcb->refused_data里面会缓存一下,不过这个能力也很有限,等pcb->refused_data也存不下了这个pbuf就被直接丢弃了。这是在TCP_WND还没用完的情况下就丢包了。
更严重一点的情况,如果上面这种状况发生的同时lwip还在向上位机程序发数据的话,之前被丢弃的包很可能同时也是这些数据包的ACK,ACK丢了就会导致lwip向上位机重发这些数据,而上位机这边也在不停的重发(window没用完却丢包了必然会重发),然后两边就互不理睬各发各的。。。最后rst。断开。
这种情况有两个前提,一个是接受速度没那么快,这种情况我觉得还是比较容易发生的,比如一边收网络包一边发送到usart,波特率慢的时候网络接收就会很慢。
还有一个前提是上位机发来大量段数据包,且这些数据包总和x10 < TCP_WND。
目前还没想到很好的办法解决这个问题,加大mbox或者减小window只能稍微缓解一下,只要mbox的size<TCP_WND这个问题都会存在。个人觉得。。。这个问题有点严重,大家帮忙出出主意吧mbbill
帖子: 33
注册: 2009年 12月 20日 03:35 页首
--------------------------------------------------------------------------------
Re: 搞死LWIP的方法
由 bernard » 2010年 4月 18日 07:23
嗯,这个确实是个大问题。
修正下才是,mbox机制需要修改下,改成非mbox机制比较好。
我的邮件地址:
和RT-Thread相关的基础技术问题请在论坛上直接发帖,就不要发信给我啦,谢谢。bernard
帖子: 1362
注册: 2008年 5月 10日 07:22 页首
--------------------------------------------------------------------------------
Re: 搞死LWIP的方法
由 mbbill » 2010年 4月 18日 14:51
这样工作量有点大了
另外这个问题在优化lwip的时候也很可能发生,比如为了提高性能把TCP_BUF和TCP_WND定的比较大,这时候很可能就会发生这种现象,wireshark一抓全都是重发的包。mbbill
帖子: 33
注册: 2009年 12月 20日 03:35 页首
--------------------------------------------------------------------------------
Re: 搞死LWIP的方法
由 bernard » 2010年 4月 18日 16:14
工作量可能还行,可以考虑把mbox更改成数据队列的方式。只是这样的话,那么lwip那边tcp线程确实会修改一些了。这个加上,系能是否会好些呢。
找个时间验证一把。 嗯 这几天我又重审了一下这个问题,产生了一点和之前不同的看法。
上面的帖子里面大致说明了一下问题,我再仔细补充一些。
首先,对于lwip的callback框架来说,每次从netif接收到数据的时候都会去调用相应的回调函数,lwip这一层是没有缓冲的,不管数据来的有多快,只要lwip能从以太网驱动把数据拿来就能通过回调函数送给应用,所以这一层没有上面说的那个问题。
然后在这一层之上lwip提供了netconn api,这一层发送数据是有缓冲区的,会自动处理数据重发之类的事情,事实上netconn结构体也是在tcp_pcb外面包了一层而来。下面问题来了,这一层netconn接收的数据是放在conn->recvmbox里面,这个mbox默认只有10,这个mbox的尺寸和当前连接的tcp window没有直接联系,所以下层的回调函数层的流控到了这里会出一点问题,就像上文所说的状况。
我和之前的不同看法是,如果要修正这个问题,则需要将这个recvmbox改成一个至少不小于tcp window的缓冲区。而且这个缓冲区是每个连接各有一个的,一下子对空闲ram造成了非常大的压力,多一个连接就会多吃掉一个tcp window大小的缓冲。而之前10个mbox只占用40个字节。
所以我想,通过在使用netconn或者更上层的socket api的时候注意一些地方来避开这个问题,做到既不多占用内存也能够避免重发。
避开问题的关键就是防止conn->recvmbox溢出。如果有一段代码像下面这个样子
while(1)
{
length = lwip_recv(socket,buffer,size,0);
blabla(); // 处理数据
lwip_send(...);
}
这里如果blabla()占用时间比较长,就可能导致recvmbox溢出,所以在设计的时候必须让这个部分尽可能没有延迟,比如直接把数据放到缓冲区里面去,交给另一个线程处理数据,然后回到recv函数继续接收。 在一般情况下,假设lwip_recv因为没有数据而阻塞了,conn->recvmbox这个邮箱只要收到邮件,就会立刻唤醒阻塞的recv函数,然后把数据返回。所以在这里只要处理数据足够快,就可以让recvmbox一直保持空着。
用简单的话概括一下指导思想就是,在使用netconn或者更上层的socket api的时候,对于任何一个可能会接收数据的tcp连接,都必须以最快的速度通过recv函数拿走mbox里的数据。如果收慢了,mbox溢出以后连接就会不稳定。
一点题外话,如果按照上面的设计思想,那么很有可能碰到一种情况就是,需要在两个线程里面访问同一个netconn,但是目前netconn是不能在多个线程里面使用的,主要是因为类似recv,send这类函数可能阻塞在同一个semaphore上,也就是conn->op_completed上面。唤醒顺序是没有保证的。 但是有个例外,socket api的select函数可以多个线程同时阻塞,所以可以通过select + mutex互斥来实现对同一个连接的多线程访问,就很容易做到全双工数据收发了。 如果问题出现在这一层,那么针对ucos-ii之类的移植,岂不是死得不是一般的惨。难怪一个个都说,lwip问题多多。 回复【42楼】armecos
不可以
-----------------------------------------------------------------------
楼上杨大侠讲讲原因?据说做机顶盒的泰信用的就是LWIP。 mark 回复【43楼】eworker
回复【42楼】armecos
不可以
-----------------------------------------------------------------------
楼上杨大侠讲讲原因?据说做机顶盒的泰信用的就是lwip。
-----------------------------------------------------------------------
上面其实说了,并不是用lwip就一定有问题,可以通过一些技巧来避免问题出现。
目前rt-thread串口以太网转换器的做法是,加大mbox同时减小tcp window,然后又专门线程负责接收,这样测下来是很稳定的。 mbbill,我觉得把mbox换成data queue关系也不大。首先,这个queue是动态的,并不是说每个连接的queue都要到tcp window的尺寸。只有当这个queue达到了tcp window的尺寸时才停止接收。
但如果每一个连接都需要这么大的尺寸,显然这将进入系统最坏的情况,不过这类情况应该也仅适用于多连接的服务器设备中,既然是多连接服务器了,那么内存占用上应该也不会顾虑太多了。 回复【43楼】eworker
回复【42楼】armecos
不可以
-----------------------------------------------------------------------
楼上杨大侠讲讲原因?据说做机顶盒的泰信用的就是lwip。
-----------------------------------------------------------------------
杨大侠的发言怎么被删了? 这是一个技术交流的平台,讲究有理有据,对漫无目的的冷讽,直接删除。 回复【46楼】ffxz
mbbill,我觉得把mbox换成data queue关系也不大。首先,这个queue是动态的,并不是说每个连接的queue都要到tcp window的尺寸。只有当这个queue达到了tcp window的尺寸时才停止接收。
但如果每一个连接都需要这么大的尺寸,显然这将进入系统最坏的情况,不过这类情况应该也仅适用于多连接的服务器设备中,既然是多连接服务器了,那么内存占用上应该也不会顾虑太多了。
-----------------------------------------------------------------------
嗯,我看看怎么改比较合适。
找到一篇帖子
http://www.mail-archive.com/lwip-users@nongnu.org/msg02940.html 回复【48楼】ffxz
这是一个技术交流的平台,讲究有理有据,对漫无目的的冷讽,直接删除。
-----------------------------------------------------------------------
杨大侠在很多地方推销支持LWIP的ECOS,可能已经做了很多优化和改进。 回复【46楼】ffxz
-----------------------------------------------------------------------
“不过这类情况应该也仅适用于多连接的服务器设备中,既然是多连接服务器了,那么内存占用上应该也不会顾虑太多了。”
加入连接的数据达到16个左右,算不算是多连接服务器呢?这种数量级的时候如何设计RAM呢?
LWIP在开头多说自己使用的ROM,RAM如何的少,其实只是指本身的消耗对吧,但是连接数据上涨后,内存的需求就增加了。这个增加如何计算不是很了解。 回复【51楼】gpfrank
回复【46楼】ffxz
-----------------------------------------------------------------------
“不过这类情况应该也仅适用于多连接的服务器设备中,既然是多连接服务器了,那么内存占用上应该也不会顾虑太多了。”
加入连接的数据达到16个左右,算不算是多连接服务器呢?这种数量级的时候如何设计ram呢?
lwip在开头多说自己使用的rom,ram如何的少,其实只是指本身的消耗对吧,但是连接数据上涨后,内存的需求就增加了。这个增加如何计算不是很了解。
-----------------------------------------------------------------------
netconn占用的ram很恐怖,如果算极限情况的话,哪怕只有10个mbox照样可以填满整个tcpwindow,这个是pbuf占着的堆空间。如果按照1k大小的tcpwindow算,16个连接就占了16k。
而且这是占得堆空间,一旦空间不够,或者碎片太多,底层的网卡驱动就直接罢工了,pbuf申请不到了。连带着甚至整个系统可能都会挂掉。
不过lwip有一个选项可以把这个值可以限制的和tcpwindow不一样大,就是conn->recv_bufsize。 回复【52楼】mbbill
-----------------------------------------------------------------------
谢谢您!我还要实践实践了!
到处找LWIP的资料,但是发现不是移植,就是教大家跑个232转串口,再或者是跑个WEB SERVER. LM3S的232->E还算稳定,有些跑WEB,我连续刷屏都会搞死哪个服务器。
但是这些都是“能用”不代表是可以未来做产品。像您这样能够深入给大家一些内部注意事项的真是太少了。感激啊!
总感觉现在很多人都停留再“能动”的水平上,或者追求大而全上。按照我的老板对我的教育“能动”不等于“产品”。
如果只是“能动”,就作为产品,那么只能叫你们中国人说的“山寨”。所以再审核我设计的产品的时候,他几乎不问我
产品的功能到底实现没实现,因为他知道交给他检查的时候都是基本“能动”的了。他只检查我设计的过程是否有遗漏,错误
处理,安全防范等方面。 是的,确实是这样。
所以我们在RT-Thread的开发上也相应的分了两个版本,稳定系列的0.3.x,冒进系列的0.4.x。web server也有做稳定的,例如当内存比较多的时候用GoAhead Webserver。一款小型的的web server正在我们内部做测试。 回复【53楼】gpfrank
回复【52楼】mbbill
-----------------------------------------------------------------------
谢谢您!我还要实践实践了!
到处找lwip的资料,但是发现不是移植,就是教大家跑个232转串口,再或者是跑个web server. lm3s的232->e还算稳定,有些跑web,我连续刷屏都会搞死哪个服务器。
但是这些都是“能用”不代表是可以未来做产品。像您这样能够深入给大家一些内部注意事项的真是太少了。感激啊!
总感觉现在很多人都停留再“能动”的水平上,或者追求大而全上。按照我的老板对我的教育“能动”不等于“产品”。
如果只是“能动”,就作为产品,那么只能叫你们中国人说的“山寨”。所以再审核我设计的产品的时候,他几乎不问我
产品的功能到底实现没实现,因为他知道交给他检查的时候都是基本“能动”的了。他只检查我设计......
-----------------------------------------------------------------------
是的没错。
我做串口转网络实现功能只花了2个星期时间,然后剩下的所有工作全部都用在稳定性调试上了。一个demo和一个产品完全是两回事。 回复【55楼】mbbill
-----------------------------------------------------------------------
你认为“使用了LWIP的串口转网络”是否达到产品级别? -----------------------------------------------------------------------
一点题外话,如果按照上面的设计思想,那么很有可能碰到一种情况就是,需要在两个线程里面访问同一个netconn,但是目前netconn是不能在多个线程里面使用的,主要是因为类似recv,send这类函数可能阻塞在同一个semaphore上,也就是conn->op_completed上面。唤醒顺序是没有保证的。 但是有个例外,socket api的select函数可以多个线程同时阻塞,所以可以通过select + mutex互斥来实现对同一个连接的多线程访问,就很容易做到全双工数据收发了。
-----------------------------------------------------------------------
请教mbbill问题,你怎么实现“通过select + mutex互斥来实现对同一个连接的多线程访问,就很容易做到全双工数据收发了”能否用代码举个例子说明。
tcp client 一般模式都是“open-read-write-close”模型,而我想实现的tcp client是需要一直处于连接状态,这样server端在任意时候都可以向client要求读取数据,而client也可以主动上送数据,也就你说的做到全双工数据收发。
先谢mbbill了!! 回复【57楼】yanxp
-----------------------------------------------------------------------
一点题外话,如果按照上面的设计思想,那么很有可能碰到一种情况就是,需要在两个线程里面访问同一个netconn,但是目前netconn是不能在多个线程里面使用的,主要是因为类似recv,send这类函数可能阻塞在同一个semaphore上,也就是conn->op_completed上面。唤醒顺序是没有保证的。 但是有个例外,socket api的select函数可以多个线程同时阻塞,所以可以通过select + mutex互斥来实现对同一个连接的多线程访问,就很容易做到全双工数据收发了。
-----------------------------------------------------------------------
请教mbbil......
-----------------------------------------------------------------------
转换器代码就是例子了。 回复【41楼】ffxz
如果问题出现在这一层,那么针对ucos-ii之类的移植,岂不是死得不是一般的惨。难怪一个个都说,lwip问题多多。
-----------------------------------------------------------------------
请问为何针对ucos-ii的移植会死得不是一般惨呢 ?能否简略的分析一下? 谢谢。 回复【59楼】kanprin
-----------------------------------------------------------------------
关注 回复【59楼】kanprin
回复【41楼】ffxz
如果问题出现在这一层,那么针对ucos-ii之类的移植,岂不是死得不是一般的惨。难怪一个个都说,lwip问题多多。
-----------------------------------------------------------------------
请问为何针对ucos-ii的移植会死得不是一般惨呢 ?能否简略的分析一下? 谢谢。
----------------------------------------------------------------------- ding 回复【59楼】kanprin
回复【41楼】ffxz
如果问题出现在这一层,那么针对ucos-ii之类的移植,岂不是死得不是一般的惨。难怪一个个都说,lwip问题多多。
-----------------------------------------------------------------------
请问为何针对ucos-ii的移植会死得不是一般惨呢 ?能否简略的分析一下? 谢谢。
-----------------------------------------------------------------------
关注 LWIP mark mark 看到有人说做server没问题,做client问题很多 帖子协议栈对比图片:
http://cache.amobbs.com/bbs_upload782111/files_35/ourdev_609495FUESO4.jpg
(原文件名:TCPIP.jpg) 请问超时重传是怎么嵌入到协议栈里面的呢? 好讨论!! 回复【67楼】eworker
看到有人说做server没问题,做client问题很多
-----------------------------------------------------------------------
??? mark mark!!! Mark!!! -----------------------------------------------------------------------
回复【40楼】mbbill
.....
这几天我又重审了一下这个问题,产生了一点和之前不同的看法。
上面的帖子里面大致说明了一下问题,我再仔细补充一些。
首先,对于lwip的callback框架来说,每次从netif接收到数据的时候都会去调用相应的回调函数,lwip这一层是没有缓冲的,不管数据来的有多快,只要lwip能从以太网驱动把数据拿来就能通过回调函数送给应用,所以这一层没有上面说的那个问题。
然后在这一层之上lwip提供了netconn api,这一层发送数据是有缓冲区的,会自动处理数据重发之类的事情,事实上netconn结构体也是在tcp_pcb外面包了一层而来。下面问题来了,这一层netconn接收的数据是放在conn->recvmbox里面,这个mbox默认只有10,这个mbox的尺寸和当前连接的tcp window没有直接联系,所以下层的回调函数层的流控到了这里会出一点问题,就像上文所说的状况。
我和之前的不同看法是,如果要修正这个问题,则需要将这个recvmbox改成一个至少不小于tcp window的缓冲区。而且这个缓冲区是每个连接各有一个的,一下子对空闲ram造成了非常大的压力,多一个连接就会多吃掉一个tcp window大小的缓冲。而之前10个mbox只占用40个字节。
所以我想,通过在使用netconn或者更上层的socket api的时候注意一些地方来避开这个问题,做到既不多占用内存也能够避免重发。
避开问题的关键就是防止conn->recvmbox溢出。如果有一段代码像下面这个样子
while(1)
{
length = lwip_recv(socket,buffer,size,0);
blabla(); // 处理数据
lwip_send(...);
}
这里如果blabla()占用时间比较长,就可能导致recvmbox溢出,所以在设计的时候必须让这个部分尽可能没有延迟,比如直接把数据放到缓冲区里面去,交给另一个线程处理数据,然后回到recv函数继续接收。 在一般情况下,假设lwip_recv因为没有数据而阻塞了,conn->recvmbox这个邮箱只要收到邮件,就会立刻唤醒阻塞的recv函数,然后把数据返回。所以在这里只要处理数据足够快,就可以让recvmbox一直保持空着。
用简单的话概括一下指导思想就是,在使用netconn或者更上层的socket api的时候,对于任何一个可能会接收数据的tcp连接,都必须以最快的速度通过recv函数拿走mbox里的数据。如果收慢了,mbox溢出以后连接就会不稳定。
一点题外话,如果按照上面的设计思想,那么很有可能碰到一种情况就是,需要在两个线程里面访问同一个netconn,但是目前netconn是不能在多个线程里面使用的,主要是因为类似recv,send这类函数可能阻塞在同一个semaphore上,也就是conn->op_completed上面。唤醒顺序是没有保证的。 但是有个例外,socket api的select函数可以多个线程同时阻塞,所以可以通过select + mutex互斥来实现对同一个连接的多线程访问,就很容易做到全双工数据收发了。
-----------------------------------------------------------------------
我们的一个产品(采用 ARM7 2468 + FREE RTOS + LWIP)也出现了运行1到3个小时候,出现死机的情况,任务阻塞导致MCU跑死,以至于看门狗复位。 起初也怀疑硬件问题,在运行一段时间后,的确是没有喂狗信号了,导致看门狗复位。(由于无法上传图片这里描述下示波器抓的实际波形)。 也无法确定到底软件那里出了问题,看到mbbill大侠的帖子,对比自己的代码才发现的确存在“recv,send这类函数可能阻塞在同一个semaphore”的情况,于是采用mbbill大侠大侠的的建议,在recv 和send 之间加了信号量。哈哈。问题就解决了。
另外:我们也遇到 conn->recvmbox溢出问题,解决方法如mbbill大侠上面所说,在设计的时候必须让这个部分尽可能没有延迟,比如直接把数据放到缓冲区里面去,交给另一个线程处理数据,然后回到recv函数继续接收。
再次感谢mbbill大侠,及各位大侠提供自己的经验。 好贴,
最近在移植lwip到tnkernel,
基本上是成功了,接下来要实现在lwip上的应用,看了这个觉的帮助很大.
还有个问题,就是用lwip自带的httpd这个来访问它自己的那个网页速度很快,快速的多次刷新也没有问题,但是我在网上下了另外的网页,转换为fsdata.c后访问就变得很慢了,很长时间才能打开,而且不是原来转换前的网页的样子,在wireshark里显示有一些从发的数据包
不知道这个是转换得到的fsdata.c不对还是要按照楼上说的需要对httpd做一定的修改.
等解决了这个问题我再回来和大家分享,如果已经有人解决了就告诉我一下,这样少走弯路
fsdata.c是使用lwip里面提供的脚本makefsdata转换得到的 回复【57楼】yanxp
-----------------------------------------------------------------------
请教mbbill问题,你怎么实现“通过select + mutex互斥来实现对同一个连接的多线程访问,就很容易做到全双工数据收发了”能否用代码举个例子说明。
tcp client 一般模式都是“open-read-write-close”模型,而我想实现的tcp client是需要一直处于连接状态,这样server端在任意时候都可以向client要求读取数据,而client也可以主动上送数据,也就你说的做到全双工数据收发。
先谢mbbill了!!
-----------------------------------------------------------------------
我觉得你的设备应该做成TCP server, 让管理系统作为client连上来。只有管理系统才知道它什么时候需要什么数据,这样它可以随时连接需要的设备获取需要的数据。当然,连接建立后作为TCP-server的设备也可以主动上报数据的。 不知道用raw api有没有特别注意的地方? 回复【78楼】eworker
不知道用raw api有没有特别注意的地方?
-----------------------------------------------------------------------
我在用raw api时,网络请求需要操作某一外设,如果该外设刚好被其它task正在使用,就有可能会把原来那个task的对该外设的操作打断,从中插入网络请求的操作,从而导致异常。 回复【79楼】Elex 阿甘
回复【78楼】eworker
不知道用raw api有没有特别注意的地方?
-----------------------------------------------------------------------
我在用raw api时,网络请求需要操作某一外设,如果该外设刚好被其它task正在使用,就有可能会把原来那个task的对该外设的操作打断,从中插入网络请求的操作,从而导致异常。
-----------------------------------------------------------------------
你说的外设是指什么?如果指串口之类,应该是没有做临界保护造成的,和LWIP没有关系。 回复【80楼】eworker
回复【79楼】elex 阿甘
回复【78楼】eworker
不知道用raw api有没有特别注意的地方?
-----------------------------------------------------------------------
我在用raw api时,网络请求需要操作某一外设,如果该外设刚好被其它task正在使用,就有可能会把原来那个task的对该外设的操作打断,从中插入网络请求的操作,从而导致异常。
-----------------------------------------------------------------------
你说的外设是指什么?如果指串口之类,应该是没有做临界保护造成的,和lwip没有关系。
-----------------------------------------------------------------------------
虽然不是LWIP本身的问题,但也是因为raw function诱发的,所以需要注意。
比如读取I2C 存储器之类, 不会一直占用的,只是偶尔需要的时候才操作一下。做了保护的话保护了原来的操作,新的请求也会因为保护而操作失败。 marklwip 标记下 回复【81楼】Elex 阿甘
-----------------------------------------------------------------------
这是个“慢设备”问题,可以通过缓冲来解决,比如把对设备的操作建立一个队列! 讨论的很火! 回复【76楼】zengeronline
-----------------------------------------------------------------------
TNKERNEL不是有自己的TCPIP协议栈吗?那个写的也还可以啊! 我计划,选择这个协议栈应用,裸跑 MARK 谢谢 mark 我也正在考虑是要用哪一种协议好,我的平台是Nios II。 回复【90楼】loveraul
我也正在考虑是要用哪一种协议好,我的平台是nios ii。
-----------------------------------------------------------------------
Nios II + RT-thread + LWIP markLWIP 回复【81楼】Elex 阿甘
-----------------------------------------------------------------------
这是个“慢设备”问题,可以通过缓冲来解决,比如把对设备的操作建立一个队列!
建立缓冲区事件队列,严重同意,不然到时死得很惨 mark 路过 ffxz 请给个联系方式。 回复【96楼】catman2004
ffxz 请给个联系方式。
-----------------------------------------------------------------------
bernard.xiong@gmail.com 回复【16楼】ffxz
-----------------------------------------------------------------------
有联系方式么,我的QQ:123600562 满世界都是牛人啊,感觉自己太渺小了,努力前进啊 对于tcp 的tx线程和rx线程被信号量阻塞的问题有个简单的办法可以解决。
在lwip的opt.h文件中,有个LWIP_TCPIP_CORE_LOCKING开关,使能就能解决这个问题。
不过注释里面写有非LWIP内部人员禁用的字样,估计是还在调试阶段,而且他们也意识到这个问题了。
页:
[1]
2