From c27683eb98b815d32a82343df952ca29c545e10f Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 21 Feb 2025 15:28:19 +0100 Subject: [PATCH] test(sdmmc): add test for high-prio task busy while writing Related to https://github.com/espressif/esp-idf/issues/13934 --- .../common_test_flows/CMakeLists.txt | 2 +- .../include/sdmmc_test_rw_common.h | 8 +++- .../common_test_flows/sdmmc_test_rw_common.c | 41 +++++++++++++++++++ .../components/sdmmc_tests/sdmmc_test_rw_sd.c | 24 ++++++++++- 4 files changed, 72 insertions(+), 3 deletions(-) diff --git a/components/esp_driver_sdmmc/test_apps/sd_test_utils/components/common_test_flows/CMakeLists.txt b/components/esp_driver_sdmmc/test_apps/sd_test_utils/components/common_test_flows/CMakeLists.txt index 649cb95a54..bd957d11b1 100644 --- a/components/esp_driver_sdmmc/test_apps/sd_test_utils/components/common_test_flows/CMakeLists.txt +++ b/components/esp_driver_sdmmc/test_apps/sd_test_utils/components/common_test_flows/CMakeLists.txt @@ -5,5 +5,5 @@ set(public_include "include") idf_component_register( SRCS ${srcs} INCLUDE_DIRS ${public_include} - PRIV_REQUIRES sdmmc unity test_utils + PRIV_REQUIRES sdmmc unity test_utils esp_timer ) diff --git a/components/esp_driver_sdmmc/test_apps/sd_test_utils/components/common_test_flows/include/sdmmc_test_rw_common.h b/components/esp_driver_sdmmc/test_apps/sd_test_utils/components/common_test_flows/include/sdmmc_test_rw_common.h index 3398c79f02..b678631a55 100644 --- a/components/esp_driver_sdmmc/test_apps/sd_test_utils/components/common_test_flows/include/sdmmc_test_rw_common.h +++ b/components/esp_driver_sdmmc/test_apps/sd_test_utils/components/common_test_flows/include/sdmmc_test_rw_common.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -50,6 +50,12 @@ void sdmmc_test_rw_unaligned_buffer(sdmmc_card_t* card); */ void sdmmc_test_rw_with_offset(sdmmc_card_t* card); +/** + * @brief Test read/write with higher priority tasks running concurrently + * @param card Pointer to the card object, must be initialized before calling this function. + */ +void sdmmc_test_rw_highprio_task(sdmmc_card_t* card); + #ifdef __cplusplus }; #endif diff --git a/components/esp_driver_sdmmc/test_apps/sd_test_utils/components/common_test_flows/sdmmc_test_rw_common.c b/components/esp_driver_sdmmc/test_apps/sd_test_utils/components/common_test_flows/sdmmc_test_rw_common.c index b883e00435..077f7ee29e 100644 --- a/components/esp_driver_sdmmc/test_apps/sd_test_utils/components/common_test_flows/sdmmc_test_rw_common.c +++ b/components/esp_driver_sdmmc/test_apps/sd_test_utils/components/common_test_flows/sdmmc_test_rw_common.c @@ -11,6 +11,7 @@ #include #include "esp_dma_utils.h" #include "esp_heap_caps.h" +#include "esp_timer.h" #include "test_utils.h" #include "sdkconfig.h" #include "soc/soc_caps.h" @@ -185,3 +186,43 @@ void sdmmc_test_rw_with_offset(sdmmc_card_t* card) do_single_rw_perf_test(card, card->csd.capacity / 2, 8, 1, NULL, 0); do_single_rw_perf_test(card, card->csd.capacity / 2, 128, 1, NULL, 0); } + +typedef struct { + SemaphoreHandle_t stop; + SemaphoreHandle_t done; + uint32_t busy_time_us; +} highprio_busy_task_args_t; + +static void highprio_busy_task(void* varg) +{ + highprio_busy_task_args_t* args = (highprio_busy_task_args_t*) varg; + while (xSemaphoreTake(args->stop, 0) != pdTRUE) { + vTaskDelay(1); + int64_t start = esp_timer_get_time(); + while (esp_timer_get_time() - start < args->busy_time_us) { + usleep(100); + } + } + xSemaphoreGive(args->done); + vTaskDelete(NULL); +} + +void sdmmc_test_rw_highprio_task(sdmmc_card_t* card) +{ + highprio_busy_task_args_t args = { + .stop = xSemaphoreCreateBinary(), + .done = xSemaphoreCreateBinary(), + .busy_time_us = 250000, + }; + + TEST_ASSERT(xTaskCreate(highprio_busy_task, "highprio_busy_task", 4096, &args, 20, NULL)); + + for (int i = 0; i < 4; ++i) { + do_single_rw_perf_test(card, 0, 64, 0, NULL, 0); + } + + xSemaphoreGive(args.stop); + xSemaphoreTake(args.done, portMAX_DELAY); + vSemaphoreDelete(args.stop); + vSemaphoreDelete(args.done); +} diff --git a/components/esp_driver_sdmmc/test_apps/sdmmc/components/sdmmc_tests/sdmmc_test_rw_sd.c b/components/esp_driver_sdmmc/test_apps/sdmmc/components/sdmmc_tests/sdmmc_test_rw_sd.c index 3a07056213..8c1a5c36a7 100644 --- a/components/esp_driver_sdmmc/test_apps/sdmmc/components/sdmmc_tests/sdmmc_test_rw_sd.c +++ b/components/esp_driver_sdmmc/test_apps/sdmmc/components/sdmmc_tests/sdmmc_test_rw_sd.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -106,3 +106,25 @@ TEST_CASE("sdmmc read/write using unaligned buffer, slot 1, 4-bit", "[sdmmc]") { do_one_sdmmc_rw_test_unaligned_buffer(SLOT_1, 4, SDMMC_FREQ_DEFAULT, 0); } + +/* ========== Read/write tests with higher priority tasks running concurrently ========== */ + +static void do_one_sdmmc_rw_test_highprio_task(int slot, int width) +{ + sdmmc_card_t card; + sdmmc_test_sd_skip_if_board_incompatible(slot, width, SDMMC_FREQ_DEFAULT, NO_DDR, NO_EMMC); + sdmmc_test_sd_begin(slot, width, SDMMC_FREQ_DEFAULT, NO_DDR, &card); + sdmmc_card_print_info(stdout, &card); + sdmmc_test_rw_highprio_task(&card); + sdmmc_test_sd_end(&card); +} + +TEST_CASE("sdmmc read/write with concurrent high-prio task, slot 0, 4-bit", "[sdmmc]") +{ + do_one_sdmmc_rw_test_highprio_task(0, 4); +} + +TEST_CASE("sdmmc read/write with concurrent high-prio task, slot 1, 4-bit", "[sdmmc]") +{ + do_one_sdmmc_rw_test_highprio_task(1, 4); +}