feat(iperf): use iperf component in iperf example

pull/13854/head
Bogdan Kolendovskyy 2024-04-02 14:58:26 +02:00
rodzic c782708f0f
commit a23d1b45af
6 zmienionych plików z 78 dodań i 253 usunięć

Wyświetl plik

@ -1,3 +1,3 @@
idf_component_register(SRCS "cmd_ethernet.c"
"ethernet_example_main.c"
"ethernet_iperf_main.c"
INCLUDE_DIRS ".")

Wyświetl plik

@ -1,35 +1,17 @@
/* Console example — Ethernet commands
/*
* SPDX-FileCopyrightText: 2018-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "sys/socket.h" // for INADDR_ANY
#include "cmd_ethernet.h"
#include "esp_netif.h"
#include "esp_log.h"
#include "esp_console.h"
#include "esp_event.h"
#include "esp_eth.h"
#include "esp_mac.h"
#include "esp_bit_defs.h"
#include "argtable3/argtable3.h"
#include "ethernet_init.h"
#include "iperf.h"
#include "sdkconfig.h"
static bool started = false;
static EventGroupHandle_t eth_event_group;
static const int GOTIP_BIT = BIT0;
static esp_eth_handle_t *s_eth_handles = NULL;
static uint8_t s_eth_port_cnt = 0;
static esp_netif_t **s_eth_netifs = NULL;
/* "ethernet" command */
static struct {
@ -48,199 +30,26 @@ static int eth_cmd_control(int argc, char **argv)
if (!strncmp(eth_control_args.control->sval[0], "info", 4)) {
uint8_t mac_addr[6];
esp_netif_ip_info_t ip;
for(uint32_t i = 0; i < s_eth_port_cnt; i++) {
printf("%s:\r\n", esp_netif_get_desc(s_eth_netifs[i]));
esp_eth_ioctl(s_eth_handles[i], ETH_CMD_G_MAC_ADDR, mac_addr);
esp_netif_t *esp_netif;
// we can use esp_netif_next_unsafe since we one time initialize the network and we don't de-init
esp_netif = esp_netif_next_unsafe(NULL);
while(esp_netif != NULL) {
printf("%s:\r\n", esp_netif_get_desc(esp_netif));
esp_eth_handle_t eth_hndl = esp_netif_get_io_driver(esp_netif);
esp_eth_ioctl(eth_hndl, ETH_CMD_G_MAC_ADDR, mac_addr);
printf(" HW ADDR: " MACSTR "\r\n", MAC2STR(mac_addr));
esp_netif_get_ip_info(s_eth_netifs[i], &ip);
esp_netif_get_ip_info(esp_netif, &ip);
printf(" ETHIP: " IPSTR "\r\n", IP2STR(&ip.ip));
printf(" ETHMASK: " IPSTR "\r\n", IP2STR(&ip.netmask));
printf(" ETHGW: " IPSTR "\r\n", IP2STR(&ip.gw));
esp_netif = esp_netif_next_unsafe(esp_netif);
}
}
return 0;
}
/* "iperf" command */
static struct {
struct arg_str *ip;
struct arg_lit *server;
struct arg_lit *udp;
struct arg_lit *version;
struct arg_int *port;
struct arg_int *length;
struct arg_int *interval;
struct arg_int *time;
struct arg_int *bw_limit;
struct arg_lit *abort;
struct arg_end *end;
} iperf_args;
static int eth_cmd_iperf(int argc, char **argv)
void register_ethernet_commands(void)
{
int nerrors = arg_parse(argc, argv, (void **)&iperf_args);
iperf_cfg_t cfg;
if (nerrors != 0) {
arg_print_errors(stderr, iperf_args.end, argv[0]);
return 0;
}
memset(&cfg, 0, sizeof(cfg));
// ethernet iperf only support IPV4 address
cfg.type = IPERF_IP_TYPE_IPV4;
/* iperf -a */
if (iperf_args.abort->count != 0) {
iperf_stop();
return 0;
}
if (((iperf_args.ip->count == 0) && (iperf_args.server->count == 0)) ||
((iperf_args.ip->count != 0) && (iperf_args.server->count != 0))) {
ESP_LOGE(__func__, "Wrong mode! ESP32 should run in client or server mode");
return 0;
}
/* iperf -s */
if (iperf_args.ip->count == 0) {
cfg.flag |= IPERF_FLAG_SERVER;
}
/* iperf -c SERVER_ADDRESS */
else {
cfg.destination_ip4 = esp_ip4addr_aton(iperf_args.ip->sval[0]);
cfg.flag |= IPERF_FLAG_CLIENT;
}
if (iperf_args.length->count == 0) {
cfg.len_send_buf = 0;
} else {
cfg.len_send_buf = iperf_args.length->ival[0];
}
/* wait for ip, could blocked here */
xEventGroupWaitBits(eth_event_group, GOTIP_BIT, pdFALSE, pdTRUE, portMAX_DELAY);
cfg.source_ip4 = INADDR_ANY;
/* iperf -u */
if (iperf_args.udp->count == 0) {
cfg.flag |= IPERF_FLAG_TCP;
} else {
cfg.flag |= IPERF_FLAG_UDP;
}
/* iperf -p */
if (iperf_args.port->count == 0) {
cfg.sport = IPERF_DEFAULT_PORT;
cfg.dport = IPERF_DEFAULT_PORT;
} else {
if (cfg.flag & IPERF_FLAG_SERVER) {
cfg.sport = iperf_args.port->ival[0];
cfg.dport = IPERF_DEFAULT_PORT;
} else {
cfg.sport = IPERF_DEFAULT_PORT;
cfg.dport = iperf_args.port->ival[0];
}
}
/* iperf -i */
if (iperf_args.interval->count == 0) {
cfg.interval = IPERF_DEFAULT_INTERVAL;
} else {
cfg.interval = iperf_args.interval->ival[0];
if (cfg.interval <= 0) {
cfg.interval = IPERF_DEFAULT_INTERVAL;
}
}
/* iperf -t */
if (iperf_args.time->count == 0) {
cfg.time = IPERF_DEFAULT_TIME;
} else {
cfg.time = iperf_args.time->ival[0];
if (cfg.time <= cfg.interval) {
cfg.time = cfg.interval;
}
}
/* iperf -b */
if (iperf_args.bw_limit->count == 0) {
cfg.bw_lim = IPERF_DEFAULT_NO_BW_LIMIT;
} else {
cfg.bw_lim = iperf_args.bw_limit->ival[0];
if (cfg.bw_lim <= 0) {
cfg.bw_lim = IPERF_DEFAULT_NO_BW_LIMIT;
}
}
printf("mode=%s-%s sip=" IPSTR ":%" PRIu16 ", dip=%" PRIu32 ".%" PRIu32 ".%" PRIu32 ".%" PRIu32 ":%" PRIu16 ", interval=%" PRIu32 ", time=%" PRIu32 "\r\n",
cfg.flag & IPERF_FLAG_TCP ? "tcp" : "udp",
cfg.flag & IPERF_FLAG_SERVER ? "server" : "client",
(uint16_t) cfg.source_ip4 & 0xFF,
(uint16_t) (cfg.source_ip4 >> 8) & 0xFF,
(uint16_t) (cfg.source_ip4 >> 16) & 0xFF,
(uint16_t) (cfg.source_ip4 >> 24) & 0xFF,
cfg.sport,
cfg.destination_ip4 & 0xFF, (cfg.destination_ip4 >> 8) & 0xFF,
(cfg.destination_ip4 >> 16) & 0xFF, (cfg.destination_ip4 >> 24) & 0xFF, cfg.dport,
cfg.interval, cfg.time);
iperf_start(&cfg);
return 0;
}
static void event_handler(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
if (event_base == ETH_EVENT && event_id == ETHERNET_EVENT_START) {
started = true;
} else if (event_base == ETH_EVENT && event_id == ETHERNET_EVENT_STOP) {
xEventGroupClearBits(eth_event_group, GOTIP_BIT);
started = false;
} else if (event_base == IP_EVENT && event_id == IP_EVENT_ETH_GOT_IP) {
xEventGroupSetBits(eth_event_group, GOTIP_BIT);
}
}
void register_ethernet(void)
{
eth_event_group = xEventGroupCreate();
ESP_ERROR_CHECK(esp_event_loop_create_default());
ESP_ERROR_CHECK(example_eth_init(&s_eth_handles, &s_eth_port_cnt));
ESP_ERROR_CHECK(esp_netif_init());
s_eth_netifs = calloc(s_eth_port_cnt, sizeof(esp_netif_t *));
esp_netif_inherent_config_t esp_netif_config = ESP_NETIF_INHERENT_DEFAULT_ETH();
esp_netif_config_t cfg_spi = {
.base = &esp_netif_config,
.stack = ESP_NETIF_NETSTACK_DEFAULT_ETH
};
char if_key_str[10];
char if_desc_str[10];
char num_str[3];
for (int i = 0; i < s_eth_port_cnt; i++) {
itoa(i, num_str, 10);
strcat(strcpy(if_key_str, "ETH_"), num_str);
strcat(strcpy(if_desc_str, "eth"), num_str);
esp_netif_config.if_key = if_key_str;
esp_netif_config.if_desc = if_desc_str;
esp_netif_config.route_prio -= i*5;
s_eth_netifs[i] = esp_netif_new(&cfg_spi);
// attach Ethernet driver to TCP/IP stack
ESP_ERROR_CHECK(esp_netif_attach(s_eth_netifs[i], esp_eth_new_netif_glue(s_eth_handles[i])));
}
ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &event_handler, NULL));
for (int i = 0; i < s_eth_port_cnt; i++) {
ESP_ERROR_CHECK(esp_eth_start(s_eth_handles[i]));
}
eth_control_args.control = arg_str1(NULL, NULL, "<info>", "Get info of Ethernet");
eth_control_args.end = arg_end(1);
const esp_console_cmd_t cmd = {
@ -251,27 +60,4 @@ void register_ethernet(void)
.argtable = &eth_control_args
};
ESP_ERROR_CHECK(esp_console_cmd_register(&cmd));
iperf_args.ip = arg_str0("c", "client", "<ip>",
"run in client mode, connecting to <host>");
iperf_args.server = arg_lit0("s", "server", "run in server mode");
iperf_args.udp = arg_lit0("u", "udp", "use UDP rather than TCP");
iperf_args.version = arg_lit0("V", "ipv6_domain", "use IPV6 address rather than IPV4");
iperf_args.port = arg_int0("p", "port", "<port>",
"server port to listen on/connect to");
iperf_args.length = arg_int0("l", "len", "<length>", "set read/write buffer size");
iperf_args.interval = arg_int0("i", "interval", "<interval>",
"seconds between periodic bandwidth reports");
iperf_args.time = arg_int0("t", "time", "<time>", "time in seconds to transmit for (default 10 secs)");
iperf_args.bw_limit = arg_int0("b", "bandwidth", "<bandwidth>", "bandwidth to send at in Mbits/sec");
iperf_args.abort = arg_lit0("a", "abort", "abort running iperf");
iperf_args.end = arg_end(1);
const esp_console_cmd_t iperf_cmd = {
.command = "iperf",
.help = "iperf command",
.hint = NULL,
.func = &eth_cmd_iperf,
.argtable = &iperf_args
};
ESP_ERROR_CHECK(esp_console_cmd_register(&iperf_cmd));
}

Wyświetl plik

@ -1,19 +1,20 @@
/* Console example — declarations of command registration functions.
/*
* SPDX-FileCopyrightText: 2018-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include "esp_netif.h"
#include "esp_eth.h"
// Register Ethernet functions
void register_ethernet(void);
void register_ethernet_commands(void);
#ifdef __cplusplus
}

Wyświetl plik

@ -1,23 +1,28 @@
/* Ethernet iperf example
/*
* SPDX-FileCopyrightText: 2018-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include <string.h>
#include "sdkconfig.h"
#include "esp_log.h"
#include "esp_console.h"
#include "esp_event.h"
#include "esp_eth.h"
#include "esp_netif.h"
#include "ethernet_init.h"
#include "esp_vfs_fat.h"
#include "cmd_system.h"
#include "cmd_ethernet.h"
#include "iperf_cmd.h"
static const char *TAG = "eth_example";
static esp_eth_handle_t *s_eth_handles = NULL;
static uint8_t s_eth_port_cnt = 0;
#if CONFIG_EXAMPLE_STORE_HISTORY
#define MOUNT_PATH "/data"
@ -38,8 +43,43 @@ static void initialize_filesystem(void)
}
#endif // CONFIG_EXAMPLE_STORE_HISTORY
void init_ethernet_and_netif(void)
{
ESP_ERROR_CHECK(esp_event_loop_create_default());
ESP_ERROR_CHECK(example_eth_init(&s_eth_handles, &s_eth_port_cnt));
ESP_ERROR_CHECK(esp_netif_init());
esp_netif_inherent_config_t esp_netif_config = ESP_NETIF_INHERENT_DEFAULT_ETH();
esp_netif_config_t cfg_spi = {
.base = &esp_netif_config,
.stack = ESP_NETIF_NETSTACK_DEFAULT_ETH
};
char if_key_str[10];
char if_desc_str[10];
char num_str[3];
for (int i = 0; i < s_eth_port_cnt; i++) {
itoa(i, num_str, 10);
strcat(strcpy(if_key_str, "ETH_"), num_str);
strcat(strcpy(if_desc_str, "eth"), num_str);
esp_netif_config.if_key = if_key_str;
esp_netif_config.if_desc = if_desc_str;
esp_netif_config.route_prio -= i*5;
esp_netif_t *eth_netif = esp_netif_new(&cfg_spi);
// attach Ethernet driver to TCP/IP stack
ESP_ERROR_CHECK(esp_netif_attach(eth_netif, esp_eth_new_netif_glue(s_eth_handles[i])));
}
for (int i = 0; i < s_eth_port_cnt; i++) {
ESP_ERROR_CHECK(esp_eth_start(s_eth_handles[i]));
}
}
void app_main(void)
{
init_ethernet_and_netif();
esp_console_repl_t *repl = NULL;
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
esp_console_dev_uart_config_t uart_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT();
@ -53,7 +93,8 @@ void app_main(void)
/* Register commands */
register_system_common();
register_ethernet();
app_register_iperf_commands();
register_ethernet_commands();
printf("\n =======================================================\n");
printf(" | Steps to Test Ethernet Bandwidth |\n");

Wyświetl plik

@ -3,5 +3,5 @@ dependencies:
path: ${IDF_PATH}/examples/system/console/advanced/components/cmd_system
ethernet_init:
path: ${IDF_PATH}/examples/ethernet/basic/components/ethernet_init
espressif/iperf:
espressif/iperf-cmd:
version: "~0.1.1"

Wyświetl plik

@ -1044,9 +1044,6 @@ examples/cxx/rtti/main/rtti_example_main.cpp
examples/ethernet/basic/main/ethernet_example_main.c
examples/ethernet/enc28j60/components/eth_enc28j60/enc28j60.h
examples/ethernet/enc28j60/main/enc28j60_example_main.c
examples/ethernet/iperf/main/cmd_ethernet.c
examples/ethernet/iperf/main/cmd_ethernet.h
examples/ethernet/iperf/main/ethernet_example_main.c
examples/get-started/blink/main/blink_example_main.c
examples/get-started/sample_project/main/main.c
examples/mesh/internal_communication/main/include/mesh_light.h