OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 7590|回复: 11

STM32F429 ucosIII+LWIP1.4.1不稳定

[复制链接]

33

主题

197

帖子

0

精华

高级会员

Rank: 4

积分
587
金钱
587
注册时间
2015-1-9
在线时间
80 小时
发表于 2017-4-29 23:29:46 | 显示全部楼层 |阅读模式
10金钱
如题。裸机的LWIP没有这个问题,加上操作系统就出现了这个问题。

具体情况是:STM32F429+DP8S848.开发板做服务器。
用网口调试助手建立TCP连接之后,不断收发数据一上午没问题,但是一旦网口调试助手主动断开连接,程序必然卡死。

有人遇到过类似的情况吗?
到哪里可以看到LWIP的调试经验呢?
目前我虽然能打印出LWIP的调试信息,但是对于代码结构原理和TCP/IP协议了解太少,不知从何下手。







最佳答案

查看完整内容[请看2#楼]

我通过下面的代码暂时解决了问题,这个写法是参考一个别人分享的代码。 至于为什么用q->len==28 && q->flags == 0 && q->type == 20做判断条件我也不知,是通过实验得到的。 [mw_shl_code=applescript,true] while(1) { accept_err=netconn_accept(conn,&newconn); if (newconn) { struct netbuf *inbuf; char* buf; u16_t buflen; ...
君子性非异也,善假于物也
不知常,妄作,凶
纵浪大化中,不喜亦不惧,应尽便须尽,无复独多虑
路漫漫其修远兮,吾将上下而求索
菩萨畏因,凡夫畏果
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

33

主题

197

帖子

0

精华

高级会员

Rank: 4

积分
587
金钱
587
注册时间
2015-1-9
在线时间
80 小时
 楼主| 发表于 2017-4-29 23:29:47 | 显示全部楼层
我通过下面的代码暂时解决了问题,这个写法是参考一个别人分享的代码。
至于为什么用q->len==28 && q->flags == 0 && q->type == 20做判断条件我也不知,是通过实验得到的。
[mw_shl_code=applescript,true]     while(1)
      {
        accept_err=netconn_accept(conn,&newconn);
      if (newconn)
        {
            struct netbuf *inbuf;
            char* buf;
            u16_t buflen;
             while(netconn_recv(newconn, &inbuf) == ERR_OK)
             {
                                                                        recv_err=ERR_OK;
                                                                        //sys_arch_protect();//½øÈëÁÙ½çÇø
                                                                        for(q=inbuf->p;q!=NULL;q=q->next)  //±éÀúÍêÕû¸öpbufÁ´±í
                                                                        {                                                                       
                                                                                if(q->len==28 && q->flags == 0 && q->type == 20)
                                                                                        {
                                                                                                recv_err=ERR_CONN;
                                                                                                //printf("\r\n q->flags=%d ,q->ref=%d ,q->type=%d\r\n",q->flags,q->ref,q->type);
                                                                                                break;
                                                                                        }//ÔÝʱ½â¾öTCP¶Ï¿ªÁ¬½ÓËÀ»úµÄÎÊÌâ2015-8-17@zzh
                                                                        }

                                                                        //sys_arch_protect();//Í˳öÁÙ½çÇø         
                                                                                if(recv_err < ERR_ISCONN)//&#212;&#221;&#202;±&#189;&#226;&#190;&#246;TCP&#182;&#207;&#191;&#170;&#193;&#172;&#189;&#211;&#203;&#192;&#187;ú&#181;&#196;&#206;&#202;&#204;&#226;2015-8-17@zzh
                                                                                {
                                                                                        netbuf_delete(inbuf);
                                                                                        netconn_close(newconn);       
                                                                                        netconn_delete(newconn);
                                                                                        printf("\r\n ·&#254;&#206;&#241;&#198;÷&#182;&#207;&#191;&#170;&#193;&#172;&#189;&#211; \r\n");
                                                                                        break;
                                                                                }
                                                                                else
                                                                                {
                                                                                        do
                                                                                                {       
                                                                                                        netbuf_data(inbuf, (void**)&buf, &buflen);
                                                                                                        commandbuf[0]=*buf;
                                                                                                        commandbuf[1]=*(buf+1);
                                                                                                        ETH_receive_Handle(commandbuf,buflen);
                                                                                                        netconn_write(newconn, buf, buflen, NETCONN_COPY);
                                                                                                }
                                                                                                while (netbuf_next(inbuf) >= 0);
                                                                                               
                                                                                                //netconn_close(newconn);
                                                                                                netbuf_delete(inbuf);
                                                                                        }
               
             }
              netconn_close(newconn);
              netconn_delete(newconn);
        }
      }[/mw_shl_code]
君子性非异也,善假于物也
不知常,妄作,凶
纵浪大化中,不喜亦不惧,应尽便须尽,无复独多虑
路漫漫其修远兮,吾将上下而求索
菩萨畏因,凡夫畏果
回复

使用道具 举报

33

主题

197

帖子

0

精华

高级会员

Rank: 4

积分
587
金钱
587
注册时间
2015-1-9
在线时间
80 小时
 楼主| 发表于 2017-4-30 18:47:17 | 显示全部楼层
Capture.PNG
我在硬件错误中断中加了串口打印,结果发现一旦我的网口调试助手主动断开连接,程序就进入hard fault

君子性非异也,善假于物也
不知常,妄作,凶
纵浪大化中,不喜亦不惧,应尽便须尽,无复独多虑
路漫漫其修远兮,吾将上下而求索
菩萨畏因,凡夫畏果
回复

使用道具 举报

5

主题

277

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1522
金钱
1522
注册时间
2014-5-16
在线时间
217 小时
发表于 2017-4-30 18:55:15 | 显示全部楼层
跟踪TCP的FIN状态,便可知哪里出了问题
另外,在进入HardFault中断后,查看调用栈,或许会有有用的信息.
回复

使用道具 举报

33

主题

197

帖子

0

精华

高级会员

Rank: 4

积分
587
金钱
587
注册时间
2015-1-9
在线时间
80 小时
 楼主| 发表于 2017-5-1 06:25:12 | 显示全部楼层
zmingwang 发表于 2017-4-30 18:55
跟踪TCP的FIN状态,便可知哪里出了问题
另外,在进入HardFault中断后,查看调用栈,或许会有有用的信息.

多谢你,我试试,昨晚不小心睡着了
君子性非异也,善假于物也
不知常,妄作,凶
纵浪大化中,不喜亦不惧,应尽便须尽,无复独多虑
路漫漫其修远兮,吾将上下而求索
菩萨畏因,凡夫畏果
回复

使用道具 举报

33

主题

197

帖子

0

精华

高级会员

Rank: 4

积分
587
金钱
587
注册时间
2015-1-9
在线时间
80 小时
 楼主| 发表于 2017-5-1 22:03:04 | 显示全部楼层
[mw_shl_code=applescript,true]/*$PAGE*/
/*
************************************************************************************************************************
*                                                 POST TO A SEMAPHORE
*
* Description: This function signals a semaphore
*
* Arguments  : p_sem    is a pointer to the semaphore
*
*              opt      determines the type of POST performed:
*
*                           OS_OPT_POST_1            POST to a single waiting task
*                           OS_OPT_POST_ALL          POST to ALL tasks that are waiting on the semaphore
*
*                           OS_OPT_POST_NO_SCHED     Do not call the scheduler
*
*                           Note(s): 1) OS_OPT_POST_NO_SCHED can be added with one of the other options.
*
*              ts       is a timestamp indicating when the post occurred.
*
*              p_err    is a pointer to a variable that will contain an error code returned by this function.
*
*                           OS_ERR_NONE          The call was successful and the semaphore was signaled.
*                           OS_ERR_OBJ_PTR_NULL  If 'p_sem' is a NULL pointer.
*                           OS_ERR_OBJ_TYPE      If 'p_sem' is not pointing at a semaphore
*                           OS_ERR_SEM_OVF       If the post would cause the semaphore count to overflow.
*
* Returns    : The current value of the semaphore counter or 0 upon error.
*
* Note(s)    : This function is INTERNAL to uC/OS-III and your application should not call it.
************************************************************************************************************************
*/

OS_SEM_CTR  OS_SemPost (OS_SEM  *p_sem,
                        OS_OPT   opt,
                        CPU_TS   ts,
                        OS_ERR  *p_err)
{
    OS_OBJ_QTY     cnt;
    OS_SEM_CTR     ctr;
    OS_PEND_LIST  *p_pend_list;
    OS_PEND_DATA  *p_pend_data;
    OS_PEND_DATA  *p_pend_data_next;
    OS_TCB        *p_tcb;
    CPU_SR_ALLOC();



    CPU_CRITICAL_ENTER();
    p_pend_list = &p_sem->PendList;
    if (p_pend_list->NbrEntries == (OS_OBJ_QTY)0) {         /* Any task waiting on semaphore?                         */
        switch (sizeof(OS_SEM_CTR)) {
            case 1u:
                 if (p_sem->Ctr == DEF_INT_08U_MAX_VAL) {
                     CPU_CRITICAL_EXIT();
                    *p_err = OS_ERR_SEM_OVF;
                     return ((OS_SEM_CTR)0);
                 }
                 break;

            case 2u:
                 if (p_sem->Ctr == DEF_INT_16U_MAX_VAL) {
                     CPU_CRITICAL_EXIT();
                    *p_err = OS_ERR_SEM_OVF;
                     return ((OS_SEM_CTR)0);
                 }
                 break;

            case 4u:
                 if (p_sem->Ctr == DEF_INT_32U_MAX_VAL) {
                     CPU_CRITICAL_EXIT();
                    *p_err = OS_ERR_SEM_OVF;
                     return ((OS_SEM_CTR)0);
                 }
                 break;

            default:
                 break;
        }
        p_sem->Ctr++;                                       /* No                                                     */
        ctr       = p_sem->Ctr;
        p_sem->TS = ts;                                     /* Save timestamp in semaphore control block              */
        CPU_CRITICAL_EXIT();
       *p_err     = OS_ERR_NONE;
        return (ctr);
    }

    OS_CRITICAL_ENTER_CPU_EXIT();
    if ((opt & OS_OPT_POST_ALL) != (OS_OPT)0) {             /* Post message to all tasks waiting?                     */
        cnt = p_pend_list->NbrEntries;                      /* Yes                                                    */
    } else {
        cnt = (OS_OBJ_QTY)1;                                /* No                                                     */
    }
    p_pend_data = p_pend_list->HeadPtr;
    while (cnt > 0u) {
        p_tcb            = p_pend_data->TCBPtr;
        p_pend_data_next = p_pend_data->NextPtr;
        OS_Post((OS_PEND_OBJ *)((void *)p_sem),
                p_tcb,
                (void      *)0,
                (OS_MSG_SIZE)0,
                ts);
        p_pend_data = p_pend_data_next;
        cnt--;
    }
    ctr = p_sem->Ctr;
                printf("\r\n point 1 \r\n");
    OS_CRITICAL_EXIT_NO_SCHED();
                printf("\r\n point 2 \r\n");
    if ((opt & OS_OPT_POST_NO_SCHED) == (OS_OPT)0) {
        OSSched();                                          /* Run the scheduler                                      */
    }
   *p_err = OS_ERR_NONE;
    return (ctr);
}[/mw_shl_code]

我通过跟踪代码发现每次都卡死在OS_CRITICAL_EXIT_NO_SCHED();这一句。
如下图:建立TCP连接之后每次收发数据都会打出两组 point 1  point 2
可是只要网口调试助手主动断开连接,就会出现下面所示    point2没打出来就进入hardfault了。
Capture.PNG
君子性非异也,善假于物也
不知常,妄作,凶
纵浪大化中,不喜亦不惧,应尽便须尽,无复独多虑
路漫漫其修远兮,吾将上下而求索
菩萨畏因,凡夫畏果
回复

使用道具 举报

33

主题

197

帖子

0

精华

高级会员

Rank: 4

积分
587
金钱
587
注册时间
2015-1-9
在线时间
80 小时
 楼主| 发表于 2017-5-1 22:06:18 | 显示全部楼层
zmingwang 发表于 2017-4-30 18:55
跟踪TCP的FIN状态,便可知哪里出了问题
另外,在进入HardFault中断后,查看调用栈,或许会有有用的信息.

请看一下第5楼,我找到了导致卡死的语句,但还是想不通。
仿真调试我没用过,上网查了一下方法都不详细,能否详细说一下,我手边只有ST-LINK可以吗?
君子性非异也,善假于物也
不知常,妄作,凶
纵浪大化中,不喜亦不惧,应尽便须尽,无复独多虑
路漫漫其修远兮,吾将上下而求索
菩萨畏因,凡夫畏果
回复

使用道具 举报

5

主题

277

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1522
金钱
1522
注册时间
2014-5-16
在线时间
217 小时
发表于 2017-5-1 23:26:23 | 显示全部楼层
XUZJWWSZ 发表于 2017-5-1 22:06
请看一下第5楼,我找到了导致卡死的语句,但还是想不通。
仿真调试我没用过,上网查了一下方法都不详细 ...

STLINK当然是可以在线调试的,你就在线调试,出fault之后看看调用栈,应该可以发现问题点
另外注意,你的ucos是否移植正确
再一个,检查是否在中断中调用了不能调用的API函数
回复

使用道具 举报

33

主题

197

帖子

0

精华

高级会员

Rank: 4

积分
587
金钱
587
注册时间
2015-1-9
在线时间
80 小时
 楼主| 发表于 2017-5-2 17:08:37 | 显示全部楼层
zmingwang 发表于 2017-5-1 23:26
STLINK当然是可以在线调试的,你就在线调试,出fault之后看看调用栈,应该可以发现问题点
另外注意,你的uco ...


我上面的分析不可靠,后来用在线调试发现程序总是死在服务器进程里:
360截图20170502171929240.jpg
我觉得很可能是这种情况。
360截图20170502171341876.jpg
但是如果是这种情况该怎么避免呢?
原贴地址:http://www.openedv.com/posts/list/55903.htm


360截图20170502171834889.jpg
君子性非异也,善假于物也
不知常,妄作,凶
纵浪大化中,不喜亦不惧,应尽便须尽,无复独多虑
路漫漫其修远兮,吾将上下而求索
菩萨畏因,凡夫畏果
回复

使用道具 举报

33

主题

197

帖子

0

精华

高级会员

Rank: 4

积分
587
金钱
587
注册时间
2015-1-9
在线时间
80 小时
 楼主| 发表于 2017-5-2 17:32:02 | 显示全部楼层
另外我在官方FREE RTOS + LWIP的例程中找到一个开发板做服务器的例子:
用这个代码每次TCP客户端发送一组数据,作为服务器的开发板收到数据原样返回,然后它自己就主动断开连接了!这种情况下也不存在卡死的情况了
我试着把主动断开连接的代码删掉,然后问题依旧。
[mw_shl_code=applescript,true]void another_server_netconn_thread(void *arg)
{
         struct netconn *conn, *newconn;
  err_t err, accept_err;
  
  /* Create a new TCP connection handle */
  conn = netconn_new(NETCONN_TCP);
  
  if (conn!= NULL)
  {
    /* Bind to port 80 (HTTP) with default IP address */
    err = netconn_bind(conn, NULL, 1032);
   
    if (err == ERR_OK)
    {
      /* Put the connection into LISTEN state */
      netconn_listen(conn);
  
      while(1)
      {
        /* accept any icoming connection */
        accept_err = netconn_accept(conn, &newconn);
        if(accept_err == ERR_OK)
        {
          /* serve connection */
          http_server_serve(newconn);

          /* delete connection */
          netconn_delete(newconn);
        }
      }
    }
    else
    {
      /* delete connection */
      netconn_delete(newconn);
      printf("can not bind netconn");
    }
  }
  else
  {
    printf("can not create netconn");
  }

}[/mw_shl_code][mw_shl_code=applescript,true]void http_server_serve(struct netconn *conn)
{
  struct netbuf *inbuf;
  err_t recv_err;
  char* buf;
  u16_t buflen;
  struct fs_file * file;
  
下面这段代码被我简化了,原本是发送网页的程序。
  /* Read the data from the port, blocking if nothing yet there.
   We assume the request (the part we care about) is in one netbuf */
  recv_err = netconn_recv(conn, &inbuf);
  
  if (recv_err == ERR_OK)
  {
    if (netconn_err(conn) == ERR_OK)
    {
                        netbuf_data(inbuf, (void**)&buf, &buflen);
                        netconn_write(conn,&buf,buflen,NETCONN_NOCOPY);
    }
  }
  /* Close the connection (server closes in HTTP) */
  netconn_close(conn);
  
  /* Delete the buffer (netconn_recv gives us ownership,
   so we have to make sure to deallocate the buffer) */
  netbuf_delete(inbuf);
}[/mw_shl_code]
君子性非异也,善假于物也
不知常,妄作,凶
纵浪大化中,不喜亦不惧,应尽便须尽,无复独多虑
路漫漫其修远兮,吾将上下而求索
菩萨畏因,凡夫畏果
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165426
金钱
165426
注册时间
2010-12-1
在线时间
2113 小时
发表于 2017-5-4 22:35:36 | 显示全部楼层
XUZJWWSZ 发表于 2017-5-3 23:22
我通过下面的代码暂时解决了问题,这个写法是参考一个别人分享的代码。
至于为什么用q->len==28 && q->fla ...

谢谢分享
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

33

主题

197

帖子

0

精华

高级会员

Rank: 4

积分
587
金钱
587
注册时间
2015-1-9
在线时间
80 小时
 楼主| 发表于 2017-5-6 13:45:46 | 显示全部楼层

感谢开源电子网。
君子性非异也,善假于物也
不知常,妄作,凶
纵浪大化中,不喜亦不惧,应尽便须尽,无复独多虑
路漫漫其修远兮,吾将上下而求索
菩萨畏因,凡夫畏果
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-4-9 01:56

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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