mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-12-07 05:34:59 -05:00
Apply git review ptach created by @aggarg
This commit is contained in:
parent
d6e2ab495d
commit
c195770fe8
7 changed files with 1152 additions and 2691 deletions
|
|
@ -1,104 +0,0 @@
|
|||
---
|
||||
Language: Cpp
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveAssignments: None
|
||||
AlignConsecutiveBitFields: AcrossEmptyLinesAndComments
|
||||
AlignConsecutiveDeclarations: None
|
||||
AlignConsecutiveMacros: AcrossEmptyLinesAndComments
|
||||
AlignEscapedNewlines: Left
|
||||
AlignOperands: AlignAfterOperator
|
||||
AlignTrailingComments: true
|
||||
AllowAllArgumentsOnNextLine: false
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
AllowShortBlocksOnASingleLine: Never
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortEnumsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: None
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLambdasOnASingleLine: All
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
BinPackArguments: false
|
||||
BinPackParameters: false
|
||||
BitFieldColonSpacing: Both
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: true
|
||||
AfterClass: true
|
||||
AfterControlStatement: Always
|
||||
AfterEnum: true
|
||||
AfterExternBlock: false
|
||||
AfterFunction: true
|
||||
AfterNamespace: true
|
||||
AfterStruct: true
|
||||
AfterUnion: true
|
||||
BeforeCatch: true
|
||||
BeforeElse: true
|
||||
BeforeLambdaBody: false
|
||||
BeforeWhile: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: true
|
||||
SplitEmptyRecord: true
|
||||
SplitEmptyNamespace: true
|
||||
BreakBeforeBinaryOperators: NonAssignment
|
||||
BreakBeforeBraces: Custom
|
||||
BreakBeforeConceptDeclarations: true
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
BreakInheritanceList: BeforeColon
|
||||
BreakStringLiterals: true
|
||||
ColumnLimit: 90
|
||||
CompactNamespaces: false
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: false
|
||||
DerivePointerAlignment: false
|
||||
EmptyLineBeforeAccessModifier: Always
|
||||
FixNamespaceComments: true
|
||||
IncludeBlocks: Preserve
|
||||
IndentCaseBlocks: false
|
||||
IndentCaseLabels: true
|
||||
IndentExternBlock: NoIndent
|
||||
IndentGotoLabels: true
|
||||
IndentPPDirectives: BeforeHash
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
PenaltyBreakAssignment: 1000
|
||||
PenaltyBreakBeforeFirstCallParameter: 200
|
||||
PenaltyBreakComment: 50
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakString: 100
|
||||
PenaltyBreakTemplateDeclaration: 10
|
||||
PenaltyExcessCharacter: 100
|
||||
PenaltyIndentedWhitespace: 0
|
||||
PenaltyReturnTypeOnItsOwnLine: 10000
|
||||
PointerAlignment: Middle
|
||||
ReflowComments: true
|
||||
SortIncludes: false
|
||||
SortUsingDeclarations: true
|
||||
SpaceAfterCStyleCast: true
|
||||
SpaceAfterLogicalNot: false
|
||||
SpaceAfterTemplateKeyword: false
|
||||
SpaceBeforeCpp11BracedList: true
|
||||
SpaceBeforeCtorInitializerColon: false
|
||||
SpaceBeforeInheritanceColon: false
|
||||
SpaceBeforeParens: Never
|
||||
SpaceBeforeRangeBasedForLoopColon: false
|
||||
SpaceBeforeSquareBrackets: false
|
||||
SpaceInEmptyBlock: false
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: false
|
||||
SpacesInConditionalStatement: true
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInCStyleCastParentheses: true
|
||||
SpacesInParentheses: true
|
||||
SpacesInSquareBrackets: true
|
||||
TabWidth: 4
|
||||
UseCRLF: false
|
||||
UseTab: Never
|
||||
...
|
||||
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,495 +0,0 @@
|
|||
/*
|
||||
* 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 MPU_PROTOTYPES_H
|
||||
#define MPU_PROTOTYPES_H
|
||||
|
||||
#include <stddef.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 "task.h"
|
||||
#include "queue.h"
|
||||
#include "timers.h"
|
||||
#include "event_groups.h"
|
||||
#include "stream_buffer.h"
|
||||
#include "mpu_prototypes.h"
|
||||
#include "mpu_syscall_numbers.h"
|
||||
|
||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||
|
||||
typedef struct xTaskGenericNotifyParams
|
||||
{
|
||||
TaskHandle_t xTaskToNotify;
|
||||
UBaseType_t uxIndexToNotify;
|
||||
uint32_t ulValue;
|
||||
eNotifyAction eAction;
|
||||
uint32_t * pulPreviousNotificationValue;
|
||||
} xTaskGenericNotifyParams_t;
|
||||
|
||||
typedef struct xTaskGenericNotifyWaitParams
|
||||
{
|
||||
UBaseType_t uxIndexToWaitOn;
|
||||
uint32_t ulBitsToClearOnEntry;
|
||||
uint32_t ulBitsToClearOnExit;
|
||||
uint32_t * pulNotificationValue;
|
||||
TickType_t xTicksToWait;
|
||||
} xTaskGenericNotifyWaitParams_t;
|
||||
|
||||
typedef struct xTimerGenericCommandParams
|
||||
{
|
||||
TimerHandle_t xTimer;
|
||||
BaseType_t xCommandID;
|
||||
TickType_t xOptionalValue;
|
||||
BaseType_t * pxHigherPriorityTaskWoken;
|
||||
TickType_t xTicksToWait;
|
||||
} xTimerGenericCommandParams_t;
|
||||
|
||||
typedef struct xEventGroupWaitBitsParams
|
||||
{
|
||||
EventGroupHandle_t xEventGroup;
|
||||
EventBits_t uxBitsToWaitFor;
|
||||
BaseType_t xClearOnExit;
|
||||
BaseType_t xWaitForAllBits;
|
||||
TickType_t xTicksToWait;
|
||||
} xEventGroupWaitBitsParams_t;
|
||||
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
extern TickType_t MPU_xTaskGetTickCount( void )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
UBaseType_t MPU_uxTaskGetNumberOfTasks( void )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut,
|
||||
TickType_t * const pxTicksToWait )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue,
|
||||
const void * const pvItemToQueue,
|
||||
TickType_t xTicksToWait,
|
||||
const BaseType_t xCopyPosition )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue,
|
||||
void * const pvBuffer,
|
||||
TickType_t xTicksToWait )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue,
|
||||
void * const pvBuffer,
|
||||
TickType_t xTicksToWait )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
|
||||
const void * pvTxData,
|
||||
size_t xDataLengthBytes,
|
||||
TickType_t xTicksToWait )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
|
||||
void * pvRxData,
|
||||
size_t xBufferLengthBytes,
|
||||
TickType_t xTicksToWait )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer,
|
||||
size_t xTriggerLevel )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToWaitFor,
|
||||
const BaseType_t xClearOnExit,
|
||||
const BaseType_t xWaitForAllBits,
|
||||
TickType_t xTicksToWait )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToClear )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToSet )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup,
|
||||
const EventBits_t uxBitsToSet,
|
||||
const EventBits_t uxBitsToWaitFor,
|
||||
TickType_t xTicksToWait )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
#if( INCLUDE_xTaskDelayUntil == 1 )
|
||||
|
||||
BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime,
|
||||
const TickType_t xTimeIncrement )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
#endif /* ( INCLUDE_xTaskDelayUntil == 1 ) */
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
#if( INCLUDE_xTaskAbortDelay == 1 )
|
||||
|
||||
BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
#endif /* ( INCLUDE_xTaskAbortDelay == 1 ) */
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
#if( INCLUDE_vTaskDelay == 1 )
|
||||
|
||||
void MPU_vTaskDelay( const TickType_t xTicksToDelay )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
#endif /* ( INCLUDE_vTaskDelay == 1 ) */
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
#if( INCLUDE_uxTaskPriorityGet == 1 )
|
||||
|
||||
UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
#endif /* ( INCLUDE_uxTaskPriorityGet == 1 ) */
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
#if( INCLUDE_eTaskGetState == 1 )
|
||||
|
||||
eTaskState MPU_eTaskGetState( TaskHandle_t xTask )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
#endif /* ( INCLUDE_eTaskGetState == 1 ) */
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
#if( INCLUDE_xTaskGetIdleTaskHandle == 1 )
|
||||
|
||||
TaskHandle_t MPU_xTaskGetIdleTaskHandle( void )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
#endif /* ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
#if( INCLUDE_vTaskSuspend == 1 )
|
||||
|
||||
void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
void MPU_vTaskResume( TaskHandle_t xTaskToResume )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
#endif /* ( INCLUDE_vTaskSuspend == 1 ) */
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
#if( configGENERATE_RUN_TIME_STATS == 1 )
|
||||
configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
#if( INCLUDE_xTaskGetIdleTaskHandle == 1 ) )
|
||||
configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
#endif /* ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */
|
||||
|
||||
#endif /* ( ( configGENERATE_RUN_TIME_STATS == 1 ) */
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
#if( configUSE_APPLICATION_TASK_TAG == 1 )
|
||||
|
||||
void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask,
|
||||
TaskHookFunction_t pxHookFunction )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
#endif /* ( configUSE_APPLICATION_TASK_TAG == 1 ) */
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
#if( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 )
|
||||
|
||||
void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet,
|
||||
BaseType_t xIndex,
|
||||
void * pvValue )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery,
|
||||
BaseType_t xIndex )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
#endif /* ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
#if( INCLUDE_uxTaskGetStackHighWaterMark == 1 )
|
||||
|
||||
UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
#endif /* ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) */
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
#if( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 )
|
||||
|
||||
configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
#endif /* ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) */
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
#if( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) )
|
||||
|
||||
TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
#endif /* ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) \
|
||||
*/
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
#if( INCLUDE_xTaskGetSchedulerState == 1 )
|
||||
|
||||
BaseType_t MPU_xTaskGetSchedulerState( void )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
#endif /* ( INCLUDE_xTaskGetSchedulerState == 1 ) */
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
#if( configUSE_TRACE_FACILITY == 1 )
|
||||
|
||||
void MPU_vTaskGetInfo( TaskHandle_t xTask,
|
||||
TaskStatus_t * pxTaskStatus,
|
||||
BaseType_t xGetFreeStackSpace,
|
||||
eTaskState eState )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray,
|
||||
const UBaseType_t uxArraySize,
|
||||
configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
void MPU_vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
#endif /* ( configUSE_TRACE_FACILITY == 1 ) */
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
#if( configUSE_TASK_NOTIFICATIONS == 1 )
|
||||
|
||||
BaseType_t MPU_xTaskGenericNotifyEntry( const xTaskGenericNotifyParams_t * pxParams )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
BaseType_t MPU_xTaskGenericNotifyWaitEntry(
|
||||
const xTaskGenericNotifyWaitParams_t * pxParams )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn,
|
||||
BaseType_t xClearCountOnExit,
|
||||
TickType_t xTicksToWait )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask,
|
||||
UBaseType_t uxIndexToClear )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask,
|
||||
UBaseType_t uxIndexToClear,
|
||||
uint32_t ulBitsToClear )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
#endif /* ( configUSE_TASK_NOTIFICATIONS == 1 ) */
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
#if( configUSE_RECURSIVE_MUTEXES == 1 )
|
||||
|
||||
BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
#if( INCLUDE_xSemaphoreGetMutexHolder == 1 )
|
||||
|
||||
TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
#endif /* ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) */
|
||||
|
||||
#endif /* ( configUSE_RECURSIVE_MUTEXES == 1 ) */
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
#if( configUSE_QUEUE_SETS == 1 )
|
||||
|
||||
QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet,
|
||||
const TickType_t xTicksToWait )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore,
|
||||
QueueSetHandle_t xQueueSet )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
#endif /* ( configUSE_QUEUE_SETS == 1 ) */
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
#if( configQUEUE_REGISTRY_SIZE > 0 )
|
||||
|
||||
void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, const char * pcName )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
const char * MPU_pcQueueGetName( QueueHandle_t xQueue )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
#endif /* ( configQUEUE_REGISTRY_SIZE > 0 ) */
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
#if( configUSE_TIMERS == 1 )
|
||||
|
||||
void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
void MPU_vTimerSetTimerID( TimerHandle_t xTimer, void * pvNewID )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
BaseType_t MPU_xTimerGenericCommandEntry( const xTimerGenericCommandParams_t * pxParams )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
const char * MPU_pcTimerGetName( TimerHandle_t xTimer )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, const BaseType_t uxAutoReload )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer )
|
||||
__attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL;
|
||||
|
||||
#endif /* ( configUSE_TIMERS == 1 ) */
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
#endif /* MPU_PROTOTYPES_H */
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -28,8 +28,6 @@
|
|||
|
||||
.arm
|
||||
.syntax unified
|
||||
/* All code in the portASM.S file is intended to be run from a prvileged
|
||||
* operating mode, as such mark the entire file as privileged_functions */
|
||||
.section privileged_functions
|
||||
|
||||
#define FREERTOS_ASSEMBLY
|
||||
|
|
@ -37,583 +35,464 @@
|
|||
#include "mpu_syscall_numbers.h"
|
||||
#undef FREERTOS_ASSEMBLY
|
||||
|
||||
/* External FreeRTOS-Kernel Variables */
|
||||
/* External FreeRTOS-Kernel variables. */
|
||||
.extern pxCurrentTCB
|
||||
.extern uxSystemCallImplementations
|
||||
.extern ulPortInterruptNesting
|
||||
.extern ulPortYieldRequired
|
||||
|
||||
/* External Linker script variables that are needed by the port */
|
||||
.extern __privileged_functions_start__
|
||||
.extern __privileged_functions_end__
|
||||
.extern __privileged_stacks_start__
|
||||
.extern __privileged_stacks_end__
|
||||
.extern __syscalls_flash_length__
|
||||
/* External Llnker script variables. */
|
||||
.extern __syscalls_flash_start__
|
||||
.extern __syscalls_flash_end__
|
||||
|
||||
/* External FreeRTOS-Kernel Functions */
|
||||
.extern vAssertCalled
|
||||
/* External FreeRTOS-Kernel functions. */
|
||||
.extern vTaskSwitchContext
|
||||
.extern vApplicationIRQHandler
|
||||
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
/* Save the register context of a FreeRTOS Task. */
|
||||
|
||||
/* Save the context of a FreeRTOS Task. */
|
||||
.macro portSAVE_CONTEXT
|
||||
DSB
|
||||
ISB
|
||||
/* Push R0 and the Link Register (LR) for scratch register space */
|
||||
/* Push R0 and LR to the stack for current mode. */
|
||||
PUSH { R0, LR }
|
||||
/* Load the pointer to the current task's Task Control Block (TCB) */
|
||||
LDR LR, =pxCurrentTCB
|
||||
/* Load the actual TCB into LR */
|
||||
LDR LR, [LR]
|
||||
/* Set LR to pxTopOfStack, the address of where to save the task context */
|
||||
LDR LR, [LR]
|
||||
|
||||
/* Load the address of ulCriticalNesting */
|
||||
LDR R0, =ulCriticalNesting
|
||||
/* Load the value of ulCriticalNesting into R0 */
|
||||
LDR R0, [R0]
|
||||
/* Push the value of ulCriticalNesting into the context, auto-increment the
|
||||
* LR by using the ! operator. */
|
||||
STM LR!, { R0 }
|
||||
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 )
|
||||
/* Save the floating point context */
|
||||
/* Copy the Floating Point Status and Control Register (FPSRC) */
|
||||
FMRX R0, FPSCR
|
||||
/* Push the value of FPSCR onto the stack */
|
||||
STM LR!, { R0 }
|
||||
/* Push the 32 Floating Point Registers (FPRs) onto the stack */
|
||||
VSTM LR!, { D0-D15 }
|
||||
VMRS R0, FPSCR /* R0 = FPSCR. */
|
||||
STM LR!, { R0 } /* Store FPSCR. */
|
||||
VSTM LR!, { D0-D15 } /* Store D0-D15. */
|
||||
#endif /* ( portENABLE_FPU == 1 ) */
|
||||
|
||||
/* Restore the saved register */
|
||||
POP { R0 }
|
||||
/* Save the General Purpose Registers (GPRs). Also save the pre-exception
|
||||
* Stack Pointer (SP) and LR. The ^ operator causes this instruction to store
|
||||
* the mode selected in the Saved Program Status Register (SPSR) */
|
||||
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 }^
|
||||
/* Not allowed to auto-increment with ! when using banked registers */
|
||||
ADD LR, LR, #portREGISTER_LENGTH
|
||||
/* Pop the pushed LR, which is the pre-exception Program Counter (PC) */
|
||||
POP { R0 }
|
||||
/* Copy the pre-exception Current Program Status Register (CPSR), which,
|
||||
* is banked as the SPSR and save it as part of the task context */
|
||||
MRS R1, SPSR
|
||||
/* Store the pre-exception CPSR and PC */
|
||||
STM LR!, { R0-R1 }
|
||||
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 register context of a FreeRTOS Task. */
|
||||
|
||||
/* 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
|
||||
/* Load the actual TCB into LR */
|
||||
LDR LR, [LR]
|
||||
/* Set R1 to the second member of the TCB struct, xMPUSettings */
|
||||
ADD R1, LR, #0x4
|
||||
/* Set LR to pxTopOfStack, the address to restore the task context from */
|
||||
LDR LR, [LR]
|
||||
/* Load the first per-task MPU region into R5 */
|
||||
MOV R5, #portFIRST_CONFIGURABLE_REGION
|
||||
/* 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:
|
||||
/* Load values of struct MPU_REGION_REGISTERS into R2-R4 */
|
||||
LDMIA R1!, { R2-R4 }
|
||||
/* Load the values set in xMPU_REGION_REGISTERS
|
||||
* R2 Will hold ulRegionSize
|
||||
* R3 will hold ulRegionAttribute
|
||||
* R4 will hold ulRegionBaseAddress
|
||||
* R5 will hold the MPU Region number */
|
||||
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. */
|
||||
|
||||
/* Select the MPU Region using R5 */
|
||||
MCR p15, #0, R5, c6, c2, #0
|
||||
/* Set the MPU Region Base Address using ulRegionBaseAddress */
|
||||
MCR p15, #0, R4, c6, c1, #0
|
||||
/* Set the MPU Region Access Attributes using ulRegionAttribute */
|
||||
MCR p15, #0, R3, c6, c1, #4
|
||||
/* Set the MPU Region Size, and if the region is enabled using ulRegionSize */
|
||||
MCR p15, #0, R2, c6, c1, #2
|
||||
/* R5++ */
|
||||
ADD R5, R5, #1
|
||||
/* R5 <= R6 */
|
||||
CMP R5, #portNUM_CONFIGURABLE_REGIONS
|
||||
/* R5 <= R6, loop again */
|
||||
BLE 123b
|
||||
/* R5 > portSTACK_REGION, all MPU regions have been restored */
|
||||
|
||||
/* Load the address of the ulCriticalNesting variable into R1 */
|
||||
LDR R1, =ulCriticalNesting
|
||||
/* Pop the previously saved value of ulCriticalNesting from ulContext */
|
||||
LDM LR!, { R2 }
|
||||
/* Store the value of ulCriticalNesting into address of ulCriticalNesting */
|
||||
STR R2, [R1]
|
||||
LDR R1, =ulCriticalNesting /* R1 = &( ulCriticalNesting ). */
|
||||
LDM LR!, { R2 } /* R2 = Stored ulCriticalNesting. */
|
||||
STR R2, [R1] /* Restore ulCriticalNesting. */
|
||||
|
||||
#if ( portENABLE_FPU == 1 )
|
||||
/* Restore Floating Point Context: Restore previous FPSCR from ulContext */
|
||||
LDM LR!, { R1 }
|
||||
/* Move the saved FPSCR value into the FPSCR */
|
||||
VMSR FPSCR, R1
|
||||
/* Restore the Floating Point Registers */
|
||||
VLDM LR!, { D0-D15 }
|
||||
LDM LR!, { R1 } /* R1 = Stored FPSCR. */
|
||||
VMSR FPSCR, R1 /* Restore FPSCR. */
|
||||
VLDM LR!, { D0-D15 } /* Restore D0-D15. */
|
||||
#endif /* portENABLE_FPU*/
|
||||
|
||||
/* Load the value of the CPSR into R0, needed to set the SP and the LR */
|
||||
LDR R0, [LR, +#(portREGISTER_LENGTH + 4UL)]
|
||||
/* Move the CPSR the into our SPSR */
|
||||
MSR SPSR_cxsf, R0
|
||||
/* Restore the saved Stack Pointer and Link Register into User Mode */
|
||||
/* 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 }^
|
||||
/* Not allowed to auto-increment with ! when using banked registers */
|
||||
ADD LR, LR, #portREGISTER_LENGTH
|
||||
/* Load the PC to return from the exception */
|
||||
RFE LR
|
||||
ADD LR, LR, #60 /* R0-R14 - Total 155 register, each 4 byte wide. */
|
||||
|
||||
RFE LR /* Restore PC and CPSR from the context. */
|
||||
|
||||
.endm
|
||||
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
/* Load the context of the first task, starting the FreeRTOS-Scheduler */
|
||||
|
||||
/*
|
||||
* void vPortStartFirstTask( void );
|
||||
*/
|
||||
.align 4
|
||||
.global vPortStartFirstTask
|
||||
.type vPortStartFirstTask, %function
|
||||
vPortStartFirstTask:
|
||||
/** This function is called from System Mode to start the FreeRTOS-Kernel.
|
||||
* This is done by restoring the context of the first task.
|
||||
* Restoring the context of a task will allow interrupts.
|
||||
* This allows the FreeRTOS Scheduler Tick to start, and therefore
|
||||
* starts the FreeRTOS-Kernel.
|
||||
*/
|
||||
/* Swap to SVC Mode for context restore */
|
||||
/* 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
|
||||
/* Load the context of first task, starting the FreeRTOS-Scheduler */
|
||||
portRESTORE_CONTEXT
|
||||
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
/* Handler for Supervisor Calls (SVCs) when using this FreeRTOS Port
|
||||
* Upon entering here the LR, or R14, will hold the address of the following
|
||||
* instruction. This then checks that instruction for the SVC # raised.
|
||||
* Checks:
|
||||
* 1. SVC is raised from the system call section (i.e. application is
|
||||
* not raising SVC directly).
|
||||
* 2. pxMpuSettings->xSystemCallStackInfo.pulTaskStack must be NULL as
|
||||
* it is non-NULL only during the execution of a system call (i.e.
|
||||
* between system call enter and exit).
|
||||
* 3. System call is not for a kernel API disabled by the configuration
|
||||
* in FreeRTOSConfig.h.
|
||||
* 4. We do not need to check that ucSystemCallNumber is within range
|
||||
* because the assembly SVC handler checks that before calling
|
||||
* this function.
|
||||
*/
|
||||
|
||||
.align 4
|
||||
.global FreeRTOS_SVC_Handler
|
||||
.type FreeRTOS_SVC_Handler, %function
|
||||
FreeRTOS_SVC_Handler:
|
||||
/* Push R11-R12 for scratch space */
|
||||
PUSH { R11-R12 }
|
||||
|
||||
/* ------------------------- Caller Flash Location Check ------------------------- */
|
||||
|
||||
/* The address of the caller will be in the Link Register (LR), it will
|
||||
* be the caller's Program Counter (PC). Check this address to ensure the
|
||||
* Supervisor call (SVC) was raised from inside the FreRTOS-Kernel. */
|
||||
|
||||
/* Get the starting address for FreeRTOS System Calls */
|
||||
LDR R12, =__syscalls_flash_start__
|
||||
/* Subtract the start point from the Program Counter of the caller */
|
||||
SUB R11, LR, R12
|
||||
/* Now check if it is less than the length of the section */
|
||||
LDR R12, =__syscalls_flash_length__
|
||||
/* Check if an SVC was raised after the end of FreeRTOS System Calls */
|
||||
CMP R11, R12
|
||||
/* If the SVC was raised from outside FreeRTOS System Calls exit now */
|
||||
BGE SVC_Handler_Exit
|
||||
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 ---------------------------- */
|
||||
|
||||
/* The SPSR will be the CPSR of the calling task, store it in R11 */
|
||||
MRS R11, SPSR
|
||||
/* Thumb Mode is bit 5 of the CPSR, AND for comparison */
|
||||
ANDS R11, R11, #0x20
|
||||
/* In Thumb Mode, the instruction 0x2 before holds the SVC numebr */
|
||||
LDRHNE R11, [LR, #-0x2]
|
||||
/* Not in Thumb Mode, the instruction 0x4 before holds the SVC numebr */
|
||||
LDRHEQ R11, [LR, #-0x4]
|
||||
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 --------------------------------- */
|
||||
|
||||
/* Determine if the SVC number is below #NUM_SYSTEM_CALLS */
|
||||
/* If SVC Number < #NUM_SYSTEM_CALLS, go to svcSystemCallEnter. */
|
||||
CMP R11, #NUM_SYSTEM_CALLS
|
||||
/* If it is go to the entry point for FreeRTOS System Calls */
|
||||
BLT svcSystemCallEnter
|
||||
|
||||
/* Check if the caller is leaving a FreeRTOS System Call */
|
||||
/* If SVC Number == #portSVC_SYSTEM_CALL_EXIT, go to svcSystemCallExit. */
|
||||
CMP R11, #portSVC_SYSTEM_CALL_EXIT
|
||||
BEQ svcSystemCallExit
|
||||
|
||||
/* Check if the caller is requesting to yield */
|
||||
/* If SVC Number == #portSVC_YIELD, go to svcPortYield. */
|
||||
CMP R11, #portSVC_YIELD
|
||||
BEQ svcPortYield
|
||||
|
||||
/* If one of the above jumps wasn't taken, go straight to the exit */
|
||||
SVC_Handler_Exit:
|
||||
/** Restore the saved R11 and R12, then return to the caller */
|
||||
svcHandlerExit:
|
||||
POP { R11-R12 }
|
||||
/* This instruction loads the SPSR into the CPSR, performing the mode swap */
|
||||
MOVS PC, LR
|
||||
MOVS PC, LR /* Copies the SPSR into the CPSR, performing the mode swap. */
|
||||
|
||||
/* Perform a task swap */
|
||||
svcPortYield:
|
||||
/* Restore the previously saved R11, R12 */
|
||||
POP { R11-R12 }
|
||||
/* Save the context of the current task and select a new task to run. */
|
||||
portSAVE_CONTEXT
|
||||
/* Select a new task to swap to */
|
||||
BL vTaskSwitchContext
|
||||
/* Restore the context of the task selected to execute. */
|
||||
portRESTORE_CONTEXT
|
||||
|
||||
/* Reset task stack and link register after a FreeRTOS System Call */
|
||||
svcSystemCallExit:
|
||||
/* Restore the Task Stack Pointer and Link Register */
|
||||
/* Load the address of pxCurrentTCB into R11 */
|
||||
LDR R11, =pxCurrentTCB
|
||||
/* Load pxCurrentTCB into R11 */
|
||||
LDR R11, [R11]
|
||||
/* Set R11 to be the location of xSystemCallStackInfo inside the TCB */
|
||||
ADD R11, R11, #portSYSTEM_CALL_INFO_OFFSET
|
||||
/* Restore the user mode Stack Pointer and Link Register */
|
||||
LDMIB R11, { R13-R14 }^
|
||||
/* Zero out R12 so we can set ulTaskStackPointer back to NULL */
|
||||
AND R12, R12, #0x0
|
||||
/* Set pulTaskStackPointer to be 0x0 */
|
||||
STR R12, [R11, #0x4]
|
||||
/* Set pulLinkRegisterAtSystemCallEntry to be 0x0 */
|
||||
STR R12, [R11, #0x8]
|
||||
/* Load the ulTaskFlag so we can determine if we're going to lower privilege */
|
||||
LDM R11, { R12 }
|
||||
/* Check if the task is privileged */
|
||||
CMP R12, #portTASK_IS_PRIVILEGED_FLAG
|
||||
/* If the task is privileged we can leave now */
|
||||
BEQ SVC_Handler_Exit
|
||||
/* Otherwise, we need to set the SPSR back to USER mode */
|
||||
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
|
||||
/* Clear the last 4 bits, which are the MODE bits */
|
||||
BIC R12, R12, #0x0F
|
||||
/* Move the new value into the SPSR */
|
||||
MSR SPSR_cxsf, R12
|
||||
/* Jump back */
|
||||
B SVC_Handler_Exit
|
||||
|
||||
/* Save task's SP and LR, swap to ulSystemCallStack Buffer, raise privilege */
|
||||
B svcHandlerExit
|
||||
|
||||
svcSystemCallEnter:
|
||||
/* Load the base address of the uxSystemCallImplementations[] table into R14 */
|
||||
LDR R14, =uxSystemCallImplementations
|
||||
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]
|
||||
|
||||
/** Shift the value of R11, the SVC number, left by two to get the jump offset
|
||||
* Add this offset to R14, which holds the jump table address. This is the address
|
||||
* of the SVC that the relevant function is trying to complete.
|
||||
* Now when the Link Register is loaded as the Program Counter at the end of this
|
||||
* handler, the caller will immediately execute the requested function */
|
||||
LDR R14, [R14, R11, lsl #2]
|
||||
/* If R12 == NULL, exit. */
|
||||
CMP R12, #0x0
|
||||
BEQ svcHandlerExit
|
||||
|
||||
/* Load the address of pxCurrentTCB into R11 */
|
||||
LDR R11, =pxCurrentTCB
|
||||
/* Load pxCurrentTCB into R11 */
|
||||
LDR R11, [R11]
|
||||
/* Set R11 to be the location of xSystemCallStackInfo inside the TCB */
|
||||
ADD R11, R11, #portSYSTEM_CALL_INFO_OFFSET
|
||||
/* Get the value in the TCB for ulTaskStackPointer */
|
||||
LDMIB R11!, { R12 }
|
||||
/* Ensure ulTaskStackPointer is null, signifying initial entry */
|
||||
TEQ R12, #0x0
|
||||
/* Make sure that the function pointer loaded is not NULL */
|
||||
CMPEQ R14, #0x0
|
||||
/* 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
|
||||
|
||||
/* Hard code the ascii value of the function name and line number to call
|
||||
* assert if the ulTaskStackPointer is not null. */
|
||||
MOVWEQ R0, #0x706F
|
||||
MOVTEQ R0, #0x7274
|
||||
MOVEQ R1, #342
|
||||
BEQ vAssertCalled
|
||||
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 the task's SP and LR to xSYSTEM_CALL_STACK_INFO */
|
||||
/* Store User mode SP and LR in xSystemCallStackInfo.pulTaskStackPointer and
|
||||
* xSystemCallStackInfo.pulLinkRegisterAtSystemCallEntry. */
|
||||
STM R11, { R13-R14 }^
|
||||
/* Not allowed to auto-increment with ! when using banked registers */
|
||||
ADD R11, R11, 0x8
|
||||
/* Load pulSystemCallStackPointer and pulSystemCallLinkRegister now */
|
||||
|
||||
/* Load User mode SP an LR with xSystemCallStackInfo.pulSystemCallStackPointer
|
||||
* and xSystemCallStackInfo.pulSystemCallExitAddress. */
|
||||
LDM R11, { R13-R14 }^
|
||||
|
||||
/* Swap the SPSR to SYS_MODE for the System Call. Move SPSR into R12 */
|
||||
/* Change to SYS_MODE for the System Call. */
|
||||
MRS R12, SPSR
|
||||
/* Set the MODE bits to SYS_MODE */
|
||||
ORR R12, R12, #SYS_MODE
|
||||
/* Assign the new value to SPSR */
|
||||
MSR SPSR_cxsf, R12
|
||||
/* Leave through the SVC Exit */
|
||||
B SVC_Handler_Exit
|
||||
|
||||
B svcHandlerExit
|
||||
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
/* Disable IRQs and increment the critical nesting count */
|
||||
.align 4
|
||||
.global vPortEnterCritical
|
||||
.type vPortEnterCritical, %function
|
||||
vPortEnterCritical:
|
||||
/* Disable IRQs */
|
||||
CPSID I
|
||||
/* Save scratch registers */
|
||||
PUSH { R0-R1 }
|
||||
/* Load address of current critical nesting count */
|
||||
LDR R0, =ulCriticalNesting
|
||||
/* Load value of current critical nesting count */
|
||||
LDR R1, [R0]
|
||||
/* Add one to ulCriticalNesting */
|
||||
ADD R1, R1, #1
|
||||
/* Store the modified ulCriticalNesting back into RAM */
|
||||
STR R1, [R0]
|
||||
/* Restore pushed registers */
|
||||
POP { R0-R1 }
|
||||
/* Return to caller */
|
||||
BX LR
|
||||
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
/* Disable IRQs */
|
||||
/*
|
||||
* void vPortDisableInterrupts( void );
|
||||
*/
|
||||
.align 4
|
||||
.global vPortDisableInterrupts
|
||||
.type vPortDisableInterrupts, %function
|
||||
vPortDisableInterrupts:
|
||||
/* Disable IRQs */
|
||||
CPSID I
|
||||
/* Return to caller */
|
||||
BX LR
|
||||
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
/* Enable IRQs and decrement the critical nesting count */
|
||||
.align 4
|
||||
.global vPortExitCritical
|
||||
.type vPortExitCritical, %function
|
||||
vPortExitCritical:
|
||||
/* Store two scratch registers and LR for IRQ Mode re-entry */
|
||||
PUSH { R0-R1, LR }
|
||||
/* Load address of current critical nesting count */
|
||||
LDR R0, =ulCriticalNesting
|
||||
/* Load value of current critical nesting count */
|
||||
LDR R1, [R0]
|
||||
/* Check if the count is 0 */
|
||||
CMP R1, #0
|
||||
/* If ulCriticalNesting is greater than 0, Subtract 1 from it */
|
||||
SUBGT R1, R1, #1
|
||||
/* Store the modified ulCriticalNesting back into RAM */
|
||||
STRGT R1, [R0]
|
||||
/* Enable IRQs */
|
||||
CPSIE I
|
||||
/* Restore Pushed registers */
|
||||
POP { R0-R1, LR }
|
||||
/* Return to caller */
|
||||
BX LR
|
||||
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
/* Enable IRQs */
|
||||
/*
|
||||
* void vPortEnableInterrupts( void );
|
||||
*/
|
||||
.align 4
|
||||
.global vPortEnableInterrupts
|
||||
.type vPortEnableInterrupts, %function
|
||||
vPortEnableInterrupts:
|
||||
/* Push LR to account for re-entry in IRQ Mode */
|
||||
PUSH { LR }
|
||||
/* Enable IRQs */
|
||||
CPSIE I
|
||||
/* Restore previous LR */
|
||||
POP { LR }
|
||||
/* Return to caller */
|
||||
BX LR
|
||||
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
/** Set MPU Registers using provided values
|
||||
* Function: void vMPUSetRegion
|
||||
* Inputs: uint32_t ulRegionNumber
|
||||
* Inputs: uint32_t ulBaseAddress
|
||||
* Inputs: uint32_t ulRegionSize
|
||||
* Inputs: uint32_t ulRegionPermissions
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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:
|
||||
/* Only 15 possible regions, drop all other bits */
|
||||
AND R0, R0, #15
|
||||
/* Select the MPU Region selected by ulRegionNumber */
|
||||
MCR p15, #0, R0, c6, c2, #0
|
||||
/* Set the Base Address to be ulBaseAddress */
|
||||
MCR p15, #0, R1, c6, c1, #0
|
||||
/* Set the Access Attributes to be ulRegionPermissions */
|
||||
MCR p15, #0, R3, c6, c1, #4
|
||||
/* Set the Size and Enable bits to be ulRegionSize */
|
||||
MCR p15, #0, R2, c6, c1, #2
|
||||
/* Return to caller */
|
||||
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
|
||||
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
/* Set the Enable bit of the MPU Enable Register to 1. */
|
||||
|
||||
/*
|
||||
* void vMPUEnable( void );
|
||||
*/
|
||||
.align 4
|
||||
.global vMPUEnable
|
||||
.type vMPUEnable, %function
|
||||
vMPUEnable:
|
||||
/* Read the current MPU control register into R0 */
|
||||
MRC p15, #0, R0, c1, c0, #0
|
||||
/* Set the enable bit to high */
|
||||
ORR R0, R0, #0x1
|
||||
/* Data sync */
|
||||
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
|
||||
/* Write out previous MPU control register with a high enable bit */
|
||||
MCR p15, #0, R0, c1, c0, #0
|
||||
/* Instruction sync */
|
||||
MCR p15, #0, R0, c1, c0, #0 /* SCTLR = R0. */
|
||||
ISB
|
||||
/* Return to caller */
|
||||
|
||||
POP { R0 }
|
||||
BX LR
|
||||
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
/* Set the Enable bit of the MPU Enable Register to 0. */
|
||||
|
||||
/*
|
||||
* void vMPUDisable( void );
|
||||
*/
|
||||
.align 4
|
||||
.global vMPUDisable
|
||||
.type vMPUDisable, %function
|
||||
vMPUDisable:
|
||||
/* Read the MPU enable register values into R0 */
|
||||
MRC p15, #0, R0, c1, c0, #0
|
||||
/* Perform a bitwise AND of R0 and NOT #1, i.e. clear bit 1 */
|
||||
BIC R0, R0, #1
|
||||
/* Wait for all pending explicit data accesses to complete */
|
||||
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
|
||||
/* Write out to the MPU Enable Register */
|
||||
MCR p15, #0, R0, c1, c0, #0
|
||||
/* Flushes the pipeline and prefetch buffer(s) in the processor. */
|
||||
/* Ensures all following instructions are fetched from cache or memory. */
|
||||
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
|
||||
/* Return to caller */
|
||||
|
||||
POP { R0 }
|
||||
BX LR
|
||||
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
/* Enable the MPU Background Region */
|
||||
|
||||
/*
|
||||
* void vMPUEnableBackgroundRegion( void );
|
||||
*/
|
||||
.align 4
|
||||
.global vMPUEnableBackgroundRegion
|
||||
.type vMPUEnableBackgroundRegion, %function
|
||||
vMPUEnableBackgroundRegion:
|
||||
/* Save value in R0 */
|
||||
PUSH { R0 }
|
||||
/* Read CP15 System Control Register into R0 */
|
||||
MRC p15, 0, R0, c1, c0, 0
|
||||
/* Set bit 17 so that privileged modes won't trigger unmapped MPU region faults */
|
||||
ORR R0, R0, #0x20000
|
||||
/* Write the value back out */
|
||||
MCR p15, 0, R0, c1, c0, 0
|
||||
/* Restore the used register */
|
||||
|
||||
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 }
|
||||
/* Return to the caller */
|
||||
BX LR
|
||||
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
/* Disable the MPU Background Region */
|
||||
|
||||
/*
|
||||
* void vMPUDisableBackgroundRegion( void );
|
||||
*/
|
||||
.align 4
|
||||
.global vMPUDisableBackgroundRegion
|
||||
.type vMPUDisableBackgroundRegion, %function
|
||||
vMPUDisableBackgroundRegion:
|
||||
/* Save value in R0 */
|
||||
PUSH { R0 }
|
||||
/* Read CP15 System Control Register into R0 */
|
||||
MRC p15, 0, R0, c1, c0, 0
|
||||
/* Clear bit 17 so that privileged modes won't trigger unmapped MPU region faults */
|
||||
BIC R0, R0, #0x20000
|
||||
/* Write the value back out */
|
||||
MCR p15, 0, R0, c1, c0, 0
|
||||
/* Restore the used register */
|
||||
|
||||
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 }
|
||||
/* Return to the caller */
|
||||
BX LR
|
||||
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
.align 4
|
||||
.global FreeRTOS_IRQ_Handler
|
||||
.type FreeRTOS_IRQ_Handler, %function
|
||||
FreeRTOS_IRQ_Handler:
|
||||
/* Disable IRQs */
|
||||
CPSID I
|
||||
/* Return to the interrupted instruction. */
|
||||
SUB LR, LR, #4
|
||||
/* Save the return state to the IRQ stack */
|
||||
SRSDB SP!, #IRQ_MODE
|
||||
/* Push used registers. */
|
||||
PUSH { R0-R3, R12 }
|
||||
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. */
|
||||
|
||||
/* Load &ulPortInterruptNesting into R0 */
|
||||
LDR R0, =ulPortInterruptNesting
|
||||
/* Load the value of ulPortInterruptNesting into R1 */
|
||||
LDR R1, [R0]
|
||||
/* R2 = ulPortInterruptNesting + 1 */
|
||||
ADD R2, R1, #1
|
||||
/* Store the value of ulPortInterruptNesting++ back into the variable */
|
||||
STR R2, [R0]
|
||||
/* 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
|
||||
|
||||
/* Save Calling Registers */
|
||||
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 }
|
||||
/* Call the User provided IRQ handler */
|
||||
BL vApplicationIRQHandler
|
||||
POP { R0-R3, LR }
|
||||
|
||||
/* Disable IRQs incase vApplicationIRQHandler enabled them for re-entry */
|
||||
CPSID I
|
||||
/* Perform a data and instruction buffer flush */
|
||||
/* Disable IRQs incase vApplicationIRQHandler enabled them for re-entry. */
|
||||
CPSID I
|
||||
DSB
|
||||
ISB
|
||||
|
||||
/* Restore the previous registers */
|
||||
POP { R0-R3, LR }
|
||||
/* R0 holds the address of ulPortInterruptNesting, R1 holds original value */
|
||||
/* Restore the old interrupt nesting count. R0 holds the address of
|
||||
* ulPortInterruptNesting and R1 holds original value of
|
||||
* ulPortInterruptNesting. */
|
||||
STR R1, [R0]
|
||||
/* Check if ulPortInterruptNesting is 0 */
|
||||
|
||||
/* Context swtich is only performed when interrupt nesting count is 0. */
|
||||
CMP R1, #0
|
||||
/* If ulPortInterruptNesting is not zero, unwind the nested interrupt */
|
||||
BNE exit_without_switch
|
||||
|
||||
/* ulPortInterruptNesting is zero, check if ulPortYieldRequired is set */
|
||||
LDR R1, =ulPortYieldRequired
|
||||
/* Load the value of ulPortYieldRequired */
|
||||
LDR R0, [R1]
|
||||
/* Check if the value of ulPortYieldRequired is zero */
|
||||
/* 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
|
||||
/* If it is non-zero select a new task to run */
|
||||
BNE switch_before_exit
|
||||
|
||||
exit_without_switch:
|
||||
/* No context switch. Restore used registers, LR_irq and SPSR before returning. */
|
||||
POP { R0-R3, R12 }
|
||||
/* Return from exception, load pre-exception PC and CPSR */
|
||||
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 the context switch pending flag. */
|
||||
/* A context swtich is to be performed. Clear ulPortYieldRequired. R1 holds
|
||||
* the address of ulPortYieldRequired. */
|
||||
MOV R0, #0
|
||||
/* Set ulPortYieldRequired back to zero */
|
||||
STR R0, [R1]
|
||||
|
||||
/* Restore used registers, LR_irq and SPSR before saving the context */
|
||||
/* Restore AAPCS callee saved registers, SPSR_irq and LR_irq before saving
|
||||
* the task context. */
|
||||
POP { R0-R3, R12 }
|
||||
/* Load the pushed SPSR from the stack */
|
||||
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 }
|
||||
/* Move it into the SPSR */
|
||||
MSR SPSR_cxsf, LR
|
||||
/* Load the pushed pre-exception Program Counter into LR_irq */
|
||||
LDMDB SP, { LR }
|
||||
/* Increment the Stack Pointer an additional 0x4 */
|
||||
ADD SP, SP, 0x4
|
||||
/* Save the current task's context */
|
||||
portSAVE_CONTEXT
|
||||
|
||||
/* Call the function that selects the new task to execute. */
|
||||
BLX vTaskSwitchContext
|
||||
|
||||
/* Restore the context of the selected task, which will start executing. */
|
||||
/* Restore the context of, and branch to, the task selected to execute
|
||||
* next. */
|
||||
portRESTORE_CONTEXT
|
||||
|
||||
/* ----------------------------------------------------------------------------------- */
|
||||
|
||||
.end
|
||||
|
|
|
|||
|
|
@ -40,45 +40,29 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Include stdint for integer types of specific bit widths */
|
||||
/* Include stdint for integer types of specific bit widths. */
|
||||
#include <stdint.h>
|
||||
|
||||
/* ------------------------------ FreeRTOS Config Check ------------------------------ */
|
||||
|
||||
/* Include the FreeRTOS Config file first to get the includes being used */
|
||||
#include "FreeRTOSConfig.h"
|
||||
|
||||
#ifndef configENABLE_MPU
|
||||
#define configENABLE_MPU 1
|
||||
#elif( configENABLE_MPU != 1 )
|
||||
#error "This port is only usable with configENABLE_MPU set to 1"
|
||||
#endif /* configENABLE_MPU */
|
||||
|
||||
#ifndef configENABLE_ACCESS_CONTROL_LIST
|
||||
#define configENABLE_ACCESS_CONTROL_LIST 1
|
||||
#endif /* configENABLE_ACCESS_CONTROL_LIST */
|
||||
|
||||
#ifndef configPROTECTED_KERNEL_OBJECT_POOL_SIZE
|
||||
#error "Set configPROTECTED_KERNEL_OBJECT_POOL_SIZE to at least the " \
|
||||
"number of FreeRTOS-Kernel Objects to be created"
|
||||
#endif /* configPROTECTED_KERNEL_OBJECT_POOL_SIZE */
|
||||
|
||||
/**
|
||||
* @brief The size in Bytes that the Privileged System Call Stack should be.
|
||||
*
|
||||
* @ingroup MPU Privilege
|
||||
*
|
||||
* @note A Stack of this length, in bytes, is used by FreeRTOS APIs when called
|
||||
* by an unprivileged task.
|
||||
*/
|
||||
#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 " \
|
||||
|
|
@ -88,115 +72,95 @@ extern "C" {
|
|||
#endif /* ( configMAX_PRIORITIES > 32 ) */
|
||||
|
||||
/**
|
||||
* @brief Mark that a task of the current priority is ready for execution.
|
||||
* @brief Mark that a task of the given priority is ready.
|
||||
*
|
||||
* @ingroup Scheduler
|
||||
*
|
||||
* @param[in] uxPriority Priority of task that can enter the ready state
|
||||
* @param[out] uxTopReadyPriority Bitmap of tasks that are in the ready state
|
||||
* @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 current priority has left the ready state.
|
||||
* @brief Mark that a task of the given priority is no longer ready.
|
||||
*
|
||||
* @ingroup Scheduler
|
||||
*
|
||||
* @param[in] uxPriority Priority of task that is leaving the ready state
|
||||
* @param[out] uxTopReadyPriority Bitmap of tasks that are in the ready state
|
||||
* @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 what the highest priority ready task is.
|
||||
* @brief Determine the highest priority ready task's priority.
|
||||
*
|
||||
* @ingroup Scheduler
|
||||
*
|
||||
* @param[out] uxTopReadyPriority Bitmap of tasks that are in the ready state
|
||||
* @param[out] uxTopPriority The highest priority ready task's priority value.
|
||||
* @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 ) ) )
|
||||
( uxTopPriority ) = ( 31UL - ulPortCountLeadingZeros( ( uxTopReadyPriority ) ) )
|
||||
|
||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
|
||||
#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_TICKLESS_IDLE != 0 )
|
||||
#error This port does not support tickless idle
|
||||
#endif /* ( configUSE_TICKLESS_IDLE != 0 ) */
|
||||
|
||||
/* ------------------------------ Port Type Definitions ------------------------------ */
|
||||
|
||||
#include "portmacro_asm.h"
|
||||
|
||||
/**
|
||||
* @brief Critical section nesting value to mark the end of a critical section.
|
||||
* @brief Critical section nesting value.
|
||||
*
|
||||
* @ingroup Critical Sections
|
||||
*
|
||||
* @note
|
||||
* A critical section is exited when the critical section nesting count reaches
|
||||
* this value. When exiting a critical section IRQs are re-enabled.
|
||||
* A task exits critical section and enables IRQs when its nesting count reaches
|
||||
* this value.
|
||||
*/
|
||||
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0x0 )
|
||||
|
||||
/**
|
||||
* @brief Bit value used to mark if the CPU is currently executing in Thumb Mode.
|
||||
* @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 Value used to check if a task's function is a Thumb function.
|
||||
* @brief Bitmask to check if an address is of Thumb Code.
|
||||
*
|
||||
* @ingroup Task Context
|
||||
*/
|
||||
#define portTHUMB_MODE_ADDRESS ( 0x01UL )
|
||||
|
||||
/**
|
||||
* @brief Unsigned Data type equal to the data word operating size of the CPU.
|
||||
* @brief Data type used to represent a stack word.
|
||||
*
|
||||
* @ingroup Port Interface Specifications
|
||||
*
|
||||
* @note
|
||||
* The FreeRTOS-Kernel needs to be able to use an unsigned type that is
|
||||
* the most efficient, natural type for the targeted architecture.
|
||||
*/
|
||||
typedef uint32_t StackType_t;
|
||||
|
||||
/**
|
||||
* @brief Signed Data type equal to the data word operating size of the CPU.
|
||||
* @brief Signed data type equal to the data word operating size of the CPU.
|
||||
*
|
||||
* @ingroup Port Interface Specifications
|
||||
*
|
||||
* @note
|
||||
* The FreeRTOS-Kernel needs to be able to use a signed type that is
|
||||
* the most efficient, natural type for the targeted architecture.
|
||||
*/
|
||||
typedef int32_t BaseType_t;
|
||||
|
||||
/**
|
||||
* @brief Unsigned Data type equal to the data word operating size of the CPU.
|
||||
* @brief Unsigned data type equal to the data word operating size of the CPU.
|
||||
*
|
||||
* @ingroup Port Interface Specifications
|
||||
*
|
||||
* @note
|
||||
* The FreeRTOS-Kernel needs to be able to use an unsigned type that is
|
||||
* the most efficient, natural type for the targeted architecture.
|
||||
*/
|
||||
typedef uint32_t UBaseType_t;
|
||||
|
||||
/**
|
||||
* @brief Integer type used for the Tick Counter.
|
||||
* @brief Data type used for the FreeRTOS Tick Counter.
|
||||
*
|
||||
* @note
|
||||
* Use a 32-bit tick type on a 32-bit architecture, so reads of the tick count
|
||||
* do not need to be guarded with a critical section.
|
||||
* @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;
|
||||
|
||||
|
|
@ -204,15 +168,13 @@ 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 at what number of bytes a stack pointer shall be aligned.
|
||||
* @brief Specifies stack pointer alignment requirements of the target CPU.
|
||||
*
|
||||
* @ingroup Port Interface Specifications
|
||||
*
|
||||
*/
|
||||
#define portBYTE_ALIGNMENT 8U
|
||||
|
||||
|
|
@ -221,9 +183,8 @@ typedef uint32_t TickType_t;
|
|||
*
|
||||
* @ingroup Port Interface Specifications
|
||||
*
|
||||
* @note
|
||||
* These are not required for this port but included in case common demo code
|
||||
* that uses these macros is used.
|
||||
* @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 )
|
||||
|
|
@ -233,46 +194,49 @@ typedef uint32_t TickType_t;
|
|||
*
|
||||
* @ingroup Port Interface Specifications
|
||||
*
|
||||
* @note
|
||||
* These are not required for this port but included in case common demo code
|
||||
* that uses these macros is used.
|
||||
* @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 )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) \
|
||||
void vFunction( void * pvParameters )
|
||||
|
||||
/**
|
||||
* @brief Wrapper for the no-op ARM Assembly Instruction.
|
||||
* @brief The no-op ARM assembly instruction.
|
||||
*
|
||||
* @ingroup Port Interface Specifications
|
||||
*/
|
||||
#define portNOP() __asm volatile( "NOP" )
|
||||
|
||||
/**
|
||||
* @brief Wrapper for the Inline GCC Label.
|
||||
* @brief The inline GCC label.
|
||||
*
|
||||
* @ingroup Port Interface Specifications
|
||||
*/
|
||||
#define portINLINE __inline
|
||||
|
||||
/**
|
||||
* @brief Wrapper for the ARM Memory Sync Assembly Instruction.
|
||||
* @brief The memory access synchronization barrier.
|
||||
*
|
||||
* @ingroup Port Interface Specifications
|
||||
*/
|
||||
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
|
||||
|
||||
/**
|
||||
* @brief Defines if the system tick count can be accessed atomically.
|
||||
* @brief Defines if the tick count can be accessed atomically.
|
||||
*
|
||||
* @ingroup System Clock
|
||||
*/
|
||||
#define portTICK_TYPE_IS_ATOMIC 1
|
||||
|
||||
/**
|
||||
* @brief Define the number of miliseconds between system ticks.
|
||||
* @brief The number of miliseconds between system ticks.
|
||||
*
|
||||
* @ingroup System Clock
|
||||
*/
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000UL / configTICK_RATE_HZ )
|
||||
|
||||
/**
|
||||
* @brief Define the larges possible delay value for a task.
|
||||
* @brief The largest possible delay value for any FreeRTOS API.
|
||||
*
|
||||
* @ingroup System Clock
|
||||
*/
|
||||
|
|
@ -280,88 +244,58 @@ typedef uint32_t TickType_t;
|
|||
|
||||
/* ----------------------------- Port Assembly Functions ----------------------------- */
|
||||
|
||||
/** @brief Assembly FreeRTOS Supervisor Call Handler. */
|
||||
/**
|
||||
* @brief FreeRTOS Supervisor Call (SVC) Handler.
|
||||
*
|
||||
* @ingroup Scheduler
|
||||
*/
|
||||
void FreeRTOS_SVC_Handler( void );
|
||||
|
||||
/** @brief Assembly FreeRTOS Interrupt Handler */
|
||||
/**
|
||||
* @brief FreeRTOS Interrupt Handler.
|
||||
*
|
||||
* @ingroup Scheduler
|
||||
*/
|
||||
void FreeRTOS_IRQ_Handler( void );
|
||||
|
||||
/**
|
||||
* @brief Make a Supervisor Call to swap the currently running task out.
|
||||
* @brief Yield the CPU.
|
||||
*
|
||||
* @ingroup Scheduler
|
||||
* @note The FreeRTOS-Kernel needs a method to swap the current task that is
|
||||
* running. The FreeRTOS-Port needs to ensure that when this happens any
|
||||
* hardware specific values related to the current task’s context are properly
|
||||
* saved. A properly saved context can be restored to allow execution of the
|
||||
* task as if it was not interrupted.
|
||||
*/
|
||||
void vPortYield( void );
|
||||
|
||||
/** @brief Raise a Supervisor Call to swap the currently running task out. */
|
||||
#define portYIELD() vPortYield()
|
||||
|
||||
/**
|
||||
* @brief Disable IRQs then increment the critical nesting count.
|
||||
* @ingroup Critical Section
|
||||
*/
|
||||
void vPortEnterCritical( void );
|
||||
|
||||
/** @brief Enter a Critical Section inside of the FreeRTOS-Kernel */
|
||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||
|
||||
/**
|
||||
* @brief Enable IRQs and decrement the critical nesting count.
|
||||
* @ingroup Critical Section
|
||||
*/
|
||||
void vPortExitCritical( void );
|
||||
|
||||
/**
|
||||
* @brief Exit a Critical Section inside of the FreeRTOS-Kernel.
|
||||
* @ingroup Critical Section
|
||||
*/
|
||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||
|
||||
/**
|
||||
* @brief Set the IRQ bit of the CPSR high, enabling IRQs.
|
||||
* @brief Enable interrupts.
|
||||
*
|
||||
* @ingroup Interrupt Management
|
||||
*/
|
||||
void vPortEnableInterrupts( void );
|
||||
|
||||
/**
|
||||
* @brief Enable Interrupts by setting the IRQ allowed flag on the CPU
|
||||
* @ingroup Interrupt Management
|
||||
*/
|
||||
#define portENABLE_INTERRUPTS() vPortEnableInterrupts()
|
||||
|
||||
/**
|
||||
* @brief Set the IRQ bit of the CPSR low, disabling IRQs.
|
||||
* @brief Disable interrupts.
|
||||
*
|
||||
* @ingroup Interrupt Management
|
||||
*/
|
||||
void vPortDisableInterrupts( void );
|
||||
|
||||
/**
|
||||
* @brief Enable Interrupts by lowering the IRQ allowed flag on the CPU.
|
||||
* @ingroup Interrupt Management
|
||||
*/
|
||||
#define portDISABLE_INTERRUPTS() vPortDisableInterrupts()
|
||||
|
||||
/**
|
||||
* @brief Exit the FreeRTOS-Kernel, restoring the task's settings.
|
||||
* @brief Exit from a FreeRTO System Call.
|
||||
*
|
||||
* @ingroup Port Privilege
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void vPortSystemCallExit( void );
|
||||
|
||||
/**
|
||||
* @brief Load the context of the first task.
|
||||
* @brief Start executing first task.
|
||||
*
|
||||
* @ingroup Scheduler
|
||||
*
|
||||
* @note This is an assembly function implemented in portASM.s, it loads the
|
||||
* context of the first task from pxCurrentTCB.
|
||||
*/
|
||||
void vPortStartFirstTask( void );
|
||||
|
||||
|
|
@ -369,8 +303,6 @@ void vPortStartFirstTask( void );
|
|||
* @brief Enable the onboard MPU.
|
||||
*
|
||||
* @ingroup MPU Control
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void vMPUEnable( void );
|
||||
|
||||
|
|
@ -378,8 +310,6 @@ void vMPUEnable( void );
|
|||
* @brief Disable the onboard MPU.
|
||||
*
|
||||
* @ingroup MPU Control
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
void vMPUDisable( void );
|
||||
|
||||
|
|
@ -387,33 +317,28 @@ void vMPUDisable( void );
|
|||
* @brief Enable the MPU Background Region.
|
||||
*
|
||||
* @ingroup MPU Control
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void vMPUEnableBackgroundRegion( void );
|
||||
|
||||
/**
|
||||
* @brief Disable the MPU Background Region
|
||||
* @brief Disable the MPU Background Region.
|
||||
*
|
||||
* @ingroup MPU Control
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void vMPUDisableBackgroundRegion( void );
|
||||
|
||||
/**
|
||||
* @brief Assembly routine to set permissions for an MPU Region.
|
||||
* @brief Set permissions for an MPU Region.
|
||||
*
|
||||
* @ingroup MPU Control
|
||||
*
|
||||
* @param[in] ulRegionNumber The MPU Region Number to change permissions for
|
||||
* @param[in] ulBaseAddress The base address of the MPU Region
|
||||
* @param[in] ulRegionSize The number of bytes to make the MPU Region
|
||||
* @param[in] ulRegionPermissions The permissions to assign to the MPU Region
|
||||
* @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 Assembly Function implemented in portASM.S.
|
||||
* This is meant as a purely internal function that performs a raw write of the
|
||||
* provided values to the relevant MPU Registers. The inputs to this function
|
||||
* are checked internally before it is called in the port.c file.
|
||||
* @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,
|
||||
|
|
@ -422,106 +347,83 @@ void vMPUSetRegion( uint32_t ulRegionNumber,
|
|||
|
||||
/* ------------------------------- 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 Privilege level is determined by checking if bits [4:0] of
|
||||
* the callers Current Program Status Register are in USER_MODE, 0x10
|
||||
*
|
||||
* @return
|
||||
* 0 If the CPSR Mode Bits are set to 0x10
|
||||
* 1 If the CPSR Mode Bits are set to 0x11-0x11F
|
||||
* @note The processor privilege level is determined by checking if bits [4:0]
|
||||
* of the Current Program Status Register (CPSR).
|
||||
*
|
||||
* @return pdTRUE, if the processer is privileged, pdFALSE otherwise.
|
||||
*/
|
||||
BaseType_t xPortIsPrivileged( void );
|
||||
|
||||
/**
|
||||
* @brief Check if the CPU is currently in a privileged operating mode.
|
||||
*
|
||||
* @ingroup Port Privilege
|
||||
*
|
||||
* @return
|
||||
* 1 If the processor is privileged
|
||||
* 0 If the processor is not privileged
|
||||
*
|
||||
*/
|
||||
#define portIS_PRIVILEGED() xPortIsPrivileged()
|
||||
|
||||
/**
|
||||
* @brief Check if ulTaskFlags has portTASK_IS_PRIVILEGED_FLAG.
|
||||
* @brief Checks whether or not a task is privileged.
|
||||
*
|
||||
* @ingroup Port Privilege
|
||||
*
|
||||
* @note
|
||||
* As this loads pxCurrentTCB to determine if the task's ulTaskFlags is privileged
|
||||
* or not, this function can return a different value than xPortIsPrivileged.
|
||||
* 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
|
||||
* 0 If pxCurrentTCB's !( ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG )
|
||||
* 1 If pxCurrentTCB's ( ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG )
|
||||
* @return pdTRUE if the task is privileged, pdFALSE otherwise.
|
||||
*/
|
||||
BaseType_t xPortIsTaskPrivileged( void );
|
||||
|
||||
/**
|
||||
* @brief Checks whether or not the currently running task is privileged.
|
||||
*
|
||||
* @ingroup Port Privilege
|
||||
*
|
||||
* @return
|
||||
* pdTRUE if the calling task is privileged
|
||||
* pdFALSE if the calling task is not privileged
|
||||
*/
|
||||
#define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged()
|
||||
|
||||
/**
|
||||
* @brief Default return address for tasks, it is not meant to be called.
|
||||
* @brief Default return address for tasks.
|
||||
*
|
||||
* @ingroup Task Context
|
||||
* @note This function is used as the default Link Register address if
|
||||
* configTASK_RETURN_ADDRESS is not defined in FreeRTOSConfig.h
|
||||
*
|
||||
* This function is used as the default return address for tasks if
|
||||
* configTASK_RETURN_ADDRESS is not defined in FreeRTOSConfig.h.
|
||||
*/
|
||||
void prvTaskExitError( void );
|
||||
|
||||
/**
|
||||
* @brief User provided task return function.
|
||||
*
|
||||
* @ingroup Task Context
|
||||
*
|
||||
* @note Let the user override the pre-loading of the initial LR with
|
||||
* the address of prvTaskExitError() in case it messes up unwinding of
|
||||
* the stack in the debugger.
|
||||
*/
|
||||
#ifdef configTASK_RETURN_ADDRESS
|
||||
#define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS
|
||||
#else
|
||||
#define configTASK_RETURN_ADDRESS prvTaskExitError
|
||||
#define portTASK_RETURN_ADDRESS prvTaskExitError
|
||||
#endif /* configTASK_RETURN_ADDRESS */
|
||||
|
||||
/**
|
||||
* @brief Function a task should execute if it exits its assigned function.
|
||||
*
|
||||
* @ingroup Task Context
|
||||
*
|
||||
* @note If configTASK_RETURN_ADDRESS is not defined this value shall be set to
|
||||
* prvTaskExitError().
|
||||
*/
|
||||
#define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS
|
||||
|
||||
/**
|
||||
* @brief Returns the number of leading zeros in a 32 bit variable.
|
||||
*
|
||||
* @param[in] ulBitmap 32 Bit long number to count zeros of.
|
||||
* @param[in] ulBitmap 32-Bit number to count leading zeros in.
|
||||
*
|
||||
* @return The number of leading zeros ulBitmap has.
|
||||
* @return The number of leading zeros in ulBitmap.
|
||||
*/
|
||||
UBaseType_t ulPortCountLeadingZeros( UBaseType_t ulBitmap );
|
||||
|
||||
/**
|
||||
* @brief Function meant to end the FreeRTOS Scheduler, not implemented on this port.
|
||||
* @brief End the FreeRTOS scheduler.
|
||||
*
|
||||
* Not implemented on this port.
|
||||
*
|
||||
* @ingroup Scheduler
|
||||
*/
|
||||
void vPortEndScheduler( void );
|
||||
|
|
@ -532,11 +434,6 @@ void vPortEndScheduler( void );
|
|||
* @brief Mark that this port utilizes the onboard ARM MPU.
|
||||
*
|
||||
* @ingroup MPU Control
|
||||
*
|
||||
* @note The structures and methods of manipulating the MPU are contained
|
||||
* within the port layer. Fills the xMPUSettings structure with the memory
|
||||
* region information contained in xRegions.
|
||||
*
|
||||
*/
|
||||
#define portUSING_MPU_WRAPPERS 1
|
||||
|
||||
|
|
@ -546,139 +443,76 @@ void vPortEndScheduler( void );
|
|||
* @ingroup Task Context
|
||||
* @ingroup MPU Control
|
||||
*
|
||||
* @note This is done 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 ).
|
||||
* 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 the System Call Buffer in the TCB. */
|
||||
|
||||
#define portSYSTEM_CALL_STACK_SIZE configSYSTEM_CALL_STACK_SIZE
|
||||
|
||||
/** @brief Size of an Access Control List (ACL) entry in bits. */
|
||||
/**
|
||||
* @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: Do not modify this structure. The ordering of this struct MUST
|
||||
* line up with the ordering explained in portRESTORE_CONTEXT.
|
||||
* @note The ordering of this struct MUST be in sync with the ordering in
|
||||
* portRESTORE_CONTEXT.
|
||||
*/
|
||||
typedef struct MPU_REGION_REGISTERS
|
||||
{
|
||||
/**
|
||||
* @brief Member used to hold the MPU register value for the Region Size.
|
||||
* @struct xMPU_REGION_REGISTERS
|
||||
* @ingroup MPU Control
|
||||
*/
|
||||
uint32_t ulRegionSize;
|
||||
|
||||
/**
|
||||
* @brief Member used to hold the MPU register value for the Region Attributes.
|
||||
* @struct xMPU_REGION_REGISTERS
|
||||
* @ingroup MPU Control
|
||||
*/
|
||||
uint32_t ulRegionAttribute;
|
||||
|
||||
/**
|
||||
* @brief Member used to hold the MPU register value for the Region Base Address.
|
||||
* @struct xMPU_REGION_REGISTERS
|
||||
* @ingroup MPU Control
|
||||
*/
|
||||
uint32_t ulRegionBaseAddress;
|
||||
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: Do not modify this structure. The ordering of this structure is expected
|
||||
* to be this way in the assembly code of the port.
|
||||
* @note The ordering of this structure MUST be in sync with the assembly code
|
||||
* of the port.
|
||||
*/
|
||||
typedef struct SYSTEM_CALL_STACK_INFO
|
||||
{
|
||||
/**
|
||||
* @brief Stack Pointer of the task when it made a FreeRTOS System Call.
|
||||
* @struct xSYSTEM_CALL_STACK_INFO
|
||||
*/
|
||||
uint32_t * pulTaskStackPointer;
|
||||
|
||||
/**
|
||||
* @brief Link Register of the task when it made a FreeRTOS System Call.
|
||||
* @struct xSYSTEM_CALL_STACK_INFO
|
||||
*/
|
||||
uint32_t * pulLinkRegisterAtSystemCallEntry;
|
||||
|
||||
/**
|
||||
* @brief Pre-Set Stack Pointer to use when making a FreeRTOS System Call.
|
||||
* @struct xSYSTEM_CALL_STACK_INFO
|
||||
* @note This will point to the start of ulSystemCallStackBuffer[]
|
||||
*/
|
||||
uint32_t * pulSystemCallStackPointer;
|
||||
|
||||
/**
|
||||
* @brief Pre-Set Link Register to exit a FreeRTOS System Call.
|
||||
* @struct xSYSTEM_CALL_STACK_INFO
|
||||
* @note This value is set in pxPortInitialiseStack() to ensure after making
|
||||
* a FreeRTOS System Call that the last LR jump is to vPortSystemCallExit()
|
||||
*/
|
||||
void * pulSystemCallLinkRegister;
|
||||
|
||||
/**
|
||||
* @brief Buffer to be used when performing a FreeRTOS System Call.
|
||||
* @struct xSYSTEM_CALL_STACK_INFO
|
||||
*/
|
||||
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ];
|
||||
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
|
||||
* @brief Per-Task MPU settings structure stored in the TCB.
|
||||
* @struct xMPU_SETTINGS
|
||||
*
|
||||
* @ingroup MPU Control
|
||||
* @ingroup Task Context
|
||||
* @ingroup Port Privilege
|
||||
*
|
||||
* NOTE: Do not modify this structure. The ordering of this structure is expected to be
|
||||
* this way in the assembly code of the port.
|
||||
* @note The ordering of this structure MUST be in sync with the assembly code
|
||||
* of the port.
|
||||
*/
|
||||
typedef struct MPU_SETTINGS
|
||||
{
|
||||
/**
|
||||
* @brief Array of Per-Task MPU Register Values. Loaded on Task Context Restore.
|
||||
* @struct xMPU_SETTINGS
|
||||
*/
|
||||
xMPU_REGION_REGISTERS xRegion[ portTOTAL_NUM_REGIONS_IN_TCB ];
|
||||
|
||||
/**
|
||||
* @brief Buffer that holds a Task's Context when being swapped out.
|
||||
* @struct xMPU_SETTINGS
|
||||
*/
|
||||
uint32_t ulContext[ MAX_CONTEXT_SIZE ];
|
||||
|
||||
/**
|
||||
* @brief Variable to hold FreeRTOS Privilege Settings.
|
||||
* @struct xMPU_SETTINGS
|
||||
*/
|
||||
uint32_t ulTaskFlags;
|
||||
|
||||
/**
|
||||
* @brief System Call Info structure that is stored in the TCB.
|
||||
* @struct xMPU_SETTINGS
|
||||
*/
|
||||
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
|
||||
#if( configENABLE_ACCESS_CONTROL_LIST == 1 )
|
||||
uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE
|
||||
/ portACL_ENTRY_SIZE_BITS )
|
||||
+ 1UL ];
|
||||
#endif
|
||||
} xMPU_SETTINGS;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
|
|
@ -37,8 +37,6 @@ extern "C" {
|
|||
|
||||
#ifndef configTOTAL_MPU_REGIONS
|
||||
#error "Set configTOTAL_MPU_REGIONS to the humber of MPU regions in FreeRTOSConfig.h"
|
||||
#elif( configTOTAL_MPU_REGIONS == 8 )
|
||||
#define portMPU_TOTAL_REGIONS ( 8UL )
|
||||
#elif( configTOTAL_MPU_REGIONS == 12 )
|
||||
#define portMPU_TOTAL_REGIONS ( 12UL )
|
||||
#elif( configTOTAL_MPU_REGIONS == 16 )
|
||||
|
|
@ -47,112 +45,74 @@ extern "C" {
|
|||
#error "Set configTOTAL_MPU_REGIONS to the number of MPU regions in FreeRTOSConfig.h"
|
||||
#endif /* configTOTAL_MPU_REGIONS */
|
||||
|
||||
/** 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 registers banked between modes are the CPSR, Stack Pointer (R13),
|
||||
* and the Link Register (R14). FIQ mode also banks the GPRs R8-R12
|
||||
* Of note, the only mode not "Privileged" is User Mode
|
||||
/*
|
||||
* 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 Mode bit field value for User Mode.
|
||||
* @ingroup Port Privilege
|
||||
*/
|
||||
#define USER_MODE 0x10U
|
||||
|
||||
/**
|
||||
* @brief CPSR Mode bit field value for Fast Interrupt Handler (FIQ) Mode.
|
||||
* @ingroup Port Privilege
|
||||
*/
|
||||
#define FIQ_MODE 0x11U
|
||||
|
||||
/**
|
||||
* @brief CPSR Mode bit field value for Interrupt Handler (IRQ) Mode.
|
||||
* @ingroup Port Privilege
|
||||
*/
|
||||
#define IRQ_MODE 0x12U
|
||||
|
||||
/**
|
||||
* @brief CPSR Mode bit field value for Supervisor (SVC) Mode.
|
||||
* @ingroup Port Privilege
|
||||
*/
|
||||
#define SVC_MODE 0x13U
|
||||
|
||||
/**
|
||||
* @brief CPSR Mode bit field value for Monitor (MON) Mode.
|
||||
* @ingroup Port Privilege
|
||||
*/
|
||||
#define MON_MODE 0x16U
|
||||
|
||||
/**
|
||||
* @brief CPSR Mode bit field value for Abort (ABT) Mode.
|
||||
* @ingroup Port Privilege
|
||||
*/
|
||||
#define ABT_MODE 0x17U
|
||||
|
||||
/**
|
||||
* @brief CPSR Mode bit field value for Hypervisor (HYP) Mode.
|
||||
* @ingroup Port Privilege
|
||||
*/
|
||||
#define HYP_MODE 0x1AU
|
||||
|
||||
/**
|
||||
* @brief CPSR Mode bit field value for Undefined (UND) Mode.
|
||||
* @ingroup Port Privilege
|
||||
*/
|
||||
#define UND_MODE 0x1BU
|
||||
|
||||
/**
|
||||
* @brief CPSR Mode bit field value for System (SYS) Mode.
|
||||
* @ingroup Port Privilege
|
||||
*/
|
||||
#define SYS_MODE 0x1FU
|
||||
|
||||
/**
|
||||
* @brief Used to mark if a task should be created as a privileged task.
|
||||
* @brief CPSR bits for various processor modes.
|
||||
*
|
||||
* @ingroup Task Context
|
||||
* @ingroup MPU Control
|
||||
*
|
||||
* @note This is done 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 ).
|
||||
* @ingroup Port Privilege
|
||||
*/
|
||||
#define portPRIVILEGE_BIT ( 0x80000000UL )
|
||||
#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 Number to use when requesting a context swap.
|
||||
* @brief SVC numbers for various scheduler operations.
|
||||
*
|
||||
* @ingroup Scheduler
|
||||
* @note This value must not be in use in mpu_syscall_numbers.h
|
||||
*
|
||||
* @note These value must not be used in mpu_syscall_numbers.h.
|
||||
*/
|
||||
#define portSVC_YIELD 0x0100U
|
||||
|
||||
/**
|
||||
* @brief SVC Number to use when exiting a FreeRTOS System Call.
|
||||
* @ingroup MPU Control
|
||||
* @note This value must not be in use in mpu_syscall_numbers.h
|
||||
*/
|
||||
#define portSVC_SYSTEM_CALL_EXIT 0x0104U
|
||||
|
||||
/**
|
||||
* @addtogroup MPU Control
|
||||
* @note The Region Access Control Register is used to set MPU Region Settings.
|
||||
* Further information about this register can be found in Arm's documentation
|
||||
* @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 settings */
|
||||
/* 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 )
|
||||
|
|
@ -162,7 +122,7 @@ extern "C" {
|
|||
#define portMPU_SUBREGION_6_DISABLE ( 0x1UL << 14UL )
|
||||
#define portMPU_SUBREGION_7_DISABLE ( 0x1UL << 15UL )
|
||||
|
||||
/* Default MPU regions */
|
||||
/* Default MPU regions. */
|
||||
#define portFIRST_CONFIGURABLE_REGION ( 0 )
|
||||
#define portLAST_CONFIGURABLE_REGION ( portMPU_TOTAL_REGIONS - 5UL )
|
||||
#define portSTACK_REGION ( portMPU_TOTAL_REGIONS - 4UL )
|
||||
|
|
@ -171,198 +131,100 @@ extern "C" {
|
|||
#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*/
|
||||
/* Plus one to make space for the stack region. */
|
||||
#define portTOTAL_NUM_REGIONS_IN_TCB ( portNUM_CONFIGURABLE_REGIONS + 1UL )
|
||||
|
||||
/* MPU region sizes */
|
||||
#define portMPU_SIZE_32B ( 0x04UL << 1UL )
|
||||
#define portMPU_SIZE_64B ( 0x05UL << 1UL )
|
||||
#define portMPU_SIZE_128B ( 0x06UL << 1UL )
|
||||
#define portMPU_SIZE_256B ( 0x07UL << 1UL )
|
||||
#define portMPU_SIZE_512B ( 0x08UL << 1UL )
|
||||
#define portMPU_SIZE_1KB ( 0x09UL << 1UL )
|
||||
#define portMPU_SIZE_2KB ( 0x0AUL << 1UL )
|
||||
#define portMPU_SIZE_4KB ( 0x0BUL << 1UL )
|
||||
#define portMPU_SIZE_8KB ( 0x0CUL << 1UL )
|
||||
#define portMPU_SIZE_16KB ( 0x0DUL << 1UL )
|
||||
#define portMPU_SIZE_32KB ( 0x0EUL << 1UL )
|
||||
#define portMPU_SIZE_64KB ( 0x0FUL << 1UL )
|
||||
#define portMPU_SIZE_128KB ( 0x10UL << 1UL )
|
||||
#define portMPU_SIZE_256KB ( 0x11UL << 1UL )
|
||||
#define portMPU_SIZE_512KB ( 0x12UL << 1UL )
|
||||
#define portMPU_SIZE_1MB ( 0x13UL << 1UL )
|
||||
#define portMPU_SIZE_2MB ( 0x14UL << 1UL )
|
||||
#define portMPU_SIZE_4MB ( 0x15UL << 1UL )
|
||||
#define portMPU_SIZE_8MB ( 0x16UL << 1UL )
|
||||
#define portMPU_SIZE_16MB ( 0x17UL << 1UL )
|
||||
#define portMPU_SIZE_32MB ( 0x18UL << 1UL )
|
||||
#define portMPU_SIZE_64MB ( 0x19UL << 1UL )
|
||||
#define portMPU_SIZE_128MB ( 0x1AUL << 1UL )
|
||||
#define portMPU_SIZE_256MB ( 0x1BUL << 1UL )
|
||||
#define portMPU_SIZE_512MB ( 0x1CUL << 1UL )
|
||||
#define portMPU_SIZE_1GB ( 0x1DUL << 1UL )
|
||||
#define portMPU_SIZE_2GB ( 0x1EUL << 1UL )
|
||||
#define portMPU_SIZE_4GB ( 0x1FUL << 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 Device Memory Types */
|
||||
#define portMPU_REGION_STRONGLY_ORDERED ( 0x00UL )
|
||||
#define portMPU_REGION_DEVICE ( 0x01UL )
|
||||
#define portMPU_REGION_CACHEABLE_BUFFERABLE ( 0x03UL )
|
||||
#define portMPU_REGION_EXECUTE_NEVER ( 0x01UL << 12UL )
|
||||
#define portMPU_STRONGLYORDERED_SHAREABLE ( 0x0000UL )
|
||||
#define portMPU_DEVICE_SHAREABLE ( 0x0001UL )
|
||||
#define portMPU_DEVICE_NONSHAREABLE ( 0x0010UL )
|
||||
#define portMPU_NORMAL_OIWTNOWA_NONSHARED ( 0x0002UL )
|
||||
#define portMPU_NORMAL_OIWBNOWA_NONSHARED ( 0x0003UL )
|
||||
#define portMPU_NORMAL_OIWTNOWA_SHARED ( 0x0006UL )
|
||||
#define portMPU_NORMAL_OIWBNOWA_SHARED ( 0x0007UL )
|
||||
#define portMPU_NORMAL_OINC_NONSHARED ( 0x0008UL )
|
||||
#define portMPU_NORMAL_OIWBWA_NONSHARED ( 0x000BUL )
|
||||
#define portMPU_NORMAL_OINC_SHARED ( 0x000CUL )
|
||||
#define portMPU_NORMAL_OIWBWA_SHARED ( 0x000FUL )
|
||||
/* 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 MPU_CTRL value for: No Access and No Execute
|
||||
* @brief The size (in words) of a task context.
|
||||
*
|
||||
* @ingroup MPU Control
|
||||
* An array of this size is allocated in TCB where a task's context is saved
|
||||
* when it is switched out.
|
||||
*
|
||||
* @brief No Access in a Privileged Operating Mode
|
||||
* No Access in User Mode
|
||||
* Cannot Execute Code from this region
|
||||
*/
|
||||
#define portMPU_PRIV_NA_USER_NA_NOEXEC ( 0x1000UL )
|
||||
|
||||
/**
|
||||
* @brief MPU_CTRL value for Privileged Read and Exec
|
||||
*
|
||||
* @ingroup MPU Control
|
||||
*
|
||||
* @note Read Only Access in Privileged Operating Modes.
|
||||
* No Read/Write Access in User Mode
|
||||
* Allowed to Execute Code from this region
|
||||
*/
|
||||
#define portMPU_PRIV_RO_USER_NA_EXEC ( 0x0500UL )
|
||||
|
||||
/**
|
||||
* @brief MPU_CTRL value for Privileged Read, Write, and Exec
|
||||
*
|
||||
* @ingroup MPU Control
|
||||
*
|
||||
* Read/Write in a Privileged Operating Mode
|
||||
* No Access in User Mode
|
||||
* Allowed to Execute Code from this region
|
||||
*/
|
||||
#define portMPU_PRIV_RW_USER_NA_EXEC ( 0x0100UL )
|
||||
|
||||
/**
|
||||
* @brief MPU_CTRL value for Read Only and Execute
|
||||
*
|
||||
* @ingroup MPU Control
|
||||
*
|
||||
* @note Read Only in a Privileged Operating Mode
|
||||
* Read Only in User Mode
|
||||
* Allowed to Execute Code from this region
|
||||
* */
|
||||
#define portMPU_PRIV_RO_USER_RO_EXEC ( 0x0600UL )
|
||||
|
||||
/**
|
||||
* @brief MPU_CTRL value for: Read, Execute, and Privileged Write
|
||||
*
|
||||
* @ingroup MPU Control
|
||||
*
|
||||
* @note Read/Write in a Privileged Operating Mode
|
||||
* Read Only in User Mode
|
||||
* Allowed to Execute Code from this region
|
||||
*/
|
||||
#define portMPU_PRIV_RW_USER_RO_EXEC ( 0x0200UL )
|
||||
|
||||
/**
|
||||
* @brief MPU_CTRL value for: Read, Write, and Execute
|
||||
*
|
||||
* @ingroup MPU Control
|
||||
*
|
||||
* @note Read/Write in a Privileged Operating Mode
|
||||
* Read/write in User Mode
|
||||
* Allowed to Execute Code from this region
|
||||
*/
|
||||
#define portMPU_PRIV_RW_USER_RW_EXEC ( 0x0300UL )
|
||||
|
||||
/**
|
||||
* @brief MPU_CTRL value for: Privileged Read, Write Only, no Execute
|
||||
*
|
||||
* @ingroup MPU Control
|
||||
*
|
||||
* @note Read/Write in a Privileged Operating Mode
|
||||
* No Access in User Mode
|
||||
* Cannot Execute Code from this region
|
||||
*/
|
||||
#define portMPU_PRIV_RW_USER_NA_NOEXEC ( 0x1100UL )
|
||||
|
||||
/**
|
||||
* @brief MPU_CTRL value for: All Read, Privileged Write, no Execute
|
||||
*
|
||||
* @ingroup MPU Control
|
||||
*
|
||||
* Read/Write in a Privileged Operating Mode
|
||||
* Read Only in User Mode
|
||||
* Cannot Execute Code from this region
|
||||
*/
|
||||
#define portMPU_PRIV_RW_USER_RO_NOEXEC ( 0x1200UL )
|
||||
|
||||
/**
|
||||
* @brief MPU_CTRL value for: Read, Write, no Execute
|
||||
*
|
||||
* @ingroup MPU Control
|
||||
*
|
||||
* @note Read/Write in a Privileged Operating Mode
|
||||
* Read/Write in User Mode
|
||||
* Cannot Execute Code from this region
|
||||
*/
|
||||
#define portMPU_PRIV_RW_USER_RW_NOEXEC ( 0x1300UL )
|
||||
|
||||
/**
|
||||
* @brief MPU_CTRL value for: Privileged Read Only, No Execute
|
||||
*
|
||||
* @ingroup MPU Control
|
||||
*
|
||||
* @note Read Only in a Privileged Operating Mode
|
||||
* No Access in User Mode
|
||||
* Cannot Execute Code from this region
|
||||
*/
|
||||
#define portMPU_PRIV_RO_USER_NA_NOEXEC ( 0x1500UL )
|
||||
|
||||
/**
|
||||
* @brief MPU_CTRL value for: Read Only, No Execute
|
||||
*
|
||||
* @ingroup MPU Control
|
||||
*
|
||||
* @note Read Only in a Privileged Operating Mode
|
||||
* Read Only in User Mode
|
||||
* Cannot Execute Code from this region
|
||||
*/
|
||||
#define portMPU_PRIV_RO_USER_RO_NOEXEC ( 0x1600UL )
|
||||
|
||||
/**
|
||||
* @brief MPU_CTRL value to enable an MPU Region
|
||||
* @ingroup MPU Control
|
||||
*/
|
||||
#define portMPU_REGION_ENABLE ( 0x01UL )
|
||||
|
||||
/** This following section is used to create the proper size for the ulContext array.
|
||||
* This array is where all registers related to a task's context are saved.
|
||||
* The size of this array will depend on if the system is using an integrated
|
||||
* Floating Point Unit (FPU) or not. If we are using the FPU we must save the
|
||||
* Floating Point Status and Control Register (FPSCR),
|
||||
* and the Floating Point Registers (FPRs). The FPSCR holds the conditional bits
|
||||
* used for floating point calculations. The FPRs hold the actual floating point bits.
|
||||
* The remainder of a task's context consists of the General Purpose Registers (GPRs).
|
||||
* General Purpose Registers are used to manipulate almost all variables.
|
||||
* The Current Program Status and Control Register, which holds the operating mode
|
||||
* and bits that correspond to any conditional checks, such as if statements.
|
||||
* And the Critical Nesting Depth of the task.
|
||||
*
|
||||
*
|
||||
* For more information about the FPU, FPSCR, and FPRs please reference ARM's website:
|
||||
* 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:
|
||||
|
|
@ -371,7 +233,7 @@ extern "C" {
|
|||
* 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
|
||||
* 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:
|
||||
|
|
@ -379,74 +241,36 @@ extern "C" {
|
|||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief The length in ulContext for the General Purpose Registers in bytes.
|
||||
* @note There are 13 GPRs, R0-R12, the SP, and the LR. Each register is 32
|
||||
* bits, so the register context length is 15 registers * 4 bytes = 60 bytes.
|
||||
*/
|
||||
#define portREGISTER_LENGTH ( 15U * 4U )
|
||||
|
||||
/**
|
||||
* If you KNOW that your system will not utilize the FPU in any capacity
|
||||
* you can set portENABLE_FPU to 0. This will reduce the per-task RAM usage
|
||||
* by ( 32 FPRs + 32 bit FPSCR ) * 4 bytes per register = 132 Bytes Per Task.
|
||||
* It will also increase context swap speed, as these can then be ignored.
|
||||
* BE CAREFUL DISABLING THIS: Certain APIs will try and optimize themselves
|
||||
* by using the FPRs. If the FPU context is not saved and this happens it could
|
||||
* be exceedingly difficult to debug why a strcpy() or other similar function
|
||||
* seems to randomly fail.
|
||||
*/
|
||||
#ifndef configENABLE_FPU
|
||||
#define configENABLE_FPU 1
|
||||
#endif /* configENABLE_FPU */
|
||||
|
||||
/**
|
||||
* @brief Mark if the Floating Point Registers (FPRs) will be saved.
|
||||
* @ingroup Task Context
|
||||
* @note Using the FPU requires save FPRs into the task's context. As well as
|
||||
* the Floating Point Status and Control Register (FPSCR).
|
||||
*/
|
||||
#define portENABLE_FPU configENABLE_FPU
|
||||
|
||||
#if( portENABLE_FPU == 1 )
|
||||
/**
|
||||
* @brief Length of a Task's Register Context when using an FPU.
|
||||
* @ingroup Task Context
|
||||
* @note Task Context which is stored in ulContext in order, consists of:
|
||||
* ulContext[ 0 ]: Critical Nesting Count: ulCriticalNesting
|
||||
* ulContext[ 1 ]: Floating Point Status and Control Register
|
||||
* ulContext[ 2 - 33 ]: Floating Point Registers: S0-S31
|
||||
* ulContext[ 34 - 46 ]: General Purpose Registers: R0-R12
|
||||
* ulContext[ 48 ]: Stack Pointer
|
||||
* ulContext[ 49 ]: Link Register
|
||||
* ulContext[ 50 ]: Program Counter
|
||||
* ulContext[ 51 ]: Current Program Status and Control Register
|
||||
/*
|
||||
* +-------------------+-------+----------+--------+----------+----------+----------+------+
|
||||
* | ulCriticalNesting | FPSCR | S0-S31 | R0-R12 | SP (R13) | LR (R14) | PC (R15) | CPSR |
|
||||
* +-------------------+-------+----------+--------+----------+----------+----------+------+
|
||||
*
|
||||
* <------------------><------><---------><--------><---------><--------><----------><----->
|
||||
* 1 1 32 13 1 1 1 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 51U
|
||||
#define CONTEXT_SIZE 51U
|
||||
#else
|
||||
/**
|
||||
* @brief Length of a Task's Register Context when not using an FPU.
|
||||
* @ingroup Task Context
|
||||
* @note Task Context which is stored in ulContext in order, consists of:
|
||||
* ulContext[ 0 ]: Critical Nesting Count: ulCriticalNesting
|
||||
* ulContext[ 1 - 13 ]: General Purpose Registers: R0-R12
|
||||
* ulContext[ 14 ]: Stack Pointer
|
||||
* ulContext[ 15 ]: Link Register
|
||||
* ulContext[ 16 ]: Program Counter
|
||||
* ulContext[ 17 ]: Current Program Status and Control Register
|
||||
/*
|
||||
* +-------------------+--------+----------+----------+----------+------+
|
||||
* | ulCriticalNesting | R0-R12 | SP (R13) | LR (R14) | PC (R15) | CPSR |
|
||||
* +-------------------+--------+----------+----------+----------+------+
|
||||
*
|
||||
* <------------------><--------><---------><--------><----------><----->
|
||||
* 1 13 1 1 1 1
|
||||
*/
|
||||
#define MAX_CONTEXT_SIZE 18U
|
||||
#endif /* MAX_CONTEXT_SIZE */
|
||||
#define CONTEXT_SIZE 18U
|
||||
#endif /* CONTEXT_SIZE */
|
||||
|
||||
/**
|
||||
* @brief Numerical offset from the start of a TCB to xSystemCallStackInfo.
|
||||
* @note This is used in portASM.S to load xSystemCallStackInfo from the TCB.
|
||||
* This provides an easy way for the exception handlers to get this structure.
|
||||
* The numerical value here should be equal to:
|
||||
* sizeof( xRegion ) + sizeof( ulContext ) + sizeof( ulTaskFlags )
|
||||
* @brief Offset of xSystemCallStackInfo from the start of a TCB.
|
||||
*/
|
||||
#define portSYSTEM_CALL_INFO_OFFSET \
|
||||
( ( ( portTOTAL_NUM_REGIONS_IN_TCB * 3U ) + ( MAX_CONTEXT_SIZE ) + 1U ) * 4U )
|
||||
#define portSYSTEM_CALL_INFO_OFFSET \
|
||||
( ( 1U /* pxTopOfStack. */ + \
|
||||
( portTOTAL_NUM_REGIONS_IN_TCB * 3U ) + \
|
||||
1U /* ulTaskFlags. */ \
|
||||
) * 4U )
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern C */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue