OpenEdv-开源电子网

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

STM32F7+FreeRTOS+LWIP UDP通信不定期失败

[复制链接]

6

主题

47

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2017-4-15
在线时间
12 小时
发表于 2021-4-12 09:35:40 | 显示全部楼层 |阅读模式
1金钱
您好,各位大佬朋友们!
目前小弟在用正点原子STM32F767 + FreeRTOS +LWIP 调试UDP以及TCP服务器端。。
1. 系统仅存在UART串口printf,以及ETH。其他外设均无
2. udpTask + tcpTask + DefaultTask(默认执行周期20ms,使用osDelay(20)延时)
3. udpTask任务内仅包含:udp_send函数
4. tcpTask任务无任何内容,只有osDelay(20);
5. default任务无任何内容,只有osDelay(10);

遇到的问题:
1. 移植STM32F7官方udp 例程,初始化等操作。可ping通,然后通过udp接收回调函数,反馈接受的内容实现,收发。
2. udp_send HAL接口,不定期不定时返回-4(概率比较大)偶尔-8,err。此时在windows相关小黄人助手里面看到接收的字节大概为20W左右(17字节一帧,20ms周期)。有些时候会达到300W字节。就开始返回-4.
3. FreeRTSO系统正常运行。ETH 的udp send发送失败。以太网RJ45灯灭。ping不通。

跪求各位大佬给一些建议或者入手查看思路。真的快被逼疯了。

以下附上部分源码:
1. 创建三个Task;
  /* Create the thread(s) */
  /* definition and creation of defaultTask */
  osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128);
  defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);

  /* USER CODE BEGIN RTOS_THREADS */
    /* definition and creation of myTaskLED */
  osThreadDef(udpTaskA, udpTask, osPriorityIdle, 0, 1024);
  UDPTaskHandle = osThreadCreate(osThread(udpTaskA), NULL);

  /* definition and creation of myTaskTCP */
  osThreadDef(tcpTaskB, tcpTask, osPriorityIdle, 0, 512);
  TCPServerHandle = osThreadCreate(osThread(tcpTaskB), NULL);
  /* USER CODE END RTOS_THREADS */


2.  UDP发送任务
void udpTask(void const * argument)
{
        UINT8 tempA = 0xFF;
        UINT8 i = 0;
       
        udp_echoserver_init();
       
        printf("UDP Task ok \n");
       
        /* Infinite loop */
        for(;;)
        {
       
                //CheckNaviMessagePacket(&naviMessage,sizeof(naviMessage));
                UDPSendMessage(NULL,sizeof(NS_CtrlInfo_t));
       
                osDelay(20);
        }
        /* USER CODE END LEDTask */

}
3. 回调函数
void udp_echoserver_receive_callback(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, UINT16 port)
{
  /* Connect to the remote client */
  udp_connect(upcb, addr, UDP_CLIENT_PORT);

  /*GetNaviMessage(&p->payload,p->len);*/
  memset(recdata,0,sizeof(recdata));
  memcpy((char *)recdata,p->payload,p->len);
  /* Tell the client that we have accepted it */
  udp_send(upcb, p);

  /* free the UDP connection, so we can accept new clients */
  udp_disconnect(upcb);

  /* Free the p buffer */
  pbuf_free(p);

}


4. 实际udpTask发送内容

void UDPSendMessage(UINT8 *ptrMsg, UINT8 Len)
{
        UINT8 srcIP[4] = {192,168,12,99};
        err_t ret;
        struct pbuf *ptr;
       
        ptr=pbuf_alloc(PBUF_TRANSPORT,strlen((char*)recdata),PBUF_POOL); //申请内存

        if(ptr)
        {
                udp_connect(udpTaskPCB, srcIP, UDP_CLIENT_PORT);
                ptr->payload=(void*)recdata;
                ptr->len = sizeof(recdata);
                ret = udp_send(udpTaskPCB,ptr);        //udp发送数据
                udp_disconnect(udpTaskPCB);
                pbuf_free(ptr);//释放内存

                printf("Ret %d \n",ret);
        }
}


5. udp初始化
void udp_echoserver_init(void)
{

        err_t err;

        /* Create a new UDP control block  */
        udpTaskPCB = udp_new();  //创建一个新的UDP控制块

        if (udpTaskPCB)
        {
                /* Bind the udpTaskPCB to the UDP_PORT port */
                /* Using IP_ADDR_ANY allow the udpTaskPCB to be used by any local interface */
                err = udp_bind(udpTaskPCB, IP_ADDR_ANY, UDP_SERVER_PORT);   //绑定本地IP地址及端口

                if(err == ERR_OK)
                {
                        /* Set a receive callback for the upcb */
                        udp_recv(udpTaskPCB, udp_echoserver_receive_callback, NULL);   //注册接收数据回调函数
                }
                else
                {
                        udp_remove(udpTaskPCB);
                        printf("can not bind pcb");
                }
        }
        else
        {
                printf("can not create pcb");
        }
}


跪求各位大佬给指点!!!!!!!!谢谢~!!!!!!


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

6

主题

47

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2017-4-15
在线时间
12 小时
 楼主| 发表于 2021-4-12 09:36:13 | 显示全部楼层
回复

使用道具 举报

6

主题

890

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1477
金钱
1477
注册时间
2020-8-19
在线时间
335 小时
发表于 2021-4-12 09:54:18 | 显示全部楼层
帮顶!!!!
回复

使用道具 举报

6

主题

47

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2017-4-15
在线时间
12 小时
 楼主| 发表于 2021-4-12 09:55:21 | 显示全部楼层

谢谢!!!!!!
回复

使用道具 举报

6

主题

47

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2017-4-15
在线时间
12 小时
 楼主| 发表于 2021-4-12 13:18:19 | 显示全部楼层
自己顶啊。。。
回复

使用道具 举报

0

主题

11

帖子

0

精华

新手上路

积分
47
金钱
47
注册时间
2019-11-15
在线时间
7 小时
发表于 2021-4-12 14:49:40 | 显示全部楼层
4. 实际udpTask发送内容

void UDPSendMessage(UINT8 *ptrMsg, UINT8 Len)
{
        UINT8 srcIP[4] = {192,168,12,99};
        err_t ret;
        struct pbuf *ptr;
      
        ptr=pbuf_alloc(PBUF_TRANSPORT,strlen((char*)recdata),PBUF_POOL); //申请内存

        if(ptr)
        {
                udp_connect(udpTaskPCB, srcIP, UDP_CLIENT_PORT);
                ptr->payload=(void*)recdata;
                ptr->len = sizeof(recdata);
                ret = udp_send(udpTaskPCB,ptr);        //udp发送数据
                udp_disconnect(udpTaskPCB);
                pbuf_free(ptr);//释放内存

                printf("Ret %d \n",ret);
        }
}

这个函数实际是20ms执行一次,里面会有连接,断开的操作,实际IP连接不需要这么频繁的吧,有没有可能是这里的问题?
回复

使用道具 举报

6

主题

47

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2017-4-15
在线时间
12 小时
 楼主| 发表于 2021-4-12 15:00:17 | 显示全部楼层
shao0129 发表于 2021-4-12 14:49
4. 实际udpTask发送内容

void UDPSendMessage(UINT8 *ptrMsg, UINT8 Len)

这个conn和disconn我删除尝试过。但是没有影响出故障。。。。和这个地方关系不是很大。。。。
回复

使用道具 举报

0

主题

11

帖子

0

精华

新手上路

积分
47
金钱
47
注册时间
2019-11-15
在线时间
7 小时
发表于 2021-4-12 15:17:15 | 显示全部楼层
hanxi0529 发表于 2021-4-12 15:00
这个conn和disconn我删除尝试过。但是没有影响出故障。。。。和这个地方关系不是很大。。。。

那就打断点确认下-4,-8是那里报出来的
回复

使用道具 举报

6

主题

47

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2017-4-15
在线时间
12 小时
 楼主| 发表于 2021-4-12 15:36:54 | 显示全部楼层
shao0129 发表于 2021-4-12 15:17
那就打断点确认下-4,-8是那里报出来的

这个已经确定到出在哪里。
出自于HAL的upd_send API中,
void udp_send()
{

     *********上面省略***************
    udp_sendto();//在这里

}


udp_sendto(struct udp_pcb *pcb, struct pbuf *p,
           const ip_addr_t *dst_ip, u16_t dst_port)
{
     
    ************省略部分***************
  /* no outgoing network interface could be found? */
  if (netif == NULL) {
    LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: No route to "));
    ip_addr_debug_print(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, dst_ip);
    LWIP_DEBUGF(UDP_DEBUG, ("\n"));
    UDP_STATS_INC(udp.rterr);
    return ERR_RTE;
  }

}

回复

使用道具 举报

0

主题

11

帖子

0

精华

新手上路

积分
47
金钱
47
注册时间
2019-11-15
在线时间
7 小时
发表于 2021-4-12 15:51:00 | 显示全部楼层
hanxi0529 发表于 2021-4-12 15:36
这个已经确定到出在哪里。
出自于HAL的upd_send API中,
void udp_send()

netif == NULL就是没有找到路由的IP地址,所以我还是觉得你的连接是不是还是哪里不对。至少你那里主动频繁连接断开,我认为是可以删除的,有错误再尝试重新连接
回复

使用道具 举报

6

主题

47

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2017-4-15
在线时间
12 小时
 楼主| 发表于 2021-4-12 16:04:17 | 显示全部楼层
shao0129 发表于 2021-4-12 15:51
netif == NULL就是没有找到路由的IP地址,所以我还是觉得你的连接是不是还是哪里不对。至少你那里主动频 ...

目前已经删除这个频繁链接,已更改:

void UDPSendMessage(UINT8 *ptrMsg, UINT8 Len)
{
        err_t ret;
        struct pbuf *ptr;       
        ip_addr_t addr;
       
        const char* reply = "http://www.usr.cn\n";

        IP4_ADDR(&addr, 192,168,12,99);
       
        ptr = pbuf_alloc(PBUF_TRANSPORT, strlen(reply)+1, PBUF_RAM);
        if(!ptr)
        {
                printf("out of PBUF_RAM\n");
                return;
        }
       
        memset(ptr->payload, 0 , ptr->len);
        memcpy(ptr->payload, reply, strlen(reply));
       
        ret=udp_sendto(udpTaskPCB, ptr, &addr, 10010);
        pbuf_free(ptr);
        printf("Ret %d \n",ret);

}
回复

使用道具 举报

6

主题

47

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2017-4-15
在线时间
12 小时
 楼主| 发表于 2021-4-12 16:05:23 | 显示全部楼层
shao0129 发表于 2021-4-12 15:51
netif == NULL就是没有找到路由的IP地址,所以我还是觉得你的连接是不是还是哪里不对。至少你那里主动频 ...

一般什么情况会出现这个找不到ip地址,因为我也尝试过,删除con和discon。但是还是会报错-4这个,不定时,但是最长没超过40min,就报错。您看您在指导一下可以么?谢谢!
回复

使用道具 举报

6

主题

47

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2017-4-15
在线时间
12 小时
 楼主| 发表于 2021-4-12 16:06:29 | 显示全部楼层
shao0129 发表于 2021-4-12 15:51
netif == NULL就是没有找到路由的IP地址,所以我还是觉得你的连接是不是还是哪里不对。至少你那里主动频 ...

您可以加我一下联系方式沟通一下嘛?qq 809485914 或者我加您也行!谢谢!
回复

使用道具 举报

6

主题

47

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2017-4-15
在线时间
12 小时
 楼主| 发表于 2021-4-12 16:11:53 | 显示全部楼层
shao0129 发表于 2021-4-12 15:51
netif == NULL就是没有找到路由的IP地址,所以我还是觉得你的连接是不是还是哪里不对。至少你那里主动频 ...

删除之后还是报错-4.。。。。。
回复

使用道具 举报

6

主题

47

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2017-4-15
在线时间
12 小时
 楼主| 发表于 2021-4-12 17:06:31 | 显示全部楼层
断点跟进之后,发现ip4_addr_isany_val这个判断不成功,导致失败,返回。
但是实在想不明白,是什么原因能引起这个问题。。。有大佬没有。。。!!!!

struct netif *
ip4_route(const ip4_addr_t *dest)
{
#if !LWIP_SINGLE_NETIF
  struct netif *netif;

  LWIP_ASSERT_CORE_LOCKED();

#if LWIP_MULTICAST_TX_OPTIONS
  /*默认使用管理选择的接口进行多播*/
  if (ip4_addr_ismulticast(dest) && ip4_default_multicast_netif) {
    return ip4_default_multicast_netif;
  }
#endif /* LWIP_MULTICAST_TX_OPTIONS */

  /* bug #54569: in case LWIP_SINGLE_NETIF=1 and LWIP_DEBUGF() disabled, the following loop is optimized away */
  LWIP_UNUSED_ARG(dest);

  /*遍历网卡列表netif_list */
  NETIF_FOREACH(netif) {
    /* 如果网卡已经挂载并且IP地址是有效的 */
    if (netif_is_up(netif) && netif_is_link_up(netif) && !ip4_addr_isany_val(*netif_ip4_addr(netif))) {
      /* 网络掩码匹配? */
      if (ip4_addr_netcmp(dest, netif_ip4_addr(netif), netif_ip4_netmask(netif))) {
        /* 返回找到的网卡netif */
        return netif;
      }
      /* 网关在非广播接口上匹配? (即在点对点接口中对等) */
      if (((netif->flags & NETIF_FLAG_BROADCAST) == 0) && ip4_addr_cmp(dest, netif_ip4_gw(netif))) {
        /* 返回找到的网卡netif */
        return netif;
      }
    }
  }

回复

使用道具 举报

0

主题

11

帖子

0

精华

新手上路

积分
47
金钱
47
注册时间
2019-11-15
在线时间
7 小时
发表于 2021-4-12 20:11:53 | 显示全部楼层
回调函数屏蔽呢?只往外发
回复

使用道具 举报

6

主题

47

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2017-4-15
在线时间
12 小时
 楼主| 发表于 2021-4-13 09:09:47 | 显示全部楼层
shao0129 发表于 2021-4-12 20:11
回调函数屏蔽呢?只往外发

尝试过,还是不可以!感觉和接收没什么关系,就是发送api出现了问题。您看您还有哪些建议指导一下!谢谢!!!
回复

使用道具 举报

6

主题

47

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2017-4-15
在线时间
12 小时
 楼主| 发表于 2021-4-14 10:36:32 | 显示全部楼层
还有人吗????
回复

使用道具 举报

6

主题

47

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2017-4-15
在线时间
12 小时
 楼主| 发表于 2021-4-15 13:10:24 | 显示全部楼层
有人指教一下嘛?
回复

使用道具 举报

6

主题

47

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2017-4-15
在线时间
12 小时
 楼主| 发表于 2021-4-21 16:38:53 | 显示全部楼层
还有人吗?
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-2-28 00:02

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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