OpenEdv-开源电子网

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

LWIP UDP发送最多252字节,求指教

[复制链接]

15

主题

47

帖子

0

精华

初级会员

Rank: 2

积分
114
金钱
114
注册时间
2020-3-12
在线时间
23 小时
发表于 2023-3-9 00:27:30 | 显示全部楼层 |阅读模式
1金钱
本帖最后由 liyancao001 于 2023-3-9 17:39 编辑

用的STM32F407ZGT6,然后用CUBE的LWIP,收发500字节数据,结果实测UDP接收没啥问题,发送语句实际只发出去252字节。是需要调整哪个参数呢?今天又用STM32F767的原子开发板测试,先用原子例程,发现最多可以收发1400+字节,而用CUBE的LWIP则只能发送550字节。经过测试发现是PBUF_POOL_BUFSIZE这个宏定义直接影响了结果。
从下面截图可以看到,目前PBUF_POOL_BUFSIZE是592。实际程序中是受TCP_MSS影响,
#define TCP_MSS                         536
如果把这个536改为936,则等同于PBUF_POOL_BUFSIZE为992时,测试发现最大能发出950字节了。
看了下别的帖子,发现应该是分配内存的问题,正常应该是数据超过PBUF_POOL_BUFSIZE时,应该分配多页,但是实际上只给分了1页,导致数据丢失了。
那么怎么才能解决这个问题呢?
原子例程中的pbuf文件跟CUBE的应该不一样版本,差异比较大。没看明白为啥原子例程可以,CUBE就不行。。。

相关代码如下:
  1. void udp_client_send_hex(char *pData,uint16_t len)
  2. {
  3.     struct pbuf *p;
  4.    
  5.     /* 分配缓冲区空间 */
  6.     p = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_POOL);
  7.    
  8.     if (p != NULL)
  9.     {
  10.         /* 填充缓冲区数据 */
  11.         pbuf_take(p, pData, len);

  12.         /* 发送udp数据 */
  13.         udp_send(upcb, p);

  14.         /* 释放缓冲区空间 */
  15.         pbuf_free(p);
  16.     }
  17. }
复制代码
下载.png
  1. struct pbuf *
  2. pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
  3. {
  4.   struct pbuf *p;
  5.   u16_t offset = (u16_t)layer;
  6.   LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc(length=%"U16_F")\n", length));

  7.   switch (type) {
  8.     case PBUF_REF: /* fall through */
  9.     case PBUF_ROM:
  10.       p = pbuf_alloc_reference(NULL, length, type);
  11.       break;
  12.     case PBUF_POOL: {
  13.       struct pbuf *q, *last;
  14.       u16_t rem_len; /* remaining length */
  15.       p = NULL;
  16.       last = NULL;
  17.       rem_len = length;
  18.       do {
  19.         u16_t qlen;
  20.         q = (struct pbuf *)memp_malloc(MEMP_PBUF_POOL);
  21.         if (q == NULL) {
  22.           PBUF_POOL_IS_EMPTY();
  23.           /* free chain so far allocated */
  24.           if (p) {
  25.             pbuf_free(p);
  26.           }
  27.           /* bail out unsuccessfully */
  28.           return NULL;
  29.         }
  30.         qlen = LWIP_MIN(rem_len, (u16_t)(PBUF_POOL_BUFSIZE_ALIGNED - LWIP_MEM_ALIGN_SIZE(offset)));
  31.         pbuf_init_alloced_pbuf(q, LWIP_MEM_ALIGN((void *)((u8_t *)q + SIZEOF_STRUCT_PBUF + offset)),
  32.                                rem_len, qlen, type, 0);
  33.         LWIP_ASSERT("pbuf_alloc: pbuf q->payload properly aligned",
  34.                     ((mem_ptr_t)q->payload % MEM_ALIGNMENT) == 0);
  35.         LWIP_ASSERT("PBUF_POOL_BUFSIZE must be bigger than MEM_ALIGNMENT",
  36.                     (PBUF_POOL_BUFSIZE_ALIGNED - LWIP_MEM_ALIGN_SIZE(offset)) > 0 );
  37.         if (p == NULL) {
  38.           /* allocated head of pbuf chain (into p) */
  39.           p = q;
  40.         } else {
  41.           /* make previous pbuf point to this pbuf */
  42.           last->next = q;
  43.         }
  44.         last = q;
  45.         rem_len = (u16_t)(rem_len - qlen);
  46.         offset = 0;
  47.       } while (rem_len > 0);
  48.       break;
  49.     }
  50.     case PBUF_RAM: {
  51.       u16_t payload_len = (u16_t)(LWIP_MEM_ALIGN_SIZE(offset) + LWIP_MEM_ALIGN_SIZE(length));
  52.       mem_size_t alloc_len = (mem_size_t)(LWIP_MEM_ALIGN_SIZE(SIZEOF_STRUCT_PBUF) + payload_len);

  53.       /* bug #50040: Check for integer overflow when calculating alloc_len */
  54.       if ((payload_len < LWIP_MEM_ALIGN_SIZE(length)) ||
  55.           (alloc_len < LWIP_MEM_ALIGN_SIZE(length))) {
  56.         return NULL;
  57.       }

  58.       /* If pbuf is to be allocated in RAM, allocate memory for it. */
  59.       p = (struct pbuf *)mem_malloc(alloc_len);
  60.       if (p == NULL) {
  61.         return NULL;
  62.       }
  63.       pbuf_init_alloced_pbuf(p, LWIP_MEM_ALIGN((void *)((u8_t *)p + SIZEOF_STRUCT_PBUF + offset)),
  64.                              length, length, type, 0);
  65.       LWIP_ASSERT("pbuf_alloc: pbuf->payload properly aligned",
  66.                   ((mem_ptr_t)p->payload % MEM_ALIGNMENT) == 0);
  67.       break;
  68.     }
  69.     default:
  70.       LWIP_ASSERT("pbuf_alloc: erroneous type", 0);
  71.       return NULL;
  72.   }
  73.   LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc(length=%"U16_F") == %p\n", length, (void *)p));
  74.   return p;
  75. }
复制代码




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

使用道具 举报

15

主题

47

帖子

0

精华

初级会员

Rank: 2

积分
114
金钱
114
注册时间
2020-3-12
在线时间
23 小时
 楼主| 发表于 2023-3-9 14:34:54 | 显示全部楼层
本帖最后由 liyancao001 于 2023-3-9 14:38 编辑

用STM32F767的原子开发板试了下,直接UDP收即发,然后发送500以内都是返回正常。但是向767发送1000字节时,网络助手只·收到了550字节
回复

使用道具 举报

5

主题

134

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1387
金钱
1387
注册时间
2019-5-29
在线时间
163 小时
发表于 2023-3-9 15:33:45 | 显示全部楼层
pbuf_alloc动态分配内存用到了栈空间,建议调整栈大小
偷偷摸鱼
回复

使用道具 举报

5

主题

353

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4300
金钱
4300
注册时间
2019-4-30
在线时间
877 小时
发表于 2023-3-9 15:53:18 | 显示全部楼层
F4 TCP跑满100mbps没问题 UDP更不是问题 之前调过优
回复

使用道具 举报

21

主题

211

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1420
金钱
1420
注册时间
2016-8-3
在线时间
575 小时
发表于 2023-3-9 16:21:26 | 显示全部楼层
找个网络抓包工具看看吧,或者串口打印下看看发了多少数据
回复

使用道具 举报

15

主题

47

帖子

0

精华

初级会员

Rank: 2

积分
114
金钱
114
注册时间
2020-3-12
在线时间
23 小时
 楼主| 发表于 2023-3-9 17:01:00 | 显示全部楼层
Havefun 发表于 2023-3-9 15:33
pbuf_alloc动态分配内存用到了栈空间,建议调整栈大小

已经设为0x4000了
回复

使用道具 举报

15

主题

47

帖子

0

精华

初级会员

Rank: 2

积分
114
金钱
114
注册时间
2020-3-12
在线时间
23 小时
 楼主| 发表于 2023-3-9 17:03:59 | 显示全部楼层
a1281854907 发表于 2023-3-9 15:53
F4 TCP跑满100mbps没问题 UDP更不是问题 之前调过优

请问怎么调呢?我用原子例程试了下1400字节以内收发没问题。我用CUBE就是不行。我看pbuf.c应该不是一个版本,有枚举定义的都不一样。我修改PBUF_POOL_BUFSIZE是有效果的。但这应该不是正确的解决办法,现在推测是申请空间只能申请一页。发送的最大数据大小完全受PBUF_POOL_BUFSIZE影响
回复

使用道具 举报

15

主题

47

帖子

0

精华

初级会员

Rank: 2

积分
114
金钱
114
注册时间
2020-3-12
在线时间
23 小时
 楼主| 发表于 2023-3-9 17:29:33 | 显示全部楼层
1965969523 发表于 2023-3-9 16:21
找个网络抓包工具看看吧,或者串口打印下看看发了多少数据

就是发出来的少了,把PBUF_POOL_BUFSIZE当前设置为536+40+14,如果把536改为936,则最多能发出来950字节
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165309
金钱
165309
注册时间
2010-12-1
在线时间
2108 小时
发表于 2023-3-9 23:24:43 | 显示全部楼层
帮顶
回复

使用道具 举报

1

主题

6

帖子

0

精华

新手入门

积分
14
金钱
14
注册时间
2023-12-19
在线时间
2 小时
发表于 2023-12-29 17:13:50 | 显示全部楼层
师兄,你使用udp send发送数据时,如果循环发送需要变化的数据,会不会出现接收端第一次发送成功, 之后全是0的数据的问题呢
回复

使用道具 举报

17

主题

76

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
277
金钱
277
注册时间
2023-5-29
在线时间
106 小时
发表于 2024-5-31 16:29:11 | 显示全部楼层
gaopan0622 发表于 2023-12-29 17:13
师兄,你使用udp send发送数据时,如果循环发送需要变化的数据,会不会出现接收端第一次发送成功, 之后全 ...

哥们,搞定没
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-11-22 10:33

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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