From 10c888c85960e199fc696dfd386e7ab8397a1eb4 Mon Sep 17 00:00:00 2001 From: Meet Patel Date: Tue, 7 Jul 2026 10:11:18 +0530 Subject: [PATCH] test(esp_system): relocate FreeRTOS tick hook test Tick hook registration lives in esp_system, so its scheduler-suspension coverage belongs in the esp_system unity test app rather than the freertos IDF additions suite. --- .../main/CMakeLists.txt | 1 + .../main/test_freertos_tick_hooks.c | 120 ++++++++++++++++++ .../freertos/misc/test_idf_additions.c | 106 ---------------- 3 files changed, 121 insertions(+), 106 deletions(-) create mode 100644 components/esp_system/test_apps/esp_system_unity_tests/main/test_freertos_tick_hooks.c diff --git a/components/esp_system/test_apps/esp_system_unity_tests/main/CMakeLists.txt b/components/esp_system/test_apps/esp_system_unity_tests/main/CMakeLists.txt index b22dd0124f0..4ac7300c83b 100644 --- a/components/esp_system/test_apps/esp_system_unity_tests/main/CMakeLists.txt +++ b/components/esp_system/test_apps/esp_system_unity_tests/main/CMakeLists.txt @@ -9,6 +9,7 @@ set(requires "unity" set(SRC "test_app_main.c" "test_backtrace.c" + "test_freertos_tick_hooks.c" "test_ipc.c" "test_panic.c" "test_reset_reason.c" diff --git a/components/esp_system/test_apps/esp_system_unity_tests/main/test_freertos_tick_hooks.c b/components/esp_system/test_apps/esp_system_unity_tests/main/test_freertos_tick_hooks.c new file mode 100644 index 00000000000..96aa1bc4482 --- /dev/null +++ b/components/esp_system/test_apps/esp_system_unity_tests/main/test_freertos_tick_hooks.c @@ -0,0 +1,120 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "sdkconfig.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_freertos_hooks.h" +#include "esp_rom_sys.h" +#include "unity.h" +#include "test_utils.h" +#include +#include + +#if !CONFIG_FREERTOS_SMP +/* +Scheduler suspension behavior has changed in SMP FreeRTOS, thus these tests are disabled for SMP FreeRTOS. +See IDF-5201 +*/ + +/* --------------------------------------------------------------------------------------------------------------------- +FreeRTOS tick hooks during scheduler suspension + +Purpose: + - Test that esp_system FreeRTOS tick hooks are called even with scheduler suspension + +Procedure: + Each core gets tested in the role of core X + - Create suspend_task pinned to core X which will register a tick hook on core X and suspend scheduler on core X + - Register tick hook on core X + - suspend_task suspends scheduling on core X for Y milliseconds and then resumes scheduling + - Delay suspend_task for Y milliseconds more after scheduler resumption + - De-register the tick hook + - Verify the tick hook callback count + +Expected: + - The tick hook is called for Y * 2 times +--------------------------------------------------------------------------------------------------------------------- */ + +#define TEST_DELAY_MS 200 +static volatile uint32_t tick_hook_count[portNUM_PROCESSORS]; + +static void IRAM_ATTR tick_hook(void) +{ + tick_hook_count[portGET_CORE_ID()] += portTICK_PERIOD_MS; +} + +static void suspend_task(void *arg) +{ + TaskHandle_t main_task_hdl = (TaskHandle_t)arg; + + /* Fetch the current core ID */ + BaseType_t xCoreID = portGET_CORE_ID(); + + /* Warm up the cache by running the scheduler suspension/resumption once. + * This reduces the execution time variance caused by cache misses during + * the actual test on targets like the esp32p4. + */ + vTaskSuspendAll(); + xTaskResumeAll(); + vTaskDelay(pdMS_TO_TICKS(10)); + + /* Register tick hook */ + tick_hook_count[xCoreID] = 0; + esp_register_freertos_tick_hook_for_cpu(tick_hook, xCoreID); + + /* Read the tick hook count before suspending */ + uint32_t initial_count = tick_hook_count[xCoreID]; + + /* Suspend scheduler */ + vTaskSuspendAll(); + + /* Suspend for TEST_DELAY_MS milliseconds */ + esp_rom_delay_us(TEST_DELAY_MS * 1000); + + /* Resume scheduler */ + xTaskResumeAll(); + + /* Delay for a further TEST_DELAY_MS milliseconds after scheduler resumption */ + vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_MS)); + + /* Read the final tick hook count */ + uint32_t final_count = tick_hook_count[xCoreID]; + + /* De-register tick hook */ + esp_deregister_freertos_tick_hook_for_cpu(tick_hook, xCoreID); + + /* Verify that the tick hook callback count equals the scheduler suspension time + the delay time. + * We add a variation of 2 ticks to account for delays encountered during test setup and teardown. + */ + printf("Core%d initial_count = %"PRIu32"\n", xCoreID, initial_count); + printf("Core%d final_count = %"PRIu32"\n", xCoreID, final_count); + TEST_ASSERT_INT_WITHIN(portTICK_PERIOD_MS * 2, TEST_DELAY_MS * 2, final_count - initial_count); + + /* Signal main task of test completion */ + xTaskNotifyGive(main_task_hdl); + + vTaskSuspend(NULL); +} + +TEST_CASE("FreeRTOS tick hooks during scheduler suspension", "[esp_system]") +{ + /* Run test for each core */ + TaskHandle_t suspend_task_handle[portNUM_PROCESSORS]; + for (int x = 0; x < portNUM_PROCESSORS; x++) { + xTaskCreatePinnedToCore(&suspend_task, "suspend_task", 8192, (void *)xTaskGetCurrentTaskHandle(), UNITY_FREERTOS_PRIORITY, &suspend_task_handle[x], x); + + /* Wait for test completion */ + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + + /* Cleanup */ + vTaskSuspend(suspend_task_handle[x]); + vTaskDelay(10); + vTaskDelete(suspend_task_handle[x]); + } +} + +#endif /* !CONFIG_FREERTOS_SMP */ diff --git a/components/freertos/test_apps/freertos/misc/test_idf_additions.c b/components/freertos/test_apps/freertos/misc/test_idf_additions.c index 8960084c1bd..0e3e05145fc 100644 --- a/components/freertos/test_apps/freertos/misc/test_idf_additions.c +++ b/components/freertos/test_apps/freertos/misc/test_idf_additions.c @@ -17,7 +17,6 @@ #include "esp_memory_utils.h" #include "unity.h" #include "test_utils.h" -#include "esp_freertos_hooks.h" #include #include #include @@ -505,108 +504,3 @@ TEST_CASE("IDF additions: ulTaskGetIdleRunTimeCounterForCore", "[freertos][idf_a } #endif /* CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS && !CONFIG_FREERTOS_SMP */ - -#if !CONFIG_FREERTOS_SMP -/* -Scheduler suspension behavior has changed in SMP FreeRTOS, thus these test are disabled for SMP FreeRTOS. -See IDF-5201 -*/ - -/* --------------------------------------------------------------------------------------------------------------------- -IDF additions: IDF tick hooks during scheduler suspension - -Purpose: - - Test that the IDF tick hooks are called even with scheduler suspension - -Procedure: - Each core gets tested in the role of core X - - Create suspend_task pinned to core X which will register a tick hook on core X and suspend scheduler on core X - - Register tick hook on core X - - suspend_task suspends scheduling on core X for Y milliseconds and then resumes scheduling - - Delay suspend_task for Y milliseconds more after scheduler resumption - - De-register the tick hook - - Verify the tick hook callback count - -Expected: - - The tick hook is called for Y * 2 times ---------------------------------------------------------------------------------------------------------------------- */ - -#define TEST_DELAY_MS 200 -static volatile uint32_t tick_hook_count[portNUM_PROCESSORS]; - -static void IRAM_ATTR tick_hook(void) -{ - tick_hook_count[portGET_CORE_ID()] += portTICK_PERIOD_MS; -} - -static void suspend_task(void *arg) -{ - TaskHandle_t main_task_hdl = (TaskHandle_t)arg; - - /* Fetch the current core ID */ - BaseType_t xCoreID = portGET_CORE_ID(); - - /* Warm up the cache by running the scheduler suspension/resumption once. - * This reduces the execution time variance caused by cache misses during - * the actual test on targets like the esp32p4. - */ - vTaskSuspendAll(); - xTaskResumeAll(); - vTaskDelay(pdMS_TO_TICKS(10)); - - /* Register tick hook */ - tick_hook_count[xCoreID] = 0; - esp_register_freertos_tick_hook_for_cpu(tick_hook, xCoreID); - - /* Read the tick hook count before suspending */ - uint32_t initial_count = tick_hook_count[xCoreID]; - - /* Suspend scheduler */ - vTaskSuspendAll(); - - /* Suspend for TEST_DELAY_MS milliseconds */ - esp_rom_delay_us(TEST_DELAY_MS * 1000); - - /* Resume scheduler */ - xTaskResumeAll(); - - /* Delay for a further TEST_DELAY_MS milliseconds after scheduler resumption */ - vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_MS)); - - /* Read the final tick hook count */ - uint32_t final_count = tick_hook_count[xCoreID]; - - /* De-register tick hook */ - esp_deregister_freertos_tick_hook_for_cpu(tick_hook, xCoreID); - - /* Verify that the tick hook callback count equals the scheduler suspension time + the delay time. - * We add a variation of 2 ticks to account for delays encountered during test setup and teardown. - */ - printf("Core%d initial_count = %"PRIu32"\n", xCoreID, initial_count); - printf("Core%d final_count = %"PRIu32"\n", xCoreID, final_count); - TEST_ASSERT_INT_WITHIN(portTICK_PERIOD_MS * 2, TEST_DELAY_MS * 2, final_count - initial_count); - - /* Signal main task of test completion */ - xTaskNotifyGive(main_task_hdl); - - vTaskSuspend(NULL); -} - -TEST_CASE("IDF additions: IDF tick hooks during scheduler suspension", "[freertos]") -{ - /* Run test for each core */ - TaskHandle_t suspend_task_handle[portNUM_PROCESSORS]; - for (int x = 0; x < portNUM_PROCESSORS; x++) { - xTaskCreatePinnedToCore(&suspend_task, "suspend_task", 8192, (void *)xTaskGetCurrentTaskHandle(), UNITY_FREERTOS_PRIORITY, &suspend_task_handle[x], x); - - /* Wait for test completion */ - ulTaskNotifyTake(pdTRUE, portMAX_DELAY); - - /* Cleanup */ - vTaskSuspend(suspend_task_handle[x]); - vTaskDelay(10); - vTaskDelete(suspend_task_handle[x]); - } -} - -#endif // !CONFIG_FREERTOS_SMP