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

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
在这里插入图片描述

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值