Просмотр исходного кода

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.
Darian Leung 3 лет назад
Родитель
Сommit
882515fcef

+ 82 - 0
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 */

+ 102 - 0
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 <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 ) ) */