Merge branch 'FreeRTOS:main' into main

This commit is contained in:
Joseph Julicher 2023-09-26 10:24:27 -07:00 committed by GitHub
commit b283a6a691
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
120 changed files with 6568 additions and 513 deletions

23
.github/workflows/formatting.yml vendored Normal file
View file

@ -0,0 +1,23 @@
name: Format Pull Request Files
on:
issue_comment:
types: [created]
env:
bashPass: \033[32;1mPASSED -
bashInfo: \033[33;1mINFO -
bashFail: \033[31;1mFAILED -
bashEnd: \033[0m
jobs:
Formatting:
name: Run Formatting Check
if: ${{ github.event.issue.pull_request }} &&
( ( github.event.comment.body == '/bot run uncrustify' ) ||
( github.event.comment.body == '/bot run formatting' ) )
runs-on: ubuntu-20.04
steps:
- name: Apply Formatting Fix
uses: FreeRTOS/CI-CD-Github-Actions/formatting-bot@main
id: check-formatting

View file

@ -166,20 +166,6 @@ jobs:
working-directory: FreeRTOS/Demo/CORTEX_LM3S102_GCC working-directory: FreeRTOS/Demo/CORTEX_LM3S102_GCC
run: make -j run: make -j
- name: Build CORTEX_M3_MPS2_QEMU_GCC Demo
shell: bash
working-directory: FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC
run: |
make clean
make -j
- name: Build CORTEX_M3_MPS2_QEMU_GCC Demo
shell: bash
working-directory: FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC
run: |
make clean
make FULL_DEMO=1 -j
- name: Build CORTEX_LM3S811_GCC Demo - name: Build CORTEX_LM3S811_GCC Demo
shell: bash shell: bash
working-directory: FreeRTOS/Demo/CORTEX_LM3S811_GCC working-directory: FreeRTOS/Demo/CORTEX_LM3S811_GCC

View file

@ -107,6 +107,8 @@
BaseType_t xReturn; BaseType_t xReturn;
CRCB_t * pxCoRoutine; CRCB_t * pxCoRoutine;
traceENTER_xCoRoutineCreate( pxCoRoutineCode, uxPriority, uxIndex );
/* Allocate the memory that will store the co-routine control block. */ /* Allocate the memory that will store the co-routine control block. */
pxCoRoutine = ( CRCB_t * ) pvPortMalloc( sizeof( CRCB_t ) ); pxCoRoutine = ( CRCB_t * ) pvPortMalloc( sizeof( CRCB_t ) );
@ -156,6 +158,8 @@
xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
} }
traceRETURN_xCoRoutineCreate( xReturn );
return xReturn; return xReturn;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -165,6 +169,8 @@
{ {
TickType_t xTimeToWake; TickType_t xTimeToWake;
traceENTER_vCoRoutineAddToDelayedList( xTicksToDelay, pxEventList );
/* Calculate the time to wake - this may overflow but this is /* Calculate the time to wake - this may overflow but this is
* not a problem. */ * not a problem. */
xTimeToWake = xCoRoutineTickCount + xTicksToDelay; xTimeToWake = xCoRoutineTickCount + xTicksToDelay;
@ -196,6 +202,8 @@
* function must be called with interrupts disabled. */ * function must be called with interrupts disabled. */
vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) ); vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) );
} }
traceRETURN_vCoRoutineAddToDelayedList();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -283,6 +291,8 @@
void vCoRoutineSchedule( void ) void vCoRoutineSchedule( void )
{ {
traceENTER_vCoRoutineSchedule();
/* Only run a co-routine after prvInitialiseCoRoutineLists() has been /* Only run a co-routine after prvInitialiseCoRoutineLists() has been
* called. prvInitialiseCoRoutineLists() is called automatically when a * called. prvInitialiseCoRoutineLists() is called automatically when a
* co-routine is created. */ * co-routine is created. */
@ -313,6 +323,8 @@
/* Call the co-routine. */ /* Call the co-routine. */
( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex ); ( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex );
} }
traceRETURN_vCoRoutineSchedule();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -341,6 +353,8 @@
CRCB_t * pxUnblockedCRCB; CRCB_t * pxUnblockedCRCB;
BaseType_t xReturn; BaseType_t xReturn;
traceENTER_xCoRoutineRemoveFromEventList( pxEventList );
/* This function is called from within an interrupt. It can only access /* This function is called from within an interrupt. It can only access
* event lists and the pending ready list. This function assumes that a * event lists and the pending ready list. This function assumes that a
* check has already been made to ensure pxEventList is not empty. */ * check has already been made to ensure pxEventList is not empty. */
@ -357,6 +371,8 @@
xReturn = pdFALSE; xReturn = pdFALSE;
} }
traceRETURN_xCoRoutineRemoveFromEventList( xReturn );
return xReturn; return xReturn;
} }

View file

@ -82,6 +82,8 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits,
{ {
EventGroup_t * pxEventBits; EventGroup_t * pxEventBits;
traceENTER_xEventGroupCreateStatic( pxEventGroupBuffer );
/* A StaticEventGroup_t object must be provided. */ /* A StaticEventGroup_t object must be provided. */
configASSERT( pxEventGroupBuffer ); configASSERT( pxEventGroupBuffer );
@ -122,6 +124,8 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits,
traceEVENT_GROUP_CREATE_FAILED(); traceEVENT_GROUP_CREATE_FAILED();
} }
traceRETURN_xEventGroupCreateStatic( pxEventBits );
return pxEventBits; return pxEventBits;
} }
@ -134,6 +138,8 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits,
{ {
EventGroup_t * pxEventBits; EventGroup_t * pxEventBits;
traceENTER_xEventGroupCreate();
/* Allocate the event group. Justification for MISRA deviation as /* Allocate the event group. Justification for MISRA deviation as
* follows: pvPortMalloc() always ensures returned memory blocks are * follows: pvPortMalloc() always ensures returned memory blocks are
* aligned per the requirements of the MCU stack. In this case * aligned per the requirements of the MCU stack. In this case
@ -170,6 +176,8 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits,
traceEVENT_GROUP_CREATE_FAILED(); /*lint !e9063 Else branch only exists to allow tracing and does not generate code if trace macros are not defined. */ traceEVENT_GROUP_CREATE_FAILED(); /*lint !e9063 Else branch only exists to allow tracing and does not generate code if trace macros are not defined. */
} }
traceRETURN_xEventGroupCreate( pxEventBits );
return pxEventBits; return pxEventBits;
} }
@ -186,6 +194,8 @@ EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup,
BaseType_t xAlreadyYielded; BaseType_t xAlreadyYielded;
BaseType_t xTimeoutOccurred = pdFALSE; BaseType_t xTimeoutOccurred = pdFALSE;
traceENTER_xEventGroupSync( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTicksToWait );
configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
configASSERT( uxBitsToWaitFor != 0 ); configASSERT( uxBitsToWaitFor != 0 );
#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
@ -303,6 +313,8 @@ EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup,
/* Prevent compiler warnings when trace macros are not used. */ /* Prevent compiler warnings when trace macros are not used. */
( void ) xTimeoutOccurred; ( void ) xTimeoutOccurred;
traceRETURN_xEventGroupSync( uxReturn );
return uxReturn; return uxReturn;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -318,6 +330,8 @@ EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
BaseType_t xWaitConditionMet, xAlreadyYielded; BaseType_t xWaitConditionMet, xAlreadyYielded;
BaseType_t xTimeoutOccurred = pdFALSE; BaseType_t xTimeoutOccurred = pdFALSE;
traceENTER_xEventGroupWaitBits( xEventGroup, uxBitsToWaitFor, xClearOnExit, xWaitForAllBits, xTicksToWait );
/* Check the user is not attempting to wait on the bits used by the kernel /* Check the user is not attempting to wait on the bits used by the kernel
* itself, and that at least one bit is being requested. */ * itself, and that at least one bit is being requested. */
configASSERT( xEventGroup ); configASSERT( xEventGroup );
@ -467,6 +481,8 @@ EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
/* Prevent compiler warnings when trace macros are not used. */ /* Prevent compiler warnings when trace macros are not used. */
( void ) xTimeoutOccurred; ( void ) xTimeoutOccurred;
traceRETURN_xEventGroupWaitBits( uxReturn );
return uxReturn; return uxReturn;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -477,6 +493,8 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup,
EventGroup_t * pxEventBits = xEventGroup; EventGroup_t * pxEventBits = xEventGroup;
EventBits_t uxReturn; EventBits_t uxReturn;
traceENTER_xEventGroupClearBits( xEventGroup, uxBitsToClear );
/* Check the user is not attempting to clear the bits used by the kernel /* Check the user is not attempting to clear the bits used by the kernel
* itself. */ * itself. */
configASSERT( xEventGroup ); configASSERT( xEventGroup );
@ -495,6 +513,8 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup,
} }
taskEXIT_CRITICAL(); taskEXIT_CRITICAL();
traceRETURN_xEventGroupClearBits( uxReturn );
return uxReturn; return uxReturn;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -506,9 +526,13 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup,
{ {
BaseType_t xReturn; BaseType_t xReturn;
traceENTER_xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear );
traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear ); traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear );
xReturn = xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL ); /*lint !e9087 Can't avoid cast to void* as a generic callback function not specific to this use case. Callback casts back to original type so safe. */ xReturn = xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL ); /*lint !e9087 Can't avoid cast to void* as a generic callback function not specific to this use case. Callback casts back to original type so safe. */
traceRETURN_xEventGroupClearBitsFromISR( xReturn );
return xReturn; return xReturn;
} }
@ -521,12 +545,16 @@ EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup )
EventGroup_t const * const pxEventBits = xEventGroup; EventGroup_t const * const pxEventBits = xEventGroup;
EventBits_t uxReturn; EventBits_t uxReturn;
traceENTER_xEventGroupGetBitsFromISR( xEventGroup );
uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR();
{ {
uxReturn = pxEventBits->uxEventBits; uxReturn = pxEventBits->uxEventBits;
} }
taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus ); taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus );
traceRETURN_xEventGroupGetBitsFromISR( uxReturn );
return uxReturn; return uxReturn;
} /*lint !e818 EventGroupHandle_t is a typedef used in other functions to so can't be pointer to const. */ } /*lint !e818 EventGroupHandle_t is a typedef used in other functions to so can't be pointer to const. */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -542,6 +570,8 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,
EventGroup_t * pxEventBits = xEventGroup; EventGroup_t * pxEventBits = xEventGroup;
BaseType_t xMatchFound = pdFALSE; BaseType_t xMatchFound = pdFALSE;
traceENTER_xEventGroupSetBits( xEventGroup, uxBitsToSet );
/* Check the user is not attempting to set the bits used by the kernel /* Check the user is not attempting to set the bits used by the kernel
* itself. */ * itself. */
configASSERT( xEventGroup ); configASSERT( xEventGroup );
@ -623,6 +653,8 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,
} }
( void ) xTaskResumeAll(); ( void ) xTaskResumeAll();
traceRETURN_xEventGroupSetBits( pxEventBits->uxEventBits );
return pxEventBits->uxEventBits; return pxEventBits->uxEventBits;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -632,6 +664,8 @@ void vEventGroupDelete( EventGroupHandle_t xEventGroup )
EventGroup_t * pxEventBits = xEventGroup; EventGroup_t * pxEventBits = xEventGroup;
const List_t * pxTasksWaitingForBits; const List_t * pxTasksWaitingForBits;
traceENTER_vEventGroupDelete( xEventGroup );
configASSERT( pxEventBits ); configASSERT( pxEventBits );
pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits ); pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
@ -670,6 +704,8 @@ void vEventGroupDelete( EventGroupHandle_t xEventGroup )
} }
} }
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
traceRETURN_vEventGroupDelete();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -680,6 +716,8 @@ void vEventGroupDelete( EventGroupHandle_t xEventGroup )
BaseType_t xReturn; BaseType_t xReturn;
EventGroup_t * pxEventBits = xEventGroup; EventGroup_t * pxEventBits = xEventGroup;
traceENTER_xEventGroupGetStaticBuffer( xEventGroup, ppxEventGroupBuffer );
configASSERT( pxEventBits ); configASSERT( pxEventBits );
configASSERT( ppxEventGroupBuffer ); configASSERT( ppxEventGroupBuffer );
@ -704,6 +742,8 @@ void vEventGroupDelete( EventGroupHandle_t xEventGroup )
} }
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
traceRETURN_xEventGroupGetStaticBuffer( xReturn );
return xReturn; return xReturn;
} }
#endif /* configSUPPORT_STATIC_ALLOCATION */ #endif /* configSUPPORT_STATIC_ALLOCATION */
@ -714,7 +754,11 @@ void vEventGroupDelete( EventGroupHandle_t xEventGroup )
void vEventGroupSetBitsCallback( void * pvEventGroup, void vEventGroupSetBitsCallback( void * pvEventGroup,
const uint32_t ulBitsToSet ) const uint32_t ulBitsToSet )
{ {
traceENTER_vEventGroupSetBitsCallback( pvEventGroup, ulBitsToSet );
( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */ ( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */
traceRETURN_vEventGroupSetBitsCallback();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -723,7 +767,11 @@ void vEventGroupSetBitsCallback( void * pvEventGroup,
void vEventGroupClearBitsCallback( void * pvEventGroup, void vEventGroupClearBitsCallback( void * pvEventGroup,
const uint32_t ulBitsToClear ) const uint32_t ulBitsToClear )
{ {
traceENTER_vEventGroupClearBitsCallback( pvEventGroup, ulBitsToClear );
( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */ ( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */
traceRETURN_vEventGroupClearBitsCallback();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -772,9 +820,13 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits,
{ {
BaseType_t xReturn; BaseType_t xReturn;
traceENTER_xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken );
traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet ); traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet );
xReturn = xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken ); /*lint !e9087 Can't avoid cast to void* as a generic callback function not specific to this use case. Callback casts back to original type so safe. */ xReturn = xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken ); /*lint !e9087 Can't avoid cast to void* as a generic callback function not specific to this use case. Callback casts back to original type so safe. */
traceRETURN_xEventGroupSetBitsFromISR( xReturn );
return xReturn; return xReturn;
} }
@ -788,6 +840,8 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits,
UBaseType_t xReturn; UBaseType_t xReturn;
EventGroup_t const * pxEventBits = ( EventGroup_t * ) xEventGroup; /*lint !e9087 !e9079 EventGroupHandle_t is a pointer to an EventGroup_t, but EventGroupHandle_t is kept opaque outside of this file for data hiding purposes. */ EventGroup_t const * pxEventBits = ( EventGroup_t * ) xEventGroup; /*lint !e9087 !e9079 EventGroupHandle_t is a pointer to an EventGroup_t, but EventGroupHandle_t is kept opaque outside of this file for data hiding purposes. */
traceENTER_uxEventGroupGetNumber( xEventGroup );
if( xEventGroup == NULL ) if( xEventGroup == NULL )
{ {
xReturn = 0; xReturn = 0;
@ -797,6 +851,8 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits,
xReturn = pxEventBits->uxEventGroupNumber; xReturn = pxEventBits->uxEventGroupNumber;
} }
traceRETURN_uxEventGroupGetNumber( xReturn );
return xReturn; return xReturn;
} }
@ -808,7 +864,11 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits,
void vEventGroupSetNumber( void * xEventGroup, void vEventGroupSetNumber( void * xEventGroup,
UBaseType_t uxEventGroupNumber ) UBaseType_t uxEventGroupNumber )
{ {
traceENTER_vEventGroupSetNumber( xEventGroup, uxEventGroupNumber );
( ( EventGroup_t * ) xEventGroup )->uxEventGroupNumber = uxEventGroupNumber; /*lint !e9087 !e9079 EventGroupHandle_t is a pointer to an EventGroup_t, but EventGroupHandle_t is kept opaque outside of this file for data hiding purposes. */ ( ( EventGroup_t * ) xEventGroup )->uxEventGroupNumber = uxEventGroupNumber; /*lint !e9087 !e9079 EventGroupHandle_t is a pointer to an EventGroup_t, but EventGroupHandle_t is kept opaque outside of this file for data hiding purposes. */
traceRETURN_vEventGroupSetNumber();
} }
#endif /* configUSE_TRACE_FACILITY */ #endif /* configUSE_TRACE_FACILITY */

File diff suppressed because it is too large Load diff

View file

@ -122,8 +122,8 @@ BaseType_t MPU_xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefin
TaskHandle_t * pxCreatedTask ) PRIVILEGED_FUNCTION; TaskHandle_t * pxCreatedTask ) PRIVILEGED_FUNCTION;
BaseType_t MPU_xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, BaseType_t MPU_xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition,
TaskHandle_t * pxCreatedTask ) PRIVILEGED_FUNCTION; TaskHandle_t * pxCreatedTask ) PRIVILEGED_FUNCTION;
void vTaskAllocateMPURegions( TaskHandle_t xTaskToModify, void MPU_vTaskAllocateMPURegions( TaskHandle_t xTaskToModify,
const MemoryRegion_t * const xRegions ) PRIVILEGED_FUNCTION; const MemoryRegion_t * const xRegions ) PRIVILEGED_FUNCTION;
BaseType_t MPU_xTaskGetStaticBuffers( TaskHandle_t xTask, BaseType_t MPU_xTaskGetStaticBuffers( TaskHandle_t xTask,
StackType_t ** ppuxStackBuffer, StackType_t ** ppuxStackBuffer,
StaticTask_t ** ppxTaskBuffer ) PRIVILEGED_FUNCTION; StaticTask_t ** ppxTaskBuffer ) PRIVILEGED_FUNCTION;

View file

@ -234,6 +234,35 @@
#define PRIVILEGED_DATA __attribute__( ( section( "privileged_data" ) ) ) #define PRIVILEGED_DATA __attribute__( ( section( "privileged_data" ) ) )
#define FREERTOS_SYSTEM_CALL #define FREERTOS_SYSTEM_CALL
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
#define vGrantAccessToTask( xTask, xTaskToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xTaskToGrantAccess ) )
#define vRevokeAccessToTask( xTask, xTaskToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xTaskToRevokeAccess ) )
#define vGrantAccessToSemaphore( xTask, xSemaphoreToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xSemaphoreToGrantAccess ) )
#define vRevokeAccessToSemaphore( xTask, xSemaphoreToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xSemaphoreToRevokeAccess ) )
#define vGrantAccessToQueue( xTask, xQueueToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xQueueToGrantAccess ) )
#define vRevokeAccessToQueue( xTask, xQueueToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xQueueToRevokeAccess ) )
#define vGrantAccessToQueueSet( xTask, xQueueSetToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xQueueSetToGrantAccess ) )
#define vRevokeAccessToQueueSet( xTask, xQueueSetToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xQueueSetToRevokeAccess ) )
#define vGrantAccessToEventGroup( xTask, xEventGroupToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xEventGroupToGrantAccess ) )
#define vRevokeAccessToEventGroup( xTask, xEventGroupToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xEventGroupToRevokeAccess ) )
#define vGrantAccessToStreamBuffer( xTask, xStreamBufferToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xStreamBufferToGrantAccess ) )
#define vRevokeAccessToStreamBuffer( xTask, xStreamBufferToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xStreamBufferToRevokeAccess ) )
#define vGrantAccessToMessageBuffer( xTask, xMessageBufferToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xMessageBufferToGrantAccess ) )
#define vRevokeAccessToMessageBuffer( xTask, xMessageBufferToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xMessageBufferToRevokeAccess ) )
#define vGrantAccessToTimer( xTask, xTimerToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xTimerToGrantAccess ) )
#define vRevokeAccessToTimer( xTask, xTimerToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xTimerToRevokeAccess ) )
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
#else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ #else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
/* Ensure API functions go in the privileged execution section. */ /* Ensure API functions go in the privileged execution section. */

View file

@ -247,6 +247,21 @@ void vPortEndScheduler( void ) PRIVILEGED_FUNCTION;
uint32_t ulAccessRequested ) PRIVILEGED_FUNCTION; uint32_t ulAccessRequested ) PRIVILEGED_FUNCTION;
#endif #endif
/**
* @brief Checks if the calling task is authorized to access the given kernel object.
*
* @param lInternalIndexOfKernelObject The index of the kernel object in the kernel
* object handle pool.
*
* @return pdTRUE if the calling task is authorized to access the kernel object,
* pdFALSE otherwise.
*/
#if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) PRIVILEGED_FUNCTION;
#endif
/* *INDENT-OFF* */ /* *INDENT-OFF* */
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -267,7 +267,7 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t;
/** /**
* queue. h * queue. h
* @code{c} * @code{c}
* BaseType_t xQueueSendToToFront( * BaseType_t xQueueSendToFront(
* QueueHandle_t xQueue, * QueueHandle_t xQueue,
* const void *pvItemToQueue, * const void *pvItemToQueue,
* TickType_t xTicksToWait * TickType_t xTicksToWait
@ -995,7 +995,7 @@ void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;
* @param pxHigherPriorityTaskWoken xQueueSendToFrontFromISR() will set * @param pxHigherPriorityTaskWoken xQueueSendToFrontFromISR() will set
* *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task
* to unblock, and the unblocked task has a priority higher than the currently * to unblock, and the unblocked task has a priority higher than the currently
* running task. If xQueueSendToFromFromISR() sets this value to pdTRUE then * running task. If xQueueSendToFrontFromISR() sets this value to pdTRUE then
* a context switch should be requested before the interrupt is exited. * a context switch should be requested before the interrupt is exited.
* *
* @return pdTRUE if the data was successfully sent to the queue, otherwise * @return pdTRUE if the data was successfully sent to the queue, otherwise

View file

@ -3469,6 +3469,27 @@ void vTaskExitCriticalFromISR( UBaseType_t uxSavedInterruptStatus );
#endif /* portUSING_MPU_WRAPPERS */ #endif /* portUSING_MPU_WRAPPERS */
#if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
/*
* For internal use only. Grant/Revoke a task's access to a kernel object.
*/
void vGrantAccessToKernelObject( TaskHandle_t xExternalTaskHandle,
int32_t lExternalKernelObjectHandle ) PRIVILEGED_FUNCTION;
void vRevokeAccessToKernelObject( TaskHandle_t xExternalTaskHandle,
int32_t lExternalKernelObjectHandle ) PRIVILEGED_FUNCTION;
/*
* For internal use only. Grant/Revoke a task's access to a kernel object.
*/
void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) PRIVILEGED_FUNCTION;
void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) PRIVILEGED_FUNCTION;
#endif /* #if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/* *INDENT-OFF* */ /* *INDENT-OFF* */
#ifdef __cplusplus #ifdef __cplusplus
} }

26
list.c
View file

@ -49,6 +49,8 @@
void vListInitialise( List_t * const pxList ) void vListInitialise( List_t * const pxList )
{ {
traceENTER_vListInitialise( pxList );
/* The list structure contains a list item which is used to mark the /* The list structure contains a list item which is used to mark the
* end of the list. To initialise the list the list end is inserted * end of the list. To initialise the list the list end is inserted
* as the only list entry. */ * as the only list entry. */
@ -80,11 +82,15 @@ void vListInitialise( List_t * const pxList )
* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ * configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ); listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList );
listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ); listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList );
traceRETURN_vListInitialise();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vListInitialiseItem( ListItem_t * const pxItem ) void vListInitialiseItem( ListItem_t * const pxItem )
{ {
traceENTER_vListInitialiseItem( pxItem );
/* Make sure the list item is not recorded as being on a list. */ /* Make sure the list item is not recorded as being on a list. */
pxItem->pxContainer = NULL; pxItem->pxContainer = NULL;
@ -92,6 +98,8 @@ void vListInitialiseItem( ListItem_t * const pxItem )
* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ * configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ); listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ); listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
traceRETURN_vListInitialiseItem();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -100,6 +108,8 @@ void vListInsertEnd( List_t * const pxList,
{ {
ListItem_t * const pxIndex = pxList->pxIndex; ListItem_t * const pxIndex = pxList->pxIndex;
traceENTER_vListInsertEnd( pxList, pxNewListItem );
/* Only effective when configASSERT() is also defined, these tests may catch /* Only effective when configASSERT() is also defined, these tests may catch
* the list data structures being overwritten in memory. They will not catch * the list data structures being overwritten in memory. They will not catch
* data errors caused by incorrect configuration or use of FreeRTOS. */ * data errors caused by incorrect configuration or use of FreeRTOS. */
@ -122,6 +132,8 @@ void vListInsertEnd( List_t * const pxList,
pxNewListItem->pxContainer = pxList; pxNewListItem->pxContainer = pxList;
( pxList->uxNumberOfItems )++; ( pxList->uxNumberOfItems )++;
traceRETURN_vListInsertEnd();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -131,6 +143,8 @@ void vListInsert( List_t * const pxList,
ListItem_t * pxIterator; ListItem_t * pxIterator;
const TickType_t xValueOfInsertion = pxNewListItem->xItemValue; const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
traceENTER_vListInsert( pxList, pxNewListItem );
/* Only effective when configASSERT() is also defined, these tests may catch /* Only effective when configASSERT() is also defined, these tests may catch
* the list data structures being overwritten in memory. They will not catch * the list data structures being overwritten in memory. They will not catch
* data errors caused by incorrect configuration or use of FreeRTOS. */ * data errors caused by incorrect configuration or use of FreeRTOS. */
@ -193,15 +207,21 @@ void vListInsert( List_t * const pxList,
pxNewListItem->pxContainer = pxList; pxNewListItem->pxContainer = pxList;
( pxList->uxNumberOfItems )++; ( pxList->uxNumberOfItems )++;
traceRETURN_vListInsert();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
{ {
/* The list item knows which list it is in. Obtain the list from the list /* The list item knows which list it is in. Obtain the list from the list
* item. */ * item. */
List_t * const pxList = pxItemToRemove->pxContainer; List_t * const pxList = pxItemToRemove->pxContainer;
traceENTER_uxListRemove( pxItemToRemove );
pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious; pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext; pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
@ -221,6 +241,8 @@ UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
pxItemToRemove->pxContainer = NULL; pxItemToRemove->pxContainer = NULL;
( pxList->uxNumberOfItems )--; ( pxList->uxNumberOfItems )--;
traceRETURN_uxListRemove( pxList->uxNumberOfItems );
return pxList->uxNumberOfItems; return pxList->uxNumberOfItems;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -977,13 +977,19 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */
uint32_t ulPreviousMask; uint32_t ulPreviousMask;
ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
traceISR_ENTER();
{ {
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
traceISR_EXIT_TO_SCHEDULER();
/* Pend a context switch. */ /* Pend a context switch. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
} }
else
{
traceISR_EXIT();
}
} }
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );
} }
@ -2019,3 +2025,85 @@ BaseType_t xPortIsInsideInterrupt( void )
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
BaseType_t xAccessGranted = pdFALSE;
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
{
xAccessGranted = pdTRUE;
}
else
{
if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 )
{
xAccessGranted = pdTRUE;
}
}
return xAccessGranted;
}
#else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
( void ) lInternalIndexOfKernelObject;
/* If Access Control List feature is not used, all the tasks have
* access to all the kernel objects. */
return pdTRUE;
}
#endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
/*-----------------------------------------------------------*/

View file

@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
/* Size of an Access Control List (ACL) entry in bits. */
#define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS
{ {
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) #if ( configUSE_MPU_WRAPPERS_V1 == 0 )
xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo;
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ];
#endif
#endif #endif
} xMPU_SETTINGS; } xMPU_SETTINGS;
@ -331,9 +337,19 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portYIELD() vPortYield() #define portYIELD() vPortYield()
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) \ #define portEND_SWITCHING_ISR( xSwitchRequired ) \
do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } \ do \
while( 0 ) { \
if( xSwitchRequired ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -363,14 +363,21 @@ void xPortSysTickHandler( void )
* save and then restore the interrupt mask value as its value is already * save and then restore the interrupt mask value as its value is already
* known. */ * known. */
( void ) portSET_INTERRUPT_MASK_FROM_ISR(); ( void ) portSET_INTERRUPT_MASK_FROM_ISR();
traceISR_ENTER();
{ {
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
traceISR_EXIT_TO_SCHEDULER();
/* A context switch is required. Context switching is performed in /* A context switch is required. Context switching is performed in
* the PendSV interrupt. Pend the PendSV interrupt. */ * the PendSV interrupt. Pend the PendSV interrupt. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
} }
else
{
traceISR_EXIT();
}
} }
portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 ); portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );
} }

View file

@ -97,8 +97,20 @@ typedef unsigned long UBaseType_t;
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) portYIELD( ); } while( 0 ) #define portEND_SWITCHING_ISR( xSwitchRequired ) \
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) do \
{ \
if( xSwitchRequired != pdFALSE ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portYIELD(); \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -388,14 +388,21 @@ void xPortSysTickHandler( void )
* save and then restore the interrupt mask value as its value is already * save and then restore the interrupt mask value as its value is already
* known. */ * known. */
( void ) portSET_INTERRUPT_MASK_FROM_ISR(); ( void ) portSET_INTERRUPT_MASK_FROM_ISR();
traceISR_ENTER();
{ {
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
traceISR_EXIT_TO_SCHEDULER();
/* A context switch is required. Context switching is performed in /* A context switch is required. Context switching is performed in
* the PendSV interrupt. Pend the PendSV interrupt. */ * the PendSV interrupt. Pend the PendSV interrupt. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
} }
else
{
traceISR_EXIT();
}
} }
portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 ); portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );
} }

View file

@ -91,8 +91,20 @@ typedef unsigned long UBaseType_t;
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) portYIELD( ); } while( 0 ) #define portEND_SWITCHING_ISR( xSwitchRequired ) \
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) do \
{ \
if( xSwitchRequired != pdFALSE ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portYIELD(); \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -106,8 +106,19 @@ extern void vPortClearInterruptMaskFromISR( UBaseType_t );
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) { portYIELD(); } } while( 0 ) #define portEND_SWITCHING_ISR( xSwitchRequired ) \
do \
{ \
if( xSwitchRequired != pdFALSE ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portYIELD(); \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
/* *INDENT-OFF* */ /* *INDENT-OFF* */
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -105,8 +105,19 @@ extern void vPortClearInterruptMaskFromISR( UBaseType_t );
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) { portYIELD(); } } while( 0 ) #define portEND_SWITCHING_ISR( xSwitchRequired ) \
do \
{ \
if( xSwitchRequired != pdFALSE ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portYIELD(); \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
/* *INDENT-OFF* */ /* *INDENT-OFF* */
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -50,6 +50,10 @@
#if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) #if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
#error Access control list is not available with this MPU wrapper. Please set configENABLE_ACCESS_CONTROL_LIST to 0.
#endif
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
BaseType_t MPU_xTaskCreate( TaskFunction_t pvTaskCode, BaseType_t MPU_xTaskCreate( TaskFunction_t pvTaskCode,
const char * const pcName, const char * const pcName,

File diff suppressed because it is too large Load diff

View file

@ -375,13 +375,19 @@ void xPortSysTickHandler( void )
uint32_t ulPreviousMask; uint32_t ulPreviousMask;
ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
traceISR_ENTER();
{ {
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
traceISR_EXIT_TO_SCHEDULER();
/* Pend a context switch. */ /* Pend a context switch. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
} }
else
{
traceISR_EXIT();
}
} }
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );
} }

View file

@ -87,9 +87,19 @@ extern void vPortYield( void );
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portYIELD() vPortYield() #define portYIELD() vPortYield()
#define portEND_SWITCHING_ISR( xSwitchRequired ) \ #define portEND_SWITCHING_ISR( xSwitchRequired ) \
do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } \ do \
while( 0 ) { \
if( xSwitchRequired ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -977,13 +977,19 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */
uint32_t ulPreviousMask; uint32_t ulPreviousMask;
ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
traceISR_ENTER();
{ {
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
traceISR_EXIT_TO_SCHEDULER();
/* Pend a context switch. */ /* Pend a context switch. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
} }
else
{
traceISR_EXIT();
}
} }
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );
} }
@ -2019,3 +2025,85 @@ BaseType_t xPortIsInsideInterrupt( void )
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
BaseType_t xAccessGranted = pdFALSE;
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
{
xAccessGranted = pdTRUE;
}
else
{
if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 )
{
xAccessGranted = pdTRUE;
}
}
return xAccessGranted;
}
#else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
( void ) lInternalIndexOfKernelObject;
/* If Access Control List feature is not used, all the tasks have
* access to all the kernel objects. */
return pdTRUE;
}
#endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
/*-----------------------------------------------------------*/

View file

@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
/* Size of an Access Control List (ACL) entry in bits. */
#define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS
{ {
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) #if ( configUSE_MPU_WRAPPERS_V1 == 0 )
xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo;
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ];
#endif
#endif #endif
} xMPU_SETTINGS; } xMPU_SETTINGS;
@ -331,9 +337,19 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portYIELD() vPortYield() #define portYIELD() vPortYield()
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) \ #define portEND_SWITCHING_ISR( xSwitchRequired ) \
do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } \ do \
while( 0 ) { \
if( xSwitchRequired ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -977,13 +977,19 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */
uint32_t ulPreviousMask; uint32_t ulPreviousMask;
ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
traceISR_ENTER();
{ {
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
traceISR_EXIT_TO_SCHEDULER();
/* Pend a context switch. */ /* Pend a context switch. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
} }
else
{
traceISR_EXIT();
}
} }
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );
} }
@ -2019,3 +2025,85 @@ BaseType_t xPortIsInsideInterrupt( void )
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
BaseType_t xAccessGranted = pdFALSE;
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
{
xAccessGranted = pdTRUE;
}
else
{
if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 )
{
xAccessGranted = pdTRUE;
}
}
return xAccessGranted;
}
#else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
( void ) lInternalIndexOfKernelObject;
/* If Access Control List feature is not used, all the tasks have
* access to all the kernel objects. */
return pdTRUE;
}
#endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
/*-----------------------------------------------------------*/

View file

@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
/* Size of an Access Control List (ACL) entry in bits. */
#define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS
{ {
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) #if ( configUSE_MPU_WRAPPERS_V1 == 0 )
xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo;
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ];
#endif
#endif #endif
} xMPU_SETTINGS; } xMPU_SETTINGS;
@ -331,9 +337,19 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portYIELD() vPortYield() #define portYIELD() vPortYield()
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) \ #define portEND_SWITCHING_ISR( xSwitchRequired ) \
do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } \ do \
while( 0 ) { \
if( xSwitchRequired ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -452,14 +452,21 @@ void xPortSysTickHandler( void )
* save and then restore the interrupt mask value as its value is already * save and then restore the interrupt mask value as its value is already
* known. */ * known. */
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
traceISR_ENTER();
{ {
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
traceISR_EXIT_TO_SCHEDULER();
/* A context switch is required. Context switching is performed in /* A context switch is required. Context switching is performed in
* the PendSV interrupt. Pend the PendSV interrupt. */ * the PendSV interrupt. Pend the PendSV interrupt. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
} }
else
{
traceISR_EXIT();
}
} }
portENABLE_INTERRUPTS(); portENABLE_INTERRUPTS();
} }

View file

@ -95,8 +95,20 @@ typedef unsigned long UBaseType_t;
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) portYIELD( ); } while( 0 ) #define portEND_SWITCHING_ISR( xSwitchRequired ) \
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) do \
{ \
if( xSwitchRequired != pdFALSE ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portYIELD(); \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Critical section management. */ /* Critical section management. */

View file

@ -977,13 +977,19 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */
uint32_t ulPreviousMask; uint32_t ulPreviousMask;
ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
traceISR_ENTER();
{ {
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
traceISR_EXIT_TO_SCHEDULER();
/* Pend a context switch. */ /* Pend a context switch. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
} }
else
{
traceISR_EXIT();
}
} }
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );
} }
@ -2019,3 +2025,85 @@ BaseType_t xPortIsInsideInterrupt( void )
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
BaseType_t xAccessGranted = pdFALSE;
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
{
xAccessGranted = pdTRUE;
}
else
{
if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 )
{
xAccessGranted = pdTRUE;
}
}
return xAccessGranted;
}
#else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
( void ) lInternalIndexOfKernelObject;
/* If Access Control List feature is not used, all the tasks have
* access to all the kernel objects. */
return pdTRUE;
}
#endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
/*-----------------------------------------------------------*/

View file

@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
/* Size of an Access Control List (ACL) entry in bits. */
#define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS
{ {
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) #if ( configUSE_MPU_WRAPPERS_V1 == 0 )
xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo;
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ];
#endif
#endif #endif
} xMPU_SETTINGS; } xMPU_SETTINGS;
@ -331,9 +337,19 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portYIELD() vPortYield() #define portYIELD() vPortYield()
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) \ #define portEND_SWITCHING_ISR( xSwitchRequired ) \
do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } \ do \
while( 0 ) { \
if( xSwitchRequired ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -977,13 +977,19 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */
uint32_t ulPreviousMask; uint32_t ulPreviousMask;
ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
traceISR_ENTER();
{ {
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
traceISR_EXIT_TO_SCHEDULER();
/* Pend a context switch. */ /* Pend a context switch. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
} }
else
{
traceISR_EXIT();
}
} }
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );
} }
@ -2019,3 +2025,85 @@ BaseType_t xPortIsInsideInterrupt( void )
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
BaseType_t xAccessGranted = pdFALSE;
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
{
xAccessGranted = pdTRUE;
}
else
{
if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 )
{
xAccessGranted = pdTRUE;
}
}
return xAccessGranted;
}
#else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
( void ) lInternalIndexOfKernelObject;
/* If Access Control List feature is not used, all the tasks have
* access to all the kernel objects. */
return pdTRUE;
}
#endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
/*-----------------------------------------------------------*/

View file

@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
/* Size of an Access Control List (ACL) entry in bits. */
#define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS
{ {
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) #if ( configUSE_MPU_WRAPPERS_V1 == 0 )
xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo;
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ];
#endif
#endif #endif
} xMPU_SETTINGS; } xMPU_SETTINGS;
@ -331,9 +337,19 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portYIELD() vPortYield() #define portYIELD() vPortYield()
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) \ #define portEND_SWITCHING_ISR( xSwitchRequired ) \
do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } \ do \
while( 0 ) { \
if( xSwitchRequired ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -977,13 +977,19 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */
uint32_t ulPreviousMask; uint32_t ulPreviousMask;
ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
traceISR_ENTER();
{ {
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
traceISR_EXIT_TO_SCHEDULER();
/* Pend a context switch. */ /* Pend a context switch. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
} }
else
{
traceISR_EXIT();
}
} }
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );
} }
@ -2019,3 +2025,85 @@ BaseType_t xPortIsInsideInterrupt( void )
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
BaseType_t xAccessGranted = pdFALSE;
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
{
xAccessGranted = pdTRUE;
}
else
{
if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 )
{
xAccessGranted = pdTRUE;
}
}
return xAccessGranted;
}
#else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
( void ) lInternalIndexOfKernelObject;
/* If Access Control List feature is not used, all the tasks have
* access to all the kernel objects. */
return pdTRUE;
}
#endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
/*-----------------------------------------------------------*/

View file

@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
/* Size of an Access Control List (ACL) entry in bits. */
#define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS
{ {
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) #if ( configUSE_MPU_WRAPPERS_V1 == 0 )
xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo;
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ];
#endif
#endif #endif
} xMPU_SETTINGS; } xMPU_SETTINGS;
@ -331,9 +337,19 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portYIELD() vPortYield() #define portYIELD() vPortYield()
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) \ #define portEND_SWITCHING_ISR( xSwitchRequired ) \
do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } \ do \
while( 0 ) { \
if( xSwitchRequired ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -977,13 +977,19 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */
uint32_t ulPreviousMask; uint32_t ulPreviousMask;
ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
traceISR_ENTER();
{ {
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
traceISR_EXIT_TO_SCHEDULER();
/* Pend a context switch. */ /* Pend a context switch. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
} }
else
{
traceISR_EXIT();
}
} }
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );
} }
@ -2019,3 +2025,85 @@ BaseType_t xPortIsInsideInterrupt( void )
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
BaseType_t xAccessGranted = pdFALSE;
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
{
xAccessGranted = pdTRUE;
}
else
{
if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 )
{
xAccessGranted = pdTRUE;
}
}
return xAccessGranted;
}
#else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
( void ) lInternalIndexOfKernelObject;
/* If Access Control List feature is not used, all the tasks have
* access to all the kernel objects. */
return pdTRUE;
}
#endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
/*-----------------------------------------------------------*/

View file

@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
/* Size of an Access Control List (ACL) entry in bits. */
#define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS
{ {
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) #if ( configUSE_MPU_WRAPPERS_V1 == 0 )
xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo;
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ];
#endif
#endif #endif
} xMPU_SETTINGS; } xMPU_SETTINGS;
@ -331,9 +337,19 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portYIELD() vPortYield() #define portYIELD() vPortYield()
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) \ #define portEND_SWITCHING_ISR( xSwitchRequired ) \
do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } \ do \
while( 0 ) { \
if( xSwitchRequired ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -185,6 +185,11 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) );
*/ */
void vResetPrivilege( void ) __attribute__( ( naked ) ); void vResetPrivilege( void ) __attribute__( ( naked ) );
/**
* @brief Make a task unprivileged.
*/
void vPortSwitchToUserMode( void );
/** /**
* @brief Enter critical section. * @brief Enter critical section.
*/ */
@ -284,7 +289,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
} }
else else
{ {
xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); xMPUSettings->ulTaskFlags &= ( ~( portTASK_IS_PRIVILEGED_FLAG ) );
xMPUSettings->ulContext[ 0 ] = portINITIAL_CONTROL_IF_UNPRIVILEGED; xMPUSettings->ulContext[ 0 ] = portINITIAL_CONTROL_IF_UNPRIVILEGED;
} }
@ -1057,13 +1062,19 @@ void xPortSysTickHandler( void )
uint32_t ulDummy; uint32_t ulDummy;
ulDummy = portSET_INTERRUPT_MASK_FROM_ISR(); ulDummy = portSET_INTERRUPT_MASK_FROM_ISR();
traceISR_ENTER();
{ {
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
traceISR_EXIT_TO_SCHEDULER();
/* Pend a context switch. */ /* Pend a context switch. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
} }
else
{
traceISR_EXIT();
}
} }
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy ); portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy );
} }
@ -1203,6 +1214,19 @@ void vResetPrivilege( void ) /* __attribute__ (( naked )) */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vPortSwitchToUserMode( void )
{
/* Load the current task's MPU settings from its TCB. */
xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL );
/* Mark the task as unprivileged. */
xTaskMpuSettings->ulTaskFlags &= ( ~( portTASK_IS_PRIVILEGED_FLAG ) );
/* Lower the processor's privilege level. */
vResetPrivilege();
}
/*-----------------------------------------------------------*/
void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
const struct xMEMORY_REGION * const xRegions, const struct xMEMORY_REGION * const xRegions,
StackType_t * pxBottomOfStack, StackType_t * pxBottomOfStack,
@ -1423,3 +1447,85 @@ BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer,
#endif /* configASSERT_DEFINED */ #endif /* configASSERT_DEFINED */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
BaseType_t xAccessGranted = pdFALSE;
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
{
xAccessGranted = pdTRUE;
}
else
{
if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 )
{
xAccessGranted = pdTRUE;
}
}
return xAccessGranted;
}
#else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
( void ) lInternalIndexOfKernelObject;
/* If Access Control List feature is not used, all the tasks have
* access to all the kernel objects. */
return pdTRUE;
}
#endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
/*-----------------------------------------------------------*/

View file

@ -96,8 +96,6 @@ typedef unsigned long UBaseType_t;
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) #define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
#define portTOTAL_NUM_REGIONS_IN_TCB ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ #define portTOTAL_NUM_REGIONS_IN_TCB ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
#define portSWITCH_TO_USER_MODE() __asm volatile ( " mrs r0, control \n orr r0, #1 \n msr control, r0 " ::: "r0", "memory" )
typedef struct MPU_REGION_REGISTERS typedef struct MPU_REGION_REGISTERS
{ {
uint32_t ulRegionBaseAddress; uint32_t ulRegionBaseAddress;
@ -127,7 +125,10 @@ typedef struct MPU_REGION_SETTINGS
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
#define MAX_CONTEXT_SIZE 20 #define MAX_CONTEXT_SIZE ( 20 )
/* Size of an Access Control List (ACL) entry in bits. */
#define portACL_ENTRY_SIZE_BITS ( 32U )
/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
@ -142,6 +143,9 @@ typedef struct MPU_SETTINGS
#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) #if ( configUSE_MPU_WRAPPERS_V1 == 0 )
xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo;
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ];
#endif
#endif #endif
} xMPU_SETTINGS; } xMPU_SETTINGS;
@ -176,9 +180,19 @@ typedef struct MPU_SETTINGS
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) \ #define portEND_SWITCHING_ISR( xSwitchRequired ) \
do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } \ do \
while( 0 ) { \
if( xSwitchRequired ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -252,24 +266,33 @@ extern void vPortExitCritical( void );
extern BaseType_t xIsPrivileged( void ); extern BaseType_t xIsPrivileged( void );
extern void vResetPrivilege( void ); extern void vResetPrivilege( void );
extern void vPortSwitchToUserMode( void );
/** /**
* @brief Checks whether or not the processor is privileged. * @brief Checks whether or not the processor is privileged.
* *
* @return 1 if the processor is already privileged, 0 otherwise. * @return 1 if the processor is already privileged, 0 otherwise.
*/ */
#define portIS_PRIVILEGED() xIsPrivileged() #define portIS_PRIVILEGED() xIsPrivileged()
/** /**
* @brief Raise an SVC request to raise privilege. * @brief Raise an SVC request to raise privilege.
*/ */
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" ); #define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
/** /**
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL * @brief Lowers the privilege level by setting the bit 0 of the CONTROL
* register. * register.
*/ */
#define portRESET_PRIVILEGE() vResetPrivilege() #define portRESET_PRIVILEGE() vResetPrivilege()
/**
* @brief Make a task unprivileged.
*
* It must be called from privileged tasks only. Calling it from unprivileged
* task will result in a memory protection fault.
*/
#define portSWITCH_TO_USER_MODE() vPortSwitchToUserMode()
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
extern BaseType_t xPortIsTaskPrivileged( void ); extern BaseType_t xPortIsTaskPrivileged( void );

View file

@ -521,14 +521,21 @@ void xPortSysTickHandler( void )
* save and then restore the interrupt mask value as its value is already * save and then restore the interrupt mask value as its value is already
* known. */ * known. */
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
traceISR_ENTER();
{ {
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
traceISR_EXIT_TO_SCHEDULER();
/* A context switch is required. Context switching is performed in /* A context switch is required. Context switching is performed in
* the PendSV interrupt. Pend the PendSV interrupt. */ * the PendSV interrupt. Pend the PendSV interrupt. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
} }
else
{
traceISR_EXIT();
}
} }
portENABLE_INTERRUPTS(); portENABLE_INTERRUPTS();
} }

View file

@ -98,8 +98,20 @@ typedef unsigned long UBaseType_t;
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) portYIELD( ); } while( 0 ) #define portEND_SWITCHING_ISR( xSwitchRequired ) \
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) do \
{ \
if( xSwitchRequired != pdFALSE ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portYIELD(); \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Critical section management. */ /* Critical section management. */

View file

@ -206,6 +206,11 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) );
*/ */
void vResetPrivilege( void ) __attribute__( ( naked ) ); void vResetPrivilege( void ) __attribute__( ( naked ) );
/**
* @brief Make a task unprivileged.
*/
void vPortSwitchToUserMode( void );
/** /**
* @brief Enter critical section. * @brief Enter critical section.
*/ */
@ -312,7 +317,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
} }
else else
{ {
xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); xMPUSettings->ulTaskFlags &= ( ~( portTASK_IS_PRIVILEGED_FLAG ) );
xMPUSettings->ulContext[ 0 ] = portINITIAL_CONTROL_IF_UNPRIVILEGED; xMPUSettings->ulContext[ 0 ] = portINITIAL_CONTROL_IF_UNPRIVILEGED;
} }
@ -1203,13 +1208,19 @@ void xPortSysTickHandler( void )
uint32_t ulDummy; uint32_t ulDummy;
ulDummy = portSET_INTERRUPT_MASK_FROM_ISR(); ulDummy = portSET_INTERRUPT_MASK_FROM_ISR();
traceISR_ENTER();
{ {
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
traceISR_EXIT_TO_SCHEDULER();
/* Pend a context switch. */ /* Pend a context switch. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
} }
else
{
traceISR_EXIT();
}
} }
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy ); portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy );
} }
@ -1384,6 +1395,19 @@ void vResetPrivilege( void ) /* __attribute__ (( naked )) */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vPortSwitchToUserMode( void )
{
/* Load the current task's MPU settings from its TCB. */
xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL );
/* Mark the task as unprivileged. */
xTaskMpuSettings->ulTaskFlags &= ( ~( portTASK_IS_PRIVILEGED_FLAG ) );
/* Lower the processor's privilege level. */
vResetPrivilege();
}
/*-----------------------------------------------------------*/
void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
const struct xMEMORY_REGION * const xRegions, const struct xMEMORY_REGION * const xRegions,
StackType_t * pxBottomOfStack, StackType_t * pxBottomOfStack,
@ -1617,3 +1641,85 @@ BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer,
#endif /* configASSERT_DEFINED */ #endif /* configASSERT_DEFINED */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
BaseType_t xAccessGranted = pdFALSE;
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
{
xAccessGranted = pdTRUE;
}
else
{
if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 )
{
xAccessGranted = pdTRUE;
}
}
return xAccessGranted;
}
#else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
( void ) lInternalIndexOfKernelObject;
/* If Access Control List feature is not used, all the tasks have
* access to all the kernel objects. */
return pdTRUE;
}
#endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
/*-----------------------------------------------------------*/

View file

@ -190,8 +190,6 @@ typedef unsigned long UBaseType_t;
#define portNUM_CONFIGURABLE_REGIONS ( configTOTAL_MPU_REGIONS - 5UL ) #define portNUM_CONFIGURABLE_REGIONS ( configTOTAL_MPU_REGIONS - 5UL )
#define portTOTAL_NUM_REGIONS_IN_TCB ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus 1 to create space for the stack region. */ #define portTOTAL_NUM_REGIONS_IN_TCB ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus 1 to create space for the stack region. */
#define portSWITCH_TO_USER_MODE() __asm volatile ( " mrs r0, control \n orr r0, #1 \n msr control, r0 " ::: "r0", "memory" )
typedef struct MPU_REGION_REGISTERS typedef struct MPU_REGION_REGISTERS
{ {
uint32_t ulRegionBaseAddress; uint32_t ulRegionBaseAddress;
@ -221,7 +219,10 @@ typedef struct MPU_REGION_SETTINGS
#endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */
#define MAX_CONTEXT_SIZE 52 #define MAX_CONTEXT_SIZE ( 52 )
/* Size of an Access Control List (ACL) entry in bits. */
#define portACL_ENTRY_SIZE_BITS ( 32U )
/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
@ -236,6 +237,9 @@ typedef struct MPU_SETTINGS
#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) #if ( configUSE_MPU_WRAPPERS_V1 == 0 )
xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo;
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ];
#endif
#endif #endif
} xMPU_SETTINGS; } xMPU_SETTINGS;
@ -270,9 +274,19 @@ typedef struct MPU_SETTINGS
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) \ #define portEND_SWITCHING_ISR( xSwitchRequired ) \
do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } \ do \
while( 0 ) { \
if( xSwitchRequired ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -346,24 +360,33 @@ extern void vPortExitCritical( void );
extern BaseType_t xIsPrivileged( void ); extern BaseType_t xIsPrivileged( void );
extern void vResetPrivilege( void ); extern void vResetPrivilege( void );
extern void vPortSwitchToUserMode( void );
/** /**
* @brief Checks whether or not the processor is privileged. * @brief Checks whether or not the processor is privileged.
* *
* @return 1 if the processor is already privileged, 0 otherwise. * @return 1 if the processor is already privileged, 0 otherwise.
*/ */
#define portIS_PRIVILEGED() xIsPrivileged() #define portIS_PRIVILEGED() xIsPrivileged()
/** /**
* @brief Raise an SVC request to raise privilege. * @brief Raise an SVC request to raise privilege.
*/ */
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" ); #define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
/** /**
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL * @brief Lowers the privilege level by setting the bit 0 of the CONTROL
* register. * register.
*/ */
#define portRESET_PRIVILEGE() vResetPrivilege() #define portRESET_PRIVILEGE() vResetPrivilege()
/**
* @brief Make a task unprivileged.
*
* It must be called from privileged tasks only. Calling it from unprivileged
* task will result in a memory protection fault.
*/
#define portSWITCH_TO_USER_MODE() vPortSwitchToUserMode()
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
extern BaseType_t xPortIsTaskPrivileged( void ); extern BaseType_t xPortIsTaskPrivileged( void );

View file

@ -977,13 +977,19 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */
uint32_t ulPreviousMask; uint32_t ulPreviousMask;
ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
traceISR_ENTER();
{ {
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
traceISR_EXIT_TO_SCHEDULER();
/* Pend a context switch. */ /* Pend a context switch. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
} }
else
{
traceISR_EXIT();
}
} }
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );
} }
@ -2019,3 +2025,85 @@ BaseType_t xPortIsInsideInterrupt( void )
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
BaseType_t xAccessGranted = pdFALSE;
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
{
xAccessGranted = pdTRUE;
}
else
{
if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 )
{
xAccessGranted = pdTRUE;
}
}
return xAccessGranted;
}
#else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
( void ) lInternalIndexOfKernelObject;
/* If Access Control List feature is not used, all the tasks have
* access to all the kernel objects. */
return pdTRUE;
}
#endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
/*-----------------------------------------------------------*/

View file

@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
/* Size of an Access Control List (ACL) entry in bits. */
#define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS
{ {
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) #if ( configUSE_MPU_WRAPPERS_V1 == 0 )
xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo;
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ];
#endif
#endif #endif
} xMPU_SETTINGS; } xMPU_SETTINGS;
@ -331,9 +337,19 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portYIELD() vPortYield() #define portYIELD() vPortYield()
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) \ #define portEND_SWITCHING_ISR( xSwitchRequired ) \
do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } \ do \
while( 0 ) { \
if( xSwitchRequired ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -977,13 +977,19 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */
uint32_t ulPreviousMask; uint32_t ulPreviousMask;
ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
traceISR_ENTER();
{ {
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
traceISR_EXIT_TO_SCHEDULER();
/* Pend a context switch. */ /* Pend a context switch. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
} }
else
{
traceISR_EXIT();
}
} }
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );
} }
@ -2019,3 +2025,85 @@ BaseType_t xPortIsInsideInterrupt( void )
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
BaseType_t xAccessGranted = pdFALSE;
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
{
xAccessGranted = pdTRUE;
}
else
{
if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 )
{
xAccessGranted = pdTRUE;
}
}
return xAccessGranted;
}
#else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
( void ) lInternalIndexOfKernelObject;
/* If Access Control List feature is not used, all the tasks have
* access to all the kernel objects. */
return pdTRUE;
}
#endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
/*-----------------------------------------------------------*/

View file

@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
/* Size of an Access Control List (ACL) entry in bits. */
#define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS
{ {
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) #if ( configUSE_MPU_WRAPPERS_V1 == 0 )
xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo;
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ];
#endif
#endif #endif
} xMPU_SETTINGS; } xMPU_SETTINGS;
@ -331,9 +337,19 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portYIELD() vPortYield() #define portYIELD() vPortYield()
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) \ #define portEND_SWITCHING_ISR( xSwitchRequired ) \
do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } \ do \
while( 0 ) { \
if( xSwitchRequired ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -95,9 +95,18 @@ typedef unsigned long UBaseType_t;
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) \ #define portEND_SWITCHING_ISR( xSwitchRequired ) \
do { if( xSwitchRequired != pdFALSE ) { traceISR_EXIT_TO_SCHEDULER(); portYIELD(); } \ do \
else { traceISR_EXIT(); } \ { \
if( xSwitchRequired != pdFALSE ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portYIELD(); \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 ) } while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -977,13 +977,19 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */
uint32_t ulPreviousMask; uint32_t ulPreviousMask;
ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
traceISR_ENTER();
{ {
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
traceISR_EXIT_TO_SCHEDULER();
/* Pend a context switch. */ /* Pend a context switch. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
} }
else
{
traceISR_EXIT();
}
} }
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );
} }
@ -2019,3 +2025,85 @@ BaseType_t xPortIsInsideInterrupt( void )
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
BaseType_t xAccessGranted = pdFALSE;
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
{
xAccessGranted = pdTRUE;
}
else
{
if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 )
{
xAccessGranted = pdTRUE;
}
}
return xAccessGranted;
}
#else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
( void ) lInternalIndexOfKernelObject;
/* If Access Control List feature is not used, all the tasks have
* access to all the kernel objects. */
return pdTRUE;
}
#endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
/*-----------------------------------------------------------*/

View file

@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
/* Size of an Access Control List (ACL) entry in bits. */
#define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS
{ {
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) #if ( configUSE_MPU_WRAPPERS_V1 == 0 )
xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo;
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ];
#endif
#endif #endif
} xMPU_SETTINGS; } xMPU_SETTINGS;
@ -331,9 +337,19 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portYIELD() vPortYield() #define portYIELD() vPortYield()
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) \ #define portEND_SWITCHING_ISR( xSwitchRequired ) \
do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } \ do \
while( 0 ) { \
if( xSwitchRequired ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -977,13 +977,19 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */
uint32_t ulPreviousMask; uint32_t ulPreviousMask;
ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
traceISR_ENTER();
{ {
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
traceISR_EXIT_TO_SCHEDULER();
/* Pend a context switch. */ /* Pend a context switch. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
} }
else
{
traceISR_EXIT();
}
} }
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );
} }
@ -2019,3 +2025,85 @@ BaseType_t xPortIsInsideInterrupt( void )
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
BaseType_t xAccessGranted = pdFALSE;
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
{
xAccessGranted = pdTRUE;
}
else
{
if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 )
{
xAccessGranted = pdTRUE;
}
}
return xAccessGranted;
}
#else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
( void ) lInternalIndexOfKernelObject;
/* If Access Control List feature is not used, all the tasks have
* access to all the kernel objects. */
return pdTRUE;
}
#endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
/*-----------------------------------------------------------*/

View file

@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
/* Size of an Access Control List (ACL) entry in bits. */
#define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS
{ {
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) #if ( configUSE_MPU_WRAPPERS_V1 == 0 )
xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo;
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ];
#endif
#endif #endif
} xMPU_SETTINGS; } xMPU_SETTINGS;
@ -331,9 +337,19 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portYIELD() vPortYield() #define portYIELD() vPortYield()
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) \ #define portEND_SWITCHING_ISR( xSwitchRequired ) \
do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } \ do \
while( 0 ) { \
if( xSwitchRequired ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -105,7 +105,19 @@ extern void vPortClearInterruptMaskFromISR( UBaseType_t );
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) { portYIELD(); } } while( 0 ) #define portEND_SWITCHING_ISR( xSwitchRequired ) \
do \
{ \
if( xSwitchRequired != pdFALSE ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portYIELD(); \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
/* *INDENT-OFF* */ /* *INDENT-OFF* */

View file

@ -84,9 +84,20 @@ typedef unsigned long UBaseType_t;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
extern void vTaskSwitchContext( void ); extern void vTaskSwitchContext( void );
#define portYIELD() asm volatile ( "trap" ); #define portYIELD() asm volatile ( "trap" );
#define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) vTaskSwitchContext( ); } while( 0 ) #define portEND_SWITCHING_ISR( xSwitchRequired ) \
do \
{ \
if( xSwitchRequired != pdFALSE ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
vTaskSwitchContext(); \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
/* Include the port_asm.S file where the Context saving/restoring is defined. */ /* Include the port_asm.S file where the Context saving/restoring is defined. */
__asm__ ( "\n\t.globl save_context" ); __asm__ ( "\n\t.globl save_context" );

View file

@ -91,9 +91,21 @@ typedef portUBASE_TYPE TickType_t;
/* Scheduler utilities. */ /* Scheduler utilities. */
extern void vTaskSwitchContext( void ); extern void vTaskSwitchContext( void );
#define portYIELD() __asm volatile ( "ecall" ); #define portYIELD() __asm volatile ( "ecall" );
#define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) vTaskSwitchContext( ); } while( 0 ) #define portEND_SWITCHING_ISR( xSwitchRequired ) \
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) do \
{ \
if( xSwitchRequired != pdFALSE ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
vTaskSwitchContext(); \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Critical section management. */ /* Critical section management. */

View file

@ -129,8 +129,13 @@ extern void vPortExitCritical( void );
\ \
if( xSwitchRequired ) \ if( xSwitchRequired ) \
{ \ { \
traceISR_EXIT_TO_SCHEDULER(); \
vTaskSwitchContext(); \ vTaskSwitchContext(); \
} \ } \
else \
{ \
traceISR_EXIT(); \
} \
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -233,13 +233,19 @@ void xPortSysTickHandler( void )
uint32_t ulPreviousMask; uint32_t ulPreviousMask;
ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
traceISR_ENTER();
{ {
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
traceISR_EXIT_TO_SCHEDULER();
/* Pend a context switch. */ /* Pend a context switch. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET;
} }
else
{
traceISR_EXIT();
}
} }
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );
} }

View file

@ -86,9 +86,21 @@ typedef unsigned long UBaseType_t;
extern void vPortYield( void ); extern void vPortYield( void );
#define portNVIC_INT_CTRL ( ( volatile uint32_t * ) 0xe000ed04 ) #define portNVIC_INT_CTRL ( ( volatile uint32_t * ) 0xe000ed04 )
#define portNVIC_PENDSVSET 0x10000000 #define portNVIC_PENDSVSET 0x10000000
#define portYIELD() vPortYield() #define portYIELD() vPortYield()
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) *( portNVIC_INT_CTRL ) = portNVIC_PENDSVSET #define portEND_SWITCHING_ISR( xSwitchRequired ) \
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) do \
{ \
if( xSwitchRequired != pdFALSE ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
*( portNVIC_INT_CTRL ) = portNVIC_PENDSVSET \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -977,13 +977,19 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */
uint32_t ulPreviousMask; uint32_t ulPreviousMask;
ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
traceISR_ENTER();
{ {
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
traceISR_EXIT_TO_SCHEDULER();
/* Pend a context switch. */ /* Pend a context switch. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
} }
else
{
traceISR_EXIT();
}
} }
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );
} }
@ -2019,3 +2025,85 @@ BaseType_t xPortIsInsideInterrupt( void )
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
BaseType_t xAccessGranted = pdFALSE;
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
{
xAccessGranted = pdTRUE;
}
else
{
if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 )
{
xAccessGranted = pdTRUE;
}
}
return xAccessGranted;
}
#else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
( void ) lInternalIndexOfKernelObject;
/* If Access Control List feature is not used, all the tasks have
* access to all the kernel objects. */
return pdTRUE;
}
#endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
/*-----------------------------------------------------------*/

View file

@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
/* Size of an Access Control List (ACL) entry in bits. */
#define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS
{ {
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) #if ( configUSE_MPU_WRAPPERS_V1 == 0 )
xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo;
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ];
#endif
#endif #endif
} xMPU_SETTINGS; } xMPU_SETTINGS;
@ -331,9 +337,19 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portYIELD() vPortYield() #define portYIELD() vPortYield()
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) \ #define portEND_SWITCHING_ISR( xSwitchRequired ) \
do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } \ do \
while( 0 ) { \
if( xSwitchRequired ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -977,13 +977,19 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */
uint32_t ulPreviousMask; uint32_t ulPreviousMask;
ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
traceISR_ENTER();
{ {
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
traceISR_EXIT_TO_SCHEDULER();
/* Pend a context switch. */ /* Pend a context switch. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
} }
else
{
traceISR_EXIT();
}
} }
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );
} }
@ -2019,3 +2025,85 @@ BaseType_t xPortIsInsideInterrupt( void )
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
BaseType_t xAccessGranted = pdFALSE;
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
{
xAccessGranted = pdTRUE;
}
else
{
if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 )
{
xAccessGranted = pdTRUE;
}
}
return xAccessGranted;
}
#else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
( void ) lInternalIndexOfKernelObject;
/* If Access Control List feature is not used, all the tasks have
* access to all the kernel objects. */
return pdTRUE;
}
#endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
/*-----------------------------------------------------------*/

View file

@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
/* Size of an Access Control List (ACL) entry in bits. */
#define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS
{ {
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) #if ( configUSE_MPU_WRAPPERS_V1 == 0 )
xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo;
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ];
#endif
#endif #endif
} xMPU_SETTINGS; } xMPU_SETTINGS;
@ -331,9 +337,19 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portYIELD() vPortYield() #define portYIELD() vPortYield()
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) \ #define portEND_SWITCHING_ISR( xSwitchRequired ) \
do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } \ do \
while( 0 ) { \
if( xSwitchRequired ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -355,14 +355,21 @@ void xPortSysTickHandler( void )
* save and then restore the interrupt mask value as its value is already * save and then restore the interrupt mask value as its value is already
* known. */ * known. */
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
traceISR_ENTER();
{ {
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
traceISR_EXIT_TO_SCHEDULER();
/* A context switch is required. Context switching is performed in /* A context switch is required. Context switching is performed in
* the PendSV interrupt. Pend the PendSV interrupt. */ * the PendSV interrupt. Pend the PendSV interrupt. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
} }
else
{
traceISR_EXIT();
}
} }
portENABLE_INTERRUPTS(); portENABLE_INTERRUPTS();
} }

View file

@ -100,8 +100,20 @@ typedef unsigned long UBaseType_t;
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) portYIELD( ); } while( 0 ) #define portEND_SWITCHING_ISR( xSwitchRequired ) \
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) do \
{ \
if( xSwitchRequired != pdFALSE ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portYIELD(); \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -977,13 +977,19 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */
uint32_t ulPreviousMask; uint32_t ulPreviousMask;
ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
traceISR_ENTER();
{ {
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
traceISR_EXIT_TO_SCHEDULER();
/* Pend a context switch. */ /* Pend a context switch. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
} }
else
{
traceISR_EXIT();
}
} }
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );
} }
@ -2019,3 +2025,85 @@ BaseType_t xPortIsInsideInterrupt( void )
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
BaseType_t xAccessGranted = pdFALSE;
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
{
xAccessGranted = pdTRUE;
}
else
{
if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 )
{
xAccessGranted = pdTRUE;
}
}
return xAccessGranted;
}
#else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
( void ) lInternalIndexOfKernelObject;
/* If Access Control List feature is not used, all the tasks have
* access to all the kernel objects. */
return pdTRUE;
}
#endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
/*-----------------------------------------------------------*/

View file

@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
/* Size of an Access Control List (ACL) entry in bits. */
#define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS
{ {
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) #if ( configUSE_MPU_WRAPPERS_V1 == 0 )
xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo;
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ];
#endif
#endif #endif
} xMPU_SETTINGS; } xMPU_SETTINGS;
@ -331,9 +337,19 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portYIELD() vPortYield() #define portYIELD() vPortYield()
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) \ #define portEND_SWITCHING_ISR( xSwitchRequired ) \
do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } \ do \
while( 0 ) { \
if( xSwitchRequired ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -977,13 +977,19 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */
uint32_t ulPreviousMask; uint32_t ulPreviousMask;
ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
traceISR_ENTER();
{ {
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
traceISR_EXIT_TO_SCHEDULER();
/* Pend a context switch. */ /* Pend a context switch. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
} }
else
{
traceISR_EXIT();
}
} }
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );
} }
@ -2019,3 +2025,85 @@ BaseType_t xPortIsInsideInterrupt( void )
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
BaseType_t xAccessGranted = pdFALSE;
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
{
xAccessGranted = pdTRUE;
}
else
{
if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 )
{
xAccessGranted = pdTRUE;
}
}
return xAccessGranted;
}
#else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
( void ) lInternalIndexOfKernelObject;
/* If Access Control List feature is not used, all the tasks have
* access to all the kernel objects. */
return pdTRUE;
}
#endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
/*-----------------------------------------------------------*/

View file

@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
/* Size of an Access Control List (ACL) entry in bits. */
#define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS
{ {
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) #if ( configUSE_MPU_WRAPPERS_V1 == 0 )
xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo;
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ];
#endif
#endif #endif
} xMPU_SETTINGS; } xMPU_SETTINGS;
@ -331,9 +337,19 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portYIELD() vPortYield() #define portYIELD() vPortYield()
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) \ #define portEND_SWITCHING_ISR( xSwitchRequired ) \
do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } \ do \
while( 0 ) { \
if( xSwitchRequired ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -977,13 +977,19 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */
uint32_t ulPreviousMask; uint32_t ulPreviousMask;
ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
traceISR_ENTER();
{ {
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
traceISR_EXIT_TO_SCHEDULER();
/* Pend a context switch. */ /* Pend a context switch. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
} }
else
{
traceISR_EXIT();
}
} }
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );
} }
@ -2019,3 +2025,85 @@ BaseType_t xPortIsInsideInterrupt( void )
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
BaseType_t xAccessGranted = pdFALSE;
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
{
xAccessGranted = pdTRUE;
}
else
{
if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 )
{
xAccessGranted = pdTRUE;
}
}
return xAccessGranted;
}
#else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
( void ) lInternalIndexOfKernelObject;
/* If Access Control List feature is not used, all the tasks have
* access to all the kernel objects. */
return pdTRUE;
}
#endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
/*-----------------------------------------------------------*/

View file

@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
/* Size of an Access Control List (ACL) entry in bits. */
#define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS
{ {
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) #if ( configUSE_MPU_WRAPPERS_V1 == 0 )
xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo;
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ];
#endif
#endif #endif
} xMPU_SETTINGS; } xMPU_SETTINGS;
@ -331,9 +337,19 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portYIELD() vPortYield() #define portYIELD() vPortYield()
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) \ #define portEND_SWITCHING_ISR( xSwitchRequired ) \
do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } \ do \
while( 0 ) { \
if( xSwitchRequired ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -977,13 +977,19 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */
uint32_t ulPreviousMask; uint32_t ulPreviousMask;
ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
traceISR_ENTER();
{ {
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
traceISR_EXIT_TO_SCHEDULER();
/* Pend a context switch. */ /* Pend a context switch. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
} }
else
{
traceISR_EXIT();
}
} }
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );
} }
@ -2019,3 +2025,85 @@ BaseType_t xPortIsInsideInterrupt( void )
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
BaseType_t xAccessGranted = pdFALSE;
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
{
xAccessGranted = pdTRUE;
}
else
{
if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 )
{
xAccessGranted = pdTRUE;
}
}
return xAccessGranted;
}
#else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
( void ) lInternalIndexOfKernelObject;
/* If Access Control List feature is not used, all the tasks have
* access to all the kernel objects. */
return pdTRUE;
}
#endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
/*-----------------------------------------------------------*/

View file

@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
/* Size of an Access Control List (ACL) entry in bits. */
#define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS
{ {
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) #if ( configUSE_MPU_WRAPPERS_V1 == 0 )
xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo;
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ];
#endif
#endif #endif
} xMPU_SETTINGS; } xMPU_SETTINGS;
@ -331,9 +337,19 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portYIELD() vPortYield() #define portYIELD() vPortYield()
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) \ #define portEND_SWITCHING_ISR( xSwitchRequired ) \
do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } \ do \
while( 0 ) { \
if( xSwitchRequired ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -399,14 +399,21 @@ void xPortSysTickHandler( void )
* save and then restore the interrupt mask value as its value is already * save and then restore the interrupt mask value as its value is already
* known. */ * known. */
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
traceISR_ENTER();
{ {
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
traceISR_EXIT_TO_SCHEDULER();
/* A context switch is required. Context switching is performed in /* A context switch is required. Context switching is performed in
* the PendSV interrupt. Pend the PendSV interrupt. */ * the PendSV interrupt. Pend the PendSV interrupt. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
} }
else
{
traceISR_EXIT();
}
} }
portENABLE_INTERRUPTS(); portENABLE_INTERRUPTS();
} }

View file

@ -99,8 +99,20 @@ typedef unsigned long UBaseType_t;
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) portYIELD( ); } while( 0 ) #define portEND_SWITCHING_ISR( xSwitchRequired ) \
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) do \
{ \
if( xSwitchRequired != pdFALSE ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portYIELD(); \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -283,6 +283,11 @@ extern void vPortRestoreContextOfFirstTask( void ) PRIVILEGED_FUNCTION;
*/ */
BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION;
/**
* @brief Make a task unprivileged.
*/
void vPortSwitchToUserMode( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Each task maintains its own interrupt status in the critical nesting /* Each task maintains its own interrupt status in the critical nesting
@ -318,7 +323,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
} }
else else
{ {
xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); xMPUSettings->ulTaskFlags &= ( ~( portTASK_IS_PRIVILEGED_FLAG ) );
xMPUSettings->ulContext[ 0 ] = portINITIAL_CONTROL_IF_UNPRIVILEGED; xMPUSettings->ulContext[ 0 ] = portINITIAL_CONTROL_IF_UNPRIVILEGED;
} }
@ -741,6 +746,19 @@ BaseType_t xPortIsTaskPrivileged( void ) /* PRIVILEGED_FUNCTION */
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vPortSwitchToUserMode( void )
{
/* Load the current task's MPU settings from its TCB. */
xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL );
/* Mark the task as unprivileged. */
xTaskMpuSettings->ulTaskFlags &= ( ~( portTASK_IS_PRIVILEGED_FLAG ) );
/* Lower the processor's privilege level. */
vResetPrivilege();
}
/*-----------------------------------------------------------*/
/* /*
* See header file for description. * See header file for description.
*/ */
@ -987,14 +1005,21 @@ void xPortSysTickHandler( void )
* save and then restore the interrupt mask value as its value is already * save and then restore the interrupt mask value as its value is already
* known. */ * known. */
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
traceISR_ENTER();
{ {
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
traceISR_EXIT_TO_SCHEDULER();
/* A context switch is required. Context switching is performed in /* A context switch is required. Context switching is performed in
* the PendSV interrupt. Pend the PendSV interrupt. */ * the PendSV interrupt. Pend the PendSV interrupt. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
} }
else
{
traceISR_EXIT();
}
} }
portENABLE_INTERRUPTS(); portENABLE_INTERRUPTS();
} }
@ -1332,3 +1357,85 @@ BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer,
#endif /* configASSERT_DEFINED */ #endif /* configASSERT_DEFINED */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
BaseType_t xAccessGranted = pdFALSE;
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
{
xAccessGranted = pdTRUE;
}
else
{
if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 )
{
xAccessGranted = pdTRUE;
}
}
return xAccessGranted;
}
#else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
( void ) lInternalIndexOfKernelObject;
/* If Access Control List feature is not used, all the tasks have
* access to all the kernel objects. */
return pdTRUE;
}
#endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
/*-----------------------------------------------------------*/

View file

@ -192,8 +192,6 @@ typedef unsigned long UBaseType_t;
#define portNUM_CONFIGURABLE_REGIONS ( configTOTAL_MPU_REGIONS - 5UL ) #define portNUM_CONFIGURABLE_REGIONS ( configTOTAL_MPU_REGIONS - 5UL )
#define portTOTAL_NUM_REGIONS_IN_TCB ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus 1 to create space for the stack region. */ #define portTOTAL_NUM_REGIONS_IN_TCB ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus 1 to create space for the stack region. */
#define portSWITCH_TO_USER_MODE() __asm volatile ( " mrs r0, control \n orr r0, r0, #1 \n msr control, r0 " ::: "r0", "memory" )
typedef struct MPU_REGION_REGISTERS typedef struct MPU_REGION_REGISTERS
{ {
uint32_t ulRegionBaseAddress; uint32_t ulRegionBaseAddress;
@ -223,7 +221,10 @@ typedef struct MPU_REGION_SETTINGS
#endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */
#define MAX_CONTEXT_SIZE 52 #define MAX_CONTEXT_SIZE ( 52 )
/* Size of an Access Control List (ACL) entry in bits. */
#define portACL_ENTRY_SIZE_BITS ( 32U )
/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
@ -238,6 +239,9 @@ typedef struct MPU_SETTINGS
#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) #if ( configUSE_MPU_WRAPPERS_V1 == 0 )
xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo;
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ];
#endif
#endif #endif
} xMPU_SETTINGS; } xMPU_SETTINGS;
@ -268,8 +272,20 @@ typedef struct MPU_SETTINGS
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) portYIELD_WITHIN_API( ); } while( 0 ) #define portEND_SWITCHING_ISR( xSwitchRequired ) \
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) do \
{ \
if( xSwitchRequired != pdFALSE ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portYIELD_WITHIN_API(); \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Architecture specific optimisations. */ /* Architecture specific optimisations. */
@ -372,24 +388,33 @@ portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void )
extern BaseType_t xIsPrivileged( void ); extern BaseType_t xIsPrivileged( void );
extern void vResetPrivilege( void ); extern void vResetPrivilege( void );
extern void vPortSwitchToUserMode( void );
/** /**
* @brief Checks whether or not the processor is privileged. * @brief Checks whether or not the processor is privileged.
* *
* @return 1 if the processor is already privileged, 0 otherwise. * @return 1 if the processor is already privileged, 0 otherwise.
*/ */
#define portIS_PRIVILEGED() xIsPrivileged() #define portIS_PRIVILEGED() xIsPrivileged()
/** /**
* @brief Raise an SVC request to raise privilege. * @brief Raise an SVC request to raise privilege.
*/ */
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" ); #define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
/** /**
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL * @brief Lowers the privilege level by setting the bit 0 of the CONTROL
* register. * register.
*/ */
#define portRESET_PRIVILEGE() vResetPrivilege() #define portRESET_PRIVILEGE() vResetPrivilege()
/**
* @brief Make a task unprivileged.
*
* It must be called from privileged tasks only. Calling it from unprivileged
* task will result in a memory protection fault.
*/
#define portSWITCH_TO_USER_MODE() vPortSwitchToUserMode()
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
extern BaseType_t xPortIsTaskPrivileged( void ); extern BaseType_t xPortIsTaskPrivileged( void );

View file

@ -977,13 +977,19 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */
uint32_t ulPreviousMask; uint32_t ulPreviousMask;
ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
traceISR_ENTER();
{ {
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
traceISR_EXIT_TO_SCHEDULER();
/* Pend a context switch. */ /* Pend a context switch. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
} }
else
{
traceISR_EXIT();
}
} }
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );
} }
@ -2019,3 +2025,85 @@ BaseType_t xPortIsInsideInterrupt( void )
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
BaseType_t xAccessGranted = pdFALSE;
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
{
xAccessGranted = pdTRUE;
}
else
{
if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 )
{
xAccessGranted = pdTRUE;
}
}
return xAccessGranted;
}
#else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
( void ) lInternalIndexOfKernelObject;
/* If Access Control List feature is not used, all the tasks have
* access to all the kernel objects. */
return pdTRUE;
}
#endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
/*-----------------------------------------------------------*/

View file

@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
/* Size of an Access Control List (ACL) entry in bits. */
#define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS
{ {
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) #if ( configUSE_MPU_WRAPPERS_V1 == 0 )
xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo;
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ];
#endif
#endif #endif
} xMPU_SETTINGS; } xMPU_SETTINGS;
@ -331,9 +337,19 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portYIELD() vPortYield() #define portYIELD() vPortYield()
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) \ #define portEND_SWITCHING_ISR( xSwitchRequired ) \
do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } \ do \
while( 0 ) { \
if( xSwitchRequired ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -977,13 +977,19 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */
uint32_t ulPreviousMask; uint32_t ulPreviousMask;
ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
traceISR_ENTER();
{ {
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
traceISR_EXIT_TO_SCHEDULER();
/* Pend a context switch. */ /* Pend a context switch. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
} }
else
{
traceISR_EXIT();
}
} }
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );
} }
@ -2019,3 +2025,85 @@ BaseType_t xPortIsInsideInterrupt( void )
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
BaseType_t xAccessGranted = pdFALSE;
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
{
xAccessGranted = pdTRUE;
}
else
{
if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 )
{
xAccessGranted = pdTRUE;
}
}
return xAccessGranted;
}
#else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
( void ) lInternalIndexOfKernelObject;
/* If Access Control List feature is not used, all the tasks have
* access to all the kernel objects. */
return pdTRUE;
}
#endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
/*-----------------------------------------------------------*/

View file

@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
/* Size of an Access Control List (ACL) entry in bits. */
#define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS
{ {
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) #if ( configUSE_MPU_WRAPPERS_V1 == 0 )
xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo;
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ];
#endif
#endif #endif
} xMPU_SETTINGS; } xMPU_SETTINGS;
@ -331,9 +337,19 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portYIELD() vPortYield() #define portYIELD() vPortYield()
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) \ #define portEND_SWITCHING_ISR( xSwitchRequired ) \
do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } \ do \
while( 0 ) { \
if( xSwitchRequired ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -387,14 +387,21 @@ void xPortSysTickHandler( void )
* save and then restore the interrupt mask value as its value is already * save and then restore the interrupt mask value as its value is already
* known. */ * known. */
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
traceISR_ENTER();
{ {
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
traceISR_EXIT_TO_SCHEDULER();
/* A context switch is required. Context switching is performed in /* A context switch is required. Context switching is performed in
* the PendSV interrupt. Pend the PendSV interrupt. */ * the PendSV interrupt. Pend the PendSV interrupt. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
} }
else
{
traceISR_EXIT();
}
} }
portENABLE_INTERRUPTS(); portENABLE_INTERRUPTS();
} }

View file

@ -99,8 +99,20 @@ typedef unsigned long UBaseType_t;
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) portYIELD( ); } while( 0 ) #define portEND_SWITCHING_ISR( xSwitchRequired ) \
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) do \
{ \
if( xSwitchRequired != pdFALSE ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portYIELD(); \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -977,13 +977,19 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */
uint32_t ulPreviousMask; uint32_t ulPreviousMask;
ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
traceISR_ENTER();
{ {
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
traceISR_EXIT_TO_SCHEDULER();
/* Pend a context switch. */ /* Pend a context switch. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
} }
else
{
traceISR_EXIT();
}
} }
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );
} }
@ -2019,3 +2025,85 @@ BaseType_t xPortIsInsideInterrupt( void )
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
BaseType_t xAccessGranted = pdFALSE;
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
{
xAccessGranted = pdTRUE;
}
else
{
if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 )
{
xAccessGranted = pdTRUE;
}
}
return xAccessGranted;
}
#else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
( void ) lInternalIndexOfKernelObject;
/* If Access Control List feature is not used, all the tasks have
* access to all the kernel objects. */
return pdTRUE;
}
#endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
/*-----------------------------------------------------------*/

View file

@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
/* Size of an Access Control List (ACL) entry in bits. */
#define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS
{ {
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) #if ( configUSE_MPU_WRAPPERS_V1 == 0 )
xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo;
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ];
#endif
#endif #endif
} xMPU_SETTINGS; } xMPU_SETTINGS;
@ -331,9 +337,19 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portYIELD() vPortYield() #define portYIELD() vPortYield()
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) \ #define portEND_SWITCHING_ISR( xSwitchRequired ) \
do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } \ do \
while( 0 ) { \
if( xSwitchRequired ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -977,13 +977,19 @@ void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */
uint32_t ulPreviousMask; uint32_t ulPreviousMask;
ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
traceISR_ENTER();
{ {
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
traceISR_EXIT_TO_SCHEDULER();
/* Pend a context switch. */ /* Pend a context switch. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
} }
else
{
traceISR_EXIT();
}
} }
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );
} }
@ -2019,3 +2025,85 @@ BaseType_t xPortIsInsideInterrupt( void )
#endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
xMPU_SETTINGS * xTaskMpuSettings;
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit );
}
#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
/*-----------------------------------------------------------*/
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
BaseType_t xAccessGranted = pdFALSE;
const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
{
xAccessGranted = pdTRUE;
}
else
{
if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 )
{
xAccessGranted = pdTRUE;
}
}
return xAccessGranted;
}
#else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
{
( void ) lInternalIndexOfKernelObject;
/* If Access Control List feature is not used, all the tasks have
* access to all the kernel objects. */
return pdTRUE;
}
#endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
/*-----------------------------------------------------------*/

View file

@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
/* Size of an Access Control List (ACL) entry in bits. */
#define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS
{ {
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) #if ( configUSE_MPU_WRAPPERS_V1 == 0 )
xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo;
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ];
#endif
#endif #endif
} xMPU_SETTINGS; } xMPU_SETTINGS;
@ -331,9 +337,19 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P
#define portYIELD() vPortYield() #define portYIELD() vPortYield()
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) \ #define portEND_SWITCHING_ISR( xSwitchRequired ) \
do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } \ do \
while( 0 ) { \
if( xSwitchRequired ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -97,8 +97,13 @@ __arm __interwork void vPortExitCritical( void );
\ \
if( xSwitchRequired ) \ if( xSwitchRequired ) \
{ \ { \
traceISR_EXIT_TO_SCHEDULER(); \
vTaskSwitchContext(); \ vTaskSwitchContext(); \
} \ } \
else \
{ \
traceISR_EXIT(); \
} \
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -100,8 +100,13 @@ __arm __interwork void vPortExitCritical( void );
\ \
if( xSwitchRequired ) \ if( xSwitchRequired ) \
{ \ { \
traceISR_EXIT_TO_SCHEDULER(); \
vTaskSwitchContext(); \ vTaskSwitchContext(); \
} \ } \
else \
{ \
traceISR_EXIT(); \
} \
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -100,8 +100,13 @@ __arm __interwork void vPortExitCritical( void );
\ \
if( xSwitchRequired ) \ if( xSwitchRequired ) \
{ \ { \
traceISR_EXIT_TO_SCHEDULER(); \
vTaskSwitchContext(); \ vTaskSwitchContext(); \
} \ } \
else \
{ \
traceISR_EXIT(); \
} \
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -93,9 +93,21 @@ typedef portUBASE_TYPE TickType_t;
/* Scheduler utilities. */ /* Scheduler utilities. */
extern void vTaskSwitchContext( void ); extern void vTaskSwitchContext( void );
#define portYIELD() __asm volatile ( "ecall" ); #define portYIELD() __asm volatile ( "ecall" );
#define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) vTaskSwitchContext( ); } while( 0 ) #define portEND_SWITCHING_ISR( xSwitchRequired ) \
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) do \
{ \
if( xSwitchRequired != pdFALSE ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
vTaskSwitchContext(); \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Critical section management. */ /* Critical section management. */

View file

@ -101,8 +101,13 @@ __arm __interwork void vPortExitCritical( void );
\ \
if( xSwitchRequired ) \ if( xSwitchRequired ) \
{ \ { \
traceISR_EXIT_TO_SCHEDULER(); \
vTaskSwitchContext(); \ vTaskSwitchContext(); \
} \ } \
else \
{ \
traceISR_EXIT(); \
} \
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -98,8 +98,13 @@ __arm __interwork void vPortExitCritical( void );
\ \
if( xSwitchRequired ) \ if( xSwitchRequired ) \
{ \ { \
traceISR_EXIT_TO_SCHEDULER(); \
vTaskSwitchContext(); \ vTaskSwitchContext(); \
} \ } \
else \
{ \
traceISR_EXIT(); \
} \
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -100,8 +100,13 @@ __arm __interwork void vPortExitCritical( void );
\ \
if( xSwitchRequired ) \ if( xSwitchRequired ) \
{ \ { \
traceISR_EXIT_TO_SCHEDULER(); \
vTaskSwitchContext(); \ vTaskSwitchContext(); \
} \ } \
else \
{ \
traceISR_EXIT(); \
} \
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -240,7 +240,19 @@ extern volatile UBaseType_t uxInterruptNesting;
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) { portYIELD(); } } while( 0 ) #define portEND_SWITCHING_ISR( xSwitchRequired ) \
do \
{ \
if( xSwitchRequired != pdFALSE ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portYIELD(); \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
/* Required by the kernel aware debugger. */ /* Required by the kernel aware debugger. */
#ifdef __DEBUG #ifdef __DEBUG

View file

@ -191,7 +191,19 @@ extern volatile UBaseType_t uxInterruptNesting;
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) { portYIELD(); } } while( 0 ) #define portEND_SWITCHING_ISR( xSwitchRequired ) \
do \
{ \
if( xSwitchRequired != pdFALSE ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portYIELD(); \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
/* Required by the kernel aware debugger. */ /* Required by the kernel aware debugger. */
#ifdef __DEBUG #ifdef __DEBUG

View file

@ -203,7 +203,19 @@ extern volatile UBaseType_t uxInterruptNesting;
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) { portYIELD(); } } while( 0 ) #define portEND_SWITCHING_ISR( xSwitchRequired ) \
do \
{ \
if( xSwitchRequired != pdFALSE ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portYIELD(); \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
/* Required by the kernel aware debugger. */ /* Required by the kernel aware debugger. */
#ifdef __DEBUG #ifdef __DEBUG

View file

@ -509,14 +509,21 @@ void xPortSysTickHandler( void ) iv IVT_INT_SysTick ics ICS_AUTO
* known - therefore the slightly faster portDISABLE_INTERRUPTS() function is * known - therefore the slightly faster portDISABLE_INTERRUPTS() function is
* used in place of portSET_INTERRUPT_MASK_FROM_ISR(). */ * used in place of portSET_INTERRUPT_MASK_FROM_ISR(). */
portDISABLE_INTERRUPTS(); portDISABLE_INTERRUPTS();
traceISR_ENTER();
{ {
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
traceISR_EXIT_TO_SCHEDULER();
/* A context switch is required. Context switching is performed in /* A context switch is required. Context switching is performed in
* the PendSV interrupt. Pend the PendSV interrupt. */ * the PendSV interrupt. Pend the PendSV interrupt. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
} }
else
{
traceISR_EXIT();
}
} }
portENABLE_INTERRUPTS(); portENABLE_INTERRUPTS();
} }

View file

@ -99,8 +99,20 @@ typedef unsigned long UBaseType_t;
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired != pdFALSE ) portYIELD( ); } while( 0 ) #define portEND_SWITCHING_ISR( xSwitchRequired ) \
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) do \
{ \
if( xSwitchRequired != pdFALSE ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portYIELD(); \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Critical section management. */ /* Critical section management. */

View file

@ -352,13 +352,19 @@ void xPortSysTickHandler( void )
uint32_t ulPreviousMask; uint32_t ulPreviousMask;
ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR(); ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
traceISR_ENTER();
{ {
/* Increment the RTOS tick. */ /* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE ) if( xTaskIncrementTick() != pdFALSE )
{ {
traceISR_EXIT_TO_SCHEDULER();
/* Pend a context switch. */ /* Pend a context switch. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
} }
else
{
traceISR_EXIT();
}
} }
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask ); portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );
} }

View file

@ -86,9 +86,19 @@ extern void vPortYield( void );
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
#define portYIELD() vPortYield() #define portYIELD() vPortYield()
#define portEND_SWITCHING_ISR( xSwitchRequired ) \ #define portEND_SWITCHING_ISR( xSwitchRequired ) \
do { if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } \ do \
while( 0 ) { \
if( xSwitchRequired ) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
} \
else \
{ \
traceISR_EXIT(); \
} \
} while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

Some files were not shown because too many files have changed in this diff Show more