mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
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.
This commit is contained in:
@@ -140,6 +140,9 @@ TEST_CASE("Task on specific core works", "[freertos][psram]")
|
|||||||
TEST_ASSERT_EQUAL((size_t) corenum, corenum_info.recorded_core_num);
|
TEST_ASSERT_EQUAL((size_t) corenum, corenum_info.recorded_core_num);
|
||||||
|
|
||||||
vTaskDelete(task_handle);
|
vTaskDelete(task_handle);
|
||||||
|
|
||||||
|
// Add a short delay to allow the idle task to free any remaining task memory
|
||||||
|
vTaskDelay(10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // !CONFIG_FREERTOS_UNICORE
|
#endif // !CONFIG_FREERTOS_UNICORE
|
||||||
|
|||||||
+1
@@ -387,6 +387,7 @@ TEST_CASE("Test vTaskSuspendAll allows scheduling on other cores", "[freertos]")
|
|||||||
// Cleanup tasks
|
// Cleanup tasks
|
||||||
vTaskDelete(a1_task_hdl);
|
vTaskDelete(a1_task_hdl);
|
||||||
vTaskDelete(b1_task_hdl);
|
vTaskDelete(b1_task_hdl);
|
||||||
|
vTaskDelay(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
vSemaphoreDelete(test_unblk_done_sem);
|
vSemaphoreDelete(test_unblk_done_sem);
|
||||||
|
|||||||
@@ -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
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -34,6 +34,9 @@ static volatile uint32_t count;
|
|||||||
// Lock variable to create a blocked task scenario
|
// Lock variable to create a blocked task scenario
|
||||||
static volatile SemaphoreHandle_t task_mutex;
|
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
|
// This helper macro is used to store the task id atomically
|
||||||
#define STORE_TASK_ID(task_id) ({ \
|
#define STORE_TASK_ID(task_id) ({ \
|
||||||
portENTER_CRITICAL(&idx_lock); \
|
portENTER_CRITICAL(&idx_lock); \
|
||||||
@@ -56,10 +59,11 @@ static void yield_task1(void *arg)
|
|||||||
/* Store task_id in the sequence array */
|
/* Store task_id in the sequence array */
|
||||||
STORE_TASK_ID(task_id);
|
STORE_TASK_ID(task_id);
|
||||||
|
|
||||||
/* Notify the yield_task2 to run */
|
/* Give semaphore to unblock yield_task2, making it READY (not just setting a flag).
|
||||||
task_sequence_ready = true;
|
* 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();
|
taskYIELD();
|
||||||
|
|
||||||
/* Increment task count to notify unity task */
|
/* Increment task count to notify unity task */
|
||||||
@@ -73,10 +77,9 @@ static void yield_task2(void *arg)
|
|||||||
{
|
{
|
||||||
uint32_t task_id = (uint32_t)arg;
|
uint32_t task_id = (uint32_t)arg;
|
||||||
|
|
||||||
/* Wait for the other task to run for the test to begin */
|
/* Block on semaphore - this ensures task1 runs first and we don't poll.
|
||||||
while (!task_sequence_ready) {
|
* When task1 gives the semaphore, we transition directly to READY state. */
|
||||||
vTaskDelay(10);
|
xSemaphoreTake(yield_sync_sem, portMAX_DELAY);
|
||||||
};
|
|
||||||
|
|
||||||
/* Store task_id in the sequence array */
|
/* Store task_id in the sequence array */
|
||||||
STORE_TASK_ID(task_id);
|
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 */
|
/* Reset task sequence flag */
|
||||||
task_sequence_ready = false;
|
task_sequence_ready = false;
|
||||||
|
|
||||||
/* Create test tasks */
|
/* Create semaphore for synchronization - start empty so task2 blocks */
|
||||||
xTaskCreatePinnedToCore(yield_task1, "yield_task1", 2048, (void *)1, UNITY_FREERTOS_PRIORITY - 1, NULL, UNITY_FREERTOS_CPU);
|
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);
|
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 */
|
/* Wait for the tasks to finish up */
|
||||||
while (count != 2) {
|
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 */
|
/* Verify that the yield is successful and the next ready task is run */
|
||||||
TEST_ASSERT_EQUAL(1, task_yield_sequence[idx++]);
|
TEST_ASSERT_EQUAL(1, task_yield_sequence[idx++]);
|
||||||
TEST_ASSERT_EQUAL(2, task_yield_sequence[idx++]);
|
TEST_ASSERT_EQUAL(2, task_yield_sequence[idx++]);
|
||||||
|
|
||||||
|
/* Clean up semaphore */
|
||||||
|
vSemaphoreDelete(yield_sync_sem);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include "freertos/semphr.h"
|
#include "freertos/semphr.h"
|
||||||
#include "esp_pm.h"
|
#include "esp_pm.h"
|
||||||
#include "esp_private/esp_clk.h"
|
#include "esp_private/esp_clk.h"
|
||||||
|
#include "esp_clk_tree.h"
|
||||||
|
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
@@ -66,9 +67,11 @@ static void consumer_task(void *arg)
|
|||||||
TEST_CASE("Test semaphore timeout during tickless idle", "[freertos]")
|
TEST_CASE("Test semaphore timeout during tickless idle", "[freertos]")
|
||||||
{
|
{
|
||||||
// Configure tickless idle
|
// 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 = {
|
esp_pm_config_t pm_config = {
|
||||||
.max_freq_mhz = esp_clk_cpu_freq() / MHZ,
|
.max_freq_mhz = CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ,
|
||||||
.min_freq_mhz = esp_clk_cpu_freq() / MHZ,
|
.min_freq_mhz = xtal_hz / MHZ,
|
||||||
.light_sleep_enable = true,
|
.light_sleep_enable = true,
|
||||||
};
|
};
|
||||||
TEST_ESP_OK(esp_pm_configure(&pm_config));
|
TEST_ESP_OK(esp_pm_configure(&pm_config));
|
||||||
|
|||||||
Reference in New Issue
Block a user