mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-12-07 13:45:00 -05:00
Merge branch 'main' into update-rp2040-define-nop
This commit is contained in:
commit
4e44157526
661 changed files with 4079 additions and 902 deletions
16
.github/.cSpellWords.txt
vendored
16
.github/.cSpellWords.txt
vendored
|
|
@ -549,6 +549,10 @@ NTRST
|
|||
NVIC
|
||||
ODAT
|
||||
ODSR
|
||||
OINC
|
||||
OIWBNOWA
|
||||
OIWBWA
|
||||
OIWTNOWA
|
||||
OPMOD
|
||||
optimisations
|
||||
OPTIMISED
|
||||
|
|
@ -795,6 +799,15 @@ SWRST
|
|||
SWTRG
|
||||
synchronise
|
||||
SYSC
|
||||
sysclk
|
||||
Sysclk
|
||||
SysClk
|
||||
SYSClk
|
||||
SYSCLK
|
||||
sysclock
|
||||
Sysclock
|
||||
SysClock
|
||||
SYSCLOCK
|
||||
TACCR
|
||||
TACCTL
|
||||
TACLR
|
||||
|
|
@ -877,6 +890,9 @@ UNDADD
|
|||
unpadded
|
||||
Unpadded
|
||||
UNPADDED
|
||||
unprotect
|
||||
Unprotect
|
||||
Unprotected
|
||||
UNRE
|
||||
UNSUB
|
||||
UNSUBACK
|
||||
|
|
|
|||
9
.github/scripts/kernel_checker.py
vendored
9
.github/scripts/kernel_checker.py
vendored
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env python3
|
||||
#/*
|
||||
# * 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
|
||||
# *
|
||||
|
|
@ -37,7 +37,8 @@ KERNEL_IGNORED_FILES = [
|
|||
'FreeRTOS-openocd.c',
|
||||
'Makefile',
|
||||
'.DS_Store',
|
||||
'cspell.config.yaml'
|
||||
'cspell.config.yaml',
|
||||
'.clang-format'
|
||||
]
|
||||
|
||||
KERNEL_IGNORED_EXTENSIONS = [
|
||||
|
|
@ -135,12 +136,16 @@ KERNEL_HEADER = [
|
|||
' */\n',
|
||||
]
|
||||
|
||||
|
||||
FREERTOS_COPYRIGHT_REGEX = r"^(;|#)?( *(\/\*|\*|#|\/\/))? Copyright \(C\) 20\d\d Amazon.com, Inc. or its affiliates. All Rights Reserved\.( \*\/)?$"
|
||||
|
||||
def main():
|
||||
parser = HeaderChecker.configArgParser()
|
||||
args = parser.parse_args()
|
||||
|
||||
# Configure the checks then run
|
||||
checker = HeaderChecker(KERNEL_HEADER,
|
||||
copyright_regex=FREERTOS_COPYRIGHT_REGEX,
|
||||
ignored_files=KERNEL_IGNORED_FILES,
|
||||
ignored_ext=KERNEL_IGNORED_EXTENSIONS,
|
||||
ignored_patterns=KERNEL_IGNORED_PATTERNS,
|
||||
|
|
|
|||
|
|
@ -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_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_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_ARM7_AT91FR40008 - Compiler: GCC Target: ARM7 Atmel AT91R40008\n"
|
||||
" GCC_ARM7_AT91SAM7S - Compiler: GCC Target: ARM7 Atmel AT91SAM7S\n"
|
||||
|
|
|
|||
10
MISRA.md
10
MISRA.md
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
FreeRTOS-Kernel conforms to [MISRA C:2012](https://www.misra.org.uk/misra-c)
|
||||
guidelines, with the deviations listed below. Compliance is checked with
|
||||
Coverity static analysis. Since the FreeRTOS kernel is designed for
|
||||
small-embedded devices, it needs to have a very small memory footprint and
|
||||
has to be efficient. To achieve that and to increase the performance, it
|
||||
deviates from some MISRA rules. The specific deviations, suppressed inline,
|
||||
are listed below.
|
||||
Coverity static analysis version 2023.6.1. Since the FreeRTOS kernel is
|
||||
designed for small-embedded devices, it needs to have a very small memory
|
||||
footprint and has to be efficient. To achieve that and to increase the
|
||||
performance, it deviates from some MISRA rules. The specific deviations,
|
||||
suppressed inline, are listed below.
|
||||
|
||||
Additionally, [MISRA configuration file](examples/coverity/coverity_misra.config)
|
||||
contains project wide deviations.
|
||||
|
|
|
|||
29
croutine.c
29
croutine.c
|
|
@ -30,7 +30,7 @@
|
|||
#include "task.h"
|
||||
#include "croutine.h"
|
||||
|
||||
/* Remove the whole file is co-routines are not being used. */
|
||||
/* Remove the whole file if co-routines are not being used. */
|
||||
#if ( configUSE_CO_ROUTINES != 0 )
|
||||
|
||||
/*
|
||||
|
|
@ -52,8 +52,10 @@
|
|||
|
||||
/* Other file private variables. --------------------------------*/
|
||||
CRCB_t * pxCurrentCoRoutine = NULL;
|
||||
static UBaseType_t uxTopCoRoutineReadyPriority = 0;
|
||||
static TickType_t xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0;
|
||||
static UBaseType_t uxTopCoRoutineReadyPriority = ( UBaseType_t ) 0U;
|
||||
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. */
|
||||
#define corINITIAL_STATE ( 0 )
|
||||
|
|
@ -378,5 +380,26 @@
|
|||
|
||||
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 */
|
||||
|
|
|
|||
|
|
@ -2,8 +2,9 @@ cmake_minimum_required(VERSION 3.15)
|
|||
|
||||
project(coverity)
|
||||
|
||||
set(FREERTOS_KERNEL_PATH "../../")
|
||||
FILE(GLOB FREERTOS_KERNEL_SOURCE ${FREERTOS_KERNEL_PATH}*.c)
|
||||
set(FREERTOS_KERNEL_PATH "../..")
|
||||
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
|
||||
# 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
|
||||
# boolean.
|
||||
add_custom_target(fix_source ALL
|
||||
COMMAND sed -i -b -e 's/pdFALSE/pdFAIL/g' -e 's/pdTRUE/pdPASS/g' ${FREERTOS_KERNEL_SOURCE}
|
||||
DEPENDS ${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} ${FREERTOS_PORT_CODE})
|
||||
|
||||
# Add the freertos_config for FreeRTOS-Kernel.
|
||||
add_library(freertos_config INTERFACE)
|
||||
|
|
|
|||
|
|
@ -1,97 +1,91 @@
|
|||
// MISRA C-2012 Rules
|
||||
|
||||
{
|
||||
version : "2.0",
|
||||
standard : "c2012",
|
||||
title: "Coverity MISRA Configuration",
|
||||
deviations : [
|
||||
// Disable the following rules.
|
||||
"version" : "2.0",
|
||||
"standard" : "c2012",
|
||||
"title": "Coverity MISRA Configuration",
|
||||
"deviations" : [
|
||||
{
|
||||
deviation: "Rule 3.1",
|
||||
reason: "We post HTTP links in code comments which contain // inside comments blocks."
|
||||
"deviation": "Rule 3.1",
|
||||
"reason": "We post HTTP links in code comments which contain // inside comments blocks."
|
||||
},
|
||||
{
|
||||
deviation: "Rule 14.4",
|
||||
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": "Rule 14.4",
|
||||
"reason": "do while( 0 ) pattern is used in macros to prevent extra semi-colon."
|
||||
},
|
||||
{
|
||||
deviation: "Directive 4.5",
|
||||
reason: "Allow names that MISRA considers ambiguous."
|
||||
"deviation": "Directive 4.4",
|
||||
"reason": "Code snippet is used in comment to help explanation."
|
||||
},
|
||||
{
|
||||
deviation: "Directive 4.6",
|
||||
reason: "Allow port to use primitive type with typedefs."
|
||||
"deviation": "Directive 4.5",
|
||||
"reason": "Allow names that MISRA considers ambiguous."
|
||||
},
|
||||
{
|
||||
deviation: "Directive 4.8",
|
||||
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": "Directive 4.6",
|
||||
"reason": "Allow port to use primitive type with typedefs."
|
||||
},
|
||||
{
|
||||
deviation: "Directive 4.9",
|
||||
reason: "FreeRTOS-Kernel is optimised to work on small micro-controllers. To achieve that, function-like macros are used."
|
||||
"deviation": "Directive 4.8",
|
||||
"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",
|
||||
reason: "FreeRTOS defines types which is used in application."
|
||||
"deviation": "Directive 4.9",
|
||||
"reason": "FreeRTOS-Kernel is optimised to work on small micro-controllers. To achieve that, function-like macros are used."
|
||||
},
|
||||
{
|
||||
deviation: "Rule 2.4",
|
||||
reason: "Allow to define unused tag."
|
||||
"deviation": "Rule 2.3",
|
||||
"reason": "FreeRTOS defines types which is used in application."
|
||||
},
|
||||
{
|
||||
deviation: "Rule 2.5",
|
||||
reason: "Allow to define unused macro."
|
||||
"deviation": "Rule 2.4",
|
||||
"reason": "Allow to define unused tag."
|
||||
},
|
||||
{
|
||||
deviation: "Rule 5.9",
|
||||
reason: "Allow to define identifier with the same name in structure and global variable."
|
||||
"deviation": "Rule 2.5",
|
||||
"reason": "Allow to define unused macro."
|
||||
},
|
||||
{
|
||||
deviation: "Rule 8.7",
|
||||
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 5.9",
|
||||
"reason": "Allow to define identifier with the same name in structure and global variable."
|
||||
},
|
||||
{
|
||||
deviation: "Rule 8.9",
|
||||
reason: "Allow to object to be defined in wider scope for debug purpose."
|
||||
"deviation": "Rule 8.7",
|
||||
"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",
|
||||
reason: "Allow to not to use const-qualified type for callback function."
|
||||
"deviation": "Rule 8.9",
|
||||
"reason": "Allow to object to be defined in wider scope for debug purpose."
|
||||
},
|
||||
{
|
||||
deviation: "Rule 11.4",
|
||||
reason: "Allow to convert between a pointer to object and an interger type for stack alignment."
|
||||
"deviation": "Rule 8.13",
|
||||
"reason": "Allow to not to use const-qualified type for callback function."
|
||||
},
|
||||
{
|
||||
deviation: "Rule 15.4",
|
||||
reason: "Allow to use multiple break statements in a loop."
|
||||
"deviation": "Rule 11.4",
|
||||
"reason": "Allow to convert between a pointer to object and an interger type for stack alignment."
|
||||
},
|
||||
{
|
||||
deviation: "Rule 15.5",
|
||||
reason: "Allow to use multiple points of exit."
|
||||
"deviation": "Rule 15.4",
|
||||
"reason": "Allow to use multiple break statements in a loop."
|
||||
},
|
||||
{
|
||||
deviation: "Rule 17.8",
|
||||
reason: "Allow to update the parameters of a function."
|
||||
"deviation": "Rule 15.5",
|
||||
"reason": "Allow to use multiple points of exit."
|
||||
},
|
||||
{
|
||||
deviation: "Rule 18.4",
|
||||
reason: "Allow to use pointer arithmetic."
|
||||
"deviation": "Rule 17.8",
|
||||
"reason": "Allow to update the parameters of a function."
|
||||
},
|
||||
{
|
||||
deviation: "Rule 19.2",
|
||||
reason: "Allow to use union."
|
||||
"deviation": "Rule 18.4",
|
||||
"reason": "Allow to use pointer arithmetic."
|
||||
},
|
||||
{
|
||||
deviation: "Rule 20.5",
|
||||
reason: "Allow to use #undef for MPU wrappers."
|
||||
"deviation": "Rule 19.2",
|
||||
"reason": "Allow to use union."
|
||||
},
|
||||
{
|
||||
"deviation": "Rule 20.5",
|
||||
"reason": "Allow to use #undef for MPU wrappers."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -283,10 +283,9 @@
|
|||
/******************************************************************************/
|
||||
|
||||
/* configKERNEL_INTERRUPT_PRIORITY sets the priority of the tick and context
|
||||
* switch performing interrupts. The default value is set to the highest interrupt
|
||||
* priority (0). Not supported by all FreeRTOS ports. See
|
||||
* https://www.freertos.org/RTOS-Cortex-M3-M4.html for information specific to ARM
|
||||
* Cortex-M devices. */
|
||||
* switch performing interrupts. Not supported by all FreeRTOS ports. See
|
||||
* https://www.freertos.org/RTOS-Cortex-M3-M4.html for information specific to
|
||||
* ARM Cortex-M devices. */
|
||||
#define configKERNEL_INTERRUPT_PRIORITY 0
|
||||
|
||||
/* configMAX_SYSCALL_INTERRUPT_PRIORITY sets the interrupt priority above which
|
||||
|
|
@ -496,6 +495,15 @@
|
|||
* run any task on any available core. */
|
||||
#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
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -96,6 +96,10 @@
|
|||
#define configNUMBER_OF_CORES 1
|
||||
#endif
|
||||
|
||||
#ifndef configUSE_MALLOC_FAILED_HOOK
|
||||
#define configUSE_MALLOC_FAILED_HOOK 0
|
||||
#endif
|
||||
|
||||
/* Basic FreeRTOS definitions. */
|
||||
#include "projdefs.h"
|
||||
|
||||
|
|
@ -484,6 +488,12 @@
|
|||
#define configUSE_CORE_AFFINITY 0
|
||||
#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
|
||||
#define configUSE_PASSIVE_IDLE_HOOK 0
|
||||
#endif /* configUSE_PASSIVE_IDLE_HOOK */
|
||||
|
|
@ -2643,10 +2653,6 @@
|
|||
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()
|
||||
#endif
|
||||
|
||||
#ifndef configUSE_MALLOC_FAILED_HOOK
|
||||
#define configUSE_MALLOC_FAILED_HOOK 0
|
||||
#endif
|
||||
|
||||
#ifndef portPRIVILEGE_BIT
|
||||
#define portPRIVILEGE_BIT ( ( UBaseType_t ) 0x00 )
|
||||
#endif
|
||||
|
|
@ -2799,9 +2805,9 @@
|
|||
|
||||
#ifndef configSTACK_DEPTH_TYPE
|
||||
|
||||
/* Defaults to uint16_t for backward compatibility, but can be overridden
|
||||
* in FreeRTOSConfig.h if uint16_t is too restrictive. */
|
||||
#define configSTACK_DEPTH_TYPE uint16_t
|
||||
/* Defaults to StackType_t for backward compatibility, but can be overridden
|
||||
* in FreeRTOSConfig.h if StackType_t is too restrictive. */
|
||||
#define configSTACK_DEPTH_TYPE StackType_t
|
||||
#endif
|
||||
|
||||
#ifndef configRUN_TIME_COUNTER_TYPE
|
||||
|
|
|
|||
|
|
@ -746,6 +746,13 @@ void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay,
|
|||
*/
|
||||
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* */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -282,7 +282,8 @@ typedef struct xLIST
|
|||
* \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY
|
||||
* \ingroup LinkedList
|
||||
*/
|
||||
#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \
|
||||
#if ( configNUMBER_OF_CORES == 1 )
|
||||
#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \
|
||||
do { \
|
||||
List_t * const pxConstList = ( pxList ); \
|
||||
/* Increment the index to the next item and return the item, ensuring */ \
|
||||
|
|
@ -294,6 +295,13 @@ typedef struct xLIST
|
|||
} \
|
||||
( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \
|
||||
} while( 0 )
|
||||
#else /* #if ( configNUMBER_OF_CORES == 1 ) */
|
||||
|
||||
/* This function is not required in SMP. FreeRTOS SMP scheduler doesn't use
|
||||
* pxIndex and it should always point to the xListEnd. Not defining this macro
|
||||
* here to prevent updating pxIndex.
|
||||
*/
|
||||
#endif /* #if ( configNUMBER_OF_CORES == 1 ) */
|
||||
|
||||
/*
|
||||
* Version of uxListRemove() that does not return a value. Provided as a slight
|
||||
|
|
@ -326,7 +334,7 @@ typedef struct xLIST
|
|||
} \
|
||||
\
|
||||
( pxItemToRemove )->pxContainer = NULL; \
|
||||
( pxList->uxNumberOfItems )--; \
|
||||
( ( pxList )->uxNumberOfItems ) -= ( UBaseType_t ) 1U; \
|
||||
} while( 0 )
|
||||
|
||||
/*
|
||||
|
|
@ -373,7 +381,7 @@ typedef struct xLIST
|
|||
/* Remember which list the item is in. */ \
|
||||
( pxNewListItem )->pxContainer = ( pxList ); \
|
||||
\
|
||||
( ( pxList )->uxNumberOfItems )++; \
|
||||
( ( pxList )->uxNumberOfItems ) += ( UBaseType_t ) 1U; \
|
||||
} while( 0 )
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -795,7 +795,7 @@ typedef StreamBufferHandle_t MessageBufferHandle_t;
|
|||
* \ingroup MessageBufferManagement
|
||||
*/
|
||||
#define xMessageBufferNextLengthBytes( xMessageBuffer ) \
|
||||
xStreamBufferNextMessageLengthBytes( xMessageBuffer ) PRIVILEGED_FUNCTION;
|
||||
xStreamBufferNextMessageLengthBytes( xMessageBuffer )
|
||||
|
||||
/**
|
||||
* message_buffer.h
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@ void vPortGetHeapStats( HeapStats_t * pxHeapStats );
|
|||
/*
|
||||
* 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,
|
||||
size_t xSize ) PRIVILEGED_FUNCTION;
|
||||
void vPortFree( void * pv ) PRIVILEGED_FUNCTION;
|
||||
|
|
@ -194,6 +194,12 @@ size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION;
|
|||
#define vPortFreeStack vPortFree
|
||||
#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 )
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3438,6 +3438,20 @@ BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut,
|
|||
*/
|
||||
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
|
||||
|
|
|
|||
|
|
@ -1417,6 +1417,12 @@ BaseType_t xTimerGenericCommandFromISR( TimerHandle_t xTimer,
|
|||
|
||||
#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* */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
9
list.c
9
list.c
|
|
@ -130,7 +130,7 @@ void vListInsertEnd( List_t * const pxList,
|
|||
/* Remember which list the item is in. */
|
||||
pxNewListItem->pxContainer = pxList;
|
||||
|
||||
( pxList->uxNumberOfItems )++;
|
||||
( pxList->uxNumberOfItems ) += ( UBaseType_t ) 1U;
|
||||
|
||||
traceRETURN_vListInsertEnd();
|
||||
}
|
||||
|
|
@ -205,12 +205,13 @@ void vListInsert( List_t * const pxList,
|
|||
* item later. */
|
||||
pxNewListItem->pxContainer = pxList;
|
||||
|
||||
( pxList->uxNumberOfItems )++;
|
||||
( pxList->uxNumberOfItems ) += ( UBaseType_t ) 1U;
|
||||
|
||||
traceRETURN_vListInsert();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
|
||||
{
|
||||
/* The list item knows which list it is in. Obtain the list from the list
|
||||
|
|
@ -219,8 +220,6 @@ UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
|
|||
|
||||
traceENTER_uxListRemove( pxItemToRemove );
|
||||
|
||||
|
||||
|
||||
pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
|
||||
pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
|
||||
|
||||
|
|
@ -238,7 +237,7 @@ UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
|
|||
}
|
||||
|
||||
pxItemToRemove->pxContainer = NULL;
|
||||
( pxList->uxNumberOfItems )--;
|
||||
( pxList->uxNumberOfItems ) -= ( UBaseType_t ) 1U;
|
||||
|
||||
traceRETURN_uxListRemove( pxList->uxNumberOfItems );
|
||||
|
||||
|
|
|
|||
|
|
@ -207,6 +207,11 @@ add_library(freertos_kernel_port OBJECT
|
|||
GCC/ARM_CR5/port.c
|
||||
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>:
|
||||
GCC/ARM_CRx_No_GIC/port.c
|
||||
GCC/ARM_CRx_No_GIC/portASM.S>
|
||||
|
|
@ -836,6 +841,7 @@ target_include_directories(freertos_kernel_port_headers INTERFACE
|
|||
|
||||
# ARMv7-R ports for GCC
|
||||
$<$<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>
|
||||
|
||||
# ARMv4T ARM7TDMI ports for GCC
|
||||
|
|
|
|||
854
portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S
Normal file
854
portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S
Normal 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
|
||||
843
portable/GCC/ARM_CRx_MPU/port.c
Normal file
843
portable/GCC/ARM_CRx_MPU/port.c
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
498
portable/GCC/ARM_CRx_MPU/portASM.S
Normal file
498
portable/GCC/ARM_CRx_MPU/portASM.S
Normal 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
|
||||
522
portable/GCC/ARM_CRx_MPU/portmacro.h
Normal file
522
portable/GCC/ARM_CRx_MPU/portmacro.h
Normal 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 */
|
||||
279
portable/GCC/ARM_CRx_MPU/portmacro_asm.h
Normal file
279
portable/GCC/ARM_CRx_MPU/portmacro_asm.h
Normal 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 */
|
||||
|
|
@ -64,7 +64,7 @@
|
|||
#endif /* configAPPLICATION_ALLOCATED_HEAP */
|
||||
|
||||
/* 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 );
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
|
|||
|
|
@ -113,6 +113,9 @@ PRIVILEGED_DATA static BlockLink_t xStart, xEnd;
|
|||
* fragmentation. */
|
||||
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 * pxPreviousBlock;
|
||||
BlockLink_t * pxNewBlockLink;
|
||||
PRIVILEGED_DATA static BaseType_t xHeapHasBeenInitialised = pdFALSE;
|
||||
void * pvReturn = NULL;
|
||||
size_t xAdditionalRequiredSize;
|
||||
|
||||
|
|
@ -384,3 +386,16 @@ static void prvHeapInit( void ) /* PRIVILEGED_FUNCTION */
|
|||
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;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
|
|||
|
|
@ -92,3 +92,15 @@ void vPortFree( void * pv )
|
|||
( 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. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
|
|||
|
|
@ -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
|
||||
* number of free bytes remaining, but says nothing about fragmentation. */
|
||||
PRIVILEGED_DATA static size_t xFreeBytesRemaining = 0U;
|
||||
PRIVILEGED_DATA static size_t xMinimumEverFreeBytesRemaining = 0U;
|
||||
PRIVILEGED_DATA static size_t xNumberOfSuccessfulAllocations = 0;
|
||||
PRIVILEGED_DATA static size_t xNumberOfSuccessfulFrees = 0;
|
||||
PRIVILEGED_DATA static size_t xFreeBytesRemaining = ( size_t ) 0U;
|
||||
PRIVILEGED_DATA static size_t xMinimumEverFreeBytesRemaining = ( size_t ) 0U;
|
||||
PRIVILEGED_DATA static size_t xNumberOfSuccessfulAllocations = ( size_t ) 0U;
|
||||
PRIVILEGED_DATA static size_t xNumberOfSuccessfulFrees = ( size_t ) 0U;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
@ -608,3 +608,19 @@ void vPortGetHeapStats( HeapStats_t * pxHeapStats )
|
|||
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;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
|
|||
|
|
@ -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
|
||||
* number of free bytes remaining, but says nothing about fragmentation. */
|
||||
PRIVILEGED_DATA static size_t xFreeBytesRemaining = 0U;
|
||||
PRIVILEGED_DATA static size_t xMinimumEverFreeBytesRemaining = 0U;
|
||||
PRIVILEGED_DATA static size_t xNumberOfSuccessfulAllocations = 0;
|
||||
PRIVILEGED_DATA static size_t xNumberOfSuccessfulFrees = 0;
|
||||
PRIVILEGED_DATA static size_t xFreeBytesRemaining = ( size_t ) 0U;
|
||||
PRIVILEGED_DATA static size_t xMinimumEverFreeBytesRemaining = ( size_t ) 0U;
|
||||
PRIVILEGED_DATA static size_t xNumberOfSuccessfulAllocations = ( size_t ) 0U;
|
||||
PRIVILEGED_DATA static size_t xNumberOfSuccessfulFrees = ( size_t ) 0U;
|
||||
|
||||
#if ( configENABLE_HEAP_PROTECTOR == 1 )
|
||||
|
||||
|
|
@ -707,3 +707,24 @@ void vPortGetHeapStats( HeapStats_t * pxHeapStats )
|
|||
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 ) */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
|
|||
2
portable/ThirdParty/GCC/Posix/portmacro.h
vendored
2
portable/ThirdParty/GCC/Posix/portmacro.h
vendored
|
|
@ -64,7 +64,7 @@ typedef long BaseType_t;
|
|||
typedef unsigned long UBaseType_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
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,10 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
|||
TaskFunction_t pxCode,
|
||||
void * pvParameters )
|
||||
{
|
||||
( void ) pxTopOfStack;
|
||||
( void ) pvParameters;
|
||||
( void ) * pxCode;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
180
tasks.c
180
tasks.c
|
|
@ -255,7 +255,7 @@
|
|||
pxTemp = pxDelayedTaskList; \
|
||||
pxDelayedTaskList = pxOverflowDelayedTaskList; \
|
||||
pxOverflowDelayedTaskList = pxTemp; \
|
||||
xNumOfOverflows++; \
|
||||
xNumOfOverflows += ( BaseType_t ) 1; \
|
||||
prvResetNextTaskUnblockTime(); \
|
||||
} while( 0 )
|
||||
|
||||
|
|
@ -1325,7 +1325,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
|
|||
#if ( ( configNUMBER_OF_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) )
|
||||
{
|
||||
/* Set the task's affinity before scheduling it. */
|
||||
pxNewTCB->uxCoreAffinityMask = tskNO_AFFINITY;
|
||||
pxNewTCB->uxCoreAffinityMask = configTASK_DEFAULT_CORE_AFFINITY;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -1442,7 +1442,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
|
|||
#if ( ( configNUMBER_OF_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) )
|
||||
{
|
||||
/* Set the task's affinity before scheduling it. */
|
||||
pxNewTCB->uxCoreAffinityMask = tskNO_AFFINITY;
|
||||
pxNewTCB->uxCoreAffinityMask = configTASK_DEFAULT_CORE_AFFINITY;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -1560,7 +1560,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
|
|||
#if ( ( configNUMBER_OF_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) )
|
||||
{
|
||||
/* 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 ) ) */
|
||||
|
||||
|
|
@ -1733,7 +1733,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
|
|||
#if ( ( configNUMBER_OF_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) )
|
||||
{
|
||||
/* Set the task's affinity before scheduling it. */
|
||||
pxNewTCB->uxCoreAffinityMask = tskNO_AFFINITY;
|
||||
pxNewTCB->uxCoreAffinityMask = configTASK_DEFAULT_CORE_AFFINITY;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -2021,7 +2021,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,
|
|||
* updated. */
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
uxCurrentNumberOfTasks++;
|
||||
uxCurrentNumberOfTasks += ( UBaseType_t ) 1U;
|
||||
|
||||
if( pxCurrentTCB == NULL )
|
||||
{
|
||||
|
|
@ -3208,6 +3208,8 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,
|
|||
|
||||
#if ( configNUMBER_OF_CORES == 1 )
|
||||
{
|
||||
UBaseType_t uxCurrentListLength;
|
||||
|
||||
if( xSchedulerRunning != pdFALSE )
|
||||
{
|
||||
/* Reset the next expected unblock time in case it referred to the
|
||||
|
|
@ -3236,7 +3238,13 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,
|
|||
/* The scheduler is not running, but the task that was pointed
|
||||
* to by pxCurrentTCB has just been suspended and pxCurrentTCB
|
||||
* must be adjusted to point to a different task. */
|
||||
if( listCURRENT_LIST_LENGTH( &xSuspendedTaskList ) == uxCurrentNumberOfTasks )
|
||||
|
||||
/* Use a temp variable as a distinct sequence point for reading
|
||||
* volatile variables prior to a comparison to ensure compliance
|
||||
* with MISRA C 2012 Rule 13.2. */
|
||||
uxCurrentListLength = listCURRENT_LIST_LENGTH( &xSuspendedTaskList );
|
||||
|
||||
if( uxCurrentListLength == uxCurrentNumberOfTasks )
|
||||
{
|
||||
/* No other tasks are ready, so set pxCurrentTCB back to
|
||||
* NULL so when the next task is created pxCurrentTCB will
|
||||
|
|
@ -3807,7 +3815,7 @@ void vTaskSuspendAll( void )
|
|||
|
||||
/* The scheduler is suspended if uxSchedulerSuspended is non-zero. An increment
|
||||
* is used to allow calls to vTaskSuspendAll() to nest. */
|
||||
++uxSchedulerSuspended;
|
||||
uxSchedulerSuspended += ( UBaseType_t ) 1U;
|
||||
|
||||
/* Enforces ordering for ports and optimised compilers that may otherwise place
|
||||
* the above increment elsewhere. */
|
||||
|
|
@ -3960,7 +3968,7 @@ BaseType_t xTaskResumeAll( void )
|
|||
* previous call to vTaskSuspendAll(). */
|
||||
configASSERT( uxSchedulerSuspended != 0U );
|
||||
|
||||
--uxSchedulerSuspended;
|
||||
uxSchedulerSuspended -= ( UBaseType_t ) 1U;
|
||||
portRELEASE_TASK_LOCK();
|
||||
|
||||
if( uxSchedulerSuspended == ( UBaseType_t ) 0U )
|
||||
|
|
@ -4169,80 +4177,6 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery )
|
|||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( INCLUDE_xTaskGetHandle == 1 )
|
||||
|
||||
#if ( configNUMBER_OF_CORES == 1 )
|
||||
static TCB_t * prvSearchForNameWithinSingleList( List_t * pxList,
|
||||
const char pcNameToQuery[] )
|
||||
{
|
||||
TCB_t * pxNextTCB;
|
||||
TCB_t * pxFirstTCB;
|
||||
TCB_t * pxReturn = NULL;
|
||||
UBaseType_t x;
|
||||
char cNextChar;
|
||||
BaseType_t xBreakLoop;
|
||||
|
||||
/* This function is called with the scheduler suspended. */
|
||||
|
||||
if( listCURRENT_LIST_LENGTH( pxList ) > ( UBaseType_t ) 0 )
|
||||
{
|
||||
/* MISRA Ref 11.5.3 [Void pointer assignment] */
|
||||
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
|
||||
/* coverity[misra_c_2012_rule_11_5_violation] */
|
||||
listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList );
|
||||
|
||||
do
|
||||
{
|
||||
/* MISRA Ref 11.5.3 [Void pointer assignment] */
|
||||
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
|
||||
/* coverity[misra_c_2012_rule_11_5_violation] */
|
||||
listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList );
|
||||
|
||||
/* Check each character in the name looking for a match or
|
||||
* mismatch. */
|
||||
xBreakLoop = pdFALSE;
|
||||
|
||||
for( x = ( UBaseType_t ) 0; x < ( UBaseType_t ) configMAX_TASK_NAME_LEN; x++ )
|
||||
{
|
||||
cNextChar = pxNextTCB->pcTaskName[ x ];
|
||||
|
||||
if( cNextChar != pcNameToQuery[ x ] )
|
||||
{
|
||||
/* Characters didn't match. */
|
||||
xBreakLoop = pdTRUE;
|
||||
}
|
||||
else if( cNextChar == ( char ) 0x00 )
|
||||
{
|
||||
/* Both strings terminated, a match must have been
|
||||
* found. */
|
||||
pxReturn = pxNextTCB;
|
||||
xBreakLoop = pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
if( xBreakLoop != pdFALSE )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( pxReturn != NULL )
|
||||
{
|
||||
/* The handle has been found. */
|
||||
break;
|
||||
}
|
||||
} while( pxNextTCB != pxFirstTCB );
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
return pxReturn;
|
||||
}
|
||||
#else /* if ( configNUMBER_OF_CORES == 1 ) */
|
||||
static TCB_t * prvSearchForNameWithinSingleList( List_t * pxList,
|
||||
const char pcNameToQuery[] )
|
||||
{
|
||||
|
|
@ -4309,7 +4243,6 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery )
|
|||
|
||||
return pxReturn;
|
||||
}
|
||||
#endif /* #if ( configNUMBER_OF_CORES == 1 ) */
|
||||
|
||||
#endif /* INCLUDE_xTaskGetHandle */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
@ -4960,7 +4893,7 @@ BaseType_t xTaskIncrementTick( void )
|
|||
}
|
||||
else
|
||||
{
|
||||
++xPendedTicks;
|
||||
xPendedTicks += 1U;
|
||||
|
||||
/* The tick hook gets called at regular intervals, even if the
|
||||
* scheduler is locked. */
|
||||
|
|
@ -6322,30 +6255,27 @@ static void prvCheckTasksWaitingTermination( void )
|
|||
List_t * pxList,
|
||||
eTaskState eState )
|
||||
{
|
||||
configLIST_VOLATILE TCB_t * pxNextTCB;
|
||||
configLIST_VOLATILE TCB_t * pxFirstTCB;
|
||||
configLIST_VOLATILE TCB_t * pxTCB;
|
||||
UBaseType_t uxTask = 0;
|
||||
const ListItem_t * pxEndMarker = listGET_END_MARKER( pxList );
|
||||
ListItem_t * pxIterator;
|
||||
|
||||
if( listCURRENT_LIST_LENGTH( pxList ) > ( UBaseType_t ) 0 )
|
||||
{
|
||||
/* MISRA Ref 11.5.3 [Void pointer assignment] */
|
||||
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
|
||||
/* coverity[misra_c_2012_rule_11_5_violation] */
|
||||
listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList );
|
||||
|
||||
/* Populate an TaskStatus_t structure within the
|
||||
* pxTaskStatusArray array for each task that is referenced from
|
||||
* pxList. See the definition of TaskStatus_t in task.h for the
|
||||
* meaning of each TaskStatus_t structure member. */
|
||||
do
|
||||
for( pxIterator = listGET_HEAD_ENTRY( pxList ); pxIterator != pxEndMarker; pxIterator = listGET_NEXT( pxIterator ) )
|
||||
{
|
||||
/* MISRA Ref 11.5.3 [Void pointer assignment] */
|
||||
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
|
||||
/* coverity[misra_c_2012_rule_11_5_violation] */
|
||||
listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList );
|
||||
vTaskGetInfo( ( TaskHandle_t ) pxNextTCB, &( pxTaskStatusArray[ uxTask ] ), pdTRUE, eState );
|
||||
pxTCB = listGET_LIST_ITEM_OWNER( pxIterator );
|
||||
|
||||
vTaskGetInfo( ( TaskHandle_t ) pxTCB, &( pxTaskStatusArray[ uxTask ] ), pdTRUE, eState );
|
||||
uxTask++;
|
||||
} while( pxNextTCB != pxFirstTCB );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -8686,3 +8616,61 @@ static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait,
|
|||
|
||||
#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 ) */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
|
|||
12
timers.c
12
timers.c
|
|
@ -1322,6 +1322,18 @@
|
|||
#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
|
||||
* to include software timer functionality. If you want to include software timer
|
||||
* functionality then ensure configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue