Răsfoiți Sursa

Merge branch 'feature/TW14048_optimize_tcp_perf_example' into 'master'

feature/TW14048_optimize_tcp_perf_example

See merge request !1041

Ivan Grokhotkov 8 ani în urmă
părinte
comite
cd5cc9927b

+ 66 - 50
examples/performance/tcp_perf/main/tcp_main.c

@@ -36,75 +36,91 @@ step3:
 
 #include "tcp_perf.h"
 
-
-
 //this task establish a TCP connection and receive data from TCP
 static void tcp_conn(void *pvParameters)
 {
-    ESP_LOGI(TAG, "task tcp_conn.");
-    /*wating for connecting to AP*/
-    xEventGroupWaitBits(tcp_event_group, WIFI_CONNECTED_BIT,false, true, portMAX_DELAY);
-
-    ESP_LOGI(TAG, "sta has connected to ap.");
-    
-    /*create tcp socket*/
-    int socket_ret;
-    
+    while (1) {
+
+        g_rxtx_need_restart = false;
+
+        ESP_LOGI(TAG, "task tcp_conn.");
+
+        /*wating for connecting to AP*/
+        xEventGroupWaitBits(tcp_event_group, WIFI_CONNECTED_BIT, false, true, portMAX_DELAY);
+
+        ESP_LOGI(TAG, "sta has connected to ap.");
+
+        int socket_ret = ESP_FAIL;
+
+        TaskHandle_t tx_rx_task = NULL;
+
 #if EXAMPLE_ESP_TCP_MODE_SERVER
-    ESP_LOGI(TAG, "tcp_server will start after 3s...");
-    vTaskDelay(3000 / portTICK_RATE_MS);
-    ESP_LOGI(TAG, "create_tcp_server.");
-    socket_ret=create_tcp_server();
+        if (socket_ret == ESP_FAIL) {
+            /*create tcp socket*/
+            ESP_LOGI(TAG, "tcp_server will start after 3s...");
+            vTaskDelay(3000 / portTICK_RATE_MS);
+            ESP_LOGI(TAG, "create_tcp_server.");
+            socket_ret = create_tcp_server();
+        }
 #else /*EXAMPLE_ESP_TCP_MODE_SERVER*/
-    ESP_LOGI(TAG, "tcp_client will start after 20s...");
-    vTaskDelay(20000 / portTICK_RATE_MS);
-    ESP_LOGI(TAG, "create_tcp_client.");
-    socket_ret = create_tcp_client();
+        if (socket_ret == ESP_FAIL) {
+            ESP_LOGI(TAG, "tcp_client will start after 20s...");
+            vTaskDelay(20000 / portTICK_RATE_MS);
+            ESP_LOGI(TAG, "create_tcp_client.");
+            socket_ret = create_tcp_client();
+        }
 #endif
-    if(socket_ret == ESP_FAIL) {
-	ESP_LOGI(TAG, "create tcp socket error,stop.");
-	vTaskDelete(NULL);
-    }
-    
-    /*create a task to tx/rx data*/
-    TaskHandle_t tx_rx_task;
+        if (socket_ret == ESP_FAIL) {
+            ESP_LOGI(TAG, "create tcp socket error,stop.");
+            continue;
+        }
+
+        /*create a task to tx/rx data*/
+
 #if EXAMPLE_ESP_TCP_PERF_TX
-    xTaskCreate(&send_data, "send_data", 4096, NULL, 4, &tx_rx_task);
+        if (tx_rx_task == NULL) {
+            if (pdPASS != xTaskCreate(&send_data, "send_data", 4096, NULL, 4, &tx_rx_task)) {
+                ESP_LOGE(TAG, "Send task create fail!");
+            }
+        }
 #else /*EXAMPLE_ESP_TCP_PERF_TX*/
-    xTaskCreate(&recv_data, "recv_data", 4096, NULL, 4, &tx_rx_task);
+        if (tx_rx_task == NULL) {
+            if (pdPASS != xTaskCreate(&recv_data, "recv_data", 4096, NULL, 4, &tx_rx_task)) {
+                ESP_LOGE(TAG, "Recv task create fail!");
+            }
+        }
 #endif
-    int bps;
-    while (1) {
-	total_data = 0;
-	vTaskDelay(3000 / portTICK_RATE_MS);//every 3s
-	bps = total_data / 3;
-	if (total_data <= 0) {
-	    int err_ret = check_working_socket();
-	    if (err_ret == ECONNRESET || ECONNABORTED) {
-		ESP_LOGW(TAG, "tcp disconnected... stop.\n");
-		break;
-	    }
-	}
+        double bps;
+
+        while (1) {
+            g_total_data = 0;
+            vTaskDelay(3000 / portTICK_RATE_MS);//every 3s
+            bps = (g_total_data * 8.0 / 3.0) / 1000000.0;
+
+            if (g_rxtx_need_restart) {
+                printf("send or receive task encoutner error, need to restart\n");
+                break;
+            }
 
 #if EXAMPLE_ESP_TCP_PERF_TX
-	ESP_LOGI(TAG, "tcp send %d byte per sec!", bps);
+            ESP_LOGI(TAG, "tcp send %.2f Mbits per sec!\n", bps);
 #if EXAMPLE_ESP_TCP_DELAY_INFO
-	ESP_LOGI(TAG, "tcp send packet total:%d  succeed:%d  failed:%d\n"
-		"time(ms):0-30:%d 30-100:%d 100-300:%d 300-1000:%d 1000+:%d\n",
-		total_pack, send_success, send_fail, delay_classify[0],
-		delay_classify[1], delay_classify[2], delay_classify[3], delay_classify[4]);
+            ESP_LOGI(TAG, "tcp send packet total:%d  succeed:%d  failed:%d\n"
+                     "time(ms):0-30:%d 30-100:%d 100-300:%d 300-1000:%d 1000+:%d\n",
+                     g_total_pack, g_send_success, g_send_fail, g_delay_classify[0],
+                     g_delay_classify[1], g_delay_classify[2], g_delay_classify[3], g_delay_classify[4]);
 #endif /*EXAMPLE_ESP_TCP_DELAY_INFO*/
 #else
-	ESP_LOGI(TAG, "tcp recv %d byte per sec!\n", bps);
+            ESP_LOGI(TAG, "tcp recv %.2f Mbits per sec!\n", bps);
 #endif /*EXAMPLE_ESP_TCP_PERF_TX*/
+        }
+
+        close_socket();
     }
-    close_socket();
-    vTaskDelete(tx_rx_task);
+
     vTaskDelete(NULL);
 }
 
-
-
 void app_main(void)
 {
 #if EXAMPLE_ESP_WIFI_MODE_AP

+ 133 - 102
examples/performance/tcp_perf/main/tcp_perf.c

@@ -29,15 +29,16 @@ static struct sockaddr_in server_addr;
 static struct sockaddr_in client_addr;
 static unsigned int socklen = sizeof(client_addr);
 static int connect_socket = 0;
+bool g_rxtx_need_restart = false;
 
-int total_data = 0;
+int g_total_data = 0;
 
 #if EXAMPLE_ESP_TCP_PERF_TX && EXAMPLE_ESP_TCP_DELAY_INFO
 
-int total_pack = 0;
-int send_success = 0;
-int send_fail = 0;
-int delay_classify[5] = { 0 };
+int g_total_pack = 0;
+int g_send_success = 0;
+int g_send_fail = 0;
+int g_delay_classify[5] = { 0 };
 
 #endif /*EXAMPLE_ESP_TCP_PERF_TX && EXAMPLE_ESP_TCP_DELAY_INFO*/
 
@@ -46,7 +47,7 @@ int delay_classify[5] = { 0 };
 
 static esp_err_t event_handler(void *ctx, system_event_t *event)
 {
-    switch(event->event_id) {
+    switch (event->event_id) {
     case SYSTEM_EVENT_STA_START:
         esp_wifi_connect();
         break;
@@ -57,22 +58,22 @@ static esp_err_t event_handler(void *ctx, system_event_t *event)
     case SYSTEM_EVENT_STA_CONNECTED:
         break;
     case SYSTEM_EVENT_STA_GOT_IP:
-    	ESP_LOGI(TAG, "got ip:%s\n",
-		ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip));
-    	xEventGroupSetBits(tcp_event_group, WIFI_CONNECTED_BIT);
+        ESP_LOGI(TAG, "got ip:%s\n",
+                 ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip));
+        xEventGroupSetBits(tcp_event_group, WIFI_CONNECTED_BIT);
         break;
     case SYSTEM_EVENT_AP_STACONNECTED:
-    	ESP_LOGI(TAG, "station:"MACSTR" join,AID=%d\n",
-		MAC2STR(event->event_info.sta_connected.mac),
-		event->event_info.sta_connected.aid);
-    	xEventGroupSetBits(tcp_event_group, WIFI_CONNECTED_BIT);
-    	break;
+        ESP_LOGI(TAG, "station:"MACSTR" join,AID=%d\n",
+                 MAC2STR(event->event_info.sta_connected.mac),
+                 event->event_info.sta_connected.aid);
+        xEventGroupSetBits(tcp_event_group, WIFI_CONNECTED_BIT);
+        break;
     case SYSTEM_EVENT_AP_STADISCONNECTED:
-    	ESP_LOGI(TAG, "station:"MACSTR"leave,AID=%d\n",
-		MAC2STR(event->event_info.sta_disconnected.mac),
-		event->event_info.sta_disconnected.aid);
-    	xEventGroupClearBits(tcp_event_group, WIFI_CONNECTED_BIT);
-    	break;
+        ESP_LOGI(TAG, "station:"MACSTR"leave,AID=%d\n",
+                 MAC2STR(event->event_info.sta_disconnected.mac),
+                 event->event_info.sta_disconnected.aid);
+        xEventGroupClearBits(tcp_event_group, WIFI_CONNECTED_BIT);
+        break;
     default:
         break;
     }
@@ -83,9 +84,9 @@ static esp_err_t event_handler(void *ctx, system_event_t *event)
 void send_data(void *pvParameters)
 {
     int len = 0;
-    char databuff[EXAMPLE_DEFAULT_PKTSIZE];
+    char *databuff = (char *)malloc(EXAMPLE_DEFAULT_PKTSIZE * sizeof(char));
     memset(databuff, EXAMPLE_PACK_BYTE_IS, EXAMPLE_DEFAULT_PKTSIZE);
-    vTaskDelay(100/portTICK_RATE_MS);
+    vTaskDelay(100 / portTICK_RATE_MS);
     ESP_LOGI(TAG, "start sending...");
 #if EXAMPLE_ESP_TCP_PERF_TX && EXAMPLE_ESP_TCP_DELAY_INFO
     //delaytime
@@ -93,66 +94,89 @@ void send_data(void *pvParameters)
     struct timeval tv_finish;
     unsigned long send_delay_ms;
 #endif /*EXAMPLE_ESP_TCP_PERF_TX && EXAMPLE_ESP_TCP_DELAY_INFO*/
-    while(1) {
+    while (1) {
+        int to_write = EXAMPLE_DEFAULT_PKTSIZE;
 
 #if EXAMPLE_ESP_TCP_PERF_TX && EXAMPLE_ESP_TCP_DELAY_INFO
-    	total_pack++;
-    	gettimeofday(&tv_start, NULL);
+        g_total_pack++;
+        gettimeofday(&tv_start, NULL);
 #endif /*EXAMPLE_ESP_TCP_PERF_TX && EXAMPLE_ESP_TCP_DELAY_INFO*/
-    	
-	//send function
-    	len = send(connect_socket, databuff, EXAMPLE_DEFAULT_PKTSIZE, 0);
 
+        //send function
+        while (to_write > 0) {
+            len = send(connect_socket, databuff + (EXAMPLE_DEFAULT_PKTSIZE - to_write), to_write, 0);
+            if (len > 0) {
+                g_total_data += len;
+                to_write -= len;
+            } else {
+                int err = get_socket_error_code(connect_socket);
 #if EXAMPLE_ESP_TCP_PERF_TX && EXAMPLE_ESP_TCP_DELAY_INFO
-    	gettimeofday(&tv_finish, NULL);
+                g_send_fail++;
 #endif /*EXAMPLE_ESP_TCP_PERF_TX && EXAMPLE_ESP_TCP_DELAY_INFO*/
-	if(len > 0) {
-	    total_data += len;
-	    
+
+                if (err != ENOMEM) {
+                    show_socket_error_reason("send_data", connect_socket);
+                    break;
+                }
+            }
+        }
+
 #if EXAMPLE_ESP_TCP_PERF_TX && EXAMPLE_ESP_TCP_DELAY_INFO
-	    send_success++;
-	    send_delay_ms = (tv_finish.tv_sec - tv_start.tv_sec) * 1000
-		+ (tv_finish.tv_usec - tv_start.tv_usec) / 1000;
-	    if(send_delay_ms < 30)
-		delay_classify[0]++;
-	    else if(send_delay_ms < 100)
-		delay_classify[1]++;
-	    else if(send_delay_ms < 300)
-		delay_classify[2]++;
-	    else if(send_delay_ms < 1000)
-		delay_classify[3]++;
-	    else
-		delay_classify[4]++;
+        gettimeofday(&tv_finish, NULL);
 #endif /*EXAMPLE_ESP_TCP_PERF_TX && EXAMPLE_ESP_TCP_DELAY_INFO*/
-	
-	} else {
-
+        if (g_total_data > 0) {
 #if EXAMPLE_ESP_TCP_PERF_TX && EXAMPLE_ESP_TCP_DELAY_INFO
-	    send_fail++;
+            g_send_success++;
+            send_delay_ms = (tv_finish.tv_sec - tv_start.tv_sec) * 1000
+                            + (tv_finish.tv_usec - tv_start.tv_usec) / 1000;
+            if (send_delay_ms < 30) {
+                g_delay_classify[0]++;
+            } else if (send_delay_ms < 100) {
+                g_delay_classify[1]++;
+            } else if (send_delay_ms < 300) {
+                g_delay_classify[2]++;
+            } else if (send_delay_ms < 1000) {
+                g_delay_classify[3]++;
+            } else {
+                g_delay_classify[4]++;
+            }
 #endif /*EXAMPLE_ESP_TCP_PERF_TX && EXAMPLE_ESP_TCP_DELAY_INFO*/
-
-	    if (LOG_LOCAL_LEVEL >= ESP_LOG_DEBUG) {
-	    	show_socket_error_reason(connect_socket);
-	    }
-	} /*if(len > 0)*/
-    } 
+        } else {
+            break;
+        }
+    }
+    g_rxtx_need_restart = true;
+    free(databuff);
+    vTaskDelete(NULL);
 }
+
 //receive data
 void recv_data(void *pvParameters)
 {
     int len = 0;
-    char databuff[EXAMPLE_DEFAULT_PKTSIZE];
+    char *databuff = (char *)malloc(EXAMPLE_DEFAULT_PKTSIZE * sizeof(char));
     while (1) {
-	len = recv(connect_socket, databuff, EXAMPLE_DEFAULT_PKTSIZE, 0);
-	if (len > 0) {
-	    total_data += len;
-	} else {
-            if (LOG_LOCAL_LEVEL >= ESP_LOG_DEBUG) {
-	        show_socket_error_reason(connect_socket);
+        int to_recv = EXAMPLE_DEFAULT_PKTSIZE;
+        while (to_recv > 0) {
+            len = recv(connect_socket, databuff + (EXAMPLE_DEFAULT_PKTSIZE - to_recv), to_recv, 0);
+            if (len > 0) {
+                g_total_data += len;
+                to_recv -= len;
+            } else {
+                show_socket_error_reason("recv_data", connect_socket);
+                break;
             }
-	    vTaskDelay(100 / portTICK_RATE_MS);
-	}
+        }
+        if (g_total_data > 0) {
+            continue;
+        } else {
+            break;
+        }
     }
+
+    g_rxtx_need_restart = true;
+    free(databuff);
+    vTaskDelete(NULL);
 }
 
 
@@ -162,27 +186,28 @@ esp_err_t create_tcp_server()
     ESP_LOGI(TAG, "server socket....port=%d\n", EXAMPLE_DEFAULT_PORT);
     server_socket = socket(AF_INET, SOCK_STREAM, 0);
     if (server_socket < 0) {
-    	show_socket_error_reason(server_socket);
-	return ESP_FAIL;
+        show_socket_error_reason("create_server", server_socket);
+        return ESP_FAIL;
     }
+
     server_addr.sin_family = AF_INET;
     server_addr.sin_port = htons(EXAMPLE_DEFAULT_PORT);
     server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
-    if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
-    	show_socket_error_reason(server_socket);
-	close(server_socket);
-	return ESP_FAIL;
+    if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
+        show_socket_error_reason("bind_server", server_socket);
+        close(server_socket);
+        return ESP_FAIL;
     }
     if (listen(server_socket, 5) < 0) {
-    	show_socket_error_reason(server_socket);
-	close(server_socket);
-	return ESP_FAIL;
+        show_socket_error_reason("listen_server", server_socket);
+        close(server_socket);
+        return ESP_FAIL;
     }
-    connect_socket = accept(server_socket, (struct sockaddr*)&client_addr, &socklen);
-    if (connect_socket<0) {
-    	show_socket_error_reason(connect_socket);
-	close(server_socket);
-	return ESP_FAIL;
+    connect_socket = accept(server_socket, (struct sockaddr *)&client_addr, &socklen);
+    if (connect_socket < 0) {
+        show_socket_error_reason("accept_server", connect_socket);
+        close(server_socket);
+        return ESP_FAIL;
     }
     /*connection established,now can send/recv*/
     ESP_LOGI(TAG, "tcp connection established!");
@@ -191,20 +216,20 @@ esp_err_t create_tcp_server()
 //use this esp32 as a tcp client. return ESP_OK:success ESP_FAIL:error
 esp_err_t create_tcp_client()
 {
-    ESP_LOGI(TAG, "client socket....serverip:port=%s:%d\n", 
-    		EXAMPLE_DEFAULT_SERVER_IP, EXAMPLE_DEFAULT_PORT);
+    ESP_LOGI(TAG, "client socket....serverip:port=%s:%d\n",
+             EXAMPLE_DEFAULT_SERVER_IP, EXAMPLE_DEFAULT_PORT);
     connect_socket = socket(AF_INET, SOCK_STREAM, 0);
     if (connect_socket < 0) {
-    	show_socket_error_reason(connect_socket);
-	return ESP_FAIL;
+        show_socket_error_reason("create client", connect_socket);
+        return ESP_FAIL;
     }
     server_addr.sin_family = AF_INET;
     server_addr.sin_port = htons(EXAMPLE_DEFAULT_PORT);
     server_addr.sin_addr.s_addr = inet_addr(EXAMPLE_DEFAULT_SERVER_IP);
     ESP_LOGI(TAG, "connecting to server...");
     if (connect(connect_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
-    	show_socket_error_reason(connect_socket);
-	return ESP_FAIL;
+        show_socket_error_reason("client connect", connect_socket);
+        return ESP_FAIL;
     }
     ESP_LOGI(TAG, "connect to server success!");
     return ESP_OK;
@@ -233,7 +258,7 @@ void wifi_init_sta()
 
     ESP_LOGI(TAG, "wifi_init_sta finished.");
     ESP_LOGI(TAG, "connect to ap SSID:%s password:%s \n",
-	    EXAMPLE_DEFAULT_SSID,EXAMPLE_DEFAULT_PWD);
+             EXAMPLE_DEFAULT_SSID, EXAMPLE_DEFAULT_PWD);
 }
 //wifi_init_softap
 void wifi_init_softap()
@@ -249,13 +274,13 @@ void wifi_init_softap()
         .ap = {
             .ssid = EXAMPLE_DEFAULT_SSID,
             .ssid_len = 0,
-            .max_connection=EXAMPLE_MAX_STA_CONN,
+            .max_connection = EXAMPLE_MAX_STA_CONN,
             .password = EXAMPLE_DEFAULT_PWD,
             .authmode = WIFI_AUTH_WPA_WPA2_PSK
         },
     };
-    if (strlen(EXAMPLE_DEFAULT_PWD) ==0) {
-	wifi_config.ap.authmode = WIFI_AUTH_OPEN;
+    if (strlen(EXAMPLE_DEFAULT_PWD) == 0) {
+        wifi_config.ap.authmode = WIFI_AUTH_OPEN;
     }
 
     ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
@@ -263,7 +288,7 @@ void wifi_init_softap()
     ESP_ERROR_CHECK(esp_wifi_start());
 
     ESP_LOGI(TAG, "wifi_init_softap finished.SSID:%s password:%s \n",
-    	    EXAMPLE_DEFAULT_SSID, EXAMPLE_DEFAULT_PWD);
+             EXAMPLE_DEFAULT_SSID, EXAMPLE_DEFAULT_PWD);
 }
 
 
@@ -273,17 +298,22 @@ int get_socket_error_code(int socket)
 {
     int result;
     u32_t optlen = sizeof(int);
-    if(getsockopt(socket, SOL_SOCKET, SO_ERROR, &result, &optlen) == -1) {
-	ESP_LOGE(TAG, "getsockopt failed");
-	return -1;
+    int err = getsockopt(socket, SOL_SOCKET, SO_ERROR, &result, &optlen);
+    if (err == -1) {
+        ESP_LOGE(TAG, "getsockopt failed:%s", strerror(err));
+        return -1;
     }
     return result;
 }
 
-int show_socket_error_reason(int socket)
+int show_socket_error_reason(const char *str, int socket)
 {
     int err = get_socket_error_code(socket);
-    ESP_LOGW(TAG, "socket error %d %s", err, strerror(err));
+
+    if (err != 0) {
+        ESP_LOGW(TAG, "%s socket error %d %s", str, err, strerror(err));
+    }
+
     return err;
 }
 
@@ -293,19 +323,21 @@ int check_working_socket()
 #if EXAMPLE_ESP_TCP_MODE_SERVER
     ESP_LOGD(TAG, "check server_socket");
     ret = get_socket_error_code(server_socket);
-    if(ret != 0) {
-	ESP_LOGW(TAG, "server socket error %d %s", ret, strerror(ret));
+    if (ret != 0) {
+        ESP_LOGW(TAG, "server socket error %d %s", ret, strerror(ret));
+    }
+    if (ret == ECONNRESET) {
+        return ret;
     }
-    if(ret == ECONNRESET)
-	return ret;
 #endif
     ESP_LOGD(TAG, "check connect_socket");
     ret = get_socket_error_code(connect_socket);
-    if(ret != 0) {
-	ESP_LOGW(TAG, "connect socket error %d %s", ret, strerror(ret));
+    if (ret != 0) {
+        ESP_LOGW(TAG, "connect socket error %d %s", ret, strerror(ret));
+    }
+    if (ret != 0) {
+        return ret;
     }
-    if(ret != 0)
-	return ret;
     return 0;
 }
 
@@ -315,4 +347,3 @@ void close_socket()
     close(server_socket);
 }
 
-

+ 7 - 6
examples/performance/tcp_perf/main/tcp_perf.h

@@ -46,13 +46,14 @@ extern "C" {
 extern EventGroupHandle_t tcp_event_group;
 #define WIFI_CONNECTED_BIT BIT0
 
-extern int total_data;
+extern int  g_total_data;
+extern bool g_rxtx_need_restart;
 
 #if EXAMPLE_ESP_TCP_PERF_TX && EXAMPLE_ESP_TCP_DELAY_INFO
-extern int total_pack;
-extern int send_success;
-extern int send_fail;
-extern int delay_classify[5];
+extern int g_total_pack;
+extern int g_send_success;
+extern int g_send_fail;
+extern int g_delay_classify[5];
 #endif/*EXAMPLE_ESP_TCP_PERF_TX && EXAMPLE_ESP_TCP_DELAY_INFO*/
 
 
@@ -78,7 +79,7 @@ void close_socket();
 int get_socket_error_code(int socket);
 
 //show socket error code. return: error code
-int show_socket_error_reason(int socket);
+int show_socket_error_reason(const char* str, int socket);
 
 //check working socket
 int check_working_socket();