mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-19 21:11:57 -04:00
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>
This commit is contained in:
parent
f8ef5f605b
commit
c0ce725293
7
.github/workflows/kernel-demos.yml
vendored
7
.github/workflows/kernel-demos.yml
vendored
|
@ -111,6 +111,13 @@ jobs:
|
||||||
cmake -S . -B build
|
cmake -S . -B build
|
||||||
cmake --build 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:
|
MSP430-GCC:
|
||||||
name: GNU MSP430 Toolchain
|
name: GNU MSP430 Toolchain
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
|
@ -7,10 +7,19 @@ set(FREERTOS_KERNEL_PATH "../../")
|
||||||
# Add the freertos_config for FreeRTOS-Kernel
|
# Add the freertos_config for FreeRTOS-Kernel
|
||||||
add_library(freertos_config INTERFACE)
|
add_library(freertos_config INTERFACE)
|
||||||
|
|
||||||
target_include_directories(freertos_config
|
if (DEFINED FREERTOS_SMP_EXAMPLE AND FREERTOS_SMP_EXAMPLE STREQUAL "1")
|
||||||
|
message(STATUS "Build FreeRTOS SMP example")
|
||||||
|
target_include_directories(freertos_config
|
||||||
INTERFACE
|
INTERFACE
|
||||||
../sample_configuration
|
"../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.
|
# Select the heap port. values between 1-4 will pick a heap.
|
||||||
set(FREERTOS_HEAP "4" CACHE STRING "" FORCE)
|
set(FREERTOS_HEAP "4" CACHE STRING "" FORCE)
|
||||||
|
|
65
examples/sample_configuration/smp/FreeRTOSConfig.h
Normal file
65
examples/sample_configuration/smp/FreeRTOSConfig.h
Normal file
|
@ -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__ */
|
10
examples/sample_configuration/smp/readme.md
Normal file
10
examples/sample_configuration/smp/readme.md
Normal file
|
@ -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)
|
|
@ -25,8 +25,18 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
||||||
void vPortYield( void )
|
void vPortYield( void )
|
||||||
{
|
{
|
||||||
/* Save the current Context */
|
/* Save the current Context */
|
||||||
|
|
||||||
/* Switch to the highest priority task that is ready to run. */
|
/* Switch to the highest priority task that is ready to run. */
|
||||||
|
#if ( configNUMBER_OF_CORES == 1 )
|
||||||
|
{
|
||||||
vTaskSwitchContext();
|
vTaskSwitchContext();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
vTaskSwitchContext( portGET_CORE_ID() );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Start executing the task we have just switched to. */
|
/* 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
|
/* Interrupts must have been enabled for the ISR to fire, so we have to
|
||||||
* save the context with interrupts enabled. */
|
* save the context with interrupts enabled. */
|
||||||
|
|
||||||
|
#if ( configNUMBER_OF_CORES == 1 )
|
||||||
|
{
|
||||||
/* Maintain the tick count. */
|
/* Maintain the tick count. */
|
||||||
if( xTaskIncrementTick() != pdFALSE )
|
if( xTaskIncrementTick() != pdFALSE )
|
||||||
{
|
{
|
||||||
/* Switch to the highest priority task that is ready to run. */
|
/* Switch to the highest priority task that is ready to run. */
|
||||||
vTaskSwitchContext();
|
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 */
|
/* start executing the new task */
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,26 +64,42 @@ typedef unsigned char UBaseType_t;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) \
|
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) \
|
||||||
{ \
|
do { \
|
||||||
uxTopPriority = 0; \
|
uxTopPriority = 0; \
|
||||||
} \
|
} while( 0 )
|
||||||
while( 0 )
|
|
||||||
|
|
||||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() \
|
/* Disable the interrupts */
|
||||||
{ /* Disable the interrupts */ \
|
#define portDISABLE_INTERRUPTS() do {} while( 0 )
|
||||||
}
|
|
||||||
#define portENABLE_INTERRUPTS() \
|
|
||||||
{ /* Enable the interrupts */ \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define portENTER_CRITICAL() \
|
/* Enable the interrupts */
|
||||||
{ /* preserve current interrupt state and then disable interrupts */ \
|
#define portENABLE_INTERRUPTS() do {} while( 0 )
|
||||||
}
|
|
||||||
#define portEXIT_CRITICAL() \
|
#if ( configNUMBER_OF_CORES == 1 )
|
||||||
{ /* restore previously preserved interrupt state */ \
|
/* 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 );
|
extern void vPortYield( void );
|
||||||
#define portYIELD() vPortYield()
|
#define portYIELD() vPortYield()
|
||||||
|
@ -92,4 +108,35 @@ extern void vPortYield( void );
|
||||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
#define portTASK_FUNCTION( 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 */
|
#endif /* PORTMACRO_H */
|
||||||
|
|
Loading…
Reference in a new issue