From 2a89a247de694e199a484ffcf2594db2ec85232b Mon Sep 17 00:00:00 2001 From: Sudeep Mohanty Date: Mon, 3 Nov 2025 11:24:45 +0800 Subject: [PATCH] test(freertos): Added miscellaneous stability fixes to unit tests This commit adds fixes for freertos unit tests for a more deterministic run and avoid occational failures. --- .../kernel/tasks/test_freertos_psram.c | 3 ++ .../test_vTaskSuspendAll_xTaskResumeAll.c | 1 + .../freertos/kernel/tasks/test_yielding.c | 33 +++++++++++++------ .../freertos/misc/test_tickless_idle.c | 7 ++-- 4 files changed, 32 insertions(+), 12 deletions(-) diff --git a/components/freertos/test_apps/freertos/kernel/tasks/test_freertos_psram.c b/components/freertos/test_apps/freertos/kernel/tasks/test_freertos_psram.c index 866b4e4bba..ea6413883e 100644 --- a/components/freertos/test_apps/freertos/kernel/tasks/test_freertos_psram.c +++ b/components/freertos/test_apps/freertos/kernel/tasks/test_freertos_psram.c @@ -140,6 +140,9 @@ TEST_CASE("Task on specific core works", "[freertos][psram]") TEST_ASSERT_EQUAL((size_t) corenum, corenum_info.recorded_core_num); vTaskDelete(task_handle); + + // Add a short delay to allow the idle task to free any remaining task memory + vTaskDelay(10); } } #endif // !CONFIG_FREERTOS_UNICORE diff --git a/components/freertos/test_apps/freertos/kernel/tasks/test_vTaskSuspendAll_xTaskResumeAll.c b/components/freertos/test_apps/freertos/kernel/tasks/test_vTaskSuspendAll_xTaskResumeAll.c index e6dd88c7aa..746540bc02 100644 --- a/components/freertos/test_apps/freertos/kernel/tasks/test_vTaskSuspendAll_xTaskResumeAll.c +++ b/components/freertos/test_apps/freertos/kernel/tasks/test_vTaskSuspendAll_xTaskResumeAll.c @@ -394,6 +394,7 @@ TEST_CASE("Test vTaskSuspendAll allows scheduling on other cores", "[freertos]") // Cleanup tasks vTaskDelete(a1_task_hdl); vTaskDelete(b1_task_hdl); + vTaskDelay(10); } vSemaphoreDelete(test_unblk_done_sem); diff --git a/components/freertos/test_apps/freertos/kernel/tasks/test_yielding.c b/components/freertos/test_apps/freertos/kernel/tasks/test_yielding.c index 6da218976f..9d5d7b2c5e 100644 --- a/components/freertos/test_apps/freertos/kernel/tasks/test_yielding.c +++ b/components/freertos/test_apps/freertos/kernel/tasks/test_yielding.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 */ @@ -34,6 +34,9 @@ static volatile uint32_t count; // Lock variable to create a blocked task scenario static volatile SemaphoreHandle_t task_mutex; +// Semaphore to synchronize yield test tasks +static SemaphoreHandle_t yield_sync_sem; + // This helper macro is used to store the task id atomically #define STORE_TASK_ID(task_id) ({ \ portENTER_CRITICAL(&idx_lock); \ @@ -56,10 +59,11 @@ static void yield_task1(void *arg) /* Store task_id in the sequence array */ STORE_TASK_ID(task_id); - /* Notify the yield_task2 to run */ - task_sequence_ready = true; + /* Give semaphore to unblock yield_task2, making it READY (not just setting a flag). + * This ensures task2 is in the ready queue when we yield. */ + xSemaphoreGive(yield_sync_sem); - /* Yield */ + /* Yield - now task2 is guaranteed to be READY and should run next */ taskYIELD(); /* Increment task count to notify unity task */ @@ -73,10 +77,9 @@ static void yield_task2(void *arg) { uint32_t task_id = (uint32_t)arg; - /* Wait for the other task to run for the test to begin */ - while (!task_sequence_ready) { - vTaskDelay(10); - }; + /* Block on semaphore - this ensures task1 runs first and we don't poll. + * When task1 gives the semaphore, we transition directly to READY state. */ + xSemaphoreTake(yield_sync_sem, portMAX_DELAY); /* Store task_id in the sequence array */ STORE_TASK_ID(task_id); @@ -108,9 +111,16 @@ TEST_CASE("Task yield must run the next ready task of the same priority", "[free /* Reset task sequence flag */ task_sequence_ready = false; - /* Create test tasks */ - xTaskCreatePinnedToCore(yield_task1, "yield_task1", 2048, (void *)1, UNITY_FREERTOS_PRIORITY - 1, NULL, UNITY_FREERTOS_CPU); + /* Create semaphore for synchronization - start empty so task2 blocks */ + yield_sync_sem = xSemaphoreCreateBinary(); + TEST_ASSERT_NOT_NULL(yield_sync_sem); + + /* Create test tasks - order matters! + * Task2 is created first and will immediately block on the semaphore. + * Task1 is created second and will run first since task2 is blocked. */ xTaskCreatePinnedToCore(yield_task2, "yield_task2", 2048, (void *)2, UNITY_FREERTOS_PRIORITY - 1, NULL, UNITY_FREERTOS_CPU); + vTaskDelay(1); /* Ensure task2 has blocked on semaphore before creating task1 */ + xTaskCreatePinnedToCore(yield_task1, "yield_task1", 2048, (void *)1, UNITY_FREERTOS_PRIORITY - 1, NULL, UNITY_FREERTOS_CPU); /* Wait for the tasks to finish up */ while (count != 2) { @@ -122,6 +132,9 @@ TEST_CASE("Task yield must run the next ready task of the same priority", "[free /* Verify that the yield is successful and the next ready task is run */ TEST_ASSERT_EQUAL(1, task_yield_sequence[idx++]); TEST_ASSERT_EQUAL(2, task_yield_sequence[idx++]); + + /* Clean up semaphore */ + vSemaphoreDelete(yield_sync_sem); } /* diff --git a/components/freertos/test_apps/freertos/misc/test_tickless_idle.c b/components/freertos/test_apps/freertos/misc/test_tickless_idle.c index 7ed64ddf35..aa73b5346c 100644 --- a/components/freertos/test_apps/freertos/misc/test_tickless_idle.c +++ b/components/freertos/test_apps/freertos/misc/test_tickless_idle.c @@ -10,6 +10,7 @@ #include "freertos/semphr.h" #include "esp_pm.h" #include "esp_private/esp_clk.h" +#include "esp_clk_tree.h" #include "sdkconfig.h" @@ -66,9 +67,11 @@ static void consumer_task(void *arg) TEST_CASE("Test semaphore timeout during tickless idle", "[freertos]") { // Configure tickless idle + uint32_t xtal_hz = 0; + esp_clk_tree_src_get_freq_hz(SOC_MOD_CLK_XTAL, ESP_CLK_TREE_SRC_FREQ_PRECISION_EXACT, &xtal_hz); esp_pm_config_t pm_config = { - .max_freq_mhz = esp_clk_cpu_freq() / MHZ, - .min_freq_mhz = esp_clk_cpu_freq() / MHZ, + .max_freq_mhz = CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ, + .min_freq_mhz = xtal_hz / MHZ, .light_sleep_enable = true, }; TEST_ESP_OK(esp_pm_configure(&pm_config));