Merge branch 'main' into update_mpu_wrappers

This commit is contained in:
Rahul Kar 2024-02-27 12:57:29 +05:30 committed by GitHub
commit b8e26bc885
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
661 changed files with 3976 additions and 735 deletions

View file

@ -549,6 +549,10 @@ NTRST
NVIC NVIC
ODAT ODAT
ODSR ODSR
OINC
OIWBNOWA
OIWBWA
OIWTNOWA
OPMOD OPMOD
optimisations optimisations
OPTIMISED OPTIMISED
@ -795,6 +799,15 @@ SWRST
SWTRG SWTRG
synchronise synchronise
SYSC SYSC
sysclk
Sysclk
SysClk
SYSClk
SYSCLK
sysclock
Sysclock
SysClock
SYSCLOCK
TACCR TACCR
TACCTL TACCTL
TACLR TACLR
@ -877,6 +890,9 @@ UNDADD
unpadded unpadded
Unpadded Unpadded
UNPADDED UNPADDED
unprotect
Unprotect
Unprotected
UNRE UNRE
UNSUB UNSUB
UNSUBACK UNSUBACK

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
#/* #/*
# * FreeRTOS Kernel <DEVELOPMENT BRANCH> # * FreeRTOS Kernel <DEVELOPMENT BRANCH>
# * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. # * Copyright (C) 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
# * # *
# * SPDX-License-Identifier: MIT # * SPDX-License-Identifier: MIT
# * # *
@ -37,7 +37,8 @@ KERNEL_IGNORED_FILES = [
'FreeRTOS-openocd.c', 'FreeRTOS-openocd.c',
'Makefile', 'Makefile',
'.DS_Store', '.DS_Store',
'cspell.config.yaml' 'cspell.config.yaml',
'.clang-format'
] ]
KERNEL_IGNORED_EXTENSIONS = [ KERNEL_IGNORED_EXTENSIONS = [
@ -135,12 +136,16 @@ KERNEL_HEADER = [
' */\n', ' */\n',
] ]
FREERTOS_COPYRIGHT_REGEX = r"^(;|#)?( *(\/\*|\*|#|\/\/))? Copyright \(C\) 20\d\d Amazon.com, Inc. or its affiliates. All Rights Reserved\.( \*\/)?$"
def main(): def main():
parser = HeaderChecker.configArgParser() parser = HeaderChecker.configArgParser()
args = parser.parse_args() args = parser.parse_args()
# Configure the checks then run # Configure the checks then run
checker = HeaderChecker(KERNEL_HEADER, checker = HeaderChecker(KERNEL_HEADER,
copyright_regex=FREERTOS_COPYRIGHT_REGEX,
ignored_files=KERNEL_IGNORED_FILES, ignored_files=KERNEL_IGNORED_FILES,
ignored_ext=KERNEL_IGNORED_EXTENSIONS, ignored_ext=KERNEL_IGNORED_EXTENSIONS,
ignored_patterns=KERNEL_IGNORED_PATTERNS, ignored_patterns=KERNEL_IGNORED_PATTERNS,

View file

@ -85,6 +85,7 @@ if(NOT FREERTOS_PORT)
" GCC_ARM_CM85_NTZ_NONSECURE - Compiler: GCC Target: ARM Cortex-M85 non-trustzone non-secure\n" " GCC_ARM_CM85_NTZ_NONSECURE - Compiler: GCC Target: ARM Cortex-M85 non-trustzone non-secure\n"
" GCC_ARM_CM85_TFM - Compiler: GCC Target: ARM Cortex-M85 non-secure for TF-M\n" " GCC_ARM_CM85_TFM - Compiler: GCC Target: ARM Cortex-M85 non-secure for TF-M\n"
" GCC_ARM_CR5 - Compiler: GCC Target: ARM Cortex-R5\n" " GCC_ARM_CR5 - Compiler: GCC Target: ARM Cortex-R5\n"
" GCC_ARM_CRX_MPU - Compiler: GCC Target: ARM Cortex-Rx with MPU\n"
" GCC_ARM_CRX_NOGIC - Compiler: GCC Target: ARM Cortex-Rx no GIC\n" " GCC_ARM_CRX_NOGIC - Compiler: GCC Target: ARM Cortex-Rx no GIC\n"
" GCC_ARM7_AT91FR40008 - Compiler: GCC Target: ARM7 Atmel AT91R40008\n" " GCC_ARM7_AT91FR40008 - Compiler: GCC Target: ARM7 Atmel AT91R40008\n"
" GCC_ARM7_AT91SAM7S - Compiler: GCC Target: ARM7 Atmel AT91SAM7S\n" " GCC_ARM7_AT91SAM7S - Compiler: GCC Target: ARM7 Atmel AT91SAM7S\n"

View file

@ -2,11 +2,11 @@
FreeRTOS-Kernel conforms to [MISRA C:2012](https://www.misra.org.uk/misra-c) FreeRTOS-Kernel conforms to [MISRA C:2012](https://www.misra.org.uk/misra-c)
guidelines, with the deviations listed below. Compliance is checked with guidelines, with the deviations listed below. Compliance is checked with
Coverity static analysis. Since the FreeRTOS kernel is designed for Coverity static analysis version 2023.6.1. Since the FreeRTOS kernel is
small-embedded devices, it needs to have a very small memory footprint and designed for small-embedded devices, it needs to have a very small memory
has to be efficient. To achieve that and to increase the performance, it footprint and has to be efficient. To achieve that and to increase the
deviates from some MISRA rules. The specific deviations, suppressed inline, performance, it deviates from some MISRA rules. The specific deviations,
are listed below. suppressed inline, are listed below.
Additionally, [MISRA configuration file](examples/coverity/coverity_misra.config) Additionally, [MISRA configuration file](examples/coverity/coverity_misra.config)
contains project wide deviations. contains project wide deviations.

View file

@ -52,8 +52,10 @@
/* Other file private variables. --------------------------------*/ /* Other file private variables. --------------------------------*/
CRCB_t * pxCurrentCoRoutine = NULL; CRCB_t * pxCurrentCoRoutine = NULL;
static UBaseType_t uxTopCoRoutineReadyPriority = 0; static UBaseType_t uxTopCoRoutineReadyPriority = ( UBaseType_t ) 0U;
static TickType_t xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0; static TickType_t xCoRoutineTickCount = ( TickType_t ) 0U;
static TickType_t xLastTickCount = ( TickType_t ) 0U;
static TickType_t xPassedTicks = ( TickType_t ) 0U;
/* The initial state of the co-routine when it is created. */ /* The initial state of the co-routine when it is created. */
#define corINITIAL_STATE ( 0 ) #define corINITIAL_STATE ( 0 )
@ -378,5 +380,26 @@
return xReturn; return xReturn;
} }
/*-----------------------------------------------------------*/
/*
* Reset state in this file. This state is normally initialized at start up.
* This function must be called by the application before restarting the
* scheduler.
*/
void vCoRoutineResetState( void )
{
/* Lists for ready and blocked co-routines. */
pxDelayedCoRoutineList = NULL;
pxOverflowDelayedCoRoutineList = NULL;
/* Other file private variables. */
pxCurrentCoRoutine = NULL;
uxTopCoRoutineReadyPriority = ( UBaseType_t ) 0U;
xCoRoutineTickCount = ( TickType_t ) 0U;
xLastTickCount = ( TickType_t ) 0U;
xPassedTicks = ( TickType_t ) 0U;
}
/*-----------------------------------------------------------*/
#endif /* configUSE_CO_ROUTINES == 0 */ #endif /* configUSE_CO_ROUTINES == 0 */

View file

@ -2,8 +2,9 @@ cmake_minimum_required(VERSION 3.15)
project(coverity) project(coverity)
set(FREERTOS_KERNEL_PATH "../../") set(FREERTOS_KERNEL_PATH "../..")
FILE(GLOB FREERTOS_KERNEL_SOURCE ${FREERTOS_KERNEL_PATH}*.c) FILE(GLOB FREERTOS_KERNEL_SOURCE ${FREERTOS_KERNEL_PATH}/*.c)
FILE(GLOB FREERTOS_PORT_CODE ${FREERTOS_KERNEL_PATH}/portable/template/*.c)
# Coverity incorrectly infers the type of pdTRUE and pdFALSE as boolean because # Coverity incorrectly infers the type of pdTRUE and pdFALSE as boolean because
# of their names. This generates multiple false positive warnings about type # of their names. This generates multiple false positive warnings about type
@ -12,8 +13,8 @@ FILE(GLOB FREERTOS_KERNEL_SOURCE ${FREERTOS_KERNEL_PATH}*.c)
# fixes the issue of incorrectly inferring the type of pdTRUE and pdFALSE as # fixes the issue of incorrectly inferring the type of pdTRUE and pdFALSE as
# boolean. # boolean.
add_custom_target(fix_source ALL add_custom_target(fix_source ALL
COMMAND sed -i -b -e 's/pdFALSE/pdFAIL/g' -e 's/pdTRUE/pdPASS/g' ${FREERTOS_KERNEL_SOURCE} COMMAND sed -i -b -e 's/pdFALSE/pdFAIL/g' -e 's/pdTRUE/pdPASS/g' ${FREERTOS_KERNEL_SOURCE} ${FREERTOS_PORT_CODE}
DEPENDS ${FREERTOS_KERNEL_SOURCE}) DEPENDS ${FREERTOS_KERNEL_SOURCE} ${FREERTOS_PORT_CODE})
# Add the freertos_config for FreeRTOS-Kernel. # Add the freertos_config for FreeRTOS-Kernel.
add_library(freertos_config INTERFACE) add_library(freertos_config INTERFACE)

View file

@ -1,97 +1,91 @@
// MISRA C-2012 Rules
{ {
version : "2.0", "version" : "2.0",
standard : "c2012", "standard" : "c2012",
title: "Coverity MISRA Configuration", "title": "Coverity MISRA Configuration",
deviations : [ "deviations" : [
// Disable the following rules.
{ {
deviation: "Rule 3.1", "deviation": "Rule 3.1",
reason: "We post HTTP links in code comments which contain // inside comments blocks." "reason": "We post HTTP links in code comments which contain // inside comments blocks."
}, },
{ {
deviation: "Rule 14.4", "deviation": "Rule 14.4",
reason: "do while( 0 ) pattern is used in macros to prevent extra semi-colon." "reason": "do while( 0 ) pattern is used in macros to prevent extra semi-colon."
},
// Disable the following advisory rules and directives.
{
deviation: "Directive 4.4",
reason: "Code snippet is used in comment to help explanation."
}, },
{ {
deviation: "Directive 4.5", "deviation": "Directive 4.4",
reason: "Allow names that MISRA considers ambiguous." "reason": "Code snippet is used in comment to help explanation."
}, },
{ {
deviation: "Directive 4.6", "deviation": "Directive 4.5",
reason: "Allow port to use primitive type with typedefs." "reason": "Allow names that MISRA considers ambiguous."
}, },
{ {
deviation: "Directive 4.8", "deviation": "Directive 4.6",
reason: "HeapRegion_t and HeapStats_t are used only in heap files but declared in portable.h which is included in multiple source files. As a result, these definitions appear in multiple source files where they are not used." "reason": "Allow port to use primitive type with typedefs."
}, },
{ {
deviation: "Directive 4.9", "deviation": "Directive 4.8",
reason: "FreeRTOS-Kernel is optimised to work on small micro-controllers. To achieve that, function-like macros are used." "reason": "HeapRegion_t and HeapStats_t are used only in heap files but declared in portable.h which is included in multiple source files. As a result, these definitions appear in multiple source files where they are not used."
}, },
{ {
deviation: "Rule 2.3", "deviation": "Directive 4.9",
reason: "FreeRTOS defines types which is used in application." "reason": "FreeRTOS-Kernel is optimised to work on small micro-controllers. To achieve that, function-like macros are used."
}, },
{ {
deviation: "Rule 2.4", "deviation": "Rule 2.3",
reason: "Allow to define unused tag." "reason": "FreeRTOS defines types which is used in application."
}, },
{ {
deviation: "Rule 2.5", "deviation": "Rule 2.4",
reason: "Allow to define unused macro." "reason": "Allow to define unused tag."
}, },
{ {
deviation: "Rule 5.9", "deviation": "Rule 2.5",
reason: "Allow to define identifier with the same name in structure and global variable." "reason": "Allow to define unused macro."
}, },
{ {
deviation: "Rule 8.7", "deviation": "Rule 5.9",
reason: "API functions are not used by the library outside of the files they are defined; however, they must be externally visible in order to be used by an application." "reason": "Allow to define identifier with the same name in structure and global variable."
}, },
{ {
deviation: "Rule 8.9", "deviation": "Rule 8.7",
reason: "Allow to object to be defined in wider scope for debug purpose." "reason": "API functions are not used by the library outside of the files they are defined; however, they must be externally visible in order to be used by an application."
}, },
{ {
deviation: "Rule 8.13", "deviation": "Rule 8.9",
reason: "Allow to not to use const-qualified type for callback function." "reason": "Allow to object to be defined in wider scope for debug purpose."
}, },
{ {
deviation: "Rule 11.4", "deviation": "Rule 8.13",
reason: "Allow to convert between a pointer to object and an interger type for stack alignment." "reason": "Allow to not to use const-qualified type for callback function."
}, },
{ {
deviation: "Rule 15.4", "deviation": "Rule 11.4",
reason: "Allow to use multiple break statements in a loop." "reason": "Allow to convert between a pointer to object and an interger type for stack alignment."
}, },
{ {
deviation: "Rule 15.5", "deviation": "Rule 15.4",
reason: "Allow to use multiple points of exit." "reason": "Allow to use multiple break statements in a loop."
}, },
{ {
deviation: "Rule 17.8", "deviation": "Rule 15.5",
reason: "Allow to update the parameters of a function." "reason": "Allow to use multiple points of exit."
}, },
{ {
deviation: "Rule 18.4", "deviation": "Rule 17.8",
reason: "Allow to use pointer arithmetic." "reason": "Allow to update the parameters of a function."
}, },
{ {
deviation: "Rule 19.2", "deviation": "Rule 18.4",
reason: "Allow to use union." "reason": "Allow to use pointer arithmetic."
}, },
{ {
deviation: "Rule 20.5", "deviation": "Rule 19.2",
reason: "Allow to use #undef for MPU wrappers." "reason": "Allow to use union."
},
{
"deviation": "Rule 20.5",
"reason": "Allow to use #undef for MPU wrappers."
} }
] ]
} }

View file

@ -496,6 +496,15 @@
* run any task on any available core. */ * run any task on any available core. */
#define configUSE_CORE_AFFINITY 0 #define configUSE_CORE_AFFINITY 0
/* When using SMP with core affinity feature enabled, set
* configTASK_DEFAULT_CORE_AFFINITY to change the default core affinity mask for
* tasks created without an affinity mask specified. Setting the define to 1 would
* make such tasks run on core 0 and setting it to (1 << portGET_CORE_ID()) would
* make such tasks run on the current core. This config value is useful, if
* swapping tasks between cores is not supported (e.g. Tricore) or if legacy code
* should be controlled. Defaults to tskNO_AFFINITY if left undefined. */
#define configTASK_DEFAULT_CORE_AFFINITY tskNO_AFFINITY
/* When using SMP (i.e. configNUMBER_OF_CORES is greater than one), if /* When using SMP (i.e. configNUMBER_OF_CORES is greater than one), if
* configUSE_TASK_PREEMPTION_DISABLE is set to 1, individual tasks can be set to * configUSE_TASK_PREEMPTION_DISABLE is set to 1, individual tasks can be set to
* either pre-emptive or co-operative mode using the vTaskPreemptionDisable and * either pre-emptive or co-operative mode using the vTaskPreemptionDisable and

View file

@ -96,6 +96,10 @@
#define configNUMBER_OF_CORES 1 #define configNUMBER_OF_CORES 1
#endif #endif
#ifndef configUSE_MALLOC_FAILED_HOOK
#define configUSE_MALLOC_FAILED_HOOK 0
#endif
/* Basic FreeRTOS definitions. */ /* Basic FreeRTOS definitions. */
#include "projdefs.h" #include "projdefs.h"
@ -492,6 +496,12 @@
#define configUSE_CORE_AFFINITY 0 #define configUSE_CORE_AFFINITY 0
#endif /* configUSE_CORE_AFFINITY */ #endif /* configUSE_CORE_AFFINITY */
#if ( ( configNUMBER_OF_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) )
#ifndef configTASK_DEFAULT_CORE_AFFINITY
#define configTASK_DEFAULT_CORE_AFFINITY tskNO_AFFINITY
#endif
#endif
#ifndef configUSE_PASSIVE_IDLE_HOOK #ifndef configUSE_PASSIVE_IDLE_HOOK
#define configUSE_PASSIVE_IDLE_HOOK 0 #define configUSE_PASSIVE_IDLE_HOOK 0
#endif /* configUSE_PASSIVE_IDLE_HOOK */ #endif /* configUSE_PASSIVE_IDLE_HOOK */
@ -2651,10 +2661,6 @@
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()
#endif #endif
#ifndef configUSE_MALLOC_FAILED_HOOK
#define configUSE_MALLOC_FAILED_HOOK 0
#endif
#ifndef portPRIVILEGE_BIT #ifndef portPRIVILEGE_BIT
#define portPRIVILEGE_BIT ( ( UBaseType_t ) 0x00 ) #define portPRIVILEGE_BIT ( ( UBaseType_t ) 0x00 )
#endif #endif

View file

@ -746,6 +746,13 @@ void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay,
*/ */
BaseType_t xCoRoutineRemoveFromEventList( const List_t * pxEventList ); BaseType_t xCoRoutineRemoveFromEventList( const List_t * pxEventList );
/*
* This function resets the internal state of the coroutine module. It must be
* called by the application before restarting the scheduler.
*/
void vCoRoutineResetState( void ) PRIVILEGED_FUNCTION;
/* *INDENT-OFF* */ /* *INDENT-OFF* */
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -178,7 +178,7 @@ void vPortGetHeapStats( HeapStats_t * pxHeapStats );
/* /*
* Map to the memory management routines required for the port. * Map to the memory management routines required for the port.
*/ */
void * pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION; void * pvPortMalloc( size_t xWantedSize ) PRIVILEGED_FUNCTION;
void * pvPortCalloc( size_t xNum, void * pvPortCalloc( size_t xNum,
size_t xSize ) PRIVILEGED_FUNCTION; size_t xSize ) PRIVILEGED_FUNCTION;
void vPortFree( void * pv ) PRIVILEGED_FUNCTION; void vPortFree( void * pv ) PRIVILEGED_FUNCTION;
@ -194,6 +194,12 @@ size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION;
#define vPortFreeStack vPortFree #define vPortFreeStack vPortFree
#endif #endif
/*
* This function resets the internal state of the heap module. It must be called
* by the application before restarting the scheduler.
*/
void vPortHeapResetState( void ) PRIVILEGED_FUNCTION;
#if ( configUSE_MALLOC_FAILED_HOOK == 1 ) #if ( configUSE_MALLOC_FAILED_HOOK == 1 )
/** /**

View file

@ -3438,6 +3438,20 @@ BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut,
*/ */
BaseType_t xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) PRIVILEGED_FUNCTION; BaseType_t xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) PRIVILEGED_FUNCTION;
/**
* task.h
* @code{c}
* void vTaskResetState( void );
* @endcode
*
* This function resets the internal state of the task. It must be called by the
* application before restarting the scheduler.
*
* \defgroup vTaskResetState vTaskResetState
* \ingroup SchedulerControl
*/
void vTaskResetState( void ) PRIVILEGED_FUNCTION;
/*----------------------------------------------------------- /*-----------------------------------------------------------
* SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES

View file

@ -1417,6 +1417,12 @@ BaseType_t xTimerGenericCommandFromISR( TimerHandle_t xTimer,
#endif #endif
/*
* This function resets the internal state of the timer module. It must be called
* by the application before restarting the scheduler.
*/
void vTimerResetState( void ) PRIVILEGED_FUNCTION;
/* *INDENT-OFF* */ /* *INDENT-OFF* */
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -207,6 +207,11 @@ add_library(freertos_kernel_port OBJECT
GCC/ARM_CR5/port.c GCC/ARM_CR5/port.c
GCC/ARM_CR5/portASM.S> GCC/ARM_CR5/portASM.S>
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CRX_MPU>:
GCC/ARM_CRx_MPU/port.c
GCC/ARM_CRx_MPU/portASM.S
GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S>
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CRX_NOGIC>: $<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CRX_NOGIC>:
GCC/ARM_CRx_No_GIC/port.c GCC/ARM_CRx_No_GIC/port.c
GCC/ARM_CRx_No_GIC/portASM.S> GCC/ARM_CRx_No_GIC/portASM.S>
@ -836,6 +841,7 @@ target_include_directories(freertos_kernel_port_headers INTERFACE
# ARMv7-R ports for GCC # ARMv7-R ports for GCC
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CR5>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CR5> $<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CR5>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CR5>
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CRX_MPU>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CRx_MPU>
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CRX_NOGIC>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CRx_No_GIC> $<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CRX_NOGIC>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CRx_No_GIC>
# ARMv4T ARM7TDMI ports for GCC # ARMv4T ARM7TDMI ports for GCC

View file

@ -0,0 +1,854 @@
/*
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2024 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
*
*/
/* ----------------------------------------------------------------------------------- */
.arm
.syntax unified
.section freertos_system_calls
#define FREERTOS_ASSEMBLY
#include "FreeRTOSConfig.h"
#include "portmacro_asm.h"
#include "mpu_syscall_numbers.h"
#undef FREERTOS_ASSEMBLY
/* ----------------------- Start of Port Specific System Calls ----------------------- */
/*
* void vPortYield( void );
*/
.align 4
.global vPortYield
.type vPortYield, %function
vPortYield:
SVC #portSVC_YIELD
BX LR
/* ----------------------------------------------------------------------------------- */
/*
* void vPortSystemCallExit( void );
*/
.align 4
.global vPortSystemCallExit
.type vPortSystemCallExit, %function
vPortSystemCallExit:
SVC #portSVC_SYSTEM_CALL_EXIT
BX LR
/* ----------------------------------------------------------------------------------- */
/*
* BaseType_t xPortIsPrivileged( void );
*
* According to the Procedure Call Standard for the ARM Architecture (AAPCS):
* - Return value must be in R0.
*/
.align 4
.global xPortIsPrivileged
.type xPortIsPrivileged, %function
xPortIsPrivileged:
MRS R0, CPSR /* R0 = CPSR. */
AND R0, R0, #0x1F /* R0 = R0 & 0x1F. Extract mode bits.*/
CMP R0, #USER_MODE /* If R0 == #USER_MODE. */
MOVEQ R0, #0x0 /* Then, set R0 to 0 to indicate that the processer is not privileged. */
MOVNE R0, #0x01 /* Otherwise, set R0 to 1 to indicate that the processer is privileged. */
BX LR
/* ----------------------------------------------------------------------------------- */
/*
* UBaseType_t ulPortCountLeadingZeros( UBaseType_t ulBitmap );
*
* According to the Procedure Call Standard for the ARM Architecture (AAPCS):
* - Parameter ulBitmap is passed in R0.
* - Return value must be in R0.
*/
.align 4
.weak ulPortCountLeadingZeros
.type ulPortCountLeadingZeros, %function
ulPortCountLeadingZeros:
CLZ R0, R0
BX LR
/* ------------------- End of Port Specific System Calls ------------------- */
.macro INVOKE_SYSTEM_CALL systemCallNumber, systemCallImpl
PUSH {R0}
MRS R0, CPSR
AND R0, R0, #0x1F
CMP R0, #USER_MODE
POP {R0}
SVCEQ \systemCallNumber
B \systemCallImpl
.endm
/* ----------------------------------------------------------------------------------- */
.extern MPU_xTaskGetTickCountImpl
.align 4
.global MPU_xTaskGetTickCount
.type MPU_xTaskGetTickCount, function
MPU_xTaskGetTickCount:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskGetTickCount, MPU_xTaskGetTickCountImpl
/* ----------------------------------------------------------------------------------- */
.extern MPU_uxTaskGetNumberOfTasksImpl
.align 4
.global MPU_uxTaskGetNumberOfTasks
.type MPU_uxTaskGetNumberOfTasks, function
MPU_uxTaskGetNumberOfTasks:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_uxTaskGetNumberOfTasks, MPU_uxTaskGetNumberOfTasksImpl
/* ----------------------------------------------------------------------------------- */
.extern MPU_vTaskSetTimeOutStateImpl
.align 4
.global MPU_vTaskSetTimeOutState
.type MPU_vTaskSetTimeOutState, function
MPU_vTaskSetTimeOutState:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_vTaskSetTimeOutState, MPU_vTaskSetTimeOutStateImpl
/* ----------------------------------------------------------------------------------- */
.extern MPU_xTaskCheckForTimeOutImpl
.align 4
.global MPU_xTaskCheckForTimeOut
.type MPU_xTaskCheckForTimeOut, function
MPU_xTaskCheckForTimeOut:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskCheckForTimeOut, MPU_xTaskCheckForTimeOutImpl
/* ----------------------------------------------------------------------------------- */
.extern MPU_xQueueGenericSendImpl
.align 4
.global MPU_xQueueGenericSend
.type MPU_xQueueGenericSend, function
MPU_xQueueGenericSend:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_xQueueGenericSend, MPU_xQueueGenericSendImpl
/* ----------------------------------------------------------------------------------- */
.extern MPU_uxQueueMessagesWaitingImpl
.align 4
.global MPU_uxQueueMessagesWaiting
.type MPU_uxQueueMessagesWaiting, function
MPU_uxQueueMessagesWaiting:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_uxQueueMessagesWaiting, MPU_uxQueueMessagesWaitingImpl
/* ----------------------------------------------------------------------------------- */
.extern MPU_uxQueueSpacesAvailableImpl
.align 4
.global MPU_uxQueueSpacesAvailable
.type MPU_uxQueueSpacesAvailable, function
MPU_uxQueueSpacesAvailable:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_uxQueueSpacesAvailable, MPU_uxQueueSpacesAvailableImpl
/* ----------------------------------------------------------------------------------- */
.extern MPU_xQueueReceiveImpl
.align 4
.global MPU_xQueueReceive
.type MPU_xQueueReceive, function
MPU_xQueueReceive:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_xQueueReceive, MPU_xQueueReceiveImpl
/* ----------------------------------------------------------------------------------- */
.extern MPU_xQueuePeekImpl
.align 4
.global MPU_xQueuePeek
.type MPU_xQueuePeek, function
MPU_xQueuePeek:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_xQueuePeek, MPU_xQueuePeekImpl
/* ----------------------------------------------------------------------------------- */
.extern MPU_xQueueSemaphoreTakeImpl
.align 4
.global MPU_xQueueSemaphoreTake
.type MPU_xQueueSemaphoreTake, function
MPU_xQueueSemaphoreTake:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_xQueueSemaphoreTake, MPU_xQueueSemaphoreTakeImpl
/* ----------------------------------------------------------------------------------- */
.extern MPU_xEventGroupWaitBitsImpl
.align 4
.global MPU_xEventGroupWaitBitsEntry
.type MPU_xEventGroupWaitBitsEntry, function
MPU_xEventGroupWaitBitsEntry:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_xEventGroupWaitBits, MPU_xEventGroupWaitBitsImpl
/* ----------------------------------------------------------------------------------- */
.extern MPU_xEventGroupClearBitsImpl
.align 4
.global MPU_xEventGroupClearBits
.type MPU_xEventGroupClearBits, function
MPU_xEventGroupClearBits:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_xEventGroupClearBits, MPU_xEventGroupClearBitsImpl
/* ----------------------------------------------------------------------------------- */
.extern MPU_xEventGroupSetBitsImpl
.align 4
.global MPU_xEventGroupSetBits
.type MPU_xEventGroupSetBits, function
MPU_xEventGroupSetBits:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_xEventGroupSetBits, MPU_xEventGroupSetBitsImpl
/* ----------------------------------------------------------------------------------- */
.extern MPU_xEventGroupSyncImpl
.align 4
.global MPU_xEventGroupSync
.type MPU_xEventGroupSync, function
MPU_xEventGroupSync:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_xEventGroupSync, MPU_xEventGroupSyncImpl
/* ----------------------------------------------------------------------------------- */
.extern MPU_xStreamBufferSendImpl
.align 4
.global MPU_xStreamBufferSend
.type MPU_xStreamBufferSend, function
MPU_xStreamBufferSend:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_xStreamBufferSend, MPU_xStreamBufferSendImpl
/* ----------------------------------------------------------------------------------- */
.extern MPU_xStreamBufferReceiveImpl
.align 4
.global MPU_xStreamBufferReceive
.type MPU_xStreamBufferReceive, function
MPU_xStreamBufferReceive:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_xStreamBufferReceive, MPU_xStreamBufferReceiveImpl
/* ----------------------------------------------------------------------------------- */
.extern MPU_xStreamBufferIsFullImpl
.align 4
.global MPU_xStreamBufferIsFull
.type MPU_xStreamBufferIsFull, function
MPU_xStreamBufferIsFull:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_xStreamBufferIsFull, MPU_xStreamBufferIsFullImpl
/* ----------------------------------------------------------------------------------- */
.extern MPU_xStreamBufferIsEmptyImpl
.align 4
.global MPU_xStreamBufferIsEmpty
.type MPU_xStreamBufferIsEmpty, function
MPU_xStreamBufferIsEmpty:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_xStreamBufferIsEmpty, MPU_xStreamBufferIsEmptyImpl
/* ----------------------------------------------------------------------------------- */
.extern MPU_xStreamBufferSpacesAvailableImpl
.align 4
.global MPU_xStreamBufferSpacesAvailable
.type MPU_xStreamBufferSpacesAvailable, function
MPU_xStreamBufferSpacesAvailable:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_xStreamBufferSpacesAvailable, MPU_xStreamBufferSpacesAvailableImpl
/* ----------------------------------------------------------------------------------- */
.extern MPU_xStreamBufferBytesAvailableImpl
.align 4
.global MPU_xStreamBufferBytesAvailable
.type MPU_xStreamBufferBytesAvailable, function
MPU_xStreamBufferBytesAvailable:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_xStreamBufferBytesAvailable, MPU_xStreamBufferBytesAvailableImpl
/* ----------------------------------------------------------------------------------- */
.extern MPU_xStreamBufferSetTriggerLevelImpl
.align 4
.global MPU_xStreamBufferSetTriggerLevel
.type MPU_xStreamBufferSetTriggerLevel, function
MPU_xStreamBufferSetTriggerLevel:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_xStreamBufferSetTriggerLevel, MPU_xStreamBufferSetTriggerLevelImpl
/* ----------------------------------------------------------------------------------- */
.extern MPU_xStreamBufferNextMessageLengthBytesImpl
.align 4
.global MPU_xStreamBufferNextMessageLengthBytes
.type MPU_xStreamBufferNextMessageLengthBytes, function
MPU_xStreamBufferNextMessageLengthBytes:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_xStreamBufferNextMessageLengthBytes, MPU_xStreamBufferNextMessageLengthBytesImpl
/* ----------------------------------------------------------------------------------- */
#if ( ( INCLUDE_xTaskDelayUntil == 1 ) || ( INCLUDE_vTaskDelayUntil == 1 ) )
.extern MPU_xTaskDelayUntilImpl
.align 4
.global MPU_xTaskDelayUntil
.type MPU_xTaskDelayUntil, function
MPU_xTaskDelayUntil:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskDelayUntil, MPU_xTaskDelayUntilImpl
#endif /* if ( ( INCLUDE_xTaskDelayUntil == 1 ) || ( INCLUDE_vTaskDelayUntil == 1 ) ) */
/* ----------------------------------------------------------------------------------- */
#if ( INCLUDE_xTaskAbortDelay == 1 )
.extern MPU_xTaskAbortDelayImpl
.align 4
.global MPU_xTaskAbortDelay
.type MPU_xTaskAbortDelay, function
MPU_xTaskAbortDelay:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskAbortDelay, MPU_xTaskAbortDelayImpl
#endif /* if ( INCLUDE_xTaskAbortDelay == 1 ) */
/* ------------------------------------------------------------------------------- */
#if ( INCLUDE_vTaskDelay == 1 )
.extern MPU_vTaskDelayImpl
.align 4
.global MPU_vTaskDelay
.type MPU_vTaskDelay, function
MPU_vTaskDelay:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_vTaskDelay, MPU_vTaskDelayImpl
#endif /* if ( INCLUDE_vTaskDelay == 1 ) */
/* ------------------------------------------------------------------------------- */
#if ( INCLUDE_uxTaskPriorityGet == 1 )
.extern MPU_uxTaskPriorityGetImpl
.align 4
.global MPU_uxTaskPriorityGet
.type MPU_uxTaskPriorityGet, function
MPU_uxTaskPriorityGet:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_uxTaskPriorityGet, MPU_uxTaskPriorityGetImpl
#endif /* if ( INCLUDE_uxTaskPriorityGet == 1 ) */
/* ------------------------------------------------------------------------------- */
#if ( INCLUDE_eTaskGetState == 1 )
.extern MPU_eTaskGetStateImpl
.align 4
.global MPU_eTaskGetState
.type MPU_eTaskGetState, function
MPU_eTaskGetState:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_eTaskGetState, MPU_eTaskGetStateImpl
#endif /* if ( INCLUDE_eTaskGetState == 1 ) */
/* ------------------------------------------------------------------------------- */
#if ( configUSE_TRACE_FACILITY == 1 )
.extern MPU_vTaskGetInfoImpl
.align 4
.global MPU_vTaskGetInfo
.type MPU_vTaskGetInfo, function
MPU_vTaskGetInfo:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_vTaskGetInfo, MPU_vTaskGetInfoImpl
/* ------------------------------------------------------------------------------- */
.extern MPU_uxTaskGetSystemStateImpl
.align 4
.global MPU_uxTaskGetSystemState
.type MPU_uxTaskGetSystemState, function
MPU_uxTaskGetSystemState:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_uxTaskGetSystemState, MPU_uxTaskGetSystemStateImpl
/* ------------------------------------------------------------------------------- */
.extern MPU_uxEventGroupGetNumberImpl
.align 4
.global MPU_uxEventGroupGetNumber
.type MPU_uxEventGroupGetNumber, function
MPU_uxEventGroupGetNumber:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_uxEventGroupGetNumber, MPU_uxEventGroupGetNumberImpl
/* ------------------------------------------------------------------------------- */
.extern MPU_vEventGroupSetNumberImpl
.align 4
.global MPU_vEventGroupSetNumber
.type MPU_vEventGroupSetNumber, function
MPU_vEventGroupSetNumber:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_vEventGroupSetNumber, MPU_vEventGroupSetNumberImpl
/* ------------------------------------------------------------------------------- */
#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */
/* ------------------------------------------------------------------------------- */
#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )
.extern MPU_xTaskGetIdleTaskHandleImpl
.align 4
.global MPU_xTaskGetIdleTaskHandle
.type MPU_xTaskGetIdleTaskHandle, function
MPU_xTaskGetIdleTaskHandle:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskGetIdleTaskHandle, MPU_xTaskGetIdleTaskHandleImpl
#endif /* if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */
/* ------------------------------------------------------------------------------- */
#if ( INCLUDE_vTaskSuspend == 1 )
.extern MPU_vTaskSuspendImpl
.align 4
.global MPU_vTaskSuspend
.type MPU_vTaskSuspend, function
MPU_vTaskSuspend:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_vTaskSuspend, MPU_vTaskSuspendImpl
/* ------------------------------------------------------------------------------- */
.extern MPU_vTaskResumeImpl
.align 4
.global MPU_vTaskResume
.type MPU_vTaskResume, function
MPU_vTaskResume:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_vTaskResume, MPU_vTaskResumeImpl
/* ------------------------------------------------------------------------------- */
#endif /* if ( INCLUDE_vTaskSuspend == 1 ) */
/* ------------------------------------------------------------------------------- */
#if ( configGENERATE_RUN_TIME_STATS == 1 )
.extern MPU_ulTaskGetRunTimeCounterImpl
.align 4
.global MPU_ulTaskGetRunTimeCounter
.type MPU_ulTaskGetRunTimeCounter, function
MPU_ulTaskGetRunTimeCounter:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_ulTaskGetRunTimeCounter, MPU_ulTaskGetRunTimeCounterImpl
/* ------------------------------------------------------------------------------- */
.extern MPU_ulTaskGetRunTimePercentImpl
.align 4
.global MPU_ulTaskGetRunTimePercent
.type MPU_ulTaskGetRunTimePercent, function
MPU_ulTaskGetRunTimePercent:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_ulTaskGetRunTimePercent, MPU_ulTaskGetRunTimePercentImpl
/* ------------------------------------------------------------------------------- */
#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )
.extern MPU_ulTaskGetIdleRunTimePercentImpl
.align 4
.global MPU_ulTaskGetIdleRunTimePercent
.type MPU_ulTaskGetIdleRunTimePercent, function
MPU_ulTaskGetIdleRunTimePercent:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_ulTaskGetIdleRunTimePercent, MPU_ulTaskGetIdleRunTimePercentImpl
/* --------------------------------------------------------------------------- */
.extern MPU_ulTaskGetIdleRunTimeCounterImpl
.align 4
.global MPU_ulTaskGetIdleRunTimeCounter
.type MPU_ulTaskGetIdleRunTimeCounter, function
MPU_ulTaskGetIdleRunTimeCounter:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_ulTaskGetIdleRunTimeCounter, MPU_ulTaskGetIdleRunTimeCounterImpl
/* --------------------------------------------------------------------------- */
#endif /* if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */
#endif /* if ( configGENERATE_RUN_TIME_STATS == 1 )*/
/* --------------------------------------------------------------------------- */
#if ( configUSE_APPLICATION_TASK_TAG == 1 )
.extern MPU_vTaskSetApplicationTaskTagImpl
.align 4
.global MPU_vTaskSetApplicationTaskTag
.type MPU_vTaskSetApplicationTaskTag, function
MPU_vTaskSetApplicationTaskTag:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_vTaskSetApplicationTaskTag, MPU_vTaskSetApplicationTaskTagImpl
/* ------------------------------------------------------------------------------- */
.extern MPU_xTaskGetApplicationTaskTagImpl
.align 4
.global MPU_xTaskGetApplicationTaskTag
.type MPU_xTaskGetApplicationTaskTag, function
MPU_xTaskGetApplicationTaskTag:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskGetApplicationTaskTag, MPU_xTaskGetApplicationTaskTagImpl
/* ------------------------------------------------------------------------------- */
#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */
/* ------------------------------------------------------------------------------- */
#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 )
.extern MPU_vTaskSetThreadLocalStoragePointerImpl
.align 4
.global MPU_vTaskSetThreadLocalStoragePointer
.type MPU_vTaskSetThreadLocalStoragePointer, function
MPU_vTaskSetThreadLocalStoragePointer:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_vTaskSetThreadLocalStoragePointer, MPU_vTaskSetThreadLocalStoragePointerImpl
/* ------------------------------------------------------------------------------- */
.extern MPU_pvTaskGetThreadLocalStoragePointerImpl
.align 4
.global MPU_pvTaskGetThreadLocalStoragePointer
.type MPU_pvTaskGetThreadLocalStoragePointer, function
MPU_pvTaskGetThreadLocalStoragePointer:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer, MPU_pvTaskGetThreadLocalStoragePointerImpl
/* ------------------------------------------------------------------------------- */
#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */
/* ------------------------------------------------------------------------------- */
#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 )
.extern MPU_uxTaskGetStackHighWaterMarkImpl
.align 4
.global MPU_uxTaskGetStackHighWaterMark
.type MPU_uxTaskGetStackHighWaterMark, function
MPU_uxTaskGetStackHighWaterMark:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_uxTaskGetStackHighWaterMark, MPU_uxTaskGetStackHighWaterMarkImpl
#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) */
/* ------------------------------------------------------------------------------- */
#if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 )
.extern MPU_uxTaskGetStackHighWaterMark2Impl
.align 4
.global MPU_uxTaskGetStackHighWaterMark2
.type MPU_uxTaskGetStackHighWaterMark2, function
MPU_uxTaskGetStackHighWaterMark2:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_uxTaskGetStackHighWaterMark2, MPU_uxTaskGetStackHighWaterMark2Impl
#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) */
/* ------------------------------------------------------------------------------- */
#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) )
.extern MPU_xTaskGetCurrentTaskHandleImpl
.align 4
.global MPU_xTaskGetCurrentTaskHandle
.type MPU_xTaskGetCurrentTaskHandle, function
MPU_xTaskGetCurrentTaskHandle:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskGetCurrentTaskHandle, MPU_xTaskGetCurrentTaskHandleImpl
#endif /* if( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */
/* ------------------------------------------------------------------------------- */
#if ( INCLUDE_xTaskGetSchedulerState == 1 )
.extern MPU_xTaskGetSchedulerStateImpl
.align 4
.global MPU_xTaskGetSchedulerState
.type MPU_xTaskGetSchedulerState, function
MPU_xTaskGetSchedulerState:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskGetSchedulerState, MPU_xTaskGetSchedulerStateImpl
#endif /* if ( INCLUDE_xTaskGetSchedulerState == 1 ) */
/* ------------------------------------------------------------------------------- */
#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) )
.extern MPU_xQueueGetMutexHolderImpl
.align 4
.global MPU_xQueueGetMutexHolder
.type MPU_xQueueGetMutexHolder, function
MPU_xQueueGetMutexHolder:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_xQueueGetMutexHolder, MPU_xQueueGetMutexHolderImpl
#endif /* if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) */
/* ------------------------------------------------------------------------------- */
#if ( configUSE_RECURSIVE_MUTEXES == 1 )
.extern MPU_xQueueTakeMutexRecursiveImpl
.align 4
.global MPU_xQueueTakeMutexRecursive
.type MPU_xQueueTakeMutexRecursive, function
MPU_xQueueTakeMutexRecursive:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_xQueueTakeMutexRecursive, MPU_xQueueTakeMutexRecursiveImpl
/* ------------------------------------------------------------------------------- */
.extern MPU_xQueueGiveMutexRecursiveImpl
.align 4
.global MPU_xQueueGiveMutexRecursive
.type MPU_xQueueGiveMutexRecursive, function
MPU_xQueueGiveMutexRecursive:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_xQueueGiveMutexRecursive, MPU_xQueueGiveMutexRecursiveImpl
/* ------------------------------------------------------------------------------- */
#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */
/* ------------------------------------------------------------------------------- */
#if ( configUSE_QUEUE_SETS == 1 )
.extern MPU_xQueueSelectFromSetImpl
.align 4
.global MPU_xQueueSelectFromSet
.type MPU_xQueueSelectFromSet, function
MPU_xQueueSelectFromSet:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_xQueueSelectFromSet, MPU_xQueueSelectFromSetImpl
/* ------------------------------------------------------------------------------- */
.extern MPU_xQueueAddToSetImpl
.align 4
.global MPU_xQueueAddToSet
.type MPU_xQueueAddToSet, function
MPU_xQueueAddToSet:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_xQueueAddToSet, MPU_xQueueAddToSetImpl
/* ------------------------------------------------------------------------------- */
#endif /* if ( configUSE_QUEUE_SETS == 1 ) */
/* ------------------------------------------------------------------------------- */
#if ( configQUEUE_REGISTRY_SIZE > 0 )
.extern MPU_vQueueAddToRegistryImpl
.align 4
.global MPU_vQueueAddToRegistry
.type MPU_vQueueAddToRegistry, function
MPU_vQueueAddToRegistry:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_vQueueAddToRegistry, MPU_vQueueAddToRegistryImpl
/* ------------------------------------------------------------------------------- */
.extern MPU_vQueueUnregisterQueueImpl
.align 4
.global MPU_vQueueUnregisterQueue
.type MPU_vQueueUnregisterQueue, function
MPU_vQueueUnregisterQueue:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_vQueueUnregisterQueue, MPU_vQueueUnregisterQueueImpl
/* ------------------------------------------------------------------------------- */
.extern MPU_pcQueueGetNameImpl
.align 4
.global MPU_pcQueueGetName
.type MPU_pcQueueGetName, function
MPU_pcQueueGetName:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_pcQueueGetName, MPU_pcQueueGetNameImpl
/* ------------------------------------------------------------------------------- */
#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */
/* ------------------------------------------------------------------------------- */
#if ( configUSE_TIMERS == 1 )
.extern MPU_pvTimerGetTimerIDImpl
.align 4
.global MPU_pvTimerGetTimerID
.type MPU_pvTimerGetTimerID, function
MPU_pvTimerGetTimerID:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_pvTimerGetTimerID, MPU_pvTimerGetTimerIDImpl
/* ------------------------------------------------------------------------------- */
.extern MPU_vTimerSetTimerIDImpl
.align 4
.global MPU_vTimerSetTimerID
.type MPU_vTimerSetTimerID, function
MPU_vTimerSetTimerID:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_vTimerSetTimerID, MPU_vTimerSetTimerIDImpl
/* ------------------------------------------------------------------------------- */
.extern MPU_xTimerIsTimerActiveImpl
.align 4
.global MPU_xTimerIsTimerActive
.type MPU_xTimerIsTimerActive, function
MPU_xTimerIsTimerActive:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTimerIsTimerActive, MPU_xTimerIsTimerActiveImpl
/* ------------------------------------------------------------------------------- */
.extern MPU_xTimerGetTimerDaemonTaskHandleImpl
.align 4
.global MPU_xTimerGetTimerDaemonTaskHandle
.type MPU_xTimerGetTimerDaemonTaskHandle, function
MPU_xTimerGetTimerDaemonTaskHandle:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle, MPU_xTimerGetTimerDaemonTaskHandleImpl
/* ------------------------------------------------------------------------------- */
.extern MPU_xTimerGenericCommandFromTaskImpl
.align 4
.global MPU_xTimerGenericCommandFromTaskEntry
.type MPU_xTimerGenericCommandFromTaskEntry, function
MPU_xTimerGenericCommandFromTaskEntry:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTimerGenericCommandFromTask, MPU_xTimerGenericCommandFromTaskImpl
/* ------------------------------------------------------------------------------- */
.extern MPU_pcTimerGetNameImpl
.align 4
.global MPU_pcTimerGetName
.type MPU_pcTimerGetName, function
MPU_pcTimerGetName:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_pcTimerGetName, MPU_pcTimerGetNameImpl
/* ------------------------------------------------------------------------------- */
.extern MPU_vTimerSetReloadModeImpl
.align 4
.global MPU_vTimerSetReloadMode
.type MPU_vTimerSetReloadMode, function
MPU_vTimerSetReloadMode:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_vTimerSetReloadMode, MPU_vTimerSetReloadModeImpl
/* ------------------------------------------------------------------------------- */
.extern MPU_xTimerGetReloadModeImpl
.align 4
.global MPU_xTimerGetReloadMode
.type MPU_xTimerGetReloadMode, function
MPU_xTimerGetReloadMode:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTimerGetReloadMode, MPU_xTimerGetReloadModeImpl
/* ------------------------------------------------------------------------------- */
.extern MPU_uxTimerGetReloadModeImpl
.align 4
.global MPU_uxTimerGetReloadMode
.type MPU_uxTimerGetReloadMode, function
MPU_uxTimerGetReloadMode:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_uxTimerGetReloadMode, MPU_uxTimerGetReloadModeImpl
/* ------------------------------------------------------------------------------- */
.extern MPU_xTimerGetPeriodImpl
.align 4
.global MPU_xTimerGetPeriod
.type MPU_xTimerGetPeriod, function
MPU_xTimerGetPeriod:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTimerGetPeriod, MPU_xTimerGetPeriodImpl
/* ------------------------------------------------------------------------------- */
.extern MPU_xTimerGetExpiryTimeImpl
.align 4
.global MPU_xTimerGetExpiryTime
.type MPU_xTimerGetExpiryTime, function
MPU_xTimerGetExpiryTime:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTimerGetExpiryTime, MPU_xTimerGetExpiryTimeImpl
/* ------------------------------------------------------------------------------- */
#endif /* if ( configUSE_TIMERS == 1 ) */
/* ------------------------------------------------------------------------------- */
#if ( configUSE_TASK_NOTIFICATIONS == 1 )
.extern MPU_xTaskGenericNotifyImpl
.align 4
.global MPU_xTaskGenericNotifyEntry
.type MPU_xTaskGenericNotifyEntry, function
MPU_xTaskGenericNotifyEntry:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskGenericNotify, MPU_xTaskGenericNotifyImpl
/* ------------------------------------------------------------------------------- */
.extern MPU_xTaskGenericNotifyWaitImpl
.align 4
.global MPU_xTaskGenericNotifyWaitEntry
.type MPU_xTaskGenericNotifyWaitEntry, function
MPU_xTaskGenericNotifyWaitEntry:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskGenericNotifyWait, MPU_xTaskGenericNotifyWaitImpl
/* ------------------------------------------------------------------------------- */
.extern MPU_ulTaskGenericNotifyTakeImpl
.align 4
.global MPU_ulTaskGenericNotifyTake
.type MPU_ulTaskGenericNotifyTake, function
MPU_ulTaskGenericNotifyTake:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_ulTaskGenericNotifyTake, MPU_ulTaskGenericNotifyTakeImpl
/* ------------------------------------------------------------------------------- */
.extern MPU_xTaskGenericNotifyStateClearImpl
.align 4
.global MPU_xTaskGenericNotifyStateClear
.type MPU_xTaskGenericNotifyStateClear, function
MPU_xTaskGenericNotifyStateClear:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskGenericNotifyStateClear, MPU_xTaskGenericNotifyStateClearImpl
/* ------------------------------------------------------------------------------- */
.extern MPU_ulTaskGenericNotifyValueClearImpl
.align 4
.global MPU_ulTaskGenericNotifyValueClear
.type MPU_ulTaskGenericNotifyValueClear, function
MPU_ulTaskGenericNotifyValueClear:
INVOKE_SYSTEM_CALL #SYSTEM_CALL_ulTaskGenericNotifyValueClear, MPU_ulTaskGenericNotifyValueClearImpl
/* ------------------------------------------------------------------------------- */
#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */
/* ------------------------------------------------------------------------------- */
.end

View file

@ -0,0 +1,843 @@
/*
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2024 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
*
*/
/* Standard includes. */
#include <stdint.h>
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
* all the API functions to use the MPU wrappers. That should only be done when
* task.h is included from an application file. */
#ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
#endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "portmacro.h"
#include "task.h"
#include "mpu_syscall_numbers.h"
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
/* Max value that fits in a uint32_t type. */
#define portUINT32_MAX ( ~( ( uint32_t ) 0 ) )
/* Check if adding a and b will result in overflow. */
#define portADD_UINT32_WILL_OVERFLOW( a, b ) ( ( a ) > ( portUINT32_MAX - ( b ) ) )
/* ----------------------------------------------------------------------------------- */
/**
* @brief Variable used to keep track of critical section nesting.
*
* @ingroup Critical Sections
*
* This variable is stored as part of the task context and must be initialised
* to a non zero value to ensure interrupts don't inadvertently become unmasked
* before the scheduler starts. As it is stored as part of the task context, it
* will be set to 0 when the first task is started.
*/
PRIVILEGED_DATA volatile UBaseType_t ulCriticalNesting = 0xFFFF;
/**
* @brief Set to 1 to pend a context switch from an ISR.
*
* @ingroup Interrupt Management
*/
PRIVILEGED_DATA volatile UBaseType_t ulPortYieldRequired = pdFALSE;
/**
* @brief Interrupt nesting depth, used to count the number of interrupts to unwind.
*
* @ingroup Interrupt Management
*/
PRIVILEGED_DATA volatile UBaseType_t ulPortInterruptNesting = 0UL;
/**
* @brief Variable to track whether or not the scheduler has been started.
*
* @ingroup Scheduler
*
* This is the port specific version of the xSchedulerRunning in tasks.c.
*/
PRIVILEGED_DATA static BaseType_t prvPortSchedulerRunning = pdFALSE;
/* -------------------------- Private Function Declarations -------------------------- */
/**
* @brief Determine if the given MPU region settings authorizes the requested
* access to the given buffer.
*
* @ingroup Task Context
* @ingroup MPU Control
*
* @param xTaskMPURegion MPU region settings.
* @param ulBufferStart Start address of the given buffer.
* @param ulBufferLength Length of the given buffer.
* @param ulAccessRequested Access requested.
*
* @return pdTRUE if MPU region settins authorizes the requested access to the
* given buffer, pdFALSE otherwise.
*/
PRIVILEGED_FUNCTION static BaseType_t prvMPURegionAuthorizesBuffer( const xMPU_REGION_REGISTERS * xTaskMPURegion,
const uint32_t ulBufferStart,
const uint32_t ulBufferLength,
const uint32_t ulAccessRequested );
/**
* @brief Determine the smallest MPU Region Size Encoding for the given MPU
* region size.
*
* @ingroup MPU Control
*
* @param ulActualMPURegionSize MPU region size in bytes.
*
* @return The smallest MPU Region Size Encoding for the given MPU region size.
*/
PRIVILEGED_FUNCTION static uint32_t prvGetMPURegionSizeEncoding( uint32_t ulActualMPURegionSize );
/**
* @brief Set up MPU.
*
* @ingroup MPU Control
*/
PRIVILEGED_FUNCTION static void prvSetupMPU( void );
/* -------------------------- Exported Function Declarations -------------------------- */
/**
* @brief Enter critical section.
*
* @ingroup Critical Section
*/
PRIVILEGED_FUNCTION void vPortEnterCritical( void );
/**
* @brief Exit critical section.
*
* @ingroup Critical Section
*/
PRIVILEGED_FUNCTION void vPortExitCritical( void );
/* ----------------------------------------------------------------------------------- */
/**
* @brief Setup a FreeRTOS task's initial context.
*
* @ingroup Task Context
*
* @param pxTopOfStack Top of stack.
* @param pxCode The task function.
* @param pvParameters Argument passed to the task function.
* @param xRunPrivileged Marks if the task is privileged.
* @param xMPUSettings MPU settings of the task.
*
* @return Location where to restore the task's context from.
*/
/* PRIVILEGED_FUNCTION */
StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
TaskFunction_t pxCode,
void * pvParameters,
BaseType_t xRunPrivileged,
xMPU_SETTINGS * xMPUSettings )
{
/* Setup the initial context of the task. The context is set exactly as
* expected by the portRESTORE_CONTEXT() macro. */
UBaseType_t ulIndex = CONTEXT_SIZE - 1U;
xSYSTEM_CALL_STACK_INFO * xSysCallInfo = NULL;
if( xRunPrivileged == pdTRUE )
{
xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG;
/* Current Program Status Register (CPSR). */
xMPUSettings->ulContext[ ulIndex ] = SYS_MODE;
}
else
{
xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG );
/* Current Program Status Register (CPSR). */
xMPUSettings->ulContext[ ulIndex ] = USER_MODE;
}
if( ( ( uint32_t ) pxCode & portTHUMB_MODE_ADDRESS ) != 0x0UL )
{
/* The task will cause the processor to start in THUMB state, set the
* Thumb state bit in the CPSR. */
xMPUSettings->ulContext[ ulIndex ] |= portTHUMB_MODE_BIT;
}
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) pxCode; /* PC. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) pxTopOfStack; /* SP. */
ulIndex--;
/* General Purpose Registers. */
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x12121212; /* R12. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x11111111; /* R11. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x10101010; /* R10. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x09090909; /* R9. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x08080808; /* R8. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x07070707; /* R7. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x06060606; /* R6. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x05050505; /* R5. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x04040404; /* R4. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x03030303; /* R3. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x02020202; /* R2. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x01010101; /* R1. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) pvParameters; /* R0. */
ulIndex--;
#if( portENABLE_FPU == 1 )
{
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000015; /* S31. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1500000; /* S30. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000014; /* S29. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1400000; /* S28. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000013; /* S27. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1300000; /* S26. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000012; /* S25. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1200000; /* S24. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000011; /* S23. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1100000; /* S22. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000010; /* S21. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1000000; /* S20. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000009; /* S19. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD9000000; /* S18. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000008; /* S17. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD8000000; /* S16. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000007; /* S15. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD7000000; /* S14. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000006; /* S13. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD6000000; /* S12. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000005; /* S11. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD5000000; /* S10. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000004; /* S9. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD4000000; /* S8. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000003; /* S7. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD3000000; /* S6. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000002; /* S5. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD2000000; /* S4. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000001; /* S3. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1000000; /* S2. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000000; /* S1. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000000; /* S0. */
ulIndex--;
xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x00000000; /* FPSR. */
ulIndex--;
}
#endif /* portENABLE_FPU */
/* The task will start with a critical nesting count of 0. */
xMPUSettings->ulContext[ ulIndex ] = portNO_CRITICAL_NESTING;
/* Ensure that the system call stack is double word aligned. */
xSysCallInfo = &( xMPUSettings->xSystemCallStackInfo );
xSysCallInfo->pulSystemCallStackPointer = &( xSysCallInfo->ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE - 1U ] );
xSysCallInfo->pulSystemCallStackPointer = ( uint32_t * ) ( ( ( uint32_t ) ( xSysCallInfo->pulSystemCallStackPointer ) ) &
( ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ) );
/* This is not NULL only for the duration of a system call. */
xSysCallInfo->pulTaskStackPointer = NULL;
/* Set the System Call to return to vPortSystemCallExit. */
xSysCallInfo->pulSystemCallExitAddress = ( uint32_t * ) ( &vPortSystemCallExit );
/* Return the address where this task's context should be restored from. */
return &( xMPUSettings->ulContext[ ulIndex ] );
}
/* ----------------------------------------------------------------------------------- */
/**
* @brief Store a FreeRTOS task's MPU settings in its TCB.
*
* @ingroup Task Context
* @ingroup MPU Control
*
* @param xMPUSettings The MPU settings in TCB.
* @param xRegions The updated MPU settings requested by the task.
* @param pxBottomOfStack The base address of the task's Stack.
* @param ulStackDepth The length of the task's stack.
*/
/* PRIVILEGED_FUNCTION */
void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
const struct xMEMORY_REGION * const xRegions,
StackType_t * pxBottomOfStack,
uint32_t ulStackDepth )
{
#if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */
extern uint32_t * __SRAM_segment_start__;
extern uint32_t * __SRAM_segment_end__;
#else
/* Declaration when these variable are exported from linker scripts. */
extern uint32_t __SRAM_segment_start__[];
extern uint32_t __SRAM_segment_end__[];
#endif /* if defined( __ARMCC_VERSION ) */
uint32_t ulIndex = 0x0;
uint32_t ulRegionLength;
uint32_t ulRegionLengthEncoded;
uint32_t ulRegionLengthDecoded;
if( xRegions == NULL )
{
/* No MPU regions are specified so allow access to all of the RAM. */
ulRegionLength = ( uint32_t ) __SRAM_segment_end__ - ( uint32_t ) __SRAM_segment_start__;
ulRegionLengthEncoded = prvGetMPURegionSizeEncoding( ulRegionLength );
ulRegionLength |= portMPU_REGION_ENABLE;
/* MPU Settings is zero'd out in the TCB before this function is called.
* We, therefore, do not need to explicitly zero out unused MPU regions
* in xMPUSettings. */
ulIndex = portSTACK_REGION;
xMPUSettings->xRegion[ ulIndex ].ulRegionBaseAddress = ( uint32_t ) __SRAM_segment_start__;
xMPUSettings->xRegion[ ulIndex ].ulRegionSize = ( ulRegionLengthEncoded |
portMPU_REGION_ENABLE );
xMPUSettings->xRegion[ ulIndex ].ulRegionAttribute = ( portMPU_REGION_PRIV_RW_USER_RW_NOEXEC |
portMPU_REGION_NORMAL_OIWTNOWA_SHARED );
}
else
{
for( ulIndex = 0UL; ulIndex < portNUM_CONFIGURABLE_REGIONS; ulIndex++ )
{
/* If a length has been provided, the region is in use. */
if( ( xRegions[ ulIndex ] ).ulLengthInBytes > 0UL )
{
ulRegionLength = xRegions[ ulIndex ].ulLengthInBytes;
ulRegionLengthEncoded = prvGetMPURegionSizeEncoding( ulRegionLength );
/* MPU region base address must be aligned to the region size
* boundary. */
ulRegionLengthDecoded = 2UL << ( ulRegionLengthEncoded >> 1UL );
configASSERT( ( ( ( uint32_t ) xRegions[ ulIndex ].pvBaseAddress ) % ( ulRegionLengthDecoded ) ) == 0UL );
xMPUSettings->xRegion[ ulIndex ].ulRegionBaseAddress = ( uint32_t ) xRegions[ ulIndex ].pvBaseAddress;
xMPUSettings->xRegion[ ulIndex ].ulRegionSize = ( ulRegionLengthEncoded |
portMPU_REGION_ENABLE );
xMPUSettings->xRegion[ ulIndex ].ulRegionAttribute = xRegions[ ulIndex ].ulParameters;
}
else
{
xMPUSettings->xRegion[ ulIndex ].ulRegionBaseAddress = 0x0UL;
xMPUSettings->xRegion[ ulIndex ].ulRegionSize = 0x0UL;
xMPUSettings->xRegion[ ulIndex ].ulRegionAttribute = 0x0UL;
}
}
/* This function is called automatically when the task is created - in
* which case the stack region parameters will be valid. At all other
* times the stack parameters will not be valid and it is assumed that the
* stack region has already been configured. */
if( ulStackDepth != 0x0UL )
{
ulRegionLengthEncoded = prvGetMPURegionSizeEncoding( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) );
/* MPU region base address must be aligned to the region size
* boundary. */
ulRegionLengthDecoded = 2UL << ( ulRegionLengthEncoded >> 1UL );
configASSERT( ( ( uint32_t ) pxBottomOfStack % ( ulRegionLengthDecoded ) ) == 0U );
ulIndex = portSTACK_REGION;
xMPUSettings->xRegion[ ulIndex ].ulRegionBaseAddress = ( uint32_t ) pxBottomOfStack;
xMPUSettings->xRegion[ ulIndex ].ulRegionSize = ( ulRegionLengthEncoded |
portMPU_REGION_ENABLE );;
xMPUSettings->xRegion[ ulIndex ].ulRegionAttribute = ( portMPU_REGION_PRIV_RW_USER_RW_NOEXEC |
portMPU_REGION_NORMAL_OIWTNOWA_SHARED );
}
}
}
/* ----------------------------------------------------------------------------------- */
/* PRIVILEGED_FUNCTION */
BaseType_t xPortIsTaskPrivileged( void )
{
BaseType_t xTaskIsPrivileged = pdFALSE;
/* Calling task's MPU settings. */
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL );
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
{
xTaskIsPrivileged = pdTRUE;
}
return xTaskIsPrivileged;
}
/* ----------------------------------------------------------------------------------- */
/* PRIVILEGED_FUNCTION */
BaseType_t xPortStartScheduler( void )
{
/* Start the timer that generates the tick ISR. */
configSETUP_TICK_INTERRUPT();
/* Configure MPU regions that are common to all tasks. */
prvSetupMPU();
prvPortSchedulerRunning = pdTRUE;
/* Load the context of the first task. */
vPortStartFirstTask();
/* Will only get here if vTaskStartScheduler() was called with the CPU in
* a non-privileged mode or the binary point register was not set to its lowest
* possible value. prvTaskExitError() is referenced to prevent a compiler
* warning about it being defined but not referenced in the case that the user
* defines their own exit address. */
( void ) prvTaskExitError();
return pdFALSE;
}
/* ----------------------------------------------------------------------------------- */
/* PRIVILEGED_FUNCTION */
static uint32_t prvGetMPURegionSizeEncoding( uint32_t ulActualMPURegionSize )
{
uint32_t ulRegionSize, ulReturnValue = 4U;
/* 32 bytes is the smallest valid region for Cortex R4 and R5 CPUs. */
for( ulRegionSize = 0x20UL; ulReturnValue < 0x1FUL; ( ulRegionSize <<= 1UL ) )
{
if( ulActualMPURegionSize <= ulRegionSize )
{
break;
}
else
{
ulReturnValue++;
}
}
/* Shift the code by one before returning so it can be written directly
* into the the correct bit position of the attribute register. */
return ulReturnValue << 1UL;
}
/* ----------------------------------------------------------------------------------- */
/* PRIVILEGED_FUNCTION */
static void prvSetupMPU( void )
{
#if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code. */
/* Sections used for FLASH. */
extern uint32_t * __FLASH_segment_start__;
extern uint32_t * __FLASH_segment_end__;
extern uint32_t * __privileged_functions_start__;
extern uint32_t * __privileged_functions_end__;
/* Sections used for RAM. */
extern uint32_t * __SRAM_segment_start__;
extern uint32_t * __SRAM_segment_end__;
extern uint32_t * __privileged_data_start__;
extern uint32_t * __privileged_data_end__;
#else
/* Declaration when these variable are exported from linker scripts. */
/* Sections used for FLASH. */
extern uint32_t __FLASH_segment_start__[];
extern uint32_t __FLASH_segment_end__[];
extern uint32_t __privileged_functions_start__[];
extern uint32_t __privileged_functions_end__[];
/* Sections used for RAM. */
extern uint32_t __SRAM_segment_start__[];
extern uint32_t __SRAM_segment_end__[];
extern uint32_t __privileged_data_start__[];
extern uint32_t __privileged_data_end__[];
#endif /* if defined( __ARMCC_VERSION ) */
uint32_t ulRegionLength;
uint32_t ulRegionLengthEncoded;
/* Disable the MPU before programming it. */
vMPUDisable();
/* Priv: RX, Unpriv: RX for entire Flash. */
ulRegionLength = ( uint32_t ) __FLASH_segment_end__ - ( uint32_t ) __FLASH_segment_start__;
ulRegionLengthEncoded = prvGetMPURegionSizeEncoding( ulRegionLength );
vMPUSetRegion( portUNPRIVILEGED_FLASH_REGION,
( uint32_t ) __FLASH_segment_start__,
( ulRegionLengthEncoded | portMPU_REGION_ENABLE ),
( portMPU_REGION_PRIV_RO_USER_RO_EXEC |
portMPU_REGION_NORMAL_OIWTNOWA_SHARED ) );
/* Priv: RX, Unpriv: No access for privileged functions. */
ulRegionLength = ( uint32_t ) __privileged_functions_end__ - ( uint32_t ) __privileged_functions_start__;
ulRegionLengthEncoded = prvGetMPURegionSizeEncoding( ulRegionLength );
vMPUSetRegion( portPRIVILEGED_FLASH_REGION,
( uint32_t ) __privileged_functions_start__,
( ulRegionLengthEncoded | portMPU_REGION_ENABLE ),
( portMPU_REGION_PRIV_RO_USER_NA_EXEC |
portMPU_REGION_NORMAL_OIWTNOWA_SHARED ) );
/* Priv: RW, Unpriv: No Access for privileged data. */
ulRegionLength = ( uint32_t ) __privileged_data_end__ - ( uint32_t ) __privileged_data_start__;
ulRegionLengthEncoded = prvGetMPURegionSizeEncoding( ulRegionLength );
vMPUSetRegion( portPRIVILEGED_RAM_REGION,
( uint32_t ) __privileged_data_start__,
( ulRegionLengthEncoded | portMPU_REGION_ENABLE ),
( portMPU_REGION_PRIV_RW_USER_NA_NOEXEC |
portMPU_REGION_PRIV_RW_USER_NA_NOEXEC ) );
/* Enable the MPU background region - it allows privileged operating modes
* access to unmapped regions of memory without generating a fault. */
vMPUEnableBackgroundRegion();
/* After setting default regions, enable the MPU. */
vMPUEnable();
}
/* ----------------------------------------------------------------------------------- */
/* PRIVILEGED_FUNCTION */
static BaseType_t prvMPURegionAuthorizesBuffer( const xMPU_REGION_REGISTERS * xTaskMPURegion,
const uint32_t ulBufferStart,
const uint32_t ulBufferLength,
const uint32_t ulAccessRequested )
{
BaseType_t xAccessGranted = pdFALSE;
uint32_t ulBufferEnd;
uint32_t ulMPURegionLength;
uint32_t ulMPURegionStart;
uint32_t ulMPURegionEnd;
uint32_t ulMPURegionAccessPermissions;
if( portADD_UINT32_WILL_OVERFLOW( ulBufferStart, ( ulBufferLength - 1UL ) ) == pdFALSE )
{
ulBufferEnd = ulBufferStart + ulBufferLength - 1UL;
ulMPURegionLength = 2UL << ( xTaskMPURegion->ulRegionSize >> 1UL );
ulMPURegionStart = xTaskMPURegion->ulRegionBaseAddress;
ulMPURegionEnd = xTaskMPURegion->ulRegionBaseAddress + ulMPURegionLength - 1UL;
if( ( ulBufferStart >= ulMPURegionStart ) &&
( ulBufferEnd <= ulMPURegionEnd ) &&
( ulBufferStart <= ulBufferEnd ) )
{
ulMPURegionAccessPermissions = xTaskMPURegion->ulRegionAttribute & portMPU_REGION_AP_BITMASK;
if( ulAccessRequested == tskMPU_READ_PERMISSION ) /* RO. */
{
if( ( ulMPURegionAccessPermissions == portMPU_REGION_PRIV_RW_USER_RO ) ||
( ulMPURegionAccessPermissions == portMPU_REGION_PRIV_RO_USER_RO ) )
{
xAccessGranted = pdTRUE;
}
}
else if( ( ulAccessRequested & tskMPU_WRITE_PERMISSION ) != 0UL ) /* W or RW. */
{
if( ulMPURegionAccessPermissions == portMPU_REGION_PRIV_RW_USER_RW )
{
xAccessGranted = pdTRUE;
}
}
}
}
return xAccessGranted;
}
/* ----------------------------------------------------------------------------------- */
/* PRIVILEGED_FUNCTION */
BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer,
uint32_t ulBufferLength,
uint32_t ulAccessRequested )
{
BaseType_t xAccessGranted = pdFALSE;
uint32_t ulRegionIndex;
xMPU_SETTINGS * xTaskMPUSettings = NULL;
if( prvPortSchedulerRunning == pdFALSE )
{
/* Grant access to all the memory before the scheduler is started. It is
* necessary because there is no task running yet and therefore, we
* cannot use the permissions of any task. */
xAccessGranted = pdTRUE;
}
else
{
/* Calling task's MPU settings. */
xTaskMPUSettings = xTaskGetMPUSettings( NULL );
if( ( xTaskMPUSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
{
/* Privileged tasks have access to all the memory. */
xAccessGranted = pdTRUE;
}
else
{
for( ulRegionIndex = 0x0UL; ulRegionIndex < portTOTAL_NUM_REGIONS_IN_TCB; ulRegionIndex++ )
{
xAccessGranted = prvMPURegionAuthorizesBuffer( &( xTaskMPUSettings->xRegion[ ulRegionIndex ] ),
( uint32_t ) pvBuffer,
ulBufferLength,
ulAccessRequested );
if( xAccessGranted == pdTRUE )
{
break;
}
}
}
}
return xAccessGranted;
}
/* ----------------------------------------------------------------------------------- */
#if( configENABLE_ACCESS_CONTROL_LIST == 1 )
/* PRIVILEGED_FUNCTION */
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject )
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
BaseType_t xAccessGranted = pdFALSE;
const xMPU_SETTINGS * xTaskMpuSettings;
if( prvPortSchedulerRunning == pdFALSE )
{
/* Grant access to all the kernel objects before the scheduler
* is started. It is necessary because there is no task running
* yet and therefore, we cannot use the permissions of any
* task. */
xAccessGranted = pdTRUE;
}
else
{
/* Calling task's MPU settings. */
xTaskMpuSettings = xTaskGetMPUSettings( NULL );
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject
/ portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject
% portACL_ENTRY_SIZE_BITS );
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
{
xAccessGranted = pdTRUE;
}
else
{
if( ( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] ) &
( 1U << ulAccessControlListEntryBit ) ) != 0UL )
{
xAccessGranted = pdTRUE;
}
}
}
return xAccessGranted;
}
#else
/* PRIVILEGED_FUNCTION */
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject )
{
( void ) lInternalIndexOfKernelObject;
/* If Access Control List feature is not used, all the tasks have
* access to all the kernel objects. */
return pdTRUE;
}
#endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
/* ----------------------------------------------------------------------------------- */
#if( configENABLE_ACCESS_CONTROL_LIST == 1 )
/* PRIVILEGED_FUNCTION */
void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject )
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject
/ portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject
% portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
/* ----------------------------------------------------------------------------------- */
#if( configENABLE_ACCESS_CONTROL_LIST == 1 )
/* PRIVILEGED_FUNCTION */
void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject )
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject
/ portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject
% portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
/* ----------------------------------------------------------------------------------- */
void prvTaskExitError( void )
{
/* A function that implements a task must not exit or attempt to return to
* its caller as there is nothing to return to. If a task wants to exit it
* should instead call vTaskDelete( NULL ).
*
* Artificially force an assert() to be triggered if configASSERT() is
* defined, then stop here so application writers can catch the error. */
configASSERT( ulPortInterruptNesting == ~0UL );
for( ;; )
{
}
}
/* ----------------------------------------------------------------------------------- */
void vPortEndScheduler( void )
{
prvPortSchedulerRunning = pdFALSE;
/* Not implemented in this port. Artificially force an assert. */
configASSERT( prvPortSchedulerRunning == pdTRUE );
}
/* ----------------------------------------------------------------------------------- */
/* PRIVILEGED_FUNCTION */
void vPortEnterCritical( void )
{
portDISABLE_INTERRUPTS();
/* Now that interrupts are disabled, ulCriticalNesting can be accessed
* directly. Increment ulCriticalNesting to keep a count of how many times
* portENTER_CRITICAL() has been called. */
ulCriticalNesting++;
/* This is not the interrupt safe version of the enter critical function so
* assert() if it is being called from an interrupt context. Only API
* functions that end in "FromISR" can be used in an interrupt. Only assert
* if the critical nesting count is 1 to protect against recursive calls if
* the assert function also uses a critical section. */
if( ulCriticalNesting == 1 )
{
configASSERT( ulPortInterruptNesting == 0 );
}
}
/* ----------------------------------------------------------------------------------- */
/* PRIVILEGED_FUNCTION */
void vPortExitCritical( void )
{
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
{
/* Decrement the nesting count as the critical section is being
* exited. */
ulCriticalNesting--;
/* If the nesting level has reached zero then all interrupt
* priorities must be re-enabled. */
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
{
/* Critical nesting has reached zero so all interrupt priorities
* should be unmasked. */
portENABLE_INTERRUPTS();
}
}
}
/* ----------------------------------------------------------------------------------- */

View file

@ -0,0 +1,498 @@
/*
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2024 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
*
*/
.arm
.syntax unified
.section privileged_functions
#define FREERTOS_ASSEMBLY
#include "portmacro_asm.h"
#include "mpu_syscall_numbers.h"
#undef FREERTOS_ASSEMBLY
/* External FreeRTOS-Kernel variables. */
.extern pxCurrentTCB
.extern uxSystemCallImplementations
.extern ulPortInterruptNesting
.extern ulPortYieldRequired
/* External Llnker script variables. */
.extern __syscalls_flash_start__
.extern __syscalls_flash_end__
/* External FreeRTOS-Kernel functions. */
.extern vTaskSwitchContext
.extern vApplicationIRQHandler
/* ----------------------------------------------------------------------------------- */
/* Save the context of a FreeRTOS Task. */
.macro portSAVE_CONTEXT
DSB
ISB
/* Push R0 and LR to the stack for current mode. */
PUSH { R0, LR }
LDR LR, =pxCurrentTCB /* LR = &( pxCurrentTCB ). */
LDR LR, [LR] /* LR = pxCurrentTCB. */
LDR LR, [LR] /* LR = pxTopOfStack i.e. the address where to store the task context. */
LDR R0, =ulCriticalNesting /* R0 = &( ulCriticalNesting ). */
LDR R0, [R0] /* R0 = ulCriticalNesting. */
STM LR!, { R0 } /* Store ulCriticalNesting. ! increments LR after storing. */
#if ( portENABLE_FPU == 1 )
VMRS R0, FPSCR /* R0 = FPSCR. */
STM LR!, { R0 } /* Store FPSCR. */
VSTM LR!, { D0-D15 } /* Store D0-D15. */
#endif /* ( portENABLE_FPU == 1 ) */
POP { R0 } /* Restore R0 to pre-exception value. */
/* STM (user registers) - In a PL1 mode other than System mode, STM (user
* registers) instruction stores multiple User mode registers to
* consecutive memory locations using an address from a base register. The
* processor reads the base register value normally, using the current mode
* to determine the correct Banked version of the register. This instruction
* cannot writeback to the base register.
*
* The following can be derived from the above description:
* - The macro portSAVE_CONTEXT MUST be called from a PL1 mode other than
* the System mode.
* - Base register LR of the current mode will be used which contains the
* location to store the context.
* - It will store R0-R14 of User mode i.e. pre-exception SP(R13) and LR(R14)
* will be stored. */
STM LR, { R0-R14 }^
ADD LR, LR, #60 /* R0-R14 - Total 155 register, each 4 byte wide. */
POP { R0 } /* Pre-exception PC is in R0. */
MRS R1, SPSR /* R1 = Pre-exception CPSR. */
STM LR!, { R0-R1 } /* Store pre-exception PC and CPSR. */
.endm
/* ----------------------------------------------------------------------------------- */
/* Restore the context of a FreeRTOS Task. */
.macro portRESTORE_CONTEXT
/* Load the pointer to the current task's Task Control Block (TCB). */
LDR LR, =pxCurrentTCB /* LR = &( pxCurrentTCB ). */
LDR LR, [LR] /* LR = pxCurrentTCB. */
ADD R1, LR, #0x4 /* R1 now points to the xMPUSettings in TCB. */
LDR LR, [LR] /* LR = pxTopOfStack i.e. the address where to restore the task context from. */
/* When creating a loop label in a macro it has to be a numeric label.
* for( R5 = portFIRST_CONFIGURABLE_REGION ; R5 <= portNUM_CONFIGURABLE_REGIONS ; R5++ ) */
MOV R5, #portFIRST_CONFIGURABLE_REGION
123:
LDMIA R1!, { R2-R4 } /* R2 = ulRegionSize, R3 = ulRegionAttribute, R4 = ulRegionBaseAddress. */
MCR p15, #0, R5, c6, c2, #0 /* MPU Region Number Register. */
MCR p15, #0, R4, c6, c1, #0 /* MPU Region Base Address Register. */
MCR p15, #0, R3, c6, c1, #4 /* MPU Region Access Control Register. */
MCR p15, #0, R2, c6, c1, #2 /* MPU Region Size and Enable Register. */
ADD R5, R5, #1
CMP R5, #portNUM_CONFIGURABLE_REGIONS
BLE 123b
LDR R1, =ulCriticalNesting /* R1 = &( ulCriticalNesting ). */
LDM LR!, { R2 } /* R2 = Stored ulCriticalNesting. */
STR R2, [R1] /* Restore ulCriticalNesting. */
#if ( portENABLE_FPU == 1 )
LDM LR!, { R1 } /* R1 = Stored FPSCR. */
VMSR FPSCR, R1 /* Restore FPSCR. */
VLDM LR!, { D0-D15 } /* Restore D0-D15. */
#endif /* portENABLE_FPU*/
/* LDM (User registers) - In a PL1 mode other than System mode, LDM (User
* registers) loads multiple User mode registers from consecutive memory
* locations using an address from a base register. The registers loaded
* cannot include the PC. The processor reads the base register value
* normally, using the current mode to determine the correct Banked version
* of the register. This instruction cannot writeback to the base register.
*
* The following can be derived from the above description:
* - The macro portRESTORE_CONTEXT MUST be called from a PL1 mode other than
* the System mode.
* - Base register LR of the current mode will be used which contains the
* location to restore the context from.
* - It will restore R0-R14 of User mode i.e. SP(R13) and LR(R14) of User
* mode will be restored.
*/
LDM LR, { R0-R14 }^
ADD LR, LR, #60 /* R0-R14 - Total 155 register, each 4 byte wide. */
RFE LR /* Restore PC and CPSR from the context. */
.endm
/* ----------------------------------------------------------------------------------- */
/*
* void vPortStartFirstTask( void );
*/
.align 4
.global vPortStartFirstTask
.type vPortStartFirstTask, %function
vPortStartFirstTask:
/* This function is called from System Mode to start the FreeRTOS-Kernel.
* As described in the portRESTORE_CONTEXT macro, portRESTORE_CONTEXT cannot
* be called from the System mode. We, therefore, switch to the Supervisor
* mode before calling portRESTORE_CONTEXT. */
CPS #SVC_MODE
portRESTORE_CONTEXT
/* ----------------------------------------------------------------------------------- */
.align 4
.global FreeRTOS_SVC_Handler
.type FreeRTOS_SVC_Handler, %function
FreeRTOS_SVC_Handler:
PUSH { R11-R12 }
/* ------------------------- Caller Flash Location Check ------------------------- */
LDR R11, =__syscalls_flash_start__
LDR R12, =__syscalls_flash_end__
CMP LR, R11 /* If SVC instruction address is less than __syscalls_flash_start__, exit. */
BLT svcHandlerExit
CMP LR, R12 /* If SVC instruction address is greater than __syscalls_flash_end__, exit. */
BGT svcHandlerExit
/* ---------------------------- Get Caller SVC Number ---------------------------- */
MRS R11, SPSR /* LR = CPSR at the time of SVC. */
TST R11, #0x20 /* Check Thumb bit (5) in CPSR. */
LDRHNE R11, [LR, #-0x2] /* If Thumb, load halfword. */
BICNE R11, R11, #0xFF00 /* And extract immidiate field (i.e. SVC number). */
LDREQ R11, [LR, #-0x4] /* If ARM, load word. */
BICEQ R11, R11, #0xFF000000 /* And extract immidiate field (i.e. SVC number). */
/* --------------------------------- SVC Routing --------------------------------- */
/* If SVC Number < #NUM_SYSTEM_CALLS, go to svcSystemCallEnter. */
CMP R11, #NUM_SYSTEM_CALLS
BLT svcSystemCallEnter
/* If SVC Number == #portSVC_SYSTEM_CALL_EXIT, go to svcSystemCallExit. */
CMP R11, #portSVC_SYSTEM_CALL_EXIT
BEQ svcSystemCallExit
/* If SVC Number == #portSVC_YIELD, go to svcPortYield. */
CMP R11, #portSVC_YIELD
BEQ svcPortYield
svcHandlerExit:
POP { R11-R12 }
MOVS PC, LR /* Copies the SPSR into the CPSR, performing the mode swap. */
svcPortYield:
POP { R11-R12 }
portSAVE_CONTEXT
BL vTaskSwitchContext
portRESTORE_CONTEXT
svcSystemCallExit:
LDR R11, =pxCurrentTCB /* R11 = &( pxCurrentTCB ). */
LDR R11, [R11] /* R11 = pxCurrentTCB. */
ADD R11, R11, #portSYSTEM_CALL_INFO_OFFSET /* R11 now points to xSystemCallStackInfo in TCB. */
/* Restore the user mode SP and LR. */
LDM R11, { R13-R14 }^
AND R12, R12, #0x0 /* R12 = 0. */
STR R12, [R11] /* xSystemCallStackInfo.pulTaskStackPointer = NULL. */
STR R12, [R11, #0x4] /* xSystemCallStackInfo.pulLinkRegisterAtSystemCallEntry = NULL. */
LDMDB R11, { R12 } /* R12 = ulTaskFlags. */
TST R12, #portTASK_IS_PRIVILEGED_FLAG
/* If the task is privileged, we can exit now. */
BNE svcHandlerExit
/* Otherwise, we need to switch back to User mode. */
MRS R12, SPSR
BIC R12, R12, #0x0F
MSR SPSR_cxsf, R12
B svcHandlerExit
svcSystemCallEnter:
LDR R12, =uxSystemCallImplementations /* R12 = uxSystemCallImplementations. */
/* R12 = uxSystemCallImplementations[ R12 + ( R11 << 2 ) ].
* R12 now contains the address of the system call impl function. */
LDR R12, [R12, R11, lsl #2]
/* If R12 == NULL, exit. */
CMP R12, #0x0
BEQ svcHandlerExit
/* It is okay to clobber LR here because we do not need to return to the
* SVC enter location anymore. LR now contains the address of the system
* call impl function. */
MOV LR, R12
LDR R11, =pxCurrentTCB /* R11 = &( pxCurrentTCB ). */
LDR R11, [R11] /* R11 = pxCurrentTCB. */
ADD R11, R11, #portSYSTEM_CALL_INFO_OFFSET /* R11 now points to xSystemCallStackInfo in TCB. */
/* Store User mode SP and LR in xSystemCallStackInfo.pulTaskStackPointer and
* xSystemCallStackInfo.pulLinkRegisterAtSystemCallEntry. */
STM R11, { R13-R14 }^
ADD R11, R11, 0x8
/* Load User mode SP an LR with xSystemCallStackInfo.pulSystemCallStackPointer
* and xSystemCallStackInfo.pulSystemCallExitAddress. */
LDM R11, { R13-R14 }^
/* Change to SYS_MODE for the System Call. */
MRS R12, SPSR
ORR R12, R12, #SYS_MODE
MSR SPSR_cxsf, R12
B svcHandlerExit
/* ----------------------------------------------------------------------------------- */
/*
* void vPortDisableInterrupts( void );
*/
.align 4
.global vPortDisableInterrupts
.type vPortDisableInterrupts, %function
vPortDisableInterrupts:
CPSID I
BX LR
/* ----------------------------------------------------------------------------------- */
/*
* void vPortEnableInterrupts( void );
*/
.align 4
.global vPortEnableInterrupts
.type vPortEnableInterrupts, %function
vPortEnableInterrupts:
CPSIE I
BX LR
/* ----------------------------------------------------------------------------------- */
/*
* void vMPUSetRegion( uint32_t ulRegionNumber,
* uint32_t ulBaseAddress,
* uint32_t ulRegionSize,
* uint32_t ulRegionPermissions );
*
* According to the Procedure Call Standard for the ARM Architecture (AAPCS),
* paramters are passed in the following registers:
* R0 = ulRegionNumber.
* R1 = ulBaseAddress.
* R2 = ulRegionSize.
* R3 = ulRegionPermissions.
*/
.align 4
.global vMPUSetRegion
.type vMPUSetRegion, %function
vMPUSetRegion:
AND R0, R0, #0x0F /* R0 = R0 & 0x0F. Max possible region number is 15. */
MCR p15, #0, R0, c6, c2, #0 /* MPU Region Number Register. */
MCR p15, #0, R1, c6, c1, #0 /* MPU Region Base Address Register. */
MCR p15, #0, R3, c6, c1, #4 /* MPU Region Access Control Register. */
MCR p15, #0, R2, c6, c1, #2 /* MPU Region Size and Enable Register. */
BX LR
/* ----------------------------------------------------------------------------------- */
/*
* void vMPUEnable( void );
*/
.align 4
.global vMPUEnable
.type vMPUEnable, %function
vMPUEnable:
PUSH { R0 }
MRC p15, #0, R0, c1, c0, #0 /* R0 = System Control Register (SCTLR). */
ORR R0, R0, #0x1 /* R0 = R0 | 0x1. Set the M bit in SCTLR. */
DSB
MCR p15, #0, R0, c1, c0, #0 /* SCTLR = R0. */
ISB
POP { R0 }
BX LR
/* ----------------------------------------------------------------------------------- */
/*
* void vMPUDisable( void );
*/
.align 4
.global vMPUDisable
.type vMPUDisable, %function
vMPUDisable:
PUSH { R0 }
MRC p15, #0, R0, c1, c0, #0 /* R0 = System Control Register (SCTLR). */
BIC R0, R0, #1 /* R0 = R0 & ~0x1. Clear the M bit in SCTLR. */
/* Wait for all pending data accesses to complete. */
DSB
MCR p15, #0, R0, c1, c0, #0 /* SCTLR = R0. */
/* Flush the pipeline and prefetch buffer(s) in the processor to ensure that
* all following instructions are fetched from cache or memory. */
ISB
POP { R0 }
BX LR
/* ----------------------------------------------------------------------------------- */
/*
* void vMPUEnableBackgroundRegion( void );
*/
.align 4
.global vMPUEnableBackgroundRegion
.type vMPUEnableBackgroundRegion, %function
vMPUEnableBackgroundRegion:
PUSH { R0 }
MRC p15, #0, R0, c1, c0, #0 /* R0 = System Control Register (SCTLR). */
ORR R0, R0, #0x20000 /* R0 = R0 | 0x20000. Set the BR bit in SCTLR. */
MCR p15, #0, R0, c1, c0, #0 /* SCTLR = R0. */
POP { R0 }
BX LR
/* ----------------------------------------------------------------------------------- */
/*
* void vMPUDisableBackgroundRegion( void );
*/
.align 4
.global vMPUDisableBackgroundRegion
.type vMPUDisableBackgroundRegion, %function
vMPUDisableBackgroundRegion:
PUSH { R0 }
MRC p15, 0, R0, c1, c0, 0 /* R0 = System Control Register (SCTLR). */
BIC R0, R0, #0x20000 /* R0 = R0 & ~0x20000. Clear the BR bit in SCTLR. */
MCR p15, 0, R0, c1, c0, 0 /* SCTLR = R0. */
POP { R0 }
BX LR
/* ----------------------------------------------------------------------------------- */
.align 4
.global FreeRTOS_IRQ_Handler
.type FreeRTOS_IRQ_Handler, %function
FreeRTOS_IRQ_Handler:
SUB LR, LR, #4 /* Return to the interrupted instruction. */
SRSDB SP!, #IRQ_MODE /* Save return state (i.e. SPSR_irq and LR_irq) to the IRQ stack. */
/* Change to supervisor mode to allow reentry. It is necessary to ensure
* that a BL instruction within the interrupt handler code does not
* overwrite LR_irq. */
CPS #SVC_MODE
PUSH { R0-R3, R12 } /* Push AAPCS callee saved registers. */
/* Update interrupt nesting count. */
LDR R0, =ulPortInterruptNesting /* R0 = &( ulPortInterruptNesting ). */
LDR R1, [R0] /* R1 = ulPortInterruptNesting. */
ADD R2, R1, #1 /* R2 = R1 + 1. */
STR R2, [R0] /* Store the updated nesting count. */
/* Call the application provided IRQ handler. */
PUSH { R0-R3, LR }
BL vApplicationIRQHandler
POP { R0-R3, LR }
/* Disable IRQs incase vApplicationIRQHandler enabled them for re-entry. */
CPSID I
DSB
ISB
/* Restore the old interrupt nesting count. R0 holds the address of
* ulPortInterruptNesting and R1 holds original value of
* ulPortInterruptNesting. */
STR R1, [R0]
/* Context swtich is only performed when interrupt nesting count is 0. */
CMP R1, #0
BNE exit_without_switch
/* Check ulPortInterruptNesting to see if the interrupt requested a context
* switch. */
LDR R1, =ulPortYieldRequired /* R1 = &( ulPortYieldRequired ). */
LDR R0, [R1] /* R0 = ulPortYieldRequired. */
/* If ulPortYieldRequired != 0, goto switch_before_exit. */
CMP R0, #0
BNE switch_before_exit
exit_without_switch:
POP { R0-R3, R12 } /* Restore AAPCS callee saved registers. */
CPS #IRQ_MODE
RFE SP!
switch_before_exit:
/* A context swtich is to be performed. Clear ulPortYieldRequired. R1 holds
* the address of ulPortYieldRequired. */
MOV R0, #0
STR R0, [R1]
/* Restore AAPCS callee saved registers, SPSR_irq and LR_irq before saving
* the task context. */
POP { R0-R3, R12 }
CPS #IRQ_MODE
/* The contents of the IRQ stack at this point is the following:
* +----------+
* SP+4 | SPSR_irq |
* +----------+
* SP | LR_irq |
* +----------+
*/
LDMIB SP!, { LR }
MSR SPSR_cxsf, LR
LDMDB SP, { LR }
ADD SP, SP, 0x4
portSAVE_CONTEXT
/* Call the function that selects the new task to execute. */
BLX vTaskSwitchContext
/* Restore the context of, and branch to, the task selected to execute
* next. */
portRESTORE_CONTEXT
/* ----------------------------------------------------------------------------------- */
.end

View file

@ -0,0 +1,522 @@
/*
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2024 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
*
*/
#ifndef PORTMACRO_H
#define PORTMACRO_H
/**
* @brief Functions, Defines, and Structs for use in the ARM_CRx_MPU FreeRTOS-Port
* @file portmacro.h
* @note The settings in this file configure FreeRTOS correctly for the given
* hardware and compiler. These settings should not be altered.
*/
#ifdef __cplusplus
extern "C" {
#endif
/* Include stdint for integer types of specific bit widths. */
#include <stdint.h>
/* ------------------------------ FreeRTOS Config Check ------------------------------ */
#ifndef configSYSTEM_CALL_STACK_SIZE
#error "Define configSYSTEM_CALL_STACK_SIZE to a length, in bytes, " \
"to use when an unprivileged task makes a FreeRTOS Kernel call. "
#endif /* configSYSTEM_CALL_STACK_SIZE */
#if( configUSE_MPU_WRAPPERS_V1 == 1 )
#error This port is usable with MPU wrappers V2 only.
#endif /* configUSE_MPU_WRAPPERS_V1 */
#ifndef configSETUP_TICK_INTERRUPT
#error "configSETUP_TICK_INTERRUPT() must be defined in FreeRTOSConfig.h " \
"to call the function that sets up the tick interrupt."
#endif /* configSETUP_TICK_INTERRUPT */
/* ----------------------------------------------------------------------------------- */
#if( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )
/* Check the configuration. */
#if( configMAX_PRIORITIES > 32 )
#error "configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when " \
"configMAX_PRIORITIES is less than or equal to 32. " \
"It is very rare that a system requires more than 10 to 15 difference " \
"priorities as tasks that share a priority will time slice."
#endif /* ( configMAX_PRIORITIES > 32 ) */
/**
* @brief Mark that a task of the given priority is ready.
*
* @ingroup Scheduler
*
* @param[in] uxPriority Priority of the task that is ready.
* @param[in] uxTopReadyPriority Bitmap of the ready tasks priorities.
*/
#define portRECORD_READY_PRIORITY( uxPriority, uxTopReadyPriority ) \
( uxTopReadyPriority ) |= ( 1UL << ( uxPriority ) )
/**
* @brief Mark that a task of the given priority is no longer ready.
*
* @ingroup Scheduler
*
* @param[in] uxPriority Priority of the task that is no longer ready.
* @param[in] uxTopReadyPriority Bitmap of the ready tasks priorities.
*/
#define portRESET_READY_PRIORITY( uxPriority, uxTopReadyPriority ) \
( uxTopReadyPriority ) &= ~( 1UL << ( uxPriority ) )
/**
* @brief Determine the highest priority ready task's priority.
*
* @ingroup Scheduler
*
* @param[in] uxTopReadyPriority Bitmap of the ready tasks priorities.
* @param[in] uxTopPriority The highest priority ready task's priority.
*/
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxTopReadyPriority ) \
( uxTopPriority ) = ( 31UL - ulPortCountLeadingZeros( ( uxTopReadyPriority ) ) )
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
/* ------------------------------ Port Type Definitions ------------------------------ */
#include "portmacro_asm.h"
/**
* @brief Critical section nesting value.
*
* @ingroup Critical Sections
*
* @note A task exits critical section and enables IRQs when its nesting count
* reaches this value.
*/
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0x0 )
/**
* @brief Bit in Current Program Status Register (CPSR) to indicate that CPU is
* in Thumb State.
*
* @ingroup Task Context
*/
#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 )
/**
* @brief Bitmask to check if an address is of Thumb Code.
*
* @ingroup Task Context
*/
#define portTHUMB_MODE_ADDRESS ( 0x01UL )
/**
* @brief Data type used to represent a stack word.
*
* @ingroup Port Interface Specifications
*/
typedef uint32_t StackType_t;
/**
* @brief Signed data type equal to the data word operating size of the CPU.
*
* @ingroup Port Interface Specifications
*/
typedef int32_t BaseType_t;
/**
* @brief Unsigned data type equal to the data word operating size of the CPU.
*
* @ingroup Port Interface Specifications
*/
typedef uint32_t UBaseType_t;
/**
* @brief Data type used for the FreeRTOS Tick Counter.
*
* @note Using 32-bit tick type on a 32-bit architecture ensures that reads of
* the tick count do not need to be guarded with a critical section.
*/
typedef uint32_t TickType_t;
/**
* @brief Marks the direction the stack grows on the targeted CPU.
*
* @ingroup Port Interface Specifications
*/
#define portSTACK_GROWTH ( -1 )
/**
* @brief Specifies stack pointer alignment requirements of the target CPU.
*
* @ingroup Port Interface Specifications
*/
#define portBYTE_ALIGNMENT 8U
/**
* @brief Task function prototype macro as described on FreeRTOS.org.
*
* @ingroup Port Interface Specifications
*
* @note This is not required for this port but included in case common demo
* code uses it.
*/
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) \
void vFunction( void * pvParameters )
/**
* @brief Task function prototype macro as described on FreeRTOS.org.
*
* @ingroup Port Interface Specifications
*
* @note This is not required for this port but included in case common demo
* code uses it.
*/
#define portTASK_FUNCTION( vFunction, pvParameters ) \
void vFunction( void * pvParameters )
/**
* @brief The no-op ARM assembly instruction.
*
* @ingroup Port Interface Specifications
*/
#define portNOP() __asm volatile( "NOP" )
/**
* @brief The inline GCC label.
*
* @ingroup Port Interface Specifications
*/
#define portINLINE __inline
/**
* @brief The memory access synchronization barrier.
*
* @ingroup Port Interface Specifications
*/
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
/**
* @brief Defines if the tick count can be accessed atomically.
*
* @ingroup System Clock
*/
#define portTICK_TYPE_IS_ATOMIC 1
/**
* @brief The number of miliseconds between system ticks.
*
* @ingroup System Clock
*/
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000UL / configTICK_RATE_HZ )
/**
* @brief The largest possible delay value for any FreeRTOS API.
*
* @ingroup System Clock
*/
#define portMAX_DELAY ( TickType_t ) 0xFFFFFFFFUL
/* ----------------------------- Port Assembly Functions ----------------------------- */
/**
* @brief FreeRTOS Supervisor Call (SVC) Handler.
*
* @ingroup Scheduler
*/
void FreeRTOS_SVC_Handler( void );
/**
* @brief FreeRTOS Interrupt Handler.
*
* @ingroup Scheduler
*/
void FreeRTOS_IRQ_Handler( void );
/**
* @brief Yield the CPU.
*
* @ingroup Scheduler
*/
void vPortYield( void );
#define portYIELD() vPortYield()
/**
* @brief Enable interrupts.
*
* @ingroup Interrupt Management
*/
void vPortEnableInterrupts( void );
#define portENABLE_INTERRUPTS() vPortEnableInterrupts()
/**
* @brief Disable interrupts.
*
* @ingroup Interrupt Management
*/
void vPortDisableInterrupts( void );
#define portDISABLE_INTERRUPTS() vPortDisableInterrupts()
/**
* @brief Exit from a FreeRTO System Call.
*
* @ingroup Port Privilege
*/
void vPortSystemCallExit( void );
/**
* @brief Start executing first task.
*
* @ingroup Scheduler
*/
void vPortStartFirstTask( void );
/**
* @brief Enable the onboard MPU.
*
* @ingroup MPU Control
*/
void vMPUEnable( void );
/**
* @brief Disable the onboard MPU.
*
* @ingroup MPU Control
*/
void vMPUDisable( void );
/**
* @brief Enable the MPU Background Region.
*
* @ingroup MPU Control
*/
void vMPUEnableBackgroundRegion( void );
/**
* @brief Disable the MPU Background Region.
*
* @ingroup MPU Control
*/
void vMPUDisableBackgroundRegion( void );
/**
* @brief Set permissions for an MPU Region.
*
* @ingroup MPU Control
*
* @param[in] ulRegionNumber The MPU Region Number to set permissions for.
* @param[in] ulBaseAddress The base address of the MPU Region.
* @param[in] ulRegionSize The size of the MPU Region in bytes.
* @param[in] ulRegionPermissions The permissions associated with the MPU Region.
*
* @note This is an internal function and assumes that the inputs to this
* function are checked before calling this function.
*/
void vMPUSetRegion( uint32_t ulRegionNumber,
uint32_t ulBaseAddress,
uint32_t ulRegionSize,
uint32_t ulRegionPermissions );
/* ------------------------------- Port.c Declarations ------------------------------- */
/**
* @brief Enter critical section.
*
* @ingroup Critical Section
*/
void vPortEnterCritical( void );
#define portENTER_CRITICAL() vPortEnterCritical()
/**
* @brief Exit critical section.
*
* @ingroup Critical Section
*/
void vPortExitCritical( void );
#define portEXIT_CRITICAL() vPortExitCritical()
/**
* @brief Checks whether or not the processor is privileged.
*
* @ingroup Port Privilege
*
* @note The processor privilege level is determined by checking the
* mode bits [4:0] of the Current Program Status Register (CPSR).
*
* @return pdTRUE, if the processer is privileged, pdFALSE otherwise.
*/
BaseType_t xPortIsPrivileged( void );
#define portIS_PRIVILEGED() xPortIsPrivileged()
/**
* @brief Checks whether or not a task is privileged.
*
* @ingroup Port Privilege
*
* @note A task's privilege level is associated with the task and is different from
* the processor's privilege level returned by xPortIsPrivileged. For example,
* the processor is privileged when an unprivileged task executes a system call.
*
* @return pdTRUE if the task is privileged, pdFALSE otherwise.
*/
BaseType_t xPortIsTaskPrivileged( void );
#define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged()
/**
* @brief Default return address for tasks.
*
* @ingroup Task Context
*
* @note This function is used as the default return address for tasks if
* configTASK_RETURN_ADDRESS is not defined in FreeRTOSConfig.h.
*/
void prvTaskExitError( void );
#ifdef configTASK_RETURN_ADDRESS
#define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS
#else
#define portTASK_RETURN_ADDRESS prvTaskExitError
#endif /* configTASK_RETURN_ADDRESS */
/**
* @brief Returns the number of leading zeros in a 32 bit variable.
*
* @param[in] ulBitmap 32-Bit number to count leading zeros in.
*
* @return The number of leading zeros in ulBitmap.
*/
UBaseType_t ulPortCountLeadingZeros( UBaseType_t ulBitmap );
/**
* @brief End the FreeRTOS scheduler.
*
* Not implemented on this port.
*
* @ingroup Scheduler
*/
void vPortEndScheduler( void );
/* --------------------------------- MPU Definitions --------------------------------- */
/**
* @brief Mark that this port utilizes the onboard ARM MPU.
*
* @ingroup MPU Control
*/
#define portUSING_MPU_WRAPPERS 1
/**
* @brief Used to mark if a task should be created as a privileged task.
*
* @ingroup Task Context
* @ingroup MPU Control
*
* @note A privileged task is created by performing a bitwise OR of this value and
* the task priority. For example, to create a privileged task at priority 2, the
* uxPriority parameter should be set to ( 2 | portPRIVILEGE_BIT ).
*/
#define portPRIVILEGE_BIT ( 0x80000000UL )
/**
* @brief Size of an Access Control List (ACL) entry in bits.
*/
#define portACL_ENTRY_SIZE_BITS ( 32UL )
/**
* @brief Structure to hold the MPU Register Values.
*
* @struct xMPU_REGION_REGISTERS
*
* @ingroup MPU Control
*
* @note The ordering of this struct MUST be in sync with the ordering in
* portRESTORE_CONTEXT.
*/
typedef struct MPU_REGION_REGISTERS
{
uint32_t ulRegionSize; /* Information for MPU Region Size and Enable Register. */
uint32_t ulRegionAttribute; /* Information for MPU Region Access Control Register. */
uint32_t ulRegionBaseAddress; /* Information for MPU Region Base Address Register. */
} xMPU_REGION_REGISTERS;
/**
* @brief Structure to hold per-task System Call Stack information.
*
* @struct xSYSTEM_CALL_STACK_INFO
*
* @ingroup Port Privilege
*
* @note The ordering of this structure MUST be in sync with the assembly code
* of the port.
*/
typedef struct SYSTEM_CALL_STACK_INFO
{
uint32_t * pulTaskStackPointer; /**< Stack Pointer of the task when it made a FreeRTOS System Call. */
uint32_t * pulLinkRegisterAtSystemCallEntry; /**< Link Register of the task when it made a FreeRTOS System Call. */
uint32_t * pulSystemCallStackPointer; /**< Stack Pointer to use for executing a FreeRTOS System Call. */
uint32_t * pulSystemCallExitAddress; /**< System call exit address. */
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; /**< Buffer to be used as stack when performing a FreeRTOS System Call. */
} xSYSTEM_CALL_STACK_INFO;
/**
* @brief Per-Task MPU settings structure stored in the TCB.
* @struct xMPU_SETTINGS
*
* @ingroup MPU Control
* @ingroup Task Context
* @ingroup Port Privilege
*
* @note The ordering of this structure MUST be in sync with the assembly code
* of the port.
*/
typedef struct MPU_SETTINGS
{
xMPU_REGION_REGISTERS xRegion[ portTOTAL_NUM_REGIONS_IN_TCB ];
uint32_t ulTaskFlags;
xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo;
uint32_t ulContext[ CONTEXT_SIZE ]; /**< Buffer used to store task context. */
#if( configENABLE_ACCESS_CONTROL_LIST == 1 )
uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE
/ portACL_ENTRY_SIZE_BITS )
+ 1UL ];
#endif
} xMPU_SETTINGS;
#ifdef __cplusplus
} /* extern C */
#endif
#endif /* PORTMACRO_H */

View file

@ -0,0 +1,279 @@
/*
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2024 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
*
*/
#ifndef PORTMACRO_ASM_H
#define PORTMACRO_ASM_H
#ifdef __cplusplus
extern "C" {
#endif
#include "FreeRTOSConfig.h"
#ifndef configTOTAL_MPU_REGIONS
#error "Set configTOTAL_MPU_REGIONS to the humber of MPU regions in FreeRTOSConfig.h"
#elif( configTOTAL_MPU_REGIONS == 12 )
#define portMPU_TOTAL_REGIONS ( 12UL )
#elif( configTOTAL_MPU_REGIONS == 16 )
#define portMPU_TOTAL_REGIONS ( 16UL )
#else
#error "Set configTOTAL_MPU_REGIONS to the number of MPU regions in FreeRTOSConfig.h"
#endif /* configTOTAL_MPU_REGIONS */
/*
* The application write can disable Floating Point Unit (FPU) support by
* setting configENABLE_FPU to 0. Floating point context stored in TCB
* comprises of 32 floating point registers (D0-D31) and FPSCR register.
* Disabling FPU, therefore, reduces the per-task RAM usage by
* ( 32 + 1 ) * 4 = 132 bytes per task.
*
* BE CAREFUL DISABLING THIS: Certain standard library APIs try to optimize
* themselves by using the floating point registers. If the FPU support is
* disabled, the use of such APIs may result in memory corruption.
*/
#ifndef configENABLE_FPU
#define configENABLE_FPU 1
#endif /* configENABLE_FPU */
#define portENABLE_FPU configENABLE_FPU
/* On the ArmV7-R Architecture the Operating mode of the Processor is set
* using the Current Program Status Register (CPSR) Mode bits, [4:0]. The only
* unprivileged mode is User Mode.
*
* Additional information about the Processor Modes can be found here:
* https://developer.arm.com/documentation/ddi0406/cb/System-Level-Architecture/The-System-Level-Programmers--Model/ARM-processor-modes-and-ARM-core-registers/ARM-processor-modes?lang=en
*
*/
/**
* @brief CPSR bits for various processor modes.
*
* @ingroup Port Privilege
*/
#define USER_MODE 0x10U
#define FIQ_MODE 0x11U
#define IRQ_MODE 0x12U
#define SVC_MODE 0x13U
#define MON_MODE 0x16U
#define ABT_MODE 0x17U
#define HYP_MODE 0x1AU
#define UND_MODE 0x1BU
#define SYS_MODE 0x1FU
/**
* @brief Flag used to mark that a FreeRTOS Task is privileged.
*
* @ingroup Port Privilege
*/
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
/**
* @brief SVC numbers for various scheduler operations.
*
* @ingroup Scheduler
*
* @note These value must not be used in mpu_syscall_numbers.h.
*/
#define portSVC_YIELD 0x0100U
#define portSVC_SYSTEM_CALL_EXIT 0x0104U
/**
* @brief Macros required to manipulate MPU.
*
* Further information about MPU can be found in Arm's documentation
* https://developer.arm.com/documentation/ddi0363/g/System-Control/Register-descriptions/c6--MPU-memory-region-programming-registers
*
*/
/* MPU sub-region disable settings. This information is encoded in the MPU
* Region Size and Enable Register. */
#define portMPU_SUBREGION_0_DISABLE ( 0x1UL << 8UL )
#define portMPU_SUBREGION_1_DISABLE ( 0x1UL << 9UL )
#define portMPU_SUBREGION_2_DISABLE ( 0x1UL << 10UL )
#define portMPU_SUBREGION_3_DISABLE ( 0x1UL << 11UL )
#define portMPU_SUBREGION_4_DISABLE ( 0x1UL << 12UL )
#define portMPU_SUBREGION_5_DISABLE ( 0x1UL << 13UL )
#define portMPU_SUBREGION_6_DISABLE ( 0x1UL << 14UL )
#define portMPU_SUBREGION_7_DISABLE ( 0x1UL << 15UL )
/* Default MPU regions. */
#define portFIRST_CONFIGURABLE_REGION ( 0 )
#define portLAST_CONFIGURABLE_REGION ( portMPU_TOTAL_REGIONS - 5UL )
#define portSTACK_REGION ( portMPU_TOTAL_REGIONS - 4UL )
#define portUNPRIVILEGED_FLASH_REGION ( portMPU_TOTAL_REGIONS - 3UL )
#define portPRIVILEGED_FLASH_REGION ( portMPU_TOTAL_REGIONS - 2UL )
#define portPRIVILEGED_RAM_REGION ( portMPU_TOTAL_REGIONS - 1UL )
#define portNUM_CONFIGURABLE_REGIONS \
( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1UL )
/* Plus one to make space for the stack region. */
#define portTOTAL_NUM_REGIONS_IN_TCB ( portNUM_CONFIGURABLE_REGIONS + 1UL )
/* MPU region sizes. This information is encoded in the MPU Region Size and
* Enable Register. */
#define portMPU_REGION_SIZE_32B ( 0x04UL << 1UL )
#define portMPU_REGION_SIZE_64B ( 0x05UL << 1UL )
#define portMPU_REGION_SIZE_128B ( 0x06UL << 1UL )
#define portMPU_REGION_SIZE_256B ( 0x07UL << 1UL )
#define portMPU_REGION_SIZE_512B ( 0x08UL << 1UL )
#define portMPU_REGION_SIZE_1KB ( 0x09UL << 1UL )
#define portMPU_REGION_SIZE_2KB ( 0x0AUL << 1UL )
#define portMPU_REGION_SIZE_4KB ( 0x0BUL << 1UL )
#define portMPU_REGION_SIZE_8KB ( 0x0CUL << 1UL )
#define portMPU_REGION_SIZE_16KB ( 0x0DUL << 1UL )
#define portMPU_REGION_SIZE_32KB ( 0x0EUL << 1UL )
#define portMPU_REGION_SIZE_64KB ( 0x0FUL << 1UL )
#define portMPU_REGION_SIZE_128KB ( 0x10UL << 1UL )
#define portMPU_REGION_SIZE_256KB ( 0x11UL << 1UL )
#define portMPU_REGION_SIZE_512KB ( 0x12UL << 1UL )
#define portMPU_REGION_SIZE_1MB ( 0x13UL << 1UL )
#define portMPU_REGION_SIZE_2MB ( 0x14UL << 1UL )
#define portMPU_REGION_SIZE_4MB ( 0x15UL << 1UL )
#define portMPU_REGION_SIZE_8MB ( 0x16UL << 1UL )
#define portMPU_REGION_SIZE_16MB ( 0x17UL << 1UL )
#define portMPU_REGION_SIZE_32MB ( 0x18UL << 1UL )
#define portMPU_REGION_SIZE_64MB ( 0x19UL << 1UL )
#define portMPU_REGION_SIZE_128MB ( 0x1AUL << 1UL )
#define portMPU_REGION_SIZE_256MB ( 0x1BUL << 1UL )
#define portMPU_REGION_SIZE_512MB ( 0x1CUL << 1UL )
#define portMPU_REGION_SIZE_1GB ( 0x1DUL << 1UL )
#define portMPU_REGION_SIZE_2GB ( 0x1EUL << 1UL )
#define portMPU_REGION_SIZE_4GB ( 0x1FUL << 1UL )
/* MPU memory types. This information is encoded in the TEX, S, C and B bits
* of the MPU Region Access Control Register. */
#define portMPU_REGION_STRONGLY_ORDERED_SHAREABLE ( 0x00UL ) /* TEX=000, S=NA, C=0, B=0. */
#define portMPU_REGION_DEVICE_SHAREABLE ( 0x01UL ) /* TEX=000, S=NA, C=0, B=1. */
#define portMPU_REGION_NORMAL_OIWTNOWA_NONSHARED ( 0x02UL ) /* TEX=000, S=0, C=1, B=0. */
#define portMPU_REGION_NORMAL_OIWTNOWA_SHARED ( 0x06UL ) /* TEX=000, S=1, C=1, B=0. */
#define portMPU_REGION_NORMAL_OIWBNOWA_NONSHARED ( 0x03UL ) /* TEX=000, S=0, C=1, B=1. */
#define portMPU_REGION_NORMAL_OIWBNOWA_SHARED ( 0x07UL ) /* TEX=000, S=1, C=1, B=1. */
#define portMPU_REGION_NORMAL_OINC_NONSHARED ( 0x08UL ) /* TEX=001, S=0, C=0, B=0. */
#define portMPU_REGION_NORMAL_OINC_SHARED ( 0x0CUL ) /* TEX=001, S=1, C=0, B=0. */
#define portMPU_REGION_NORMAL_OIWBWA_NONSHARED ( 0x0BUL ) /* TEX=001, S=0, C=1, B=1. */
#define portMPU_REGION_NORMAL_OIWBWA_SHARED ( 0x0FUL ) /* TEX=001, S=1, C=1, B=1. */
#define portMPU_REGION_DEVICE_NONSHAREABLE ( 0x10UL ) /* TEX=010, S=NA, C=0, B=0. */
/* MPU access permissions. This information is encoded in the XN and AP bits of
* the MPU Region Access Control Register. */
#define portMPU_REGION_AP_BITMASK ( 0x07UL << 8UL )
#define portMPU_REGION_XN_BITMASK ( 0x01UL << 12UL )
#define portMPU_REGION_PRIV_NA_USER_NA ( 0x00UL << 8UL )
#define portMPU_REGION_PRIV_NA_USER_NA_EXEC ( portMPU_REGION_PRIV_NA_USER_NA ) /* Priv: X, Unpriv: X. */
#define portMPU_REGION_PRIV_NA_USER_NA_NOEXEC ( portMPU_REGION_PRIV_NA_USER_NA | \
portMPU_REGION_XN_BITMASK ) /* Priv: No Access, Unpriv: No Access. */
#define portMPU_REGION_PRIV_RW_USER_NA ( 0x01UL << 8UL )
#define portMPU_REGION_PRIV_RW_USER_NA_EXEC ( portMPU_REGION_PRIV_RW_USER_NA ) /* Priv: RWX, Unpriv: X. */
#define portMPU_REGION_PRIV_RW_USER_NA_NOEXEC ( portMPU_REGION_PRIV_RW_USER_NA | \
portMPU_REGION_XN_BITMASK ) /* Priv: RW, Unpriv: No access. */
#define portMPU_REGION_PRIV_RW_USER_RO ( 0x02UL << 8UL )
#define portMPU_REGION_PRIV_RW_USER_RO_EXEC ( portMPU_REGION_PRIV_RW_USER_RO ) /* Priv: RWX, Unpriv: RX. */
#define portMPU_REGION_PRIV_RW_USER_RO_NOEXEC ( portMPU_REGION_PRIV_RW_USER_RO | \
portMPU_REGION_XN_BITMASK ) /* Priv: RW, Unpriv: R. */
#define portMPU_REGION_PRIV_RW_USER_RW ( 0x03UL << 8UL )
#define portMPU_REGION_PRIV_RW_USER_RW_EXEC ( portMPU_REGION_PRIV_RW_USER_RW ) /* Priv: RWX, Unpriv: RWX. */
#define portMPU_REGION_PRIV_RW_USER_RW_NOEXEC ( portMPU_REGION_PRIV_RW_USER_RW | \
portMPU_REGION_XN_BITMASK ) /* Priv: RW, Unpriv: RW. */
#define portMPU_REGION_PRIV_RO_USER_NA ( 0x05UL << 8UL )
#define portMPU_REGION_PRIV_RO_USER_NA_EXEC ( portMPU_REGION_PRIV_RO_USER_NA ) /* Priv: RX, Unpriv: X. */
#define portMPU_REGION_PRIV_RO_USER_NA_NOEXEC ( portMPU_REGION_PRIV_RO_USER_NA | \
portMPU_REGION_XN_BITMASK ) /* Priv: R, Unpriv: No access. */
#define portMPU_REGION_PRIV_RO_USER_RO ( 0x06UL << 8UL )
#define portMPU_REGION_PRIV_RO_USER_RO_EXEC ( portMPU_REGION_PRIV_RO_USER_RO ) /* Priv: RX, Unpriv: RX. */
#define portMPU_REGION_PRIV_RO_USER_RO_NOEXEC ( portMPU_REGION_PRIV_RO_USER_RO | \
portMPU_REGION_XN_BITMASK ) /* Priv: R, Unpriv: R. */
/* MPU region management. */
#define portMPU_REGION_EXECUTE_NEVER ( 0x01UL << 12UL )
#define portMPU_REGION_ENABLE ( 0x01UL )
/**
* @brief The size (in words) of a task context.
*
* An array of this size is allocated in TCB where a task's context is saved
* when it is switched out.
*
* Information about Floating Point Unit (FPU):
* https://developer.arm.com/documentation/den0042/a/Floating-Point
*
* Additional information related to the Cortex R4-F's FPU Implementation:
* https://developer.arm.com/documentation/ddi0363/e/fpu-programmer-s-model
*
* Additional information related to the Cortex R5-F's FPU Implementation:
* https://developer.arm.com/documentation/ddi0460/d/FPU-Programmers-Model
*
* Additional information related to the ArmV7-R CPSR:
* https://developer.arm.com/documentation/ddi0406/cb/Application-Level-Architecture/Application-Level-Programmers--Model/The-Application-Program-Status-Register--APSR-?lang=en
*
* Additional information related to the GPRs:
* https://developer.arm.com/documentation/ddi0406/cb/System-Level-Architecture/The-System-Level-Programmers--Model/ARM-processor-modes-and-ARM-core-registers/ARM-core-registers?lang=en
*
*/
#if( portENABLE_FPU == 1 )
/*
* +-------------------+-------+----------+--------+----------+----------+----------+------+
* | ulCriticalNesting | FPSCR | S0-S31 | R0-R12 | SP (R13) | LR (R14) | PC (R15) | CPSR |
* +-------------------+-------+----------+--------+----------+----------+----------+------+
*
* <------------------><------><---------><--------><---------><--------><----------><----->
* 1 1 32 13 1 1 1 1
*/
#define CONTEXT_SIZE 51U
#else
/*
* +-------------------+--------+----------+----------+----------+------+
* | ulCriticalNesting | R0-R12 | SP (R13) | LR (R14) | PC (R15) | CPSR |
* +-------------------+--------+----------+----------+----------+------+
*
* <------------------><--------><---------><--------><----------><----->
* 1 13 1 1 1 1
*/
#define CONTEXT_SIZE 18U
#endif /* CONTEXT_SIZE */
/**
* @brief Offset of xSystemCallStackInfo from the start of a TCB.
*/
#define portSYSTEM_CALL_INFO_OFFSET \
( ( 1U /* pxTopOfStack. */ + \
( portTOTAL_NUM_REGIONS_IN_TCB * 3U ) + \
1U /* ulTaskFlags. */ \
) * 4U )
#ifdef __cplusplus
} /* extern C */
#endif
#endif /* PORTMACRO_ASM_H */

View file

@ -64,7 +64,7 @@
#endif /* configAPPLICATION_ALLOCATED_HEAP */ #endif /* configAPPLICATION_ALLOCATED_HEAP */
/* Index into the ucHeap array. */ /* Index into the ucHeap array. */
static size_t xNextFreeByte = ( size_t ) 0; static size_t xNextFreeByte = ( size_t ) 0U;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -150,3 +150,16 @@ size_t xPortGetFreeHeapSize( void )
{ {
return( configADJUSTED_HEAP_SIZE - xNextFreeByte ); return( configADJUSTED_HEAP_SIZE - xNextFreeByte );
} }
/*-----------------------------------------------------------*/
/*
* Reset the state in this file. This state is normally initialized at start up.
* This function must be called by the application before restarting the
* scheduler.
*/
void vPortHeapResetState( void )
{
xNextFreeByte = ( size_t ) 0U;
}
/*-----------------------------------------------------------*/

View file

@ -113,6 +113,9 @@ PRIVILEGED_DATA static BlockLink_t xStart, xEnd;
* fragmentation. */ * fragmentation. */
PRIVILEGED_DATA static size_t xFreeBytesRemaining = configADJUSTED_HEAP_SIZE; PRIVILEGED_DATA static size_t xFreeBytesRemaining = configADJUSTED_HEAP_SIZE;
/* Indicates whether the heap has been initialised or not. */
PRIVILEGED_DATA static BaseType_t xHeapHasBeenInitialised = pdFALSE;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
@ -155,7 +158,6 @@ void * pvPortMalloc( size_t xWantedSize )
BlockLink_t * pxBlock; BlockLink_t * pxBlock;
BlockLink_t * pxPreviousBlock; BlockLink_t * pxPreviousBlock;
BlockLink_t * pxNewBlockLink; BlockLink_t * pxNewBlockLink;
PRIVILEGED_DATA static BaseType_t xHeapHasBeenInitialised = pdFALSE;
void * pvReturn = NULL; void * pvReturn = NULL;
size_t xAdditionalRequiredSize; size_t xAdditionalRequiredSize;
@ -384,3 +386,16 @@ static void prvHeapInit( void ) /* PRIVILEGED_FUNCTION */
pxFirstFreeBlock->pxNextFreeBlock = &xEnd; pxFirstFreeBlock->pxNextFreeBlock = &xEnd;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/*
* Reset the state in this file. This state is normally initialized at start up.
* This function must be called by the application before restarting the
* scheduler.
*/
void vPortHeapResetState( void )
{
xFreeBytesRemaining = configADJUSTED_HEAP_SIZE;
xHeapHasBeenInitialised = pdFALSE;
}
/*-----------------------------------------------------------*/

View file

@ -92,3 +92,15 @@ void vPortFree( void * pv )
( void ) xTaskResumeAll(); ( void ) xTaskResumeAll();
} }
} }
/*-----------------------------------------------------------*/
/*
* Reset the state in this file. This state is normally initialized at start up.
* This function must be called by the application before restarting the
* scheduler.
*/
void vPortHeapResetState( void )
{
/* No state needs to be re-initialised in heap_3. */
}
/*-----------------------------------------------------------*/

View file

@ -163,10 +163,10 @@ PRIVILEGED_DATA static BlockLink_t * pxEnd = NULL;
/* Keeps track of the number of calls to allocate and free memory as well as the /* Keeps track of the number of calls to allocate and free memory as well as the
* number of free bytes remaining, but says nothing about fragmentation. */ * number of free bytes remaining, but says nothing about fragmentation. */
PRIVILEGED_DATA static size_t xFreeBytesRemaining = 0U; PRIVILEGED_DATA static size_t xFreeBytesRemaining = ( size_t ) 0U;
PRIVILEGED_DATA static size_t xMinimumEverFreeBytesRemaining = 0U; PRIVILEGED_DATA static size_t xMinimumEverFreeBytesRemaining = ( size_t ) 0U;
PRIVILEGED_DATA static size_t xNumberOfSuccessfulAllocations = 0; PRIVILEGED_DATA static size_t xNumberOfSuccessfulAllocations = ( size_t ) 0U;
PRIVILEGED_DATA static size_t xNumberOfSuccessfulFrees = 0; PRIVILEGED_DATA static size_t xNumberOfSuccessfulFrees = ( size_t ) 0U;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -608,3 +608,19 @@ void vPortGetHeapStats( HeapStats_t * pxHeapStats )
taskEXIT_CRITICAL(); taskEXIT_CRITICAL();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/*
* Reset the state in this file. This state is normally initialized at start up.
* This function must be called by the application before restarting the
* scheduler.
*/
void vPortHeapResetState( void )
{
pxEnd = NULL;
xFreeBytesRemaining = ( size_t ) 0U;
xMinimumEverFreeBytesRemaining = ( size_t ) 0U;
xNumberOfSuccessfulAllocations = ( size_t ) 0U;
xNumberOfSuccessfulFrees = ( size_t ) 0U;
}
/*-----------------------------------------------------------*/

View file

@ -187,10 +187,10 @@ PRIVILEGED_DATA static BlockLink_t * pxEnd = NULL;
/* Keeps track of the number of calls to allocate and free memory as well as the /* Keeps track of the number of calls to allocate and free memory as well as the
* number of free bytes remaining, but says nothing about fragmentation. */ * number of free bytes remaining, but says nothing about fragmentation. */
PRIVILEGED_DATA static size_t xFreeBytesRemaining = 0U; PRIVILEGED_DATA static size_t xFreeBytesRemaining = ( size_t ) 0U;
PRIVILEGED_DATA static size_t xMinimumEverFreeBytesRemaining = 0U; PRIVILEGED_DATA static size_t xMinimumEverFreeBytesRemaining = ( size_t ) 0U;
PRIVILEGED_DATA static size_t xNumberOfSuccessfulAllocations = 0; PRIVILEGED_DATA static size_t xNumberOfSuccessfulAllocations = ( size_t ) 0U;
PRIVILEGED_DATA static size_t xNumberOfSuccessfulFrees = 0; PRIVILEGED_DATA static size_t xNumberOfSuccessfulFrees = ( size_t ) 0U;
#if ( configENABLE_HEAP_PROTECTOR == 1 ) #if ( configENABLE_HEAP_PROTECTOR == 1 )
@ -707,3 +707,24 @@ void vPortGetHeapStats( HeapStats_t * pxHeapStats )
taskEXIT_CRITICAL(); taskEXIT_CRITICAL();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/*
* Reset the state in this file. This state is normally initialized at start up.
* This function must be called by the application before restarting the
* scheduler.
*/
void vPortHeapResetState( void )
{
pxEnd = NULL;
xFreeBytesRemaining = ( size_t ) 0U;
xMinimumEverFreeBytesRemaining = ( size_t ) 0U;
xNumberOfSuccessfulAllocations = ( size_t ) 0U;
xNumberOfSuccessfulFrees = ( size_t ) 0U;
#if ( configENABLE_HEAP_PROTECTOR == 1 )
pucHeapHighAddress = NULL;
pucHeapLowAddress = NULL;
#endif /* #if ( configENABLE_HEAP_PROTECTOR == 1 ) */
}
/*-----------------------------------------------------------*/

View file

@ -64,7 +64,7 @@ typedef long BaseType_t;
typedef unsigned long UBaseType_t; typedef unsigned long UBaseType_t;
typedef unsigned long TickType_t; typedef unsigned long TickType_t;
#define portMAX_DELAY ( TickType_t ) ULONG_MAX #define portMAX_DELAY ( ( TickType_t ) ULONG_MAX )
#define portTICK_TYPE_IS_ATOMIC 1 #define portTICK_TYPE_IS_ATOMIC 1

View file

@ -19,6 +19,10 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
TaskFunction_t pxCode, TaskFunction_t pxCode,
void * pvParameters ) void * pvParameters )
{ {
( void ) pxTopOfStack;
( void ) pvParameters;
( void ) * pxCode;
return NULL; return NULL;
} }

66
tasks.c
View file

@ -1325,7 +1325,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
#if ( ( configNUMBER_OF_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) ) #if ( ( configNUMBER_OF_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) )
{ {
/* Set the task's affinity before scheduling it. */ /* Set the task's affinity before scheduling it. */
pxNewTCB->uxCoreAffinityMask = tskNO_AFFINITY; pxNewTCB->uxCoreAffinityMask = configTASK_DEFAULT_CORE_AFFINITY;
} }
#endif #endif
@ -1442,7 +1442,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
#if ( ( configNUMBER_OF_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) ) #if ( ( configNUMBER_OF_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) )
{ {
/* Set the task's affinity before scheduling it. */ /* Set the task's affinity before scheduling it. */
pxNewTCB->uxCoreAffinityMask = tskNO_AFFINITY; pxNewTCB->uxCoreAffinityMask = configTASK_DEFAULT_CORE_AFFINITY;
} }
#endif #endif
@ -1560,7 +1560,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
#if ( ( configNUMBER_OF_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) ) #if ( ( configNUMBER_OF_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) )
{ {
/* Set the task's affinity before scheduling it. */ /* Set the task's affinity before scheduling it. */
pxNewTCB->uxCoreAffinityMask = tskNO_AFFINITY; pxNewTCB->uxCoreAffinityMask = configTASK_DEFAULT_CORE_AFFINITY;
} }
#endif /* #if ( ( configNUMBER_OF_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) ) */ #endif /* #if ( ( configNUMBER_OF_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) ) */
@ -1733,7 +1733,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
#if ( ( configNUMBER_OF_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) ) #if ( ( configNUMBER_OF_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) )
{ {
/* Set the task's affinity before scheduling it. */ /* Set the task's affinity before scheduling it. */
pxNewTCB->uxCoreAffinityMask = tskNO_AFFINITY; pxNewTCB->uxCoreAffinityMask = configTASK_DEFAULT_CORE_AFFINITY;
} }
#endif #endif
@ -8694,3 +8694,61 @@ static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait,
#endif /* #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configKERNEL_PROVIDED_STATIC_MEMORY == 1 ) && ( portUSING_MPU_WRAPPERS == 0 ) ) */ #endif /* #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configKERNEL_PROVIDED_STATIC_MEMORY == 1 ) && ( portUSING_MPU_WRAPPERS == 0 ) ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/*
* Reset the state in this file. This state is normally initialized at start up.
* This function must be called by the application before restarting the
* scheduler.
*/
void vTaskResetState( void )
{
BaseType_t xCoreID;
/* Task control block. */
#if ( configNUMBER_OF_CORES == 1 )
{
pxCurrentTCB = NULL;
}
#endif /* #if ( configNUMBER_OF_CORES == 1 ) */
#if ( INCLUDE_vTaskDelete == 1 )
{
uxDeletedTasksWaitingCleanUp = ( UBaseType_t ) 0U;
}
#endif /* #if ( INCLUDE_vTaskDelete == 1 ) */
#if ( configUSE_POSIX_ERRNO == 1 )
{
FreeRTOS_errno = 0;
}
#endif /* #if ( configUSE_POSIX_ERRNO == 1 ) */
/* Other file private variables. */
uxCurrentNumberOfTasks = ( UBaseType_t ) 0U;
xTickCount = ( TickType_t ) configINITIAL_TICK_COUNT;
uxTopReadyPriority = tskIDLE_PRIORITY;
xSchedulerRunning = pdFALSE;
xPendedTicks = ( TickType_t ) 0U;
for( xCoreID = 0; xCoreID < configNUMBER_OF_CORES; xCoreID++ )
{
xYieldPendings[ xCoreID ] = pdFALSE;
}
xNumOfOverflows = ( BaseType_t ) 0;
uxTaskNumber = ( UBaseType_t ) 0U;
xNextTaskUnblockTime = ( TickType_t ) 0U;
uxSchedulerSuspended = ( UBaseType_t ) 0U;
#if ( configGENERATE_RUN_TIME_STATS == 1 )
{
for( xCoreID = 0; xCoreID < configNUMBER_OF_CORES; xCoreID++ )
{
ulTaskSwitchedInTime[ xCoreID ] = 0U;
ulTotalRunTime[ xCoreID ] = 0U;
}
}
#endif /* #if ( configGENERATE_RUN_TIME_STATS == 1 ) */
}
/*-----------------------------------------------------------*/

View file

@ -1322,6 +1322,18 @@
#endif /* configUSE_TRACE_FACILITY */ #endif /* configUSE_TRACE_FACILITY */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/*
* Reset the state in this file. This state is normally initialized at start up.
* This function must be called by the application before restarting the
* scheduler.
*/
void vTimerResetState( void )
{
xTimerQueue = NULL;
xTimerTaskHandle = NULL;
}
/*-----------------------------------------------------------*/
/* This entire source file will be skipped if the application is not configured /* This entire source file will be skipped if the application is not configured
* to include software timer functionality. If you want to include software timer * to include software timer functionality. If you want to include software timer
* functionality then ensure configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */ * functionality then ensure configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */