Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FreeRTOS/FreeRTOS-Kernel.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchinglee-iot <61685396+chinglee-iot@users.noreply.github.com>2023-12-04 05:49:41 +0300
committerGitHub <noreply@github.com>2023-12-04 05:49:41 +0300
commitc0ce725293bb8cf9b30626a8bba173af33163533 (patch)
tree4a66439567e82b935be49458423eb839a853f706
parentf8ef5f605b28c00b5251e8cf7c45b8ac1a54ef86 (diff)
Add SMP template port and example (#900)
* Add SMP template port and example * Add readme file for smp configuration * Update SMP build flow and add CI build --------- Co-authored-by: Soren Ptak <ptaksoren@gmail.com> Co-authored-by: Rahul Kar <118818625+kar-rahul-aws@users.noreply.github.com>
-rw-r--r--.github/workflows/kernel-demos.yml7
-rw-r--r--examples/cmake_example/CMakeLists.txt17
-rw-r--r--examples/sample_configuration/smp/FreeRTOSConfig.h65
-rw-r--r--examples/sample_configuration/smp/readme.md10
-rw-r--r--portable/template/port.c42
-rw-r--r--portable/template/portmacro.h77
6 files changed, 194 insertions, 24 deletions
diff --git a/.github/workflows/kernel-demos.yml b/.github/workflows/kernel-demos.yml
index 7d83d7482..bae32c966 100644
--- a/.github/workflows/kernel-demos.yml
+++ b/.github/workflows/kernel-demos.yml
@@ -111,6 +111,13 @@ jobs:
cmake -S . -B build
cmake --build build
+ - name: Build CMake SMP Example Demo
+ shell: bash
+ working-directory: examples/cmake_example
+ run: |
+ cmake -S . -B build -DFREERTOS_SMP_EXAMPLE=1
+ cmake --build build
+
MSP430-GCC:
name: GNU MSP430 Toolchain
runs-on: ubuntu-latest
diff --git a/examples/cmake_example/CMakeLists.txt b/examples/cmake_example/CMakeLists.txt
index 85329678d..f8a4e2d63 100644
--- a/examples/cmake_example/CMakeLists.txt
+++ b/examples/cmake_example/CMakeLists.txt
@@ -7,10 +7,19 @@ set(FREERTOS_KERNEL_PATH "../../")
# Add the freertos_config for FreeRTOS-Kernel
add_library(freertos_config INTERFACE)
-target_include_directories(freertos_config
- INTERFACE
- ../sample_configuration
-)
+if (DEFINED FREERTOS_SMP_EXAMPLE AND FREERTOS_SMP_EXAMPLE STREQUAL "1")
+ message(STATUS "Build FreeRTOS SMP example")
+ target_include_directories(freertos_config
+ INTERFACE
+ "../sample_configuration/smp"
+ )
+else()
+ message(STATUS "Build FreeRTOS example")
+ target_include_directories(freertos_config
+ INTERFACE
+ "../sample_configuration"
+ )
+endif()
# Select the heap port. values between 1-4 will pick a heap.
set(FREERTOS_HEAP "4" CACHE STRING "" FORCE)
diff --git a/examples/sample_configuration/smp/FreeRTOSConfig.h b/examples/sample_configuration/smp/FreeRTOSConfig.h
new file mode 100644
index 000000000..f3b68a444
--- /dev/null
+++ b/examples/sample_configuration/smp/FreeRTOSConfig.h
@@ -0,0 +1,65 @@
+/*
+ * FreeRTOS Kernel <DEVELOPMENT BRANCH>
+ * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * 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
+ *
+ */
+
+/*******************************************************************************
+ * This file provides an example FreeRTOSConfig.h header file, inclusive of an
+ * abbreviated explanation of each configuration item. Online and reference
+ * documentation provides more information.
+ * https://www.freertos.org/a00110.html
+ *
+ * Constant values enclosed in square brackets ('[' and ']') must be completed
+ * before this file will build.
+ *
+ * Use the FreeRTOSConfig.h supplied with the RTOS port in use rather than this
+ * generic file, if one is available.
+ ******************************************************************************/
+
+#ifndef __FREERTOS_CONFIG_SMP_H__
+#define __FREERTOS_CONFIG_SMP_H__
+
+#include "../FreeRTOSConfig.h"
+
+/******************************************************************************/
+/* Scheduling behaviour related definitions. **********************************/
+/******************************************************************************/
+
+/* Set configNUMBER_OF_CORES to greater than 1 to enable running one instance of
+ * FreeRTOS kernel to schedule tasks across multiple identical processor cores. */
+#define configNUMBER_OF_CORES 2
+
+/******************************************************************************/
+/* Hook and callback function related definitions. ****************************/
+/******************************************************************************/
+
+/* Set the following configUSE_* constants to 1 to include the named hook
+ * functionality in the build. Set to 0 to exclude the hook functionality from the
+ * build. The application writer is responsible for providing the hook function
+ * for any set to 1. See https://www.freertos.org/a00016.html */
+#define configUSE_PASSIVE_IDLE_HOOK 0
+
+#endif /* __FREERTOS_CONFIG_SMP_H__ */
diff --git a/examples/sample_configuration/smp/readme.md b/examples/sample_configuration/smp/readme.md
new file mode 100644
index 000000000..8dc02bd56
--- /dev/null
+++ b/examples/sample_configuration/smp/readme.md
@@ -0,0 +1,10 @@
+# Configuration support for FreeRTOS SMP
+
+## Overview
+The FreeRTOSConfig.h provided in this folder is a sample configuration that will
+assist you in preparing the configuration to enable SMP support in the FreeRTOS
+Kernel for your application.
+
+Based on single core sample configuration file, this configuration file is created
+with minimal configuration change. More SMP scheduler configurations can be found
+in [Symmetric Multiprocessing (SMP) with FreeRTOS](https://freertos.org/symmetric-multiprocessing-introduction.html)
diff --git a/portable/template/port.c b/portable/template/port.c
index 4011eac15..d4eb56eac 100644
--- a/portable/template/port.c
+++ b/portable/template/port.c
@@ -25,8 +25,18 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
void vPortYield( void )
{
/* Save the current Context */
+
/* Switch to the highest priority task that is ready to run. */
- vTaskSwitchContext();
+ #if ( configNUMBER_OF_CORES == 1 )
+ {
+ vTaskSwitchContext();
+ }
+ #else
+ {
+ vTaskSwitchContext( portGET_CORE_ID() );
+ }
+ #endif
+
/* Start executing the task we have just switched to. */
}
@@ -35,12 +45,34 @@ static void prvTickISR( void )
/* Interrupts must have been enabled for the ISR to fire, so we have to
* save the context with interrupts enabled. */
- /* Maintain the tick count. */
- if( xTaskIncrementTick() != pdFALSE )
+ #if ( configNUMBER_OF_CORES == 1 )
{
- /* Switch to the highest priority task that is ready to run. */
- vTaskSwitchContext();
+ /* Maintain the tick count. */
+ if( xTaskIncrementTick() != pdFALSE )
+ {
+ /* Switch to the highest priority task that is ready to run. */
+ vTaskSwitchContext();
+ }
+ }
+ #else
+ {
+ UBaseType_t ulPreviousMask;
+
+ /* Tasks or ISRs running on other cores may still in critical section in
+ * multiple cores environment. Incrementing tick needs to performed in
+ * critical section. */
+ ulPreviousMask = taskENTER_CRITICAL_FROM_ISR();
+
+ /* Maintain the tick count. */
+ if( xTaskIncrementTick() != pdFALSE )
+ {
+ /* Switch to the highest priority task that is ready to run. */
+ vTaskSwitchContext( portGET_CORE_ID() );
+ }
+
+ taskEXIT_CRITICAL_FROM_ISR( ulPreviousMask );
}
+ #endif /* if ( configNUMBER_OF_CORES == 1 ) */
/* start executing the new task */
}
diff --git a/portable/template/portmacro.h b/portable/template/portmacro.h
index 4e4aa934d..199053208 100644
--- a/portable/template/portmacro.h
+++ b/portable/template/portmacro.h
@@ -64,26 +64,42 @@ typedef unsigned char UBaseType_t;
/*-----------------------------------------------------------*/
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) \
- { \
+ do { \
uxTopPriority = 0; \
- } \
- while( 0 )
+ } while( 0 )
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
-#define portDISABLE_INTERRUPTS() \
- { /* Disable the interrupts */ \
- }
-#define portENABLE_INTERRUPTS() \
- { /* Enable the interrupts */ \
- }
+/* Disable the interrupts */
+#define portDISABLE_INTERRUPTS() do {} while( 0 )
-#define portENTER_CRITICAL() \
- { /* preserve current interrupt state and then disable interrupts */ \
- }
-#define portEXIT_CRITICAL() \
- { /* restore previously preserved interrupt state */ \
- }
+/* Enable the interrupts */
+#define portENABLE_INTERRUPTS() do {} while( 0 )
+
+#if ( configNUMBER_OF_CORES == 1 )
+/* preserve current interrupt state and then disable interrupts */
+ #define portENTER_CRITICAL() do {} while( 0 )
+
+/* restore previously preserved interrupt state */
+ #define portEXIT_CRITICAL() do {} while( 0 )
+#else
+
+/* The port can maintain the critical nesting count in TCB or maintain the critical
+ * nesting count in the port. */
+ #define portCRITICAL_NESTING_IN_TCB 1
+
+/* vTaskEnterCritical and vTaskExitCritical should be used in the implementation
+ * of portENTER/EXIT_CRITICAL if the number of cores is more than 1 in the system. */
+ #define portENTER_CRITICAL vTaskEnterCritical
+ #define portEXIT_CRITICAL vTaskExitCritical
+
+/* vTaskEnterCriticalFromISR and vTaskExitCriticalFromISR should be used in the
+ * implementation of portENTER/EXIT_CRITICAL_FROM_ISR if the number of cores is
+ * more than 1 in the system. */
+ #define portENTER_CRITICAL_FROM_ISR vTaskEnterCriticalFromISR
+ #define portEXIT_CRITICAL_FROM_ISR vTaskExitCriticalFromISR
+
+#endif /* if ( configNUMBER_OF_CORES == 1 ) */
extern void vPortYield( void );
#define portYIELD() vPortYield()
@@ -92,4 +108,35 @@ extern void vPortYield( void );
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
+#if ( configNUMBER_OF_CORES > 1 )
+ /* Return the core ID on which the code is running. */
+ #define portGET_CORE_ID() 0
+
+/* Set the interrupt mask. */
+ #define portSET_INTERRUPT_MASK() 0
+
+/* Clear the interrupt mask. */
+ #define portCLEAR_INTERRUPT_MASK( x ) ( ( void ) ( x ) )
+
+/* Request the core ID x to yield. */
+ #define portYIELD_CORE( x ) do {} while( 0 )
+
+/* Acquire the TASK lock. TASK lock is a recursive lock.
+ * It should be able to be locked by the same core multiple times. */
+ #define portGET_TASK_LOCK() do {} while( 0 )
+
+/* Release the TASK lock. If a TASK lock is locked by the same core multiple times,
+ * it should be released as many times as it is locked. */
+ #define portRELEASE_TASK_LOCK() do {} while( 0 )
+
+/* Acquire the ISR lock. ISR lock is a recursive lock.
+ * It should be able to be locked by the same core multiple times. */
+ #define portGET_ISR_LOCK() do {} while( 0 )
+
+/* Release the ISR lock. If a ISR lock is locked by the same core multiple times, \
+ * it should be released as many times as it is locked. */
+ #define portRELEASE_ISR_LOCK() do {} while( 0 )
+
+#endif /* if ( configNUMBER_OF_CORES > 1 ) */
+
#endif /* PORTMACRO_H */