diff --git a/components/freertos/test/integration/tasks/test_priority_scheduling.c b/components/freertos/test/integration/tasks/test_priority_scheduling.c new file mode 100644 index 0000000000..a9b7e76fa8 --- /dev/null +++ b/components/freertos/test/integration/tasks/test_priority_scheduling.c @@ -0,0 +1,82 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "FreeRTOS.h" +#include "task.h" +#include "unity.h" +#include "portTestMacro.h" + +/* ------------------------------------------------------------------------------------------------------------------ */ + +/* +Test Priority Scheduling (Single Core) + +Purpose: + - Test that the single-core scheduler always schedules the highest priority ready task +Procedure: + - Raise the unityTask priority to (configMAX_PRIORITIES - 1) + - unityTask creates the following lower priority tasks + - task_A (configMAX_PRIORITIES - 2) + - task_B (configMAX_PRIORITIES - 3) + - UnityTask blocks for a short period of time to allow task_A to run + - Clean up and restore unityTask's original priority +Expected: + - task_A should run after unityTask blocks + - task_B should never have run +*/ + +#if ( configNUM_CORES == 1 ) + +#define UNITY_TASK_DELAY_TICKS 10 + +static BaseType_t task_A_ran; +static BaseType_t task_B_ran; + +static void task_A(void *arg) +{ + task_A_ran = pdTRUE; + /* Keeping spinning to prevent the lower priority task_B from running */ + while (1) { + ; + } +} + +static void task_B(void *arg) +{ + /* The following should never run due to task_B having a lower priority */ + task_B_ran = pdTRUE; + while (1) { + ; + } +} + +TEST_CASE("Tasks: Test priority scheduling", "[freertos]") +{ + TaskHandle_t task_A_handle; + TaskHandle_t task_B_handle; + task_A_ran = pdFALSE; + task_B_ran = pdFALSE; + + /* Raise the priority of the unityTask */ + vTaskPrioritySet(NULL, configMAX_PRIORITIES - 1); + /* Create task_A and task_B */ + xTaskCreate(task_A, "task_A", configTEST_DEFAULT_STACK_SIZE, (void *)xTaskGetCurrentTaskHandle(), configMAX_PRIORITIES - 2, &task_A_handle); + xTaskCreate(task_B, "task_B", configTEST_DEFAULT_STACK_SIZE, (void *)xTaskGetCurrentTaskHandle(), configMAX_PRIORITIES - 3, &task_B_handle); + + /* Block to allow task_A to be scheduled */ + vTaskDelay(UNITY_TASK_DELAY_TICKS); + + /* Test that only task_A has run */ + TEST_ASSERT_EQUAL(pdTRUE, task_A_ran); + TEST_ASSERT_EQUAL(pdFALSE, task_B_ran); + + vTaskDelete(task_A_handle); + vTaskDelete(task_B_handle); + /* Restore the priority of the unityTask */ + vTaskPrioritySet(NULL, configTEST_UNITY_TASK_PRIORITY); +} + +#endif /* configNUM_CORES == 1 */ diff --git a/components/freertos/test/integration/tasks/test_priority_scheduling_smp.c b/components/freertos/test/integration/tasks/test_priority_scheduling_smp.c new file mode 100644 index 0000000000..2f4b0cad9a --- /dev/null +++ b/components/freertos/test/integration/tasks/test_priority_scheduling_smp.c @@ -0,0 +1,102 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "sdkconfig.h" +#include +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" +#include "unity.h" +#include "portTestMacro.h" + +/* ------------------------------------------------------------------------------------------------------------------ */ + +/* +Test Priority Scheduling SMP + +Purpose: + - Test that the SMP scheduler always schedules the highest priority ready tasks for each core +Procedure: + - Raise the unityTask priority to (configMAX_PRIORITIES - 1) + - unityTask creates the following lower priority tasks for each core + - task_A (configMAX_PRIORITIES - 2) for each core + - task_B (configMAX_PRIORITIES - 3) for each core + - unityTask blocks for a short period of time to allow all of the task_As to run + - Clean up and restore unityTask's original priority +Expected: + - All of the task_As should be run by the scheduler + - None of the task_Bs should have run +*/ + +#if ( defined( CONFIG_FREERTOS_SMP ) && ( configNUM_CORES > 1 ) && ( configRUN_MULTIPLE_PRIORITIES == 1 ) ) \ + || ( !defined( CONFIG_FREERTOS_SMP ) && ( configNUM_CORES > 1 ) ) + +#define UNITY_TASK_DELAY_TICKS 10 + +static BaseType_t task_A_ran[configNUM_CORES]; +static BaseType_t task_B_ran[configNUM_CORES]; + +static void task_A(void *arg) +{ + BaseType_t task_idx = (BaseType_t) arg; + task_A_ran[task_idx] = pdTRUE; + /* Keeping spinning to prevent the lower priority task_B from running */ + while (1) { + ; + } +} + +static void task_B(void *arg) +{ + /* The following should never be run due to task_B having a lower priority */ + BaseType_t task_idx = (BaseType_t) arg; + task_B_ran[task_idx] = pdTRUE; + while (1) { + ; + } +} + +TEST_CASE("Tasks: Test priority scheduling (SMP)", "[freertos]") +{ + TaskHandle_t task_A_handles[configNUM_CORES]; + TaskHandle_t task_B_handles[configNUM_CORES]; + memset(task_A_ran, pdFALSE, sizeof(task_A_ran)); + memset(task_B_ran, pdFALSE, sizeof(task_B_ran)); + + /* Raise the priority of the unityTask */ + vTaskPrioritySet(NULL, configMAX_PRIORITIES - 1); + + /* Create task_A for each core */ + for (UBaseType_t x = 0; x < configNUM_CORES; x++) { + xTaskCreate(task_A, "task_A", configTEST_DEFAULT_STACK_SIZE, (void *)x, configMAX_PRIORITIES - 2, &task_A_handles[x]); + } + + /* Create task_B for each core */ + for (UBaseType_t x = 0; x < configNUM_CORES; x++) { + xTaskCreate(task_B, "task_B", configTEST_DEFAULT_STACK_SIZE, (void *)x, configMAX_PRIORITIES - 3, &task_B_handles[x]); + } + + /* Block to ensure all the task_As to be scheduled */ + vTaskDelay(UNITY_TASK_DELAY_TICKS); + + /* Check that all the task_As have run, and none of the task_Bs have run */ + for (UBaseType_t x = 0; x < configNUM_CORES; x++) { + TEST_ASSERT_EQUAL(pdTRUE, task_A_ran[x]); + TEST_ASSERT_EQUAL(pdFALSE, task_B_ran[x]); + } + + /* Cleanup */ + for (UBaseType_t x = 0; x < configNUM_CORES; x++) { + vTaskDelete(task_A_handles[x]); + vTaskDelete(task_B_handles[x]); + } + + /* Restore the priority of the unityTask */ + vTaskPrioritySet(NULL, configTEST_UNITY_TASK_PRIORITY); +} + +#endif /* ( defined( CONFIG_FREERTOS_SMP ) && ( configNUM_CORES > 1 ) && ( configRUN_MULTIPLE_PRIORITIES == 1 ) ) + || ( !defined( CONFIG_FREERTOS_SMP ) && ( configNUM_CORES > 1 ) ) */