diff --git a/components/freertos/test/CMakeLists.txt b/components/freertos/test/CMakeLists.txt index e25755ba72..00b876bf1c 100644 --- a/components/freertos/test/CMakeLists.txt +++ b/components/freertos/test/CMakeLists.txt @@ -1,5 +1,3 @@ idf_component_register(SRC_DIRS . PRIV_INCLUDE_DIRS . PRIV_REQUIRES cmock test_utils esp_system driver) -# Enable task snapshots by setting configENABLE_TASK_SNAPSHOT macro -idf_build_set_property(COMPILE_OPTIONS "-DconfigENABLE_TASK_SNAPSHOT=1" APPEND) diff --git a/components/freertos/test/test_tasks_snapshot.c b/components/freertos/test/test_tasks_snapshot.c index 20ffd8d855..8551005d13 100644 --- a/components/freertos/test/test_tasks_snapshot.c +++ b/components/freertos/test/test_tasks_snapshot.c @@ -1,38 +1,151 @@ /* - Test FreeRTOS support for core dump. -*/ + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "sdkconfig.h" + +#if CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT #include -#include "esp_cpu.h" #include "freertos/FreeRTOS.h" +#include "freertos/task.h" #include "freertos/task_snapshot.h" +#include "esp_cpu.h" #include "unity.h" #include "sdkconfig.h" -#define TEST_MAX_TASKS_NUM 32 +#define TEST_MAX_TASKS_NUM 32 +#define NUM_TASKS_PER_LIST 2 +#define TASK_PRIORITY (configMAX_PRIORITIES - 2) -/* simple test to check that in normal conditions uxTaskGetSnapshotAll does not generate exception */ -TEST_CASE("Tasks snapshot", "[freertos]") +static void ready_task(void *arg) { - TaskSnapshot_t tasks[TEST_MAX_TASKS_NUM]; - UBaseType_t tcb_sz; -#ifndef CONFIG_FREERTOS_UNICORE - int other_core_id = xPortGetCoreID() == 0 ? 1 : 0; -#endif - - // uxTaskGetSnapshotAll is supposed to be called when all tasks on both CPUs are - // inactive and can not alter FreeRTOS internal tasks lists, e.g. from panic handler - unsigned state = portSET_INTERRUPT_MASK_FROM_ISR(); -#ifndef CONFIG_FREERTOS_UNICORE - esp_cpu_stall(other_core_id); -#endif - UBaseType_t task_num = uxTaskGetSnapshotAll(tasks, TEST_MAX_TASKS_NUM, &tcb_sz); -#ifndef CONFIG_FREERTOS_UNICORE - esp_cpu_unstall(other_core_id); -#endif - portCLEAR_INTERRUPT_MASK_FROM_ISR(state); - - printf("Dumped %d tasks. TCB size %d\n", task_num, tcb_sz); - TEST_ASSERT_NOT_EQUAL(0, task_num); - TEST_ASSERT_NOT_EQUAL(0, tcb_sz); + while (1) { + ; + } } + +static void blocked_task(void *arg) +{ + // Delay for portMAX_DELAY - 1 as not to go on the suspended list + vTaskDelay(portMAX_DELAY - 1); +} + +static void suspended_task(void *arg) +{ + vTaskSuspend(NULL); +} + +static void setup(TaskHandle_t *task_list, int *num_tasks_ret, UBaseType_t *old_priority_ret) +{ + // Raise our priority so that we aren't preempted + *old_priority_ret = uxTaskPriorityGet(NULL); + vTaskPrioritySet(NULL, configMAX_PRIORITIES - 1); + + // Create tasks + int num_tasks = 0; + for (int i = 0; i < NUM_TASKS_PER_LIST; i++) { + //Ready task + xTaskCreate(ready_task, "ready", 1024, NULL, TASK_PRIORITY, &(task_list[num_tasks])); + num_tasks++; + //Blocked task + xTaskCreate(blocked_task, "blkd", 1024, NULL, TASK_PRIORITY, &(task_list[num_tasks])); + num_tasks++; + //Suspended task + xTaskCreate(suspended_task, "susp", 1024, NULL, TASK_PRIORITY, &(task_list[num_tasks])); + num_tasks++; + } + *num_tasks_ret = num_tasks; + // Short delay to allow tasks to spin up + vTaskDelay(10); + + // Stop preemption on this core, and stall the other core + taskDISABLE_INTERRUPTS(); +#if !CONFIG_FREERTOS_UNICORE + esp_cpu_stall(!xPortGetCoreID()); +#endif + + +} + +static void check_snapshots(TaskHandle_t *task_list, int num_tasks, TaskSnapshot_t *task_snapshots, UBaseType_t num_snapshots) +{ + // Check task snapshots. Every created task should be found in the task snapshot + for (int i = 0; i < num_tasks; i++) { + bool found = false; + for (int j = 0; j < num_snapshots; j++) { + if (task_list[i] == (TaskHandle_t)task_snapshots[j].pxTCB) { + found = true; + break; + } + } + TEST_ASSERT(found); + } +} + +static void teardown(TaskHandle_t *task_list, int num_tasks, UBaseType_t old_priority) +{ + // Resume other cores and allow preemption +#if !CONFIG_FREERTOS_UNICORE + esp_cpu_unstall(!xPortGetCoreID()); +#endif + taskENABLE_INTERRUPTS(); + + for (int i = 0; i < num_tasks; i++) { + vTaskDelete(task_list[i]); + } + // Restore priority + vTaskPrioritySet(NULL, old_priority); + // Short delay to allow tasks to clean up + vTaskDelay(10); +} + +TEST_CASE("Task snapshot: Get all", "[freertos]") +{ + // Short delay to allow both cores to spin up + vTaskDelay(10); + + TaskHandle_t task_list[TEST_MAX_TASKS_NUM]; + int num_tasks; + UBaseType_t old_priority; + setup(task_list, &num_tasks, &old_priority); + + // Get task snapshots using uxTaskGetSnapshotAll() + TaskSnapshot_t task_snapshots[TEST_MAX_TASKS_NUM]; + UBaseType_t tcb_size; + UBaseType_t num_snapshots; + num_snapshots = uxTaskGetSnapshotAll(task_snapshots, TEST_MAX_TASKS_NUM, &tcb_size); + TEST_ASSERT_LESS_OR_EQUAL(TEST_MAX_TASKS_NUM, num_snapshots); + + check_snapshots(task_list, num_tasks, task_snapshots, num_snapshots); + teardown(task_list, num_tasks, old_priority); +} + +TEST_CASE("Task snapshot: Iterate", "[freertos]") +{ + // Short delay to allow both cores to spin up + vTaskDelay(10); + + TaskHandle_t task_list[TEST_MAX_TASKS_NUM]; + int num_tasks; + UBaseType_t old_priority; + setup(task_list, &num_tasks, &old_priority); + + // Get task snapshots using pxTaskGetNext() and vTaskGetSnapshot() + TaskSnapshot_t task_snapshots[TEST_MAX_TASKS_NUM]; + UBaseType_t num_snapshots = 0; + TaskHandle_t cur_task_handle = pxTaskGetNext(NULL); + while (cur_task_handle != NULL) { + // Get the task's snapshot + vTaskGetSnapshot(cur_task_handle, &task_snapshots[num_snapshots]); + num_snapshots++; + cur_task_handle = pxTaskGetNext(cur_task_handle); + } + TEST_ASSERT_LESS_OR_EQUAL(TEST_MAX_TASKS_NUM, num_snapshots); + + check_snapshots(task_list, num_tasks, task_snapshots, num_snapshots); + teardown(task_list, num_tasks, old_priority); +} + +#endif // CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT diff --git a/tools/unit-test-app/configs/freertos_options b/tools/unit-test-app/configs/freertos_options index d48ae92fb1..3e3196c6c5 100644 --- a/tools/unit-test-app/configs/freertos_options +++ b/tools/unit-test-app/configs/freertos_options @@ -20,3 +20,4 @@ CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y CONFIG_FREERTOS_FPU_IN_ISR=y CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=16 +CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT=y