OpenEdv-开源电子网

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

STM32F407 LwIP 如何快速发送数据?

[复制链接]

16

主题

110

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
329
金钱
329
注册时间
2014-2-25
在线时间
44 小时
发表于 2018-8-25 21:32:45 | 显示全部楼层 |阅读模式
5金钱
  最近想研究下以太网通讯,参考了原子的F407 带ucOS的LwIP例程,但是发现当以太网发送的时候1秒钟轮询两次,我需要一秒钟发送100次左右。
所以需要更改一下发送方式。有人说参考F429和F767系列的例程,但是我看了一下429的TCP服务器发送方式仍然是轮询的,请教下大家怎样不轮询的方式发送数据呢?
下图是F429 实验58 中TCP Server Demo 文件内的发送相关,仍然是轮询的吧。
1.png
2.png

   TCP服务端是如何不通过轮询的方式发送数据的呢? 非常感谢!!


回复

使用道具 举报

11

主题

1044

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3731
金钱
3731
注册时间
2011-5-23
在线时间
2014 小时
发表于 2018-8-25 23:06:51 | 显示全部楼层
TCP不适合高频次的小包数据。
可以考虑把数据打包起来一次性发NN包数据。
RT-Thread RTOS 音频,WIFI,蓝牙
回复

使用道具 举报

16

主题

110

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
329
金钱
329
注册时间
2014-2-25
在线时间
44 小时
 楼主| 发表于 2018-8-26 06:48:14 | 显示全部楼层
aozima 发表于 2018-8-25 23:06
TCP不适合高频次的小包数据。
可以考虑把数据打包起来一次性发NN包数据。

一次发4800字节左右的数据,现在我想要做的主要是能在想发的时候发送,而不是轮询的时候发送
回复

使用道具 举报

1

主题

21

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
222
金钱
222
注册时间
2017-9-2
在线时间
104 小时
发表于 2018-8-27 07:16:59 来自手机 | 显示全部楼层
我修改这个可以想发就发,但是容易卡死,没找到原因http://www.openedv.com/forum.php?mod=viewthread&tid=276037&mobile=2
回复

使用道具 举报

16

主题

110

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
329
金钱
329
注册时间
2014-2-25
在线时间
44 小时
 楼主| 发表于 2018-8-27 08:31:36 | 显示全部楼层
thread256 发表于 2018-8-27 07:16
我修改这个可以想发就发,但是容易卡死,没找到原因http://www.openedv.com/forum.php?mod=viewthread&tid= ...

链接没内容啊 大兄弟
回复

使用道具 举报

16

主题

110

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
329
金钱
329
注册时间
2014-2-25
在线时间
44 小时
 楼主| 发表于 2018-8-27 10:27:06 | 显示全部楼层
thread256 发表于 2018-8-27 07:16
我修改这个可以想发就发,但是容易卡死,没找到原因http://www.openedv.com/forum.php?mod=viewthread&tid= ...

原来是手机端的网址,网页是这个http://www.openedv.com/forum.php ... P%B7%FE%CE%F1%C6%F7   感谢提供思路 我研究下。
回复

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
11
金钱
11
注册时间
2022-7-13
在线时间
4 小时
发表于 2025-12-3 08:45:10 | 显示全部楼层
这个问题居然这么久没人回答,最近项目要用到LWIP,移植了正点原子的标准库例程。也同样遇到了相同的问题,tcp_server_flag置位到轮询发送清位,大概需要500毫秒时间。这样的发送方式,确实实用性不强。我是这样解决的:
1、在tcp_server_demo.c文件里定义全局变量:struct tcp_pcb *my_tcp_pcb;//用来缓存accept时候tcp的全局变量
2、在tcp_server_demo.c文件的err_t tcp_server_accept(void *arg,struct tcp_pcb *newpcb,err_t err)函数里,tcp_arg(newpcb,es);这一行的下面,添加一行:my_tcp_pcb=newpcb;
3、在tcp_server_demo.c文件里新建一个立即发送的函数:
err_t tcp_immediate_send(void)
{
    err_t err = ERR_OK;
    struct pbuf *p = NULL;

    // 1. 检查连接有效性(必须是已建立状态)
    if (my_tcp_pcb == NULL || my_tcp_pcb->state != ESTABLISHED) {
        return ERR_CONN;  // 连接无效或已断开
    }

    // 2. 分配 PBUF(TCP 数据需用 PBUF_TRANSPORT 层级)
    //    PBUF_RAM:数据存于RAM,可直接修改;PBUF_POOL:从内存池分配(更省内存)
    p = pbuf_alloc(PBUF_TRANSPORT,strlen((char*)tcp_server_sendbuf),PBUF_POOL);
    if (p == NULL) {
        return ERR_MEM;  // 内存不足,分配失败
    }

    // 3. 将待发送数据复制到 PBUF 中
    //    pbuf_take 会自动处理 PBUF 链(若数据超长,无需手动拆分)
    if (pbuf_take(p, (char*)tcp_server_sendbuf,strlen((char*)tcp_server_sendbuf)) != ERR_OK) {
        pbuf_free(p);    // 复制失败,释放 PBUF
        return ERR_BUF;
    }

    // 4. 写入 TCP 发送缓冲区(tcp_write)
    //    第三个参数 flags:0=普通发送;TCP_WRITE_FLAG_MORE=后续还有数据(用于批量发送)
    err = tcp_write(my_tcp_pcb, p, strlen((char*)tcp_server_sendbuf), 0);
    if (err != ERR_OK) {
        pbuf_free(p);    // 写入失败,释放 PBUF
        return err;
    }

    // 5. 强制触发发送(关键!tcp_output 跳过默认超时,立即发送)
    tcp_output(my_tcp_pcb);

    // 6. 释放 PBUF(因未使用 TCP_WRITE_FLAG_COPY,LWIP 已复制数据到自身缓冲区)
    //    若用 TCP_WRITE_FLAG_COPY,可省略此步(但 pbuf_take 仍需执行)
    pbuf_free(p);

    return ERR_OK;
}
4、在在tcp_server_demo.h文件里添加一行:err_t tcp_immediate_send(void);
5、在需要发送的地方添加头头文件#include "tcp_server_demo.h",直接调用tcp_immediate_send函数即可。
备注:重点是struct tcp_pcb *my_tcp_pcb;的获取,需要发送的数据提前缓存到tcp_server_sendbuf里。
      
回复

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
11
金钱
11
注册时间
2022-7-13
在线时间
4 小时
发表于 2025-12-3 13:15:35 | 显示全部楼层
xifanlover 发表于 2025-12-3 08:45
这个问题居然这么久没人回答,最近项目要用到LWIP,移植了正点原子的标准库例程。也同样遇到了相同的问题, ...

不好意思,误导大家了,这样做貌似发送的数据会乱码。
回复

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
11
金钱
11
注册时间
2022-7-13
在线时间
4 小时
发表于 2025-12-3 16:01:54 | 显示全部楼层
xifanlover 发表于 2025-12-3 08:45
这个问题居然这么久没人回答,最近项目要用到LWIP,移植了正点原子的标准库例程。也同样遇到了相同的问题, ...

最终我只把TCP_TMR_INTERVAL这个宏定义从250改成了1,然后我lwip_localtime是每10毫秒加一次:lwip_localtime+=10;所以我差不多11-12毫秒可以发送一次。暂时满足我需求了。
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165650
金钱
165650
注册时间
2010-12-1
在线时间
2122 小时
发表于 7 天前 | 显示全部楼层
xifanlover 发表于 2025-12-3 16:01
最终我只把TCP_TMR_INTERVAL这个宏定义从250改成了1,然后我lwip_localtime是每10毫秒加一次:lwip_local ...

good job
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子产品购买店铺https://zhengdianyuanzi.tmall.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

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

本版积分规则


关闭

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

正点原子公众号

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

GMT+8, 2025-12-13 01:48

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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