OpenEdv-开源电子网

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

STM32F407+dp83848利用UDP协议一次最多能发送多少数据?

[复制链接]

21

主题

134

帖子

0

精华

高级会员

Rank: 4

积分
624
金钱
624
注册时间
2014-11-11
在线时间
161 小时
发表于 2015-9-1 20:31:16 | 显示全部楼层 |阅读模式
5金钱
请教一下各位大侠,问题已经困扰我很久了,。。。
移植原子的程序,想测试一下网口的速度,想法是通过网络调试助手,发送一个指令如0xeb90,然后STM32通过网口返回大量数据,然后算出速度。。。。。
看很多资料说如果要发送大量数据的话,可以利用PBUF_POOL类型的Pbuf,然后多个这种类型的pbuf组成pbuf链,要发送的数据包分配到这个链的每个pbuf的payload指向的数据处,原理如图



最佳答案

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

一次最大发送字节数为MTU,MTU默认为1500个字节,而且这1500个字节不全是你的数据,还有包括开销的。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

88

主题

7377

帖子

5

精华

资深版主

Rank: 8Rank: 8

积分
14980
金钱
14980
注册时间
2013-11-13
在线时间
1823 小时
发表于 2015-9-1 20:31:17 | 显示全部楼层
一次最大发送字节数为MTU,MTU默认为1500个字节,而且这1500个字节不全是你的数据,还有包括开销的。
开往春天的手扶拖拉机
回复

使用道具 举报

8

主题

67

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
226
金钱
226
注册时间
2013-9-27
在线时间
26 小时
发表于 2015-9-1 20:31:17 | 显示全部楼层
我之前也发现过这个问题,按照原子的例程,数据只能存在第一个payload指向的数据区,所以这里需要你在程序中将所需要发送的数据放到payload中。这是我之前改过的程序(不规范勿喷)
不过按照如下改过之后,最多只能发送1400多个字节数据,具体多少记不清楚了,就是楼上说的一次最大发送字节数,但不到1500。
void udp_senddata(void *PData, uint16_t totlen) 
{
struct pbuf *ptr, *ptmp;
char *Ptemp;
uint16_t Currlen=0,remlen=0;
ptr=pbuf_alloc(PBUF_TRANSPORT,totlen,PBUF_POOL); //申请内存
Ptemp=PData;
remlen=totlen;
ptmp=ptr;
if(ptr)

while(remlen>0)
{
ptmp->payload=(uint8_t *)&Ptemp[Currlen]; //(void*)不能进行算法操作,因此加一临时变量替换
Currlen=Currlen+ptmp->len;
remlen=totlen-Currlen;
if(remlen!=0)
{
ptmp=ptmp->next;
}
else
{
ptmp->next=NULL;
}
}
udp_send(UDPPCB,ptr);
pbuf_free(ptr);

}
回复

使用道具 举报

21

主题

134

帖子

0

精华

高级会员

Rank: 4

积分
624
金钱
624
注册时间
2014-11-11
在线时间
161 小时
 楼主| 发表于 2015-9-1 20:40:20 | 显示全部楼层
程序     ptr=pbuf_alloc(PBUF_TRANSPORT,1024,PBUF_POOL); //申请内存
? 申请了1024个字节的内存
?每个pbuf的大小修改为#define BUF_POOL_BUFSIZE       512 + 54
?也就是链的第一个数据有效存储数据区域的大小为512个字节,但是不管是用ptr->payload=(void*)buffer2;(buffer2是我定义的一个数组,   for(ts=0;ts<2048;ts++)
    {
        buffer2[ts] =ts;  //预存数组数据
    })
 还是调用pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len),数据只能存在第一个payload指向的数据区,链表中的第二个pbuf的payload指向的地址处根本没有任何数据。申请内存是用的pbuf_alloc()函数没有加任何修改,因为我看到这个函数就是建了一个有两个pbuf的pbuf链,请教大侠这是什么原因,怎么才能把数据放到第二个pbuf的payload指向的区域
回复

使用道具 举报

21

主题

134

帖子

0

精华

高级会员

Rank: 4

积分
624
金钱
624
注册时间
2014-11-11
在线时间
161 小时
 楼主| 发表于 2015-9-1 20:48:57 | 显示全部楼层
通过网络调试助手的到的数据的多少随着PBUF_POOL_BUFSIZE的大小而变化,例如上面数据区的大小是512,申请的内存是1024个字节,网络调试助手得到的数据是前512字节是数组buffer中的数据,后512字节全部是0,当#define BUF_POOL_BUFSIZE       1024 + 54 时
得到的全是buffer2中的数据,也就是说pbuf链中根本没有分配进数据。。。。还有一个问题就是如果申请的内存超过1476个字节,网络调试助手根本得不到任何数据!!!!!!不知道什么原因,小弟文字功底不好,描述的不好,还请大侠或者做个网口的赐教,鞠躬。。。。。。。
回复

使用道具 举报

21

主题

134

帖子

0

精华

高级会员

Rank: 4

积分
624
金钱
624
注册时间
2014-11-11
在线时间
161 小时
 楼主| 发表于 2015-9-1 20:51:07 | 显示全部楼层
回复【3楼】zuozhongkai:
---------------------------------
大侠,可找到你了,那为什么我不能把数据放在pbuf链中的第二个pbuf的payloa指向的区域呢
回复

使用道具 举报

88

主题

7377

帖子

5

精华

资深版主

Rank: 8Rank: 8

积分
14980
金钱
14980
注册时间
2013-11-13
在线时间
1823 小时
发表于 2015-9-1 20:52:45 | 显示全部楼层
回复【5楼】刺客mfl:
---------------------------------
看一下你究竟申请到了几个pbuf结构体,还有就是将PBUF_POOL_BUFSIZE改为1500试一下
开往春天的手扶拖拉机
回复

使用道具 举报

21

主题

134

帖子

0

精华

高级会员

Rank: 4

积分
624
金钱
624
注册时间
2014-11-11
在线时间
161 小时
 楼主| 发表于 2015-9-1 20:53:19 | 显示全部楼层
回复【4楼】刺客mfl:
--------------------------------- 
这个MTU我也改过
    netif->mtu=2500; //最大允许传输单元,允许该网卡广播和ARP功能
  netif->flags = NETIF_FLAG_BROADCAST|NETIF_FLAG_ETHARP|NETIF_FLAG_LINK_UP;
改成2500还是这种现象,求赐教,谢谢
回复

使用道具 举报

21

主题

134

帖子

0

精华

高级会员

Rank: 4

积分
624
金钱
624
注册时间
2014-11-11
在线时间
161 小时
 楼主| 发表于 2015-9-1 20:58:45 | 显示全部楼层
回复【8楼】amyoubo:
---------------------------------
谢谢你,我测的是最多发1467个字节,但是MTU我都给增大了啊,你先在知道为什么数据只能存在pbuf链中的第一个pbuf的payload指向的数据区了吗?
如果这样的话,那还要pbuf链干什么呀
回复

使用道具 举报

8

主题

67

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
226
金钱
226
注册时间
2013-9-27
在线时间
26 小时
发表于 2015-9-1 21:01:27 | 显示全部楼层
回复【9楼】刺客mfl:
---------------------------------
原子的程序中只有一句ptr->payload=(void*)buffer2;,所以肯定只有第一个Pbuf有数据,我上个回复中的代码就可以把所有的数据填到pbuf链中
回复

使用道具 举报

21

主题

134

帖子

0

精华

高级会员

Rank: 4

积分
624
金钱
624
注册时间
2014-11-11
在线时间
161 小时
 楼主| 发表于 2015-9-1 21:07:04 | 显示全部楼层
回复【10楼】amyoubo:
---------------------------------
谢谢你,那你又试过用函数pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len),或者改大一点zuozhongkai所说的MTU吗,这样会不会发送的数据会大点。。。。。
回复

使用道具 举报

8

主题

67

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
226
金钱
226
注册时间
2013-9-27
在线时间
26 小时
发表于 2015-9-1 21:09:33 | 显示全部楼层
恩,两个都没有试过,第一个函数不清楚是干什么的,第二个,由于我当时1400多已经足够我用了,所以并没有试过改MTU,不过我感觉应该可以,前提是你先要手动把数据填到pbuf中
回复

使用道具 举报

21

主题

134

帖子

0

精华

高级会员

Rank: 4

积分
624
金钱
624
注册时间
2014-11-11
在线时间
161 小时
 楼主| 发表于 2015-9-1 21:09:39 | 显示全部楼层
回复【10楼】amyoubo:
---------------------------------,
还有如果最大只能发送1400多字节的话还不如修改PBUF_POOL_SIZE的大小了,也就是把单个pbuf的payload指向的数据区加大,这样还省事
回复

使用道具 举报

8

主题

67

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
226
金钱
226
注册时间
2013-9-27
在线时间
26 小时
发表于 2015-9-1 21:12:33 | 显示全部楼层
回复【13楼】刺客mfl:
---------------------------------
这个看你需要1次发送多少了,超过了1500就不行了
回复

使用道具 举报

21

主题

134

帖子

0

精华

高级会员

Rank: 4

积分
624
金钱
624
注册时间
2014-11-11
在线时间
161 小时
 楼主| 发表于 2015-9-1 21:14:50 | 显示全部楼层
回复【6楼】zuozhongkai:
---------------------------------
调用的是官方的函数pbuf_alloc,看这个函数的代码应该是是两个pbuf,如果是改成1500的话减去首部54字节不到1476,我现在还遇到的问题就是每次最大发送的数据最大是1476,不知道是什么原因,修改过您说的MTU 
  netif->mtu=2500; //最大允许传输单元,允许该网卡广播和ARP功能 
  netif->flags = NETIF_FLAG_BROADCAST|NETIF_FLAG_ETHARP|NETIF_FLAG_LINK_UP; 
改成2500还是这种现象,求赐教,谢谢
回复

使用道具 举报

21

主题

134

帖子

0

精华

高级会员

Rank: 4

积分
624
金钱
624
注册时间
2014-11-11
在线时间
161 小时
 楼主| 发表于 2015-9-1 21:19:11 | 显示全部楼层
回复【14楼】amyoubo:
---------------------------------
我现在就是一次能发送的越大越好,所以我想试试一次最大能发送多少,看一下极限,1400多字节感觉太少了,我想一次要是16K就好了....现在只能是1K。。。哎
回复

使用道具 举报

8

主题

67

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
226
金钱
226
注册时间
2013-9-27
在线时间
26 小时
发表于 2015-9-1 21:22:05 | 显示全部楼层
16K感觉需要你自己定个发送接收协议,分多次发送,一次发送应该是不现实的
回复

使用道具 举报

88

主题

7377

帖子

5

精华

资深版主

Rank: 8Rank: 8

积分
14980
金钱
14980
注册时间
2013-11-13
在线时间
1823 小时
发表于 2015-9-1 21:51:43 | 显示全部楼层
回复【16楼】刺客mfl:
---------------------------------
建议最好设置为1500,刚好一个MTU的大小。
开往春天的手扶拖拉机
回复

使用道具 举报

21

主题

134

帖子

0

精华

高级会员

Rank: 4

积分
624
金钱
624
注册时间
2014-11-11
在线时间
161 小时
 楼主| 发表于 2015-9-2 11:39:10 | 显示全部楼层
回复【18楼】zuozhongkai:
---------------------------------
今天上午测了一下STM32F4发给的上位机也就是网络调试助手的速度,从windows任务管理器---联网看网络应用只有百分之0.56,感觉速度不咋地,想请教一下大侠,您测过UDP协议的速度吗,我移植的是原子的程序,也在论坛看了一篇您回复的帖子,哪个是用的TCP,您给出的建议是
1、尽量不要使用delay延时函数!应用程序中的延时函数对于速度的影响很大的。
2、尽量减少数据拷贝,数据拷贝也会浪费大量的时间。
3、就像别人说的,将缓存开大一点,你如果使用了ST的官方以太网库的话,有下面几个地方需要改打一点。
那么要优化UDP协议的速度改怎么改呢?
我修改的是
//MEM_SIZE:heap内存的大小,如果在应用中有大量数据发送的话这个值最好设置大一点 
//#define MEM_SIZE                16000 //内存堆大小
#define MEM_SIZE                32000 //内存堆大小 20150831

//MEMP_NUM_PBUF:memp结构的pbuf数量,如果应用从ROM或者静态存储区发送大量数据时,这个值应该设置大一点
//#define MEMP_NUM_PBUF           10
#define MEMP_NUM_PBUF           20         //20150831
//MEMP_NUM_UDP_PCB:UDP协议控制块(PCB)数量.每个活动的UDP"连接"需要一个PCB.
//#define MEMP_NUM_UDP_PCB        6
#define MEMP_NUM_UDP_PCB        10
//MEMP_NUM_TCP_PCB:同时建立激活的TCP数量
#define MEMP_NUM_TCP_PCB        10

//MEMP_NUM_TCP_PCB_LISTEN:能够监听的TCP连接数量
#define MEMP_NUM_TCP_PCB_LISTEN 6

//MEMP_NUM_TCP_SEG:最多同时在队列中的TCP段数量
#define MEMP_NUM_TCP_SEG        15

//MEMP_NUM_SYS_TIMEOUT:能够同时激活的timeout个数
#define MEMP_NUM_SYS_TIMEOUT    8


/* ---------- buf选项---------- */
//PBUF_POOL_SIZE:pbuf内存池个数. 
//#define BUF_POOL_SIZE          20
#define BUF_POOL_SIZE          24 //20150901   

//PBUF_POOL_BUFSIZE:每个pbuf内存池大小. 
//#define BUF_POOL_BUFSIZE       512
#define BUF_POOL_BUFSIZE       1024 + 54
回复

使用道具 举报

87

主题

331

帖子

0

精华

高级会员

Rank: 4

积分
906
金钱
906
注册时间
2016-3-26
在线时间
116 小时
发表于 2016-7-22 15:30:22 | 显示全部楼层
amyoubo 发表于 2015-9-1 20:31
我之前也发现过这个问题,按照原子的例程,数据只能存在第一个payload指向的数据区,所以这里需要你在程序 ...

我想问一下。为什么我使用UDP传输,只有数据大于256字节的话出现问题,payload缓冲区里面只是前256字节的数据。
比如我要传输一个50兆的文件的话,我该怎么做?
回复

使用道具 举报

4

主题

28

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2019-1-9
在线时间
20 小时
发表于 2019-1-25 12:43:56 | 显示全部楼层
刺客mfl 发表于 2015-9-1 20:40
程序&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ptr=pbuf_alloc(PBUF_TRANSPORT,1024,PBUF_POOL);&nbsp;//申请内存
?&n ...

这个需要设置一个循环一个一个写入PBUF
回复

使用道具 举报

4

主题

28

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2019-1-9
在线时间
20 小时
发表于 2019-1-25 12:47:45 | 显示全部楼层
刺客mfl 发表于 2015-9-1 20:40
程序&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ptr=pbuf_alloc(PBUF_TRANSPORT,1024,PBUF_POOL);&nbsp;//申请内存
?&n ...

PBUF_TAKE就可以帮你放进去,LEN设为1024就可以,里面有个循环专门干这事的
回复

使用道具 举报

4

主题

28

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2019-1-9
在线时间
20 小时
发表于 2019-1-25 13:02:01 | 显示全部楼层
刺客mfl 发表于 2015-9-1 21:19
回复【14楼】amyoubo:
---------------------------------
我现在就是一次能发送的越大越好,所以我想试试 ...

这要看PBUF_POLL的大小,内存够大就可以,但是最大不能超过65536(含报头),因为协议中有个数据长度字段LEN,定义为U16,我用的H7,留了300K左右的SRAM,最大一次发送能到48K,我要发送130K,所以自己分了几个包,不过两个包发送中间要有约100MS的延时才行,速度会受到一定的影响,如果内存够大,应该可以再开一个新的TCB会快一些
回复

使用道具 举报

19

主题

62

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
211
金钱
211
注册时间
2016-8-21
在线时间
47 小时
发表于 2019-1-25 18:37:28 | 显示全部楼层
papabbb 发表于 2019-1-25 13:02
这要看PBUF_POLL的大小,内存够大就可以,但是最大不能超过65536(含报头),因为协议中有个数据长度字段 ...

请问您用的h7开发板连接的dp83848吗,还是自己画的板子?
回复

使用道具 举报

4

主题

28

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2019-1-9
在线时间
20 小时
发表于 2019-1-25 20:16:39 | 显示全部楼层
z0011k 发表于 2019-1-25 18:37
请问您用的h7开发板连接的dp83848吗,还是自己画的板子?

我连的8720,原子的开发板
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-9 14:57

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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