From 0d9d4f60df699612e4cb73cb10984add38a71c43 Mon Sep 17 00:00:00 2001 From: Darian Leung Date: Wed, 21 Sep 2022 13:20:19 +0800 Subject: [PATCH] freertos: Add unit test utilities This commit adds "freertos_test_utils.h/c" that contains utility functions used in FreeRTOS unit tests. --- components/freertos/test/CMakeLists.txt | 3 +- .../test/integration/freertos_test_utils.c | 72 +++++++++++++++++++ .../test/integration/freertos_test_utils.h | 32 +++++++++ 3 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 components/freertos/test/integration/freertos_test_utils.c create mode 100644 components/freertos/test/integration/freertos_test_utils.h diff --git a/components/freertos/test/CMakeLists.txt b/components/freertos/test/CMakeLists.txt index f7958de644..ac4364d633 100644 --- a/components/freertos/test/CMakeLists.txt +++ b/components/freertos/test/CMakeLists.txt @@ -1,7 +1,8 @@ # For refactored FreeRTOS unit tests, we need to support #include "xxx.h" of FreeRTOS headers idf_component_get_property(FREERTOS_ORIG_INCLUDE_PATH freertos ORIG_INCLUDE_PATH) -idf_component_register(SRC_DIRS integration/event_groups +idf_component_register(SRC_DIRS integration # For freertos_test_utils.c + integration/event_groups integration/queue integration/stream_buffer integration/tasks diff --git a/components/freertos/test/integration/freertos_test_utils.c b/components/freertos/test/integration/freertos_test_utils.c new file mode 100644 index 0000000000..80ba37c788 --- /dev/null +++ b/components/freertos/test/integration/freertos_test_utils.c @@ -0,0 +1,72 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "FreeRTOS.h" +#include "semphr.h" +#include "freertos_test_utils.h" + +#if ( configNUM_CORES > 1 ) + + typedef struct { + const TestFunction_t pxTestCode; + void * const pvTestCodeArg; + const SemaphoreHandle_t xTaskDoneSem; + } TestArgs_t; + + static void test_func_task( void * pvParameters ) + { + TestArgs_t * pxTestArgs = ( TestArgs_t * ) pvParameters; + /* Call the test function */ + pxTestArgs->pxTestCode( pxTestArgs->pvTestCodeArg ); + /* Indicate completion to the creation task and wait to be deleted. */ + xSemaphoreGive( pxTestArgs->xTaskDoneSem ); + vTaskSuspend( NULL ); + } + + void vTestOnAllCores( TestFunction_t pxTestCode, void * pvTestCodeArg, uint32_t ulStackDepth, UBaseType_t uxPriority ) + { + SemaphoreHandle_t xTaskDoneSem = xSemaphoreCreateCounting( configNUM_CORES, 0 ); + TaskHandle_t xTaskHandles[ configNUM_CORES ]; + TestArgs_t xTestArgs = { + .pxTestCode = pxTestCode, + .pvTestCodeArg = pvTestCodeArg, + .xTaskDoneSem = xTaskDoneSem, + }; + + /* Create a separate task on each core to run the test function */ + for( BaseType_t xCoreID = 0; xCoreID < configNUM_CORES; xCoreID++ ) { + #if ( CONFIG_FREERTOS_SMP == 1 ) + xTaskCreateAffinitySet( test_func_task, + "task", + ulStackDepth, + ( void * ) &xTestArgs, + uxPriority, + ( UBaseType_t ) ( 1 << xCoreID ), + &( xTaskHandles[ xCoreID ] ) ); + #else + xTaskCreatePinnedToCore( test_func_task, + "task", + ulStackDepth, + ( void * ) &xTestArgs, + uxPriority, + &( xTaskHandles[ xCoreID ] ), + xCoreID ); + #endif + } + + /* Wait for each tasks to complete test */ + for( BaseType_t xCoreID = 0; xCoreID < configNUM_CORES; xCoreID++ ) { + xSemaphoreTake( xTaskDoneSem, portMAX_DELAY ); + } + + /* Cleanup */ + for( BaseType_t xCoreID = 0; xCoreID < configNUM_CORES; xCoreID++ ) { + vTaskDelete( xTaskHandles[ xCoreID ] ); + } + vSemaphoreDelete( xTaskDoneSem ); + } + +#endif /* ( configNUM_CORES > 1 ) */ diff --git a/components/freertos/test/integration/freertos_test_utils.h b/components/freertos/test/integration/freertos_test_utils.h new file mode 100644 index 0000000000..fee7259d21 --- /dev/null +++ b/components/freertos/test/integration/freertos_test_utils.h @@ -0,0 +1,32 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "FreeRTOS.h" + +#if ( configNUM_CORES > 1 ) + + /** + * @brief Prototype for test function. + * + * A test function can be passed to vTestOnAllCores() which will run the test function from a task on each core. + */ + typedef void (* TestFunction_t)( void * ); + + /** + * @brief Run a test function on each core + * + * This function will internally create a task pinned to each core, where each task will call the provided test + * function. This function will block until all cores finish executing the test function. + * + * @param pxTestCode Test function + * @param pvTestCodeArg Argument provided to test function + * @param ulStackDepth Stack depth of the created tasks + * @param uxPriority Priority of the created tasks + */ + void vTestOnAllCores( TestFunction_t pxTestCode, void * pvTestCodeArg, uint32_t ulStackDepth, UBaseType_t uxPriority ); + +#endif /* ( configNUM_CORES > 1 ) */