From 731a4f05fd46afb76b67892599b26bc126c451dc Mon Sep 17 00:00:00 2001 From: chinglee-iot <61685396+chinglee-iot@users.noreply.github.com> Date: Tue, 27 Feb 2024 11:29:15 +0800 Subject: [PATCH] Add SMP schedule highest priority on-target test (#1167) * Add SMP scheduler highest priority task on target test --------- Signed-off-by: Gaurav Aggarwal Co-authored-by: Rahul Kar <118818625+kar-rahul-aws@users.noreply.github.com> Co-authored-by: Gaurav Aggarwal Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> --- .../Test/Target/boards/pico/FreeRTOSConfig.h | 2 +- .../schedule_highest_priority/CMakeLists.txt | 33 +++ .../schedule_highest_priority_test_runner.c | 73 ++++++ .../schedule_highest_priority.c | 220 ++++++++++++++++++ .../schedule_highest_priority/test_config.h | 63 +++++ 5 files changed, 390 insertions(+), 1 deletion(-) create mode 100644 FreeRTOS/Test/Target/boards/pico/tests/smp/schedule_highest_priority/CMakeLists.txt create mode 100644 FreeRTOS/Test/Target/boards/pico/tests/smp/schedule_highest_priority/schedule_highest_priority_test_runner.c create mode 100644 FreeRTOS/Test/Target/tests/smp/schedule_highest_priority/schedule_highest_priority.c create mode 100644 FreeRTOS/Test/Target/tests/smp/schedule_highest_priority/test_config.h diff --git a/FreeRTOS/Test/Target/boards/pico/FreeRTOSConfig.h b/FreeRTOS/Test/Target/boards/pico/FreeRTOSConfig.h index 22d7b7720..57ee878e3 100644 --- a/FreeRTOS/Test/Target/boards/pico/FreeRTOSConfig.h +++ b/FreeRTOS/Test/Target/boards/pico/FreeRTOSConfig.h @@ -105,7 +105,7 @@ #define configTICK_CORE 1 #define configRUN_MULTIPLE_PRIORITIES 1 #define configUSE_CORE_AFFINITY 1 -#define configUSE_MINIMAL_IDLE_HOOK 0 +#define configUSE_PASSIVE_IDLE_HOOK 0 #define configUSE_TASK_PREEMPTION_DISABLE 0 /* RP2040 specific */ diff --git a/FreeRTOS/Test/Target/boards/pico/tests/smp/schedule_highest_priority/CMakeLists.txt b/FreeRTOS/Test/Target/boards/pico/tests/smp/schedule_highest_priority/CMakeLists.txt new file mode 100644 index 000000000..d0b96e7bf --- /dev/null +++ b/FreeRTOS/Test/Target/boards/pico/tests/smp/schedule_highest_priority/CMakeLists.txt @@ -0,0 +1,33 @@ +cmake_minimum_required(VERSION 3.13) + +project(example C CXX ASM) +set(CMAKE_C_STANDARD 11) +set(CMAKE_CXX_STANDARD 17) + +set(TEST_INCLUDE_PATHS ${CMAKE_CURRENT_LIST_DIR}/../../../../../tests/smp/schedule_highest_priority) +set(TEST_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/../../../../../tests/smp/schedule_highest_priority) + +add_library(schedule_highest_priority INTERFACE) +target_sources(schedule_highest_priority INTERFACE + ${BOARD_LIBRARY_DIR}/main.c + ${CMAKE_CURRENT_LIST_DIR}/schedule_highest_priority_test_runner.c + ${TEST_SOURCE_DIR}/schedule_highest_priority.c) + +target_include_directories(schedule_highest_priority INTERFACE + ${CMAKE_CURRENT_LIST_DIR}/../../.. + ${TEST_INCLUDE_PATHS} + ) + +target_link_libraries(schedule_highest_priority INTERFACE + FreeRTOS-Kernel + FreeRTOS-Kernel-Heap4 + ${BOARD_LINK_LIBRARIES}) + +add_executable(test_schedule_highest_priority) +enable_board_functions(test_schedule_highest_priority) +target_link_libraries(test_schedule_highest_priority schedule_highest_priority) +target_include_directories(test_schedule_highest_priority PUBLIC + ${BOARD_INCLUDE_PATHS}) +target_compile_definitions(test_schedule_highest_priority PRIVATE + ${BOARD_DEFINES} +) diff --git a/FreeRTOS/Test/Target/boards/pico/tests/smp/schedule_highest_priority/schedule_highest_priority_test_runner.c b/FreeRTOS/Test/Target/boards/pico/tests/smp/schedule_highest_priority/schedule_highest_priority_test_runner.c new file mode 100644 index 000000000..e6c0cb8ad --- /dev/null +++ b/FreeRTOS/Test/Target/boards/pico/tests/smp/schedule_highest_priority/schedule_highest_priority_test_runner.c @@ -0,0 +1,73 @@ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/** + * @file schedule_highest_priority_test_runner.c + * @brief The implementation of main function to start test runner task. + * + * Procedure: + * - Initialize environment. + * - Run the test case. + */ + +/* Kernel includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Unit testing support functions. */ +#include "unity.h" + +/* Pico includes. */ +#include "pico/multicore.h" +#include "pico/stdlib.h" + +/*-----------------------------------------------------------*/ + +static void prvTestRunnerTask( void * pvParameters ); + +/*-----------------------------------------------------------*/ + +static void prvTestRunnerTask( void * pvParameters ) +{ + ( void ) pvParameters; + + /* Run test case. */ + vRunScheduleHighestPriorityTest(); + + vTaskDelete( NULL ); +} +/*-----------------------------------------------------------*/ + +void vRunTest( void ) +{ + xTaskCreate( prvTestRunnerTask, + "testRunner", + configMINIMAL_STACK_SIZE, + NULL, + configMAX_PRIORITIES - 1, + NULL ); +} +/*-----------------------------------------------------------*/ diff --git a/FreeRTOS/Test/Target/tests/smp/schedule_highest_priority/schedule_highest_priority.c b/FreeRTOS/Test/Target/tests/smp/schedule_highest_priority/schedule_highest_priority.c new file mode 100644 index 000000000..e34d7456a --- /dev/null +++ b/FreeRTOS/Test/Target/tests/smp/schedule_highest_priority/schedule_highest_priority.c @@ -0,0 +1,220 @@ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/** + * @file schedule_highest_priority.c + * @brief The scheduler shall correctly schedule the highest priority ready tasks. + * + * Procedure: + * - Create ( num of cores ) tasks ( T0~Tn-1 ). Priority T0 > T1 > ... > Tn-2 > Tn-1. + * - for each task Ti in [T0..Tn-1]: + * - Tasks T0..Ti-1 are running. If any of the task in T0..Ti-1 is not + * running notify the test runner task about error. + * - If i == n -1: + * - Notify test runner task about success. + * Expected: + * - When a task runs, all tasks of higher priority are running. + */ + +/* Standard includes. */ +#include + +/* Kernel includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Unit testing support functions. */ +#include "unity.h" +/*-----------------------------------------------------------*/ + +#if ( configNUMBER_OF_CORES < 2 ) + #error This test is for FreeRTOS SMP and therefore, requires at least 2 cores. +#endif /* #if ( configNUMBER_OF_CORES < 2 ) */ + +#if ( configMAX_PRIORITIES <= configNUMBER_OF_CORES ) + #error This test creates tasks with different priority, requires configMAX_PRIORITIES to be larger than configNUMBER_OF_CORES. +#endif /* #if ( configMAX_PRIORITIES <= configNUMBER_OF_CORES ) */ +/*-----------------------------------------------------------*/ + +/** + * @brief Timeout value to stop test. + */ +#define TEST_TIMEOUT_MS ( 10000U ) + +/** + * @brief Nop operation for busy looping. + */ +#ifdef portNOP + #define TEST_NOP portNOP +#else + #define TEST_NOP() __asm volatile ( "nop" ) +#endif + +/*-----------------------------------------------------------*/ + +/** + * @brief Function that implements a never blocking FreeRTOS task. + */ +static void prvEverRunningTask( void * pvParameters ); +/*-----------------------------------------------------------*/ + +/** + * @brief Handle of the test runner task. + */ +static TaskHandle_t xTestRunnerTaskHandle; + +/** + * @brief Handles of the tasks created in this test. + */ +static TaskHandle_t xTaskHandles[ configNUMBER_OF_CORES ]; + +/** + * @brief Indexes of the tasks created in this test. + */ +static uint32_t xTaskIndexes[ configNUMBER_OF_CORES ]; +/*-----------------------------------------------------------*/ + +/** + * @brief Ever running task function. + * + * Test runner task is notified with the following values: + * - A value between 0 and ( configNUMBER_OF_CORES -1 ) : Task with the index + * equal to value encountered an error during the test. + * - configNUMBER_OF_CORES : The test finished without any error. + */ +static void prvEverRunningTask( void * pvParameters ) +{ + uint32_t i; + uint32_t uxCurrentTaskIdx = *( ( uint32_t * ) pvParameters ); + eTaskState xTaskState; + + /* Tasks with index smaller than the current task are of higher priority and + * must be running when this task is running. */ + for( i = 0; i < uxCurrentTaskIdx; i++ ) + { + xTaskState = eTaskGetState( xTaskHandles[ i ] ); + + if( eRunning != xTaskState ) + { + /* Notify the test runner task about the error. */ + ( void ) xTaskNotify( xTestRunnerTaskHandle, uxCurrentTaskIdx, eSetValueWithoutOverwrite ); + } + } + + /* If current task is the last task, then we finish the check because all + * tasks are checked. */ + if( uxCurrentTaskIdx == ( configNUMBER_OF_CORES - 1 ) ) + { + /* Notify the test runner task about success. */ + ( void ) xTaskNotify( xTestRunnerTaskHandle, configNUMBER_OF_CORES, eSetValueWithoutOverwrite ); + } + + for( ; ; ) + { + /* Busy looping in this task. */ + TEST_NOP(); + } +} +/*-----------------------------------------------------------*/ + +/** + * @brief Test running task. + * + * It waits for a notification from one of the ever running tasks. + */ +void Test_ScheduleHighestPriority( void ) +{ + uint32_t ulNotifiedValue; + BaseType_t xReturn; + + xReturn = xTaskNotifyWait( 0U, ULONG_MAX, &ulNotifiedValue, pdMS_TO_TICKS( TEST_TIMEOUT_MS ) ); + + /* Test runner task is notified within TEST_TIMEOUT_MS. */ + TEST_ASSERT_EQUAL( pdTRUE, xReturn ); + + /* The notified value indicates that no error occurred during the test. */ + TEST_ASSERT_EQUAL_INT( configNUMBER_OF_CORES, ulNotifiedValue ); +} +/*-----------------------------------------------------------*/ + +/** + * @brief Runs before every test, put init calls here. + */ +void setUp( void ) +{ + uint32_t i; + BaseType_t xTaskCreationResult; + + /* Save the test runner task handle here. It is used to notify test runner + * from ever running tasks. */ + xTestRunnerTaskHandle = xTaskGetCurrentTaskHandle(); + + /* Create configNUMBER_OF_CORES tasks with decending priority. */ + for( i = 0; i < configNUMBER_OF_CORES; i++ ) + { + xTaskIndexes[ i ] = i; + xTaskCreationResult = xTaskCreate( prvEverRunningTask, + "EverRun", + configMINIMAL_STACK_SIZE * 2, + &( xTaskIndexes[ i ] ), + configMAX_PRIORITIES - 1 - i, + &( xTaskHandles[ i ] ) ); + + TEST_ASSERT_EQUAL_MESSAGE( pdPASS, xTaskCreationResult, "Task creation failed." ); + } +} +/*-----------------------------------------------------------*/ + +/** + * @brief Runs after every test, put clean-up calls here. + */ +void tearDown( void ) +{ + uint32_t i; + + /* Delete all the tasks. */ + for( i = 0; i < configNUMBER_OF_CORES; i++ ) + { + if( xTaskHandles[ i ] != NULL ) + { + vTaskDelete( xTaskHandles[ i ] ); + } + } +} +/*-----------------------------------------------------------*/ + +/** + * @brief Entry point for test runner to run highest priority test. + */ +void vRunScheduleHighestPriorityTest( void ) +{ + UNITY_BEGIN(); + + RUN_TEST( Test_ScheduleHighestPriority ); + + UNITY_END(); +} +/*-----------------------------------------------------------*/ diff --git a/FreeRTOS/Test/Target/tests/smp/schedule_highest_priority/test_config.h b/FreeRTOS/Test/Target/tests/smp/schedule_highest_priority/test_config.h new file mode 100644 index 000000000..c258ebeb0 --- /dev/null +++ b/FreeRTOS/Test/Target/tests/smp/schedule_highest_priority/test_config.h @@ -0,0 +1,63 @@ +/* + * FreeRTOS V202212.00 + * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef TEST_CONFIG_H +#define TEST_CONFIG_H + +/* This file must be included at the end of the FreeRTOSConfig.h. It contains + * any FreeRTOS specific configurations that the test requires. */ + +#ifdef configRUN_MULTIPLE_PRIORITIES + #undef configRUN_MULTIPLE_PRIORITIES +#endif /* #ifdef configRUN_MULTIPLE_PRIORITIES */ + +#ifdef configUSE_TIME_SLICING + #undef configUSE_TIME_SLICING +#endif /* #ifdef configUSE_TIME_SLICING */ + +#ifdef configUSE_PREEMPTION + #undef configUSE_PREEMPTION +#endif /* #ifdef configUSE_PREEMPTION */ + +#ifdef configUSE_TASK_NOTIFICATIONS + #undef configUSE_TASK_NOTIFICATIONS +#endif /* #ifdef configUSE_TASK_NOTIFICATIONS */ + +#define configRUN_MULTIPLE_PRIORITIES 1 +#define configUSE_TIME_SLICING 1 +#define configUSE_PREEMPTION 1 +#define configUSE_TASK_NOTIFICATIONS 1 + +/*-----------------------------------------------------------*/ + +/** + * @brief Entry point for test runner to run highest priority test. + */ +void vRunScheduleHighestPriorityTest( void ); + +/*-----------------------------------------------------------*/ + +#endif /* ifndef TEST_CONFIG_H */