From 746581f33cd74e46f45e251dad5b52a219584452 Mon Sep 17 00:00:00 2001 From: Giacomo Dematteis Date: Thu, 7 Nov 2024 14:00:55 +0100 Subject: [PATCH] tests: on_target: 400k trace test on conn bridge Add a test for conn bridge with 400k of modem traces. Signed-off-by: Giacomo Dematteis --- .../artifacts/usb_uart_bridge_app.zip | Bin 89890 -> 92839 bytes .../test_apps/usb_uart_bridge/CMakeLists.txt | 12 + .../test_apps/usb_uart_bridge/app.overlay | 4 + .../test_apps/usb_uart_bridge/prj.conf | 7 + .../test_apps/usb_uart_bridge/src/main.c | 278 ++++++++++++++++++ .../tests/test_bridge/test_conn_bridge.py | 70 +++-- 6 files changed, 339 insertions(+), 32 deletions(-) create mode 100644 tests/on_target/test_apps/usb_uart_bridge/CMakeLists.txt create mode 100644 tests/on_target/test_apps/usb_uart_bridge/app.overlay create mode 100644 tests/on_target/test_apps/usb_uart_bridge/prj.conf create mode 100644 tests/on_target/test_apps/usb_uart_bridge/src/main.c diff --git a/tests/on_target/artifacts/usb_uart_bridge_app.zip b/tests/on_target/artifacts/usb_uart_bridge_app.zip index 3fac75a7784e205797d19e64222e85c47d8da137..833802108002243f88ef8d0d640d0ee982eb1604 100644 GIT binary patch delta 20580 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 diff --git a/tests/on_target/test_apps/usb_uart_bridge/CMakeLists.txt b/tests/on_target/test_apps/usb_uart_bridge/CMakeLists.txt new file mode 100644 index 00000000..6791f14b --- /dev/null +++ b/tests/on_target/test_apps/usb_uart_bridge/CMakeLists.txt @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(uart_echo_bot) + +target_include_directories(app PRIVATE inc) + +target_sources(app PRIVATE + src/main.c +) diff --git a/tests/on_target/test_apps/usb_uart_bridge/app.overlay b/tests/on_target/test_apps/usb_uart_bridge/app.overlay new file mode 100644 index 00000000..89bbd23e --- /dev/null +++ b/tests/on_target/test_apps/usb_uart_bridge/app.overlay @@ -0,0 +1,4 @@ +/* Enable UART1 */ +&uart1 { + status = "okay"; +}; diff --git a/tests/on_target/test_apps/usb_uart_bridge/prj.conf b/tests/on_target/test_apps/usb_uart_bridge/prj.conf new file mode 100644 index 00000000..7721d805 --- /dev/null +++ b/tests/on_target/test_apps/usb_uart_bridge/prj.conf @@ -0,0 +1,7 @@ +CONFIG_SERIAL=y +CONFIG_CONSOLE=n +CONFIG_UART_CONSOLE=n +CONFIG_UART_ASYNC_API=y +CONFIG_WATCHDOG=y +CONFIG_LOG=n + diff --git a/tests/on_target/test_apps/usb_uart_bridge/src/main.c b/tests/on_target/test_apps/usb_uart_bridge/src/main.c new file mode 100644 index 00000000..0330d5b5 --- /dev/null +++ b/tests/on_target/test_apps/usb_uart_bridge/src/main.c @@ -0,0 +1,278 @@ +#include +#include +#include +#include + +#include +#include +#include +#include + +/* defines for watchdog */ +#define WDT_MAX_WINDOW 10000U +#define WDT_FEED_WORKER_DELAY_MS 2500U + +#define MSG_SIZE 5120 +#define LINE_LEN 64 +#define LINE_COUNT 64 + +#define RECEIVE_TIMEOUT 1000 + +/* queue to store up to 8 messages (aligned to 4-byte boundary) */ +K_MSGQ_DEFINE(uart_msgq, MSG_SIZE, 8, 4); + +static const struct device *uart0 = DEVICE_DT_GET(DT_NODELABEL(uart0)); +static const struct device *uart1 = DEVICE_DT_GET(DT_NODELABEL(uart1)); + +struct wdt_data_storage { + const struct device *wdt_drv; + int wdt_channel_id; + struct k_work_delayable system_workqueue_work; +}; + +static struct wdt_data_storage wdt_data = { + .wdt_drv = DEVICE_DT_GET(DT_NODELABEL(wdt)) +}; + + + +/* Define a semaphore for UART1 transmission synchronization */ +K_SEM_DEFINE(uart1_tx_sem, 1, 1); // Initial count = 1, max count = 1 + +/* RX buffer for UART0 DMA */ +static uint8_t rx_dma_buf[MSG_SIZE]; + +/* Buffer used in callback to process incoming lines */ +static char rx_line_buf[MSG_SIZE]; +static size_t rx_line_buf_pos = 0; + +/* UART Print function using async API for UART0 */ +static void print_uart0_async(const struct device *uart, const char *str) +{ + size_t len = strlen(str); + if (len == 0) { + return; + } + uart_tx(uart, (const uint8_t *)str, len, SYS_FOREVER_MS); +} + +/* UART Print function using async API for UART1 with semaphore */ +static void print_uart1_async(const struct device *uart, const char *str) +{ + size_t len = strlen(str); + if (len == 0) { + return; + } + + /* Acquire the semaphore before initiating transmission */ + if (k_sem_take(&uart1_tx_sem, K_FOREVER) == 0) { + int ret = uart_tx(uart, (const uint8_t *)str, len, SYS_FOREVER_MS); + if (ret < 0) { + /* Transmission failed, release the semaphore */ + k_sem_give(&uart1_tx_sem); + } + /* If uart_tx is successful, the semaphore will be released in the callback */ + } +} + +/* UART0 callback to handle TX completion */ +static void uart0_cb(const struct device *dev, struct uart_event *evt, void *user_data) +{ + switch (evt->type) { + case UART_RX_RDY: + /* Data received. Copy it into rx_line_buf and look for line endings */ + const uint8_t *data = &evt->data.rx.buf[evt->data.rx.offset]; + size_t len = evt->data.rx.len; + for (size_t i = 0; i < len; i++) { + char c = (char)data[i]; + if ((c == '\n' || c == '\r') && rx_line_buf_pos > 0) { + /* Terminate string */ + rx_line_buf[rx_line_buf_pos] = '\0'; + /* Put line into message queue (if full, dropped) */ + k_msgq_put(&uart_msgq, rx_line_buf, K_NO_WAIT); + /* Reset buffer */ + rx_line_buf_pos = 0; + } else if (rx_line_buf_pos < (sizeof(rx_line_buf) - 1)) { + rx_line_buf[rx_line_buf_pos++] = c; + } + /* else: drop characters beyond buffer size */ + } + break; + case UART_RX_DISABLED: + uart_rx_enable(uart0, rx_dma_buf, sizeof(rx_dma_buf), RECEIVE_TIMEOUT); + break; + case UART_RX_STOPPED: + /* RX stopped due to an error. Restart RX. */ + uart_rx_enable(dev, rx_dma_buf, sizeof(rx_dma_buf), RECEIVE_TIMEOUT); + break; + default: + break; + } +} + +/* UART1 callback to handle TX completion */ +static void uart1_cb(const struct device *dev, struct uart_event *evt, void *user_data) +{ + switch (evt->type) { + case UART_TX_DONE: + case UART_TX_ABORTED: + /* Release the semaphore to allow the next transmission */ + k_sem_give(&uart1_tx_sem); + break; + default: + break; + } +} + + +/* + * Generate a large predefined string to be checked by test + */ +static void generate_str(char *str, int line_len, int line_count) +{ + int count = 0; + char c; + int t; + + for (int i = 0; i < line_count; ++i) { + for (int j = i; j < i + line_len-1; ++j) { + t = j % line_len; + c = '!' + t; + if (c == '\"' || c == '\'' || c == '\\') { + c = 'a'; + } + *(str+count) = c; + count++; + } + if (i < line_count-1) { + *(str+count) = 'A'; + count++; + } + } + *(str+count) = '\0'; +} + +static void init_watchdog(void) +{ + struct wdt_timeout_cfg wdt_config = { + /* Reset SoC when watchdog timer expires. */ + .flags = WDT_FLAG_RESET_SOC, + + /* Expire watchdog after max window */ + .window.min = 0U, + .window.max = WDT_MAX_WINDOW, + }; + wdt_data.wdt_channel_id = wdt_install_timeout(wdt_data.wdt_drv, &wdt_config); + wdt_setup(wdt_data.wdt_drv, WDT_OPT_PAUSE_HALTED_BY_DBG); +} + +static void init_uart(void) +{ + /* Set the UART0 callback */ + uart_callback_set(uart0, uart0_cb, NULL); + /* Set the UART1 callback */ + uart_callback_set(uart1, uart1_cb, NULL); + + /* Enable asynchronous RX (required by async API) */ + uart_rx_enable(uart0, rx_dma_buf, sizeof(rx_dma_buf), RECEIVE_TIMEOUT); + + /* Enable UART1 asynchronous RX (required by async API), though we don't use RX here. + * Just provide a dummy buffer. */ + static uint8_t dummy_rx_buf1[1]; + uart_rx_enable(uart1, dummy_rx_buf1, sizeof(dummy_rx_buf1), SYS_FOREVER_MS); + + /* Configure UART1 to 1000000 baud */ + struct uart_config cfg1; + uart_config_get(uart1, &cfg1); + cfg1.baudrate = 1000000; + uart_configure(uart1, &cfg1); +} + +/* Buffer to read from message queue */ +static char buffer_to_read_msgq[MSG_SIZE]; + +/* Control String */ +static char control_str[LINE_LEN*LINE_COUNT]; + +int main(void) +{ + int err; + char hex_buf[5]; + + /* Ensure UART0 is ready */ + if (!device_is_ready(uart0)) { + return 0; + } + + /* Ensure UART1 is ready */ + if (!device_is_ready(uart1)) { + return 0; + } + + init_uart(); + init_watchdog(); + + + + /* Generate a control string */ + generate_str(control_str, LINE_LEN, LINE_COUNT); + + while (1) { + err = k_msgq_get(&uart_msgq, buffer_to_read_msgq, K_MSEC(WDT_FEED_WORKER_DELAY_MS)); + if (!err) { + wdt_feed(wdt_data.wdt_drv, wdt_data.wdt_channel_id); + if (strstr(buffer_to_read_msgq, control_str)) { + print_uart0_async(uart0, "Control string received from usb via bridge to nrf9160!\r\n"); + } + /* CHECK_UART0_SMOKE */ + else if (strstr(buffer_to_read_msgq, "CHECK_UART0_SMOKE")) { + print_uart0_async(uart0, "This message should be seen on UART0!\r\n"); + } + /* CHECK_UART1_SMOKE */ + else if (strstr(buffer_to_read_msgq, "CHECK_UART1_SMOKE")) { + print_uart1_async(uart1, "This message should be seen on UART1!\r\n"); + } + else if (strstr(buffer_to_read_msgq, "CHECK_UART1_4k_TRACES")) { + print_uart0_async(uart0, "4k of data sent over UART1\r\n"); + print_uart1_async(uart1, control_str); + } + else if (strstr(buffer_to_read_msgq, "CHECK_UART1_100k_TRACES")) { + print_uart0_async(uart0, "100k of data sent over UART1\r\n"); + for (int i = 0; i < 25; ++i) { + print_uart1_async(uart1, control_str); + } + } + else if (strstr(buffer_to_read_msgq, "CHECK_UART1_400k_TRACES")) { + print_uart0_async(uart0, "400k of data sent over UART1\r\n"); + for (int i = 0; i < 100; ++i) { + print_uart1_async(uart1, control_str); + } + } + else if (strstr(buffer_to_read_msgq, "CHECK_UART1_600k_TRACES")) { + print_uart0_async(uart0, "600k of data sent over UART1\r\n"); + for (int i = 0; i < 150; ++i) { + print_uart1_async(uart1, control_str); + } + } + else { + print_uart0_async(uart0, "Unexpected message received:\r\n"); + for (int i = 0; i < (int)strlen(buffer_to_read_msgq); ++i) { + snprintk(hex_buf, sizeof(hex_buf), "%02X, ", buffer_to_read_msgq[i]); + print_uart1_async(uart0, hex_buf); + } + print_uart0_async(uart0, "\r\n"); + } + } + else if (err == -EAGAIN) { + wdt_feed(wdt_data.wdt_drv, wdt_data.wdt_channel_id); + print_uart0_async(uart0, "UART0 running at baudrate 115200\r\n"); + print_uart1_async(uart1, "UART1 running at baudrate 1000000\r\n"); + } + else { + print_uart0_async(uart0, "Error receiving message from queue\r\n"); + return 0; + } + k_sleep(K_SECONDS(1)); + } + return 0; +} diff --git a/tests/on_target/tests/test_bridge/test_conn_bridge.py b/tests/on_target/tests/test_bridge/test_conn_bridge.py index 94471161..ea4e6177 100644 --- a/tests/on_target/tests/test_bridge/test_conn_bridge.py +++ b/tests/on_target/tests/test_bridge/test_conn_bridge.py @@ -33,13 +33,14 @@ -@pytest.fixture(scope="function") +@pytest.fixture(scope="module") def t91x_conn_bridge(): ''' This fixture initializes the nRF53 and nRF91 for connectivity bridge test. First the nRF53 is flashed with connectivity bridge fw. Then dfu is performed on nrf91 with custom test app. ''' + logger.info("Recovering nRF53 network core") recover_device(serial=SEGGER_NRF53, core='Network') logger.info("Recovering nRF53 application core") @@ -77,13 +78,12 @@ def t91x_conn_bridge(): @pytest.mark.slow def test_conn_bridge(t91x_conn_bridge): ''' - Test the connectivity bridge between nRF53 and nRF91 + Test basic functionalities of the connectivity bridge Test steps: 1. Wait for UART0 and UART1 to be available 2. Send 4k of data from USB to UART0 3. Send 4k of data from UART1 to USB - 4. Send 40k of data from UART1 to USB ''' t91x_conn_bridge.uart0.wait_for_str( "UART0 running at baudrate 115200", timeout=UART_TIMEOUT @@ -147,36 +147,42 @@ def test_conn_bridge(t91x_conn_bridge): assert line in log[count], line + " not in " + log[count] count = count + 1 - # Test beefy tx on uart1 from nrf9160 to usb - # Emulates 40k of uart1 modem traces (10 times the 4k control string) - logger.info("Testing 40k of uart1 modem traces") - beefy_ctrl_str = ''.join([generate_control_str() for _ in range(10)]) # Generate 10 times the control string + +@pytest.mark.slow +def test_conn_bridge_stress_traces(t91x_conn_bridge): + ''' + Stress test the connectivity bridge, simulating heavy modem tyraces coming from NRF91 + + Test steps: + 1. Wait for UART0 and UART1 to be available + 2. Send 400k of data from NRF91 to usb through NRF53 + ''' + t91x_conn_bridge.uart0.wait_for_str( + "UART0 running at baudrate 115200", timeout=UART_TIMEOUT + ) + t91x_conn_bridge.uart1.wait_for_str( + "UART1 running at baudrate 1000000", timeout=UART_TIMEOUT + ) + + # Test beefy tx on uart1 from NRF91 to usb + logger.info(f"Testing 400k of uart1 modem traces") + # Generate 100 times the control string to get 400k + beefy_ctrl_str = ''.join([generate_control_str() for _ in range(100)]) t91x_conn_bridge.uart1.flush() - t91x_conn_bridge.uart0.write(b"CHECK_UART1_40k_TRACES\r\n") - t91x_conn_bridge.uart1.wait_for_str(beefy_ctrl_str, timeout=20) - - # TODO: refine assertion handling, see below for inspiration - # try: - # t91x_conn_bridge.uart1.wait_for_str(beefy_ctrl_str, timeout=20) # Wait for the null-terminated string - # except Exception as e: - # logger.error(f"wait_for_str failed, exception: {e}") - - # log = t91x_conn_bridge.uart1.log.split() - # beefy_ctrl_str = beefy_ctrl_str.split('\x00') # Split the control string by null-terminator - - # missing_strings = [] # List to keep track of missing control strings - # missing_strings_counter = 0 - # for ctrl in beefy_ctrl_str: - # if ctrl not in log: - # missing_strings.append(ctrl) # Add missing control string to the list - # missing_strings_counter = missing_strings_counter + 1 - - # if missing_strings: - # logger.error("LOG") - # logger.error(log) - # raise AssertionError( - # f"The following {missing_strings_counter} control strings were not found in the log:\n" + "\n".join(missing_strings) - # ) from AssertionError + t91x_conn_bridge.uart0.write(b"CHECK_UART1_400k_TRACES\r\n") + try: + t91x_conn_bridge.uart1.wait_for_str(beefy_ctrl_str, timeout=20) + except Exception: + ctrl_str = generate_control_str() + log = t91x_conn_bridge.uart1.log + number_of_control_strings_in_trace = log.count(ctrl_str) + logger.error(f"found only {number_of_control_strings_in_trace} control strings out of 100") + raise AssertionError + + ctrl_str = generate_control_str() + log = t91x_conn_bridge.uart1.log + number_of_control_strings_in_trace = log.count(ctrl_str) + logger.debug(f"found {number_of_control_strings_in_trace} control strings out of 100") def generate_control_str(): control_str = ""