GD32F307+lwip+freeRTOS+DP83848 JPerf接收测速

news2024/10/7 3:28:20
1.原理图

在这里插入图片描述
在这里插入图片描述

2.代码

https://www.firebbs.cn/forum.php?mod=viewthread&tid=26274&fromuid=37393
//22_ENET

1)注释掉tcp_client_init();
2)init_task中添加测速线程iperf_server_init()

//main.c

#include "gd32f30x.h"
#include "netconf.h"
#include "main.h"
#include "lwip/tcp.h"
#include "gd32f307c_eval.h"
#include "hello_gigadevice.h"
#include "tcp_client.h"
#include "udp_echo.h"
#include "ipref.h"


#define INIT_TASK_PRIO   ( tskIDLE_PRIORITY + 1 )
#define DHCP_TASK_PRIO   ( tskIDLE_PRIORITY + 4 )
#define LED_TASK_PRIO    ( tskIDLE_PRIORITY + 2 )


extern struct netif g_mynetif;
 
void led_task(void * pvParameters); 
void init_task(void * pvParameters);

/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/
int main(void)
{
    /* configure 4 bits pre-emption priority */
    nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);

    /* init task */
    xTaskCreate(init_task, "INIT", configMINIMAL_STACK_SIZE * 2, NULL, INIT_TASK_PRIO, NULL);
    
    /* start scheduler */
    vTaskStartScheduler();

    while(1){
    }
}

/*!
    \brief      init task
    \param[in]  pvParameters not used
    \param[out] none
    \retval     none
*/
void init_task(void * pvParameters)
{
//    gd_eval_com_init(EVAL_COM0);
    gd_eval_led_init(LED3);
    
    /* configure ethernet (GPIOs, clocks, MAC, DMA) */ 
    enet_system_setup();

    /* initilaize the LwIP stack */
    lwip_stack_init();

#ifdef USE_DHCP
    /* start DHCP client */
    xTaskCreate(dhcp_task, "DHCP", configMINIMAL_STACK_SIZE * 2, NULL, DHCP_TASK_PRIO, NULL);
#endif /* USE_DHCP */

    /* start toogle LED task every 250ms */
    xTaskCreate(led_task, "LED", configMINIMAL_STACK_SIZE, NULL, LED_TASK_PRIO, NULL);
  
  iperf_server_init();

    for( ;; ){
        vTaskDelete(NULL);
    }
}

/*!
    \brief      after the netif is fully configured, it will be called to initialize the function of telnet, client and udp
    \param[in]  netif: the struct used for lwIP network interface
    \param[out] none
    \retval     none
*/
void lwip_netif_status_callback(struct netif *netif)
{
    if(((netif->flags & NETIF_FLAG_UP) != 0) && (0 != netif->ip_addr.addr)) {
        /* initilaize the tcp server: telnet 8000 */
        hello_gigadevice_init();
        /* initilaize the tcp client: echo 10260 */
//        tcp_client_init();
        /* initilaize the udp: echo 1025 */
        udp_echo_init();
    }
}

/*!
    \brief      led task
    \param[in]  pvParameters not used
    \param[out] none
    \retval     none
*/
void led_task(void * pvParameters)
{  
    for( ;; ){
        /* toggle LED3 each 250ms */
        gd_eval_led_toggle(LED3);
        vTaskDelay(1000);
    }
}

/* retarget the C library printf function to the USART */
int fputc(int ch, FILE *f)
{
    usart_data_transmit(EVAL_COM0, (uint8_t) ch);
    while (RESET == usart_flag_get(EVAL_COM0, USART_FLAG_TBE));
    return ch;
}

//ipref.c

#if 1
/* FreeRTOS头文件 */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"

#include <stdint.h>
#include <stdio.h>

#include <lwip/sockets.h>

#include "ipref.h"

#include "lwip/opt.h"

#include "lwip/sys.h"
#include "lwip/api.h"

#define IPERF_PORT          5001
#define IPERF_BUFSZ         (4 * 1024)

void iperf_server(void *thread_param)
{
   struct netconn *conn, *newconn;
   err_t err;
   void* recv_data;

   recv_data = (void *)pvPortMalloc(IPERF_BUFSZ);
   if (recv_data == NULL)    {
       printf("No memory\n");
   }

   conn = netconn_new(NETCONN_TCP);
   netconn_bind(conn, IP_ADDR_ANY, 5001);

   LWIP_ERROR("tcpecho: invalid conn", (conn != NULL), return;);

   /* Tell connection to go into listening mode. */
   netconn_listen(conn);

   while (1)
   {

       /* Grab new connection. */
       err = netconn_accept(conn, &newconn);
       /*printf("accepted new connection %p\n", newconn);*/
       /* Process the new connection. */
       if (err == ERR_OK)
       {
           struct netbuf *buf;
//      void *data;
           u16_t len;

           while ((err = netconn_recv(newconn, &buf)) == ERR_OK)
           {
               /*printf("Recved\n");*/
               do
               {
                   netbuf_data(buf, &recv_data, &len);
//             err = netconn_write(newconn, data, len, NETCONN_COPY);
               }
               while (netbuf_next(buf) >= 0);
               netbuf_delete(buf);
           }
           /*printf("Got EOF, looping\n");*/
           /* Close connection and discard connection identifier. */
           netconn_close(newconn);
           netconn_delete(newconn);
       }
   }
}

void
iperf_server_init(void)
{
   sys_thread_new("iperf_server", iperf_server, NULL, 2048, 4);
}

#else

/* FreeRTOS头文件 */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"

#include <stdint.h>
#include <stdio.h>

//#include <lwip/time.h>
#include <lwip/sockets.h>
//#include <lwip/select.h>
//#include "netdb.h"
#include "ipref.h"

#include "lwip/opt.h"

#include "lwip/sys.h"
#include "lwip/api.h"

#define IPERF_PORT          5001
#define IPERF_BUFSZ         (4 * 1024)

void iperf_server(void *thread_param)
{
   uint8_t *recv_data;
   socklen_t sin_size;
   uint32_t tick1, tick2;
   int sock = -1, connected, bytes_received;
   uint64_t recvlen;
   struct sockaddr_in server_addr, client_addr;
   char speed[32] = { 0 };
   fd_set readset;
   struct timeval timeout;

   recv_data = (uint8_t *)pvPortMalloc(IPERF_BUFSZ);
   if (recv_data == NULL)
   {
       printf("No memory\n");
       goto __exit;
   }

   sock = socket(AF_INET, SOCK_STREAM, 0);
   if (sock < 0)
   {
       printf("Socket error\n");
       goto __exit;
   }

   server_addr.sin_family = AF_INET;
   server_addr.sin_addr.s_addr = INADDR_ANY;
   server_addr.sin_port = htons(IPERF_PORT);
   memset(&(server_addr.sin_zero), 0x0, sizeof(server_addr.sin_zero));

if (bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1)
   {
       printf("Unable to bind\n");
       goto __exit;
   }

   if (listen(sock, 5) == -1)
   {
       printf("Listen error\n");
       goto __exit;
   }

   timeout.tv_sec = 3;
   timeout.tv_usec = 0;

   printf("iperf_server\n");
   while (1)
   {
       FD_ZERO(&readset);
       FD_SET(sock, &readset);

       if (select(sock + 1, &readset, NULL, NULL, &timeout) == 0)
           continue;

       printf("iperf_server\n");

       sin_size = sizeof(struct sockaddr_in);

       connected = accept(sock, (struct sockaddr *)&client_addr, &sin_size);

       printf("new client connected from (%s, %d)\n",
           inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));

       {
           int flag = 1;

           setsockopt(connected,
                   IPPROTO_TCP,     /* set option at TCP level */
                   TCP_NODELAY,     /* name of option */
                   (void *) &flag,  /* the cast is historical cruft */
                   sizeof(int));    /* length of option value */
       }

       recvlen = 0;
       tick1 = xTaskGetTickCount();
       while (1)
       {
           bytes_received = recv(connected, recv_data, IPERF_BUFSZ, 0);
           if (bytes_received <= 0) break;

           recvlen += bytes_received;

           tick2 = xTaskGetTickCount();
           if (tick2 - tick1 >= configTICK_RATE_HZ * 5)
           {
               float f;
               f=(float)(recvlen * configTICK_RATE_HZ/125/(tick2-tick1));
               f /= 1000.0f;
//                snprintf(speed, sizeof(speed), "%.4f Mbps!\n", f);
//                printf("%s", speed);
               tick1 = tick2;
               recvlen = 0;
           }
       }

       if (connected >= 0) closesocket(connected);
       connected = -1;
   }

__exit:
   if (sock >= 0) closesocket(sock);
   if (recv_data) free(recv_data);
}

void
iperf_server_init(void)
{
   sys_thread_new("iperf_server", iperf_server, NULL, 2048, 4);
}
#endif

//ipref.h

#ifndef LWIP_IPERF_H
#define LWIP_IPERF_H


#define TCP_SERVER_THREAD_NAME            "iperf_server"
#define TCP_SERVER_THREAD_STACKSIZE        1024
#define TCP_SERVER_THREAD_PRIO             4

void iperf_server(void *thread_param);
void iperf_server_init(void);
#endif
3.实际效果
1) NETCONN API,代码未优化的情况下只有20Mb/s左右,且不稳定。

在这里插入图片描述
教材优化后可以到94M
在这里插入图片描述

2)Socket API,代码未优化的情况下有32MB/s左右,较稳定。

在这里插入图片描述
教材优化后可以到71M
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1684619.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

自定义RedisTemplate序列化器

大纲 RedisSerializerFastJsonRedisSerializer自定义二进制序列化器总结代码 在《RedisTemplate保存二进制数据的方法》一文中&#xff0c;我们将Java对象通过《使用java.io库序列化Java对象》中介绍的方法转换为二进制数组&#xff0c;然后保存到Redis中。实际可以通过定制Red…

QTextCodec NO such file or directory让qt6兼容qt5

首先在.pro 文件中新加 QT core5compat这时会报错 链接 报错之后修复qt&#xff0c;新加兼容模块&#xff0c;见链接。

C++实现基于http协议的epoll非阻塞模型的web服务器框架(支持访问服务器目录下文件的解析)

使用方法&#xff1a; 编译 例子&#xff1a;./httpserver 9999 ../ htmltest/ 可执行文件 端口 要访问的目录下的 例子&#xff1a;http://192.168.88.130:9999/luffy.html 前提概要 http协议 &#xff1a;应用层协议&#xff0c;用于网络通信&#xff0c;封装要传输的数据&…

LeetCode 79.单词搜索

原题链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 单词必须按照字母顺序&#xff0c;通过相邻的单元格内…

本地centos7+docker+ollama+gpu部署

1、一台有 NVIDIA GPU 驱动的机器 2、Docker CE安装 # 删除旧版本的 Docker&#xff08;如果存在&#xff09; sudo yum remove -y docker docker-common docker-selinux docker-engine # 安装必要的软件包&#xff1a; sudo yum install -y yum-utils device-mapper-persiste…

PyCharm设置——用于调试虚拟环境中的django程序

使用Pycharm新建了一个项目。 项目目录&#xff1a;C:\Users\grace\PycharmProjects\learning_log 在该路径下安装虚拟环境ll_env&#xff0c;并在虚拟环境下安装Django。 为了调试该Django需要对PyCharm进行设置。 1、确保PyCharm使用正确的虚拟环境 打开PyCharm&#xff…

市面上前 11 名的 Android 数据恢复软件

Android数据恢复软件是恢复无意中删除的文件或文件夹的必要工具。该软件还将帮助您恢复丢失或损坏的信息。本文介绍提供数据备份和磁盘克隆选项的程序&#xff0c;这些选项有助于在Android设备上恢复文件的过程。 如果您正在寻找一种有效的方法来恢复图像&#xff0c;文档&…

qmt量化交易策略小白学习笔记第8期【qmt编程之获取股票资金流向数据--内置Python】

qmt编程之获取股票资金流向数据 qmt更加详细的教程方法&#xff0c;会持续慢慢梳理。 也可找寻博主的历史文章&#xff0c;搜索关键词查看解决方案 &#xff01; 感谢关注&#xff0c;需免费开通量化回测与咨询实盘权限&#xff0c;可以和博主联系&#xff01; 获取股票资金…

java学习四

Random 随机数 数组 静态初始化数组 数组在计算机中的基本原理 数组的访问 什么是遍历 数组的动态初始化 动态初始化数组元素默认值规则 Java内存分配介绍 数组在计算机中的执行原理 使用数组时常见的一个问题 案例求数组元素最大值 public class Test1 {public static void ma…

面试八股之MySQL篇5——主从同步原理篇

&#x1f308;hello&#xff0c;你好鸭&#xff0c;我是Ethan&#xff0c;一名不断学习的码农&#xff0c;很高兴你能来阅读。 ✔️目前博客主要更新Java系列、项目案例、计算机必学四件套等。 &#x1f3c3;人生之义&#xff0c;在于追求&#xff0c;不在成败&#xff0c;勤通…

Qt学习记录(14)线程

前言&#xff1a; 我的臀部已经翘到可以顶起一屁股债了 为什么要使用线程 什么时候用线程 复杂的数据处理 头文件.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTimer>//定时器头文件QT_BEGIN_NAMESPACE namespace Ui { class Widget; }…

表现层框架设计之表现层设计模式_3.MVVM模式

1.MVVM模式 MVVM模式正是为解决MVP中UI种类变多&#xff0c;接口也会不断增加的问题而提出的。 MVVM模式全称是模型-视图-视图模型&#xff08;Model-View-ViewModel&#xff09;&#xff0c;它和MVC、MVP类似&#xff0c;主要目的都是为了实现视图和模型的分离&#xff0c;不…

Mac网线连接windows本【局域网互传文件】

Mac网线连接windows本【局域网互传文件】 两台电脑网线互联 Mac->网络->USP TCP/IP 手动配置IP&#xff0c;子网掩码&#xff0c;路由器 windows 网络和Internet配置->更改适配器选项->以太网->Internet协议版本4&#xff08;TCP/IPv4&#xff09;->属性 …

概率论统计——大数定律

大数定律 弱大数定律&#xff08;辛钦大数定律&#xff09; 利用切比雪夫不等式&#xff0c;证明弱大数定律 应用 伯努利大数定理&#xff0c;&#xff08;辛钦大数定理的推论&#xff09; 证明伯努利大数定理 注意&#xff1a;这里将二项分布转化成0,1分布来表示&#xff0c;…

跨境小白shopee被封号的原因?如何有效预防?

提到跨境电商平台&#xff0c;大家都知道亚马逊、Temu、TikTok shop这些是比较大的电商平台。但最近几年&#xff0c;在东南亚市场上&#xff0c;Shopee虾皮却是颇负盛名的一个跨境电商平台&#xff0c;这也让众多中国跨境小白蜂拥而至。目前shopee的商家正在不断增多&#xff…

奥威BI软件能做金蝶ERP以外的数据分析吗?

奥威BI软件能够进行金蝶ERP以外的数据分析。除了金蝶ERP外&#xff0c;奥威BI软件还可以对接用友等主流ERP&#xff1b;支持MS SQL、Oracle、Mysql等主流的关系型数据库&#xff0c;这允许用户直接从这些数据库中导入和分析数据&#xff1b;可以直接上传Excel文件作为数据源。 …

Prompt Engineering Guide

本文转载自&#xff1a;Prompt Engineering Guide https://www.promptingguide.ai/zh/introduction/basics 文章目录 提示工程简介1、基本概念1&#xff09;基础提示词2&#xff09;提示词格式 2、提示词要素3、设计提示的通用技巧从简单开始指令具体性避免不精确做还是不做&am…

编译aosp刷入pixel 真机得问题记录

编译aosp要做什么&#xff08;ubuntu下编译问题相对少&#xff09; 需要vmware并且已经安装了ubuntu镜像系统 直接切换到root 避免后期避免麻烦 参考地址 https://mp.weixin.qq.com/s/yJp3ijIxykiMmNVYr2V1nQ apt install git //安装git sudo apt install git//给git设置用户…

CDN用户平台安装说明

CDN用户平台安装说明 登录管理员系统 在”系统设置” – “高级设置” – “用户节点”中点击”添加节点” 如果所示&#xff1a; 节点名称 - 可以任意填写 进程监听端口 - 启动用户节点后&#xff0c;进程所监听的端口&#xff0c;通常是HTTP 80或者HTTPS 443&#xff0c;…

Django中使用Celery(通用方案、官方方案)

Django中使用Celery&#xff08;通用方案、官方方案&#xff09; 目录 Django中使用Celery&#xff08;通用方案、官方方案&#xff09;通用方案场景前置准备完整代码 Celery官方方案【1】注册celery配置【2】创建celery文件【3】init注册【4】添加任务【5】启动worker异步任务…