PZLPDY 发表于 2009-12-4 18:17:27

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

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

tick 发表于 2009-12-4 19:26:18

90% 是某地方数组越界!

PZLPDY 发表于 2009-12-4 21:21:14

可是我自己提供的代码里就没有使用数组呀。难道这是LwIP的硬伤?
好像别人也出现了类似的现象

ffxz 发表于 2009-12-6 23:40:31

我的RT-Thread + LwIP on STM32,用的dm9000a,基本上调得比较稳定了,tcp echo 50万个包跑下来没什么问题

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

jacky2056 发表于 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(),有人有碰到这种情况吗?

ffxz 发表于 2009-12-7 09:08:58

sys_arch_mbox_fetch()这个是移植时提供的,估计是没移植好

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

PZLPDY 发表于 2009-12-7 10:45:21

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

PZLPDY 发表于 2009-12-7 10:49:34

知道原因,但不知道是哪个地方导致这个结果的。
猜测是有某个地方内存访问越界了。
导致系统的任务TCB结构被修改了。
好像每次都是修改最高优先级的任务的TCB的堆栈指针.却死在tcpip_thread(void *arg)线程。因为切到这个线程之后就再也切不出去了

ffxz 发表于 2009-12-7 12:20:52

PZLPDY,换RT-Thread吧

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

PZLPDY 发表于 2009-12-7 13:01:52

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

ffxz 发表于 2009-12-7 13:13:25

你可以换一种策略,在RT-Thread基础上实现一套ucos --> RT-Thread的转换层,这样速度就快了。UCGUI开始转不过来,可以先继续沿用它的,其他的换成RT-Thread的。

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

PZLPDY 发表于 2009-12-8 09:56:22

谢谢ffxz,时间只剩下两星期。估计够呛。

Scanner 发表于 2009-12-9 10:27:12

还好啦,ucos和rtt差别不大的,无非就是几个api接口不一样了。

jacky2056 发表于 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 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;
}

jacky2056 发表于 2009-12-9 11:57:50

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

PZLPDY 发表于 2009-12-9 13:30:28

奇怪了,我的为啥会出现这种现象呢。我自己写的函数也没有不可重入得地方呀!

jacky2056 发表于 2009-12-9 14:14:32

现在调试的现象是指向lwip的底层,不过个人觉得可能是哪里移植出错了,虽然不排除应用程序还有bug,但是现在没有方向,难道要吃透底层代码?还请高手指点迷津!

PZLPDY 发表于 2009-12-9 19:14:56

我觉得是底层的问题不大。是底层的问题就相当好调了。

seasonpplp 发表于 2009-12-15 16:46:26

楼主,能把源码发我参考下吗?先谢谢了。邮箱:seasonpplp@163.com

eworker 发表于 2010-7-29 20:01:02

回复【楼主位】PZLPDY
-----------------------------------------------------------------------

楼主问题解决了么?

eworker 发表于 2010-12-30 22:39:26

回复【19楼】eworker
回复【楼主位】pzlpdy
-----------------------------------------------------------------------
楼主问题解决了么?
-----------------------------------------------------------------------

hnclcj 发表于 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 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;
}

hnclcj 发表于 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;
}

kammari 发表于 2011-3-8 10:21:02

我也遇到同样的问题了,MARK一下

ljt8015 发表于 2011-6-9 22:31:18

mark!~

linliangqiu 发表于 2012-4-7 11:06:39

ffxz 发表于 2009-12-6 23:40 static/image/common/back.gif
我的RT-Thread + LwIP on STM32,用的dm9000a,基本上调得比较稳定了,tcp echo 50万个包跑下来没什么问题
...

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

ljt80158015 发表于 2012-4-7 11:21:56

我也正在做这块的移植,关注一下!

ffxz 发表于 2012-4-7 11:53:29

linliangqiu 发表于 2012-4-7 11:06 static/image/common/back.gif
我用客户端的时候,发现重连就连接不上,状态是9,是不是哪里要设置才可以重新连接 ...

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

linliangqiu 发表于 2012-4-7 23:00:05

ffxz 发表于 2012-4-7 11:53 static/image/common/back.gif
要把lwip用好还是需要花一定精力的,有的时候又需要平衡性能与资源占用,蛮繁琐蛮花时间的。 ...

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

pwwp 发表于 2012-10-20 16:30:43

关注一下!

Hz01800475 发表于 2012-12-14 13:45:26

{:shy:}看帖要回帖
页: [1]
查看完整版本: 使用lwip的人有发现什么bug么?