From fb7d8f49be7271d45ade73bb208366f08a6eb177 Mon Sep 17 00:00:00 2001 From: wanlei Date: Thu, 10 Nov 2022 17:37:26 +0800 Subject: [PATCH] test: move uart test to test_app --- components/driver/.build-test-rules.yml | 6 ++ .../driver/test_apps/uart/CMakeLists.txt | 7 +++ components/driver/test_apps/uart/README.md | 2 + .../driver/test_apps/uart/main/CMakeLists.txt | 7 +++ .../test_apps/uart/main/test_app_main.c | 48 +++++++++++++++ .../{test => test_apps/uart/main}/test_uart.c | 59 ++++++++++--------- .../driver/test_apps/uart/pytest_uart.py | 11 ++++ .../test_apps/uart/sdkconfig.ci.release | 6 ++ .../driver/test_apps/uart/sdkconfig.defaults | 2 + 9 files changed, 121 insertions(+), 27 deletions(-) create mode 100644 components/driver/test_apps/uart/CMakeLists.txt create mode 100644 components/driver/test_apps/uart/README.md create mode 100644 components/driver/test_apps/uart/main/CMakeLists.txt create mode 100644 components/driver/test_apps/uart/main/test_app_main.c rename components/driver/{test => test_apps/uart/main}/test_uart.c (91%) create mode 100644 components/driver/test_apps/uart/pytest_uart.py create mode 100644 components/driver/test_apps/uart/sdkconfig.ci.release create mode 100644 components/driver/test_apps/uart/sdkconfig.defaults diff --git a/components/driver/.build-test-rules.yml b/components/driver/.build-test-rules.yml index 3cbdbaecc6..74646d5a0a 100644 --- a/components/driver/.build-test-rules.yml +++ b/components/driver/.build-test-rules.yml @@ -76,3 +76,9 @@ components/driver/test_apps/touch_sensor_v2: components/driver/test_apps/twai: disable: - if: SOC_TWAI_SUPPORTED != 1 + +components/driver/test_apps/uart: + disable_test: + - if: IDF_TARGET == "esp32c6" + temporary: true + reason: target esp32c6 not supported yet diff --git a/components/driver/test_apps/uart/CMakeLists.txt b/components/driver/test_apps/uart/CMakeLists.txt new file mode 100644 index 0000000000..be8a89bfb0 --- /dev/null +++ b/components/driver/test_apps/uart/CMakeLists.txt @@ -0,0 +1,7 @@ +# This is the project CMakeLists.txt file for the test subproject +cmake_minimum_required(VERSION 3.16) + +set(EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/unit-test-app/components") + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(uart_test) diff --git a/components/driver/test_apps/uart/README.md b/components/driver/test_apps/uart/README.md new file mode 100644 index 0000000000..7e7523ec85 --- /dev/null +++ b/components/driver/test_apps/uart/README.md @@ -0,0 +1,2 @@ +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/driver/test_apps/uart/main/CMakeLists.txt b/components/driver/test_apps/uart/main/CMakeLists.txt new file mode 100644 index 0000000000..e4d03ea3f7 --- /dev/null +++ b/components/driver/test_apps/uart/main/CMakeLists.txt @@ -0,0 +1,7 @@ +# In order for the cases defined by `TEST_CASE` to be linked into the final elf, +# the component can be registered as WHOLE_ARCHIVE +idf_component_register( + SRCS "test_app_main.c" "test_uart.c" + REQUIRES driver unity + WHOLE_ARCHIVE +) diff --git a/components/driver/test_apps/uart/main/test_app_main.c b/components/driver/test_apps/uart/main/test_app_main.c new file mode 100644 index 0000000000..c1070bd94d --- /dev/null +++ b/components/driver/test_apps/uart/main/test_app_main.c @@ -0,0 +1,48 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "unity.h" +#include "unity_test_utils.h" +#include "esp_heap_caps.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +#define TEST_MEMORY_LEAK_THRESHOLD (200) + +static size_t before_free_8bit; +static size_t before_free_32bit; + +void setUp(void) +{ + before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); + before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); +} + +void tearDown(void) +{ + size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); + size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); + printf("\n"); + unity_utils_check_leak(before_free_8bit, after_free_8bit, "8BIT", TEST_MEMORY_LEAK_THRESHOLD); + unity_utils_check_leak(before_free_32bit, after_free_32bit, "32BIT", TEST_MEMORY_LEAK_THRESHOLD); +} + +void app_main(void) +{ + // _____ _ _ _ _ ____ _____ + //|_ _|__ ___| |_ | | | | / \ | _ \_ _| + // | |/ _ \/ __| __| | | | |/ _ \ | |_) || | + // | | __/\__ \ |_ | |_| / ___ \| _ < | | + // |_|\___||___/\__| \___/_/ \_\_| \_\|_| + printf("\n"); + printf(" _____ _ _ _ _ ____ _____ \n"); + printf(" |_ _|__ ___| |_ | | | | / \\ | _ \\_ _|\n"); + printf(" | |/ _ \\/ __| __| | | | |/ _ \\ | |_) || | \n"); + printf(" | | __/\\__ \\ |_ | |_| / ___ \\| _ < | | \n"); + printf(" |_|\\___||___/\\__| \\___/_/ \\_\\_| \\_\\|_| \n"); + + unity_run_menu(); +} diff --git a/components/driver/test/test_uart.c b/components/driver/test_apps/uart/main/test_uart.c similarity index 91% rename from components/driver/test/test_uart.c rename to components/driver/test_apps/uart/main/test_uart.c index da040e57e2..e8c1eee187 100644 --- a/components/driver/test/test_uart.c +++ b/components/driver/test_apps/uart/main/test_uart.c @@ -6,7 +6,6 @@ #include #include #include "unity.h" -#include "test_utils.h" // unity_send_signal #include "driver/uart.h" // for the uart driver access #include "esp_log.h" #include "esp_system.h" // for uint32_t esp_random() @@ -23,14 +22,6 @@ #define TOLERANCE (0.02) //baud rate error tolerance 2%. #define UART1_CTS_PIN (13) -// RTS for RS485 Half-Duplex Mode manages DE/~RE -#define UART1_RTS_PIN (18) - -// Number of packets to be send during test -#define PACKETS_NUMBER (10) - -// Wait timeout for uart driver -#define PACKET_READ_TICS (1000 / portTICK_PERIOD_MS) static void uart_config(uint32_t baud_rate, uart_sclk_t source_clk) { @@ -48,9 +39,9 @@ static void uart_config(uint32_t baud_rate, uart_sclk_t source_clk) TEST_ESP_OK(uart_set_loop_back(UART_NUM1, true)); } -static volatile bool exit_flag; +static volatile bool exit_flag, case_end; -static void test_task(void *pvParameters) +static void test_task1(void *pvParameters) { SemaphoreHandle_t *sema = (SemaphoreHandle_t *) pvParameters; char* data = (char *) malloc(256); @@ -76,26 +67,39 @@ static void test_task2(void *pvParameters) vTaskDelete(NULL); } -TEST_CASE("test uart_wait_tx_done is not blocked when ticks_to_wait=0", "[uart]") +static void test_task3(void *pvParameters) { uart_config(UART_BAUD_11520, UART_SCLK_DEFAULT); SemaphoreHandle_t exit_sema = xSemaphoreCreateBinary(); exit_flag = false; + case_end = false; - xTaskCreate(test_task, "tsk1", 2048, &exit_sema, 5, NULL); + xTaskCreate(test_task1, "tsk1", 2048, &exit_sema, 5, NULL); xTaskCreate(test_task2, "tsk2", 2048, NULL, 5, NULL); printf("Waiting for 5 sec\n"); - vTaskDelay(5000 / portTICK_PERIOD_MS); + vTaskDelay(pdMS_TO_TICKS(5000)); exit_flag = true; - if (xSemaphoreTake(exit_sema, 1000 / portTICK_PERIOD_MS) == pdTRUE) { + if (xSemaphoreTake(exit_sema, pdMS_TO_TICKS(1000)) == pdTRUE) { vSemaphoreDelete(exit_sema); } else { TEST_FAIL_MESSAGE("uart_wait_tx_done is blocked"); } TEST_ESP_OK(uart_driver_delete(UART_NUM1)); + + vTaskDelay(2); // wait for test_task1 to exit + + case_end = true; + vTaskDelete(NULL); +} + +TEST_CASE("test uart_wait_tx_done is not blocked when ticks_to_wait=0", "[uart]") +{ + xTaskCreate(test_task3, "tsk3", 4096, NULL, 5, NULL); + while(!case_end); + vTaskDelay(2); // wait for test_task3 to exit } TEST_CASE("test uart get baud-rate", "[uart]") @@ -130,7 +134,7 @@ TEST_CASE("test uart tx data with break", "[uart]") uart_config(UART_BAUD_115200, UART_SCLK_DEFAULT); printf("Uart%d send %d bytes with break\n", UART_NUM1, send_len); uart_write_bytes_with_break(UART_NUM1, (const char *)psend, send_len, brk_len); - uart_wait_tx_done(UART_NUM1, (TickType_t)portMAX_DELAY); + uart_wait_tx_done(UART_NUM1, portMAX_DELAY); //If the code is running here, it means the test passed, otherwise it will crash due to the interrupt wdt timeout. printf("Send data with break test passed\n"); free(psend); @@ -238,7 +242,7 @@ static void uart_write_task(void *param) tx_buf[0] = (i & 0xff); tx_buf[1023] = ((~i) & 0xff); uart_write_bytes(uart_num, (const char*)tx_buf, 1024); - uart_wait_tx_done(uart_num, (TickType_t)portMAX_DELAY); + uart_wait_tx_done(uart_num, portMAX_DELAY); } free(tx_buf); vTaskDelete(NULL); @@ -277,15 +281,14 @@ TEST_CASE("uart read write test", "[uart]") esp_rom_gpio_connect_out_signal(UART1_CTS_PIN, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RTS_PIN_IDX), 0, 0); TEST_ESP_OK(uart_wait_tx_done(uart_num, portMAX_DELAY)); - vTaskDelay(1 / portTICK_PERIOD_MS); // make sure last byte has flushed from TX FIFO + vTaskDelay(pdMS_TO_TICKS(20)); // make sure last byte has flushed from TX FIFO TEST_ESP_OK(uart_flush_input(uart_num)); - - xTaskCreate(uart_write_task, "uart_write_task", 2048 * 4, (void *)uart_num, UNITY_FREERTOS_PRIORITY - 1, NULL); + xTaskCreate(uart_write_task, "uart_write_task", 8192, (void *)uart_num, 5, NULL); for (int i = 0; i < 1024; i++) { int bytes_remaining = 1024; memset(rd_data, 0, 1024); while (bytes_remaining) { - int bytes_received = uart_read_bytes(uart_num, rd_data + 1024 - bytes_remaining, bytes_remaining, (TickType_t)1000); + int bytes_received = uart_read_bytes(uart_num, rd_data + 1024 - bytes_remaining, bytes_remaining, pdMS_TO_TICKS(100)); if (bytes_received < 0) { TEST_FAIL_MESSAGE("read timeout, uart read write test fail"); } @@ -315,9 +318,11 @@ TEST_CASE("uart read write test", "[uart]") TEST_FAIL(); } } - uart_wait_tx_done(uart_num, (TickType_t)portMAX_DELAY); + uart_wait_tx_done(uart_num, portMAX_DELAY); uart_driver_delete(uart_num); free(rd_data); + + vTaskDelay(pdMS_TO_TICKS(100)); // wait for uart_write_task to exit } TEST_CASE("uart tx with ringbuffer test", "[uart]") @@ -357,10 +362,10 @@ TEST_CASE("uart tx with ringbuffer test", "[uart]") uart_get_tx_buffer_free_size(uart_num, &tx_buffer_free_space); TEST_ASSERT_LESS_THAN(2048, tx_buffer_free_space); // tx transmit in progress: tx buffer has content TEST_ASSERT_GREATER_OR_EQUAL(1024, tx_buffer_free_space); - uart_wait_tx_done(uart_num, (TickType_t)portMAX_DELAY); + uart_wait_tx_done(uart_num, portMAX_DELAY); uart_get_tx_buffer_free_size(uart_num, &tx_buffer_free_space); TEST_ASSERT_EQUAL_INT(2048, tx_buffer_free_space); // tx done: tx buffer back to empty - uart_read_bytes(uart_num, rd_data, 1024, (TickType_t)1000); + uart_read_bytes(uart_num, rd_data, 1024, pdMS_TO_TICKS(1000)); TEST_ASSERT_EQUAL_HEX8_ARRAY(wr_data, rd_data, 1024); TEST_ESP_OK(uart_driver_delete(uart_num)); free(rd_data); @@ -403,7 +408,7 @@ TEST_CASE("uart int state restored after flush", "[uart]") uart_write_bytes(uart_echo, (const char *) data, buf_size); /* As we set up a loopback, we can read them back on RX */ - int len = uart_read_bytes(uart_echo, data, buf_size, 1000 / portTICK_PERIOD_MS); + int len = uart_read_bytes(uart_echo, data, buf_size, pdMS_TO_TICKS(1000)); TEST_ASSERT_EQUAL(len, buf_size); /* Fill the RX buffer, this should disable the RX interrupts */ @@ -418,7 +423,7 @@ TEST_CASE("uart int state restored after flush", "[uart]") uart_flush_input(uart_echo); written = uart_write_bytes(uart_echo, (const char *) data, buf_size); TEST_ASSERT_NOT_EQUAL(-1, written); - len = uart_read_bytes(uart_echo, data, buf_size, 1000 / portTICK_PERIOD_MS); + len = uart_read_bytes(uart_echo, data, buf_size, pdMS_TO_TICKS(1000)); /* len equals buf_size bytes if interrupts were indeed re-enabled */ TEST_ASSERT_EQUAL(len, buf_size); @@ -433,7 +438,7 @@ TEST_CASE("uart int state restored after flush", "[uart]") uart_flush_input(uart_echo); written = uart_write_bytes(uart_echo, (const char *) data, buf_size); TEST_ASSERT_NOT_EQUAL(-1, written); - len = uart_read_bytes(uart_echo, data, buf_size, 250 / portTICK_PERIOD_MS); + len = uart_read_bytes(uart_echo, data, buf_size, pdMS_TO_TICKS(250)); TEST_ASSERT_EQUAL(len, 0); TEST_ESP_OK(uart_driver_delete(uart_echo)); diff --git a/components/driver/test_apps/uart/pytest_uart.py b/components/driver/test_apps/uart/pytest_uart.py new file mode 100644 index 0000000000..1035378e80 --- /dev/null +++ b/components/driver/test_apps/uart/pytest_uart.py @@ -0,0 +1,11 @@ +# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 + +import pytest + + +@pytest.mark.supported_targets +@pytest.mark.generic +@pytest.mark.parametrize('config', ['release',], indirect=True,) +def test_uart_single_dev(case_tester) -> None: # type: ignore + case_tester.run_all_normal_cases(reset=True) diff --git a/components/driver/test_apps/uart/sdkconfig.ci.release b/components/driver/test_apps/uart/sdkconfig.ci.release new file mode 100644 index 0000000000..673b6f8f74 --- /dev/null +++ b/components/driver/test_apps/uart/sdkconfig.ci.release @@ -0,0 +1,6 @@ +CONFIG_PM_ENABLE=y +CONFIG_FREERTOS_USE_TICKLESS_IDLE=y +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y +CONFIG_COMPILER_OPTIMIZATION_NONE=y diff --git a/components/driver/test_apps/uart/sdkconfig.defaults b/components/driver/test_apps/uart/sdkconfig.defaults new file mode 100644 index 0000000000..b308cb2ddd --- /dev/null +++ b/components/driver/test_apps/uart/sdkconfig.defaults @@ -0,0 +1,2 @@ +CONFIG_FREERTOS_HZ=1000 +CONFIG_ESP_TASK_WDT=n