搜索
bottom↓
回复: 30

使用lwip的人有发现什么bug么?

[复制链接]

出0入0汤圆

发表于 2009-12-4 18:17:27 | 显示全部楼层 |阅读模式
我按照焦海波写的《uC/OS-II平台下LwIP移植笔记》移植了1.30版的LwIP.以太网芯片是DM9000A。
发现用TCP接收和发送数据,运行一段时间后系统就死掉了。原因是操作系统的任务数据结构的参数被修改了,只剩下一个任务在运行了
其它的任务都不调度了。这个死掉的时间有长又短。有时候一天都没事,有时候一会就挂掉了。实在是摸不着头脑。
有人遇到过么?

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2009-12-4 19:26:18 | 显示全部楼层
90% 是某地方数组越界!

出0入0汤圆

 楼主| 发表于 2009-12-4 21:21:14 | 显示全部楼层
可是我自己提供的代码里就没有使用数组呀。难道这是LwIP的硬伤?
好像别人也出现了类似的现象

出0入0汤圆

发表于 2009-12-6 23:40:31 | 显示全部楼层
我的RT-Thread + LwIP on STM32,用的dm9000a,基本上调得比较稳定了,tcp echo 50万个包跑下来没什么问题

现在在做1k大小的包,5ms间隔自动发送,打算放一个晚上看看效果如何,已经跑了1个小时了。

出0入0汤圆

发表于 2009-12-7 08:37:26 | 显示全部楼层
我用的是ucosII+lwip,网络芯片是RTL819AS,lwip用的是1.3.0版本。通过网络不停的发送接收数据测试,运行较长时间后,PC软件发送数据给ucosII+lwip的系统,系统接收不到数据,不知道是什么问题?深入调试,发现出错时程序停在Api_lib.c文件的
netconn_recv()函数内调用的函数sys_arch_mbox_fetch(),有人有碰到这种情况吗?

出0入0汤圆

发表于 2009-12-7 09:08:58 | 显示全部楼层
sys_arch_mbox_fetch()这个是移植时提供的,估计是没移植好

后来的TCP测试跑了9个小时,要上班就关机了。

出0入0汤圆

 楼主| 发表于 2009-12-7 10:45:21 | 显示全部楼层
4楼的,你看看sys_arch_mbox_fetch()函数是不是每次都取到了一个空指针。
我的是tcpip.c文件的tcpip_thread(void *arg)线程调用函数sys_mbox_fetch(mbox,(void *)&msg);每次都取到一个空指针。
这显然有错误,因为并没有任何地方给它发消息。
查明原因是调度器已经停止调度了。导致这个函数等待消息时,没有消息也直接返回了。
正确的时候应该是没有消息时直接切换到别的任务。

出0入0汤圆

 楼主| 发表于 2009-12-7 10:49:34 | 显示全部楼层
知道原因,但不知道是哪个地方导致这个结果的。
猜测是有某个地方内存访问越界了。
导致系统的任务TCB结构被修改了。
好像每次都是修改最高优先级的任务的TCB的堆栈指针.却死在tcpip_thread(void *arg)线程。因为切到这个线程之后就再也切不出去了

出0入0汤圆

发表于 2009-12-7 12:20:52 | 显示全部楼层
PZLPDY,换RT-Thread吧

不会有调度器的问题,有内存越界也容易查,还有就是现在整了个RTI组件,会对LwIP继续优化(通过RTI,发现LwIP中在使用RTOS时确实有些地方做得比较RZ,打算把一些patch发给LwIP了,有所取则有所贡献),希望这些patch能够融合到下一版的LwIP正式发布中。

出0入0汤圆

 楼主| 发表于 2009-12-7 13:01:52 | 显示全部楼层
to ffxz.早就想改用RT-Thread了。但是迫于这个项目是升级以前的老版本。就是把原来的串口改成以太网。其他的地方不动。
要改用RT-Thread的话改动量太大了。另外老板给的时间也比较少(因为要参加招标),要熟悉RT-GUI的使用也得要段时间,操作系统已经很熟悉了,没什么可说的。
所以我想以后全新的项目启用RT-Thread。这个老项目只能采取求稳的策略,继续用UCOS+UCGUI了,时间不允许呀。
另外我的LWIP有时候能测到200多万个包没问题,就是有时候突然就挂了。
再调几天找不出问题我就直接用ucTCP/IP了。

出0入0汤圆

发表于 2009-12-7 13:13:25 | 显示全部楼层
你可以换一种策略,在RT-Thread基础上实现一套ucos --> RT-Thread的转换层,这样速度就快了。UCGUI开始转不过来,可以先继续沿用它的,其他的换成RT-Thread的。

或者我有时间提供一套ucos --> RT-Thread的转换包给你?不过关键是时间上,是否来得及,因为有了转换包,测试肯定是需要的

出0入0汤圆

 楼主| 发表于 2009-12-8 09:56:22 | 显示全部楼层
谢谢ffxz,时间只剩下两星期。估计够呛。

出0入0汤圆

发表于 2009-12-9 10:27:12 | 显示全部楼层
还好啦,ucos和rtt差别不大的,无非就是几个api接口不一样了。

出0入0汤圆

发表于 2009-12-9 11:46:54 | 显示全部楼层
回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 is  millisecond
    //in ucosII ,timeout is timer  tick!
    //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;
}

出0入0汤圆

发表于 2009-12-9 11:57:50 | 显示全部楼层
回6楼,应不是每次都收到空指针,我有将“if( ucErr == OS_TIMEOUT )”修改为“if( (ucErr != OS_NO_ERR) || (data == (void *)0))”对空指针作为超时判断,并没有能解决问题。你说“查明原因是调度器已经停止调度了”,我有对每个任务都进行监听,出错时除了调用recv()函数的任务处于“停”在recv()函数退不出来,其他的网络任务和ucos任务仍然在执行的。但是网络任务控制和udp查找都不能执行了,这些任务都有调用到recv()函数。还没找到原因,继续测试

出0入0汤圆

 楼主| 发表于 2009-12-9 13:30:28 | 显示全部楼层
奇怪了,我的为啥会出现这种现象呢。我自己写的函数也没有不可重入得地方呀!

出0入0汤圆

发表于 2009-12-9 14:14:32 | 显示全部楼层
现在调试的现象是指向lwip的底层,不过个人觉得可能是哪里移植出错了,虽然不排除应用程序还有bug,但是现在没有方向,难道要吃透底层代码?还请高手指点迷津!

出0入0汤圆

 楼主| 发表于 2009-12-9 19:14:56 | 显示全部楼层
我觉得是底层的问题不大。是底层的问题就相当好调了。

出0入0汤圆

发表于 2009-12-15 16:46:26 | 显示全部楼层
楼主,能把源码发我参考下吗?先谢谢了。邮箱:seasonpplp@163.com

出0入0汤圆

发表于 2010-7-29 20:01:02 | 显示全部楼层
回复【楼主位】PZLPDY
-----------------------------------------------------------------------

楼主问题解决了么?

出0入0汤圆

发表于 2010-12-30 22:39:26 | 显示全部楼层
回复【19楼】eworker
回复【楼主位】pzlpdy  
-----------------------------------------------------------------------
楼主问题解决了么?
-----------------------------------------------------------------------

出0入0汤圆

发表于 2011-2-24 22:33:54 | 显示全部楼层
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 is  millisecond  
    //in ucosII ,timeout is timer  tick!  
    //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 is  millisecond  
    //in ucosII ,timeout is timer  tick!  
    //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;
}

出0入0汤圆

发表于 2011-2-24 22:35:56 | 显示全部楼层
我的是这样的测试还行
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;
}

出0入0汤圆

发表于 2011-3-8 10:21:02 | 显示全部楼层
我也遇到同样的问题了,MARK一下

出0入0汤圆

发表于 2011-6-9 22:31:18 | 显示全部楼层
mark!~

出0入0汤圆

发表于 2012-4-7 11:06:39 | 显示全部楼层
ffxz 发表于 2009-12-6 23:40
我的RT-Thread + LwIP on STM32,用的dm9000a,基本上调得比较稳定了,tcp echo 50万个包跑下来没什么问题
...

我用客户端的时候,发现重连就连接不上,状态是9,是不是哪里要设置才可以重新连接

出0入0汤圆

发表于 2012-4-7 11:21:56 | 显示全部楼层
我也正在做这块的移植,关注一下!

出0入0汤圆

发表于 2012-4-7 11:53:29 | 显示全部楼层
linliangqiu 发表于 2012-4-7 11:06
我用客户端的时候,发现重连就连接不上,状态是9,是不是哪里要设置才可以重新连接 ...

要把lwip用好还是需要花一定精力的,有的时候又需要平衡性能与资源占用,蛮繁琐蛮花时间的。

出0入0汤圆

发表于 2012-4-7 23:00:05 | 显示全部楼层
ffxz 发表于 2012-4-7 11:53
要把lwip用好还是需要花一定精力的,有的时候又需要平衡性能与资源占用,蛮繁琐蛮花时间的。 ...

我的QQ是305514512,能不能请教下TCP你是如何配置的?

出0入0汤圆

发表于 2012-10-20 16:30:43 | 显示全部楼层
关注一下!

出0入0汤圆

发表于 2012-12-14 13:45:26 | 显示全部楼层
看帖要回帖
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 08:07

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表