基于LWIP实现实时网速的统计

  • LWIP版本为2.0.3,注意分辨;其他版本应该也可以实现
  • 使用RTThread版本4.1.0
  • 硬件为STM32F407VGT6+LAN8720A

实现思路:理解LWIP数据接收过程,在收到数据后读取数据长度,并对数据长度做累加计算,间隔1秒进行单位转换后即可。

分析接收过程:当数据来临时触发硬件中断,调用中断回调函数 HAL_ETH_RxCpltCallback()函数,在回调函数中调用eth_device_ready(),在eth_device_ready中通过邮箱传递指针到eth_rx_thread_entry线程中进行接收数据,在eth_rx_thread_entry中创建接收使用的pbuf指针,在线程中完成数据的一次拷贝,之后调用函数device->netif->input(p, device->netif);实际上是netif_input()函数,之后调用ethernet_input()函数,在ethernet_input()中调用ip4_input()函数或者etharp_input()函数区分IP包和ARP包,之后IP包又分为UDP、TCP、ICMP和IGMP处理;ARP包分为ARP请求和ARP应答。

以TCP数据为例,流程图如下:

实现方案:在硬件接收到数据后进行统计接收的字节数,字节数可有接收的pbuf结构体的len提供,pbuf结构

  • 14
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是一个使用lwip实现UDP通信的示例程序: ```c #include "lwip/udp.h" #include "lwip/inet.h" #define UDP_SERVER_PORT 1234 void udp_server_task(void *arg) { struct udp_pcb *pcb; struct pbuf *p; err_t err; ip_addr_t addr; uint16_t port; pcb = udp_new(); udp_bind(pcb, IP_ADDR_ANY, UDP_SERVER_PORT); while (1) { err = udp_recv(pcb, &p, NULL); if (err == ERR_OK) { // 获取发送者的IP地址和端口 udp_remote_ip_port(pcb, &addr, &port); printf("Received packet from %s:%d\n", inet_ntoa(addr), port); // 处理接收到的数据 // ... // 释放pbuf缓冲区 pbuf_free(p); } } } void udp_client_task(void *arg) { struct udp_pcb *pcb; struct pbuf *p; err_t err; ip_addr_t addr; // 创建UDP协议控制块 pcb = udp_new(); // 设置目标IP地址和端口号 IP4_ADDR(&addr, 192, 168, 1, 100); err = udp_connect(pcb, &addr, UDP_SERVER_PORT); if (err != ERR_OK) { printf("udp_connect error: %d\n", err); return; } // 发送数据 p = pbuf_alloc(PBUF_TRANSPORT, 1024, PBUF_RAM); memcpy(p->payload, "Hello, UDP server!", 18); err = udp_send(pcb, p); if (err != ERR_OK) { printf("udp_send error: %d\n", err); } // 关闭UDP协议控制块 udp_remove(pcb); pbuf_free(p); } int main() { sys_init(); tcpip_init(NULL, NULL); sys_thread_new("udp_server", udp_server_task, NULL, 1024, 1); sys_thread_new("udp_client", udp_client_task, NULL, 1024, 1); vTaskStartScheduler(); return 0; } ``` 该示例程序中包含一个UDP服务器任务和一个UDP客户端任务,分别实现UDP数据的接收和发送。在服务器任务中,使用`udp_new()`函数创建UDP协议控制块,并使用`udp_bind()`函数绑定本地IP地址和端口号。然后使用`udp_recv()`函数等待接收来自客户端的数据包,处理接收到的数据并释放pbuf缓冲区。在客户端任务中,使用`udp_new()`函数创建UDP协议控制块,并使用`udp_connect()`函数设置目标IP地址和端口号。然后使用`udp_send()`函数发送数据,并在发送完成后关闭UDP协议控制块并释放pbuf缓冲区。 需要注意的是,lwip库中提供的UDP接口是非阻塞的,因此在接收和发送数据时需要注意处理错误码。同时,lwip库中提供的UDP接口是基于pbuf缓冲区的,因此在接收到数据后需要使用`pbuf_free()`函数释放pbuf缓冲区。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值