mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-06 14:14:33 +02:00
freertos: Add priority scheduling unit tests
This commit adds a priority scheduling unit test to test that the scheduler always schedules the highest priority ready state task. Single core and SMP variants of the test are both added.
This commit is contained in:
@@ -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 */
|
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include <string.h>
|
||||
#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 ) ) */
|
Reference in New Issue
Block a user