使用lwip的人有发现什么bug么?
我按照焦海波写的《uC/OS-II平台下LwIP移植笔记》移植了1.30版的LwIP.以太网芯片是DM9000A。发现用TCP接收和发送数据,运行一段时间后系统就死掉了。原因是操作系统的任务数据结构的参数被修改了,只剩下一个任务在运行了
其它的任务都不调度了。这个死掉的时间有长又短。有时候一天都没事,有时候一会就挂掉了。实在是摸不着头脑。
有人遇到过么? 90% 是某地方数组越界! 可是我自己提供的代码里就没有使用数组呀。难道这是LwIP的硬伤?
好像别人也出现了类似的现象 我的RT-Thread + LwIP on STM32,用的dm9000a,基本上调得比较稳定了,tcp echo 50万个包跑下来没什么问题
现在在做1k大小的包,5ms间隔自动发送,打算放一个晚上看看效果如何,已经跑了1个小时了。 我用的是ucosII+lwip,网络芯片是RTL819AS,lwip用的是1.3.0版本。通过网络不停的发送接收数据测试,运行较长时间后,PC软件发送数据给ucosII+lwip的系统,系统接收不到数据,不知道是什么问题?深入调试,发现出错时程序停在Api_lib.c文件的
netconn_recv()函数内调用的函数sys_arch_mbox_fetch(),有人有碰到这种情况吗? sys_arch_mbox_fetch()这个是移植时提供的,估计是没移植好
后来的TCP测试跑了9个小时,要上班就关机了。 4楼的,你看看sys_arch_mbox_fetch()函数是不是每次都取到了一个空指针。
我的是tcpip.c文件的tcpip_thread(void *arg)线程调用函数sys_mbox_fetch(mbox,(void *)&msg);每次都取到一个空指针。
这显然有错误,因为并没有任何地方给它发消息。
查明原因是调度器已经停止调度了。导致这个函数等待消息时,没有消息也直接返回了。
正确的时候应该是没有消息时直接切换到别的任务。 知道原因,但不知道是哪个地方导致这个结果的。
猜测是有某个地方内存访问越界了。
导致系统的任务TCB结构被修改了。
好像每次都是修改最高优先级的任务的TCB的堆栈指针.却死在tcpip_thread(void *arg)线程。因为切到这个线程之后就再也切不出去了 PZLPDY,换RT-Thread吧
不会有调度器的问题,有内存越界也容易查,还有就是现在整了个RTI组件,会对LwIP继续优化(通过RTI,发现LwIP中在使用RTOS时确实有些地方做得比较RZ,打算把一些patch发给LwIP了,有所取则有所贡献),希望这些patch能够融合到下一版的LwIP正式发布中。 to ffxz.早就想改用RT-Thread了。但是迫于这个项目是升级以前的老版本。就是把原来的串口改成以太网。其他的地方不动。
要改用RT-Thread的话改动量太大了。另外老板给的时间也比较少(因为要参加招标),要熟悉RT-GUI的使用也得要段时间,操作系统已经很熟悉了,没什么可说的。
所以我想以后全新的项目启用RT-Thread。这个老项目只能采取求稳的策略,继续用UCOS+UCGUI了,时间不允许呀。
另外我的LWIP有时候能测到200多万个包没问题,就是有时候突然就挂了。
再调几天找不出问题我就直接用ucTCP/IP了。 你可以换一种策略,在RT-Thread基础上实现一套ucos --> RT-Thread的转换层,这样速度就快了。UCGUI开始转不过来,可以先继续沿用它的,其他的换成RT-Thread的。
或者我有时间提供一套ucos --> RT-Thread的转换包给你?不过关键是时间上,是否来得及,因为有了转换包,测试肯定是需要的 谢谢ffxz,时间只剩下两星期。估计够呛。 还好啦,ucos和rtt差别不大的,无非就是几个api接口不一样了。 回5楼,我是测试了一个星期多才出现接收不到数据的。你估计是没移植好,我将sys_arch_mbox_fetch()函数代码贴出来,你看看是否哪里有问题?谢谢!
u32_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u32_t timeout)
{
u8_t ucErr;
u32_t ucos_timeout;
u32_t start;
void *data;
//in lwip ,timeout ismillisecond
//in ucosII ,timeout is timertick!
//chang timeout from millisecond to ucos tick
ucos_timeout = 0;
if(timeout != 0){
ucos_timeout = (timeout * OS_TICKS_PER_SEC)/1000;
if(ucos_timeout < 1)
ucos_timeout = 1;
else if(ucos_timeout > 65535)
ucos_timeout = 65535;
}
start = OSTimeGet();
data = OSQPend( mbox->pQ, (u16_t)ucos_timeout, &ucErr );
if( ucErr == OS_TIMEOUT ) {
timeout = SYS_ARCH_TIMEOUT;
} else {
//单位转换,从ucos tick->ms
timeout = (OSTimeGet() - start)*(1000/ OS_TICKS_PER_SEC);
//timeout = 1;
if(msg)
{
if(data == (void*)&pvNullPointer )
*msg = NULL;
else
*msg = data;
}
}
return timeout;
} 回6楼,应不是每次都收到空指针,我有将“if( ucErr == OS_TIMEOUT )”修改为“if( (ucErr != OS_NO_ERR) || (data == (void *)0))”对空指针作为超时判断,并没有能解决问题。你说“查明原因是调度器已经停止调度了”,我有对每个任务都进行监听,出错时除了调用recv()函数的任务处于“停”在recv()函数退不出来,其他的网络任务和ucos任务仍然在执行的。但是网络任务控制和udp查找都不能执行了,这些任务都有调用到recv()函数。还没找到原因,继续测试 奇怪了,我的为啥会出现这种现象呢。我自己写的函数也没有不可重入得地方呀! 现在调试的现象是指向lwip的底层,不过个人觉得可能是哪里移植出错了,虽然不排除应用程序还有bug,但是现在没有方向,难道要吃透底层代码?还请高手指点迷津! 我觉得是底层的问题不大。是底层的问题就相当好调了。 楼主,能把源码发我参考下吗?先谢谢了。邮箱:seasonpplp@163.com 回复【楼主位】PZLPDY
-----------------------------------------------------------------------
楼主问题解决了么? 回复【19楼】eworker
回复【楼主位】pzlpdy
-----------------------------------------------------------------------
楼主问题解决了么?
----------------------------------------------------------------------- u32_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u32_t timeout)
{
u8_t ucErr;
u32_t ucos_timeout;
u32_t start;
void *data;
//in lwip ,timeout ismillisecond
//in ucosII ,timeout is timertick!
//chang timeout from millisecond to ucos tick
ucos_timeout = 0;
if(timeout != 0){
ucos_timeout = (timeout * OS_TICKS_PER_SEC)/1000;
if(ucos_timeout < 1)
ucos_timeout = 1;
else if(ucos_timeout > 65535)
ucos_timeout = 65535;
}
start = OSTimeGet();
data = OSQPend( mbox->pQ, (u16_t)ucos_timeout, &ucErr );
if( ucErr == OS_TIMEOUT ) {
timeout = SYS_ARCH_TIMEOUT;
} else {
//单位转换,从ucos tick->ms
timeout = (OSTimeGet() - start)*(1000/ OS_TICKS_PER_SEC);
//timeout = 1;
if(msg)
{
if(data == (void*)&pvNullPointer )
*msg = NULL;
else
*msg = data;
}
}
return timeout;
}
/** Wait for a new message to arrive in the mbox
* @param mbox mbox to get a message from
* @param msg pointer where the message is stored
* @param timeout maximum time (in milliseconds) to wait for a message
* @return time (in milliseconds) waited for a message, may be 0 if not waited
or SYS_ARCH_TIMEOUT on timeout
* The returned time has to be accurate to prevent timer jitter! */
其实 准确点的是这样的 不要endless 这个超时了需要返回的 不是sem_wait那个wait forever
u32_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u32_t timeout)
{
u8_t ucErr;
u32_t ucos_timeout;
u32_t start;
void *data;
//in lwip ,timeout ismillisecond
//in ucosII ,timeout is timertick!
//chang timeout from millisecond to ucos tick
ucos_timeout = 3;//
if(timeout != 0){
ucos_timeout = (timeout * OS_TICKS_PER_SEC)/1000;
if(ucos_timeout < 1)
ucos_timeout = 1;
else if(ucos_timeout > 65535)
ucos_timeout = 65535;
}
start = OSTimeGet();
data = OSQPend( mbox->pQ, (u16_t)ucos_timeout, &ucErr );
if( ucErr == OS_TIMEOUT ) {
timeout = SYS_ARCH_TIMEOUT;
} else {
//单位转换,从ucos tick->ms
timeout = (OSTimeGet() - start)*(1000/ OS_TICKS_PER_SEC);
//timeout = 1;
if(msg)
{
if(data == (void*)&pvNullPointer )
*msg = NULL;
else
*msg = data;
}
}
return timeout;
} 我的是这样的测试还行
u32_t sys_arch_mbox_fetch (sys_mbox_t *box, void **msg, u32_t timeout)
{
sys_mbox_t mbox = *box;
u32_t startTick = OSTimeGet();
u32_t endTick;
u32_t ElapseTime;
u8_t ucErr;
if (timeout != 0) {
timeout = (timeout * OS_TICKS_PER_SEC) / 1000;
if (timeout < 1) {
timeout = 1;
} else if(timeout > 65535) {
timeout = 65535;
}
} else {
timeout = 3;
}
if (msg != NULL) {
*msg = OSQPend( mbox->pQ, (u16_t)timeout, &ucErr);
// if (*msg == (void*)&pvNullPointer) {
// *msg = NULL;
// }
} else {
OSQPend(mbox->pQ,(u16_t)timeout, &ucErr); //just discard return value if msg==NULL
}
if ( ucErr == OS_ERR_TIMEOUT ) {
return SYS_ARCH_TIMEOUT;
} else {
if (*msg == (void*)&pvNullPointer ) {
*msg = NULL;
}
endTick = OSTimeGet();
ElapseTime = ((endTick - startTick) * 1000) / OS_TICKS_PER_SEC;
}
return ElapseTime;
} 我也遇到同样的问题了,MARK一下 mark!~ ffxz 发表于 2009-12-6 23:40 static/image/common/back.gif
我的RT-Thread + LwIP on STM32,用的dm9000a,基本上调得比较稳定了,tcp echo 50万个包跑下来没什么问题
...
我用客户端的时候,发现重连就连接不上,状态是9,是不是哪里要设置才可以重新连接 我也正在做这块的移植,关注一下! linliangqiu 发表于 2012-4-7 11:06 static/image/common/back.gif
我用客户端的时候,发现重连就连接不上,状态是9,是不是哪里要设置才可以重新连接 ...
要把lwip用好还是需要花一定精力的,有的时候又需要平衡性能与资源占用,蛮繁琐蛮花时间的。 ffxz 发表于 2012-4-7 11:53 static/image/common/back.gif
要把lwip用好还是需要花一定精力的,有的时候又需要平衡性能与资源占用,蛮繁琐蛮花时间的。 ...
我的QQ是305514512,能不能请教下TCP你是如何配置的? 关注一下! {:shy:}看帖要回帖
页:
[1]