mirror of
				https://github.com/FreeRTOS/FreeRTOS-Kernel.git
				synced 2025-11-04 02:59:01 +01: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 --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
 | 
			
		||||
 | 
			
		||||
@ -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)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										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 )
 | 
			
		||||
{
 | 
			
		||||
    /* 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 */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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 */
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user