From ca28123353eecfcdabdfd6c3bf90c531ac6c5038 Mon Sep 17 00:00:00 2001 From: laokaiyao Date: Thu, 27 Jun 2024 20:19:01 +0800 Subject: [PATCH] refactor(esp_probe): add kconfig to select data dump mode --- .../components/esp_probe/host/tcp_server.py | 45 ++++++++-------- .../logic_analyzer/main/Kconfig.projbuild | 53 +++++++++++++++---- .../main/logic_analyzer_example_main.c | 21 +++++--- .../logic_analyzer/sdkconfig.ci.flash_stream | 2 +- 4 files changed, 81 insertions(+), 40 deletions(-) diff --git a/examples/peripherals/parlio/parlio_rx/logic_analyzer/components/esp_probe/host/tcp_server.py b/examples/peripherals/parlio/parlio_rx/logic_analyzer/components/esp_probe/host/tcp_server.py index e5fee66ed4..0c0de04407 100644 --- a/examples/peripherals/parlio/parlio_rx/logic_analyzer/components/esp_probe/host/tcp_server.py +++ b/examples/peripherals/parlio/parlio_rx/logic_analyzer/components/esp_probe/host/tcp_server.py @@ -1,6 +1,5 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Apache-2.0 - import argparse import socket from io import TextIOWrapper @@ -23,29 +22,30 @@ def _tcp_server(port:int, chan_num:int, vcd_out_io:TextIOWrapper) -> None: s.listen(5) print(f'TCP listening at {host}:{port}') + c, addr = s.accept() + print(f'Client {addr[0]}:{addr[1]} joined') + c.settimeout(3) + vcd = VCDDumper() + vcd.open_new_vcd_file(chan_num, vcd_out_io) + recv_data = b'' try: while True: - c, addr = s.accept() - print(f'Client {addr[0]}:{addr[1]} joined') - vcd = VCDDumper() - vcd.open_new_vcd_file(chan_num, vcd_out_io) - - while True: - recv_data = c.recv(16384) - if recv_data == b'': - break - print(f'data received {len(recv_data)} bytes') - vcd.dump_samples(recv_data) - - print(f'Client {addr[0]}:{addr[1]} left') - vcd.close_vcd_file() - c.close() + temp = c.recv(10240) + recv_data += temp + if temp == b'': + break + print(f'Data received {len(temp)} bytes') + except socket.timeout: + print('Done!') finally: - vcd.close_vcd_file() - c.close() - s.shutdown(socket.SHUT_RDWR) - s.close() - print('TCP server closed') + print(f'Received {len(recv_data)} bytes in total') + vcd.dump_samples(recv_data) + + print(f'Client {addr[0]}:{addr[1]} left') + vcd.close_vcd_file() + c.close() + s.close() + print('TCP server closed') def tcp_server_main() -> None: @@ -70,6 +70,7 @@ def tcp_server_main() -> None: chan_num = 1 << p _tcp_server(port, chan_num, vcd_out_io) + exit(0) if __name__ == '__main__': diff --git a/examples/peripherals/parlio/parlio_rx/logic_analyzer/main/Kconfig.projbuild b/examples/peripherals/parlio/parlio_rx/logic_analyzer/main/Kconfig.projbuild index de589fd111..0042fc2b17 100644 --- a/examples/peripherals/parlio/parlio_rx/logic_analyzer/main/Kconfig.projbuild +++ b/examples/peripherals/parlio/parlio_rx/logic_analyzer/main/Kconfig.projbuild @@ -9,30 +9,63 @@ menu "ESP probe configurations" bool "Probing the External signals" endchoice - choice EXAMPLE_STREAM + choice EXAMPLE_DATA_DUMP_MODE + prompt "Select ESP probe dump mode" + default EXAMPLE_DATA_BUFFER_MODE + help + Select how to dump the data. Different modes have different requirements. + config EXAMPLE_DATA_BUFFER_MODE + bool "Buffer mode (recommended)" + help + The buffer mode will store the data onto the heap storage first, + and output all of them to the stream in once. + The probe will stop if run out of the given storage on the heap. + So that to guarantee a reliable data storing during the sampling period. + However, the disadvantage is that, the probing time is limited by the available heap size, + the higher the sample rate is, the shorter time the sampling last. + config EXAMPLE_DATA_STREAM_MODE + bool "Stream mode" + help + The stream mode relies heavily on the bandwidth of the output stream. + Stream mode can only achieve a relatively low sample rate to guarantee no samples are dropped, + but it can keep sampling continuously for a long time. + config EXAMPLE_DATA_BUFFER_STREAM_MODE + bool "Buffer + Stream mode" + help + The buffer stream mode will store the data onto heap storage first, + and output them to the stream every half of the storage. + Buffer stream mode means the probe will loop to use the given storage on heap. + So that we can also sample the data continuously for a long time. + However, while the data outputting rate can't catch the data producing rate, + data will still be dropped. + The difference comparing to the stream mode is that, it sends a larger block in every output, + i.e., it can hold more reliable samples for a time + endchoice + + choice EXAMPLE_DATA_IO_DEVICE prompt "Select ESP probe dump stream" - default EXAMPLE_FLASH_STREAM if !SOC_WIFI_SUPPORTED && !SOC_EMAC_SUPPORTED - default EXAMPLE_TCP_STREAM if SOC_WIFI_SUPPORTED || SOC_EMAC_SUPPORTED + default EXAMPLE_DUMP_VIA_FS if !SOC_WIFI_SUPPORTED && !SOC_EMAC_SUPPORTED + default EXAMPLE_DUMP_VIA_TCP if SOC_WIFI_SUPPORTED || SOC_EMAC_SUPPORTED help Select the dump stream for the sampled data - config EXAMPLE_FLASH_STREAM - bool "Dump data into FLASH" - config EXAMPLE_TCP_STREAM + config EXAMPLE_DUMP_VIA_FS + bool "Dump data to the flash via file stream" + config EXAMPLE_DUMP_VIA_TCP depends on SOC_WIFI_SUPPORTED || SOC_EMAC_SUPPORTED - bool "Dump data to the host using TCP" + bool "Dump data to the host via TCP stream" endchoice config EXAMPLE_HOST_IP_ADDR - depends on EXAMPLE_TCP_STREAM + depends on EXAMPLE_DUMP_VIA_TCP default "192.168.1.100" string "TCP server IP address" config EXAMPLE_HOST_PORT - depends on EXAMPLE_TCP_STREAM + depends on EXAMPLE_DUMP_VIA_TCP default 8888 int "TCP server port" config EXAMPLE_PARTITION_LABEL - depends on EXAMPLE_FLASH_STREAM + depends on EXAMPLE_DUMP_VIA_FS default "storage" string "The label of the data storage partition" diff --git a/examples/peripherals/parlio/parlio_rx/logic_analyzer/main/logic_analyzer_example_main.c b/examples/peripherals/parlio/parlio_rx/logic_analyzer/main/logic_analyzer_example_main.c index 4f86027739..68b36895d1 100644 --- a/examples/peripherals/parlio/parlio_rx/logic_analyzer/main/logic_analyzer_example_main.c +++ b/examples/peripherals/parlio/parlio_rx/logic_analyzer/main/logic_analyzer_example_main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: CC0-1.0 */ @@ -15,14 +15,14 @@ #include "esp_probe_streams.h" // Alias of the Kconfig options -#if CONFIG_EXAMPLE_TCP_STREAM +#if CONFIG_EXAMPLE_DUMP_VIA_TCP #include "nvs_flash.h" #include "protocol_examples_common.h" #include "esp_event.h" #define EXAMPLE_HOST_IP_ADDR CONFIG_EXAMPLE_HOST_IP_ADDR // Host IP (string) #define EXAMPLE_HOST_PORT CONFIG_EXAMPLE_HOST_PORT // Host port (int) -#elif CONFIG_EXAMPLE_FLASH_STREAM +#elif CONFIG_EXAMPLE_DUMP_VIA_FS #define EXAMPLE_MOUNT_POINT "/esp_probe" #define EXAMPLE_DATA_FILE_PATH EXAMPLE_MOUNT_POINT"/probe_raw.dat" #define EXAMPLE_PARTITION_LABEL CONFIG_EXAMPLE_PARTITION_LABEL // Flash partition label (string, see 'partitions.csv') @@ -71,20 +71,27 @@ FILE *example_probe_init(void) { FILE *f = NULL; // Create dump stream -#if CONFIG_EXAMPLE_TCP_STREAM +#if CONFIG_EXAMPLE_DUMP_VIA_TCP ESP_ERROR_CHECK(nvs_flash_init()); ESP_ERROR_CHECK(esp_netif_init()); ESP_ERROR_CHECK(esp_event_loop_create_default()); ESP_ERROR_CHECK(example_connect()); f = esp_probe_open_tcp_stream(EXAMPLE_HOST_IP_ADDR, EXAMPLE_HOST_PORT); -#elif CONFIG_EXAMPLE_FLASH_STREAM +#elif CONFIG_EXAMPLE_DUMP_VIA_FS ESP_ERROR_CHECK(esp_probe_init_spiflash_fatfs(EXAMPLE_MOUNT_POINT, EXAMPLE_PARTITION_LABEL, NULL)); f = esp_probe_open_file_stream(EXAMPLE_DATA_FILE_PATH); #endif assert(f); // Configure and allocate the ESP probe +#if CONFIG_EXAMPLE_DATA_BUFFER_MODE esp_probe_config_t config = ESP_PROBE_DEFAULT_BUFFER_CONFIG(EXAMPLE_SAMPLE_RATE_HZ, EXAMPLE_STORAGE_DEPTH_KB); +#elif CONFIG_EXAMPLE_DATA_STREAM_MODE + esp_probe_config_t config = ESP_PROBE_DEFAULT_STREAM_CONFIG(EXAMPLE_SAMPLE_RATE_HZ); +#else // CONFIG_EXAMPLE_DATA_BUFFER_STREAM_MODE + esp_probe_config_t config = ESP_PROBE_DEFAULT_BUFFER_STREAM_CONFIG(EXAMPLE_SAMPLE_RATE_HZ, EXAMPLE_STORAGE_DEPTH_KB); +#endif + // Set the GPIOs to be probed memcpy(&config.probe_gpio, &s_probe_gpio, sizeof(s_probe_gpio)); ESP_ERROR_CHECK(esp_new_probe(&config, &s_probe)); @@ -108,10 +115,10 @@ void example_probe_deinit(FILE *f) s_probe = NULL; // Close the output stream -#if CONFIG_EXAMPLE_TCP_STREAM +#if CONFIG_EXAMPLE_DUMP_VIA_TCP esp_probe_close_tcp_stream(f); example_disconnect(); -#elif CONFIG_EXAMPLE_FLASH_STREAM +#elif CONFIG_EXAMPLE_DUMP_VIA_FS esp_probe_close_file_stream(f); esp_probe_deinit_spiflash_fatfs(EXAMPLE_PARTITION_LABEL); #endif diff --git a/examples/peripherals/parlio/parlio_rx/logic_analyzer/sdkconfig.ci.flash_stream b/examples/peripherals/parlio/parlio_rx/logic_analyzer/sdkconfig.ci.flash_stream index 4149416a65..4c1076aeab 100644 --- a/examples/peripherals/parlio/parlio_rx/logic_analyzer/sdkconfig.ci.flash_stream +++ b/examples/peripherals/parlio/parlio_rx/logic_analyzer/sdkconfig.ci.flash_stream @@ -1 +1 @@ -CONFIG_EXAMPLE_FLASH_STREAM=y +CONFIG_EXAMPLE_DUMP_VIA_FS=y