From 4a74745eb222791a77a2e81dd56fa7d003295c5f Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Wed, 27 Dec 2023 18:50:31 -0500 Subject: [PATCH 01/51] First draft of a CRx MPU Port for FreeRTOS --- .../GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S | 1332 +++++++++++++++++ .../GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.h | 516 +++++++ portable/GCC/ARM_CRx_MPU/port.c | 760 ++++++++++ portable/GCC/ARM_CRx_MPU/portASM.S | 660 ++++++++ portable/GCC/ARM_CRx_MPU/portmacro.h | 661 ++++++++ portable/GCC/ARM_CRx_MPU/portmacro_asm.h | 539 +++++++ 6 files changed, 4468 insertions(+) create mode 100644 portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S create mode 100644 portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.h create mode 100644 portable/GCC/ARM_CRx_MPU/port.c create mode 100644 portable/GCC/ARM_CRx_MPU/portASM.S create mode 100644 portable/GCC/ARM_CRx_MPU/portmacro.h create mode 100644 portable/GCC/ARM_CRx_MPU/portmacro_asm.h diff --git a/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S b/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S new file mode 100644 index 0000000000..cbbeda00ac --- /dev/null +++ b/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S @@ -0,0 +1,1332 @@ +/* + * FreeRTOS V202112.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/*---------------------------------------------------------------------------*/ + + .arm + .syntax unified + .section freertos_system_calls +#define FREERTOS_ASSEMBLY + #include "FreeRTOSConfig.h" + #include "portmacro_asm.h" + #include "mpu_syscall_numbers.h" +#undef FREERTOS_ASSEMBLY + +/* ------------------ Start of Port Specific System Calls ------------------ */ + +/** + * Function: void vPortYield + * Inputs: VOID +*/ +.align 4 +.global vPortYield +.type vPortYield, %function +vPortYield: + /* Make the SVC to swap tasks */ + SVC #portSVC_YIELD + /* After yielding to another task, resume executing the calling task */ + BX LR + + +/*-------------------------------------------------------------------------------*/ +/* vPortSystemCallExit */ +.align 4 +.global vPortSystemCallExit +.type vPortSystemCallExit, %function +vPortSystemCallExit: + /* Make the SVC to exit a system call */ + SVC #portSVC_SYSTEM_CALL_EXIT + /* After performing the requested FreeRTOS API, return to the calling task */ + BX LR + +/*-------------------------------------------------------------------------------*/ +/** + * Function: BaseType_t xPortIsPrivileged + * Inputs: VOID +*/ +.align 4 +.weak xPortIsPrivileged +.type xPortIsPrivileged, %function +xPortIsPrivileged: + /* Load value of SPSR into R0 */ + MRS R0, CPSR + /* Get the relevant mode bits */ + AND R0, R0, #0x1F + /* Check if we're in user mode */ + CMP R0, #USER_MODE + /* If we are in user mode set R0 to 0 for the return */ + MOVEQ R0, #0x0 + /* Otherwise set R0 to 1 for the return */ + MOVNE R0, #0x01 + BLX LR + +/*-------------------------------------------------------------------------------*/ +/** + * Function: UBaseType_t ulPortCountLeadingZeros + * Inputs: UBaseType_t ulBitmap +*/ +.align 4 +.weak ulPortCountLeadingZeros +.type ulPortCountLeadingZeros, %function +ulPortCountLeadingZeros: + /* Count the leading zeros and return in R0 */ + CLZ R0, R0 + BX LR + +/* ------------------- End of Port Specific System Calls ------------------- */ + +.macro processorInUserMode + /* Push R0 before using it */ + PUSH {R0} + /* Load value of SPSR into R0 */ + MRS R0, CPSR + /* Get the relevant mode bits */ + AND R0, R0, #0x1F + /* Determine if the CPU is in user mode */ + CMP R0, #USER_MODE + /* Restore the pushed register */ + POP {R0} +.endm + +/*---------------------------------------------------------------------------*/ + +.extern MPU_xTaskGetTickCountImpl +/** + * Function: TickType_t MPU_xTaskGetTickCount + * Inputs: void - No Inputs +*/ +.align 4 +.global MPU_xTaskGetTickCount +.type MPU_xTaskGetTickCount, function +MPU_xTaskGetTickCount: + processorInUserMode + SVCEQ #SYSTEM_CALL_xTaskGetTickCount + B MPU_xTaskGetTickCountImpl + +/*---------------------------------------------------------------------------*/ + +.extern MPU_uxTaskGetNumberOfTasksImpl +/** + * Function: UBaseType_t MPU_uxTaskGetNumberOfTasks + * Inputs: void - No Inputs +*/ +.align 4 +.global MPU_uxTaskGetNumberOfTasks +.type MPU_uxTaskGetNumberOfTasks, function +MPU_uxTaskGetNumberOfTasks: + processorInUserMode + SVCEQ #SYSTEM_CALL_uxTaskGetNumberOfTasks + B MPU_uxTaskGetNumberOfTasksImpl + +/*---------------------------------------------------------------------------*/ + +.extern MPU_vTaskSetTimeOutStateImpl +/** + * Function: void MPU_vTaskSetTimeOutState + * Inputs: TimeOut_t * const pxTimeOut +*/ +.align 4 +.global MPU_vTaskSetTimeOutState +.type MPU_vTaskSetTimeOutState, function +MPU_vTaskSetTimeOutState: + processorInUserMode + SVCEQ #SYSTEM_CALL_vTaskSetTimeOutState + B MPU_vTaskSetTimeOutStateImpl + +/*---------------------------------------------------------------------------*/ + +.extern MPU_xTaskCheckForTimeOutImpl +/** + * Function: BaseType_t MPU_xTaskCheckForTimeOut + * Inputs: TimeOut_t * const pxTimeOut + * Inputs: TickType_t * const pxTicksToWait +*/ +.align 4 +.global MPU_xTaskCheckForTimeOut +.type MPU_xTaskCheckForTimeOut, function +MPU_xTaskCheckForTimeOut: + processorInUserMode + SVCEQ #SYSTEM_CALL_xTaskCheckForTimeOut + B MPU_xTaskCheckForTimeOutImpl + +/*---------------------------------------------------------------------------*/ + +.extern MPU_xQueueGenericSendImpl +/** + * Function: BaseType_t MPU_xQueueGenericSend + * Inputs: QueueHandle_t xQueue + * Inputs: const void * const pvItemToQueue + * Inputs: TickType_t xTicksToWait + * Inputs: constBaseType_t xCopyPosition +*/ +.align 4 +.global MPU_xQueueGenericSend +.type MPU_xQueueGenericSend, function +MPU_xQueueGenericSend: + processorInUserMode + SVCEQ #SYSTEM_CALL_xQueueGenericSend + B MPU_xQueueGenericSendImpl + +/*---------------------------------------------------------------------------*/ + +.extern MPU_uxQueueMessagesWaitingImpl +/** + * Function: UBaseType_t MPU_uxQueueMessagesWaiting + * Inputs: const QueueHandle_t xQueue +*/ +.align 4 +.global MPU_uxQueueMessagesWaiting +.type MPU_uxQueueMessagesWaiting, function +MPU_uxQueueMessagesWaiting: + processorInUserMode + SVCEQ #SYSTEM_CALL_uxQueueMessagesWaiting + B MPU_uxQueueMessagesWaitingImpl + +/*---------------------------------------------------------------------------*/ + +.extern MPU_uxQueueSpacesAvailableImpl +/** + * Function: UBaseType_t MPU_uxQueueSpacesAvailable + * Inputs: const QueueHandle_t xQueue +*/ +.align 4 +.global MPU_uxQueueSpacesAvailable +.type MPU_uxQueueSpacesAvailable, function +MPU_uxQueueSpacesAvailable: + processorInUserMode + SVCEQ #SYSTEM_CALL_uxQueueSpacesAvailable + B MPU_uxQueueSpacesAvailableImpl + +/*---------------------------------------------------------------------------*/ + +.extern MPU_xQueueReceiveImpl +/** + * Function: BaseType_t MPU_xQueueReceive + * Inputs: QueueHandle_t xQueue + * Inputs: void * const pvBuffer + * Inputs: TickType_t xTicksToWait +*/ +.align 4 +.global MPU_xQueueReceive +.type MPU_xQueueReceive, function +MPU_xQueueReceive: + processorInUserMode + SVCEQ #SYSTEM_CALL_xQueueReceive + B MPU_xQueueReceiveImpl + +/*---------------------------------------------------------------------------*/ + +.extern MPU_xQueuePeekImpl +/** + * Function: BaseType_t MPU_xQueuePeek + * Inputs: QueueHandle_t xQueue + * Inputs: void * const pvBuffer + * Inputs: TickType_t xTicksToWait +*/ +.align 4 +.global MPU_xQueuePeek +.type MPU_xQueuePeek, function +MPU_xQueuePeek: + processorInUserMode + SVCEQ #SYSTEM_CALL_xQueuePeek + B MPU_xQueuePeekImpl + +/*---------------------------------------------------------------------------*/ + +.extern MPU_xQueueSemaphoreTakeImpl +/** + * Function: BaseType_t MPU_xQueueSemaphoreTake + * Inputs: QueueHandle_t xQueue + * Inputs: TickType_t xTicksToWait +*/ +.align 4 +.global MPU_xQueueSemaphoreTake +.type MPU_xQueueSemaphoreTake, function +MPU_xQueueSemaphoreTake: + processorInUserMode + SVCEQ #SYSTEM_CALL_xQueueSemaphoreTake + B MPU_xQueueSemaphoreTakeImpl + +/*---------------------------------------------------------------------------*/ + +.extern MPU_xEventGroupWaitBitsImpl +/** + * Function: EventBits_t MPU_xEventGroupWaitBitsEntry + * Inputs: const xEventGroupWaitBitsParams_t * pxParams +*/ +.align 4 +.global MPU_xEventGroupWaitBitsEntry +.type MPU_xEventGroupWaitBitsEntry, function +MPU_xEventGroupWaitBitsEntry: + processorInUserMode + SVCEQ #SYSTEM_CALL_xEventGroupWaitBits + B MPU_xEventGroupWaitBitsImpl + +/*---------------------------------------------------------------------------*/ + +.extern MPU_xEventGroupClearBitsImpl +/** + * Function: EventBits_t MPU_xEventGroupClearBits + * Inputs: EventGroupHandle_t xEventGroup + * Inputs: constEventBits_t uxBitsToClear +*/ +.align 4 +.global MPU_xEventGroupClearBits +.type MPU_xEventGroupClearBits, function +MPU_xEventGroupClearBits: + processorInUserMode + SVCEQ #SYSTEM_CALL_xEventGroupClearBits + B MPU_xEventGroupClearBitsImpl + +/*---------------------------------------------------------------------------*/ + +.extern MPU_xEventGroupSetBitsImpl +/** + * Function: EventBits_t MPU_xEventGroupSetBits + * Inputs: EventGroupHandle_t xEventGroup + * Inputs: constEventBits_t uxBitsToSet +*/ +.align 4 +.global MPU_xEventGroupSetBits +.type MPU_xEventGroupSetBits, function +MPU_xEventGroupSetBits: + processorInUserMode + SVCEQ #SYSTEM_CALL_xEventGroupSetBits + B MPU_xEventGroupSetBitsImpl + +/*---------------------------------------------------------------------------*/ + +.extern MPU_xEventGroupSyncImpl +/** + * Function: EventBits_t MPU_xEventGroupSync + * Inputs: EventGroupHandle_t xEventGroup + * Inputs: constEventBits_t uxBitsToSet + * Inputs: constEventBits_t uxBitsToWaitFor + * Inputs: TickType_t xTicksToWait +*/ +.align 4 +.global MPU_xEventGroupSync +.type MPU_xEventGroupSync, function +MPU_xEventGroupSync: + processorInUserMode + SVCEQ #SYSTEM_CALL_xEventGroupSync + B MPU_xEventGroupSyncImpl + +/*---------------------------------------------------------------------------*/ + +.extern MPU_xStreamBufferSendImpl +/** + * Function: size_t MPU_xStreamBufferSend + * Inputs: StreamBufferHandle_t xStreamBuffer + * Inputs: const void * pvTxData + * Inputs: size_t xDataLengthBytes + * Inputs: TickType_t xTicksToWait +*/ +.align 4 +.global MPU_xStreamBufferSend +.type MPU_xStreamBufferSend, function +MPU_xStreamBufferSend: + processorInUserMode + SVCEQ #SYSTEM_CALL_xStreamBufferSend + B MPU_xStreamBufferSendImpl + +/*---------------------------------------------------------------------------*/ + +.extern MPU_xStreamBufferReceiveImpl +/** + * Function: size_t MPU_xStreamBufferReceive + * Inputs: StreamBufferHandle_t xStreamBuffer + * Inputs: void * pvRxData + * Inputs: size_t xBufferLengthBytes + * Inputs: TickType_t xTicksToWait +*/ +.align 4 +.global MPU_xStreamBufferReceive +.type MPU_xStreamBufferReceive, function +MPU_xStreamBufferReceive: + processorInUserMode + SVCEQ #SYSTEM_CALL_xStreamBufferReceive + B MPU_xStreamBufferReceiveImpl + +/*---------------------------------------------------------------------------*/ + +.extern MPU_xStreamBufferIsFullImpl +/** + * Function: BaseType_t MPU_xStreamBufferIsFull + * Inputs: StreamBufferHandle_t xStreamBuffer +*/ +.align 4 +.global MPU_xStreamBufferIsFull +.type MPU_xStreamBufferIsFull, function +MPU_xStreamBufferIsFull: + processorInUserMode + SVCEQ #SYSTEM_CALL_xStreamBufferIsFull + B MPU_xStreamBufferIsFullImpl + +/*---------------------------------------------------------------------------*/ + +.extern MPU_xStreamBufferIsEmptyImpl +/** + * Function: BaseType_t MPU_xStreamBufferIsEmpty + * Inputs: StreamBufferHandle_t xStreamBuffer +*/ +.align 4 +.global MPU_xStreamBufferIsEmpty +.type MPU_xStreamBufferIsEmpty, function +MPU_xStreamBufferIsEmpty: + processorInUserMode + SVCEQ #SYSTEM_CALL_xStreamBufferIsEmpty + B MPU_xStreamBufferIsEmptyImpl + +/*---------------------------------------------------------------------------*/ + +.extern MPU_xStreamBufferSpacesAvailableImpl +/** + * Function: size_t MPU_xStreamBufferSpacesAvailable + * Inputs: StreamBufferHandle_t xStreamBuffer +*/ +.align 4 +.global MPU_xStreamBufferSpacesAvailable +.type MPU_xStreamBufferSpacesAvailable, function +MPU_xStreamBufferSpacesAvailable: + processorInUserMode + SVCEQ #SYSTEM_CALL_xStreamBufferSpacesAvailable + B MPU_xStreamBufferSpacesAvailableImpl + +/*---------------------------------------------------------------------------*/ + +.extern MPU_xStreamBufferBytesAvailableImpl +/** + * Function: size_t MPU_xStreamBufferBytesAvailable + * Inputs: StreamBufferHandle_t xStreamBuffer +*/ +.align 4 +.global MPU_xStreamBufferBytesAvailable +.type MPU_xStreamBufferBytesAvailable, function +MPU_xStreamBufferBytesAvailable: + processorInUserMode + SVCEQ #SYSTEM_CALL_xStreamBufferBytesAvailable + B MPU_xStreamBufferBytesAvailableImpl + +/*---------------------------------------------------------------------------*/ + +.extern MPU_xStreamBufferSetTriggerLevelImpl +/** + * Function: BaseType_t MPU_xStreamBufferSetTriggerLevel + * Inputs: StreamBufferHandle_t xStreamBuffer + * Inputs: size_t xTriggerLevel +*/ +.align 4 +.global MPU_xStreamBufferSetTriggerLevel +.type MPU_xStreamBufferSetTriggerLevel, function +MPU_xStreamBufferSetTriggerLevel: + processorInUserMode + SVCEQ #SYSTEM_CALL_xStreamBufferSetTriggerLevel + B MPU_xStreamBufferSetTriggerLevelImpl + +/*---------------------------------------------------------------------------*/ + +.extern MPU_xStreamBufferNextMessageLengthBytesImpl +/** + * Function: size_t MPU_xStreamBufferNextMessageLengthBytes + * Inputs: StreamBufferHandle_t xStreamBuffer +*/ +.align 4 +.global MPU_xStreamBufferNextMessageLengthBytes +.type MPU_xStreamBufferNextMessageLengthBytes, function +MPU_xStreamBufferNextMessageLengthBytes: + processorInUserMode + SVCEQ #SYSTEM_CALL_xStreamBufferNextMessageLengthBytes + B MPU_xStreamBufferNextMessageLengthBytesImpl + +/*---------------------------------------------------------------------------*/ + +#if INCLUDE_xTaskDelayUntil == 1 + .extern MPU_xTaskDelayUntilImpl + /** + * Function: TaskHandle_t MPU_xTaskDelayUntil + * Inputs: TickType_t * const pxPreviousWakeTime + * Inputs: constTickType_t xTimeIncrement + */ + .align 4 + .global MPU_xTaskDelayUntil + .type MPU_xTaskDelayUntil, function + MPU_xTaskDelayUntil: + processorInUserMode + SVCEQ #SYSTEM_CALL_xTaskDelayUntil + B MPU_xTaskDelayUntilImpl + + /*-----------------------------------------------------------------------*/ + +#endif /* if ( INCLUDE_xTaskDelayUntil == 1 ) */ + +#if INCLUDE_xTaskAbortDelay == 1 + +/*---------------------------------------------------------------------------*/ + + .extern MPU_xTaskAbortDelayImpl + /** + * Function: TaskHandle_t MPU_xTaskAbortDelay + * Inputs: TaskHandle_t xTask + */ + .align 4 + .global MPU_xTaskAbortDelay + .type MPU_xTaskAbortDelay, function + MPU_xTaskAbortDelay: + processorInUserMode + SVCEQ #SYSTEM_CALL_xTaskAbortDelay + B MPU_xTaskAbortDelayImpl + + /*-----------------------------------------------------------------------*/ + +#endif /* if ( INCLUDE_xTaskAbortDelay == 1 ) */ + +#if INCLUDE_vTaskDelay == 1 + + /*-----------------------------------------------------------------------*/ + + .extern MPU_vTaskDelayImpl + /** + * Function: void MPU_vTaskDelay + * Inputs: const TickType_t xTicksToDelay + */ + .align 4 + .global MPU_vTaskDelay + .type MPU_vTaskDelay, function + MPU_vTaskDelay: + processorInUserMode + SVCEQ #SYSTEM_CALL_vTaskDelay + B MPU_vTaskDelayImpl + + /*-----------------------------------------------------------------------*/ + +#endif /* if ( INCLUDE_vTaskDelay == 1 ) */ + +#if INCLUDE_uxTaskPriorityGet == 1 + + /*-----------------------------------------------------------------------*/ + + .extern MPU_uxTaskPriorityGetImpl + /** + * Function: UBaseType_t MPU_uxTaskPriorityGet + * Inputs: const TaskHandle_t xTask + */ + .align 4 + .global MPU_uxTaskPriorityGet + .type MPU_uxTaskPriorityGet, function + MPU_uxTaskPriorityGet: + processorInUserMode + SVCEQ #SYSTEM_CALL_uxTaskPriorityGet + B MPU_uxTaskPriorityGetImpl + + /*-----------------------------------------------------------------------*/ + +#endif /* if ( INCLUDE_uxTaskPriorityGet == 1 ) */ + +#if INCLUDE_eTaskGetState == 1 + + /*-----------------------------------------------------------------------*/ + + .extern MPU_eTaskGetStateImpl + /** + * Function: eTaskState MPU_eTaskGetState + * Inputs: TaskHandle_t xTask + */ + .align 4 + .global MPU_eTaskGetState + .type MPU_eTaskGetState, function + MPU_eTaskGetState: + processorInUserMode + SVCEQ #SYSTEM_CALL_eTaskGetState + B MPU_eTaskGetStateImpl + + /*-----------------------------------------------------------------------*/ + +#endif /* if ( INCLUDE_eTaskGetState == 1 ) */ + +#if configUSE_TRACE_FACILITY == 1 + + /*-----------------------------------------------------------------------*/ + + .extern MPU_vTaskGetInfoImpl + /** + * Function: void MPU_vTaskGetInfo + * Inputs: TaskHandle_t xTask + * Inputs: TaskStatus_t* pxTaskStatus + * Inputs: TaskHandle_t xGetFreeStackSpace + * Inputs: eTaskState eState + */ + .align 4 + .global MPU_vTaskGetInfo + .type MPU_vTaskGetInfo, function + MPU_vTaskGetInfo: + processorInUserMode + SVCEQ #SYSTEM_CALL_vTaskGetInfo + B MPU_vTaskGetInfoImpl + + /*-----------------------------------------------------------------------*/ + + .extern MPU_uxTaskGetSystemStateImpl + /** + * Function: UBaseType_t MPU_uxTaskGetSystemState + * Inputs: TaskStatus_t * const pxTaskStatusArray + * Inputs: constUBaseType_t uxArraySize + * Inputs: configRUN_TIME_COUNTER_TYPE* const pulTotalRunTime + */ + .align 4 + .global MPU_uxTaskGetSystemState + .type MPU_uxTaskGetSystemState, function + MPU_uxTaskGetSystemState: + processorInUserMode + SVCEQ #SYSTEM_CALL_uxTaskGetSystemState + B MPU_uxTaskGetSystemStateImpl + + /*-----------------------------------------------------------------------*/ + + .extern MPU_uxEventGroupGetNumberImpl + /** + * Function: UBaseType_t MPU_uxEventGroupGetNumber + * Inputs: void * xEventGroup + */ + .align 4 + .global MPU_uxEventGroupGetNumber + .type MPU_uxEventGroupGetNumber, function + MPU_uxEventGroupGetNumber: + processorInUserMode + SVCEQ #SYSTEM_CALL_uxEventGroupGetNumber + B MPU_uxEventGroupGetNumberImpl + + /*-----------------------------------------------------------------------*/ + + .extern MPU_vEventGroupSetNumberImpl + /** + * Function: void MPU_vEventGroupSetNumber + * Inputs: void * xEventGroup + * Inputs: UBaseType_t uxEventGroupNumber + */ + .align 4 + .global MPU_vEventGroupSetNumber + .type MPU_vEventGroupSetNumber, function + MPU_vEventGroupSetNumber: + processorInUserMode + SVCEQ #SYSTEM_CALL_vEventGroupSetNumber + B MPU_vEventGroupSetNumberImpl + + /*-----------------------------------------------------------------------*/ +#endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ + +#if INCLUDE_xTaskGetIdleTaskHandle == 1 + + /*-----------------------------------------------------------------------*/ + .extern MPU_xTaskGetIdleTaskHandleImpl + /** + * Function: TaskHandle_t MPU_xTaskGetIdleTaskHandle + * Inputs: void - No Inputs + */ + .align 4 + .global MPU_xTaskGetIdleTaskHandle + .type MPU_xTaskGetIdleTaskHandle, function + MPU_xTaskGetIdleTaskHandle: + processorInUserMode + SVCEQ #SYSTEM_CALL_xTaskGetIdleTaskHandle + B MPU_xTaskGetIdleTaskHandleImpl + + /*-----------------------------------------------------------------------*/ + +#endif /* if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */ + +#if INCLUDE_vTaskSuspend == 1 + + /*-----------------------------------------------------------------------*/ + + .extern MPU_vTaskSuspendImpl + /** + * Function: void MPU_vTaskSuspend + * Inputs: TaskHandle_t xTaskToSuspend + */ + .align 4 + .global MPU_vTaskSuspend + .type MPU_vTaskSuspend, function + MPU_vTaskSuspend: + processorInUserMode + SVCEQ #SYSTEM_CALL_vTaskSuspend + B MPU_vTaskSuspendImpl + + /*-----------------------------------------------------------------------*/ + + .extern MPU_vTaskResumeImpl + /** + * Function: void MPU_vTaskResume + * Inputs: TaskHandle_t xTaskToResume + */ + .align 4 + .global MPU_vTaskResume + .type MPU_vTaskResume, function + MPU_vTaskResume: + processorInUserMode + SVCEQ #SYSTEM_CALL_vTaskResume + B MPU_vTaskResumeImpl + + /*-----------------------------------------------------------------------*/ + +#endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ + +#if configGENERATE_RUN_TIME_STATS == 1 + + /*-----------------------------------------------------------------------*/ + + .extern MPU_ulTaskGetRunTimeCounterImpl + /** + * Function: configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter + * Inputs: const TaskHandle_t xTask + */ + .align 4 + .global MPU_ulTaskGetRunTimeCounter + .type MPU_ulTaskGetRunTimeCounter, function + MPU_ulTaskGetRunTimeCounter: + processorInUserMode + SVCEQ #SYSTEM_CALL_ulTaskGetRunTimeCounter + B MPU_ulTaskGetRunTimeCounterImpl + + /*-----------------------------------------------------------------------*/ + + .extern MPU_ulTaskGetRunTimePercentImpl + /** + * Function: configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent + * Inputs: const TaskHandle_t xTask + */ + .align 4 + .global MPU_ulTaskGetRunTimePercent + .type MPU_ulTaskGetRunTimePercent, function + MPU_ulTaskGetRunTimePercent: + processorInUserMode + SVCEQ #SYSTEM_CALL_ulTaskGetRunTimePercent + B MPU_ulTaskGetRunTimePercentImpl + + /*-----------------------------------------------------------------------*/ + + #if INCLUDE_xTaskGetIdleTaskHandle == 1 + + /*-------------------------------------------------------------------*/ + + .extern MPU_ulTaskGetIdleRunTimePercentImpl + /** + * Function: configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent + * Inputs: void + */ + .align 4 + .global MPU_ulTaskGetIdleRunTimePercent + .type MPU_ulTaskGetIdleRunTimePercent, function + MPU_ulTaskGetIdleRunTimePercent: + processorInUserMode + SVCEQ #SYSTEM_CALL_ulTaskGetIdleRunTimePercent + B MPU_ulTaskGetIdleRunTimePercentImpl + + /*-------------------------------------------------------------------*/ + + .extern MPU_ulTaskGetIdleRunTimeCounterImpl + /** + * Function: configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter + * Inputs: void - No Inputs + */ + .align 4 + .global MPU_ulTaskGetIdleRunTimeCounter + .type MPU_ulTaskGetIdleRunTimeCounter, function + MPU_ulTaskGetIdleRunTimeCounter: + processorInUserMode + SVCEQ #SYSTEM_CALL_ulTaskGetIdleRunTimeCounter + B MPU_ulTaskGetIdleRunTimeCounterImpl + + /*-------------------------------------------------------------------*/ + + #endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ +#endif /* configGENERATE_RUN_TIME_STATS */ + +#if configUSE_APPLICATION_TASK_TAG == 1 + + /*-----------------------------------------------------------------------*/ + + .extern MPU_vTaskSetApplicationTaskTagImpl + /** + * Function: void MPU_vTaskSetApplicationTaskTag + * Inputs: TaskHandle_t xTask + * Inputs: TaskHookFunction_tpxHookFunction + */ + .align 4 + .global MPU_vTaskSetApplicationTaskTag + .type MPU_vTaskSetApplicationTaskTag, function + MPU_vTaskSetApplicationTaskTag: + processorInUserMode + SVCEQ #SYSTEM_CALL_vTaskSetApplicationTaskTag + B MPU_vTaskSetApplicationTaskTagImpl + + /*-----------------------------------------------------------------------*/ + + .extern MPU_xTaskGetApplicationTaskTagImpl + /** + * Function: TaskHookFunction_t MPU_xTaskGetApplicationTaskTag + * Inputs: TaskHandle_t xTask + */ + .align 4 + .global MPU_xTaskGetApplicationTaskTag + .type MPU_xTaskGetApplicationTaskTag, function + MPU_xTaskGetApplicationTaskTag: + processorInUserMode + SVCEQ #SYSTEM_CALL_xTaskGetApplicationTaskTag + B MPU_xTaskGetApplicationTaskTagImpl + + /*-----------------------------------------------------------------------*/ +#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ + +#if configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 + + /*-----------------------------------------------------------------------*/ + + .extern MPU_vTaskSetThreadLocalStoragePointerImpl + /** + * Function: void MPU_vTaskSetThreadLocalStoragePointer + * Inputs: TaskHandle_t xTaskToSet + * Inputs: TaskHandle_t xIndex + * Inputs: void * pvValue + */ + .align 4 + .global MPU_vTaskSetThreadLocalStoragePointer + .type MPU_vTaskSetThreadLocalStoragePointer, function + MPU_vTaskSetThreadLocalStoragePointer: + processorInUserMode + SVCEQ #SYSTEM_CALL_vTaskSetThreadLocalStoragePointer + B MPU_vTaskSetThreadLocalStoragePointerImpl + + /*-----------------------------------------------------------------------*/ + + .extern MPU_pvTaskGetThreadLocalStoragePointerImpl + /** + * Function: void * MPU_pvTaskGetThreadLocalStoragePointer + * Inputs: TaskHandle_t xTaskToQuery + * Inputs: TaskHandle_t xIndex + */ + .align 4 + .global MPU_pvTaskGetThreadLocalStoragePointer + .type MPU_pvTaskGetThreadLocalStoragePointer, function + MPU_pvTaskGetThreadLocalStoragePointer: + processorInUserMode + SVCEQ #SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer + B MPU_pvTaskGetThreadLocalStoragePointerImpl + + /*-----------------------------------------------------------------------*/ + +#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ + +#if INCLUDE_uxTaskGetStackHighWaterMark == 1 + + /*-----------------------------------------------------------------------*/ + + .extern MPU_uxTaskGetStackHighWaterMarkImpl + /** + * Function: UBaseType_t MPU_uxTaskGetStackHighWaterMark + * Inputs: TaskHandle_t xTask + */ + .align 4 + .global MPU_uxTaskGetStackHighWaterMark + .type MPU_uxTaskGetStackHighWaterMark, function + MPU_uxTaskGetStackHighWaterMark: + processorInUserMode + SVCEQ #SYSTEM_CALL_uxTaskGetStackHighWaterMark + B MPU_uxTaskGetStackHighWaterMarkImpl + + /*-----------------------------------------------------------------------*/ + +#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) */ + + +#if INCLUDE_uxTaskGetStackHighWaterMark == 2 + + /*-----------------------------------------------------------------------*/ + + .extern MPU_uxTaskGetStackHighWaterMark2Impl + /** + * Function: configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2 + * Inputs: TaskHandle_t xTask + */ + .align 4 + .global MPU_uxTaskGetStackHighWaterMark2 + .type MPU_uxTaskGetStackHighWaterMark2, function + MPU_uxTaskGetStackHighWaterMark2: + processorInUserMode + SVCEQ #SYSTEM_CALL_uxTaskGetStackHighWaterMark2 + B MPU_uxTaskGetStackHighWaterMark2Impl + + /*-----------------------------------------------------------------------*/ + +#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) */ + + +#if INCLUDE_xTaskGetCurrentTaskHandle == 1 || configUSE_MUTEXES == 1 + + /*-----------------------------------------------------------------------*/ + + .extern MPU_xTaskGetCurrentTaskHandleImpl + /** + * Function: TaskHandle_t MPU_xTaskGetCurrentTaskHandle + * Inputs: void - No Inputs + */ + .align 4 + .global MPU_xTaskGetCurrentTaskHandle + .type MPU_xTaskGetCurrentTaskHandle, function + MPU_xTaskGetCurrentTaskHandle: + processorInUserMode + SVCEQ #SYSTEM_CALL_xTaskGetCurrentTaskHandle + B MPU_xTaskGetCurrentTaskHandleImpl + + /*-----------------------------------------------------------------------*/ + +#endif /* if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ + +#if INCLUDE_xTaskGetSchedulerState == 1 + + /*-----------------------------------------------------------------------*/ + + .extern MPU_xTaskGetSchedulerStateImpl + /** + * Function: TaskHandle_t MPU_xTaskGetSchedulerState + * Inputs: void - No Inputs + */ + .align 4 + .global MPU_xTaskGetSchedulerState + .type MPU_xTaskGetSchedulerState, function + MPU_xTaskGetSchedulerState: + processorInUserMode + SVCEQ #SYSTEM_CALL_xTaskGetSchedulerState + B MPU_xTaskGetSchedulerStateImpl + + /*-----------------------------------------------------------------------*/ + +#endif /* if ( INCLUDE_xTaskGetSchedulerState == 1 ) */ + +#if configUSE_MUTEXES == 1 && INCLUDE_xSemaphoreGetMutexHolder + + /*-----------------------------------------------------------------------*/ + + .extern MPU_xQueueGetMutexHolderImpl + /** + * Function: TaskHandle_t MPU_xQueueGetMutexHolder + * Inputs: QueueHandle_t xSemaphore + */ + .align 4 + .global MPU_xQueueGetMutexHolder + .type MPU_xQueueGetMutexHolder, function + MPU_xQueueGetMutexHolder: + processorInUserMode + SVCEQ #SYSTEM_CALL_xQueueGetMutexHolder + B MPU_xQueueGetMutexHolderImpl + + /*-----------------------------------------------------------------------*/ + +#endif /* if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) */ + +#if configUSE_RECURSIVE_MUTEXES == 1 + + /*-----------------------------------------------------------------------*/ + + .extern MPU_xQueueTakeMutexRecursiveImpl + /** + * Function: TaskHandle_t MPU_xQueueTakeMutexRecursive + * Inputs: QueueHandle_t xMutex + * Inputs: TickType_t xTicksToWait + */ + .align 4 + .global MPU_xQueueTakeMutexRecursive + .type MPU_xQueueTakeMutexRecursive, function + MPU_xQueueTakeMutexRecursive: + processorInUserMode + SVCEQ #SYSTEM_CALL_xQueueTakeMutexRecursive + B MPU_xQueueTakeMutexRecursiveImpl + + /*-----------------------------------------------------------------------*/ + + .extern MPU_xQueueGiveMutexRecursiveImpl + /** + * Function: TaskHandle_t MPU_xQueueGiveMutexRecursive + * Inputs: QueueHandle_t pxMutex + */ + .align 4 + .global MPU_xQueueGiveMutexRecursive + .type MPU_xQueueGiveMutexRecursive, function + MPU_xQueueGiveMutexRecursive: + processorInUserMode + SVCEQ #SYSTEM_CALL_xQueueGiveMutexRecursive + B MPU_xQueueGiveMutexRecursiveImpl + + /*-----------------------------------------------------------------------*/ + +#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ + +#if configUSE_QUEUE_SETS == 1 + + /*-----------------------------------------------------------------------*/ + + .extern MPU_xQueueSelectFromSetImpl + /** + * Function: QueueSetMemberHandle_t MPU_xQueueSelectFromSet + * Inputs: QueueSetHandle_t xQueueSet + * Inputs: constTickType_t xTicksToWait + */ + .align 4 + .global MPU_xQueueSelectFromSet + .type MPU_xQueueSelectFromSet, function + MPU_xQueueSelectFromSet: + processorInUserMode + SVCEQ #SYSTEM_CALL_xQueueSelectFromSet + B MPU_xQueueSelectFromSetImpl + + /*-----------------------------------------------------------------------*/ + + .extern MPU_xQueueAddToSetImpl + /** + * Function: TaskHandle_t MPU_xQueueAddToSet + * Inputs: QueueSetMemberHandle_t xQueueOrSemaphore + * Inputs: QueueSetHandle_t xQueueSet + */ + .align 4 + .global MPU_xQueueAddToSet + .type MPU_xQueueAddToSet, function + MPU_xQueueAddToSet: + processorInUserMode + SVCEQ #SYSTEM_CALL_xQueueAddToSet + B MPU_xQueueAddToSetImpl + + /*-----------------------------------------------------------------------*/ + +#endif /* if ( configUSE_QUEUE_SETS == 1 ) */ + +#if configQUEUE_REGISTRY_SIZE == 1 + + /*-----------------------------------------------------------------------*/ + + .extern MPU_vQueueAddToRegistryImpl + /** + * Function: void MPU_vQueueAddToRegistry + * Inputs: QueueHandle_t xQueue + * Inputs: constchar * pcName + */ + .align 4 + .global MPU_vQueueAddToRegistry + .type MPU_vQueueAddToRegistry, function + MPU_vQueueAddToRegistry: + processorInUserMode + SVCEQ #SYSTEM_CALL_vQueueAddToRegistry + B MPU_vQueueAddToRegistryImpl + + /*-----------------------------------------------------------------------*/ + + .extern MPU_vQueueUnregisterQueueImpl + /** + * Function: void MPU_vQueueUnregisterQueue + * Inputs: QueueHandle_t xQueue + */ + .align 4 + .global MPU_vQueueUnregisterQueue + .type MPU_vQueueUnregisterQueue, function + MPU_vQueueUnregisterQueue: + processorInUserMode + SVCEQ #SYSTEM_CALL_vQueueUnregisterQueue + B MPU_vQueueUnregisterQueueImpl + + /*-----------------------------------------------------------------------*/ + + .extern MPU_pcQueueGetNameImpl + /** + * Function: const char * MPU_pcQueueGetName + * Inputs: QueueHandle_t xQueue + */ + .align 4 + .global MPU_pcQueueGetName + .type MPU_pcQueueGetName, function + MPU_pcQueueGetName: + processorInUserMode + SVCEQ #SYSTEM_CALL_pcQueueGetName + B MPU_pcQueueGetNameImpl + + /*-----------------------------------------------------------------------*/ + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ + +#if configUSE_TIMERS == 1 + + /*-----------------------------------------------------------------------*/ + + .extern MPU_pvTimerGetTimerIDImpl + /** + * Function: void * MPU_pvTimerGetTimerID + * Inputs: const TimerHandle_t xTimer + */ + .align 4 + .global MPU_pvTimerGetTimerID + .type MPU_pvTimerGetTimerID, function + MPU_pvTimerGetTimerID: + processorInUserMode + SVCEQ #SYSTEM_CALL_pvTimerGetTimerID + B MPU_pvTimerGetTimerIDImpl + + /*-----------------------------------------------------------------------*/ + + .extern MPU_vTimerSetTimerIDImpl + /** + * Function: void MPU_vTimerSetTimerID + * Inputs: TimerHandle_t xTimer + * Inputs: void * pvNewID + */ + .align 4 + .global MPU_vTimerSetTimerID + .type MPU_vTimerSetTimerID, function + MPU_vTimerSetTimerID: + processorInUserMode + SVCEQ #SYSTEM_CALL_vTimerSetTimerID + B MPU_vTimerSetTimerIDImpl + + /*-----------------------------------------------------------------------*/ + + .extern MPU_xTimerIsTimerActiveImpl + /** + * Function: TaskHandle_t MPU_xTimerIsTimerActive + * Inputs: TimerHandle_t xTimer + */ + .align 4 + .global MPU_xTimerIsTimerActive + .type MPU_xTimerIsTimerActive, function + MPU_xTimerIsTimerActive: + processorInUserMode + SVCEQ #SYSTEM_CALL_xTimerIsTimerActive + B MPU_xTimerIsTimerActiveImpl + + /*-----------------------------------------------------------------------*/ + + .extern MPU_xTimerGetTimerDaemonTaskHandleImpl + /** + * Function: TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle + * Inputs: void - No Inputs + */ + .align 4 + .global MPU_xTimerGetTimerDaemonTaskHandle + .type MPU_xTimerGetTimerDaemonTaskHandle, function + MPU_xTimerGetTimerDaemonTaskHandle: + processorInUserMode + SVCEQ #SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle + B MPU_xTimerGetTimerDaemonTaskHandleImpl + + /*-----------------------------------------------------------------------*/ + + .extern MPU_xTimerGenericCommandFromTaskImpl + /** + * Function: TaskHandle_t MPU_xTimerGenericCommandFromTaskEntry + * Inputs: const xTimerGenericCommandParams_t * pxParams + */ + .align 4 + .global MPU_xTimerGenericCommandFromTaskEntry + .type MPU_xTimerGenericCommandFromTaskEntry, function + MPU_xTimerGenericCommandFromTaskEntry: + processorInUserMode + SVCEQ #SYSTEM_CALL_xTimerGenericCommandFromTask + B MPU_xTimerGenericCommandFromTaskImpl + + /*-----------------------------------------------------------------------*/ + + + .extern MPU_pcTimerGetNameImpl + /** + * Function: const char * MPU_pcTimerGetName + * Inputs: TimerHandle_t xTimer + */ + .align 4 + .global MPU_pcTimerGetName + .type MPU_pcTimerGetName, function + MPU_pcTimerGetName: + processorInUserMode + SVCEQ #SYSTEM_CALL_pcTimerGetName + B MPU_pcTimerGetNameImpl + + /*-----------------------------------------------------------------------*/ + + .extern MPU_vTimerSetReloadModeImpl + /** + * Function: void MPU_vTimerSetReloadMode + * Inputs: TimerHandle_t xTimer + * Inputs: constBaseType_t uxAutoReload + */ + .align 4 + .global MPU_vTimerSetReloadMode + .type MPU_vTimerSetReloadMode, function + MPU_vTimerSetReloadMode: + processorInUserMode + SVCEQ #SYSTEM_CALL_vTimerSetReloadMode + B MPU_vTimerSetReloadModeImpl + + /*-----------------------------------------------------------------------*/ + + .extern MPU_xTimerGetReloadModeImpl + /** + * Function: TaskHandle_t MPU_xTimerGetReloadMode + * Inputs: TimerHandle_t xTimer + */ + .align 4 + .global MPU_xTimerGetReloadMode + .type MPU_xTimerGetReloadMode, function + MPU_xTimerGetReloadMode: + processorInUserMode + SVCEQ #SYSTEM_CALL_xTimerGetReloadMode + B MPU_xTimerGetReloadModeImpl + + /*-----------------------------------------------------------------------*/ + + .extern MPU_uxTimerGetReloadModeImpl + /** + * Function: UBaseType_t MPU_uxTimerGetReloadMode + * Inputs: TimerHandle_t xTimer + */ + .align 4 + .global MPU_uxTimerGetReloadMode + .type MPU_uxTimerGetReloadMode, function + MPU_uxTimerGetReloadMode: + processorInUserMode + SVCEQ #SYSTEM_CALL_uxTimerGetReloadMode + B MPU_uxTimerGetReloadModeImpl + + /*-----------------------------------------------------------------------*/ + + .extern MPU_xTimerGetPeriodImpl + /** + * Function: TickType_t MPU_xTimerGetPeriod + * Inputs: TimerHandle_t xTimer + */ + .align 4 + .global MPU_xTimerGetPeriod + .type MPU_xTimerGetPeriod, function + MPU_xTimerGetPeriod: + processorInUserMode + SVCEQ #SYSTEM_CALL_xTimerGetPeriod + B MPU_xTimerGetPeriodImpl + + /*-----------------------------------------------------------------------*/ + + .extern MPU_xTimerGetExpiryTimeImpl + /** + * Function: TickType_t MPU_xTimerGetExpiryTime + * Inputs: TimerHandle_t xTimer + */ + .align 4 + .global MPU_xTimerGetExpiryTime + .type MPU_xTimerGetExpiryTime, function + MPU_xTimerGetExpiryTime: + processorInUserMode + SVCEQ #SYSTEM_CALL_xTimerGetExpiryTime + B MPU_xTimerGetExpiryTimeImpl + + /*-----------------------------------------------------------------------*/ + +#endif /* if ( configUSE_TIMERS == 1 ) */ + +#if configUSE_TASK_NOTIFICATIONS == 1 + .extern MPU_xTaskGenericNotifyImpl + /** + * Function: TaskHandle_t MPU_xTaskGenericNotifyEntry + * Inputs: const xTaskGenericNotifyParams_t * pxParams + */ + .align 4 + .global MPU_xTaskGenericNotifyEntry + .type MPU_xTaskGenericNotifyEntry, function + MPU_xTaskGenericNotifyEntry: + processorInUserMode + SVCEQ #SYSTEM_CALL_xTaskGenericNotify + B MPU_xTaskGenericNotifyImpl + + /*-----------------------------------------------------------------------*/ + + .extern MPU_xTaskGenericNotifyWaitImpl + /** + * Function: TaskHandle_t MPU_xTaskGenericNotifyWaitEntry + * Inputs: const xTaskGenericNotifyWaitParams_t * pxParams + */ + .align 4 + .global MPU_xTaskGenericNotifyWaitEntry + .type MPU_xTaskGenericNotifyWaitEntry, function + MPU_xTaskGenericNotifyWaitEntry: + processorInUserMode + SVCEQ #SYSTEM_CALL_xTaskGenericNotifyWait + B MPU_xTaskGenericNotifyWaitImpl + + /*-----------------------------------------------------------------------*/ + + .extern MPU_ulTaskGenericNotifyTakeImpl + /** + * Function: uint32_t MPU_ulTaskGenericNotifyTake + * Inputs: UBaseType_t uxIndexToWaitOn + * Inputs: TaskHandle_t xClearCountOnExit + * Inputs: TickType_t xTicksToWait + */ + .align 4 + .global MPU_ulTaskGenericNotifyTake + .type MPU_ulTaskGenericNotifyTake, function + MPU_ulTaskGenericNotifyTake: + processorInUserMode + SVCEQ #SYSTEM_CALL_ulTaskGenericNotifyTake + B MPU_ulTaskGenericNotifyTakeImpl + + /*-----------------------------------------------------------------------*/ + + .extern MPU_xTaskGenericNotifyStateClearImpl + /** + * Function: TaskHandle_t MPU_xTaskGenericNotifyStateClear + * Inputs: TaskHandle_t xTask + * Inputs: UBaseType_t uxIndexToClear + */ + .align 4 + .global MPU_xTaskGenericNotifyStateClear + .type MPU_xTaskGenericNotifyStateClear, function + MPU_xTaskGenericNotifyStateClear: + processorInUserMode + SVCEQ #SYSTEM_CALL_xTaskGenericNotifyStateClear + B MPU_xTaskGenericNotifyStateClearImpl + + /*-----------------------------------------------------------------------*/ + + .extern MPU_ulTaskGenericNotifyValueClearImpl + /** + * Function: uint32_t MPU_ulTaskGenericNotifyValueClear + * Inputs: TaskHandle_t xTask + * Inputs: UBaseType_t uxIndexToClear + * Inputs: uint32_t ulBitsToClear + */ + .align 4 + .global MPU_ulTaskGenericNotifyValueClear + .type MPU_ulTaskGenericNotifyValueClear, function + MPU_ulTaskGenericNotifyValueClear: + processorInUserMode + SVCEQ #SYSTEM_CALL_ulTaskGenericNotifyValueClear + B MPU_ulTaskGenericNotifyValueClearImpl + + /*-----------------------------------------------------------------------*/ + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ diff --git a/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.h b/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.h new file mode 100644 index 0000000000..faf6c9b86b --- /dev/null +++ b/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.h @@ -0,0 +1,516 @@ +/* + * FreeRTOS Kernel V10.6.0 + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef MPU_PROTOTYPES_H +#define MPU_PROTOTYPES_H + +#include + +/** Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from + * redefining all the API functions to use the MPU wrappers. That should only + * be done when task.h is included from an application file. */ +#ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE +#endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "timers.h" +#include "event_groups.h" +#include "stream_buffer.h" +#include "mpu_prototypes.h" +#include "mpu_syscall_numbers.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +typedef struct xTaskGenericNotifyParams +{ + TaskHandle_t xTaskToNotify; + UBaseType_t uxIndexToNotify; + uint32_t ulValue; + eNotifyAction eAction; + uint32_t * pulPreviousNotificationValue; +} xTaskGenericNotifyParams_t; + +typedef struct xTaskGenericNotifyWaitParams +{ + UBaseType_t uxIndexToWaitOn; + uint32_t ulBitsToClearOnEntry; + uint32_t ulBitsToClearOnExit; + uint32_t * pulNotificationValue; + TickType_t xTicksToWait; +} xTaskGenericNotifyWaitParams_t; + +typedef struct xTimerGenericCommandParams +{ + TimerHandle_t xTimer; + BaseType_t xCommandID; + TickType_t xOptionalValue; + BaseType_t * pxHigherPriorityTaskWoken; + TickType_t xTicksToWait; +} xTimerGenericCommandParams_t; + +typedef struct xEventGroupWaitBitsParams +{ + EventGroupHandle_t xEventGroup; + EventBits_t uxBitsToWaitFor; + BaseType_t xClearOnExit; + BaseType_t xWaitForAllBits; + TickType_t xTicksToWait; +} xEventGroupWaitBitsParams_t; + +/*-----------------------------------------------------------*/ + +extern TickType_t MPU_xTaskGetTickCount( void ) __attribute__( ( naked ) +) FREERTOS_SYSTEM_CALL; + +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) __attribute__( ( naked ) +) FREERTOS_SYSTEM_CALL; + +/*-----------------------------------------------------------*/ + +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) __attribute__( ( naked ) +) FREERTOS_SYSTEM_CALL; + +/*-----------------------------------------------------------*/ + +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) __attribute__( ( naked ) +) FREERTOS_SYSTEM_CALL; + +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xTaskCheckForTimeOut( + TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait +) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueGenericSend( + QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition +) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue +) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue +) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueReceive( + QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait +) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueuePeek( + QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait +) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSend( + StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait +) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferReceive( + StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait +) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer +) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer +) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer +) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer +) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferSetTriggerLevel( + StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel +) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer +) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupWaitBits( + EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait +) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupClearBits( + EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear +) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSetBits( + EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet +) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSync( + EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait +) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + +/*-----------------------------------------------------------*/ + +#if( INCLUDE_xTaskDelayUntil == 1 ) + +BaseType_t MPU_xTaskDelayUntil( + TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement +) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + +#endif /* if ( INCLUDE_xTaskDelayUntil == 1 ) */ +/*-----------------------------------------------------------*/ + +#if( INCLUDE_xTaskAbortDelay == 1 ) + +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) __attribute__( ( naked ) +) FREERTOS_SYSTEM_CALL; + +#endif /* if ( INCLUDE_xTaskAbortDelay == 1 ) */ +/*-----------------------------------------------------------*/ + +#if( INCLUDE_vTaskDelay == 1 ) + +void MPU_vTaskDelay( const TickType_t xTicksToDelay ) __attribute__( ( naked ) +) FREERTOS_SYSTEM_CALL; + +#endif /* if ( INCLUDE_vTaskDelay == 1 ) */ +/*-----------------------------------------------------------*/ + +#if( INCLUDE_uxTaskPriorityGet == 1 ) + +UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) __attribute__( ( naked ) +) FREERTOS_SYSTEM_CALL; + +#endif /* if ( INCLUDE_uxTaskPriorityGet == 1 ) */ +/*-----------------------------------------------------------*/ + +#if( INCLUDE_eTaskGetState == 1 ) + +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) __attribute__( ( naked ) +) FREERTOS_SYSTEM_CALL; + +#endif /* if ( INCLUDE_eTaskGetState == 1 ) */ +/*-----------------------------------------------------------*/ + +#if( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) __attribute__( ( naked ) +) FREERTOS_SYSTEM_CALL; + +#endif /* if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */ +/*-----------------------------------------------------------*/ + +#if( INCLUDE_vTaskSuspend == 1 ) + +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) __attribute__( ( naked ) +) FREERTOS_SYSTEM_CALL; + +void MPU_vTaskResume( TaskHandle_t xTaskToResume ) __attribute__( ( naked ) +) FREERTOS_SYSTEM_CALL; + +#endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ +/*-----------------------------------------------------------*/ + +#if( configGENERATE_RUN_TIME_STATS == 1 ) +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask +) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask +) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + + #if( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void +) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void +) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + #endif /* ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */ + +#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if( configUSE_APPLICATION_TASK_TAG == 1 ) + +void MPU_vTaskSetApplicationTaskTag( + TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction +) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask +) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + +#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/*-----------------------------------------------------------*/ + +#if( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + +void MPU_vTaskSetThreadLocalStoragePointer( + TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue +) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + +void * MPU_pvTaskGetThreadLocalStoragePointer( + TaskHandle_t xTaskToQuery, + BaseType_t xIndex +) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + +#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/*-----------------------------------------------------------*/ + +#if( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) + +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) __attribute__( ( naked ) +) FREERTOS_SYSTEM_CALL; + +#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) */ +/*-----------------------------------------------------------*/ + +#if( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) + +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask +) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + +#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) */ +/*-----------------------------------------------------------*/ + +#if( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) + +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) __attribute__( ( naked ) +) FREERTOS_SYSTEM_CALL; + +#endif /* if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) \ + ) */ +/*-----------------------------------------------------------*/ + +#if( INCLUDE_xTaskGetSchedulerState == 1 ) + +BaseType_t MPU_xTaskGetSchedulerState( void ) __attribute__( ( naked ) +) FREERTOS_SYSTEM_CALL; + +#endif /* if ( INCLUDE_xTaskGetSchedulerState == 1 ) */ +/*-----------------------------------------------------------*/ + +#if( configUSE_TRACE_FACILITY == 1 ) + +void MPU_vTaskGetInfo( + TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState +) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTaskGetSystemState( + TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime +) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) __attribute__( ( naked ) +) FREERTOS_SYSTEM_CALL; + +void MPU_vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + +#endif /*( configUSE_TRACE_FACILITY == 1 )*/ +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + +BaseType_t MPU_xTaskGenericNotifyEntry( const xTaskGenericNotifyParams_t * pxParams +) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotifyWaitEntry( const xTaskGenericNotifyWaitParams_t * pxParams +) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + +uint32_t MPU_ulTaskGenericNotifyTake( + UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait +) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTaskGenericNotifyStateClear( + TaskHandle_t xTask, + UBaseType_t uxIndexToClear +) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + +uint32_t MPU_ulTaskGenericNotifyValueClear( + TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear +) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + +#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if( configUSE_RECURSIVE_MUTEXES == 1 ) + +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) __attribute__( ( naked ) +) FREERTOS_SYSTEM_CALL; + + #if( INCLUDE_xSemaphoreGetMutexHolder == 1 ) + +TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) __attribute__( ( naked ) +) FREERTOS_SYSTEM_CALL; + + #endif /* ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) */ + +#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/*-----------------------------------------------------------*/ + +#if( configUSE_QUEUE_SETS == 1 ) + +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( + QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait +) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xQueueAddToSet( + QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet +) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + +#endif /* if ( configUSE_QUEUE_SETS == 1 ) */ +/*-----------------------------------------------------------*/ + +#if( configQUEUE_REGISTRY_SIZE > 0 ) + +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, const char * pcName ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) __attribute__( ( naked ) +) FREERTOS_SYSTEM_CALL; + +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) __attribute__( ( naked ) +) FREERTOS_SYSTEM_CALL; + +#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/*-----------------------------------------------------------*/ + +#if( configUSE_TIMERS == 1 ) + +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) __attribute__( ( naked ) +) FREERTOS_SYSTEM_CALL; + +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, void * pvNewID ) __attribute__( ( naked ) +) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) __attribute__( ( naked ) +) FREERTOS_SYSTEM_CALL; + +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) __attribute__( ( naked ) +) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerGenericCommandEntry( const xTimerGenericCommandParams_t * pxParams +) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) __attribute__( ( naked ) +) FREERTOS_SYSTEM_CALL; + +void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, const BaseType_t uxAutoReload ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + +BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) __attribute__( ( naked ) +) FREERTOS_SYSTEM_CALL; + +UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) __attribute__( ( naked ) +) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) __attribute__( ( naked ) +) FREERTOS_SYSTEM_CALL; + +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) __attribute__( ( naked ) +) FREERTOS_SYSTEM_CALL; + +#endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + +#endif /* MPU_PROTOTYPES_H */ diff --git a/portable/GCC/ARM_CRx_MPU/port.c b/portable/GCC/ARM_CRx_MPU/port.c new file mode 100644 index 0000000000..7427aa7c57 --- /dev/null +++ b/portable/GCC/ARM_CRx_MPU/port.c @@ -0,0 +1,760 @@ +/* + * FreeRTOS Kernel V10.6.1 + * Copyright (C) 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* Standard includes. */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining + * all the API functions to use the MPU wrappers. That should only be done when + * task.h is included from an application file. */ +#ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE +#endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ + +/* Scheduler includes. */ +#include "FreeRTOSConfig.h" +#include "FreeRTOS.h" +#include "portmacro.h" +#include "task.h" +#include "mpu_syscall_numbers.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/** @brief Variable used to keep track of critical section nesting. + * @ingroup Critical Sections + * @note + * This variable has to be stored as part of the task context and must be + * initialised to a non zero value to ensure interrupts don't inadvertently + * become unmasked before the scheduler starts. As it is stored as part of the + * task context it will be set to 0 when the first task is started. + */ +PRIVILEGED_DATA volatile uint32_t ulCriticalNesting = 0xFFFF; + +/** @brief Set to 1 to pend a context switch from an ISR. + * @ingroup Interrupt Management + */ +PRIVILEGED_DATA volatile uint32_t ulPortYieldRequired = pdFALSE; + +/** @brief Interrupt nesting depth, used to count the number of interrupts to unwind. + * @ingroup Interrupt Management + */ +PRIVILEGED_DATA volatile uint32_t ulPortInterruptNesting = 0UL; + +/** @brief Variable to track whether or not the scheduler has been started. + * @ingroup Scheduler + * @note This variable is set to pdTRUE when the scheduler is started. + */ +PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; + +/** @brief Used in portASM.S's IRQ Handler to clear an interrupt. + * @ingroup Interrupt Management + */ +PRIVILEGED_DATA volatile uint32_t ulICCEOIR = configEOI_ADDRESS; + +/*---------------------------------------------------------------------------*/ + +/** @brief Set a FreeRTOS Task's initial context + * + * @param pxTopOfStack Pointer to where the task's stack starts + * @param pxCode Pointer to the function a task will run + * @param pvParameters Pointer to any arguments to be passed to the task's function + * @param xRunPrivileged Marks if the task is to be run in a privileged CPU mode. + * @param xMPUSettings MPU settings to be loaded as part of a task's context + * @return StackType_t* Pointer to where to restore the task's context from. + * + * @ingroup Task Context + * @note pxTopOfStack must be a region of memory that is a valid MPU region size. + */ +StackType_t * pxPortInitialiseStack( + StackType_t * pxTopOfStack, + TaskFunction_t pxCode, + void * pvParameters, + BaseType_t xRunPrivileged, + xMPU_SETTINGS * xMPUSettings +) /* PRIVILEGED_FUNCTION */ +{ + /** Setup the initial context of the task. The context is set exactly as + * expected by the portRESTORE_CONTEXT() macro. */ + UBaseType_t ulContextIndex = MAX_CONTEXT_SIZE - 1U; + + /* These two locations are used for SVC entry, fill them for debugging */ + xMPUSettings->ulContext[ ulContextIndex-- ] = 0xFEED2002; + xMPUSettings->ulContext[ ulContextIndex-- ] = 0xFEED1001; + + if( xRunPrivileged == pdTRUE ) + { + /* Current Program Status and Control Register */ + xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; + xMPUSettings->ulTaskFlags |= 0x1F000000; + xMPUSettings->ulContext[ ulContextIndex ] = SYS_MODE; + } + else + { + /* Current Program Status and Control Register */ + xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); + xMPUSettings->ulTaskFlags |= 0x10000000; + xMPUSettings->ulContext[ ulContextIndex ] = USER_MODE; + } + + if( ( ( uint32_t ) pxCode & portTHUMB_MODE_ADDRESS ) != 0x00UL ) + { + /* The task will start in THUMB mode, set the bit in the CPSR. */ + xMPUSettings->ulContext[ ulContextIndex ] |= portTHUMB_MODE_BIT; + xMPUSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + } + + /* Decrement ulContextIndex here after setting the CPSR */ + ulContextIndex--; + + /** First we load the Memory Location of the Task's function. + * Task Program Counter */ + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) pxCode; + + /** A FreeRTOS Task is not designed to return or exit from its function. + * As such a default Link Register is provided that will return to an + * error handling function. + * Task Link Register */ + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) portTASK_RETURN_ADDRESS; + + /** Set the task's stack pointer to be the bottom of it's stack, since on this + * CPU stacks grow upwards. + * Task Stack Pointer */ + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) pxTopOfStack; /* SP */ + + /* Next the General Purpose Registers */ + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0x12121212; /* R12 */ + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0x11111111; /* R11 */ + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0x10101010; /* R10 */ + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0x09090909; /* R9 */ + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0x08080808; /* R8 */ + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0x07070707; /* R7 */ + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0x06060606; /* R6 */ + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0x05050505; /* R5 */ + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0x04040404; /* R4 */ + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0x03030303; /* R3 */ + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0x02020202; /* R2 */ + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0x01010101; /* R1 */ + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) pvParameters; /* R0 */ + +#ifdef portENABLE_FPU + /* Initial Floating Point Context is the Floating Point Registers (FPRs) */ + /* There are 16 Double FPRs, D0-D15 on the Cortex-R FPU enabled chips */ + /* These map to the Single Precision FPRs, S0-S31 */ + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD0000015; /* S31 */ + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD1500000; /* S30 */ + + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD0000014; /* S29 */ + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD1400000; /* S28 */ + + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD0000013; /* S27 */ + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD1300000; /* S26 */ + + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD0000012; /* S25 */ + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD1200000; /* S24 */ + + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD0000011; /* S23 */ + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD1100000; /* S22 */ + + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD0000010; /* S21 */ + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD1000000; /* S20 */ + + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD0000009; /* S19 */ + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD9000000; /* S18 */ + + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD0000008; /* S17 */ + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD8000000; /* S16 */ + + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD0000007; /* S15 */ + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD7000000; /* S14 */ + + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD0000006; /* S13 */ + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD6000000; /* S12 */ + + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD0000005; /* S11 */ + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD5000000; /* S10 */ + + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD0000004; /* S9 */ + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD4000000; /* S8 */ + + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD0000003; /* S7 */ + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD3000000; /* S6 */ + + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD0000002; /* S5 */ + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD2000000; /* S4 */ + + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD0000001; /* S3 */ + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD1000000; /* S2 */ + + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD0000000; /* S1 */ + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD0000000; /* S0 */ + + /* Floating Point Status and Control Register */ + xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0x00000000; /* FPSR */ +#endif /* portENABLE_FPU */ + + /* The task will start with a critical nesting count of 0. */ + xMPUSettings->ulContext[ ulContextIndex ] = portNO_CRITICAL_NESTING; + + /* Ensure that the system call stack is double word aligned. */ + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackPointer = &( + xMPUSettings->xSystemCallStackInfo + .ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE - 1 ] + ); + xMPUSettings->xSystemCallStackInfo.pulSystemCallStackPointer = + ( uint32_t * ) ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo + .pulSystemCallStackPointer ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + + /* This is not NULL only for the duration of a system call. */ + xMPUSettings->xSystemCallStackInfo.pulTaskStackPointer = NULL; + /* Set the System Call LR to go directly to vPortSystemCallExit */ + xMPUSettings->xSystemCallStackInfo.pulSystemCallLinkRegister = &vPortSystemCallExit; + UBaseType_t ulStackIndex; + /* Fill the System Call Stack with known values for debugging. */ + for( ulStackIndex = 0x0; ulStackIndex < configSYSTEM_CALL_STACK_SIZE; ulStackIndex++ ) + { + xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ ulStackIndex ] = + 0x575B | ulStackIndex; + } + + /* Return the address where the context of this task should be restored from*/ + return ( &xMPUSettings->ulContext[ ulContextIndex ] ); +} + +/*----------------------------------------------------------------------------*/ + +/** @brief Returns the smallest valid MPU Region size that can hold a number of bytes. + * + * @ingroup MPU Control + * + * @param ulActualSizeInBytes Number of bytes to find a valid MPU region size for + * @return uint32_t The smallest MPU region size that can hold the requested bytes. + */ +PRIVILEGED_FUNCTION static uint32_t prvGetMPURegionSizeSetting( + uint32_t ulActualSizeInBytes +); + +static uint32_t prvGetMPURegionSizeSetting( uint32_t ulActualSizeInBytes +) /* PRIVILEGED_FUNCTION */ +{ + uint32_t ulRegionSize, ulReturnValue = 4U; + + /* 32 is the smallest region size, 31 is the largest valid value for + * ulReturnValue. */ + for( ulRegionSize = 32UL; ulReturnValue < 31UL; ( ulRegionSize <<= 1UL ) ) + { + if( ulActualSizeInBytes <= ulRegionSize ) + { + break; + } + else + { + ulReturnValue++; + } + } + + /* Shift the code by one before returning so it can be written directly + * into the the correct bit position of the attribute register. */ + return ulReturnValue << 1UL; +} + +/*----------------------------------------------------------------------------*/ + +/** @brief Stores a FreeRTOS Task's MPU Settings in its TCB + * + * @param xMPUSettings The memory location in the TCB to store MPU settings + * @param xRegions The MPU settings being requested by the task. + * @param pxBottomOfStack The base address of the Task's Stack + * @param ulStackDepth The length of the task's stack. + * + * @ingroup Task Context + * @ingroup MPU Control + * + * @note pxBottomOfStack must be aligned to a region size of length ulStackDepth. + * @note ulStackDepth must be a power of 2 larger than 32 bytes. + */ +void vPortStoreTaskMPUSettings( + xMPU_SETTINGS * xMPUSettings, + const struct xMEMORY_REGION * const xRegions, + StackType_t * pxBottomOfStack, + uint32_t ulStackDepth +) /* PRIVILEGED_FUNCTION */ +{ +#if defined( __ARMCC_VERSION ) + + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __SRAM_segment_start__; + extern uint32_t * __SRAM_segment_end__; + extern uint32_t * __privileged_data_start__; + extern uint32_t * __privileged_data_end__; +#else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __SRAM_segment_start__[]; + extern uint32_t __SRAM_segment_end__[]; + +#endif /* if defined( __ARMCC_VERSION ) */ + uint32_t lIndex = 0x0; + uint32_t ul = 0x0; + + if( xRegions == NULL ) + { + /* No MPU regions are specified so allow access to all of the RAM. */ + xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress = ( uint32_t + ) __SRAM_segment_start__; + xMPUSettings->xRegion[ 0 ].ulRegionSize = + ( prvGetMPURegionSizeSetting( + ( uint32_t ) __SRAM_segment_end__ - ( uint32_t ) __SRAM_segment_start__ + ) ) | + portMPU_REGION_ENABLE; + xMPUSettings->xRegion[ 0 ].ulRegionAttribute = + portMPU_PRIV_RW_USER_RW_NOEXEC | portMPU_NORMAL_OIWTNOWA_SHARED; + + /* Invalidate all other regions. */ + for( ul = 1; ul <= portNUM_CONFIGURABLE_REGIONS; ul++ ) + { + xMPUSettings->xRegion[ ul ].ulRegionBaseAddress = 0x0UL; + xMPUSettings->xRegion[ ul ].ulRegionSize = 0x0UL; + xMPUSettings->xRegion[ ul ].ulRegionAttribute = 0x0UL; + } + } + else + { + /* This function is called automatically when the task is created - in + * which case the stack region parameters will be valid. At all other + * times the stack parameters will not be valid and it is assumed that the + * stack region has already been configured. */ + + if( ulStackDepth > 0 ) + { + uint32_t ulSmallestRegion = prvGetMPURegionSizeSetting( ulStackDepth * 0x4 ); + /* Define the region that allows access to the stack. */ + xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress = ( uint32_t ) pxBottomOfStack; + xMPUSettings->xRegion[ 0 ].ulRegionSize = + ulSmallestRegion | portMPU_REGION_ENABLE; + xMPUSettings->xRegion[ 0 ].ulRegionAttribute = + portMPU_PRIV_RW_USER_RW_NOEXEC | portMPU_NORMAL_OIWTNOWA_SHARED; + } + + for( ul = 1; ul <= portNUM_CONFIGURABLE_REGIONS; ul++ ) + { + if( ( xRegions[ lIndex ] ).ulLengthInBytes > 0UL ) + { + /* Translate the generic region definition contained in + * xRegions into the R4 specific MPU settings that are then + * stored in xMPUSettings. */ + xMPUSettings->xRegion[ ul ].ulRegionBaseAddress = + ( uint32_t ) xRegions[ lIndex ].pvBaseAddress; + xMPUSettings->xRegion[ ul ].ulRegionSize = + prvGetMPURegionSizeSetting( xRegions[ lIndex ].ulLengthInBytes ) | + portMPU_REGION_ENABLE; + xMPUSettings->xRegion[ ul ].ulRegionAttribute = + xRegions[ lIndex ].ulParameters; + } + else + { + /* Invalidate the region. */ + xMPUSettings->xRegion[ ul ].ulRegionBaseAddress = 0x0UL; + xMPUSettings->xRegion[ ul ].ulRegionSize = 0x0UL; + xMPUSettings->xRegion[ ul ].ulRegionAttribute = 0x0UL; + } + + lIndex++; + } + } +} + +/*----------------------------------------------------------------------------*/ + +/** @brief Set up a default MPU memory Map + * @return PRIVILEGED_FUNCTION VOID + * @ingroup MPU Control + * @note This function shall be called before calling vPortStartFirstTask(). + * @note This function works by pulling variables from the linker script. + * Ensure that the variables used in your linker script match up with the variable names + * used at the start of this function. + */ +PRIVILEGED_FUNCTION static void prvSetupDefaultMPU( void ) +{ +#if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + /* Sections used for FLASH */ + extern uint32_t * __FLASH_segment_start__; + extern uint32_t * __FLASH_segment_end__; + extern uint32_t * __privileged_functions_start__; + extern uint32_t * __privileged_functions_end__; + + /* Sections used for RAM */ + extern uint32_t * __SRAM_segment_start__; + extern uint32_t * __SRAM_segment_end__; + extern uint32_t * __privileged_data_start__; + extern uint32_t * __privileged_data_end__; + + /* Sections used for system peripherals, such as UART */ + extern uint32_t * __peripherals_start__; + extern uint32_t * __peripherals_end__; + +#else + /* Declaration when these variable are exported from linker scripts. */ + /* Sections used for FLASH */ + extern uint32_t __FLASH_segment_start__[]; + extern uint32_t __FLASH_segment_end__[]; + extern uint32_t __privileged_functions_start__[]; + extern uint32_t __privileged_functions_end__[]; + + /* Sections used for RAM */ + extern uint32_t __SRAM_segment_start__[]; + extern uint32_t __SRAM_segment_end__[]; + extern uint32_t __privileged_data_start__[]; + extern uint32_t __privileged_data_end__[]; + + /* Sections used for system peripherals, such as UART */ + extern uint32_t __peripherals_start__[]; + extern uint32_t __peripherals_end__[]; +#endif /* if defined( __ARMCC_VERSION ) */ + uint32_t ulRegionStart; + uint32_t ulRegionEnd; + uint32_t ulRegionLength; + + /* Ensure the MPU is disabled */ + prvMpuDisable(); + + /* Unprivileged and Privileged Read and Exec MPU Region for Flash */ + ulRegionStart = ( uint32_t ) __FLASH_segment_start__; + ulRegionEnd = ( uint32_t ) __FLASH_segment_end__; + ulRegionLength = ulRegionEnd - ulRegionStart; + ulRegionLength = prvGetMPURegionSizeSetting( ulRegionLength ) | portMPU_REGION_ENABLE; + + prvMpuSetRegion( + portUNPRIVILEGED_FLASH_REGION, + ulRegionStart, + ulRegionLength, + portMPU_PRIV_RO_USER_RO_EXEC | portMPU_NORMAL_OIWTNOWA_SHARED + ); + + /* Privileged Read and Exec MPU Region for PRIVILEGED_FUNCTIONS. */ + ulRegionStart = ( uint32_t ) __privileged_functions_start__; + ulRegionEnd = ( uint32_t ) __privileged_functions_end__; + ulRegionLength = ulRegionEnd - ulRegionStart; + ulRegionLength = prvGetMPURegionSizeSetting( ulRegionLength ) | portMPU_REGION_ENABLE; + prvMpuSetRegion( + portPRIVILEGED_FLASH_REGION, + ulRegionStart, + ulRegionLength, + portMPU_PRIV_RO_USER_NA_EXEC | portMPU_NORMAL_OIWTNOWA_SHARED + ); + + /* MPU Region for Peripheral Usage */ + ulRegionStart = ( uint32_t ) __peripherals_start__; + ulRegionEnd = ( uint32_t ) __peripherals_end__; + ulRegionLength = ulRegionEnd - ulRegionStart; + ulRegionLength = prvGetMPURegionSizeSetting( ulRegionLength ) | portMPU_REGION_ENABLE; + prvMpuSetRegion( + portGENERAL_PERIPHERALS_REGION, + ulRegionStart, + ulRegionLength, + portMPU_PRIV_RW_USER_RW_NOEXEC | portMPU_DEVICE_NONSHAREABLE + ); + + /* All Read, and Privileged Write MPU Region for PRIVILEGED_DATA. */ + ulRegionStart = ( uint32_t ) __privileged_data_start__; + ulRegionEnd = ( uint32_t ) __privileged_data_end__; + ulRegionLength = ulRegionEnd - ulRegionStart; + ulRegionLength = prvGetMPURegionSizeSetting( ulRegionLength ) | portMPU_REGION_ENABLE; + prvMpuSetRegion( + portPRIVILEGED_RAM_REGION, + ulRegionStart, + ulRegionLength, + portMPU_PRIV_RW_USER_RO_NOEXEC | portMPU_NORMAL_OIWTNOWA_SHARED + ); + + /* After setting default regions, enable the MPU */ + prvMpuEnable(); +} + +/*---------------------------------------------------------------------------*/ + +/** @brief Determine if a FreeRTOS Task has been granted access to a memory region + * + * @param pvBuffer Base address of the memory region access is being requested. + * @param ulBufferLength The length of the memory region that access is being requested. + * @param ulAccessRequested The type of access being requested, either read or write. + * @return BaseType_t pdTRUE if the task can access the region, pdFALSE otherwise + * + * @ingroup Task Context + * @ingroup MPU Control + */ +BaseType_t xPortIsAuthorizedToAccessBuffer( + const void * pvBuffer, + uint32_t ulBufferLength, + uint32_t ulAccessRequested +) /* PRIVILEGED_FUNCTION */ +{ + volatile uint32_t i, ulBufferStartAddress, ulBufferEndAddress; + BaseType_t xAccessGranted = pdFALSE; + + if( pdFALSE == xSchedulerRunning ) + { + xAccessGranted = pdTRUE; + } + else + { + /* Calling task's MPU settings. */ + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); + + uint32_t regionEndAddress = 0U; + uint32_t regionLength = 0U; + uint32_t regionStartAddress = 0u; + + if( portTASK_IS_PRIVILEGED_FLAG == + ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) ) + { + xAccessGranted = pdTRUE; + } + else + { + /* Protect against buffer overflow range check */ + if( pdFALSE == + ( ( uint32_t ) pvBuffer > + ( ( ( uint32_t ) 0 ) - ( uint32_t ) 1U ) - ulBufferLength - 1UL ) ) + { + ulBufferStartAddress = ( uint32_t ) pvBuffer; + ulBufferEndAddress = ( ( ( uint32_t ) pvBuffer ) + ulBufferLength - 1UL ); + + for( i = 0; i < portTOTAL_NUM_REGIONS_IN_TCB; i++ ) + { + regionStartAddress = + xTaskMpuSettings->xRegion[ i ].ulRegionBaseAddress; + regionLength = + 1 << ( ( xTaskMpuSettings->xRegion[ i ].ulRegionSize >> 1 ) + 1U ); + regionEndAddress = regionStartAddress + regionLength; + + if( ( ulBufferStartAddress >= regionStartAddress ) && + ( ulBufferEndAddress <= regionEndAddress ) ) + { + if( tskMPU_READ_PERMISSION == ulAccessRequested ) + { + /* MPU CTRL Register Access Permission for unprivileged Read + * is bX1X */ + if( portMPU_PRIV_RO_USER_RO_EXEC & + xTaskMpuSettings->xRegion[ i ].ulRegionAttribute ) + { + xAccessGranted = pdTRUE; + break; + } + } + /* MPU CTRL Register Access Permission for unprivileged write is + * b011 */ + else if( tskMPU_WRITE_PERMISSION & ulAccessRequested ) + { + if( portMPU_PRIV_RW_USER_RW_EXEC == + ( portMPU_PRIV_RW_USER_RW_EXEC & + xTaskMpuSettings->xRegion[ i ].ulRegionAttribute ) ) + { + xAccessGranted = pdTRUE; + break; + } + } + } + } + } + } + } + return xAccessGranted; +} + +#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; + + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else + { + 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 + +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 ) */ + +/*---------------------------------------------------------------------------*/ + +/** @brief Determine if the FreeRTOS Task was created as a privileged task + * + * @return BaseType_t pdTRUE if the task's ulTaskFlags mark it as privileged. + * pdFALSE if the task was not created as a privileged task. + * + * @ingroup MPU Control + * @ingroup Task Context + */ +BaseType_t xPortIsTaskPrivileged( void ) /* PRIVILEGED_FUNCTION */ +{ + BaseType_t xTaskIsPrivileged = pdFALSE; + + /* Calling task's MPU settings. */ + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == + portTASK_IS_PRIVILEGED_FLAG ) + { + xTaskIsPrivileged = pdTRUE; + } + + return xTaskIsPrivileged; +} +/*---------------------------------------------------------------------------*/ + +/** @brief Function that is used as the default Link Register address for a new Task + * + * @ingroup Task Context + * @note This function is used as the default Link Register address if + * configTASK_RETURN_ADDRESS is not defined in FreeRTOSConfig.h + * + */ +void prvTaskExitError( void ) +{ + /* A function that implements a task must not exit or attempt to return to + * its caller as there is nothing to return to. If a task wants to exit it + * should instead call vTaskDelete( NULL ). + * + * Artificially force an assert() to be triggered if configASSERT() is + * defined, then stop here so application writers can catch the error. */ + configASSERT( ulPortInterruptNesting == ~0UL ); + + for( ;; ) + { + } +} + +/*---------------------------------------------------------------------------*/ + +/** @brief Start the FreeRTOS-Kernel's control of Tasks by starting the System Tick + * Interrupt. + * + * @ingroup Scheduler + * @return BaseType_t This function is not meant to be returned from. + * If it does return it returns pdFALSE to mark that the scheduler could not be started. + */ +BaseType_t xPortStartScheduler( void ) +{ +#if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + /* Sections used for Privileged Stacks to zero them out before starting tasks */ + extern uint32_t * __privileged_stacks_start__; + extern uint32_t * __privileged_stacks_end__; +#else /* if defined( __ARMCC_VERSION ) */ + /* Declaration when these variable are exported from linker scripts. */ + /* Sections used for Privileged Stacks to zero them out before starting tasks */ +/* + extern uint32_t __privileged_stacks_start__[]; + extern uint32_t __privileged_stacks_end__[]; +*/ +#endif /* if defined( __ARMCC_VERSION ) */ + + /* Start the timer that generates the tick ISR. */ + configSETUP_TICK_INTERRUPT(); + + /* Reset the critical section nesting count read to execute the first task. */ + ulCriticalNesting = 0UL; + + /* Configure the regions in the MPU that are common to all tasks. */ + prvSetupDefaultMPU(); + + xSchedulerRunning = pdTRUE; + + /* Load the context of the first task, starting the FreeRTOS-Scheduler's control. */ + vPortStartFirstTask(); + + /* Will only get here if vTaskStartScheduler() was called with the CPU in + * a non-privileged mode or the binary point register was not set to its lowest + * possible value. prvTaskExitError() is referenced to prevent a compiler + * warning about it being defined but not referenced in the case that the user + * defines their own exit address. */ + ( void ) prvTaskExitError(); + return 0; +} +/*---------------------------------------------------------------------------*/ + +/** @brief Function meant to end the FreeRTOS Scheduler, not implemented on this port. + * @ingroup Scheduler + */ +void vPortEndScheduler( void ) +{ + xSchedulerRunning = pdFALSE; + /* Not implemented in ports where there is nothing to return to. + * Artificially force an assert. */ + configASSERT( xSchedulerRunning ); +} + +/*---------------------------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CRx_MPU/portASM.S b/portable/GCC/ARM_CRx_MPU/portASM.S new file mode 100644 index 0000000000..7ea5ad42ca --- /dev/null +++ b/portable/GCC/ARM_CRx_MPU/portASM.S @@ -0,0 +1,660 @@ +/* + * FreeRTOS Kernel V10.6.0 + * Copyright (C) 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + + .arm + .syntax unified + /* All code in the portASM.S file is intended to be run from a prvileged + * operating mode, as such mark the entire file as privileged_functions */ + .section privileged_functions + +#define FREERTOS_ASSEMBLY + #include "portmacro_asm.h" + #include "mpu_syscall_numbers.h" +#undef FREERTOS_ASSEMBLY + + /* External FreeRTOS-Kernel Variables */ + .extern pxCurrentTCB + .extern ulPortInterruptNesting + .extern ulICCEOIR + .extern ulPortYieldRequired + .extern __privileged_functions_start__ + .extern __privileged_functions_end__ + .extern __privileged_stacks_start__ + .extern __privileged_stacks_end__ + .extern __syscalls_flash_length__ + .extern __syscalls_flash_start__ + .extern __syscalls_flash_end__ + + /* External FreeRTOS-Kernel Functions */ + .extern vAssertCalled + .extern vTaskSwitchContext + .extern vApplicationIRQHandler + +/****************************************************************************** + * portSAVE_CONTEXT is used to save all the registers, variables, and MPU + * settings that make up a task's context. + *****************************************************************************/ +.macro portSAVE_CONTEXT + DSB + ISB + /* Move the SVC SP backwards before calling the SRS */ + SRSDB SP!, #SVC_MODE + /* Change to Supervisor Mode for the Context Save */ + CPS #SVC_MODE + /* Get the saved SPSR that was pushed to the SVC SP */ + LDR LR, [SP, #0x4] + /* Move it to our SPSR so we can save the correct SP and LR */ + MSR SPSR_cxsf, LR + /* Save the previous operating modes Registers, Stack Pointer, and Link Register */ + STMDB SP, {R0-R14}^ + /** Can't do a PUSH when using the ^ character, so need to manually move + * the SP after pushing the registers */ + SUB SP, SP, #portREGISTER_CONTEXT_LENGTH +#ifdef portENABLE_FPU + /* Save the floating point context */ + /* Push the 16 floating point registers onto the stack */ + VPUSH {D0-D15} + /* Load the FPSCR into R0 */ + FMRX R0, FPSCR + /* Push the value of FPSCR onto the stack */ + PUSH {R0} +#endif /* portENABLE_FPU */ + /* Load the address of ulCriticalNesting */ + LDR R0, =ulCriticalNesting + /* Load the value of ulCriticalNesting into R0 */ + LDR R0, [R0] + /* Push the value of ulCriticalNesting into the context */ + PUSH {R0} + /* Load the address of pxCurrentTCB into R0 */ + LDR R0, =pxCurrentTCB + /* Load the TCB into R0 */ + LDR R0, [R0] + /* Set pxTopOfStack in the TCB to be the current Stack Pointer. This is + * where to load the FreeRTOS-Task context from. */ + STR SP, [R0] + /* Move the SVC SP forward to the scratch area in ulContext */ + ADD SP, SP, 0x8 +.endm + +/****************************************************************************** + * portRESTORE_CONTEXT is used to restore all the registers, variables, and MPU + * settings that make up a task's context. + *****************************************************************************/ +.macro portRESTORE_CONTEXT + /* Load the address of the current task TCB */ + LDR R0, =pxCurrentTCB + /* Load the TCB into R0 */ + LDR R0, [R0] + /* Set R1 to the second member of the TCB struct, xMPUSettings */ + ADD R1, R0, #0x4 + /* Set our SP to pxTopOfStack, the address of the Task context */ + LDR SP, [R0] + /* Load the first per-task MPU region into R5 */ + MOV R5, #portFIRST_CONFIGURABLE_REGION + /* Dynamically load the last MPU region */ + MRC p15, 0, R6, c0, c0, 0x4 + /* Move the number of MPU regions forward */ + LSR R6, #0x8 + /* Clear other bits, as there can only be 8-16 regions */ + AND R6, 0x1F + /* When creating a loop label in a macro it has to be a numeric label. */ +123: /* For (R5 = portFIRST_CONFIGURABLE_REGION ; R5 <= portSTACK_REGION ; R5++ ) */ + /* Load values of struct MPU_REGION_REGISTERS into R1-R3 */ + LDMIA R1!, {R2-R4} + /* Load the values set in xMPU_REGION_REGISTERS */ + /* R2 Will hold ulRegionSize */ + /* R3 will hold ulRegionAttribute */ + /* R4 will hold ulRegionBaseAddress */ + /* R5 will hold the MPU Region number */ + + /* Select the MPU Region using R5 */ + MCR p15, #0, R5, c6, c2, #0 + /* Set the MPU Region Base Address using ulRegionBaseAddress */ + MCR p15, #0, R4, c6, c1, #0 + /* Set the MPU Region Access Attributes using ulRegionAttribute */ + MCR p15, #0, R3, c6, c1, #4 + /* Set the MPU Region Size, and if the region is enabled using ulRegionSize */ + MCR p15, #0, R2, c6, c1, #2 + /* R5++ */ + ADD R5, R5, #1 + /* R5 <= R6 */ + CMP R5, #portSTACK_REGION + /* R5 <= R6, loop again */ + BLE 123b + /* R5 > portSTACK_REGION, all MPU regions have been restored */ + + /* Restore the critical section nesting depth. */ + /* Load the address of the ulCriticalNesting variable into R1 */ + LDR R1, =ulCriticalNesting + /* Pop the previously saved value of ulCriticalNesting from ulContext */ + POP {R2} + /* Store the value of ulCriticalNesting into address of ulCriticalNesting */ + STR R2, [R1] + +#ifdef portENABLE_FPU + /* Restore the Floating Point Context */ + /* Pop the value of FPSCR from ulContext */ + POP {R1} + /* Move the saved FPSCR value into the FPSCR */ + VMSR FPSCR, R1 + /* Restore the Floating Point Registers */ + VPOP {D0-D15} +#endif /* portENABLE_FPU*/ + /* At this point the SVC stack pointer will be in one of three places: + * 1. ulContext[51] - This is the bottom of the context inside of the TCB for task saving + * 1. ulContext[1] - We reloaded a nested context, the next context to restore is a task context + * 2. ulSystemCallStackBuffer[?] - Restoring a nested context inside of an exception handler + */ + + /* Restore the register context, first need to load the mode bits */ + /* Set R1 to be past R0-R12 */ + ADD R1, SP, #portGPR_LENGTH + /* Get the CPSR from the context, needed to set the SP and the LR */ + LDR R2, [R1, +#0x0C] + /* Move the CPSR the into our SPSR */ + MSR SPSR_cxsf, R2 + /* Load the stored Stack Pointer and Link Register */ + LDM R1, {R13-R14}^ + /* Load R0-R12 from the context */ + POP {R0-R12} + /* Jump over the already set R13 and R14 */ + ADD SP, SP, #0x8 + /* Return from the exception, loading the PC and CPSR */ + RFE SP! + +.endm + +/****************************************************************************** + * FreeRTOS_Tick_Handler is used to save context, increment the tick count, and + * then switch tasks if neeeded + *****************************************************************************/ +.align 4 +.global FreeRTOS_Tick_Handler +.type FreeRTOS_Tick_Handler, %function +FreeRTOS_Tick_Handler: + /* Return to the interrupted instruction. */ + SUB LR, LR, #4 + /* Save the context of the current task. */ + portSAVE_CONTEXT + /* Enter back into IRQ mode after saving task context */ + CPS #IRQ_MODE + /* Clear interrupt flag in RTI. */ + LDR R0, =configRTI_ADDRESS + MOV R1, #1 + STR R1, [R0] + /* Increment the tick count, making any adjustments to the blocked lists + that may be necessary. */ + BL xTaskIncrementTick + /* If xTaskIncrementTick returned non-zero then select the next task to execute. */ + CMP R0, #0 + BLNE vTaskSwitchContext + /* Swap to SVC Mode to restore the task context */ + CPS #SVC_MODE + /* Restore the context of the task selected to execute. */ + portRESTORE_CONTEXT + +/*-----------------------------------------------------------*/ +/* Yield to another task from within the FreeRTOS API */ + +.align 4 +.global vPortYieldWithinAPI +.type vPortYieldWithinAPI, %function +vPortYieldWithinAPI: + /* Return to the interrupted instruction. */ + SUB LR, LR, #4 + /* Save the context of the current task */ + portSAVE_CONTEXT + /* Swap back to IRQ Mode for selecting the next task */ + CPS #IRQ_MODE + /* Clear the Interrupt Flag for vPortYieldWithinAPI */ + MOV R0, #configSSI_ADDRESS + LDR R0, [R0] + /* Select the next task to execute. */ + BL vTaskSwitchContext + /* Swap back to SVC Mode for context restore */ + CPS #SVC_MODE + /* Restore the context of the task selected to execute. */ + portRESTORE_CONTEXT + +/****************************************************************************** + * vPortStartFirstTask is used to start the scheduler. + *****************************************************************************/ +.align 4 +.global vPortStartFirstTask +.type vPortStartFirstTask, %function +vPortStartFirstTask: + /** This function is called from System Mode to start the FreeRTOS-Kernel. + * This is done by restoring the context of the first task. + * Restoring the context of a task will allow interrupts. + * This allows the FreeRTOS Scheduler Tick to start, and therefore + * starts the FreeRTOS-Kernel. + */ + /* Swap to SVC Mode for context restore */ + CPS #SVC_MODE + /* Restore context of first task, which enables IRQs, starting the sys tick timer */ + portRESTORE_CONTEXT + +/****************************************************************************** + * The FreeRTOS SVC Handler is used to handle Supervisor Calls + *****************************************************************************/ +/** Upon entering here the LR, or R14, will hold the address of the + * following instruction. The instruction can be inspected to determine + * what SVC # was raised. + * This handler is ONLY safe when called from the exposed SVC wrapper functions + * located after this handler in this file. +*/ + + /* Checks: + * 1. SVC is raised from the system call section (i.e. application is + * not raising SVC directly). + * 2. pxMpuSettings->xSystemCallStackInfo.pulTaskStack must be NULL as + * it is non-NULL only during the execution of a system call (i.e. + * between system call enter and exit). + * 3. System call is not for a kernel API disabled by the configuration + * in FreeRTOSConfig.h. + * 4. We do not need to check that ucSystemCallNumber is within range + * because the assembly SVC handler checks that before calling + * this function. + */ + +.align 4 +.global FreeRTOS_SVC_Handler +.type FreeRTOS_SVC_Handler, %function +FreeRTOS_SVC_Handler: + /* Push R11 and R12 to the bottom two, pre-resereved, addresses in ulContext */ + STM R13, {R11, R12} + + /* -------------------- Caller Flash Location Check -------------------- */ + + /** The address of the caller will be in the Link Register (LR), it will be + * the caller's Program Counter (PC). Check this address to ensure the + * Supervisor call (SVC) was raised from inside the FreRTOS-Kernel. */ + + /* Get the starting address for FreeRTOS System Calls */ + LDR R12, =__syscalls_flash_start__ + /* Subtract the start point from the Program Counter of the caller */ + SUB R11, LR, R12 + /* Now check if it is less than the length of the section */ + LDR R12, =__syscalls_flash_length__ + /* Check if an SVC was raised after the end of FreeRTOS System Calls */ + CMP R11, R12 + /* If the SVC was raised from outside FreeRTOS System Calls exit */ + BGE SVC_Handler_Exit + + /* ----------------------- Get Caller SVC Number ----------------------- */ + +svcNumberCheck: + /* The SPSR will be the CPSR of the calling task, store it in R11 */ + MRS R11, SPSR + /* Thumb Mode is bit 5 of the CPSR. And it with the CPSR for comparison check */ + ANDS R11, R11, #0x20 + + /* The SVC instruction will be 0x2 before LR in Thumb Mode, or 0x4 if not */ + + /* In Thumb Mode, so get instruction 0x2 before */ + LDRHNE R11, [LR, #-0x2] + /* Not in Thumb Mode, so get the instruction 0x4 before */ + LDRHEQ R11, [LR, #-0x4] + + /* ---------------------------- SVC Routing ---------------------------- */ + + /* Determine if the SVC number is below #NUM_SYSTEM_CALLS */ + CMP R11, #NUM_SYSTEM_CALLS + /* If it is go to the entry point for FreeRTOS System Calls */ + BLT svcSystemCallEnter + + /* Check if the caller is leaving a FreeRTOS System Call */ + CMP R11, #portSVC_SYSTEM_CALL_EXIT + BEQ svcSystemCallExit + + /* Check if the caller is requesting to yield */ + CMP R11, #portSVC_YIELD + BEQ svcPortYield + + /* If one of the above jumps wasn't taken, go straight to the exit */ +SVC_Handler_Exit: + /** Restore the saved R11 and R12, then return to the caller */ + LDM SP, {R11, R12} + /* This instruction loads the SPSR into the CPSR, performing the mode swap */ + MOVS PC, LR + +/*-----------------------------------------------------------*/ + +/* Save a FreeRTOS-Task's Context, select a new task, and then restore its context */ +svcPortYield: + /* Restore the previously saved R11, R12 */ + LDM SP, {R11, R12} + /* Save the context of the current task and select a new task to run. */ + portSAVE_CONTEXT + /* Run the following function from the IRQ stack */ + CPS #IRQ_MODE + /* Select a new task to swap to */ + BL vTaskSwitchContext + /* Swap back to SVC Mode for context restore */ + CPS #SVC_MODE + /* Restore the context of the task selected to execute. */ + portRESTORE_CONTEXT + +/* Swap a task back to using its task stack, and reset its privilege level if needed */ +svcSystemCallExit: + /* Restore the Task Stack Pointer and Link Register */ + /* Load the address of pxCurrentTCB into R11 */ + LDR R11, =pxCurrentTCB + /* Load pxCurrentTCB into R11 */ + LDR R11, [R11] + /* Set R11 to be the location of xSystemCallStackInfo inside the TCB */ + ADD R11, R11, #portSYSTEM_CALL_INFO_OFFSET + /* Restore the user mode Stack Pointer and Link Register */ + LDMIB R11, {R13-R14}^ + /* Zero out R12 so we can set ulTaskStackPointer back to NULL */ + AND R12, R12, #0x0 + /* Set pulTaskStackPointer to be 0x0 */ + STR R12, [R11, #0x4] + /* Set pulLinkRegisterAtSystemCallEntry to be 0x0 */ + STR R12, [R11, #0x8] + /* Load the ulTaskFlag so we can determine if we're going to lower privilege */ + LDM R11, {R12} + /* Check if the task is privileged */ + CMP R12, #portTASK_IS_PRIVILEGED_FLAG + /* If the task is privileged we can leave now */ + BEQ SVC_Handler_Exit + /* Otherwise, we need to set the SPSR back to USER mode */ + MRS R12, SPSR + /* Clear the last 4 bits, which are the MODE bits */ + BIC R12, R12, #0x0F + /* Move the new value into the SPSR */ + MSR SPSR_cxsf, R12 + /* Jump back */ + B SVC_Handler_Exit + +/* svcSystemCallEnter */ +/* Swap a task to using the ulSystemCallStack Buffer, and set its privilege high */ +svcSystemCallEnter: + /* Load the base address of the uxSystemCallImplementations[] table into R14 */ + LDR R14, =uxSystemCallImplementations + + /** Shift the value of R11, the SVC number, left by two to get the jump offset + * Add this offset to R14, which holds the jump table address. This is the address + * of the SVC that the relevant function is trying to complete. + * Now when the Link Register is loaded as the Program Counter at the end of this + * handler, the caller will immediately execute the requested function */ + LDR R14, [R14, R11, lsl #2] + + /* Load the address of pxCurrentTCB into R11 */ + LDR R11, =pxCurrentTCB + /* Load pxCurrentTCB into R11 */ + LDR R11, [R11] + /* Set R11 to be the location of xSystemCallStackInfo inside the TCB */ + ADD R11, R11, #portSYSTEM_CALL_INFO_OFFSET + /* Get the value in the TCB for ulTaskStackPointer */ + LDMIB R11!, { R12 } + /* Make sure that ulTaskStackPointer was null, meaning that this is initial entry */ + TST R12, #0x0 + /** Hard code the ascii value of the function name and line number to call + * assert if the ulTaskStackPointer is not null. */ + MOVWNE R0, #0x706F + MOVTNE R0, #0x7274 + MOVNE R1, #458 + BNE vAssertCalled + + /* Store the task's SP and LR to xSYSTEM_CALL_STACK_INFO */ + STM R11, {R13-R14}^ + /* It's a compilation warning to use the ! for writeback, so manually move R11 */ + ADD R11, R11, 0x8 + /* Load pulSystemCallStackPointer and pulSystemCallLinkRegister now */ + LDM R11, {R13-R14}^ + + /* Swap the SPSR to SYS_MODE for the System Call. Move SPSR into R12 */ + MRS R12, SPSR + /* Set the MODE bits to SYS_MODE */ + ORR R12, R12, #SYS_MODE + /* Assign the new value to SPSR */ + MSR SPSR_cxsf, R12 + /* Leave through the SVC Exit */ + B SVC_Handler_Exit + +/*-------------------------------------------------------------------------------*/ +/* vPortEnterCritical */ +.align 4 +.global vPortEnterCritical +.type vPortEnterCritical, %function +vPortEnterCritical: + /* Disable IRQs */ + CPSID I + /* Save scratch registers */ + PUSH {R0-R1} + /* Load address of current critical nesting count */ + LDR R0, =ulCriticalNesting + /* Load value of current critical nesting count */ + LDR R1, [R0] + /* Add one to ulCriticalNesting */ + ADD R1, R1, #1 + /* Store the modified ulCriticalNesting back into RAM */ + STR R1, [R0] + /* Return to caller */ + POP {R0-R1} + BX LR + +/*-------------------------------------------------------------------------------*/ +/* vPortDisableInterrupts */ +.align 4 +.global vPortDisableInterrupts +.type vPortDisableInterrupts, %function +vPortDisableInterrupts: + /* Disable IRQs */ + CPSID I + /* Return to caller */ + BX LR + +/*-------------------------------------------------------------------------------*/ +/* vPortExitCritical */ +.align 4 +.global vPortExitCritical +.type vPortExitCritical, %function +vPortExitCritical: + /* Store two scratch registers */ + PUSH {R0-R1} + /* Load address of current critical nesting count */ + LDR R0, =ulCriticalNesting + /* Load value of current critical nesting count */ + LDR R1, [R0] + /* Check if the count is 0 */ + CMP R1, #0 + /* If ulCriticalNesting is greater than 0, Subtract 1 from it */ + SUBGT R1, R1, #1 + /* Store the modified ulCriticalNesting back into RAM */ + STRGT R1, [R0] + /* Enable IRQs */ + CPSIE I + /* Return to caller */ + POP {R0-R1} + BX LR + +/*-------------------------------------------------------------------------------*/ +/* vPortEnableInterrupts */ +.align 4 +.global vPortEnableInterrupts +.type vPortEnableInterrupts, %function +vPortEnableInterrupts: + /* Enable IRQs */ + CPSIE I + /* Return to caller */ + BX LR + +/****************************************************************************** + * prvMpuSetRegion is used to set the base address, access attributes, + * and the size and enable bits of a selected MPU region. + * void prvMpuSetRegion(unsigned region, unsigned base, unsigned size, unsigned access) + *****************************************************************************/ +.align 4 +.global prvMpuSetRegion +.type prvMpuSetRegion, %function +prvMpuSetRegion: + /* Only 15 possible regions, drop all other bits */ + AND R0, R0, #15 + /* Select the MPU Region selected by region */ + MCR p15, #0, R0, c6, c2, #0 + /* Set the Base Address to be base */ + MCR p15, #0, R1, c6, c1, #0 + /* Set the Access Attributes to be access */ + MCR p15, #0, R3, c6, c1, #4 + /* Set the Size and Enable bits to be size */ + MCR p15, #0, R2, c6, c1, #2 + BX LR + +/****************************************************************************** + * prvMpuEnable is used to set the Enable bit of the MPU Enable Register to 1. + *****************************************************************************/ +.align 4 +.global prvMpuEnable +.type prvMpuEnable, %function +prvMpuEnable: + /* Read the current MPU control register into R0 */ + MRC p15, #0, R0, c1, c0, #0 + /* Set the enable bit to high */ + ORR R0, R0, #0x1 + /* Data sync */ + DSB + /* Write out previous MPU control register with a high enable bit */ + MCR p15, #0, R0, c1, c0, #0 + /* Instruction sync */ + ISB + BX LR + +/****************************************************************************** + * prvMpuDisable is used to set the Enable bit of the MPU Enable Register to 0. + *****************************************************************************/ +.align 4 +.global prvMpuDisable +.type prvMpuDisable, %function +prvMpuDisable: + /* Read the MPU enable register values into R0 */ + MRC p15, #0, R0, c1, c0, #0 + /* Clear out all bits in R0 except for bit 1 */ + BIC R0, R0, #1 + /* Wait for all pending explicit data accesses to complete */ + DSB + /* Write out to the MPU Enable Register */ + MCR p15, #0, R0, c1, c0, #0 + /* Flushes the pipeline and prefetch buffer(s) in the processor. */ + /* Ensures all following instructions are fetched from cache or memory. */ + ISB + BX LR + +.align 4 +.global FreeRTOS_IRQ_Handler +.type FreeRTOS_IRQ_Handler, %function +FreeRTOS_IRQ_Handler: + /* Return to the interrupted instruction. */ + SUB LR, LR, #4 + + /* Save the return state to the IRQ stack */ + SRS SP!, #IRQ_MODE + + /* Push used registers. */ + PUSH {R0-R3, R12} + + /* Increment nesting count. R3 holds the address of ulPortInterruptNesting + for future use. R1 holds the original ulPortInterruptNesting value for + future use. */ + LDR R3, =ulPortInterruptNesting + LDR R1, [R3] + ADD R0, R1, #1 + STR R0, [R3] + + /* Ensure bit 2 of the stack pointer is clear. R2 holds the bit 2 value for + future use. */ + MOV R0, SP + AND R2, R0, #4 + SUB SP, SP, R2 + + /* Call the interrupt handler. */ + PUSH {R0-R3, LR} + BL vApplicationIRQHandler + + /* Restore the registers */ + POP {R0-R3, LR} + ADD SP, SP, R2 + + CPSID i + DSB + ISB + + /* Write to the EOI register. */ + LDR R0, =ulICCEOIR + LDR R2, [R0] + STR R0, [R2] + + /* Restore the old nesting count. */ + STR R1, [R3] + + /* A context switch is never performed if the nesting count is not 0. */ + CMP R1, #0 + BNE exit_without_switch + + /* Did the interrupt request a context switch? R1 holds the address of + ulPortYieldRequired and R0 the value of ulPortYieldRequired for future use. */ + LDR R1, =ulPortYieldRequired + LDR R0, [R1] + CMP R0, #0 + BNE switch_before_exit + +exit_without_switch: + /* No context switch. Restore used registers, LR_irq and SPSR before returning. */ + POP {R0-R3, R12} + CPS #IRQ_MODE + POP {LR} + MSR SPSR_cxsf, LR + POP {LR} + MOVS PC, LR + +switch_before_exit: + /* A context swtich is to be performed. Clear the context switch pending flag. */ + MOV R0, #0 + STR R0, [R1] + + /* Restore used registers, LR-irq and SPSR before saving the context + to the task stack. */ + POP {R0-R3, R12} + CPS #IRQ_MODE + POP {LR} + MSR SPSR_cxsf, LR + POP {LR} + portSAVE_CONTEXT + + /* Call the function that selects the new task to execute. + vTaskSwitchContext() if vTaskSwitchContext() uses LDRD or STRD + instructions, or 8 byte aligned stack allocated data. LR does not need + saving as a new LR will be loaded by portRESTORE_CONTEXT anyway. */ + LDR R0, =vTaskSwitchContext + BLX R0 + + /* Restore the context of, and branch to, the task selected to execute next. */ + portRESTORE_CONTEXT + +.end diff --git a/portable/GCC/ARM_CRx_MPU/portmacro.h b/portable/GCC/ARM_CRx_MPU/portmacro.h new file mode 100644 index 0000000000..cf46ac0c6d --- /dev/null +++ b/portable/GCC/ARM_CRx_MPU/portmacro.h @@ -0,0 +1,661 @@ +/* + * FreeRTOS Kernel V11.0.1 + * Copyright (C) 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef PORTMACRO_H +#define PORTMACRO_H + +/** @brief Functions, Defines, and Structs for use in the ARM_CRx_MPU FreeRTOS-Port + * @file portmacro.h + * @note The settings in this file configure FreeRTOS correctly for the given + * hardware and compiler. These settings should not be altered. + */ + +/** @defgroup MPU Control + * @brief APIs and Variables used to control the onboard MPU. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Include stdint for integer types of specific bit widths */ +#include + +/* ------------------------- FreeRTOS Config Check ------------------------- */ + +/* Include the FreeRTOS Config file first to get the includes being used */ +#include "FreeRTOSConfig.h" + +#ifndef configENABLE_MPU + #error "This port is only usable with configENABLE_MPU set to 1" +#elif( configENABLE_MPU != 1 ) + #error "This port is only usable with configENABLE_MPU set to 1" +#endif /* configENABLE_MPU */ + +#ifndef configUSE_MPU_WRAPPERS_V1 + #define configUSE_MPU_WRAPPERS_V1 0 +#elif( ( configUSE_MPU_WRAPPERS_V1 != 0 ) ) + #error "This port is only usable with configUSE_MPU_WRAPPERS_V1 set to 0" +#endif /* ( configUSE_MPU_WRAPPERS_V1 != 0 ) */ + +#ifndef configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY + #define configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY 1 +#elif( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY != 1 ) + #error This Port is only usable with configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY set to 1 +#endif /* ( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY != 1 ) */ + +/** @brief The size in Bytes that the Privileged System Call Stack should be. + * + * @ingroup MPU Privilege + * + * @note This stack is used when performing FreeRTOS System Calls. The stack pointer + * is changed to use this region when a call to a function is made that goes through + * the MPU Wrappers. + * + * This value should be a size that can be made into a MPU Region. + * + */ +#ifndef configSYSTEM_CALL_STACK_SIZE + #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. +#endif /* configSYSTEM_CALL_STACK_SIZE */ + +#if( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 ) + /* Check the configuration. */ + #if( configMAX_PRIORITIES > 32 ) + #error "configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when " \ + "configMAX_PRIORITIES is less than or equal to 32." \ + "It is very rare that a system requires more than 10 to 15 difference " \ + "priorities as tasks that share a priority will time slice." + #endif /* ( configMAX_PRIORITIES > 32 ) */ + + /** @brief Mark that a task of the current priority is ready for execution + * + * @ingroup Scheduler + * + * @param[in] uxPriority Priority of task that can enter the ready state + * @param[out] uxTopReadyPriority Bitmap of tasks that are in the ready state + */ + #define portRECORD_READY_PRIORITY( uxPriority, uxTopReadyPriority ) \ + ( uxTopReadyPriority ) |= ( 1UL << ( uxPriority ) ) + + /** @brief Mark that a task of the current priority has left the ready state + * + * @ingroup Scheduler + * + * @param[in] uxPriority Priority of task that is leaving the ready state + * @param[out] uxTopReadyPriority Bitmap of tasks that are in the ready state + */ + #define portRESET_READY_PRIORITY( uxPriority, uxTopReadyPriority ) \ + ( uxTopReadyPriority ) &= ~( 1UL << ( uxPriority ) ) + + /** @brief Determine what the highest priority ready task is. + * + * @ingroup Scheduler + * + * @param[out] uxTopReadyPriority Bitmap of tasks that are in the ready state + * @param[out] uxTopPriority The highest priority ready task's priority value. + */ + #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxTopReadyPriority ) \ + uxTopPriority = ( 31UL - ulPortCountLeadingZeros( ( uxTopReadyPriority ) ) ) + +#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ + +#ifndef configSETUP_TICK_INTERRUPT + #error configSETUP_TICK_INTERRUPT() must be defined in FreeRTOSConfig.h to call the function that sets up the tick interrupt. +#endif /* configSETUP_TICK_INTERRUPT */ + +#ifndef configCLEAR_TICK_INTERRUPT + #error configCLEAR_TICK_INTERRUPT must be defined in FreeRTOSConfig.h to clear which ever interrupt was used to generate the tick interrupt. +#endif /* configCLEAR_TICK_INTERRUPT */ + +#ifndef configEOI_ADDRESS + #error Did not define a memrory address to mark the end of an Interrupt +#endif /* configEOI_ADDRESS */ + +#ifdef configUSE_TICKLESS_IDLE + #if( configUSE_TICKLESS_IDLE != 0 ) + #error This port does not yet support tickless idle + #endif /* ( configUSE_TICKLESS_IDLE != 0 ) */ +#endif /* configUSE_TICKLESS_IDLE */ + +/* ------------------------- Port Type Definitions ------------------------- */ + +#include "portmacro_asm.h" + +/** @brief Critical section nesting value to mark the end of a critical section. + * + * @ingroup Critical Sections + * + * @note + * A critical section is exited when the critical section nesting count reaches + * this value. When exiting a critical section IRQs are re-enabled. + */ +#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0x0 ) + +/** @brief Bit value used to mark if the CPU is currently executing in Thumb Mode. + * @ingroup Task Context + */ +#define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 ) + +/** @brief Value used to check if a task's function is a Thumb function. + * @ingroup Task Context + */ +#define portTHUMB_MODE_ADDRESS ( 0x01UL ) + +/** @brief Unsigned Data type equal to the data word operating size of the CPU. + * + * @ingroup Port Interface Specifications + * + * @note + * The FreeRTOS-Kernel needs to be able to use an unsigned type that is + * the most efficient, natural type for the targeted architecture. + */ +typedef uint32_t StackType_t; + +/** @brief Signed Data type equal to the data word operating size of the CPU. + * + * @ingroup Port Interface Specifications + * + * @note + * The FreeRTOS-Kernel needs to be able to use a signed type that is + * the most efficient, natural type for the targeted architecture. + */ +typedef int32_t BaseType_t; + +/** @brief Unsigned Data type equal to the data word operating size of the CPU. + * + * @ingroup Port Interface Specifications + * + * @note + * The FreeRTOS-Kernel needs to be able to use an unsigned type that is + * the most efficient, natural type for the targeted architecture. + */ +typedef uint32_t UBaseType_t; + +/** @brief Integer type used for the Tick Counter + * + * @note + * Use a 32-bit tick type on a 32-bit architecture, so reads of the tick count + * do not need to be guarded with a critical section. + */ +typedef uint32_t TickType_t; + +/** @brief Marks the direction the stack grows on the targeted CPU. + * + * @ingroup Port Interface Specifications + * + */ +#define portSTACK_GROWTH ( -1 ) + +/** @brief Specifies at what number of bytes a stack pointer shall be aligned. + * + * @ingroup Port Interface Specifications + * + */ +#define portBYTE_ALIGNMENT 8U + +/** @brief Task function prototype macro as described on FreeRTOS.org + * + * @ingroup Port Interface Specifications + * + * @note + * These are not required for this port but included in case common demo code + * that uses these macros is used. + */ +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) \ + void vFunction( void * pvParameters ) + +/** @brief Task function prototype macro as described on FreeRTOS.org + * + * @ingroup Port Interface Specifications + * + * @note + * These are not required for this port but included in case common demo code + * that uses these macros is used. + */ +#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) + +/** @brief Wrapper for the no-op ARM Assembly Instruction + * @ingroup Port Interface Specifications + */ +#define portNOP() __asm volatile( "NOP" ) + +/** @brief Wrapper for the Inline GCC Label + * @ingroup Port Interface Specifications + */ +#define portINLINE __inline + +/** @brief Wrapper for the ARM Memory Sync Assembly Instruction + * @ingroup Port Interface Specifications + */ +#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" ) + +/** @brief Defines if the system tick count can be accessed atomically + * + * @ingroup System Clock + */ +#define portTICK_TYPE_IS_ATOMIC 1 + +/** @brief Define the number of miliseconds between system ticks. + * + * @ingroup System Clock + */ +#define portTICK_PERIOD_MS ( ( TickType_t ) 1000UL / configTICK_RATE_HZ ) + +/** @brief Define the larges possible delay value for a task. + * + * @ingroup System Clock + */ +#define portMAX_DELAY ( TickType_t ) 0xFFFFFFFFUL + +/* --------------------------- Port Assembly Handlers --------------------------- */ + +/** @brief Assembly FreeRTOS Supervisor Call Handler */ +void FreeRTOS_SVC_Handler( void ); + +/** @brief Assembly FreeRTOS Interrupt Handler */ +void FreeRTOS_IRQ_Handler( void ); + +/** @brief Assembly FreeRTOS IRQ Handler + * + * @ingroup Scheduler + * + * @note This must be installed as the handler for whichever peripheral is used + * to generate the RTOS tick if using a VIM. */ + +/** @brief Decleration of the FreeRTOS Tick Handler. + * + * @ingroup Scheduler + * + * @note This must be installed as the handler for whichever peripheral is used + * to generate the RTOS tick if using a VIM. */ +void FreeRTOS_Tick_Handler( void ) __attribute__( ( weak, interrupt( "IRQ" ) ) ); + +/** @brief Pend a context switch inside of the FreeRTOS-Kernel. + * @ingroup Scheduler + * @note This is used to raise a pending IRQ on a board that supplies a VIM. + */ +void vPortYieldWithinAPI( void ) __attribute__( ( weak, interrupt( "IRQ" ) ) ); + +/* --------------------------- Port Assembly Functions --------------------------- */ + +/** @brief Make a Supervisor Call to swap the currently running task out. + * + * @ingroup Scheduler + * @note The FreeRTOS-Kernel needs a method to swap the current task that is + * running. The FreeRTOS-Port needs to ensure that when this happens any + * hardware specific values related to the current task’s context are properly + * saved. A properly saved context can be restored to allow execution of the + * task as if it was not interrupted. + */ +void vPortYield( void ); + +/** @brief Raise a Supervisor Call to swap the currently running task out. */ +#define portYIELD() vPortYield() + +/** @brief Disable IRQs then increment the critical nesting count. + * @ingroup Critical Section + */ +void vPortEnterCritical( void ); + +/** @brief Enter a Critical Section inside of the FreeRTOS-Kernel */ +#define portENTER_CRITICAL() vPortEnterCritical() + +/** @brief Enable IRQs and decrement the critical nesting count. + * @ingroup Critical Section + */ +void vPortExitCritical( void ); + +/** @brief Exit a Critical Section inside of the FreeRTOS-Kernel. + * @ingroup Critical Section + */ +#define portEXIT_CRITICAL() vPortExitCritical() + +/** @brief Set the IRQ bit of the CPSR high, enabling IRQs. + * @ingroup Interrupt Management + */ +void vPortEnableInterrupts( void ); + +/** @brief Enable Interrupts by setting the IRQ allowed flag on the CPU + * @ingroup Interrupt Management + */ +#define portENABLE_INTERRUPTS() vPortEnableInterrupts() + +/** @brief Set the IRQ bit of the CPSR low, disabling IRQs. + * @ingroup Interrupt Management + */ +void vPortDisableInterrupts( void ); + +/** @brief Enable Interrupts by lowering the IRQ allowed flag on the CPU. + * @ingroup Interrupt Management + */ +#define portDISABLE_INTERRUPTS() vPortDisableInterrupts() + +/** @brief Exit the FreeRTOS-Kernel, restoring the task's settings. + * + * @ingroup Port Privilege + * + * @return void + */ +void vPortSystemCallExit( void ); + +/** @brief Load the context of the first task. + * + * @ingroup Scheduler + * + * @note This is an assembly function implemented in portASM.s, it loads the context + * of the first task from pxCurrentTCB. + */ +void vPortStartFirstTask( void ); + +/** @brief Enable the onboard MPU + * + * @ingroup MPU Control + * + * @return void + */ +void prvMpuEnable( void ); + +/** @brief Disable the onboard MPU + * + * @ingroup MPU Control + * + * @return VOID + */ +void prvMpuDisable( void ); + +/** @brief Assembly routine to set permissions for an MPU Region. + * + * @ingroup MPU Control + * + * @param[in] regionNumber The MPU Region Number to change permissions for + * @param[in] baseAddress The base address of the MPU Region + * @param[in] regionSize The number of bytes to make the MPU Region + * @param[in] regionPermissions The permissions to assign to the MPU Region + * + * @note This is an Assembly Function implemented in portASM.S. + * This is meant as a purely internal function that performs a raw write of the + * provided values to the relevant MPU Registers. The inputs to this function + * are checked internally before it is called in the port.c file. + */ +void prvMpuSetRegion( + uint32_t regionNumber, + uint32_t baseAddress, + uint32_t regionSize, + uint32_t regionPermissions +); + +/* ----------------------------- Port C Functions ----------------------------- */ + +/** @brief Checks whether or not the processor is privileged. + * + * @ingroup Port Privilege + * + * @note + * The Privilege level is determined by checking if bits [4:0] of + * the callers Current Program Status Register are in USER_MODE, 0x10 + * + * @return + * 0 If the CPSR Mode Bits are set to 0x10 + * 1 If the CPSR Mode Bits are set to 0x11-0x11F + * + */ +BaseType_t xPortIsPrivileged( void ); + +/** @brief Check if the CPU is currently in a privileged operating mode + * + * @ingroup Port Privilege + * + * @return + * 1 If the processor is privileged + * 0 If the processor is not privileged + * + */ +#define portIS_PRIVILEGED() xPortIsPrivileged() + +/** @brief Check if ulTaskFlags has portTASK_IS_PRIVILEGED_FLAG. + * + * @ingroup Port Privilege + * + * @note + * As this loads pxCurrentTCB to determine if the task's ulTaskFlags is privileged + * or not, this function can return a different value than xPortIsPrivileged. + * + * @return + * 0 If pxCurrentTCB's !( ulTaskFlags && portTASK_IS_PRIVILEGED_FLAG ) + * 1 If pxCurrentTCB's ( ulTaskFlags && portTASK_IS_PRIVILEGED_FLAG ) + */ +BaseType_t xPortIsTaskPrivileged( void ); + +/** @brief Checks whether or not the currently running task is privileged. + * + * @ingroup Port Privilege + * + * @return + * pdTRUE if the calling task is privileged + * pdFALSE if the calling task is not privileged + */ +#define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged() + +/** @brief Default return to catch tasks incorrectly exiting their functions. */ +void prvTaskExitError( void ); + +/** @brief User provided task return function. + * + * @ingroup Task Context + * + * @note Let the user override the pre-loading of the initial LR with + * the address of prvTaskExitError() in case it messes up unwinding of + * the stack in the debugger. + */ +#ifdef configTASK_RETURN_ADDRESS + #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS +#else + #define configTASK_RETURN_ADDRESS prvTaskExitError +#endif /* configTASK_RETURN_ADDRESS */ + +/** @brief Address of function a task should execute if it exits its assigned function. + * + * @ingroup Task Context + * + * @note If configTASK_RETURN_ADDRESS is not defined this value shall be set to + * prvTaskExitError(). + */ +#define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS + +/** @brief The lowest priority interrupt available on the CPU */ +#define portLOWEST_INTERRUPT_PRIORITY \ + ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL ) + +/** @brief The lowest priority interrupt that is usable by the system. + * @ingroup Interrupt Management + */ +#define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL ) + +/** @brief Returns the number of leading zeros in a 32 bit variable. + * + * @param[in] ulBitmap 32 Bit long number to count zeros of. + * + * @return The number of leading zeros ulBitmap has. + */ +UBaseType_t ulPortCountLeadingZeros( UBaseType_t ulBitmap ); + +/* ------------------------- Port MPU Definitions ------------------------- */ + +/** @brief Mark that this port utilizes the onboard ARM MPU. + * + * @ingroup MPU Control + * + * @note The structures and methods of manipulating the MPU are contained + * within the port layer. Fills the xMPUSettings structure with the memory + * region information contained in xRegions. + * + */ +#define portUSING_MPU_WRAPPERS 1 + +/** @brief Used to mark if a task should be created as a privileged task. + * + * @ingroup Task Context + * @ingroup MPU Control + * + * @note This is done by performing a bitwise OR of this value and the task priority. + * For example, to create a privileged task at priority 2 the uxPriority + * parameter should be set to ( 2 | portPRIVILEGE_BIT ). + */ +#define portPRIVILEGE_BIT ( 0x80000000UL ) + +/** @brief Mark that a Task has Stack Frame Padding + * + * @ingroup Task Context + * + * @note Flags used for xMPU_SETTINGS.ulTaskFlags member to mark the stack frame is + * padded. */ +#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) + +#define portSYSTEM_CALL_STACK_SIZE configSYSTEM_CALL_STACK_SIZE + +/** @brief Structure to hold the MPU Register Values + * @struct xMPU_REGION_REGISTERS + * + * @ingroup MPU Control + * + * NOTE: Do not modify this structure. The ordering of this struct MUST + * line up with the ordering explained in portRESTORE_CONTEXT. + */ +typedef struct MPU_REGION_REGISTERS +{ + /** @brief Member used to hold the MPU register value for the Region Size + * @struct xMPU_REGION_REGISTERS + * @ingroup MPU Control + */ + uint32_t ulRegionSize; + + /** @brief Member used to hold the MPU register value for the Region Attributes + * @struct xMPU_REGION_REGISTERS + * @ingroup MPU Control + */ + uint32_t ulRegionAttribute; + + /** @brief Member used to hold the MPU register value for the Region Base Address. + * @struct xMPU_REGION_REGISTERS + * @ingroup MPU Control + */ + uint32_t ulRegionBaseAddress; +} xMPU_REGION_REGISTERS; + +/** @brief Structure to hold per-task System Call Stack information + * @struct xSYSTEM_CALL_STACK_INFO + * + * @ingroup Port Privilege + * + * NOTE: Do not modify this structure. The ordering of this structure is expected to be + * this way in the assembly code of the port. + */ +typedef struct SYSTEM_CALL_STACK_INFO +{ + /** @brief Stack Pointer of the task when it made a FreeRTOS System Call + * @note This will point to the start of ulSystemCallStackBuffer[] + * @struct xSYSTEM_CALL_STACK_INFO + * @ingroup Port Privilege + */ + uint32_t * pulTaskStackPointer; + + /** @brief Link Register of the task when it made a FreeRTOS System Call + * @struct xSYSTEM_CALL_STACK_INFO + * @ingroup Port Privilege + */ + uint32_t * pulLinkRegisterAtSystemCallEntry; + + /** @brief Pre-Set Stack Pointer to use when making a FreeRTOS System Call + * @struct xSYSTEM_CALL_STACK_INFO + * @ingroup Port Privilege + */ + uint32_t * pulSystemCallStackPointer; + + /** @brief Pre-Set Link Register to exit a FreeRTOS System Call + * @note This value is set in pxPortInitialiseStack to ensure after making + * a FreeRTOS System Call that the last LR jump is to vPortSystemCallExit() + * @struct xSYSTEM_CALL_STACK_INFO + * @ingroup Port Privilege + */ + void * pulSystemCallLinkRegister; + + /** @brief Buffer to be used when performing a FreeRTOS System Call + * @struct xSYSTEM_CALL_STACK_INFO + * @ingroup Port Privilege + */ + uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; +} xSYSTEM_CALL_STACK_INFO; + +/** @brief Per-Task MPU Settings structure stored in the TCB + * @struct xMPU_SETTINGS + * + * @ingroup MPU Control + * @ingroup Task Context + * @ingroup Port Privilege + * + * NOTE: Do not modify this structure. The ordering of this structure is expected to be + * this way in the assembly code of the port. + */ +typedef struct MPU_SETTINGS +{ + /** @brief Array of Per-Task MPU Register Values. Loaded on Task Context Restore + * @struct xMPU_SETTINGS + * + * @ingroup Task Context + * @ingroup Port Privilege + * @ingroup MPU Control + */ + xMPU_REGION_REGISTERS xRegion[ portTOTAL_NUM_REGIONS_IN_TCB ]; + + /** @brief Buffer that holds a Task's Context when being swapped out + * @struct xMPU_SETTINGS + * @ingroup Task Context + */ + uint32_t ulContext[ MAX_CONTEXT_SIZE ]; + + /** @brief Variable to hold FreeRTOS Privilege Settings + * @struct xMPU_SETTINGS + * @ingroup Task Context + * @ingroup MPU Control + */ + uint32_t ulTaskFlags; + + /** @brief System Call Info structure that is stored in the TCB + * @struct xMPU_SETTINGS + * @ingroup Task Context + * @ingroup Port Privilege + */ + xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; +} xMPU_SETTINGS; + +#ifdef __cplusplus +} /* extern C */ +#endif + +#endif /* PORTMACRO_H */ diff --git a/portable/GCC/ARM_CRx_MPU/portmacro_asm.h b/portable/GCC/ARM_CRx_MPU/portmacro_asm.h new file mode 100644 index 0000000000..c2d0c02ef2 --- /dev/null +++ b/portable/GCC/ARM_CRx_MPU/portmacro_asm.h @@ -0,0 +1,539 @@ +/* + * FreeRTOS Kernel V10.6.0 + * Copyright (C) 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ +#ifndef PORTMACRO_ASM_H +#define PORTMACRO_ASM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "FreeRTOSConfig.h" + +#ifndef configTOTAL_MPU_REGIONS + #error "Set configTOTAL_MPU_REGIONS to the humber of MPU regions in FreeRTOSConfig.h" +#endif /* configTOTAL_MPU_REGIONS */ + +#if( configTOTAL_MPU_REGIONS == 8 ) + #define portMPU_TOTAL_REGIONS ( 8UL ) +#elif( configTOTAL_MPU_REGIONS == 12 ) + #define portMPU_TOTAL_REGIONS ( 12UL ) +#elif( configTOTAL_MPU_REGIONS == 16 ) + #define portMPU_TOTAL_REGIONS ( 16UL ) +#else + #error Please specify the number of MPU regions available for your microcontroller +#endif + +/** On the ArmV7-R Architecture the Operating mode of the Processor is set using + * the Current Program Status and Control Register (CPSR) Mode bits, [4:0] + * the only registers banked between modes are the CPSR, Stack Pointer (R13), + * and the Link Register (R14). FIQ mode also banks the GPRs R8-R12 + * Of note, the only mode not "Privileged" is User Mode + * + * Additional information about the Processor Modes can be found here: + * https://developer.arm.com/documentation/ddi0406/cb/System-Level-Architecture/The-System-Level-Programmers--Model/ARM-processor-modes-and-ARM-core-registers/ARM-processor-modes?lang=en + * + * */ + +/** @brief CPSR Mode bit field value for User Mode + * @ingroup Port Privilege + */ +#define USER_MODE 0x10U + +/** @brief CPSR Mode bit field value for Fast Interrupt Handler (FIQ) Mode + * @ingroup Port Privilege + */ +#define FIQ_MODE 0x11U + +/** @brief CPSR Mode bit field value for Interrupt Handler (IRQ) Mode + * @ingroup Port Privilege + */ +#define IRQ_MODE 0x12U + +/** @brief CPSR Mode bit field value for Supervisor (SVC) Mode + * @ingroup Port Privilege + */ +#define SVC_MODE 0x13U + +/** @brief CPSR Mode bit field value for Monitor (MON) Mode + * @ingroup Port Privilege + */ +#define MON_MODE 0x16U + +/** @brief CPSR Mode bit field value for Abort (ABT) Mode + * @ingroup Port Privilege + */ +#define ABT_MODE 0x17U + +/** @brief CPSR Mode bit field value for Hypervisor (HYP) Mode + * @ingroup Port Privilege + */ +#define HYP_MODE 0x1AU + +/** @brief CPSR Mode bit field value for Undefined (UND) Mode + * @ingroup Port Privilege + */ +#define UND_MODE 0x1BU + +/** @brief CPSR Mode bit field value for System (SYS) Mode + * @ingroup Port Privilege + */ +#define SYS_MODE 0x1FU + +/** @brief Mark that a Task Stack has padding values added + * @ingroup Task Context + */ +#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) + +/** @brief Flag uses to mark that a FreeRTOS Task is privileged + * @ingroup Port Privilege + */ +#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) + +/** @brief SVC Number to use when requesting a context swap. + * @ingroup Scheduler + */ +#define portSVC_YIELD 0x0100 + +/** @brief SVC Number to use when exiting a FreeRTOS System Call + * @ingroup MPU Control + */ +#define portSVC_SYSTEM_CALL_EXIT 0x0104 + +/** + * @addtogroup MPU Control + * @note The Region Access Control Register is used to set MPU Region Settings. + * Further information about this register can be found in Arm's documentation + * https://developer.arm.com/documentation/ddi0363/g/System-Control/Register-descriptions/c6--MPU-memory-region-programming-registers + * + */ + +/* MPU Sub Region region */ +#define portMPU_SUBREGION_0_DISABLE ( 0x1UL << 8UL ) +#define portMPU_SUBREGION_1_DISABLE ( 0x1UL << 9UL ) +#define portMPU_SUBREGION_2_DISABLE ( 0x1UL << 10UL ) +#define portMPU_SUBREGION_3_DISABLE ( 0x1UL << 11UL ) +#define portMPU_SUBREGION_4_DISABLE ( 0x1UL << 12UL ) +#define portMPU_SUBREGION_5_DISABLE ( 0x1UL << 13UL ) +#define portMPU_SUBREGION_6_DISABLE ( 0x1UL << 14UL ) +#define portMPU_SUBREGION_7_DISABLE ( 0x1UL << 15UL ) + +#define MPU_REGION_COUNT_OFFSET 8U +#define MPU_REGION_COUNT_MASK ( 0xFFUL << MPU_REGION_COUNT_OFFSET ) + +#define portSTACK_GUARD \ + portMPU_SUBREGION_0_DISABLE | portMPU_SUBREGION_1_DISABLE | \ + portMPU_SUBREGION_2_DISABLE | portMPU_SUBREGION_3_DISABLE | \ + portMPU_SUBREGION_4_DISABLE | portMPU_SUBREGION_5_DISABLE | \ + portMPU_SUBREGION_6_DISABLE | portMPU_SUBREGION_7_DISABLE + +#define portUND_STACK_GUARD portSTACK_GUARD & ~portMPU_SUBREGION_0_DISABLE +#define portSVC_STACK_GUARD portSTACK_GUARD & ~portMPU_SUBREGION_1_DISABLE + +#define portFIQ_STACK_GUARD \ + portSTACK_GUARD & ~portMPU_SUBREGION_2_DISABLE | ~portMPU_SUBREGION_3_DISABLE + +#define portABT_STACK_GUARD \ + portSTACK_GUARD & ~portMPU_SUBREGION_4_DISABLE | ~portMPU_SUBREGION_5_DISABLE + +#define portIRQ_STACK_GUARD \ + ( ( portSTACK_GUARD ) & ( ~portMPU_SUBREGION_7_DISABLE ) & \ + ( ~portMPU_SUBREGION_7_DISABLE ) ) + +/* Default MPU regions */ +#define portFIRST_CONFIGURABLE_REGION ( 0 ) +#define portLAST_CONFIGURABLE_REGION ( portMPU_TOTAL_REGIONS - 6UL ) +#define portSTACK_REGION ( portMPU_TOTAL_REGIONS - 5UL ) +#define portGENERAL_PERIPHERALS_REGION ( portMPU_TOTAL_REGIONS - 4UL ) +#define portUNPRIVILEGED_FLASH_REGION ( portMPU_TOTAL_REGIONS - 3UL ) +#define portPRIVILEGED_FLASH_REGION ( portMPU_TOTAL_REGIONS - 2UL ) +#define portPRIVILEGED_RAM_REGION ( portMPU_TOTAL_REGIONS - 1UL ) +#define portNUM_CONFIGURABLE_REGIONS \ + ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1UL ) +/* Plus one to make space for the stack region*/ +#define portTOTAL_NUM_REGIONS_IN_TCB ( portNUM_CONFIGURABLE_REGIONS + 1UL ) + +/* MPU region sizes */ +#define portMPU_SIZE_32B ( 0x04UL << 1UL ) +#define portMPU_SIZE_64B ( 0x05UL << 1UL ) +#define portMPU_SIZE_128B ( 0x06UL << 1UL ) +#define portMPU_SIZE_256B ( 0x07UL << 1UL ) +#define portMPU_SIZE_512B ( 0x08UL << 1UL ) +#define portMPU_SIZE_1KB ( 0x09UL << 1UL ) +#define portMPU_SIZE_2KB ( 0x0AUL << 1UL ) +#define portMPU_SIZE_4KB ( 0x0BUL << 1UL ) +#define portMPU_SIZE_8KB ( 0x0CUL << 1UL ) +#define portMPU_SIZE_16KB ( 0x0DUL << 1UL ) +#define portMPU_SIZE_32KB ( 0x0EUL << 1UL ) +#define portMPU_SIZE_64KB ( 0x0FUL << 1UL ) +#define portMPU_SIZE_128KB ( 0x10UL << 1UL ) +#define portMPU_SIZE_256KB ( 0x11UL << 1UL ) +#define portMPU_SIZE_512KB ( 0x12UL << 1UL ) +#define portMPU_SIZE_1MB ( 0x13UL << 1UL ) +#define portMPU_SIZE_2MB ( 0x14UL << 1UL ) +#define portMPU_SIZE_4MB ( 0x15UL << 1UL ) +#define portMPU_SIZE_8MB ( 0x16UL << 1UL ) +#define portMPU_SIZE_16MB ( 0x17UL << 1UL ) +#define portMPU_SIZE_32MB ( 0x18UL << 1UL ) +#define portMPU_SIZE_64MB ( 0x19UL << 1UL ) +#define portMPU_SIZE_128MB ( 0x1AUL << 1UL ) +#define portMPU_SIZE_256MB ( 0x1BUL << 1UL ) +#define portMPU_SIZE_512MB ( 0x1CUL << 1UL ) +#define portMPU_SIZE_1GB ( 0x1DUL << 1UL ) +#define portMPU_SIZE_2GB ( 0x1EUL << 1UL ) +#define portMPU_SIZE_4GB ( 0x1FUL << 1UL ) + +/** @brief Used to mark if a task should be created as a privileged task. + * + * @ingroup Task Context + * @ingroup MPU Control + * + * @note This is done by performing a bitwise OR of this value and the task priority. + * For example, to create a privileged task at priority 2 the uxPriority + * parameter should be set to ( 2 | portPRIVILEGE_BIT ). + */ +#define portPRIVILEGE_BIT ( 0x80000000UL ) + +/** @brief MPU Setting for a Strongly Ordered Memory Region + * + * @ingroup MPU Control + * + */ +#define portMPU_REGION_STRONGLY_ORDERED ( 0x00UL ) + +/** @brief MPU Setting for a Strongly Ordered Memory Region + * + * @ingroup MPU Control + * + */ +#define portMPU_REGION_DEVICE ( 0x01UL ) + +/** @brief MPU Setting for a Strongly Ordered Memory Region + * + * @ingroup MPU Control + * + */ +#define portMPU_REGION_CACHEABLE_BUFFERABLE ( 0x03UL ) + +/** @brief MPU Setting for a Strongly Ordered Memory Region + * + * @ingroup MPU Control + * + */ +#define portMPU_REGION_EXECUTE_NEVER ( 0x01UL << 12UL ) + +/** @brief MPU Setting for a Strongly Ordered and Shareable Memory Region + * + * @ingroup MPU Control + * + */ +#define portMPU_STRONGLYORDERED_SHAREABLE ( 0x0000UL ) + +/** @brief MPU Setting for a Device and Shareable Memory Region + * + * @ingroup MPU Control + * + */ +#define portMPU_DEVICE_SHAREABLE ( 0x0001UL ) + +/** @brief MPU Setting for a Device and Non-Shareable Memory Region + * + * @ingroup MPU Control + * + */ +#define portMPU_DEVICE_NONSHAREABLE ( 0x0010UL ) + +/** @brief MPU Setting for a Normal Outer & Inner Write-Through, No Write Allocate & Non + * Shared + * + * @ingroup MPU Control + * + */ +#define portMPU_NORMAL_OIWTNOWA_NONSHARED ( 0x0002UL ) + +/** @brief MPU Setting for a Normal Outer & Inner Write-Back, No Write Allocate & Non + * Shared + * + * @ingroup MPU Control + * + */ +#define portMPU_NORMAL_OIWBNOWA_NONSHARED ( 0x0003UL ) + +/** @brief MPU Setting for a Normal Outer & Inner Write-Through, no Write Allocate & + * Shared + * + * @ingroup MPU Control + * + */ +#define portMPU_NORMAL_OIWTNOWA_SHARED ( 0x0006UL ) + +/** @brief MPU Setting for a Normal Outer & Inner Write-back, no Write Allocate & Shared + * + * @ingroup MPU Control + * + */ +#define portMPU_NORMAL_OIWBNOWA_SHARED ( 0x0007UL ) + +/** @brief MPU Setting for a Normal Outer & Inner Non-Cacheable & Non Shared + * + * @ingroup MPU Control + * + */ +#define portMPU_NORMAL_OINC_NONSHARED ( 0x0008UL ) + +/** @brief MPU Setting for a Normal Outer & Inner Write-Back, Write Allocate & Non Shared + * + * @ingroup MPU Control + * + */ +#define portMPU_NORMAL_OIWBWA_NONSHARED ( 0x000BUL ) + +/** @brief MPU Setting for a Normal Outer & Inner Non-Cacheable & Shared + * + * @ingroup MPU Control + * + */ +#define portMPU_NORMAL_OINC_SHARED ( 0x000CUL ) + +/** @brief MPU Setting for a Normal Outer & Inner Write-Back, Write Allocate & Shared + * + * @ingroup MPU Control + * + */ +#define portMPU_NORMAL_OIWBWA_SHARED ( 0x000FUL ) + +/** @brief MPU_CTRL value for: No Access and No Execute + * + * @ingroup MPU Control + * + * @brief No Access in a Privileged Operating Mode + * No Access in User Mode + * Cannot Execute Code from this region + */ +#define portMPU_PRIV_NA_USER_NA_NOEXEC ( 0x1000UL ) + +/** @brief MPU_CTRL value for Privileged Read and Exec + * + * @ingroup MPU Control + * + * @note Read Only Access in Privileged Operating Modes. + * No Read/Write Access in User Mode + * Allowed to Execute Code from this region + */ +#define portMPU_PRIV_RO_USER_NA_EXEC ( 0x0500UL ) + +/** @brief MPU_CTRL value for Privileged Read, Write, and Exec + * + * @ingroup MPU Control + * + * Read/Write in a Privileged Operating Mode + * No Access in User Mode + * Allowed to Execute Code from this region + */ +#define portMPU_PRIV_RW_USER_NA_EXEC ( 0x0100UL ) + +/** @brief MPU_CTRL value for Read Only and Execute + * + * @ingroup MPU Control + * + * @note Read Only in a Privileged Operating Mode + * Read Only in User Mode + * Allowed to Execute Code from this region + * */ +#define portMPU_PRIV_RO_USER_RO_EXEC ( 0x0600UL ) + +/** @brief MPU_CTRL value for: Read, Execute, and Privileged Write + * + * @ingroup MPU Control + * + * @note Read/Write in a Privileged Operating Mode + * Read Only in User Mode + * Allowed to Execute Code from this region + */ +#define portMPU_PRIV_RW_USER_RO_EXEC ( 0x0200UL ) + +/** @brief MPU_CTRL value for: Read, Write, and Execute + * + * @ingroup MPU Control + * + * @note Read/Write in a Privileged Operating Mode + * Read/write in User Mode + * Allowed to Execute Code from this region + */ +#define portMPU_PRIV_RW_USER_RW_EXEC ( 0x0300UL ) + +/** @brief MPU_CTRL value for: Privileged Read, Write Only, no Execute + * + * @ingroup MPU Control + * + * @note Read/Write in a Privileged Operating Mode + * No Access in User Mode + * Cannot Execute Code from this region + */ +#define portMPU_PRIV_RW_USER_NA_NOEXEC ( 0x1100UL ) + +/** @brief MPU_CTRL value for: All Read, Privileged Write, no Execute + * + * @ingroup MPU Control + * + * Read/Write in a Privileged Operating Mode + * Read Only in User Mode + * Cannot Execute Code from this region + */ +#define portMPU_PRIV_RW_USER_RO_NOEXEC ( 0x1200UL ) + +/** @brief MPU_CTRL value for: Read, Write, no Execute + * + * @ingroup MPU Control + * + * @note Read/Write in a Privileged Operating Mode + * Read/Write in User Mode + * Cannot Execute Code from this region + */ +#define portMPU_PRIV_RW_USER_RW_NOEXEC ( 0x1300UL ) + +/** @brief MPU_CTRL value for: Privileged Read Only, No Execute + * + * @ingroup MPU Control + * + * @note Read Only in a Privileged Operating Mode + * No Access in User Mode + * Cannot Execute Code from this region + */ +#define portMPU_PRIV_RO_USER_NA_NOEXEC ( 0x1500UL ) + +/** @brief MPU_CTRL value for: Read Only, No Execute + * + * @ingroup MPU Control + * + * @note Read Only in a Privileged Operating Mode + * Read Only in User Mode + * Cannot Execute Code from this region + */ +#define portMPU_PRIV_RO_USER_RO_NOEXEC ( 0x1600UL ) + +/** @brief MPU_CTRL value to enable an MPU Region + * @ingroup MPU Control + */ +#define portMPU_REGION_ENABLE ( 0x01UL ) + +/** @brief The lowest priority interrupt that is usable by the system */ +#define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL ) + +/** This following section is used to create the proper size for the ulContext array. + * This array is where all registers related to a task's context are saved. + * The size of this array will depend on if the system is using an integrated + * Floating Point Unit (FPU) or not. If we are using the FPU we must save the + * Floating Point Status and Control Register (FPSCR), + * and the Floating Point Registers (FPRs). The FPSCR holds the conditional bits + * used for floating point calculations. The FPRs hold the actual floating point bits. + * The remainder of a task's context consists of the General Purpose Registers (GPRs). + * General Purpose Registers are used to manipulate almost all variables. + * The Current Program Status and Control Register, which holds the operating mode + * and bits that correspond to any conditional checks, such as if statements. + * And the Critical Nesting Depth of the task. + * + * + * For more information about the FPU, FPSCR, and FPRs please reference ARM's website: + * https://developer.arm.com/documentation/den0042/a/Floating-Point + * + * Additional information related to the Cortex R4-F's FPU Implementation: + * https://developer.arm.com/documentation/ddi0363/e/fpu-programmer-s-model + * + * Additional information related to the Cortex R5-F's FPU Implementation: + * https://developer.arm.com/documentation/ddi0460/d/FPU-Programmers-Model + * + * Additional information related to the ArmV7-R CPSR + * https://developer.arm.com/documentation/ddi0406/cb/Application-Level-Architecture/Application-Level-Programmers--Model/The-Application-Program-Status-Register--APSR-?lang=en + * + * Additional information related to the GPRs: + * https://developer.arm.com/documentation/ddi0406/cb/System-Level-Architecture/The-System-Level-Programmers--Model/ARM-processor-modes-and-ARM-core-registers/ARM-core-registers?lang=en + * + */ + +/** @brief The length in ulContext for the General Purpose Registers in bytes + * @note There are 13 GPRs, R0-R12 each is 32 bits, so 13 registers * 4 Bytes each + */ +#define portGPR_LENGTH ( 13U * 4U ) + +/** @brief The length in ulContext for all the registers in a context + * @note There are the 13 GPRs, the Stack Pointer, and the Link Register + */ +#define portREGISTER_CONTEXT_LENGTH ( portGPR_LENGTH + ( 2 * 4U ) ) + +/** If you KNOW that your system will not utilize the FPU in any capacity + * you can set portENABLE_FPU to 0, which will reduce the per-task RAM usage + * by ( 32 FPRs + 32 bit FPSCR ) * 4 bytes per register = 132, or 0x84, Bytes Per Task + * BE CAREFUL DISABLING THIS: Certain APIs will try and optimize themselves + * by using the FPRs. If the FPU context is not saved and this happens it could be + * exceedingly difficult to debug why a strcpy() or other similar function + * seems to randomly fail. + */ +#ifndef configENABLE_FPU + #define configENABLE_FPU 0 +#endif + +/** @brief Mark if the Floating Point Registers will be saved. + * @ingroup Task Context + * @note When using the FPU, we must save additional registers into the task's context + * These consist of the Floating Point Status and Control Register (FPSCR), + * As well as the Floating Point Registers (FPRs) + * Task Context which is stored in ulContext in order, consists of: + * ulContext[ 0 ]: Critical Nesting Count: ulCriticalNesting + * ulContext[ 1 ]: Floating Point Status and Control Register + * ulContext[ 2 - 33 ]: Floating Point Registers: S0-S31 + * ulContext[ 34 - 46 ]: General Purpose Registers: R0-R12 + * ulContext[ 47 ]: Stack Pointer + * ulContext[ 48 ]: Link Register + * ulContext[ 49 ]: Program Counter + * ulContext[ 50 ]: Current Program Status and Control Register + * ulContext[ 51 ]: Supervisor Mode SRS PC Scratch Space + * ulContext[ 52 ]: Supervisor Mode SRS CPSR Scratch Space + */ +#define portENABLE_FPU configENABLE_FPU + +#if( portENABLE_FPU == 1 ) + /** @brief Length of a Task's Register Context when using an FPU. */ + #define MAX_CONTEXT_SIZE 52U +#else + /** @brief Length of a Task's Register Context when not using an FPU. */ + #define MAX_CONTEXT_SIZE 20U +#endif +/** @brief Numerical offset from the start of a TCB to xSystemCallStackInfo + * @note In the exception handlers it is necessary to load this variable from the TCB. + * This provides an easy way for the exception handlers to get this structure. + * The numerical value here should be equal to: + * sizeof( xRegion ) + sizeof( ulContext ) + sizeof( ulTaskFlags) + */ +#define portSYSTEM_CALL_INFO_OFFSET \ + ( ( ( portTOTAL_NUM_REGIONS_IN_TCB * 3U ) + ( MAX_CONTEXT_SIZE ) + 1 ) * 4U ) + +#ifdef __cplusplus +} /* extern C */ +#endif + +#endif /* PORTMACRO_ASM_H */ From d8b08270d0101a552455a18a69c2d3614f77db13 Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Wed, 27 Dec 2023 19:39:38 -0500 Subject: [PATCH 02/51] Add support for the port in the CMakeLists.txt files --- CMakeLists.txt | 1 + portable/CMakeLists.txt | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5323ec19bf..bbe9b7219b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,6 +85,7 @@ if(NOT FREERTOS_PORT) " GCC_ARM_CM85_NTZ_NONSECURE - Compiler: GCC Target: ARM Cortex-M85 non-trustzone non-secure\n" " GCC_ARM_CM85_TFM - Compiler: GCC Target: ARM Cortex-M85 non-secure for TF-M\n" " GCC_ARM_CR5 - Compiler: GCC Target: ARM Cortex-R5\n" + " GCC_ARM_CRX_MPU - Compiler: GCC Target: ARM Cortex-Rx with MPU\n" " GCC_ARM_CRX_NOGIC - Compiler: GCC Target: ARM Cortex-Rx no GIC\n" " GCC_ARM7_AT91FR40008 - Compiler: GCC Target: ARM7 Atmel AT91R40008\n" " GCC_ARM7_AT91SAM7S - Compiler: GCC Target: ARM7 Atmel AT91SAM7S\n" diff --git a/portable/CMakeLists.txt b/portable/CMakeLists.txt index b84b3018bb..861f50ef3b 100644 --- a/portable/CMakeLists.txt +++ b/portable/CMakeLists.txt @@ -193,6 +193,11 @@ add_library(freertos_kernel_port STATIC GCC/ARM_CR5/port.c GCC/ARM_CR5/portASM.S> + $<$: + GCC/ARM_CRx_MPU/port.c + GCC/ARM_CRx_MPU/portASM.S + GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S> + $<$: GCC/ARM_CRx_No_GIC/port.c GCC/ARM_CRx_No_GIC/portASM.S> @@ -806,6 +811,7 @@ target_include_directories(freertos_kernel_port PUBLIC # ARMv7-R ports for GCC $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CR5> + $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CRx_MPU> $<$:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CRx_No_GIC> # ARMv4T ARM7TDMI ports for GCC From a33a6ddc76422ab4e0b485e968e03cfa49e5648a Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Wed, 27 Dec 2023 20:31:08 -0500 Subject: [PATCH 03/51] Add new spell check words --- .github/.cSpellWords.txt | 440 ++++++++++++++++++++------------------- 1 file changed, 222 insertions(+), 218 deletions(-) diff --git a/.github/.cSpellWords.txt b/.github/.cSpellWords.txt index 9e0f6560b4..69691e85e3 100644 --- a/.github/.cSpellWords.txt +++ b/.github/.cSpellWords.txt @@ -9,14 +9,9 @@ ACCBH ACCBL ACCBU ACLK -acpa ACPA -acpc ACPC -addi -addiu ADTRG -aeevt AEEVT AERR AIRCR @@ -28,44 +23,31 @@ APIC APROCFREQ APSR ARMCM -Armv ARMVFP ASTRINGZ -aswtrg ASWTRG -Ateml ATMEGA -Atmel ATMEL -atomatic ATPASTE AVRDX +Armv +Ateml +Atmel BANDL -bcpb BCPB -bcpc BCPC -beevt BEEVT BERR -bfextu -Biagioni -bics BISR BODIEN BODSTS BRGR -brhi -brne -bswtrg BSWTRG +Biagioni CANEN CANRX CANTX -capitalisation -cbmc CBMC -cbor CBOR CCIE CCMP @@ -92,7 +74,6 @@ CLDIV CLKA CLKB CLKEN -clki CLKI CLKP CLKS @@ -105,67 +86,45 @@ CMCON CMCOR CMCR CMIE -cmock -Cmock -CMock CMOCK -cmpx CMSIS CMSTR +CMock CNTE -coalescences CODAN -codecov CODR -comms COMPA CONFG CORTUS -coverity -Coverity -covfs COVFS CPACR -cpas CPAS -cpbs CPBS -cpcdis CPCDIS CPCS -cpcstop CPCSTOP CPCTRG CPIV CPRD CPRDR CPRE -cpsid -cpsie CPSR CPUID CRCB -crflash CRGFLG CRGINT -crhook -croutine CRTV CSAAT -csrr -csrs -csrw CTCR -ctest CTRLA CTSIC CUPD CUPDR CWGR -cxsf CYGNAL +Cmock +Coverity DADR -daif DAIFCLR DAIFSET DATAR @@ -175,14 +134,10 @@ DATRDY DBGU DCDIC DCMR -Dconfig DCOUNT -decf -decfsz DECNT DFPU DFREERTOS -dicr DICR DIVB DLYBCS @@ -216,32 +171,25 @@ DTREN DTXD DUNITY DVAR +Dconfig EABI -ecall ECIT ECRS ECRSDV -eevt EEVT -eevtedg EEVTEDG EFRHD EINT EIPC EIPSW -Elektronika EMACB EMDC EMDIO -emption -endm ENDRX ENDTX -enetrg ENETRG ENMFILE EOICR -epage EPEDS EPINT EPTYPE @@ -249,37 +197,31 @@ EQIC EQIF EQMK EREFCK -eret ERRA ERSTL ERXCK ERXDV ERXER -Espeche -Espressif ESTATUS ETRCS ETRGEDG -etrgs ETRGS ETXCK ETXEN ETXER -evba EVBA EWARM EWAVR EWRL EWRX EXID -expandnl EXTRSM +Elektronika +Espeche +Espressif FADD FCMD -fcolor FCSE -fdiagnostics -fdiv FDIV FEDPICC FERR @@ -288,13 +230,10 @@ FFER FFSR FIDI FLASH -Flsh FLSH FMCN FMRXNE FMXR -fninit -fnsave FNTR FOSC FPCCR @@ -302,16 +241,15 @@ FPCSR FPSW FPUL FRDY -Frieder FSDEN FSEDGE FSLEN FSOS FSR -fwait +Flsh +Frieder GCACC GCTRL -getvect GIEH GIEL GIRQ @@ -319,16 +257,15 @@ GLBSTATE GMSK GNURX GOVRE -gpio GPIO GPNVM GPTA HCLK -Hitach HRESP HWHSH HWORD HWRD +Hitach IADR IADRSZ ICCAVR @@ -348,10 +285,8 @@ IFDR IFER IFLASH IFSR -imajeff INACK INDF -inpw INTE INTFRCH INTFRCL @@ -361,69 +296,47 @@ IODEFINE IORLW IPEN IPLB -ipsr IPSR -iret IRET IRXFCS +ISR's ISRAM ISRR -ISR's ISRS ISRTICK ITIF ITMC ITMK -ittt JFRAME JTAG JTVIC Kamil -kbhit Kbyte Krutmann LAPIC LCDR LCOL -lcov -ldaa LDATA LDBDIS LDBSTOP -ldmdb LDMFD -ldmia LDRA -ldras LDRAS -ldrb -ldrbs LDRBS LDRNE -ldsr -lidt LINKR LJMP LLIO -lovrs LOVRS -lpcount -lpend -lpstart LPTHREAD -lsls LSPEN LSPENS -ltorg LWRD MABT MACL MAINF MAINRDY MAIR -Mang -Mbits -mcause MCFR MCKA MCKB @@ -436,60 +349,28 @@ MDER MDIO MDLC MDSR -mepc -mevents MFCR -mfear -mfedr -mfesr -mffsr -mfgpr -mfhi MFID -mflo -mfloat -mfmsr -mfpu -mhartid MIDE -Mikro MIKROC -misra -Misra MISRA MMCR MMSYSERR MOSC MOSCS MOSI -movem -moveq MOVF MOVFF -movhi -movia -movlb -movlw -movne -movs -movw MOVWF -movx MPLAB MPUCTRL MQTT MRDY MREAD -mret -mrseq -mrsne MRTR MSBF MSDIS MSEN -mspgcc -msreq -mstatus MSTATUS MSTP MSTPA @@ -498,11 +379,8 @@ MSTPCRA MSTPCRC MSTR MTCR -mthi MTIOA MTIOB -mtlo -mtsr MVFACGU MVFACHI MVFACLO @@ -513,16 +391,17 @@ MVTACHI MVTACLO MVTC MVTIPL +Mang +Mbits +Mikro +Misra NCFGR NCPHA NEBP NFIQ -Nios NIOSII NIRQ NOGIC -noheap -nostdint NPCS NRSTL NSACR @@ -530,20 +409,21 @@ NSFPU NSSR NTRST NVIC +Nios ODAT ODSR +OINC +OIWBNOWA +OIWBWA +OIWTNOWA OPMOD -optimisations OPTIMISED -optimiser ORCCR -orrs OSCBYPASS OSCEN OSCOFF OSCOUNT OSMC -outpw OVLY OVRE OVRES @@ -570,15 +450,10 @@ PENDSVSET PENSVCLEAR PERIODH PERIODL -periph PERIPH PFRE -phelter PHYA PICNT -pico -picolibc -Picolibc PICOLIBC PIEN PIIR @@ -592,53 +467,37 @@ PITIEN PIVR PLLB PLLR -popa -popm POPNE POPW -popx -portcomn PORTEN -portex -portisr POWERUP -ppuc PPUDR PPUER PPUSR -ppux PRCR PREA PREB PRIA -Prioritised PRIS PROCDLY PRODH PRODL PROGE -Prokic -prtmacro -psha -psplim PSPLIM PSTDBY PSVPAG PTCR PTSR -Pulpino PUON -pusha -pushf -pushm PUSHNE PUSHW -pushx PWMC +Picolibc +Prioritised +Prokic +Pulpino RAMPZ RASR -Rationalised -Raynald RBAR RBOF RBQP @@ -649,22 +508,16 @@ RCIF RCMR RCOMP RCOUNT -rddsp RDRF -reent REENT REGA RELD -Renesas -reta -reti RETP RETTO RFEIA RFMR RIIC RIPL -riscv RLAR RLCE RLES @@ -676,7 +529,6 @@ RNPR ROUSSET ROVR RSHR -rslcx RSLCX RSMINPR RSTC @@ -686,7 +538,6 @@ RSTNACK RSTRX RSTSTA RSTTX -Rsvd RTAR RTCEN RTCSC @@ -704,7 +555,6 @@ RXBRK RXBUFF RXBYTECNT RXDIS -Rxed RXEN RXENA RXOVERWRITE @@ -715,6 +565,11 @@ RXSUSP RXSYN RXTEN RXUBR +Rationalised +Raynald +Renesas +Rsvd +Rxed SBYCR SCALL SCBR @@ -728,14 +583,12 @@ SETB SETEN SETPSW SETR -setvect SFRC SHLL SHLR SHPR SHTIM SIFIVE -sinclude SODR SOFTIRQ SPCK @@ -747,21 +600,14 @@ SRSDB SSBY SSIR SSKEY -staa -Stellaris STILM STKPTR -stmdb -stmia -stsr STTBRK STTDLY STTOUT STTTO SVACC -svcne SVDIS -svlcx SVMST SWAPW SWHSH @@ -770,8 +616,8 @@ SWINT SWINTR SWRST SWTRG -synchronise SYSC +Stellaris TACCR TACCTL TACLR @@ -784,7 +630,6 @@ TBLPTRUH TBLPTRUL TBQP TBSY -tcclks TCCR TCKPS TCLK @@ -805,7 +650,6 @@ TIMFRZ TIMSK TIOA TIOB -tmcsr TMCSR TMIF TMKAEN @@ -824,7 +668,6 @@ TRAPA TRGEN TRGSEL TSHR -tstfsz TSTP TSTR TTGR @@ -848,44 +691,27 @@ TXUBR TXVC TXVDIS UDCP -uncrustify UNRE -unsuspended URAD URAT URSTEN URSTIEN URSTS -Usart USART USPRG USRIO -utest -utilises -utilising +Usart VDDCORE -vect VECT VECTACTIVE -visualisation -vldmdbeq -vldmia -vldmiaeq VMSRNE -vpop VPOPNE -vpush VPUSHNE VRPM -Vrtc -vstmdbeq -vstmiaeq VTOR +Vrtc W WAVESEL -wavsel -Wcolor -Wconversion WDCR WDDBGHLT WDDIS @@ -898,22 +724,200 @@ WDRSTEN WDRSTT WDSR WDTC -wdtcon WDUNF -Werror WESTAT +WIZC +WREG +Wcolor +Wconversion +Werror Weverything Wextra -winmm -WIZC Wpedantic -wrdsp -WREG Wunused XEXC XPAR -xparameters XPSR XRAM -xtal XTENSA +acpa +acpc +addi +addiu +aeevt +aswtrg +atomatic +bcpb +bcpc +beevt +bfextu +bics +brhi +brne +bswtrg +capitalisation +cbmc +cbor +clki +cmock +cmpx +coalescences +codecov +comms +coverity +covfs +cpas +cpbs +cpcdis +cpcstop +cpsid +cpsie +crflash +crhook +croutine +csrr +csrs +csrw +ctest +cxsf +daif +decf +decfsz +dicr +ecall +eevt +eevtedg +emption +endm +enetrg +epage +eret +etrgs +evba +expandnl +fcolor +fdiagnostics +fdiv +fninit +fnsave +fwait +getvect +gpio +imajeff +inpw +ipsr +iret +ittt +kbhit +lcov +ldaa +ldmdb +ldmia +ldras +ldrb +ldrbs +ldsr +lidt +lovrs +lpcount +lpend +lpstart +lsls +ltorg +mcause +mepc +mevents +mfear +mfedr +mfesr +mffsr +mfgpr +mfhi +mflo +mfloat +mfmsr +mfpu +mhartid +misra +movem +moveq +movhi +movia +movlb +movlw +movne +movs +movw +movx +mret +mrseq +mrsne +mspgcc +msreq +mstatus +mthi +mtlo +mtsr +noheap +nostdint +optimisations +optimiser +orrs +outpw +periph +phelter +pico +picolibc +popa +popm +popx +portcomn +portex +portisr +ppuc +ppux +prtmacro +psha +psplim +pusha +pushf +pushm +pushx +rddsp +reent +reta +reti +riscv +rslcx +setvect +sinclude +staa +stmdb +stmia +stsr +svcne +svlcx +synchronise +tcclks +tmcsr +tstfsz +uncrustify +unsuspended +utest +utilises +utilising +vect +visualisation +vldmdbeq +vldmia +vldmiaeq +vpop +vpush +vstmdbeq +vstmiaeq +wavsel +wdtcon +winmm +wrdsp +xparameters +xtal From 26019cd2d7aafdb59f1e2378ceb66db6450474af Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Wed, 27 Dec 2023 21:44:04 -0500 Subject: [PATCH 04/51] Fix copyright headers in the new port files --- portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S | 6 ++++-- portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.h | 2 +- portable/GCC/ARM_CRx_MPU/port.c | 4 ++-- portable/GCC/ARM_CRx_MPU/portASM.S | 4 ++-- portable/GCC/ARM_CRx_MPU/portmacro.h | 4 ++-- portable/GCC/ARM_CRx_MPU/portmacro_asm.h | 5 +++-- 6 files changed, 14 insertions(+), 11 deletions(-) diff --git a/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S b/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S index cbbeda00ac..b2005122a6 100644 --- a/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S +++ b/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S @@ -1,6 +1,8 @@ /* - * FreeRTOS V202112.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in diff --git a/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.h b/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.h index faf6c9b86b..f5ea990d79 100644 --- a/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.h +++ b/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.h @@ -1,5 +1,5 @@ /* - * FreeRTOS Kernel V10.6.0 + * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT diff --git a/portable/GCC/ARM_CRx_MPU/port.c b/portable/GCC/ARM_CRx_MPU/port.c index 7427aa7c57..abee64c334 100644 --- a/portable/GCC/ARM_CRx_MPU/port.c +++ b/portable/GCC/ARM_CRx_MPU/port.c @@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.6.1 - * Copyright (C) 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CRx_MPU/portASM.S b/portable/GCC/ARM_CRx_MPU/portASM.S index 7ea5ad42ca..7ae518d5a8 100644 --- a/portable/GCC/ARM_CRx_MPU/portASM.S +++ b/portable/GCC/ARM_CRx_MPU/portASM.S @@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.6.0 - * Copyright (C) 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CRx_MPU/portmacro.h b/portable/GCC/ARM_CRx_MPU/portmacro.h index cf46ac0c6d..b091860f53 100644 --- a/portable/GCC/ARM_CRx_MPU/portmacro.h +++ b/portable/GCC/ARM_CRx_MPU/portmacro.h @@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V11.0.1 - * Copyright (C) 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CRx_MPU/portmacro_asm.h b/portable/GCC/ARM_CRx_MPU/portmacro_asm.h index c2d0c02ef2..d8c5423cc9 100644 --- a/portable/GCC/ARM_CRx_MPU/portmacro_asm.h +++ b/portable/GCC/ARM_CRx_MPU/portmacro_asm.h @@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.6.0 - * Copyright (C) 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -25,6 +25,7 @@ * https://github.com/FreeRTOS * */ + #ifndef PORTMACRO_ASM_H #define PORTMACRO_ASM_H From 80d09879d1ba8256146e5909c67b542868035139 Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Thu, 28 Dec 2023 17:51:42 -0500 Subject: [PATCH 05/51] Add in Access Control List support to the port --- portable/GCC/ARM_CRx_MPU/port.c | 214 ++++++++++++++------------- portable/GCC/ARM_CRx_MPU/portmacro.h | 24 ++- 2 files changed, 135 insertions(+), 103 deletions(-) diff --git a/portable/GCC/ARM_CRx_MPU/port.c b/portable/GCC/ARM_CRx_MPU/port.c index 7427aa7c57..1fa59fdbe1 100644 --- a/portable/GCC/ARM_CRx_MPU/port.c +++ b/portable/GCC/ARM_CRx_MPU/port.c @@ -39,6 +39,7 @@ /* Scheduler includes. */ #include "FreeRTOSConfig.h" #include "FreeRTOS.h" +#include "portmacro_asm.h" #include "portmacro.h" #include "task.h" #include "mpu_syscall_numbers.h" @@ -589,73 +590,16 @@ BaseType_t xPortIsAuthorizedToAccessBuffer( return xAccessGranted; } -#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; - - if( xSchedulerRunning == pdFALSE ) - { - /* Grant access to all the kernel objects before the scheduler - * is started. It is necessary because there is no task running - * yet and therefore, we cannot use the permissions of any - * task. */ - xAccessGranted = pdTRUE; - } - else - { - 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 - -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 ) */ - /*---------------------------------------------------------------------------*/ /** @brief Determine if the FreeRTOS Task was created as a privileged task - * - * @return BaseType_t pdTRUE if the task's ulTaskFlags mark it as privileged. - * pdFALSE if the task was not created as a privileged task. * * @ingroup MPU Control * @ingroup Task Context + * + * @return pdTRUE if the Task was created as a privileged task. + * pdFALSE if the task was not created as a privileged task. + * */ BaseType_t xPortIsTaskPrivileged( void ) /* PRIVILEGED_FUNCTION */ { @@ -672,31 +616,6 @@ BaseType_t xPortIsTaskPrivileged( void ) /* PRIVILEGED_FUNCTION */ return xTaskIsPrivileged; } -/*---------------------------------------------------------------------------*/ - -/** @brief Function that is used as the default Link Register address for a new Task - * - * @ingroup Task Context - * @note This function is used as the default Link Register address if - * configTASK_RETURN_ADDRESS is not defined in FreeRTOSConfig.h - * - */ -void prvTaskExitError( void ) -{ - /* A function that implements a task must not exit or attempt to return to - * its caller as there is nothing to return to. If a task wants to exit it - * should instead call vTaskDelete( NULL ). - * - * Artificially force an assert() to be triggered if configASSERT() is - * defined, then stop here so application writers can catch the error. */ - configASSERT( ulPortInterruptNesting == ~0UL ); - - for( ;; ) - { - } -} - -/*---------------------------------------------------------------------------*/ /** @brief Start the FreeRTOS-Kernel's control of Tasks by starting the System Tick * Interrupt. @@ -707,21 +626,6 @@ void prvTaskExitError( void ) */ BaseType_t xPortStartScheduler( void ) { -#if defined( __ARMCC_VERSION ) - /* Declaration when these variable are defined in code instead of being - * exported from linker scripts. */ - /* Sections used for Privileged Stacks to zero them out before starting tasks */ - extern uint32_t * __privileged_stacks_start__; - extern uint32_t * __privileged_stacks_end__; -#else /* if defined( __ARMCC_VERSION ) */ - /* Declaration when these variable are exported from linker scripts. */ - /* Sections used for Privileged Stacks to zero them out before starting tasks */ -/* - extern uint32_t __privileged_stacks_start__[]; - extern uint32_t __privileged_stacks_end__[]; -*/ -#endif /* if defined( __ARMCC_VERSION ) */ - /* Start the timer that generates the tick ISR. */ configSETUP_TICK_INTERRUPT(); @@ -746,6 +650,114 @@ BaseType_t xPortStartScheduler( void ) } /*---------------------------------------------------------------------------*/ +#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; + + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else + { + 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; + } + + + 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 ); + } + + 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 ); + } + +#else + +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 ) */ + +/*---------------------------------------------------------------------------*/ + +/** @brief Function that is used as the default Link Register address for a new Task + * + * @ingroup Task Context + * @note This function is used as the default Link Register address if + * configTASK_RETURN_ADDRESS is not defined in FreeRTOSConfig.h + * + */ +void prvTaskExitError( void ) +{ + /* A function that implements a task must not exit or attempt to return to + * its caller as there is nothing to return to. If a task wants to exit it + * should instead call vTaskDelete( NULL ). + * + * Artificially force an assert() to be triggered if configASSERT() is + * defined, then stop here so application writers can catch the error. */ + configASSERT( ulPortInterruptNesting == ~0UL ); + + for( ;; ) + { + } +} + +/*---------------------------------------------------------------------------*/ + /** @brief Function meant to end the FreeRTOS Scheduler, not implemented on this port. * @ingroup Scheduler */ diff --git a/portable/GCC/ARM_CRx_MPU/portmacro.h b/portable/GCC/ARM_CRx_MPU/portmacro.h index cf46ac0c6d..ab42a1cab7 100644 --- a/portable/GCC/ARM_CRx_MPU/portmacro.h +++ b/portable/GCC/ARM_CRx_MPU/portmacro.h @@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V11.0.1 - * Copyright (C) 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -69,6 +69,15 @@ extern "C" { #error This Port is only usable with configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY set to 1 #endif /* ( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY != 1 ) */ +#ifndef configENABLE_ACCESS_CONTROL_LIST + #define configENABLE_ACCESS_CONTROL_LIST 0 +#elif( configENABLE_ACCESS_CONTROL_LIST == 1 ) + #ifndef configPROTECTED_KERNEL_OBJECT_POOL_SIZE + #error "Set configPROTECTED_KERNEL_OBJECT_POOL_SIZE to at least the number " \ + "of FreeRTOS-Kernel Objects to be created" + #endif /* configPROTECTED_KERNEL_OBJECT_POOL_SIZE */ +#endif /* configENABLE_ACCESS_CONTROL_LIST */ + /** @brief The size in Bytes that the Privileged System Call Stack should be. * * @ingroup MPU Privilege @@ -537,8 +546,15 @@ UBaseType_t ulPortCountLeadingZeros( UBaseType_t ulBitmap ); * padded. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) +/** @brief Size of the System Call Buffer in the TCB + * @ingroup Task Context + */ + #define portSYSTEM_CALL_STACK_SIZE configSYSTEM_CALL_STACK_SIZE +/* Size of an Access Control List (ACL) entry in bits. */ +#define portACL_ENTRY_SIZE_BITS ( 32U ) + /** @brief Structure to hold the MPU Register Values * @struct xMPU_REGION_REGISTERS * @@ -652,6 +668,10 @@ typedef struct MPU_SETTINGS * @ingroup Port Privilege */ 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 } xMPU_SETTINGS; #ifdef __cplusplus From 43946db07bbbd387a37ef715ce610ab87805bbca Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Fri, 29 Dec 2023 11:18:27 -0500 Subject: [PATCH 06/51] Refactoring xPortIsAuthorizedToAccessBuffer --- portable/GCC/ARM_CRx_MPU/port.c | 141 ++++++++++++++++++-------------- 1 file changed, 79 insertions(+), 62 deletions(-) diff --git a/portable/GCC/ARM_CRx_MPU/port.c b/portable/GCC/ARM_CRx_MPU/port.c index e730f49475..0edcfa5b24 100644 --- a/portable/GCC/ARM_CRx_MPU/port.c +++ b/portable/GCC/ARM_CRx_MPU/port.c @@ -499,97 +499,114 @@ PRIVILEGED_FUNCTION static void prvSetupDefaultMPU( void ) prvMpuEnable(); } -/*---------------------------------------------------------------------------*/ +/* ------------------------------------------------------------------------- */ /** @brief Determine if a FreeRTOS Task has been granted access to a memory region * - * @param pvBuffer Base address of the memory region access is being requested. - * @param ulBufferLength The length of the memory region that access is being requested. + * @param xTaskMPURegion Pointer to a single set of MPU region registers. + * @param ulRegionStart Base address of the memory region access is being requested. + * @param ulRegionLength The length of the memory region that access is being requested. * @param ulAccessRequested The type of access being requested, either read or write. * @return BaseType_t pdTRUE if the task can access the region, pdFALSE otherwise * * @ingroup Task Context * @ingroup MPU Control */ -BaseType_t xPortIsAuthorizedToAccessBuffer( - const void * pvBuffer, - uint32_t ulBufferLength, - uint32_t ulAccessRequested -) /* PRIVILEGED_FUNCTION */ +PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( + const xMPU_REGION_REGISTERS * xTaskMPURegion, + const uint32_t ulRegionStart, + const uint32_t ulRegionLength, + const uint32_t ulAccessRequested ) +{ + BaseType_t xAccessGranted; + uint32_t ulRegionEnd = ulRegionStart + ulRegionLength; + + /* Convert the MPU Region Size value to the actual size */ + uint32_t ulTaskRegionLength = 1 << ( ( xTaskMPURegion->ulRegionSize >> 1 ) + 1U ); + // uint32_t ulTaskRegionLength = 2 << ( xTaskMPURegion->ulRegionSize >> 1 ); + uint32_t ulTaskRegionEnd = xTaskMPURegion->ulRegionBaseAddress + ulTaskRegionLength; + if( ( ulRegionStart >= xTaskMPURegion->ulRegionBaseAddress ) + && ( ulRegionEnd <= ulTaskRegionEnd ) ) + { + /* Unprivileged read is MPU Ctrl Access Bit Value bX1X */ + if( ( tskMPU_READ_PERMISSION == ulAccessRequested ) && + ( ( portMPU_PRIV_RW_USER_RO_NOEXEC ) + & xTaskMPURegion->ulRegionAttribute ) ) + { + xAccessGranted = pdTRUE; + } + + /* Unprivileged Write is MPU Ctrl Access Bit Value b011 */ + else if( ( tskMPU_WRITE_PERMISSION & ulAccessRequested ) && + ( portMPU_PRIV_RW_USER_RW_NOEXEC == + ( portMPU_PRIV_RW_USER_RW_NOEXEC & xTaskMPURegion->ulRegionAttribute ) ) ) + { + xAccessGranted = pdTRUE; + } + + else + { + xAccessGranted = pdFALSE; + } + } + else + { + xAccessGranted = pdFALSE; + } + + return xAccessGranted; +} + +/* ------------------------------------------------------------------------- */ + + +BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, + uint32_t ulBufferLength, + uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ + { - volatile uint32_t i, ulBufferStartAddress, ulBufferEndAddress; - BaseType_t xAccessGranted = pdFALSE; + BaseType_t xAccessGranted; + + /* Calling task's MPU settings. */ + xMPU_SETTINGS * xTaskMPUSettings = NULL; + xMPU_REGION_REGISTERS * xTaskMPURegion = NULL; if( pdFALSE == xSchedulerRunning ) { + /* Before the scheduler starts an unknown task will be pxCurrentTCB */ xAccessGranted = pdTRUE; } else { - /* Calling task's MPU settings. */ - const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); - - uint32_t regionEndAddress = 0U; - uint32_t regionLength = 0U; - uint32_t regionStartAddress = 0u; + xTaskMPUSettings = xTaskGetMPUSettings( NULL ); - if( portTASK_IS_PRIVILEGED_FLAG == - ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) ) + if( NULL == xTaskMPUSettings ) { + xAccessGranted = pdFALSE; + } + else if( xTaskMPUSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) + { + /* If a task is privileged it is assumed that it can access the buffer */ xAccessGranted = pdTRUE; } else { - /* Protect against buffer overflow range check */ - if( pdFALSE == - ( ( uint32_t ) pvBuffer > - ( ( ( uint32_t ) 0 ) - ( uint32_t ) 1U ) - ulBufferLength - 1UL ) ) + uint32_t ulRegionIndex = 0x0UL; + do { - ulBufferStartAddress = ( uint32_t ) pvBuffer; - ulBufferEndAddress = ( ( ( uint32_t ) pvBuffer ) + ulBufferLength - 1UL ); - - for( i = 0; i < portTOTAL_NUM_REGIONS_IN_TCB; i++ ) - { - regionStartAddress = - xTaskMpuSettings->xRegion[ i ].ulRegionBaseAddress; - regionLength = - 1 << ( ( xTaskMpuSettings->xRegion[ i ].ulRegionSize >> 1 ) + 1U ); - regionEndAddress = regionStartAddress + regionLength; - - if( ( ulBufferStartAddress >= regionStartAddress ) && - ( ulBufferEndAddress <= regionEndAddress ) ) - { - if( tskMPU_READ_PERMISSION == ulAccessRequested ) - { - /* MPU CTRL Register Access Permission for unprivileged Read - * is bX1X */ - if( portMPU_PRIV_RO_USER_RO_EXEC & - xTaskMpuSettings->xRegion[ i ].ulRegionAttribute ) - { - xAccessGranted = pdTRUE; - break; - } - } - /* MPU CTRL Register Access Permission for unprivileged write is - * b011 */ - else if( tskMPU_WRITE_PERMISSION & ulAccessRequested ) - { - if( portMPU_PRIV_RW_USER_RW_EXEC == - ( portMPU_PRIV_RW_USER_RW_EXEC & - xTaskMpuSettings->xRegion[ i ].ulRegionAttribute ) ) - { - xAccessGranted = pdTRUE; - break; - } - } - } - } - } + xTaskMPURegion = &( xTaskMPUSettings->xRegion[ ulRegionIndex++ ] ); + xAccessGranted = prvTaskCanAccessRegion( xTaskMPURegion, + ( uint32_t ) pvBuffer, + ulBufferLength, + ulAccessRequested ); + } while( ( pdFALSE == xAccessGranted ) && + ( ulRegionIndex < portTOTAL_NUM_REGIONS_IN_TCB ) ); } } return xAccessGranted; } + /*---------------------------------------------------------------------------*/ /** @brief Determine if the FreeRTOS Task was created as a privileged task From 89227494cfeef0c6bb87d259f1ec433544e3f21e Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Tue, 2 Jan 2024 11:48:07 -0500 Subject: [PATCH 07/51] Clang format the mpu_wrappers_v2_asm.h file with slight tweaks to the format options --- .../GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.h | 178 +++++++++--------- 1 file changed, 88 insertions(+), 90 deletions(-) diff --git a/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.h b/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.h index f5ea990d79..e4a411adea 100644 --- a/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.h +++ b/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.h @@ -88,23 +88,23 @@ typedef struct xEventGroupWaitBitsParams /*-----------------------------------------------------------*/ -extern TickType_t MPU_xTaskGetTickCount( void ) __attribute__( ( naked ) -) FREERTOS_SYSTEM_CALL; +extern TickType_t MPU_xTaskGetTickCount( void ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; /*-----------------------------------------------------------*/ -UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) __attribute__( ( naked ) -) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; /*-----------------------------------------------------------*/ -char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) __attribute__( ( naked ) -) FREERTOS_SYSTEM_CALL; +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; /*-----------------------------------------------------------*/ -void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) __attribute__( ( naked ) -) FREERTOS_SYSTEM_CALL; +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; /*-----------------------------------------------------------*/ @@ -124,13 +124,13 @@ BaseType_t MPU_xQueueGenericSend( /*-----------------------------------------------------------*/ -UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue -) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; /*-----------------------------------------------------------*/ -UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue -) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; /*-----------------------------------------------------------*/ @@ -172,23 +172,23 @@ size_t MPU_xStreamBufferReceive( /*-----------------------------------------------------------*/ -BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer -) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; /*-----------------------------------------------------------*/ -BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer -) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; /*-----------------------------------------------------------*/ -size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer -) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; /*-----------------------------------------------------------*/ -size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer -) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; /*-----------------------------------------------------------*/ @@ -199,8 +199,8 @@ BaseType_t MPU_xStreamBufferSetTriggerLevel( /*-----------------------------------------------------------*/ -size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer -) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; /*-----------------------------------------------------------*/ @@ -248,67 +248,67 @@ BaseType_t MPU_xTaskDelayUntil( #if( INCLUDE_xTaskAbortDelay == 1 ) -BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) __attribute__( ( naked ) -) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; #endif /* if ( INCLUDE_xTaskAbortDelay == 1 ) */ /*-----------------------------------------------------------*/ #if( INCLUDE_vTaskDelay == 1 ) -void MPU_vTaskDelay( const TickType_t xTicksToDelay ) __attribute__( ( naked ) -) FREERTOS_SYSTEM_CALL; +void MPU_vTaskDelay( const TickType_t xTicksToDelay ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; #endif /* if ( INCLUDE_vTaskDelay == 1 ) */ /*-----------------------------------------------------------*/ #if( INCLUDE_uxTaskPriorityGet == 1 ) -UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) __attribute__( ( naked ) -) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; #endif /* if ( INCLUDE_uxTaskPriorityGet == 1 ) */ /*-----------------------------------------------------------*/ #if( INCLUDE_eTaskGetState == 1 ) -eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) __attribute__( ( naked ) -) FREERTOS_SYSTEM_CALL; +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; #endif /* if ( INCLUDE_eTaskGetState == 1 ) */ /*-----------------------------------------------------------*/ #if( INCLUDE_xTaskGetIdleTaskHandle == 1 ) -TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) __attribute__( ( naked ) -) FREERTOS_SYSTEM_CALL; +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; #endif /* if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */ /*-----------------------------------------------------------*/ #if( INCLUDE_vTaskSuspend == 1 ) -void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) __attribute__( ( naked ) -) FREERTOS_SYSTEM_CALL; +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -void MPU_vTaskResume( TaskHandle_t xTaskToResume ) __attribute__( ( naked ) -) FREERTOS_SYSTEM_CALL; +void MPU_vTaskResume( TaskHandle_t xTaskToResume ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; #endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ /*-----------------------------------------------------------*/ #if( configGENERATE_RUN_TIME_STATS == 1 ) -configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask -) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask -) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; #if( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) -configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void -) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void -) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; #endif /* ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */ #endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ @@ -316,13 +316,11 @@ configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void #if( configUSE_APPLICATION_TASK_TAG == 1 ) -void MPU_vTaskSetApplicationTaskTag( - TaskHandle_t xTask, - TaskHookFunction_t pxHookFunction -) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask -) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; #endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ /*-----------------------------------------------------------*/ @@ -345,24 +343,24 @@ void * MPU_pvTaskGetThreadLocalStoragePointer( #if( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) -UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) __attribute__( ( naked ) -) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; #endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) */ /*-----------------------------------------------------------*/ #if( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) -configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask -) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; #endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) */ /*-----------------------------------------------------------*/ #if( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) -TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) __attribute__( ( naked ) -) FREERTOS_SYSTEM_CALL; +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; #endif /* if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) \ ) */ @@ -370,8 +368,8 @@ TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) __attribute__( ( naked ) #if( INCLUDE_xTaskGetSchedulerState == 1 ) -BaseType_t MPU_xTaskGetSchedulerState( void ) __attribute__( ( naked ) -) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskGetSchedulerState( void ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; #endif /* if ( INCLUDE_xTaskGetSchedulerState == 1 ) */ /*-----------------------------------------------------------*/ @@ -391,8 +389,8 @@ UBaseType_t MPU_uxTaskGetSystemState( configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) __attribute__( ( naked ) -) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; void MPU_vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; @@ -402,8 +400,8 @@ void MPU_vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumbe #if( configUSE_TASK_NOTIFICATIONS == 1 ) -BaseType_t MPU_xTaskGenericNotifyEntry( const xTaskGenericNotifyParams_t * pxParams -) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskGenericNotifyEntry( const xTaskGenericNotifyParams_t * pxParams ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTaskGenericNotifyWaitEntry( const xTaskGenericNotifyWaitParams_t * pxParams ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; @@ -433,13 +431,13 @@ uint32_t MPU_ulTaskGenericNotifyValueClear( BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) __attribute__( ( naked ) -) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; #if( INCLUDE_xSemaphoreGetMutexHolder == 1 ) -TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) __attribute__( ( naked ) -) FREERTOS_SYSTEM_CALL; +TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; #endif /* ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) */ @@ -466,49 +464,49 @@ BaseType_t MPU_xQueueAddToSet( void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, const char * pcName ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) __attribute__( ( naked ) -) FREERTOS_SYSTEM_CALL; +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) __attribute__( ( naked ) -) FREERTOS_SYSTEM_CALL; +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; #endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ /*-----------------------------------------------------------*/ #if( configUSE_TIMERS == 1 ) -void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) __attribute__( ( naked ) -) FREERTOS_SYSTEM_CALL; +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -void MPU_vTimerSetTimerID( TimerHandle_t xTimer, void * pvNewID ) __attribute__( ( naked ) -) FREERTOS_SYSTEM_CALL; +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, void * pvNewID ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) __attribute__( ( naked ) -) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) __attribute__( ( naked ) -) FREERTOS_SYSTEM_CALL; +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -BaseType_t MPU_xTimerGenericCommandEntry( const xTimerGenericCommandParams_t * pxParams -) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTimerGenericCommandEntry( const xTimerGenericCommandParams_t * pxParams ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) __attribute__( ( naked ) -) FREERTOS_SYSTEM_CALL; +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, const BaseType_t uxAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) __attribute__( ( naked ) -) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) __attribute__( ( naked ) -) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) __attribute__( ( naked ) -) FREERTOS_SYSTEM_CALL; +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) __attribute__( ( naked ) -) FREERTOS_SYSTEM_CALL; +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; #endif /* if ( configUSE_TIMERS == 1 ) */ /*-----------------------------------------------------------*/ From 4f659312940b8eb53d4a1f7a7251638e57c49967 Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Tue, 2 Jan 2024 11:48:21 -0500 Subject: [PATCH 08/51] Clang format port.c with slight tweaks to the format options --- portable/GCC/ARM_CRx_MPU/port.c | 199 +++++++++++++++++--------------- 1 file changed, 109 insertions(+), 90 deletions(-) diff --git a/portable/GCC/ARM_CRx_MPU/port.c b/portable/GCC/ARM_CRx_MPU/port.c index 0edcfa5b24..2b351331b8 100644 --- a/portable/GCC/ARM_CRx_MPU/port.c +++ b/portable/GCC/ARM_CRx_MPU/port.c @@ -239,8 +239,8 @@ StackType_t * pxPortInitialiseStack( /* Fill the System Call Stack with known values for debugging. */ for( ulStackIndex = 0x0; ulStackIndex < configSYSTEM_CALL_STACK_SIZE; ulStackIndex++ ) { - xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ ulStackIndex ] = - 0x575B | ulStackIndex; + xMPUSettings->xSystemCallStackInfo + .ulSystemCallStackBuffer[ ulStackIndex ] = 0x575B | ulStackIndex; } /* Return the address where the context of this task should be restored from*/ @@ -260,8 +260,8 @@ PRIVILEGED_FUNCTION static uint32_t prvGetMPURegionSizeSetting( uint32_t ulActualSizeInBytes ); -static uint32_t prvGetMPURegionSizeSetting( uint32_t ulActualSizeInBytes -) /* PRIVILEGED_FUNCTION */ +static uint32_t prvGetMPURegionSizeSetting( uint32_t ulActualSizeInBytes ) /* PRIVILEGED_FUNCTION + */ { uint32_t ulRegionSize, ulReturnValue = 4U; @@ -328,13 +328,13 @@ void vPortStoreTaskMPUSettings( /* No MPU regions are specified so allow access to all of the RAM. */ xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress = ( uint32_t ) __SRAM_segment_start__; - xMPUSettings->xRegion[ 0 ].ulRegionSize = - ( prvGetMPURegionSizeSetting( - ( uint32_t ) __SRAM_segment_end__ - ( uint32_t ) __SRAM_segment_start__ - ) ) | - portMPU_REGION_ENABLE; - xMPUSettings->xRegion[ 0 ].ulRegionAttribute = - portMPU_PRIV_RW_USER_RW_NOEXEC | portMPU_NORMAL_OIWTNOWA_SHARED; + xMPUSettings->xRegion[ 0 ].ulRegionSize = ( prvGetMPURegionSizeSetting( + ( uint32_t ) __SRAM_segment_end__ - + ( uint32_t ) __SRAM_segment_start__ + ) ) | + portMPU_REGION_ENABLE; + xMPUSettings->xRegion[ 0 ].ulRegionAttribute = portMPU_PRIV_RW_USER_RW_NOEXEC | + portMPU_NORMAL_OIWTNOWA_SHARED; /* Invalidate all other regions. */ for( ul = 1; ul <= portNUM_CONFIGURABLE_REGIONS; ul++ ) @@ -356,10 +356,10 @@ void vPortStoreTaskMPUSettings( uint32_t ulSmallestRegion = prvGetMPURegionSizeSetting( ulStackDepth * 0x4 ); /* Define the region that allows access to the stack. */ xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress = ( uint32_t ) pxBottomOfStack; - xMPUSettings->xRegion[ 0 ].ulRegionSize = - ulSmallestRegion | portMPU_REGION_ENABLE; - xMPUSettings->xRegion[ 0 ].ulRegionAttribute = - portMPU_PRIV_RW_USER_RW_NOEXEC | portMPU_NORMAL_OIWTNOWA_SHARED; + xMPUSettings->xRegion[ 0 ].ulRegionSize = ulSmallestRegion | + portMPU_REGION_ENABLE; + xMPUSettings->xRegion[ 0 ].ulRegionAttribute = portMPU_PRIV_RW_USER_RW_NOEXEC | + portMPU_NORMAL_OIWTNOWA_SHARED; } for( ul = 1; ul <= portNUM_CONFIGURABLE_REGIONS; ul++ ) @@ -369,13 +369,15 @@ void vPortStoreTaskMPUSettings( /* Translate the generic region definition contained in * xRegions into the R4 specific MPU settings that are then * stored in xMPUSettings. */ - xMPUSettings->xRegion[ ul ].ulRegionBaseAddress = - ( uint32_t ) xRegions[ lIndex ].pvBaseAddress; - xMPUSettings->xRegion[ ul ].ulRegionSize = - prvGetMPURegionSizeSetting( xRegions[ lIndex ].ulLengthInBytes ) | - portMPU_REGION_ENABLE; - xMPUSettings->xRegion[ ul ].ulRegionAttribute = - xRegions[ lIndex ].ulParameters; + xMPUSettings->xRegion[ ul ] + .ulRegionBaseAddress = ( uint32_t ) xRegions[ lIndex ].pvBaseAddress; + xMPUSettings->xRegion[ ul ] + .ulRegionSize = prvGetMPURegionSizeSetting( + xRegions[ lIndex ].ulLengthInBytes + ) | + portMPU_REGION_ENABLE; + xMPUSettings->xRegion[ ul ].ulRegionAttribute = xRegions[ lIndex ] + .ulParameters; } else { @@ -513,10 +515,11 @@ PRIVILEGED_FUNCTION static void prvSetupDefaultMPU( void ) * @ingroup MPU Control */ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( - const xMPU_REGION_REGISTERS * xTaskMPURegion, - const uint32_t ulRegionStart, - const uint32_t ulRegionLength, - const uint32_t ulAccessRequested ) + const xMPU_REGION_REGISTERS * xTaskMPURegion, + const uint32_t ulRegionStart, + const uint32_t ulRegionLength, + const uint32_t ulAccessRequested +) { BaseType_t xAccessGranted; uint32_t ulRegionEnd = ulRegionStart + ulRegionLength; @@ -525,13 +528,12 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( uint32_t ulTaskRegionLength = 1 << ( ( xTaskMPURegion->ulRegionSize >> 1 ) + 1U ); // uint32_t ulTaskRegionLength = 2 << ( xTaskMPURegion->ulRegionSize >> 1 ); uint32_t ulTaskRegionEnd = xTaskMPURegion->ulRegionBaseAddress + ulTaskRegionLength; - if( ( ulRegionStart >= xTaskMPURegion->ulRegionBaseAddress ) - && ( ulRegionEnd <= ulTaskRegionEnd ) ) + if( ( ulRegionStart >= xTaskMPURegion->ulRegionBaseAddress ) && + ( ulRegionEnd <= ulTaskRegionEnd ) ) { /* Unprivileged read is MPU Ctrl Access Bit Value bX1X */ if( ( tskMPU_READ_PERMISSION == ulAccessRequested ) && - ( ( portMPU_PRIV_RW_USER_RO_NOEXEC ) - & xTaskMPURegion->ulRegionAttribute ) ) + ( ( portMPU_PRIV_RW_USER_RO_NOEXEC ) &xTaskMPURegion->ulRegionAttribute ) ) { xAccessGranted = pdTRUE; } @@ -559,10 +561,11 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( /* ------------------------------------------------------------------------- */ - -BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, - uint32_t ulBufferLength, - uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */ +BaseType_t xPortIsAuthorizedToAccessBuffer( + const void * pvBuffer, + uint32_t ulBufferLength, + uint32_t ulAccessRequested +) /* PRIVILEGED_FUNCTION */ { BaseType_t xAccessGranted; @@ -595,10 +598,12 @@ BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, do { xTaskMPURegion = &( xTaskMPUSettings->xRegion[ ulRegionIndex++ ] ); - xAccessGranted = prvTaskCanAccessRegion( xTaskMPURegion, - ( uint32_t ) pvBuffer, - ulBufferLength, - ulAccessRequested ); + xAccessGranted = prvTaskCanAccessRegion( + xTaskMPURegion, + ( uint32_t ) pvBuffer, + ulBufferLength, + ulAccessRequested + ); } while( ( pdFALSE == xAccessGranted ) && ( ulRegionIndex < portTOTAL_NUM_REGIONS_IN_TCB ) ); } @@ -606,7 +611,6 @@ BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, return xAccessGranted; } - /*---------------------------------------------------------------------------*/ /** @brief Determine if the FreeRTOS Task was created as a privileged task @@ -669,71 +673,86 @@ BaseType_t xPortStartScheduler( void ) #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; +BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject +) /* PRIVILEGED_FUNCTION */ +{ + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings; + + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else + { + xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ - if( xSchedulerRunning == pdFALSE ) + 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 ) { - /* Grant access to all the kernel objects before the scheduler - * is started. It is necessary because there is no task running - * yet and therefore, we cannot use the permissions of any - * task. */ xAccessGranted = pdTRUE; } - else - { - 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; } + } + return xAccessGranted; +} - void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle, - int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ - { - uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; - xMPU_SETTINGS * xTaskMpuSettings; +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 ); + ulAccessControlListEntryIndex = + ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = + ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); - xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); - xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit ); - } + xTaskMpuSettings->ulAccessControlList + [ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit ); +} - void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle, - int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ - { - uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; - xMPU_SETTINGS * xTaskMpuSettings; +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 ); + ulAccessControlListEntryIndex = + ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = + ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); - xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); - xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit ); - } + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( + 1U << ulAccessControlListEntryBit + ); +} #else From 7650690bef12b1e80abf667109a229ffb6659298 Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Tue, 2 Jan 2024 11:48:30 -0500 Subject: [PATCH 09/51] Clang format portmacro.h with slight tweaks to the format options --- portable/GCC/ARM_CRx_MPU/portmacro.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/portable/GCC/ARM_CRx_MPU/portmacro.h b/portable/GCC/ARM_CRx_MPU/portmacro.h index ab42a1cab7..7fdc824790 100644 --- a/portable/GCC/ARM_CRx_MPU/portmacro.h +++ b/portable/GCC/ARM_CRx_MPU/portmacro.h @@ -76,7 +76,7 @@ extern "C" { #error "Set configPROTECTED_KERNEL_OBJECT_POOL_SIZE to at least the number " \ "of FreeRTOS-Kernel Objects to be created" #endif /* configPROTECTED_KERNEL_OBJECT_POOL_SIZE */ -#endif /* configENABLE_ACCESS_CONTROL_LIST */ +#endif /* configENABLE_ACCESS_CONTROL_LIST */ /** @brief The size in Bytes that the Privileged System Call Stack should be. * @@ -553,7 +553,7 @@ UBaseType_t ulPortCountLeadingZeros( UBaseType_t ulBitmap ); #define portSYSTEM_CALL_STACK_SIZE configSYSTEM_CALL_STACK_SIZE /* Size of an Access Control List (ACL) entry in bits. */ -#define portACL_ENTRY_SIZE_BITS ( 32U ) +#define portACL_ENTRY_SIZE_BITS ( 32U ) /** @brief Structure to hold the MPU Register Values * @struct xMPU_REGION_REGISTERS @@ -669,9 +669,10 @@ typedef struct MPU_SETTINGS */ 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 +#if( configENABLE_ACCESS_CONTROL_LIST == 1 ) + uint32_t ulAccessControlList + [ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ]; +#endif } xMPU_SETTINGS; #ifdef __cplusplus From 4c53a433df1a02feaf4e148f59d86e2802e4ccb2 Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Tue, 2 Jan 2024 11:48:48 -0500 Subject: [PATCH 10/51] Add the .clang-format file that is being used to the port --- portable/GCC/ARM_CRx_MPU/.clang-format | 103 +++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 portable/GCC/ARM_CRx_MPU/.clang-format diff --git a/portable/GCC/ARM_CRx_MPU/.clang-format b/portable/GCC/ARM_CRx_MPU/.clang-format new file mode 100644 index 0000000000..b10f7ad5cf --- /dev/null +++ b/portable/GCC/ARM_CRx_MPU/.clang-format @@ -0,0 +1,103 @@ +--- +Language: Cpp +AlignAfterOpenBracket: BlockIndent +AlignConsecutiveAssignments: None +AlignConsecutiveBitFields: AcrossEmptyLinesAndComments +AlignConsecutiveDeclarations: None +AlignConsecutiveMacros: AcrossEmptyLinesAndComments +AlignEscapedNewlines: Left +AlignOperands: AlignAfterOperator +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: false +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortEnumsOnASingleLine: false +AllowShortFunctionsOnASingleLine: None +AllowShortIfStatementsOnASingleLine: false +AllowShortLambdasOnASingleLine: All +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: Yes +BinPackArguments: false +BinPackParameters: false +BitFieldColonSpacing: Both +BraceWrapping: + AfterCaseLabel: true + AfterClass: true + AfterControlStatement: Always + AfterEnum: true + AfterExternBlock: false + AfterFunction: true + AfterNamespace: true + AfterStruct: true + AfterUnion: true + BeforeCatch: true + BeforeElse: true + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Custom +BreakBeforeConceptDeclarations: true +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: BeforeColon +BreakInheritanceList: BeforeColon +BreakStringLiterals: true +ColumnLimit: 90 +CompactNamespaces: false +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: false +DerivePointerAlignment: false +EmptyLineBeforeAccessModifier: Always +FixNamespaceComments: true +IncludeBlocks: Preserve +IndentCaseBlocks: false +IndentCaseLabels: true +IndentExternBlock: NoIndent +IndentGotoLabels: true +IndentPPDirectives: BeforeHash +IndentWidth: 4 +KeepEmptyLinesAtTheStartOfBlocks: false +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +PenaltyBreakAssignment: 1000 +PenaltyBreakBeforeFirstCallParameter: 200 +PenaltyBreakComment: 50 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 100 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 100 +PenaltyIndentedWhitespace: 0 +PenaltyReturnTypeOnItsOwnLine: 10000 +PointerAlignment: Middle +ReflowComments: true +SortIncludes: false +SortUsingDeclarations: true +SpaceAfterCStyleCast: true +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: false +SpaceBeforeCpp11BracedList: true +SpaceBeforeCtorInitializerColon: false +SpaceBeforeInheritanceColon: false +SpaceBeforeParens: Never +SpaceBeforeRangeBasedForLoopColon: false +SpaceBeforeSquareBrackets: false +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInConditionalStatement: true +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: true +SpacesInParentheses: true +SpacesInSquareBrackets: true +TabWidth: 4 +LineEnding: LF +UseTab: Never +... + From bdd9f7129c2b667dad38e9d53971696a0bbc3a7f Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Tue, 2 Jan 2024 11:49:19 -0500 Subject: [PATCH 11/51] Add the CI-CD check for clang formatting the ARM_CRx_MPU port --- .github/workflows/ci.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bc6d8802b3..5d5b659187 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,6 +15,15 @@ jobs: with: exclude-dirs: portable + port-formatting: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Check Formatting of FreeRTOS-Kernel Files + uses: FreeRTOS/CI-CD-Github-Actions/clang-formatting@main + with: + path: portable/GCC/ARM_CRx_MPU + spell-check: runs-on: ubuntu-latest steps: From dc0e508008ca9812611e40b1c7651e318c62a28d Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Tue, 2 Jan 2024 12:51:08 -0500 Subject: [PATCH 12/51] Add the ARM_CRx_MPU Demos to the kernel build checks --- .github/workflows/kernel-demos.yml | 47 +++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/.github/workflows/kernel-demos.yml b/.github/workflows/kernel-demos.yml index bae32c9662..0c925d1fb9 100644 --- a/.github/workflows/kernel-demos.yml +++ b/.github/workflows/kernel-demos.yml @@ -1,6 +1,12 @@ name: FreeRTOS-Kernel Demos on: [push, pull_request] +env: + bashPass: \033[32;1mPASSED - + bashInfo: \033[33;1mINFO - + bashFail: \033[31;1mFAILED - + bashEnd: \033[0m + jobs: WIN32-MSVC: name: WIN32 MSVC @@ -127,7 +133,6 @@ jobs: with: ref: main repository: FreeRTOS/FreeRTOS - submodules: 'recursive' fetch-depth: 1 # Checkout user pull request changes @@ -211,3 +216,43 @@ jobs: shell: bash working-directory: FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC run: make -C build/gcc -j + + - env: + stepName: Build CORTEX_R4_RM46_HERCULES_MCU_GCC Demo + shell: bash + working-directory: FreeRTOS/Demo/CORTEX_R4_RM46_HERCULES_MCU_GCC + run: | + # ${{ env.stepName }} + echo -e "::group::${{ env.bashInfo }} ${{ env.stepName }} ${{ env.bashEnd }}" + set +e + cmake -S . -B build; + make -C build all; + exitStatus=$? + set -e + echo -e "::endgroup::" + if [ $exitStatus -eq 0 ]; then + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }}" + else + echo -e "${{ env.bashFail }} ${{ env.stepName }} ${{ env.bashEnd }}" + exit 1 + fi + + - env: + stepName: Build CORTEX_R5_RM57_HERCULES_MCU_GCC Demo + shell: bash + working-directory: FreeRTOS/Demo/CORTEX_R5_RM57_HERCULES_MCU_GCC + run: | + # ${{ env.stepName }} + echo -e "::group::${{ env.bashInfo }} ${{ env.stepName }} ${{ env.bashEnd }}" + set +e + cmake -S . -B build; + make -C build all; + exitStatus=$? + set -e + echo -e "::endgroup::" + if [ $exitStatus -eq 0 ]; then + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }}" + else + echo -e "${{ env.bashFail }} ${{ env.stepName }} ${{ env.bashEnd }}" + exit 1 + fi From b2c406c3a37f3b984e0a6bbc67ab6d9f088db49d Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Tue, 2 Jan 2024 12:58:46 -0500 Subject: [PATCH 13/51] Change to make the .clang-format file work with V14 of clang-format. Moving the comment for PRIVILEGED_FUNCTION to the front to help with formatting, also makes more sense when looking at the func imo --- portable/GCC/ARM_CRx_MPU/.clang-format | 2 +- portable/GCC/ARM_CRx_MPU/port.c | 38 ++++++++++++++------------ 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/portable/GCC/ARM_CRx_MPU/.clang-format b/portable/GCC/ARM_CRx_MPU/.clang-format index b10f7ad5cf..0ce7b55f18 100644 --- a/portable/GCC/ARM_CRx_MPU/.clang-format +++ b/portable/GCC/ARM_CRx_MPU/.clang-format @@ -97,7 +97,7 @@ SpacesInCStyleCastParentheses: true SpacesInParentheses: true SpacesInSquareBrackets: true TabWidth: 4 -LineEnding: LF +UseCRLF: false UseTab: Never ... diff --git a/portable/GCC/ARM_CRx_MPU/port.c b/portable/GCC/ARM_CRx_MPU/port.c index 2b351331b8..392c1cd31c 100644 --- a/portable/GCC/ARM_CRx_MPU/port.c +++ b/portable/GCC/ARM_CRx_MPU/port.c @@ -91,13 +91,13 @@ PRIVILEGED_DATA volatile uint32_t ulICCEOIR = configEOI_ADDRESS; * @ingroup Task Context * @note pxTopOfStack must be a region of memory that is a valid MPU region size. */ -StackType_t * pxPortInitialiseStack( +/* PRIVILEGED_FUNCTION */ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void * pvParameters, BaseType_t xRunPrivileged, xMPU_SETTINGS * xMPUSettings -) /* PRIVILEGED_FUNCTION */ +) { /** Setup the initial context of the task. The context is set exactly as * expected by the portRESTORE_CONTEXT() macro. */ @@ -260,8 +260,9 @@ PRIVILEGED_FUNCTION static uint32_t prvGetMPURegionSizeSetting( uint32_t ulActualSizeInBytes ); -static uint32_t prvGetMPURegionSizeSetting( uint32_t ulActualSizeInBytes ) /* PRIVILEGED_FUNCTION - */ +/* PRIVILEGED_FUNCTION */ static uint32_t prvGetMPURegionSizeSetting( + uint32_t ulActualSizeInBytes +) { uint32_t ulRegionSize, ulReturnValue = 4U; @@ -299,12 +300,12 @@ static uint32_t prvGetMPURegionSizeSetting( uint32_t ulActualSizeInBytes ) /* PR * @note pxBottomOfStack must be aligned to a region size of length ulStackDepth. * @note ulStackDepth must be a power of 2 larger than 32 bytes. */ -void vPortStoreTaskMPUSettings( +/* PRIVILEGED_FUNCTION */ void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, uint32_t ulStackDepth -) /* PRIVILEGED_FUNCTION */ +) { #if defined( __ARMCC_VERSION ) @@ -561,12 +562,11 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( /* ------------------------------------------------------------------------- */ -BaseType_t xPortIsAuthorizedToAccessBuffer( +/* PRIVILEGED_FUNCTION */ BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, uint32_t ulBufferLength, uint32_t ulAccessRequested -) /* PRIVILEGED_FUNCTION */ - +) { BaseType_t xAccessGranted; @@ -622,7 +622,7 @@ BaseType_t xPortIsAuthorizedToAccessBuffer( * pdFALSE if the task was not created as a privileged task. * */ -BaseType_t xPortIsTaskPrivileged( void ) /* PRIVILEGED_FUNCTION */ +/* PRIVILEGED_FUNCTION */ BaseType_t xPortIsTaskPrivileged( void ) { BaseType_t xTaskIsPrivileged = pdFALSE; @@ -673,8 +673,9 @@ BaseType_t xPortStartScheduler( void ) #if( configENABLE_ACCESS_CONTROL_LIST == 1 ) -BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject -) /* PRIVILEGED_FUNCTION */ +/* PRIVILEGED_FUNCTION */ BaseType_t xPortIsAuthorizedToAccessKernelObject( + int32_t lInternalIndexOfKernelObject +) { uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; BaseType_t xAccessGranted = pdFALSE; @@ -715,10 +716,10 @@ BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernel return xAccessGranted; } -void vPortGrantAccessToKernelObject( +/* PRIVILEGED_FUNCTION */ void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle, int32_t lInternalIndexOfKernelObject -) /* PRIVILEGED_FUNCTION */ +) { uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; xMPU_SETTINGS * xTaskMpuSettings; @@ -734,10 +735,10 @@ void vPortGrantAccessToKernelObject( [ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit ); } -void vPortRevokeAccessToKernelObject( +/* PRIVILEGED_FUNCTION */ void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle, int32_t lInternalIndexOfKernelObject -) /* PRIVILEGED_FUNCTION */ +) { uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; xMPU_SETTINGS * xTaskMpuSettings; @@ -756,8 +757,9 @@ void vPortRevokeAccessToKernelObject( #else -BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject -) /* PRIVILEGED_FUNCTION */ +/* PRIVILEGED_FUNCTION */ BaseType_t xPortIsAuthorizedToAccessKernelObject( + int32_t lInternalIndexOfKernelObject +) { ( void ) lInternalIndexOfKernelObject; From be4dc05b78571acf9db6b1684d7f8cff68a6ae8e Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Tue, 2 Jan 2024 13:06:59 -0500 Subject: [PATCH 14/51] Slight format change --- portable/GCC/ARM_CRx_MPU/port.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/portable/GCC/ARM_CRx_MPU/port.c b/portable/GCC/ARM_CRx_MPU/port.c index 392c1cd31c..07cc62a091 100644 --- a/portable/GCC/ARM_CRx_MPU/port.c +++ b/portable/GCC/ARM_CRx_MPU/port.c @@ -222,26 +222,21 @@ PRIVILEGED_DATA volatile uint32_t ulICCEOIR = configEOI_ADDRESS; xMPUSettings->ulContext[ ulContextIndex ] = portNO_CRITICAL_NESTING; /* Ensure that the system call stack is double word aligned. */ - xMPUSettings->xSystemCallStackInfo.pulSystemCallStackPointer = &( - xMPUSettings->xSystemCallStackInfo - .ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE - 1 ] + xSYSTEM_CALL_STACK_INFO * xSysCallInfo = &( xMPUSettings->xSystemCallStackInfo ); + xSysCallInfo->pulSystemCallStackPointer = &( + xSysCallInfo->ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE - 1U ] ); - xMPUSettings->xSystemCallStackInfo.pulSystemCallStackPointer = - ( uint32_t * ) ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo - .pulSystemCallStackPointer ) & + + xSysCallInfo->pulSystemCallStackPointer = + ( uint32_t * ) ( ( uint32_t ) ( xSysCallInfo->pulSystemCallStackPointer ) & ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); /* This is not NULL only for the duration of a system call. */ - xMPUSettings->xSystemCallStackInfo.pulTaskStackPointer = NULL; - /* Set the System Call LR to go directly to vPortSystemCallExit */ - xMPUSettings->xSystemCallStackInfo.pulSystemCallLinkRegister = &vPortSystemCallExit; + xSysCallInfo->pulTaskStackPointer = NULL; + + /* Set the System Call LR to go directly to vPortSystemCallExit */ + xSysCallInfo->pulSystemCallLinkRegister = &vPortSystemCallExit; UBaseType_t ulStackIndex; - /* Fill the System Call Stack with known values for debugging. */ - for( ulStackIndex = 0x0; ulStackIndex < configSYSTEM_CALL_STACK_SIZE; ulStackIndex++ ) - { - xMPUSettings->xSystemCallStackInfo - .ulSystemCallStackBuffer[ ulStackIndex ] = 0x575B | ulStackIndex; - } /* Return the address where the context of this task should be restored from*/ return ( &xMPUSettings->ulContext[ ulContextIndex ] ); From d965464f4e2a22d5bcd0d85ae63fac4356ff8b8d Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Tue, 2 Jan 2024 13:09:29 -0500 Subject: [PATCH 15/51] Use my fork for the Demo builds --- .github/workflows/kernel-demos.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/kernel-demos.yml b/.github/workflows/kernel-demos.yml index 0c925d1fb9..fe1f7fbc56 100644 --- a/.github/workflows/kernel-demos.yml +++ b/.github/workflows/kernel-demos.yml @@ -159,8 +159,8 @@ jobs: - name: Checkout the FreeRTOS/FreeRTOS Repository uses: actions/checkout@v3 with: - ref: main - repository: FreeRTOS/FreeRTOS + ref: ARM_CRx_MPU + repository: skptak/FreeRTOS fetch-depth: 1 - name: Fetch Community-Supported-Demos Submodule From e25b6e145de1facce13651a27e7fe4ff568a3c2b Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Tue, 2 Jan 2024 13:26:24 -0500 Subject: [PATCH 16/51] Formatting fix --- portable/GCC/ARM_CRx_MPU/port.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/portable/GCC/ARM_CRx_MPU/port.c b/portable/GCC/ARM_CRx_MPU/port.c index 07cc62a091..4f6336b55c 100644 --- a/portable/GCC/ARM_CRx_MPU/port.c +++ b/portable/GCC/ARM_CRx_MPU/port.c @@ -228,8 +228,7 @@ PRIVILEGED_DATA volatile uint32_t ulICCEOIR = configEOI_ADDRESS; ); xSysCallInfo->pulSystemCallStackPointer = - ( uint32_t * ) ( ( uint32_t ) ( xSysCallInfo->pulSystemCallStackPointer ) & - ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + ( uint32_t * ) ( ( uint32_t ) ( xSysCallInfo->pulSystemCallStackPointer ) & ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); /* This is not NULL only for the duration of a system call. */ xSysCallInfo->pulTaskStackPointer = NULL; From b0ec6d0cc634bf6bc1d870940cabde5fd92dbb06 Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Tue, 2 Jan 2024 13:38:39 -0500 Subject: [PATCH 17/51] Ignore the clang format file for the header checks --- .github/scripts/kernel_checker.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/scripts/kernel_checker.py b/.github/scripts/kernel_checker.py index 0e8556350d..6992aa2b9e 100755 --- a/.github/scripts/kernel_checker.py +++ b/.github/scripts/kernel_checker.py @@ -37,7 +37,8 @@ 'FreeRTOS-openocd.c', 'Makefile', '.DS_Store', - 'cspell.config.yaml' + 'cspell.config.yaml', + '.clang-format' ] KERNEL_IGNORED_EXTENSIONS = [ From fd19c0ee5279573ac4b02b8effc77d9b29eb2bf2 Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Tue, 2 Jan 2024 15:15:34 -0500 Subject: [PATCH 18/51] Throw an error if configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS is set to 1 --- portable/GCC/ARM_CRx_MPU/portmacro.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/portable/GCC/ARM_CRx_MPU/portmacro.h b/portable/GCC/ARM_CRx_MPU/portmacro.h index 7fdc824790..58d6bb3519 100644 --- a/portable/GCC/ARM_CRx_MPU/portmacro.h +++ b/portable/GCC/ARM_CRx_MPU/portmacro.h @@ -78,6 +78,13 @@ extern "C" { #endif /* configPROTECTED_KERNEL_OBJECT_POOL_SIZE */ #endif /* configENABLE_ACCESS_CONTROL_LIST */ +#ifndef configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS + #define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS 0 +#elif( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) + #error "This port does not support unprivileged tasks to enter a critical section" +#endif /* configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS */ +/* ------------------------- FreeRTOS Config Check ------------------------- */ + /** @brief The size in Bytes that the Privileged System Call Stack should be. * * @ingroup MPU Privilege From a60fe75267aa5529b358263848d2f185e11ea005 Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Wed, 3 Jan 2024 10:16:51 -0500 Subject: [PATCH 19/51] Fix cSpellWords issue --- .github/.cSpellWords.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/.cSpellWords.txt b/.github/.cSpellWords.txt index 69691e85e3..ad0451afb8 100644 --- a/.github/.cSpellWords.txt +++ b/.github/.cSpellWords.txt @@ -44,6 +44,7 @@ BODSTS BRGR BSWTRG Biagioni +Bytesto CANEN CANRX CANTX @@ -71,12 +72,15 @@ CKGR CKLO CKPS CLDIV +CLEARINTENA CLKA CLKB +CLKDIS CLKEN CLKI CLKP CLKS +CLKSOURCE CLKSTA CLRB CLRF @@ -541,6 +545,7 @@ RSTTX RTAR RTCEN RTCSC +RTICTL RTIE RTIF RTIFRC @@ -563,6 +568,7 @@ RXRSM RXSETUP RXSUSP RXSYN +RXTDIS RXTEN RXUBR Rationalised @@ -581,6 +587,7 @@ SECU SENDA SETB SETEN +SETINTENA SETPSW SETR SFRC @@ -691,6 +698,7 @@ TXUBR TXVC TXVDIS UDCP +UNDADD UNRE URAD URAT @@ -704,6 +712,7 @@ Usart VDDCORE VECT VECTACTIVE +VECTKEY VMSRNE VPOPNE VPUSHNE From 56b400f1a2aced332bd5264071ce0d73af37503a Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Wed, 3 Jan 2024 11:05:50 -0500 Subject: [PATCH 20/51] Change the parameters for prvMpuSetRegion() to follow the naming convention a bit more --- portable/GCC/ARM_CRx_MPU/portmacro.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/portable/GCC/ARM_CRx_MPU/portmacro.h b/portable/GCC/ARM_CRx_MPU/portmacro.h index 58d6bb3519..af8cec650d 100644 --- a/portable/GCC/ARM_CRx_MPU/portmacro.h +++ b/portable/GCC/ARM_CRx_MPU/portmacro.h @@ -420,10 +420,10 @@ void prvMpuDisable( void ); * are checked internally before it is called in the port.c file. */ void prvMpuSetRegion( - uint32_t regionNumber, - uint32_t baseAddress, - uint32_t regionSize, - uint32_t regionPermissions + uint32_t ulRegionNumber, + uint32_t ulBaseAddress, + uint32_t ulRegionSize, + uint32_t ulRegionPermissions ); /* ----------------------------- Port C Functions ----------------------------- */ From ae127206fa81a312e0c808002567c4e11aafb49f Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Wed, 3 Jan 2024 11:06:40 -0500 Subject: [PATCH 21/51] Formatting changes for the portASM.S file --- portable/GCC/ARM_CRx_MPU/portASM.S | 266 ++++++++++++++--------------- 1 file changed, 125 insertions(+), 141 deletions(-) diff --git a/portable/GCC/ARM_CRx_MPU/portASM.S b/portable/GCC/ARM_CRx_MPU/portASM.S index 7ae518d5a8..700dccc172 100644 --- a/portable/GCC/ARM_CRx_MPU/portASM.S +++ b/portable/GCC/ARM_CRx_MPU/portASM.S @@ -55,10 +55,8 @@ .extern vTaskSwitchContext .extern vApplicationIRQHandler -/****************************************************************************** - * portSAVE_CONTEXT is used to save all the registers, variables, and MPU - * settings that make up a task's context. - *****************************************************************************/ +/* ------------------------------------------------------------------------- */ +/* Save the register context of a FreeRTOS Task. */ .macro portSAVE_CONTEXT DSB ISB @@ -101,10 +99,8 @@ ADD SP, SP, 0x8 .endm -/****************************************************************************** - * portRESTORE_CONTEXT is used to restore all the registers, variables, and MPU - * settings that make up a task's context. - *****************************************************************************/ +/* ------------------------------------------------------------------------- */ +/* Restore the register context of a FreeRTOS Task. */ .macro portRESTORE_CONTEXT /* Load the address of the current task TCB */ LDR R0, =pxCurrentTCB @@ -122,33 +118,33 @@ LSR R6, #0x8 /* Clear other bits, as there can only be 8-16 regions */ AND R6, 0x1F - /* When creating a loop label in a macro it has to be a numeric label. */ -123: /* For (R5 = portFIRST_CONFIGURABLE_REGION ; R5 <= portSTACK_REGION ; R5++ ) */ - /* Load values of struct MPU_REGION_REGISTERS into R1-R3 */ - LDMIA R1!, {R2-R4} - /* Load the values set in xMPU_REGION_REGISTERS */ - /* R2 Will hold ulRegionSize */ - /* R3 will hold ulRegionAttribute */ - /* R4 will hold ulRegionBaseAddress */ - /* R5 will hold the MPU Region number */ - - /* Select the MPU Region using R5 */ - MCR p15, #0, R5, c6, c2, #0 - /* Set the MPU Region Base Address using ulRegionBaseAddress */ - MCR p15, #0, R4, c6, c1, #0 - /* Set the MPU Region Access Attributes using ulRegionAttribute */ - MCR p15, #0, R3, c6, c1, #4 - /* Set the MPU Region Size, and if the region is enabled using ulRegionSize */ - MCR p15, #0, R2, c6, c1, #2 - /* R5++ */ - ADD R5, R5, #1 - /* R5 <= R6 */ - CMP R5, #portSTACK_REGION - /* R5 <= R6, loop again */ - BLE 123b + /* When creating a loop label in a macro it has to be a numeric label. + * For (R5 = portFIRST_CONFIGURABLE_REGION ; R5 <= portSTACK_REGION ; R5++ ) */ + 123: + /* Load values of struct MPU_REGION_REGISTERS into R2-R4 */ + LDMIA R1!, {R2-R4} + /* Load the values set in xMPU_REGION_REGISTERS + * R2 Will hold ulRegionSize + * R3 will hold ulRegionAttribute + * R4 will hold ulRegionBaseAddress + * R5 will hold the MPU Region number */ + + /* Select the MPU Region using R5 */ + MCR p15, #0, R5, c6, c2, #0 + /* Set the MPU Region Base Address using ulRegionBaseAddress */ + MCR p15, #0, R4, c6, c1, #0 + /* Set the MPU Region Access Attributes using ulRegionAttribute */ + MCR p15, #0, R3, c6, c1, #4 + /* Set the MPU Region Size, and if the region is enabled using ulRegionSize */ + MCR p15, #0, R2, c6, c1, #2 + /* R5++ */ + ADD R5, R5, #1 + /* R5 <= R6 */ + CMP R5, #portSTACK_REGION + /* R5 <= R6, loop again */ + BLE 123b /* R5 > portSTACK_REGION, all MPU regions have been restored */ - /* Restore the critical section nesting depth. */ /* Load the address of the ulCriticalNesting variable into R1 */ LDR R1, =ulCriticalNesting /* Pop the previously saved value of ulCriticalNesting from ulContext */ @@ -157,19 +153,13 @@ STR R2, [R1] #ifdef portENABLE_FPU - /* Restore the Floating Point Context */ - /* Pop the value of FPSCR from ulContext */ - POP {R1} + /* Restore Floating Point Context: Restore previous FPSCR from ulContext */ + POP {R1} /* Move the saved FPSCR value into the FPSCR */ VMSR FPSCR, R1 /* Restore the Floating Point Registers */ VPOP {D0-D15} #endif /* portENABLE_FPU*/ - /* At this point the SVC stack pointer will be in one of three places: - * 1. ulContext[51] - This is the bottom of the context inside of the TCB for task saving - * 1. ulContext[1] - We reloaded a nested context, the next context to restore is a task context - * 2. ulSystemCallStackBuffer[?] - Restoring a nested context inside of an exception handler - */ /* Restore the register context, first need to load the mode bits */ /* Set R1 to be past R0-R12 */ @@ -183,16 +173,14 @@ /* Load R0-R12 from the context */ POP {R0-R12} /* Jump over the already set R13 and R14 */ - ADD SP, SP, #0x8 + ADD SP, SP, #0x8 /* Return from the exception, loading the PC and CPSR */ - RFE SP! + RFE SP! .endm -/****************************************************************************** - * FreeRTOS_Tick_Handler is used to save context, increment the tick count, and - * then switch tasks if neeeded - *****************************************************************************/ +/* ------------------------------------------------------------------------- */ +/* Default FreeRTOS-Kernel System Tick Interrupt for VIM support */ .align 4 .global FreeRTOS_Tick_Handler .type FreeRTOS_Tick_Handler, %function @@ -201,9 +189,8 @@ FreeRTOS_Tick_Handler: SUB LR, LR, #4 /* Save the context of the current task. */ portSAVE_CONTEXT - /* Enter back into IRQ mode after saving task context */ - CPS #IRQ_MODE - /* Clear interrupt flag in RTI. */ + + /* Clear interrupt flag in Real Time Interrupt. */ LDR R0, =configRTI_ADDRESS MOV R1, #1 STR R1, [R0] @@ -218,9 +205,8 @@ FreeRTOS_Tick_Handler: /* Restore the context of the task selected to execute. */ portRESTORE_CONTEXT -/*-----------------------------------------------------------*/ -/* Yield to another task from within the FreeRTOS API */ - +/* ------------------------------------------------------------------------- */ +/* Respond to a pending IRQ raised by the FreeRTOS-Kernel to swap tasks */ .align 4 .global vPortYieldWithinAPI .type vPortYieldWithinAPI, %function @@ -241,9 +227,8 @@ vPortYieldWithinAPI: /* Restore the context of the task selected to execute. */ portRESTORE_CONTEXT -/****************************************************************************** - * vPortStartFirstTask is used to start the scheduler. - *****************************************************************************/ +/* ------------------------------------------------------------------------- */ +/* Load the context of the first task, starting the FreeRTOS-Scheduler */ .align 4 .global vPortStartFirstTask .type vPortStartFirstTask, %function @@ -256,32 +241,28 @@ vPortStartFirstTask: */ /* Swap to SVC Mode for context restore */ CPS #SVC_MODE - /* Restore context of first task, which enables IRQs, starting the sys tick timer */ + /* Load the context of first task, starting the FreeRTOS-Scheduler */ portRESTORE_CONTEXT -/****************************************************************************** - * The FreeRTOS SVC Handler is used to handle Supervisor Calls - *****************************************************************************/ -/** Upon entering here the LR, or R14, will hold the address of the - * following instruction. The instruction can be inspected to determine - * what SVC # was raised. - * This handler is ONLY safe when called from the exposed SVC wrapper functions - * located after this handler in this file. -*/ - - /* Checks: - * 1. SVC is raised from the system call section (i.e. application is - * not raising SVC directly). - * 2. pxMpuSettings->xSystemCallStackInfo.pulTaskStack must be NULL as - * it is non-NULL only during the execution of a system call (i.e. - * between system call enter and exit). - * 3. System call is not for a kernel API disabled by the configuration - * in FreeRTOSConfig.h. - * 4. We do not need to check that ucSystemCallNumber is within range - * because the assembly SVC handler checks that before calling - * this function. - */ - +/* ------------------------------------------------------------------------- */ +/* Handler for Supervisor Calls (SVCs) when using this FreeRTOS Port */ + +/* Upon entering here the LR, or R14, will hold the address of the following + * instruction. This then checks that instruction for the SVC # raised. + * This handler is ONLY safe when called from the exposed SVC wrapper functions + * located after this handler in this file. + * Checks: + * 1. SVC is raised from the system call section (i.e. application is + * not raising SVC directly). + * 2. pxMpuSettings->xSystemCallStackInfo.pulTaskStack must be NULL as + * it is non-NULL only during the execution of a system call (i.e. + * between system call enter and exit). + * 3. System call is not for a kernel API disabled by the configuration + * in FreeRTOSConfig.h. + * 4. We do not need to check that ucSystemCallNumber is within range + * because the assembly SVC handler checks that before calling + * this function. + */ .align 4 .global FreeRTOS_SVC_Handler .type FreeRTOS_SVC_Handler, %function @@ -291,8 +272,8 @@ FreeRTOS_SVC_Handler: /* -------------------- Caller Flash Location Check -------------------- */ - /** The address of the caller will be in the Link Register (LR), it will be - * the caller's Program Counter (PC). Check this address to ensure the + /* The address of the caller will be in the Link Register (LR), it will + * be the caller's Program Counter (PC). Check this address to ensure the * Supervisor call (SVC) was raised from inside the FreRTOS-Kernel. */ /* Get the starting address for FreeRTOS System Calls */ @@ -303,22 +284,18 @@ FreeRTOS_SVC_Handler: LDR R12, =__syscalls_flash_length__ /* Check if an SVC was raised after the end of FreeRTOS System Calls */ CMP R11, R12 - /* If the SVC was raised from outside FreeRTOS System Calls exit */ + /* If the SVC was raised from outside FreeRTOS System Calls exit now */ BGE SVC_Handler_Exit /* ----------------------- Get Caller SVC Number ----------------------- */ -svcNumberCheck: /* The SPSR will be the CPSR of the calling task, store it in R11 */ - MRS R11, SPSR - /* Thumb Mode is bit 5 of the CPSR. And it with the CPSR for comparison check */ + MRS R11, SPSR + /* Thumb Mode is bit 5 of the CPSR, AND for comparison */ ANDS R11, R11, #0x20 - - /* The SVC instruction will be 0x2 before LR in Thumb Mode, or 0x4 if not */ - - /* In Thumb Mode, so get instruction 0x2 before */ + /* In Thumb Mode, the instruction 0x2 before holds the SVC numebr */ LDRHNE R11, [LR, #-0x2] - /* Not in Thumb Mode, so get the instruction 0x4 before */ + /* Not in Thumb Mode, the instruction 0x4 before holds the SVC numebr */ LDRHEQ R11, [LR, #-0x4] /* ---------------------------- SVC Routing ---------------------------- */ @@ -343,24 +320,24 @@ SVC_Handler_Exit: /* This instruction loads the SPSR into the CPSR, performing the mode swap */ MOVS PC, LR -/*-----------------------------------------------------------*/ - -/* Save a FreeRTOS-Task's Context, select a new task, and then restore its context */ +/* ------------------------------------------------------------------------- */ +/* Perform a task swap */ svcPortYield: /* Restore the previously saved R11, R12 */ LDM SP, {R11, R12} /* Save the context of the current task and select a new task to run. */ portSAVE_CONTEXT /* Run the following function from the IRQ stack */ - CPS #IRQ_MODE + CPS #IRQ_MODE /* Select a new task to swap to */ - BL vTaskSwitchContext + BL vTaskSwitchContext /* Swap back to SVC Mode for context restore */ - CPS #SVC_MODE + CPS #SVC_MODE /* Restore the context of the task selected to execute. */ portRESTORE_CONTEXT -/* Swap a task back to using its task stack, and reset its privilege level if needed */ +/* ------------------------------------------------------------------------- */ +/* Reset task stack and link register after a FreeRTOS System Call */ svcSystemCallExit: /* Restore the Task Stack Pointer and Link Register */ /* Load the address of pxCurrentTCB into R11 */ @@ -392,8 +369,8 @@ svcSystemCallExit: /* Jump back */ B SVC_Handler_Exit -/* svcSystemCallEnter */ -/* Swap a task to using the ulSystemCallStack Buffer, and set its privilege high */ +/* ------------------------------------------------------------------------- */ +/* Save task's SP and LR, swap to ulSystemCallStack Buffer, raise privilege */ svcSystemCallEnter: /* Load the base address of the uxSystemCallImplementations[] table into R14 */ LDR R14, =uxSystemCallImplementations @@ -413,9 +390,12 @@ svcSystemCallEnter: ADD R11, R11, #portSYSTEM_CALL_INFO_OFFSET /* Get the value in the TCB for ulTaskStackPointer */ LDMIB R11!, { R12 } - /* Make sure that ulTaskStackPointer was null, meaning that this is initial entry */ - TST R12, #0x0 - /** Hard code the ascii value of the function name and line number to call + /* Ensure ulTaskStackPointer is null, signifying initial entry */ + TEQ R12, #0x0 + /* Make sure that the function pointer loaded is not NULL */ + TEQNE R14, #0x0 + + /* Hard code the ascii value of the function name and line number to call * assert if the ulTaskStackPointer is not null. */ MOVWNE R0, #0x706F MOVTNE R0, #0x7274 @@ -424,7 +404,7 @@ svcSystemCallEnter: /* Store the task's SP and LR to xSYSTEM_CALL_STACK_INFO */ STM R11, {R13-R14}^ - /* It's a compilation warning to use the ! for writeback, so manually move R11 */ + /* Undefined behaviour to auto-increment with the ^ operator */ ADD R11, R11, 0x8 /* Load pulSystemCallStackPointer and pulSystemCallLinkRegister now */ LDM R11, {R13-R14}^ @@ -436,10 +416,10 @@ svcSystemCallEnter: /* Assign the new value to SPSR */ MSR SPSR_cxsf, R12 /* Leave through the SVC Exit */ - B SVC_Handler_Exit + B SVC_Handler_Exit -/*-------------------------------------------------------------------------------*/ -/* vPortEnterCritical */ +/* ------------------------------------------------------------------------- */ +/* Disable IRQs and increment the critical nesting count */ .align 4 .global vPortEnterCritical .type vPortEnterCritical, %function @@ -460,8 +440,8 @@ vPortEnterCritical: POP {R0-R1} BX LR -/*-------------------------------------------------------------------------------*/ -/* vPortDisableInterrupts */ +/* ------------------------------------------------------------------------- */ +/* Disable IRQs */ .align 4 .global vPortDisableInterrupts .type vPortDisableInterrupts, %function @@ -471,14 +451,14 @@ vPortDisableInterrupts: /* Return to caller */ BX LR -/*-------------------------------------------------------------------------------*/ -/* vPortExitCritical */ +/* ------------------------------------------------------------------------- */ +/* Enable IRQs and decrement the critical nesting count */ .align 4 .global vPortExitCritical .type vPortExitCritical, %function vPortExitCritical: /* Store two scratch registers */ - PUSH {R0-R1} + PUSH { R0-R1 } /* Load address of current critical nesting count */ LDR R0, =ulCriticalNesting /* Load value of current critical nesting count */ @@ -495,8 +475,8 @@ vPortExitCritical: POP {R0-R1} BX LR -/*-------------------------------------------------------------------------------*/ -/* vPortEnableInterrupts */ +/* ------------------------------------------------------------------------- */ +/* Enable IRQs */ .align 4 .global vPortEnableInterrupts .type vPortEnableInterrupts, %function @@ -504,67 +484,71 @@ vPortEnableInterrupts: /* Enable IRQs */ CPSIE I /* Return to caller */ - BX LR + BX LR -/****************************************************************************** - * prvMpuSetRegion is used to set the base address, access attributes, - * and the size and enable bits of a selected MPU region. - * void prvMpuSetRegion(unsigned region, unsigned base, unsigned size, unsigned access) - *****************************************************************************/ +/* ------------------------------------------------------------------------- */ +/** Set MPU Registers using provided values + * Function: void prvMpuSetRegion + * Inputs: uint32_t ulRegionNumber + * Inputs: uint32_t ulBaseAddress + * Inputs: uint32_t ulRegionSize + * Inputs: uint32_t ulRegionPermissions +*/ .align 4 .global prvMpuSetRegion .type prvMpuSetRegion, %function prvMpuSetRegion: /* Only 15 possible regions, drop all other bits */ - AND R0, R0, #15 + AND R0, R0, #15 /* Select the MPU Region selected by region */ - MCR p15, #0, R0, c6, c2, #0 + MCR p15, #0, R0, c6, c2, #0 /* Set the Base Address to be base */ - MCR p15, #0, R1, c6, c1, #0 + MCR p15, #0, R1, c6, c1, #0 /* Set the Access Attributes to be access */ - MCR p15, #0, R3, c6, c1, #4 + MCR p15, #0, R3, c6, c1, #4 /* Set the Size and Enable bits to be size */ - MCR p15, #0, R2, c6, c1, #2 - BX LR + MCR p15, #0, R2, c6, c1, #2 + /* Return to caller */ + BX LR -/****************************************************************************** - * prvMpuEnable is used to set the Enable bit of the MPU Enable Register to 1. - *****************************************************************************/ +/* ------------------------------------------------------------------------- */ +/* Set the Enable bit of the MPU Enable Register to 1. */ .align 4 .global prvMpuEnable .type prvMpuEnable, %function prvMpuEnable: /* Read the current MPU control register into R0 */ - MRC p15, #0, R0, c1, c0, #0 + MRC p15, #0, R0, c1, c0, #0 /* Set the enable bit to high */ - ORR R0, R0, #0x1 + ORR R0, R0, #0x1 /* Data sync */ DSB /* Write out previous MPU control register with a high enable bit */ - MCR p15, #0, R0, c1, c0, #0 + MCR p15, #0, R0, c1, c0, #0 /* Instruction sync */ ISB - BX LR + /* Return to caller */ + BX LR -/****************************************************************************** - * prvMpuDisable is used to set the Enable bit of the MPU Enable Register to 0. - *****************************************************************************/ +/* ------------------------------------------------------------------------- */ +/* Set the Enable bit of the MPU Enable Register to 0. */ .align 4 .global prvMpuDisable .type prvMpuDisable, %function prvMpuDisable: /* Read the MPU enable register values into R0 */ - MRC p15, #0, R0, c1, c0, #0 - /* Clear out all bits in R0 except for bit 1 */ - BIC R0, R0, #1 + MRC p15, #0, R0, c1, c0, #0 + /* Perform a bitwise AND of R0 and NOT #1, i.e. clear bit 1 */ + BIC R0, R0, #1 /* Wait for all pending explicit data accesses to complete */ DSB /* Write out to the MPU Enable Register */ - MCR p15, #0, R0, c1, c0, #0 + MCR p15, #0, R0, c1, c0, #0 /* Flushes the pipeline and prefetch buffer(s) in the processor. */ /* Ensures all following instructions are fetched from cache or memory. */ ISB - BX LR + /* Return to caller */ + BX LR .align 4 .global FreeRTOS_IRQ_Handler From d23078088c57da666748c522cc080bea57da592c Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Wed, 3 Jan 2024 17:04:10 -0500 Subject: [PATCH 22/51] Remove the use of ulContext and a controlled SVC stack pointer for the port --- portable/GCC/ARM_CRx_MPU/port.c | 7 +- portable/GCC/ARM_CRx_MPU/portASM.S | 176 ++++++++++------------- portable/GCC/ARM_CRx_MPU/portmacro_asm.h | 11 +- 3 files changed, 84 insertions(+), 110 deletions(-) diff --git a/portable/GCC/ARM_CRx_MPU/port.c b/portable/GCC/ARM_CRx_MPU/port.c index 4f6336b55c..bdaf388656 100644 --- a/portable/GCC/ARM_CRx_MPU/port.c +++ b/portable/GCC/ARM_CRx_MPU/port.c @@ -103,10 +103,6 @@ PRIVILEGED_DATA volatile uint32_t ulICCEOIR = configEOI_ADDRESS; * expected by the portRESTORE_CONTEXT() macro. */ UBaseType_t ulContextIndex = MAX_CONTEXT_SIZE - 1U; - /* These two locations are used for SVC entry, fill them for debugging */ - xMPUSettings->ulContext[ ulContextIndex-- ] = 0xFEED2002; - xMPUSettings->ulContext[ ulContextIndex-- ] = 0xFEED1001; - if( xRunPrivileged == pdTRUE ) { /* Current Program Status and Control Register */ @@ -235,9 +231,8 @@ PRIVILEGED_DATA volatile uint32_t ulICCEOIR = configEOI_ADDRESS; /* Set the System Call LR to go directly to vPortSystemCallExit */ xSysCallInfo->pulSystemCallLinkRegister = &vPortSystemCallExit; - UBaseType_t ulStackIndex; - /* Return the address where the context of this task should be restored from*/ + /* Return the address where the context of this task should be restored from */ return ( &xMPUSettings->ulContext[ ulContextIndex ] ); } diff --git a/portable/GCC/ARM_CRx_MPU/portASM.S b/portable/GCC/ARM_CRx_MPU/portASM.S index 700dccc172..96d75c9bf9 100644 --- a/portable/GCC/ARM_CRx_MPU/portASM.S +++ b/portable/GCC/ARM_CRx_MPU/portASM.S @@ -55,69 +55,67 @@ .extern vTaskSwitchContext .extern vApplicationIRQHandler -/* ------------------------------------------------------------------------- */ +/* ----------------------------------------------------------------------------------- */ /* Save the register context of a FreeRTOS Task. */ .macro portSAVE_CONTEXT DSB ISB - /* Move the SVC SP backwards before calling the SRS */ - SRSDB SP!, #SVC_MODE - /* Change to Supervisor Mode for the Context Save */ - CPS #SVC_MODE - /* Get the saved SPSR that was pushed to the SVC SP */ - LDR LR, [SP, #0x4] - /* Move it to our SPSR so we can save the correct SP and LR */ - MSR SPSR_cxsf, LR - /* Save the previous operating modes Registers, Stack Pointer, and Link Register */ - STMDB SP, {R0-R14}^ - /** Can't do a PUSH when using the ^ character, so need to manually move - * the SP after pushing the registers */ - SUB SP, SP, #portREGISTER_CONTEXT_LENGTH -#ifdef portENABLE_FPU - /* Save the floating point context */ - /* Push the 16 floating point registers onto the stack */ - VPUSH {D0-D15} - /* Load the FPSCR into R0 */ - FMRX R0, FPSCR - /* Push the value of FPSCR onto the stack */ - PUSH {R0} -#endif /* portENABLE_FPU */ + /* Push R0 and the Link Register (LR) for scratch register space */ + PUSH { R0, LR } + /* Load the pointer to the current task's Task Control Block (TCB) */ + LDR LR, =pxCurrentTCB + /* Load the actual TCB into LR */ + LDR LR, [LR] + /* Set LR to pxTopOfStack, the address of where to save the task context */ + LDR LR, [LR] + /* Load the address of ulCriticalNesting */ LDR R0, =ulCriticalNesting /* Load the value of ulCriticalNesting into R0 */ LDR R0, [R0] /* Push the value of ulCriticalNesting into the context */ - PUSH {R0} - /* Load the address of pxCurrentTCB into R0 */ - LDR R0, =pxCurrentTCB - /* Load the TCB into R0 */ - LDR R0, [R0] - /* Set pxTopOfStack in the TCB to be the current Stack Pointer. This is - * where to load the FreeRTOS-Task context from. */ - STR SP, [R0] - /* Move the SVC SP forward to the scratch area in ulContext */ - ADD SP, SP, 0x8 + STM LR!, {R0} + +#if ( portENABLE_FPU == 1 ) + /* Save the floating point context */ + /* Load the Floating Point Status and Control Register (FPSRC) into R1 */ + FMRX R0, FPSCR + /* Push the value of FPSCR onto the stack */ + STM LR!, { R0 } + /* Push the 32 Floating Point Registers (FPRs) onto the stack */ + VSTM LR!, { D0-D15 } +#endif /* ( portENABLE_FPU == 1 ) */ + + /* Restore the saved R0 */ + POP { R0 } + /* Save the pre-exception Registers, Stack Pointer (SP), and LR */ + STM LR, { R0-R14 }^ + /* Increment the LR after the popped registers */ + ADD LR, LR, #portGPR_LENGTH + /* Pop the pushed LR, which is the pre-exception Program Counter (PC) */ + POP { R0 } + /* Move the pre-exception Current Program Status and Control Register (CPSR) + * which is banked as the Saved Program Status and Control Register (SPSR) + * to R1 to save as part of the context. */ + MRS R1, SPSR + /* Store the pre-exception CPSR and PC */ + STM LR!, { R0-R1 } + .endm -/* ------------------------------------------------------------------------- */ +/* ----------------------------------------------------------------------------------- */ /* Restore the register context of a FreeRTOS Task. */ .macro portRESTORE_CONTEXT - /* Load the address of the current task TCB */ - LDR R0, =pxCurrentTCB - /* Load the TCB into R0 */ - LDR R0, [R0] + /* Load the pointer to the current task's Task Control Block (TCB) */ + LDR LR, =pxCurrentTCB + /* Load the actual TCB into LR */ + LDR LR, [LR] /* Set R1 to the second member of the TCB struct, xMPUSettings */ - ADD R1, R0, #0x4 - /* Set our SP to pxTopOfStack, the address of the Task context */ - LDR SP, [R0] + ADD R1, LR, #0x4 + /* Set LR to pxTopOfStack, the address to restore the task context from */ + LDR LR, [LR] /* Load the first per-task MPU region into R5 */ MOV R5, #portFIRST_CONFIGURABLE_REGION - /* Dynamically load the last MPU region */ - MRC p15, 0, R6, c0, c0, 0x4 - /* Move the number of MPU regions forward */ - LSR R6, #0x8 - /* Clear other bits, as there can only be 8-16 regions */ - AND R6, 0x1F /* When creating a loop label in a macro it has to be a numeric label. * For (R5 = portFIRST_CONFIGURABLE_REGION ; R5 <= portSTACK_REGION ; R5++ ) */ 123: @@ -148,38 +146,33 @@ /* Load the address of the ulCriticalNesting variable into R1 */ LDR R1, =ulCriticalNesting /* Pop the previously saved value of ulCriticalNesting from ulContext */ - POP {R2} + LDM LR!, { R2 } /* Store the value of ulCriticalNesting into address of ulCriticalNesting */ STR R2, [R1] -#ifdef portENABLE_FPU +#if ( portENABLE_FPU == 1 ) /* Restore Floating Point Context: Restore previous FPSCR from ulContext */ - POP {R1} + LDM LR!, { R1 } /* Move the saved FPSCR value into the FPSCR */ VMSR FPSCR, R1 /* Restore the Floating Point Registers */ - VPOP {D0-D15} + VLDM LR!, {D0-D15} #endif /* portENABLE_FPU*/ - /* Restore the register context, first need to load the mode bits */ - /* Set R1 to be past R0-R12 */ - ADD R1, SP, #portGPR_LENGTH - /* Get the CPSR from the context, needed to set the SP and the LR */ - LDR R2, [R1, +#0x0C] + /* Load the value of the CPSR into R1, needed to set the SP and the LR */ + LDR R0, [LR, +#portREGISTER_CONTEXT_LENGTH] /* Move the CPSR the into our SPSR */ - MSR SPSR_cxsf, R2 - /* Load the stored Stack Pointer and Link Register */ - LDM R1, {R13-R14}^ - /* Load R0-R12 from the context */ - POP {R0-R12} - /* Jump over the already set R13 and R14 */ - ADD SP, SP, #0x8 - /* Return from the exception, loading the PC and CPSR */ - RFE SP! + MSR SPSR_cxsf, R0 + /* Restore the saved Stack Pointer and Link Register */ + LDM LR, {R0-R14}^ + /* Increment the Link Register after the popped registers */ + ADD LR, LR, #portGPR_LENGTH + /* Load the PC to return from the exception */ + RFE LR .endm -/* ------------------------------------------------------------------------- */ +/* ----------------------------------------------------------------------------------- */ /* Default FreeRTOS-Kernel System Tick Interrupt for VIM support */ .align 4 .global FreeRTOS_Tick_Handler @@ -187,9 +180,8 @@ FreeRTOS_Tick_Handler: /* Return to the interrupted instruction. */ SUB LR, LR, #4 - /* Save the context of the current task. */ + /* Save Currently Executing Task Context */ portSAVE_CONTEXT - /* Clear interrupt flag in Real Time Interrupt. */ LDR R0, =configRTI_ADDRESS MOV R1, #1 @@ -200,12 +192,10 @@ FreeRTOS_Tick_Handler: /* If xTaskIncrementTick returned non-zero then select the next task to execute. */ CMP R0, #0 BLNE vTaskSwitchContext - /* Swap to SVC Mode to restore the task context */ - CPS #SVC_MODE /* Restore the context of the task selected to execute. */ portRESTORE_CONTEXT -/* ------------------------------------------------------------------------- */ +/* ----------------------------------------------------------------------------------- */ /* Respond to a pending IRQ raised by the FreeRTOS-Kernel to swap tasks */ .align 4 .global vPortYieldWithinAPI @@ -213,21 +203,17 @@ FreeRTOS_Tick_Handler: vPortYieldWithinAPI: /* Return to the interrupted instruction. */ SUB LR, LR, #4 - /* Save the context of the current task */ + /* Save Currently Executing Task Context */ portSAVE_CONTEXT - /* Swap back to IRQ Mode for selecting the next task */ - CPS #IRQ_MODE /* Clear the Interrupt Flag for vPortYieldWithinAPI */ MOV R0, #configSSI_ADDRESS LDR R0, [R0] /* Select the next task to execute. */ BL vTaskSwitchContext - /* Swap back to SVC Mode for context restore */ - CPS #SVC_MODE /* Restore the context of the task selected to execute. */ portRESTORE_CONTEXT -/* ------------------------------------------------------------------------- */ +/* ----------------------------------------------------------------------------------- */ /* Load the context of the first task, starting the FreeRTOS-Scheduler */ .align 4 .global vPortStartFirstTask @@ -244,13 +230,11 @@ vPortStartFirstTask: /* Load the context of first task, starting the FreeRTOS-Scheduler */ portRESTORE_CONTEXT -/* ------------------------------------------------------------------------- */ +/* ----------------------------------------------------------------------------------- */ /* Handler for Supervisor Calls (SVCs) when using this FreeRTOS Port */ /* Upon entering here the LR, or R14, will hold the address of the following * instruction. This then checks that instruction for the SVC # raised. - * This handler is ONLY safe when called from the exposed SVC wrapper functions - * located after this handler in this file. * Checks: * 1. SVC is raised from the system call section (i.e. application is * not raising SVC directly). @@ -267,8 +251,8 @@ vPortStartFirstTask: .global FreeRTOS_SVC_Handler .type FreeRTOS_SVC_Handler, %function FreeRTOS_SVC_Handler: - /* Push R11 and R12 to the bottom two, pre-resereved, addresses in ulContext */ - STM R13, {R11, R12} + /* Push R10-R12 for scratch space */ + PUSH { R10-R12 } /* -------------------- Caller Flash Location Check -------------------- */ @@ -316,27 +300,23 @@ FreeRTOS_SVC_Handler: /* If one of the above jumps wasn't taken, go straight to the exit */ SVC_Handler_Exit: /** Restore the saved R11 and R12, then return to the caller */ - LDM SP, {R11, R12} + POP { R10-R12 } /* This instruction loads the SPSR into the CPSR, performing the mode swap */ MOVS PC, LR -/* ------------------------------------------------------------------------- */ +/* ----------------------------------------------------------------------------------- */ /* Perform a task swap */ svcPortYield: /* Restore the previously saved R11, R12 */ - LDM SP, {R11, R12} + POP { R10-R12 } /* Save the context of the current task and select a new task to run. */ portSAVE_CONTEXT - /* Run the following function from the IRQ stack */ - CPS #IRQ_MODE /* Select a new task to swap to */ BL vTaskSwitchContext - /* Swap back to SVC Mode for context restore */ - CPS #SVC_MODE /* Restore the context of the task selected to execute. */ portRESTORE_CONTEXT -/* ------------------------------------------------------------------------- */ +/* ----------------------------------------------------------------------------------- */ /* Reset task stack and link register after a FreeRTOS System Call */ svcSystemCallExit: /* Restore the Task Stack Pointer and Link Register */ @@ -369,7 +349,7 @@ svcSystemCallExit: /* Jump back */ B SVC_Handler_Exit -/* ------------------------------------------------------------------------- */ +/* ----------------------------------------------------------------------------------- */ /* Save task's SP and LR, swap to ulSystemCallStack Buffer, raise privilege */ svcSystemCallEnter: /* Load the base address of the uxSystemCallImplementations[] table into R14 */ @@ -418,7 +398,7 @@ svcSystemCallEnter: /* Leave through the SVC Exit */ B SVC_Handler_Exit -/* ------------------------------------------------------------------------- */ +/* ----------------------------------------------------------------------------------- */ /* Disable IRQs and increment the critical nesting count */ .align 4 .global vPortEnterCritical @@ -440,7 +420,7 @@ vPortEnterCritical: POP {R0-R1} BX LR -/* ------------------------------------------------------------------------- */ +/* ----------------------------------------------------------------------------------- */ /* Disable IRQs */ .align 4 .global vPortDisableInterrupts @@ -451,7 +431,7 @@ vPortDisableInterrupts: /* Return to caller */ BX LR -/* ------------------------------------------------------------------------- */ +/* ----------------------------------------------------------------------------------- */ /* Enable IRQs and decrement the critical nesting count */ .align 4 .global vPortExitCritical @@ -475,7 +455,7 @@ vPortExitCritical: POP {R0-R1} BX LR -/* ------------------------------------------------------------------------- */ +/* ----------------------------------------------------------------------------------- */ /* Enable IRQs */ .align 4 .global vPortEnableInterrupts @@ -486,7 +466,7 @@ vPortEnableInterrupts: /* Return to caller */ BX LR -/* ------------------------------------------------------------------------- */ +/* ----------------------------------------------------------------------------------- */ /** Set MPU Registers using provided values * Function: void prvMpuSetRegion * Inputs: uint32_t ulRegionNumber @@ -511,7 +491,7 @@ prvMpuSetRegion: /* Return to caller */ BX LR -/* ------------------------------------------------------------------------- */ +/* ----------------------------------------------------------------------------------- */ /* Set the Enable bit of the MPU Enable Register to 1. */ .align 4 .global prvMpuEnable @@ -530,7 +510,7 @@ prvMpuEnable: /* Return to caller */ BX LR -/* ------------------------------------------------------------------------- */ +/* ----------------------------------------------------------------------------------- */ /* Set the Enable bit of the MPU Enable Register to 0. */ .align 4 .global prvMpuDisable diff --git a/portable/GCC/ARM_CRx_MPU/portmacro_asm.h b/portable/GCC/ARM_CRx_MPU/portmacro_asm.h index d8c5423cc9..29d4ffe92c 100644 --- a/portable/GCC/ARM_CRx_MPU/portmacro_asm.h +++ b/portable/GCC/ARM_CRx_MPU/portmacro_asm.h @@ -479,12 +479,12 @@ extern "C" { /** @brief The length in ulContext for the General Purpose Registers in bytes * @note There are 13 GPRs, R0-R12 each is 32 bits, so 13 registers * 4 Bytes each */ -#define portGPR_LENGTH ( 13U * 4U ) +#define portGPR_LENGTH ( 15U * 4U ) /** @brief The length in ulContext for all the registers in a context * @note There are the 13 GPRs, the Stack Pointer, and the Link Register */ -#define portREGISTER_CONTEXT_LENGTH ( portGPR_LENGTH + ( 2 * 4U ) ) +#define portREGISTER_CONTEXT_LENGTH ( ( 16 * 4U ) ) /** If you KNOW that your system will not utilize the FPU in any capacity * you can set portENABLE_FPU to 0, which will reduce the per-task RAM usage @@ -512,18 +512,17 @@ extern "C" { * ulContext[ 48 ]: Link Register * ulContext[ 49 ]: Program Counter * ulContext[ 50 ]: Current Program Status and Control Register - * ulContext[ 51 ]: Supervisor Mode SRS PC Scratch Space - * ulContext[ 52 ]: Supervisor Mode SRS CPSR Scratch Space */ #define portENABLE_FPU configENABLE_FPU #if( portENABLE_FPU == 1 ) /** @brief Length of a Task's Register Context when using an FPU. */ - #define MAX_CONTEXT_SIZE 52U + #define MAX_CONTEXT_SIZE 50U #else /** @brief Length of a Task's Register Context when not using an FPU. */ - #define MAX_CONTEXT_SIZE 20U + #define MAX_CONTEXT_SIZE 18U #endif + /** @brief Numerical offset from the start of a TCB to xSystemCallStackInfo * @note In the exception handlers it is necessary to load this variable from the TCB. * This provides an easy way for the exception handlers to get this structure. From 0fc0a5fbbabadfc0a7c9e5be6ea7387872b7f8b1 Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Wed, 3 Jan 2024 17:14:36 -0500 Subject: [PATCH 23/51] Formatting fix --- portable/GCC/ARM_CRx_MPU/portmacro_asm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/portable/GCC/ARM_CRx_MPU/portmacro_asm.h b/portable/GCC/ARM_CRx_MPU/portmacro_asm.h index 29d4ffe92c..2545403a09 100644 --- a/portable/GCC/ARM_CRx_MPU/portmacro_asm.h +++ b/portable/GCC/ARM_CRx_MPU/portmacro_asm.h @@ -484,7 +484,7 @@ extern "C" { /** @brief The length in ulContext for all the registers in a context * @note There are the 13 GPRs, the Stack Pointer, and the Link Register */ -#define portREGISTER_CONTEXT_LENGTH ( ( 16 * 4U ) ) +#define portREGISTER_CONTEXT_LENGTH ( ( 16 * 4U ) ) /** If you KNOW that your system will not utilize the FPU in any capacity * you can set portENABLE_FPU to 0, which will reduce the per-task RAM usage From 63dfe612be7f19ddbaa48a4fef51cb2b0be7702c Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Thu, 4 Jan 2024 08:59:47 -0500 Subject: [PATCH 24/51] Fix assert check in svc enter, remove un-used defines --- portable/GCC/ARM_CRx_MPU/portASM.S | 26 +++++++++++----------- portable/GCC/ARM_CRx_MPU/portmacro_asm.h | 28 ++---------------------- 2 files changed, 15 insertions(+), 39 deletions(-) diff --git a/portable/GCC/ARM_CRx_MPU/portASM.S b/portable/GCC/ARM_CRx_MPU/portASM.S index 96d75c9bf9..63ba3cf477 100644 --- a/portable/GCC/ARM_CRx_MPU/portASM.S +++ b/portable/GCC/ARM_CRx_MPU/portASM.S @@ -78,7 +78,7 @@ #if ( portENABLE_FPU == 1 ) /* Save the floating point context */ - /* Load the Floating Point Status and Control Register (FPSRC) into R1 */ + /* Copy the Floating Point Status and Control Register (FPSRC) */ FMRX R0, FPSCR /* Push the value of FPSCR onto the stack */ STM LR!, { R0 } @@ -86,7 +86,7 @@ VSTM LR!, { D0-D15 } #endif /* ( portENABLE_FPU == 1 ) */ - /* Restore the saved R0 */ + /* Restore the saved register */ POP { R0 } /* Save the pre-exception Registers, Stack Pointer (SP), and LR */ STM LR, { R0-R14 }^ @@ -94,9 +94,9 @@ ADD LR, LR, #portGPR_LENGTH /* Pop the pushed LR, which is the pre-exception Program Counter (PC) */ POP { R0 } - /* Move the pre-exception Current Program Status and Control Register (CPSR) + /* Copy the pre-exception Current Program Status and Control Register (CPSR) * which is banked as the Saved Program Status and Control Register (SPSR) - * to R1 to save as part of the context. */ + * to save it as part of the context. */ MRS R1, SPSR /* Store the pre-exception CPSR and PC */ STM LR!, { R0-R1 } @@ -373,14 +373,14 @@ svcSystemCallEnter: /* Ensure ulTaskStackPointer is null, signifying initial entry */ TEQ R12, #0x0 /* Make sure that the function pointer loaded is not NULL */ - TEQNE R14, #0x0 + CMPEQ R14, #0x0 /* Hard code the ascii value of the function name and line number to call * assert if the ulTaskStackPointer is not null. */ - MOVWNE R0, #0x706F - MOVTNE R0, #0x7274 - MOVNE R1, #458 - BNE vAssertCalled + MOVWEQ R0, #0x706F + MOVTEQ R0, #0x7274 + MOVEQ R1, #458 + BEQ vAssertCalled /* Store the task's SP and LR to xSYSTEM_CALL_STACK_INFO */ STM R11, {R13-R14}^ @@ -480,13 +480,13 @@ vPortEnableInterrupts: prvMpuSetRegion: /* Only 15 possible regions, drop all other bits */ AND R0, R0, #15 - /* Select the MPU Region selected by region */ + /* Select the MPU Region selected by ulRegionNumber */ MCR p15, #0, R0, c6, c2, #0 - /* Set the Base Address to be base */ + /* Set the Base Address to be ulBaseAddress */ MCR p15, #0, R1, c6, c1, #0 - /* Set the Access Attributes to be access */ + /* Set the Access Attributes to be ulRegionPermissions */ MCR p15, #0, R3, c6, c1, #4 - /* Set the Size and Enable bits to be size */ + /* Set the Size and Enable bits to be ulRegionSize */ MCR p15, #0, R2, c6, c1, #2 /* Return to caller */ BX LR diff --git a/portable/GCC/ARM_CRx_MPU/portmacro_asm.h b/portable/GCC/ARM_CRx_MPU/portmacro_asm.h index 2545403a09..ec18b93303 100644 --- a/portable/GCC/ARM_CRx_MPU/portmacro_asm.h +++ b/portable/GCC/ARM_CRx_MPU/portmacro_asm.h @@ -37,16 +37,14 @@ extern "C" { #ifndef configTOTAL_MPU_REGIONS #error "Set configTOTAL_MPU_REGIONS to the humber of MPU regions in FreeRTOSConfig.h" -#endif /* configTOTAL_MPU_REGIONS */ - -#if( configTOTAL_MPU_REGIONS == 8 ) +#elif( configTOTAL_MPU_REGIONS == 8 ) #define portMPU_TOTAL_REGIONS ( 8UL ) #elif( configTOTAL_MPU_REGIONS == 12 ) #define portMPU_TOTAL_REGIONS ( 12UL ) #elif( configTOTAL_MPU_REGIONS == 16 ) #define portMPU_TOTAL_REGIONS ( 16UL ) #else - #error Please specify the number of MPU regions available for your microcontroller + #error "Set configTOTAL_MPU_REGIONS to the humber of MPU regions in FreeRTOSConfig.h" #endif /** On the ArmV7-R Architecture the Operating mode of the Processor is set using @@ -143,28 +141,6 @@ extern "C" { #define portMPU_SUBREGION_6_DISABLE ( 0x1UL << 14UL ) #define portMPU_SUBREGION_7_DISABLE ( 0x1UL << 15UL ) -#define MPU_REGION_COUNT_OFFSET 8U -#define MPU_REGION_COUNT_MASK ( 0xFFUL << MPU_REGION_COUNT_OFFSET ) - -#define portSTACK_GUARD \ - portMPU_SUBREGION_0_DISABLE | portMPU_SUBREGION_1_DISABLE | \ - portMPU_SUBREGION_2_DISABLE | portMPU_SUBREGION_3_DISABLE | \ - portMPU_SUBREGION_4_DISABLE | portMPU_SUBREGION_5_DISABLE | \ - portMPU_SUBREGION_6_DISABLE | portMPU_SUBREGION_7_DISABLE - -#define portUND_STACK_GUARD portSTACK_GUARD & ~portMPU_SUBREGION_0_DISABLE -#define portSVC_STACK_GUARD portSTACK_GUARD & ~portMPU_SUBREGION_1_DISABLE - -#define portFIQ_STACK_GUARD \ - portSTACK_GUARD & ~portMPU_SUBREGION_2_DISABLE | ~portMPU_SUBREGION_3_DISABLE - -#define portABT_STACK_GUARD \ - portSTACK_GUARD & ~portMPU_SUBREGION_4_DISABLE | ~portMPU_SUBREGION_5_DISABLE - -#define portIRQ_STACK_GUARD \ - ( ( portSTACK_GUARD ) & ( ~portMPU_SUBREGION_7_DISABLE ) & \ - ( ~portMPU_SUBREGION_7_DISABLE ) ) - /* Default MPU regions */ #define portFIRST_CONFIGURABLE_REGION ( 0 ) #define portLAST_CONFIGURABLE_REGION ( portMPU_TOTAL_REGIONS - 6UL ) From aacae9f21c5b92f7931eab718edd22b48020e7b5 Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Thu, 4 Jan 2024 12:16:55 -0500 Subject: [PATCH 25/51] Fix formatting in portmacro_asm.h --- portable/GCC/ARM_CRx_MPU/portmacro_asm.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/portable/GCC/ARM_CRx_MPU/portmacro_asm.h b/portable/GCC/ARM_CRx_MPU/portmacro_asm.h index ec18b93303..b10f9351a2 100644 --- a/portable/GCC/ARM_CRx_MPU/portmacro_asm.h +++ b/portable/GCC/ARM_CRx_MPU/portmacro_asm.h @@ -142,13 +142,13 @@ extern "C" { #define portMPU_SUBREGION_7_DISABLE ( 0x1UL << 15UL ) /* Default MPU regions */ -#define portFIRST_CONFIGURABLE_REGION ( 0 ) -#define portLAST_CONFIGURABLE_REGION ( portMPU_TOTAL_REGIONS - 6UL ) -#define portSTACK_REGION ( portMPU_TOTAL_REGIONS - 5UL ) -#define portGENERAL_PERIPHERALS_REGION ( portMPU_TOTAL_REGIONS - 4UL ) -#define portUNPRIVILEGED_FLASH_REGION ( portMPU_TOTAL_REGIONS - 3UL ) -#define portPRIVILEGED_FLASH_REGION ( portMPU_TOTAL_REGIONS - 2UL ) -#define portPRIVILEGED_RAM_REGION ( portMPU_TOTAL_REGIONS - 1UL ) +#define portFIRST_CONFIGURABLE_REGION ( 0 ) +#define portLAST_CONFIGURABLE_REGION ( portMPU_TOTAL_REGIONS - 6UL ) +#define portSTACK_REGION ( portMPU_TOTAL_REGIONS - 5UL ) +#define portGENERAL_PERIPHERALS_REGION ( portMPU_TOTAL_REGIONS - 4UL ) +#define portUNPRIVILEGED_FLASH_REGION ( portMPU_TOTAL_REGIONS - 3UL ) +#define portPRIVILEGED_FLASH_REGION ( portMPU_TOTAL_REGIONS - 2UL ) +#define portPRIVILEGED_RAM_REGION ( portMPU_TOTAL_REGIONS - 1UL ) #define portNUM_CONFIGURABLE_REGIONS \ ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1UL ) /* Plus one to make space for the stack region*/ From 8f9deb451470c7918147ea01195cc59e5720f4ff Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Tue, 9 Jan 2024 11:34:48 -0500 Subject: [PATCH 26/51] Add the system call table as an actual extern declaration to the ASM file --- portable/GCC/ARM_CRx_MPU/portASM.S | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/portable/GCC/ARM_CRx_MPU/portASM.S b/portable/GCC/ARM_CRx_MPU/portASM.S index 63ba3cf477..c7278859d6 100644 --- a/portable/GCC/ARM_CRx_MPU/portASM.S +++ b/portable/GCC/ARM_CRx_MPU/portASM.S @@ -39,6 +39,7 @@ /* External FreeRTOS-Kernel Variables */ .extern pxCurrentTCB + .extern uxSystemCallImplementations .extern ulPortInterruptNesting .extern ulICCEOIR .extern ulPortYieldRequired @@ -125,7 +126,7 @@ * R2 Will hold ulRegionSize * R3 will hold ulRegionAttribute * R4 will hold ulRegionBaseAddress - * R5 will hold the MPU Region number */ + * R5 will hold the MPU Region number */ /* Select the MPU Region using R5 */ MCR p15, #0, R5, c6, c2, #0 From 501daf43bca317ee83ba0cfd8a2e32a4ea8fb960 Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Tue, 9 Jan 2024 11:48:20 -0500 Subject: [PATCH 27/51] Update spelling wordlist --- .github/.cSpellWords.txt | 44 ++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/.github/.cSpellWords.txt b/.github/.cSpellWords.txt index e0db1d75d5..e583e5373e 100644 --- a/.github/.cSpellWords.txt +++ b/.github/.cSpellWords.txt @@ -119,6 +119,7 @@ CRGFLG CRGINT CRTV CSAAT +CSDK CTCR CTRLA CTSIC @@ -137,8 +138,10 @@ DATNB DATRDY DBGU DCDIC +DCMOCK DCMR DCOUNT +DECIHOURS DECNT DFPU DFREERTOS @@ -176,6 +179,7 @@ DTXD DUNITY DVAR Dconfig +Decihours EABI ECIT ECRS @@ -406,6 +410,7 @@ NFIQ NIOSII NIRQ NOGIC +NONDET NPCS NRSTL NSACR @@ -414,12 +419,9 @@ NSSR NTRST NVIC Nios +Nondet ODAT ODSR -OINC -OIWBNOWA -OIWBWA -OIWTNOWA OPMOD OPTIMISED ORCCR @@ -624,7 +626,14 @@ SWINTR SWRST SWTRG SYSC +SYSCLK +SYSCLOCK +SYSClk Stellaris +SysClk +SysClock +Sysclk +Sysclock TACCR TACCTL TACLR @@ -698,9 +707,12 @@ TXUBR TXVC TXVDIS UDCP -uncrustify +UNACKED UNDADD +UNPADDED UNRE +UNSUB +UNSUBACK URAD URAT URSTEN @@ -709,20 +721,20 @@ URSTS USART USPRG USRIO +Unpadded +Unprotect +Unprotected Usart VDDCORE VECT VECTACTIVE VECTKEY -visualisation -vldmdbeq -vldmia -vldmiaeq VMSRNE VPOPNE VPUSHNE VRPM VTOR +Vect Vrtc W WAVESEL @@ -778,6 +790,7 @@ cmpx coalescences codecov comms +coremqtt coverity covfs cpas @@ -797,6 +810,7 @@ cxsf daif decf decfsz +decihours dicr ecall eevt @@ -815,12 +829,14 @@ fdiv fninit fnsave fwait +getpacketid getvect gpio imajeff inpw ipsr iret +isystem ittt kbhit lcov @@ -872,7 +888,9 @@ mstatus mthi mtlo mtsr +mypy noheap +nondet nostdint optimisations optimiser @@ -897,6 +915,9 @@ pusha pushf pushm pushx +pylint +pytest +pyyaml rddsp reent reta @@ -912,10 +933,15 @@ stsr svcne svlcx synchronise +sysclk +sysclock tcclks tmcsr tstfsz uncrustify +unpadded +unprotect +unsubscriptions unsuspended utest utilises From 745384b04d18b92e8f1973e5c390f10667707d36 Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Tue, 9 Jan 2024 15:45:45 -0500 Subject: [PATCH 28/51] Make vPortYieldWithinAPI and FreeRTOS_Tick_Handler into more configurable functions --- portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S | 1 - portable/GCC/ARM_CRx_MPU/portASM.S | 13 ++++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S b/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S index b2005122a6..0bd760f021 100644 --- a/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S +++ b/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S @@ -52,7 +52,6 @@ vPortYield: /* After yielding to another task, resume executing the calling task */ BX LR - /*-------------------------------------------------------------------------------*/ /* vPortSystemCallExit */ .align 4 diff --git a/portable/GCC/ARM_CRx_MPU/portASM.S b/portable/GCC/ARM_CRx_MPU/portASM.S index c7278859d6..30579d9204 100644 --- a/portable/GCC/ARM_CRx_MPU/portASM.S +++ b/portable/GCC/ARM_CRx_MPU/portASM.S @@ -185,10 +185,10 @@ FreeRTOS_Tick_Handler: portSAVE_CONTEXT /* Clear interrupt flag in Real Time Interrupt. */ LDR R0, =configRTI_ADDRESS - MOV R1, #1 + LDR R1, =configRTI_CLEAR_VALUE STR R1, [R0] /* Increment the tick count, making any adjustments to the blocked lists - that may be necessary. */ + * that may be necessary. */ BL xTaskIncrementTick /* If xTaskIncrementTick returned non-zero then select the next task to execute. */ CMP R0, #0 @@ -206,9 +206,12 @@ vPortYieldWithinAPI: SUB LR, LR, #4 /* Save Currently Executing Task Context */ portSAVE_CONTEXT - /* Clear the Interrupt Flag for vPortYieldWithinAPI */ - MOV R0, #configSSI_ADDRESS - LDR R0, [R0] + /* Load the register address to clear the pending yield */ + LDR R0, =configCLEAR_YIELD_REG_ADDR + /* Load the value needed to mark the pending yield as done */ + LDR R1, =configCLEAR_YIELD_CLR_VAL + /* Write the clear value to the register */ + LDR R1, [R0] /* Select the next task to execute. */ BL vTaskSwitchContext /* Restore the context of the task selected to execute. */ From 53c84a1f6f77193b721fbb4f85aa5e31896bc933 Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Wed, 10 Jan 2024 09:19:56 -0500 Subject: [PATCH 29/51] Update the port to use FreeRTOS_IRQ_Handler instead of the VIM functions --- portable/GCC/ARM_CRx_MPU/portASM.S | 155 +++++++++++---------------- portable/GCC/ARM_CRx_MPU/portmacro.h | 9 +- 2 files changed, 66 insertions(+), 98 deletions(-) diff --git a/portable/GCC/ARM_CRx_MPU/portASM.S b/portable/GCC/ARM_CRx_MPU/portASM.S index 30579d9204..fe2cc87f42 100644 --- a/portable/GCC/ARM_CRx_MPU/portASM.S +++ b/portable/GCC/ARM_CRx_MPU/portASM.S @@ -173,50 +173,6 @@ .endm -/* ----------------------------------------------------------------------------------- */ -/* Default FreeRTOS-Kernel System Tick Interrupt for VIM support */ -.align 4 -.global FreeRTOS_Tick_Handler -.type FreeRTOS_Tick_Handler, %function -FreeRTOS_Tick_Handler: - /* Return to the interrupted instruction. */ - SUB LR, LR, #4 - /* Save Currently Executing Task Context */ - portSAVE_CONTEXT - /* Clear interrupt flag in Real Time Interrupt. */ - LDR R0, =configRTI_ADDRESS - LDR R1, =configRTI_CLEAR_VALUE - STR R1, [R0] - /* Increment the tick count, making any adjustments to the blocked lists - * that may be necessary. */ - BL xTaskIncrementTick - /* If xTaskIncrementTick returned non-zero then select the next task to execute. */ - CMP R0, #0 - BLNE vTaskSwitchContext - /* Restore the context of the task selected to execute. */ - portRESTORE_CONTEXT - -/* ----------------------------------------------------------------------------------- */ -/* Respond to a pending IRQ raised by the FreeRTOS-Kernel to swap tasks */ -.align 4 -.global vPortYieldWithinAPI -.type vPortYieldWithinAPI, %function -vPortYieldWithinAPI: - /* Return to the interrupted instruction. */ - SUB LR, LR, #4 - /* Save Currently Executing Task Context */ - portSAVE_CONTEXT - /* Load the register address to clear the pending yield */ - LDR R0, =configCLEAR_YIELD_REG_ADDR - /* Load the value needed to mark the pending yield as done */ - LDR R1, =configCLEAR_YIELD_CLR_VAL - /* Write the clear value to the register */ - LDR R1, [R0] - /* Select the next task to execute. */ - BL vTaskSwitchContext - /* Restore the context of the task selected to execute. */ - portRESTORE_CONTEXT - /* ----------------------------------------------------------------------------------- */ /* Load the context of the first task, starting the FreeRTOS-Scheduler */ .align 4 @@ -255,8 +211,8 @@ vPortStartFirstTask: .global FreeRTOS_SVC_Handler .type FreeRTOS_SVC_Handler, %function FreeRTOS_SVC_Handler: - /* Push R10-R12 for scratch space */ - PUSH { R10-R12 } + /* Push R11-R12 for scratch space */ + PUSH { R11-R12 } /* -------------------- Caller Flash Location Check -------------------- */ @@ -304,7 +260,7 @@ FreeRTOS_SVC_Handler: /* If one of the above jumps wasn't taken, go straight to the exit */ SVC_Handler_Exit: /** Restore the saved R11 and R12, then return to the caller */ - POP { R10-R12 } + POP { R11-R12 } /* This instruction loads the SPSR into the CPSR, performing the mode swap */ MOVS PC, LR @@ -312,7 +268,7 @@ SVC_Handler_Exit: /* Perform a task swap */ svcPortYield: /* Restore the previously saved R11, R12 */ - POP { R10-R12 } + POP { R11-R12 } /* Save the context of the current task and select a new task to run. */ portSAVE_CONTEXT /* Select a new task to swap to */ @@ -538,91 +494,102 @@ prvMpuDisable: .global FreeRTOS_IRQ_Handler .type FreeRTOS_IRQ_Handler, %function FreeRTOS_IRQ_Handler: + /* Disable IRQs */ + CPSID I + /* Return to the interrupted instruction. */ SUB LR, LR, #4 /* Save the return state to the IRQ stack */ - SRS SP!, #IRQ_MODE + SRSDB SP!, #IRQ_MODE /* Push used registers. */ PUSH {R0-R3, R12} - /* Increment nesting count. R3 holds the address of ulPortInterruptNesting - for future use. R1 holds the original ulPortInterruptNesting value for - future use. */ - LDR R3, =ulPortInterruptNesting - LDR R1, [R3] - ADD R0, R1, #1 - STR R0, [R3] - - /* Ensure bit 2 of the stack pointer is clear. R2 holds the bit 2 value for - future use. */ - MOV R0, SP - AND R2, R0, #4 - SUB SP, SP, R2 - - /* Call the interrupt handler. */ + /* Load &ulPortInterruptNesting into R0 */ + LDR R0, =ulPortInterruptNesting + /* Load the value of ulPortInterruptNesting into R1 */ + LDR R1, [R0] + /* R2 = ulPortInterruptNesting + 1 */ + ADD R2, R1, #1 + /* Store the value of ulPortInterruptNesting++ back into the variable */ + STR R2, [R0] + + /* Align the IRQ Mode Stack Pointer future use. */ + MOV R2, SP + AND R3, R2, #4 + SUB SP, SP, R3 + + /* Save Calling Registers */ PUSH {R0-R3, LR} + /* Call the User provided IRQ handler */ BL vApplicationIRQHandler - /* Restore the registers */ - POP {R0-R3, LR} - ADD SP, SP, R2 + /* Disable Interrupts in case user handler enabled them */ + CPSID I - CPSID i + /* Perform a data and instruction buffer flush */ DSB ISB - /* Write to the EOI register. */ - LDR R0, =ulICCEOIR - LDR R2, [R0] - STR R0, [R2] + /* Restore the previous registers */ + POP {R0-R3, LR} + /* Align the IRQ Mode Stack Pointer to previous location */ + ADD SP, SP, R3 + + /* R0 holds the address of ulPortInterruptNesting, R1 holds original value */ + STR R1, [R0] - /* Restore the old nesting count. */ - STR R1, [R3] + /* Load the address of the End of Interrupt Register */ + LDR R3, =configRTI_ADDRESS + /* Load the value inside of the End of Interrupt Register */ + LDR R2, =configRTI_CLEAR_VALUE + /* Use that value to clear out the End of Interrupt Value */ + STR R2, [R3] - /* A context switch is never performed if the nesting count is not 0. */ + /* Check if ulPortInterruptNesting is 0 */ CMP R1, #0 + /* If ulPortInterruptNesting is not zero, unwind the nested interrupt */ BNE exit_without_switch - /* Did the interrupt request a context switch? R1 holds the address of - ulPortYieldRequired and R0 the value of ulPortYieldRequired for future use. */ + /* ulPortInterruptNesting is zero, check if ulPortYieldRequired is set */ LDR R1, =ulPortYieldRequired + /* Load the value of ulPortYieldRequired */ LDR R0, [R1] + /* Check if the value of ulPortYieldRequired is zero */ CMP R0, #0 + /* If it is non-zero select a new task to run */ BNE switch_before_exit exit_without_switch: /* No context switch. Restore used registers, LR_irq and SPSR before returning. */ POP {R0-R3, R12} - CPS #IRQ_MODE - POP {LR} - MSR SPSR_cxsf, LR - POP {LR} - MOVS PC, LR + /* Return from exception, load pre-exception PC and CPSR */ + RFE SP! switch_before_exit: /* A context swtich is to be performed. Clear the context switch pending flag. */ MOV R0, #0 + /* Set ulPortYieldRequired back to zero */ STR R0, [R1] - /* Restore used registers, LR-irq and SPSR before saving the context - to the task stack. */ + /* Restore used registers, LR_irq and SPSR before saving the context */ POP {R0-R3, R12} - CPS #IRQ_MODE - POP {LR} + /* Load the pushed SPSR from the stack */ + LDMIB SP!, {LR} + /* Move it into the SPSR */ MSR SPSR_cxsf, LR - POP {LR} + /* Load the pushed pre-exception Program Counter into LR_irq */ + LDMDB SP, {LR} + /* Increment the Stack Pointer an additional 0x4 */ + ADD SP, SP, 0x4 + /* Save the current task's context */ portSAVE_CONTEXT - /* Call the function that selects the new task to execute. - vTaskSwitchContext() if vTaskSwitchContext() uses LDRD or STRD - instructions, or 8 byte aligned stack allocated data. LR does not need - saving as a new LR will be loaded by portRESTORE_CONTEXT anyway. */ - LDR R0, =vTaskSwitchContext - BLX R0 + /* Call the function that selects the new task to execute. */ + BLX vTaskSwitchContext - /* Restore the context of, and branch to, the task selected to execute next. */ + /* Restore the context of the selected task, which will start executing. */ portRESTORE_CONTEXT .end diff --git a/portable/GCC/ARM_CRx_MPU/portmacro.h b/portable/GCC/ARM_CRx_MPU/portmacro.h index af8cec650d..42940189b5 100644 --- a/portable/GCC/ARM_CRx_MPU/portmacro.h +++ b/portable/GCC/ARM_CRx_MPU/portmacro.h @@ -83,6 +83,7 @@ extern "C" { #elif( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) #error "This port does not support unprivileged tasks to enter a critical section" #endif /* configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS */ + /* ------------------------- FreeRTOS Config Check ------------------------- */ /** @brief The size in Bytes that the Privileged System Call Stack should be. @@ -409,10 +410,10 @@ void prvMpuDisable( void ); * * @ingroup MPU Control * - * @param[in] regionNumber The MPU Region Number to change permissions for - * @param[in] baseAddress The base address of the MPU Region - * @param[in] regionSize The number of bytes to make the MPU Region - * @param[in] regionPermissions The permissions to assign to the MPU Region + * @param[in] ulRegionNumber The MPU Region Number to change permissions for + * @param[in] ulBaseAddress The base address of the MPU Region + * @param[in] ulRegionSize The number of bytes to make the MPU Region + * @param[in] ulRegionPermissions The permissions to assign to the MPU Region * * @note This is an Assembly Function implemented in portASM.S. * This is meant as a purely internal function that performs a raw write of the From fdd8565f3502fb0c1bccfa7e39d9fad10a652f77 Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Thu, 11 Jan 2024 13:35:11 -0500 Subject: [PATCH 30/51] Add words back to the lexicon that were accidentally removed --- .github/.cSpellWords.txt | 31 ++++--------------------------- 1 file changed, 4 insertions(+), 27 deletions(-) diff --git a/.github/.cSpellWords.txt b/.github/.cSpellWords.txt index da8b42b0e0..e32556661d 100644 --- a/.github/.cSpellWords.txt +++ b/.github/.cSpellWords.txt @@ -99,7 +99,6 @@ CODAN CODR COMPA CONFG -coremqtt CORTUS COVFS CPACR @@ -121,9 +120,6 @@ CRGINT CRTV CSAAT CSDK -csrr -csrs -csrw CTCR CTRLA CTSIC @@ -145,10 +141,6 @@ DCDIC DCMOCK DCMR DCOUNT -decf -decfsz -decihours -Decihours DECIHOURS DECNT DFPU @@ -266,8 +258,6 @@ Flsh Frieder GCACC GCTRL -getpacketid -getvect GIEH GIEL GIRQ @@ -322,7 +312,6 @@ ISRAM ISRR ISRS ISRTICK -isystem ITIF ITMC ITMK @@ -414,7 +403,6 @@ Mang Mbits Mikro Misra -mypy NCFGR NCPHA NEBP @@ -422,11 +410,7 @@ NFIQ NIOSII NIRQ NOGIC -noheap -nondet -Nondet NONDET -nostdint NPCS NRSTL NSACR @@ -438,6 +422,10 @@ Nios Nondet ODAT ODSR +OINC +OIWBNOWA +OIWBWA +OIWTNOWA OPMOD OPTIMISED ORCCR @@ -518,9 +506,6 @@ Picolibc Prioritised Prokic Pulpino -pylint -pytest -pyyaml RAMPZ RASR RBAR @@ -728,16 +713,10 @@ TXVDIS UDCP UNACKED UNDADD -uncrustify -UNDADD -unpadded -Unpadded UNPADDED UNRE UNSUB UNSUBACK -unsubscriptions -unsuspended URAD URAT URSTEN @@ -751,8 +730,6 @@ Unprotect Unprotected Usart VDDCORE -vect -Vect VECT VECTACTIVE VECTKEY From e3d023b6bd7316e86a60b456cfd76edee9e9cb17 Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Fri, 12 Jan 2024 17:06:29 -0500 Subject: [PATCH 31/51] Move the declaration of prvGetMPURegionSizeSetting to the top of the file --- portable/GCC/ARM_CRx_MPU/port.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/portable/GCC/ARM_CRx_MPU/port.c b/portable/GCC/ARM_CRx_MPU/port.c index bdaf388656..bcb84b99b5 100644 --- a/portable/GCC/ARM_CRx_MPU/port.c +++ b/portable/GCC/ARM_CRx_MPU/port.c @@ -79,6 +79,18 @@ PRIVILEGED_DATA volatile uint32_t ulICCEOIR = configEOI_ADDRESS; /*---------------------------------------------------------------------------*/ +/** @brief Returns the smallest valid MPU Region size that can hold a number of bytes. + * + * @ingroup MPU Control + * + * @param ulActualSizeInBytes Number of bytes to find a valid MPU region size for + * @return uint32_t The smallest MPU region size that can hold the requested bytes. + */ +PRIVILEGED_FUNCTION static uint32_t prvGetMPURegionSizeSetting( + uint32_t ulActualSizeInBytes +); + + /** @brief Set a FreeRTOS Task's initial context * * @param pxTopOfStack Pointer to where the task's stack starts @@ -238,17 +250,6 @@ PRIVILEGED_DATA volatile uint32_t ulICCEOIR = configEOI_ADDRESS; /*----------------------------------------------------------------------------*/ -/** @brief Returns the smallest valid MPU Region size that can hold a number of bytes. - * - * @ingroup MPU Control - * - * @param ulActualSizeInBytes Number of bytes to find a valid MPU region size for - * @return uint32_t The smallest MPU region size that can hold the requested bytes. - */ -PRIVILEGED_FUNCTION static uint32_t prvGetMPURegionSizeSetting( - uint32_t ulActualSizeInBytes -); - /* PRIVILEGED_FUNCTION */ static uint32_t prvGetMPURegionSizeSetting( uint32_t ulActualSizeInBytes ) @@ -475,7 +476,7 @@ PRIVILEGED_FUNCTION static void prvSetupDefaultMPU( void ) portMPU_PRIV_RW_USER_RW_NOEXEC | portMPU_DEVICE_NONSHAREABLE ); - /* All Read, and Privileged Write MPU Region for PRIVILEGED_DATA. */ + /* Privileged Write and Read, Unprivileged Read, MPU Region for PRIVILEGED_DATA. */ ulRegionStart = ( uint32_t ) __privileged_data_start__; ulRegionEnd = ( uint32_t ) __privileged_data_end__; ulRegionLength = ulRegionEnd - ulRegionStart; From ec679094e9c0799e34e946e3cb328924df38725e Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Fri, 12 Jan 2024 17:06:59 -0500 Subject: [PATCH 32/51] Remove the end of interrupt clearing from the FreeRTOS_IRQ_Handler. Users should clear it in vApplicationIRQHandler() --- portable/GCC/ARM_CRx_MPU/portASM.S | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/portable/GCC/ARM_CRx_MPU/portASM.S b/portable/GCC/ARM_CRx_MPU/portASM.S index fe2cc87f42..8e132b52f1 100644 --- a/portable/GCC/ARM_CRx_MPU/portASM.S +++ b/portable/GCC/ARM_CRx_MPU/portASM.S @@ -515,17 +515,12 @@ FreeRTOS_IRQ_Handler: /* Store the value of ulPortInterruptNesting++ back into the variable */ STR R2, [R0] - /* Align the IRQ Mode Stack Pointer future use. */ - MOV R2, SP - AND R3, R2, #4 - SUB SP, SP, R3 - /* Save Calling Registers */ - PUSH {R0-R3, LR} + PUSH { R0-R3, LR } /* Call the User provided IRQ handler */ BL vApplicationIRQHandler - /* Disable Interrupts in case user handler enabled them */ + /* Disable IRQs incase vApplicationIRQHandler enabled them for re-entry */ CPSID I /* Perform a data and instruction buffer flush */ @@ -533,20 +528,10 @@ FreeRTOS_IRQ_Handler: ISB /* Restore the previous registers */ - POP {R0-R3, LR} - /* Align the IRQ Mode Stack Pointer to previous location */ - ADD SP, SP, R3 + POP { R0-R3, LR } /* R0 holds the address of ulPortInterruptNesting, R1 holds original value */ STR R1, [R0] - - /* Load the address of the End of Interrupt Register */ - LDR R3, =configRTI_ADDRESS - /* Load the value inside of the End of Interrupt Register */ - LDR R2, =configRTI_CLEAR_VALUE - /* Use that value to clear out the End of Interrupt Value */ - STR R2, [R3] - /* Check if ulPortInterruptNesting is 0 */ CMP R1, #0 /* If ulPortInterruptNesting is not zero, unwind the nested interrupt */ @@ -563,7 +548,7 @@ FreeRTOS_IRQ_Handler: exit_without_switch: /* No context switch. Restore used registers, LR_irq and SPSR before returning. */ - POP {R0-R3, R12} + POP { R0-R3, R12 } /* Return from exception, load pre-exception PC and CPSR */ RFE SP! @@ -574,7 +559,7 @@ switch_before_exit: STR R0, [R1] /* Restore used registers, LR_irq and SPSR before saving the context */ - POP {R0-R3, R12} + POP { R0-R3, R12 } /* Load the pushed SPSR from the stack */ LDMIB SP!, {LR} /* Move it into the SPSR */ From ae6fc131113ecf6d1498a2586bb4a2c9790aaa66 Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Fri, 12 Jan 2024 18:27:25 -0500 Subject: [PATCH 33/51] Formatting fix --- portable/GCC/ARM_CRx_MPU/port.c | 1 - 1 file changed, 1 deletion(-) diff --git a/portable/GCC/ARM_CRx_MPU/port.c b/portable/GCC/ARM_CRx_MPU/port.c index bcb84b99b5..2687ba3870 100644 --- a/portable/GCC/ARM_CRx_MPU/port.c +++ b/portable/GCC/ARM_CRx_MPU/port.c @@ -90,7 +90,6 @@ PRIVILEGED_FUNCTION static uint32_t prvGetMPURegionSizeSetting( uint32_t ulActualSizeInBytes ); - /** @brief Set a FreeRTOS Task's initial context * * @param pxTopOfStack Pointer to where the task's stack starts From 6f361a23345546f9c7b84244b7f723050bbbc7b7 Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Fri, 12 Jan 2024 19:15:45 -0500 Subject: [PATCH 34/51] Remove the CI-CD Check from the FreeRTOS-Kernel repo until after https://github.com/FreeRTOS/FreeRTOS/pull/1149 gets merged --- .github/workflows/kernel-demos.yml | 51 ++---------------------------- 1 file changed, 3 insertions(+), 48 deletions(-) diff --git a/.github/workflows/kernel-demos.yml b/.github/workflows/kernel-demos.yml index fe1f7fbc56..bae32c9662 100644 --- a/.github/workflows/kernel-demos.yml +++ b/.github/workflows/kernel-demos.yml @@ -1,12 +1,6 @@ name: FreeRTOS-Kernel Demos on: [push, pull_request] -env: - bashPass: \033[32;1mPASSED - - bashInfo: \033[33;1mINFO - - bashFail: \033[31;1mFAILED - - bashEnd: \033[0m - jobs: WIN32-MSVC: name: WIN32 MSVC @@ -133,6 +127,7 @@ jobs: with: ref: main repository: FreeRTOS/FreeRTOS + submodules: 'recursive' fetch-depth: 1 # Checkout user pull request changes @@ -159,8 +154,8 @@ jobs: - name: Checkout the FreeRTOS/FreeRTOS Repository uses: actions/checkout@v3 with: - ref: ARM_CRx_MPU - repository: skptak/FreeRTOS + ref: main + repository: FreeRTOS/FreeRTOS fetch-depth: 1 - name: Fetch Community-Supported-Demos Submodule @@ -216,43 +211,3 @@ jobs: shell: bash working-directory: FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC run: make -C build/gcc -j - - - env: - stepName: Build CORTEX_R4_RM46_HERCULES_MCU_GCC Demo - shell: bash - working-directory: FreeRTOS/Demo/CORTEX_R4_RM46_HERCULES_MCU_GCC - run: | - # ${{ env.stepName }} - echo -e "::group::${{ env.bashInfo }} ${{ env.stepName }} ${{ env.bashEnd }}" - set +e - cmake -S . -B build; - make -C build all; - exitStatus=$? - set -e - echo -e "::endgroup::" - if [ $exitStatus -eq 0 ]; then - echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }}" - else - echo -e "${{ env.bashFail }} ${{ env.stepName }} ${{ env.bashEnd }}" - exit 1 - fi - - - env: - stepName: Build CORTEX_R5_RM57_HERCULES_MCU_GCC Demo - shell: bash - working-directory: FreeRTOS/Demo/CORTEX_R5_RM57_HERCULES_MCU_GCC - run: | - # ${{ env.stepName }} - echo -e "::group::${{ env.bashInfo }} ${{ env.stepName }} ${{ env.bashEnd }}" - set +e - cmake -S . -B build; - make -C build all; - exitStatus=$? - set -e - echo -e "::endgroup::" - if [ $exitStatus -eq 0 ]; then - echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }}" - else - echo -e "${{ env.bashFail }} ${{ env.stepName }} ${{ env.bashEnd }}" - exit 1 - fi From 494c78db1b5da47568b6e42461a08a7facd55565 Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Tue, 23 Jan 2024 10:44:33 -0500 Subject: [PATCH 35/51] Use Linux sort for the lexicon --- .github/.cSpellWords.txt | 486 +++++++++++++++++++-------------------- 1 file changed, 243 insertions(+), 243 deletions(-) diff --git a/.github/.cSpellWords.txt b/.github/.cSpellWords.txt index e32556661d..f4550eba95 100644 --- a/.github/.cSpellWords.txt +++ b/.github/.cSpellWords.txt @@ -9,9 +9,14 @@ ACCBH ACCBL ACCBU ACLK +acpa ACPA +acpc ACPC +addi +addiu ADTRG +aeevt AEEVT AERR AIRCR @@ -23,32 +28,45 @@ APIC APROCFREQ APSR ARMCM +Armv ARMVFP ASTRINGZ +aswtrg ASWTRG +Ateml ATMEGA +Atmel ATMEL +atomatic ATPASTE AVRDX -Armv -Ateml -Atmel BANDL +bcpb BCPB +bcpc BCPC +beevt BEEVT BERR +bfextu +Biagioni +bics BISR BODIEN BODSTS BRGR +brhi +brne +bswtrg BSWTRG -Biagioni Bytesto CANEN CANRX CANTX +capitalisation +cbmc CBMC +cbor CBOR CCIE CCMP @@ -77,6 +95,7 @@ CLKA CLKB CLKDIS CLKEN +clki CLKI CLKP CLKS @@ -90,46 +109,69 @@ CMCON CMCOR CMCR CMIE +cmock +Cmock +CMock CMOCK +cmpx CMSIS CMSTR -CMock CNTE +coalescences CODAN +codecov CODR +comms COMPA CONFG +coremqtt CORTUS +coverity +Coverity +covfs COVFS CPACR +cpas CPAS +cpbs CPBS +cpcdis CPCDIS CPCS +cpcstop CPCSTOP CPCTRG CPIV CPRD CPRDR CPRE +cpsid +cpsie CPSR CPUID CRCB +crflash CRGFLG CRGINT +crhook +croutine CRTV CSAAT CSDK +csrr +csrs +csrw CTCR +ctest CTRLA CTSIC CUPD CUPDR CWGR +cxsf CYGNAL -Cmock -Coverity DADR +daif DAIFCLR DAIFSET DATAR @@ -140,11 +182,17 @@ DBGU DCDIC DCMOCK DCMR +Dconfig DCOUNT +decf +decfsz +decihours +Decihours DECIHOURS DECNT DFPU DFREERTOS +dicr DICR DIVB DLYBCS @@ -178,26 +226,32 @@ DTREN DTXD DUNITY DVAR -Dconfig -Decihours EABI +ecall ECIT ECRS ECRSDV +eevt EEVT +eevtedg EEVTEDG EFRHD EINT EIPC EIPSW +Elektronika EMACB EMDC EMDIO +emption +endm ENDRX ENDTX +enetrg ENETRG ENMFILE EOICR +epage EPEDS EPINT EPTYPE @@ -205,31 +259,37 @@ EQIC EQIF EQMK EREFCK +eret ERRA ERSTL ERXCK ERXDV ERXER +Espeche +Espressif ESTATUS ETRCS ETRGEDG +etrgs ETRGS ETXCK ETXEN ETXER +evba EVBA EWARM EWAVR EWRL EWRX EXID +expandnl EXTRSM -Elektronika -Espeche -Espressif FADD FCMD +fcolor FCSE +fdiagnostics +fdiv FDIV FEDPICC FERR @@ -238,10 +298,13 @@ FFER FFSR FIDI FLASH +Flsh FLSH FMCN FMRXNE FMXR +fninit +fnsave FNTR FOSC FPCCR @@ -249,15 +312,17 @@ FPCSR FPSW FPUL FRDY +Frieder FSDEN FSEDGE FSLEN FSOS FSR -Flsh -Frieder +fwait GCACC GCTRL +getpacketid +getvect GIEH GIEL GIRQ @@ -265,15 +330,16 @@ GLBSTATE GMSK GNURX GOVRE +gpio GPIO GPNVM GPTA HCLK +Hitach HRESP HWHSH HWORD HWRD -Hitach IADR IADRSZ ICCAVR @@ -293,8 +359,10 @@ IFDR IFER IFLASH IFSR +imajeff INACK INDF +inpw INTE INTFRCH INTFRCL @@ -304,47 +372,70 @@ IODEFINE IORLW IPEN IPLB +ipsr IPSR +iret IRET IRXFCS -ISR's ISRAM ISRR +ISR's ISRS ISRTICK +isystem ITIF ITMC ITMK +ittt JFRAME JTAG JTVIC Kamil +kbhit Kbyte Krutmann LAPIC LCDR LCOL +lcov +ldaa LDATA LDBDIS LDBSTOP +ldmdb LDMFD +ldmia LDRA +ldras LDRAS +ldrb +ldrbs LDRBS LDRNE +ldsr +lidt LINKR LJMP LLIO +lovrs LOVRS +lpcount +lpend +lpstart LPTHREAD +lsls LSPEN LSPENS +ltorg LWRD MABT MACL MAINF MAINRDY MAIR +Mang +Mbits +mcause MCFR MCKA MCKB @@ -357,28 +448,60 @@ MDER MDIO MDLC MDSR +mepc +mevents MFCR +mfear +mfedr +mfesr +mffsr +mfgpr +mfhi MFID +mflo +mfloat +mfmsr +mfpu +mhartid MIDE +Mikro MIKROC +misra +Misra MISRA MMCR MMSYSERR MOSC MOSCS MOSI +movem +moveq MOVF MOVFF +movhi +movia +movlb +movlw +movne +movs +movw MOVWF +movx MPLAB MPUCTRL MQTT MRDY MREAD +mret +mrseq +mrsne MRTR MSBF MSDIS MSEN +mspgcc +msreq +mstatus MSTATUS MSTP MSTPA @@ -387,8 +510,11 @@ MSTPCRA MSTPCRC MSTR MTCR +mthi MTIOA MTIOB +mtlo +mtsr MVFACGU MVFACHI MVFACLO @@ -399,18 +525,20 @@ MVTACHI MVTACLO MVTC MVTIPL -Mang -Mbits -Mikro -Misra +mypy NCFGR NCPHA NEBP NFIQ +Nios NIOSII NIRQ NOGIC +noheap +nondet +Nondet NONDET +nostdint NPCS NRSTL NSACR @@ -418,8 +546,6 @@ NSFPU NSSR NTRST NVIC -Nios -Nondet ODAT ODSR OINC @@ -427,13 +553,17 @@ OIWBNOWA OIWBWA OIWTNOWA OPMOD +optimisations OPTIMISED +optimiser ORCCR +orrs OSCBYPASS OSCEN OSCOFF OSCOUNT OSMC +outpw OVLY OVRE OVRES @@ -460,10 +590,15 @@ PENDSVSET PENSVCLEAR PERIODH PERIODL +periph PERIPH PFRE +phelter PHYA PICNT +pico +picolibc +Picolibc PICOLIBC PIEN PIIR @@ -477,37 +612,56 @@ PITIEN PIVR PLLB PLLR +popa +popm POPNE POPW +popx +portcomn PORTEN +portex +portisr POWERUP +ppuc PPUDR PPUER PPUSR +ppux PRCR PREA PREB PRIA +Prioritised PRIS PROCDLY PRODH PRODL PROGE +Prokic +prtmacro +psha +psplim PSPLIM PSTDBY PSVPAG PTCR PTSR +Pulpino PUON +pusha +pushf +pushm PUSHNE PUSHW +pushx PWMC -Picolibc -Prioritised -Prokic -Pulpino +pylint +pytest +pyyaml RAMPZ RASR +Rationalised +Raynald RBAR RBOF RBQP @@ -518,16 +672,22 @@ RCIF RCMR RCOMP RCOUNT +rddsp RDRF +reent REENT REGA RELD +Renesas +reta +reti RETP RETTO RFEIA RFMR RIIC RIPL +riscv RLAR RLCE RLES @@ -539,6 +699,7 @@ RNPR ROUSSET ROVR RSHR +rslcx RSLCX RSMINPR RSTC @@ -548,6 +709,7 @@ RSTNACK RSTRX RSTSTA RSTTX +Rsvd RTAR RTCEN RTCSC @@ -566,6 +728,7 @@ RXBRK RXBUFF RXBYTECNT RXDIS +Rxed RXEN RXENA RXOVERWRITE @@ -577,11 +740,6 @@ RXSYN RXTDIS RXTEN RXUBR -Rationalised -Raynald -Renesas -Rsvd -Rxed SBYCR SCALL SCBR @@ -596,12 +754,14 @@ SETEN SETINTENA SETPSW SETR +setvect SFRC SHLL SHLR SHPR SHTIM SIFIVE +sinclude SODR SOFTIRQ SPCK @@ -613,14 +773,21 @@ SRSDB SSBY SSIR SSKEY +staa +Stellaris STILM STKPTR +stmdb +stmia +stsr STTBRK STTDLY STTOUT STTTO SVACC +svcne SVDIS +svlcx SVMST SWAPW SWHSH @@ -629,15 +796,17 @@ SWINT SWINTR SWRST SWTRG +synchronise SYSC -SYSCLK -SYSCLOCK -SYSClk -Stellaris -SysClk -SysClock +sysclk Sysclk +SysClk +SYSClk +SYSCLK +sysclock Sysclock +SysClock +SYSCLOCK TACCR TACCTL TACLR @@ -650,6 +819,7 @@ TBLPTRUH TBLPTRUL TBQP TBSY +tcclks TCCR TCKPS TCLK @@ -670,6 +840,7 @@ TIMFRZ TIMSK TIOA TIOB +tmcsr TMCSR TMIF TMKAEN @@ -688,6 +859,7 @@ TRAPA TRGEN TRGSEL TSHR +tstfsz TSTP TSTR TTGR @@ -712,36 +884,56 @@ TXVC TXVDIS UDCP UNACKED +uncrustify UNDADD +unpadded +Unpadded UNPADDED +unprotect +Unprotect +Unprotected UNRE UNSUB UNSUBACK +unsubscriptions +unsuspended URAD URAT URSTEN URSTIEN URSTS +Usart USART USPRG USRIO -Unpadded -Unprotect -Unprotected -Usart +utest +utilises +utilising VDDCORE +vect +Vect VECT VECTACTIVE VECTKEY +visualisation +vldmdbeq +vldmia +vldmiaeq VMSRNE +vpop VPOPNE +vpush VPUSHNE VRPM -VTOR -Vect Vrtc +vstmdbeq +vstmiaeq +VTOR W WAVESEL +wavsel +Wcolor +Wconversion WDCR WDDBGHLT WDDIS @@ -754,214 +946,22 @@ WDRSTEN WDRSTT WDSR WDTC +wdtcon WDUNF -WESTAT -WIZC -WREG -Wcolor -Wconversion Werror +WESTAT Weverything Wextra +winmm +WIZC Wpedantic +wrdsp +WREG Wunused XEXC XPAR +xparameters XPSR XRAM -XTENSA -acpa -acpc -addi -addiu -aeevt -aswtrg -atomatic -bcpb -bcpc -beevt -bfextu -bics -brhi -brne -bswtrg -capitalisation -cbmc -cbor -clki -cmock -cmpx -coalescences -codecov -comms -coremqtt -coverity -covfs -cpas -cpbs -cpcdis -cpcstop -cpsid -cpsie -crflash -crhook -croutine -csrr -csrs -csrw -ctest -cxsf -daif -decf -decfsz -decihours -dicr -ecall -eevt -eevtedg -emption -endm -enetrg -epage -eret -etrgs -evba -expandnl -fcolor -fdiagnostics -fdiv -fninit -fnsave -fwait -getpacketid -getvect -gpio -imajeff -inpw -ipsr -iret -isystem -ittt -kbhit -lcov -ldaa -ldmdb -ldmia -ldras -ldrb -ldrbs -ldsr -lidt -lovrs -lpcount -lpend -lpstart -lsls -ltorg -mcause -mepc -mevents -mfear -mfedr -mfesr -mffsr -mfgpr -mfhi -mflo -mfloat -mfmsr -mfpu -mhartid -misra -movem -moveq -movhi -movia -movlb -movlw -movne -movs -movw -movx -mret -mrseq -mrsne -mspgcc -msreq -mstatus -mthi -mtlo -mtsr -mypy -noheap -nondet -nostdint -optimisations -optimiser -orrs -outpw -periph -phelter -pico -picolibc -popa -popm -popx -portcomn -portex -portisr -ppuc -ppux -prtmacro -psha -psplim -pusha -pushf -pushm -pushx -pylint -pytest -pyyaml -rddsp -reent -reta -reti -riscv -rslcx -setvect -sinclude -staa -stmdb -stmia -stsr -svcne -svlcx -synchronise -sysclk -sysclock -tcclks -tmcsr -tstfsz -uncrustify -unpadded -unprotect -unsubscriptions -unsuspended -utest -utilises -utilising -vect -visualisation -vldmdbeq -vldmia -vldmiaeq -vpop -vpush -vstmdbeq -vstmiaeq -wavsel -wdtcon -winmm -wrdsp -xparameters xtal +XTENSA From 91d4d2416a3aa6e498257a40ac93dd645329f834 Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Tue, 30 Jan 2024 14:15:10 -0500 Subject: [PATCH 36/51] Respond to PR Feedback Fix incorrect context size define Add MPU Region alignment check Use highest priority MPU region when not provided xRegions Remove unused variables Remove dangling function declarations --- portable/GCC/ARM_CRx_MPU/port.c | 170 ++++++++++++----------- portable/GCC/ARM_CRx_MPU/portASM.S | 60 ++++---- portable/GCC/ARM_CRx_MPU/portmacro.h | 25 +--- portable/GCC/ARM_CRx_MPU/portmacro_asm.h | 43 +++--- 4 files changed, 153 insertions(+), 145 deletions(-) diff --git a/portable/GCC/ARM_CRx_MPU/port.c b/portable/GCC/ARM_CRx_MPU/port.c index 2687ba3870..07db8bf500 100644 --- a/portable/GCC/ARM_CRx_MPU/port.c +++ b/portable/GCC/ARM_CRx_MPU/port.c @@ -72,11 +72,6 @@ PRIVILEGED_DATA volatile uint32_t ulPortInterruptNesting = 0UL; */ PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; -/** @brief Used in portASM.S's IRQ Handler to clear an interrupt. - * @ingroup Interrupt Management - */ -PRIVILEGED_DATA volatile uint32_t ulICCEOIR = configEOI_ADDRESS; - /*---------------------------------------------------------------------------*/ /** @brief Returns the smallest valid MPU Region size that can hold a number of bytes. @@ -114,7 +109,7 @@ PRIVILEGED_FUNCTION static uint32_t prvGetMPURegionSizeSetting( * expected by the portRESTORE_CONTEXT() macro. */ UBaseType_t ulContextIndex = MAX_CONTEXT_SIZE - 1U; - if( xRunPrivileged == pdTRUE ) + if( pdTRUE == xRunPrivileged ) { /* Current Program Status and Control Register */ xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; @@ -129,7 +124,7 @@ PRIVILEGED_FUNCTION static uint32_t prvGetMPURegionSizeSetting( xMPUSettings->ulContext[ ulContextIndex ] = USER_MODE; } - if( ( ( uint32_t ) pxCode & portTHUMB_MODE_ADDRESS ) != 0x00UL ) + if( 0x0UL != ( ( uint32_t ) pxCode & portTHUMB_MODE_ADDRESS ) ) { /* The task will start in THUMB mode, set the bit in the CPSR. */ xMPUSettings->ulContext[ ulContextIndex ] |= portTHUMB_MODE_BIT; @@ -235,7 +230,8 @@ PRIVILEGED_FUNCTION static uint32_t prvGetMPURegionSizeSetting( ); xSysCallInfo->pulSystemCallStackPointer = - ( uint32_t * ) ( ( uint32_t ) ( xSysCallInfo->pulSystemCallStackPointer ) & ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + ( uint32_t * ) ( ( uint32_t ) ( xSysCallInfo->pulSystemCallStackPointer ) & + ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); /* This is not NULL only for the duration of a system call. */ xSysCallInfo->pulTaskStackPointer = NULL; @@ -255,9 +251,8 @@ PRIVILEGED_FUNCTION static uint32_t prvGetMPURegionSizeSetting( { uint32_t ulRegionSize, ulReturnValue = 4U; - /* 32 is the smallest region size, 31 is the largest valid value for - * ulReturnValue. */ - for( ulRegionSize = 32UL; ulReturnValue < 31UL; ( ulRegionSize <<= 1UL ) ) + /* 32 bytes is the smallest valid region for Cortex R4 and R5 CPUs */ + for( ulRegionSize = 0x20UL; ulReturnValue < 0x1FUL; ( ulRegionSize <<= 1UL ) ) { if( ulActualSizeInBytes <= ulRegionSize ) { @@ -310,75 +305,87 @@ PRIVILEGED_FUNCTION static uint32_t prvGetMPURegionSizeSetting( extern uint32_t __SRAM_segment_end__[]; #endif /* if defined( __ARMCC_VERSION ) */ - uint32_t lIndex = 0x0; - uint32_t ul = 0x0; + uint32_t ulIndex = 0x0; + uint32_t ulRegionStart; + uint32_t ulRegionEnd; + uint32_t ulRegionLen; + uint32_t ulAlignment; + /* Allow Read/Write from User and Privileged modes */ + uint32_t ulRegionAttr = portMPU_PRIV_RW_USER_RW_NOEXEC | + portMPU_NORMAL_OIWTNOWA_SHARED; - if( xRegions == NULL ) + if( NULL == xRegions ) { /* No MPU regions are specified so allow access to all of the RAM. */ - xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress = ( uint32_t - ) __SRAM_segment_start__; - xMPUSettings->xRegion[ 0 ].ulRegionSize = ( prvGetMPURegionSizeSetting( - ( uint32_t ) __SRAM_segment_end__ - - ( uint32_t ) __SRAM_segment_start__ - ) ) | - portMPU_REGION_ENABLE; - xMPUSettings->xRegion[ 0 ].ulRegionAttribute = portMPU_PRIV_RW_USER_RW_NOEXEC | - portMPU_NORMAL_OIWTNOWA_SHARED; - - /* Invalidate all other regions. */ - for( ul = 1; ul <= portNUM_CONFIGURABLE_REGIONS; ul++ ) - { - xMPUSettings->xRegion[ ul ].ulRegionBaseAddress = 0x0UL; - xMPUSettings->xRegion[ ul ].ulRegionSize = 0x0UL; - xMPUSettings->xRegion[ ul ].ulRegionAttribute = 0x0UL; - } + ulRegionStart = ( uint32_t ) __SRAM_segment_start__; + ulRegionEnd = ( uint32_t ) __SRAM_segment_end__; + ulRegionLen = ulRegionEnd - ulRegionStart; + ulRegionLen = prvGetMPURegionSizeSetting( ulRegionLen ); + ulRegionLen |= portMPU_REGION_ENABLE; + + /* Invalidate other MPU regions by using the last configurable region */ + ulIndex = portNUM_CONFIGURABLE_REGIONS; + + xMPUSettings->xRegion[ ulIndex ].ulRegionBaseAddress = ulRegionStart; + xMPUSettings->xRegion[ ulIndex ].ulRegionSize = ulRegionLen; + xMPUSettings->xRegion[ ulIndex ].ulRegionAttribute = ulRegionAttr; } else { - /* This function is called automatically when the task is created - in - * which case the stack region parameters will be valid. At all other - * times the stack parameters will not be valid and it is assumed that the - * stack region has already been configured. */ - - if( ulStackDepth > 0 ) + for( ulIndex = 0UL; ulIndex < portNUM_CONFIGURABLE_REGIONS; ulIndex++ ) { - uint32_t ulSmallestRegion = prvGetMPURegionSizeSetting( ulStackDepth * 0x4 ); - /* Define the region that allows access to the stack. */ - xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress = ( uint32_t ) pxBottomOfStack; - xMPUSettings->xRegion[ 0 ].ulRegionSize = ulSmallestRegion | - portMPU_REGION_ENABLE; - xMPUSettings->xRegion[ 0 ].ulRegionAttribute = portMPU_PRIV_RW_USER_RW_NOEXEC | - portMPU_NORMAL_OIWTNOWA_SHARED; - } - - for( ul = 1; ul <= portNUM_CONFIGURABLE_REGIONS; ul++ ) - { - if( ( xRegions[ lIndex ] ).ulLengthInBytes > 0UL ) + /* If a length has been provided, the region is in use */ + if( ( xRegions[ ulIndex ] ).ulLengthInBytes > 0UL ) { - /* Translate the generic region definition contained in - * xRegions into the R4 specific MPU settings that are then - * stored in xMPUSettings. */ - xMPUSettings->xRegion[ ul ] - .ulRegionBaseAddress = ( uint32_t ) xRegions[ lIndex ].pvBaseAddress; - xMPUSettings->xRegion[ ul ] - .ulRegionSize = prvGetMPURegionSizeSetting( - xRegions[ lIndex ].ulLengthInBytes - ) | - portMPU_REGION_ENABLE; - xMPUSettings->xRegion[ ul ].ulRegionAttribute = xRegions[ lIndex ] - .ulParameters; + ulRegionStart = ( uint32_t ) xRegions[ ulIndex ].pvBaseAddress; + ulRegionAttr = xRegions[ ulIndex ].ulParameters; + + ulRegionLen = xRegions[ ulIndex ].ulLengthInBytes; + ulRegionLen = prvGetMPURegionSizeSetting( ulRegionLen ); + ulRegionLen |= portMPU_REGION_ENABLE; + + /* MPU Regions must be aligned to a power of 2 equal to length */ + ulAlignment = 2UL << ( ulRegionLen >> 1UL ); + configASSERT( 0U == ( ulRegionStart % 2UL ) ); + configASSERT( 0U == ( ulRegionStart % ( ulAlignment ) ) ); } else { - /* Invalidate the region. */ - xMPUSettings->xRegion[ ul ].ulRegionBaseAddress = 0x0UL; - xMPUSettings->xRegion[ ul ].ulRegionSize = 0x0UL; - xMPUSettings->xRegion[ ul ].ulRegionAttribute = 0x0UL; + /* Otherwise ensure the region is zero'd out */ + ulRegionStart = 0x0UL; + ulRegionLen = 0x0UL; + ulRegionAttr = 0x0UL; } - lIndex++; + xMPUSettings->xRegion[ ulIndex ].ulRegionBaseAddress = ulRegionStart; + xMPUSettings->xRegion[ ulIndex ].ulRegionSize = ulRegionLen; + xMPUSettings->xRegion[ ulIndex ].ulRegionAttribute = ulRegionAttr; } + /* This function is called automatically when the task is created - in + * which case the stack region parameters will be valid. At all other + * times the stack parameters will not be valid and it is assumed that the + * stack region has already been configured. */ + + /* Cannot have a task stack of size 0 */ + configASSERT( ulStackDepth != 0x0UL ); + + /* Define the region that allows access to the stack. */ + ulRegionStart = ( uint32_t ) pxBottomOfStack; + ulRegionAttr = portMPU_PRIV_RW_USER_RW_NOEXEC | portMPU_NORMAL_OIWTNOWA_SHARED; + ulRegionLen = prvGetMPURegionSizeSetting( ulStackDepth << 2UL ); + ulRegionLen |= portMPU_REGION_ENABLE; + + /* MPU Regions must be aligned to a power of 2 equal to length */ + ulAlignment = 2UL << ( ulRegionLen >> 1UL ); + configASSERT( 0U == ( ulRegionStart % 2UL ) ); + configASSERT( 0U == ( ulRegionStart % ( ulAlignment ) ) ); + + /* xRegion[portNUM_CONFIGURABLE_REGIONS] is the Task Stack */ + ulIndex = portNUM_CONFIGURABLE_REGIONS; + + xMPUSettings->xRegion[ ulIndex ].ulRegionBaseAddress = ulRegionStart; + xMPUSettings->xRegion[ ulIndex ].ulRegionSize = ulRegionLen; + xMPUSettings->xRegion[ ulIndex ].ulRegionAttribute = ulRegionAttr; } } @@ -436,13 +443,14 @@ PRIVILEGED_FUNCTION static void prvSetupDefaultMPU( void ) uint32_t ulRegionLength; /* Ensure the MPU is disabled */ - prvMpuDisable(); + prvMPUDisable(); /* Unprivileged and Privileged Read and Exec MPU Region for Flash */ ulRegionStart = ( uint32_t ) __FLASH_segment_start__; ulRegionEnd = ( uint32_t ) __FLASH_segment_end__; ulRegionLength = ulRegionEnd - ulRegionStart; - ulRegionLength = prvGetMPURegionSizeSetting( ulRegionLength ) | portMPU_REGION_ENABLE; + ulRegionLength = prvGetMPURegionSizeSetting( ulRegionLength ); + ulRegionLength |= portMPU_REGION_ENABLE; prvMpuSetRegion( portUNPRIVILEGED_FLASH_REGION, @@ -455,7 +463,9 @@ PRIVILEGED_FUNCTION static void prvSetupDefaultMPU( void ) ulRegionStart = ( uint32_t ) __privileged_functions_start__; ulRegionEnd = ( uint32_t ) __privileged_functions_end__; ulRegionLength = ulRegionEnd - ulRegionStart; - ulRegionLength = prvGetMPURegionSizeSetting( ulRegionLength ) | portMPU_REGION_ENABLE; + ulRegionLength = prvGetMPURegionSizeSetting( ulRegionLength ); + ulRegionLength |= portMPU_REGION_ENABLE; + prvMpuSetRegion( portPRIVILEGED_FLASH_REGION, ulRegionStart, @@ -467,7 +477,9 @@ PRIVILEGED_FUNCTION static void prvSetupDefaultMPU( void ) ulRegionStart = ( uint32_t ) __peripherals_start__; ulRegionEnd = ( uint32_t ) __peripherals_end__; ulRegionLength = ulRegionEnd - ulRegionStart; - ulRegionLength = prvGetMPURegionSizeSetting( ulRegionLength ) | portMPU_REGION_ENABLE; + ulRegionLength = prvGetMPURegionSizeSetting( ulRegionLength ); + ulRegionLength |= portMPU_REGION_ENABLE; + prvMpuSetRegion( portGENERAL_PERIPHERALS_REGION, ulRegionStart, @@ -479,7 +491,9 @@ PRIVILEGED_FUNCTION static void prvSetupDefaultMPU( void ) ulRegionStart = ( uint32_t ) __privileged_data_start__; ulRegionEnd = ( uint32_t ) __privileged_data_end__; ulRegionLength = ulRegionEnd - ulRegionStart; - ulRegionLength = prvGetMPURegionSizeSetting( ulRegionLength ) | portMPU_REGION_ENABLE; + ulRegionLength = prvGetMPURegionSizeSetting( ulRegionLength ); + ulRegionLength |= portMPU_REGION_ENABLE; + prvMpuSetRegion( portPRIVILEGED_RAM_REGION, ulRegionStart, @@ -488,7 +502,7 @@ PRIVILEGED_FUNCTION static void prvSetupDefaultMPU( void ) ); /* After setting default regions, enable the MPU */ - prvMpuEnable(); + prvMPUEnable(); } /* ------------------------------------------------------------------------- */ @@ -514,12 +528,12 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( BaseType_t xAccessGranted; uint32_t ulRegionEnd = ulRegionStart + ulRegionLength; - /* Convert the MPU Region Size value to the actual size */ - uint32_t ulTaskRegionLength = 1 << ( ( xTaskMPURegion->ulRegionSize >> 1 ) + 1U ); - // uint32_t ulTaskRegionLength = 2 << ( xTaskMPURegion->ulRegionSize >> 1 ); + /* Get Region Size value in words, need to clear the enable bit */ + uint32_t ulTaskRegionLength = 2UL << ( xTaskMPURegion->ulRegionSize >> 1UL ); uint32_t ulTaskRegionEnd = xTaskMPURegion->ulRegionBaseAddress + ulTaskRegionLength; + if( ( ulRegionStart >= xTaskMPURegion->ulRegionBaseAddress ) && - ( ulRegionEnd <= ulTaskRegionEnd ) ) + ( ulRegionEnd <= ulTaskRegionEnd ) && ( ulRegionEnd >= ulRegionStart ) ) { /* Unprivileged read is MPU Ctrl Access Bit Value bX1X */ if( ( tskMPU_READ_PERMISSION == ulAccessRequested ) && @@ -656,7 +670,7 @@ BaseType_t xPortStartScheduler( void ) * warning about it being defined but not referenced in the case that the user * defines their own exit address. */ ( void ) prvTaskExitError(); - return 0; + return pdFALSE; } /*---------------------------------------------------------------------------*/ @@ -670,7 +684,7 @@ BaseType_t xPortStartScheduler( void ) BaseType_t xAccessGranted = pdFALSE; const xMPU_SETTINGS * xTaskMpuSettings; - if( xSchedulerRunning == pdFALSE ) + if( pdFALSE == xSchedulerRunning ) { /* Grant access to all the kernel objects before the scheduler * is started. It is necessary because there is no task running diff --git a/portable/GCC/ARM_CRx_MPU/portASM.S b/portable/GCC/ARM_CRx_MPU/portASM.S index 8e132b52f1..bafc469b5a 100644 --- a/portable/GCC/ARM_CRx_MPU/portASM.S +++ b/portable/GCC/ARM_CRx_MPU/portASM.S @@ -41,8 +41,9 @@ .extern pxCurrentTCB .extern uxSystemCallImplementations .extern ulPortInterruptNesting - .extern ulICCEOIR .extern ulPortYieldRequired + + /* External Linker script variables that are needed by the port */ .extern __privileged_functions_start__ .extern __privileged_functions_end__ .extern __privileged_stacks_start__ @@ -74,7 +75,8 @@ LDR R0, =ulCriticalNesting /* Load the value of ulCriticalNesting into R0 */ LDR R0, [R0] - /* Push the value of ulCriticalNesting into the context */ + /* Push the value of ulCriticalNesting into the context, auto-increment the + * LR by using the ! operator. */ STM LR!, {R0} #if ( portENABLE_FPU == 1 ) @@ -89,15 +91,16 @@ /* Restore the saved register */ POP { R0 } - /* Save the pre-exception Registers, Stack Pointer (SP), and LR */ + /* Save the General Purpose Registers (GPRs). Also save the pre-exception + * Stack Pointer (SP) and LR. The ^ operator causes this instruction to store + * the mode selected in the Saved Program Status Register (SPSR) */ STM LR, { R0-R14 }^ - /* Increment the LR after the popped registers */ + /* Not allowed to auto-increment with ! when using banked registers */ ADD LR, LR, #portGPR_LENGTH /* Pop the pushed LR, which is the pre-exception Program Counter (PC) */ POP { R0 } - /* Copy the pre-exception Current Program Status and Control Register (CPSR) - * which is banked as the Saved Program Status and Control Register (SPSR) - * to save it as part of the context. */ + /* Copy the pre-exception Current Program Status Register (CPSR), which, + * is banked as the SPSR and save it as part of the task context */ MRS R1, SPSR /* Store the pre-exception CPSR and PC */ STM LR!, { R0-R1 } @@ -166,7 +169,7 @@ MSR SPSR_cxsf, R0 /* Restore the saved Stack Pointer and Link Register */ LDM LR, {R0-R14}^ - /* Increment the Link Register after the popped registers */ + /* Not allowed to auto-increment with ! when using banked registers */ ADD LR, LR, #portGPR_LENGTH /* Load the PC to return from the exception */ RFE LR @@ -179,7 +182,7 @@ .global vPortStartFirstTask .type vPortStartFirstTask, %function vPortStartFirstTask: - /** This function is called from System Mode to start the FreeRTOS-Kernel. + /** This function is called from Supervisor Mode to start the FreeRTOS-Kernel. * This is done by restoring the context of the first task. * Restoring the context of a task will allow interrupts. * This allows the FreeRTOS Scheduler Tick to start, and therefore @@ -344,7 +347,7 @@ svcSystemCallEnter: /* Store the task's SP and LR to xSYSTEM_CALL_STACK_INFO */ STM R11, {R13-R14}^ - /* Undefined behaviour to auto-increment with the ^ operator */ + /* Not allowed to auto-increment with ! when using banked registers */ ADD R11, R11, 0x8 /* Load pulSystemCallStackPointer and pulSystemCallLinkRegister now */ LDM R11, {R13-R14}^ @@ -367,7 +370,7 @@ vPortEnterCritical: /* Disable IRQs */ CPSID I /* Save scratch registers */ - PUSH {R0-R1} + PUSH { R0-R1 } /* Load address of current critical nesting count */ LDR R0, =ulCriticalNesting /* Load value of current critical nesting count */ @@ -376,8 +379,9 @@ vPortEnterCritical: ADD R1, R1, #1 /* Store the modified ulCriticalNesting back into RAM */ STR R1, [R0] + /* Restore pushed registers */ + POP { R0-R1 } /* Return to caller */ - POP {R0-R1} BX LR /* ----------------------------------------------------------------------------------- */ @@ -397,8 +401,8 @@ vPortDisableInterrupts: .global vPortExitCritical .type vPortExitCritical, %function vPortExitCritical: - /* Store two scratch registers */ - PUSH { R0-R1 } + /* Store two scratch registers and LR for IRQ Mode re-entry */ + PUSH { R0-R1, LR } /* Load address of current critical nesting count */ LDR R0, =ulCriticalNesting /* Load value of current critical nesting count */ @@ -411,8 +415,9 @@ vPortExitCritical: STRGT R1, [R0] /* Enable IRQs */ CPSIE I + /* Restore Pushed registers */ + POP { R0-R1, LR } /* Return to caller */ - POP {R0-R1} BX LR /* ----------------------------------------------------------------------------------- */ @@ -421,8 +426,12 @@ vPortExitCritical: .global vPortEnableInterrupts .type vPortEnableInterrupts, %function vPortEnableInterrupts: + /* Push LR to account for re-entry in IRQ Mode */ + PUSH { LR } /* Enable IRQs */ CPSIE I + /* Restore previous LR */ + POP { LR } /* Return to caller */ BX LR @@ -454,9 +463,9 @@ prvMpuSetRegion: /* ----------------------------------------------------------------------------------- */ /* Set the Enable bit of the MPU Enable Register to 1. */ .align 4 -.global prvMpuEnable -.type prvMpuEnable, %function -prvMpuEnable: +.global prvMPUEnable +.type prvMPUEnable, %function +prvMPUEnable: /* Read the current MPU control register into R0 */ MRC p15, #0, R0, c1, c0, #0 /* Set the enable bit to high */ @@ -473,9 +482,9 @@ prvMpuEnable: /* ----------------------------------------------------------------------------------- */ /* Set the Enable bit of the MPU Enable Register to 0. */ .align 4 -.global prvMpuDisable -.type prvMpuDisable, %function -prvMpuDisable: +.global prvMPUDisable +.type prvMPUDisable, %function +prvMPUDisable: /* Read the MPU enable register values into R0 */ MRC p15, #0, R0, c1, c0, #0 /* Perform a bitwise AND of R0 and NOT #1, i.e. clear bit 1 */ @@ -496,13 +505,10 @@ prvMpuDisable: FreeRTOS_IRQ_Handler: /* Disable IRQs */ CPSID I - /* Return to the interrupted instruction. */ SUB LR, LR, #4 - /* Save the return state to the IRQ stack */ SRSDB SP!, #IRQ_MODE - /* Push used registers. */ PUSH {R0-R3, R12} @@ -522,14 +528,12 @@ FreeRTOS_IRQ_Handler: /* Disable IRQs incase vApplicationIRQHandler enabled them for re-entry */ CPSID I - /* Perform a data and instruction buffer flush */ DSB ISB /* Restore the previous registers */ POP { R0-R3, LR } - /* R0 holds the address of ulPortInterruptNesting, R1 holds original value */ STR R1, [R0] /* Check if ulPortInterruptNesting is 0 */ @@ -561,11 +565,11 @@ switch_before_exit: /* Restore used registers, LR_irq and SPSR before saving the context */ POP { R0-R3, R12 } /* Load the pushed SPSR from the stack */ - LDMIB SP!, {LR} + LDMIB SP!, { LR } /* Move it into the SPSR */ MSR SPSR_cxsf, LR /* Load the pushed pre-exception Program Counter into LR_irq */ - LDMDB SP, {LR} + LDMDB SP, { LR } /* Increment the Stack Pointer an additional 0x4 */ ADD SP, SP, 0x4 /* Save the current task's context */ diff --git a/portable/GCC/ARM_CRx_MPU/portmacro.h b/portable/GCC/ARM_CRx_MPU/portmacro.h index 42940189b5..317b5216ba 100644 --- a/portable/GCC/ARM_CRx_MPU/portmacro.h +++ b/portable/GCC/ARM_CRx_MPU/portmacro.h @@ -298,27 +298,6 @@ void FreeRTOS_SVC_Handler( void ); /** @brief Assembly FreeRTOS Interrupt Handler */ void FreeRTOS_IRQ_Handler( void ); -/** @brief Assembly FreeRTOS IRQ Handler - * - * @ingroup Scheduler - * - * @note This must be installed as the handler for whichever peripheral is used - * to generate the RTOS tick if using a VIM. */ - -/** @brief Decleration of the FreeRTOS Tick Handler. - * - * @ingroup Scheduler - * - * @note This must be installed as the handler for whichever peripheral is used - * to generate the RTOS tick if using a VIM. */ -void FreeRTOS_Tick_Handler( void ) __attribute__( ( weak, interrupt( "IRQ" ) ) ); - -/** @brief Pend a context switch inside of the FreeRTOS-Kernel. - * @ingroup Scheduler - * @note This is used to raise a pending IRQ on a board that supplies a VIM. - */ -void vPortYieldWithinAPI( void ) __attribute__( ( weak, interrupt( "IRQ" ) ) ); - /* --------------------------- Port Assembly Functions --------------------------- */ /** @brief Make a Supervisor Call to swap the currently running task out. @@ -396,7 +375,7 @@ void vPortStartFirstTask( void ); * * @return void */ -void prvMpuEnable( void ); +void prvMPUEnable( void ); /** @brief Disable the onboard MPU * @@ -404,7 +383,7 @@ void prvMpuEnable( void ); * * @return VOID */ -void prvMpuDisable( void ); +void prvMPUDisable( void ); /** @brief Assembly routine to set permissions for an MPU Region. * diff --git a/portable/GCC/ARM_CRx_MPU/portmacro_asm.h b/portable/GCC/ARM_CRx_MPU/portmacro_asm.h index b10f9351a2..8cfa15eddd 100644 --- a/portable/GCC/ARM_CRx_MPU/portmacro_asm.h +++ b/portable/GCC/ARM_CRx_MPU/portmacro_asm.h @@ -44,7 +44,7 @@ extern "C" { #elif( configTOTAL_MPU_REGIONS == 16 ) #define portMPU_TOTAL_REGIONS ( 16UL ) #else - #error "Set configTOTAL_MPU_REGIONS to the humber of MPU regions in FreeRTOSConfig.h" + #error "Set configTOTAL_MPU_REGIONS to the number of MPU regions in FreeRTOSConfig.h" #endif /** On the ArmV7-R Architecture the Operating mode of the Processor is set using @@ -471,33 +471,44 @@ extern "C" { * seems to randomly fail. */ #ifndef configENABLE_FPU - #define configENABLE_FPU 0 -#endif + #define configENABLE_FPU 1 +#endif /* configENABLE_FPU */ /** @brief Mark if the Floating Point Registers will be saved. * @ingroup Task Context * @note When using the FPU, we must save additional registers into the task's context * These consist of the Floating Point Status and Control Register (FPSCR), * As well as the Floating Point Registers (FPRs) - * Task Context which is stored in ulContext in order, consists of: - * ulContext[ 0 ]: Critical Nesting Count: ulCriticalNesting - * ulContext[ 1 ]: Floating Point Status and Control Register - * ulContext[ 2 - 33 ]: Floating Point Registers: S0-S31 - * ulContext[ 34 - 46 ]: General Purpose Registers: R0-R12 - * ulContext[ 47 ]: Stack Pointer - * ulContext[ 48 ]: Link Register - * ulContext[ 49 ]: Program Counter - * ulContext[ 50 ]: Current Program Status and Control Register */ #define portENABLE_FPU configENABLE_FPU #if( portENABLE_FPU == 1 ) - /** @brief Length of a Task's Register Context when using an FPU. */ - #define MAX_CONTEXT_SIZE 50U + /** @brief Length of a Task's Register Context when using an FPU. + * @ingroup Task Context + * @note Task Context which is stored in ulContext in order, consists of: + * ulContext[ 0 ]: Critical Nesting Count: ulCriticalNesting + * ulContext[ 1 ]: Floating Point Status and Control Register + * ulContext[ 2 - 33 ]: Floating Point Registers: S0-S31 + * ulContext[ 34 - 46 ]: General Purpose Registers: R0-R12 + * ulContext[ 48 ]: Stack Pointer + * ulContext[ 49 ]: Link Register + * ulContext[ 50 ]: Program Counter + * ulContext[ 51 ]: Current Program Status and Control Register + */ + #define MAX_CONTEXT_SIZE 51U #else - /** @brief Length of a Task's Register Context when not using an FPU. */ + /** @brief Length of a Task's Register Context when not using an FPU. + * @ingroup Task Context + * @note Task Context which is stored in ulContext in order, consists of: + * ulContext[ 0 ]: Critical Nesting Count: ulCriticalNesting + * ulContext[ 1 - 13 ]: General Purpose Registers: R0-R12 + * ulContext[ 14 ]: Stack Pointer + * ulContext[ 15 ]: Link Register + * ulContext[ 16 ]: Program Counter + * ulContext[ 17 ]: Current Program Status and Control Register + */ #define MAX_CONTEXT_SIZE 18U -#endif +#endif /* MAX_CONTEXT_SIZE */ /** @brief Numerical offset from the start of a TCB to xSystemCallStackInfo * @note In the exception handlers it is necessary to load this variable from the TCB. From 11beb7156ef6e704a53aef768be40e97ea862b6e Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Tue, 30 Jan 2024 14:28:02 -0500 Subject: [PATCH 37/51] Formatting fixes --- portable/GCC/ARM_CRx_MPU/port.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/portable/GCC/ARM_CRx_MPU/port.c b/portable/GCC/ARM_CRx_MPU/port.c index 07db8bf500..f43a32b196 100644 --- a/portable/GCC/ARM_CRx_MPU/port.c +++ b/portable/GCC/ARM_CRx_MPU/port.c @@ -230,8 +230,7 @@ PRIVILEGED_FUNCTION static uint32_t prvGetMPURegionSizeSetting( ); xSysCallInfo->pulSystemCallStackPointer = - ( uint32_t * ) ( ( uint32_t ) ( xSysCallInfo->pulSystemCallStackPointer ) & - ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + ( uint32_t * ) ( ( uint32_t ) ( xSysCallInfo->pulSystemCallStackPointer ) & ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); /* This is not NULL only for the duration of a system call. */ xSysCallInfo->pulTaskStackPointer = NULL; From ca37a2cfc7060d2b73378f8d72d47795ca49a0be Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Wed, 31 Jan 2024 14:56:48 -0500 Subject: [PATCH 38/51] Respond to additional review feedback. Use periods at end of briefs. Remove same line brief. Add a check back in, change some file names, slight code formatting change. --- portable/GCC/ARM_CRx_MPU/port.c | 340 ++++++++++++----------- portable/GCC/ARM_CRx_MPU/portASM.S | 53 ++-- portable/GCC/ARM_CRx_MPU/portmacro.h | 282 ++++++++++--------- portable/GCC/ARM_CRx_MPU/portmacro_asm.h | 222 +++++---------- 4 files changed, 437 insertions(+), 460 deletions(-) diff --git a/portable/GCC/ARM_CRx_MPU/port.c b/portable/GCC/ARM_CRx_MPU/port.c index f43a32b196..ee86ba11ca 100644 --- a/portable/GCC/ARM_CRx_MPU/port.c +++ b/portable/GCC/ARM_CRx_MPU/port.c @@ -37,16 +37,15 @@ #endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ /* Scheduler includes. */ -#include "FreeRTOSConfig.h" #include "FreeRTOS.h" -#include "portmacro_asm.h" #include "portmacro.h" #include "task.h" #include "mpu_syscall_numbers.h" #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE -/** @brief Variable used to keep track of critical section nesting. +/** + * @brief Variable used to keep track of critical section nesting. * @ingroup Critical Sections * @note * This variable has to be stored as part of the task context and must be @@ -61,12 +60,14 @@ PRIVILEGED_DATA volatile uint32_t ulCriticalNesting = 0xFFFF; */ PRIVILEGED_DATA volatile uint32_t ulPortYieldRequired = pdFALSE; -/** @brief Interrupt nesting depth, used to count the number of interrupts to unwind. +/** + * @brief Interrupt nesting depth, used to count the number of interrupts to unwind. * @ingroup Interrupt Management */ PRIVILEGED_DATA volatile uint32_t ulPortInterruptNesting = 0UL; -/** @brief Variable to track whether or not the scheduler has been started. +/** + * @brief Variable to track whether or not the scheduler has been started. * @ingroup Scheduler * @note This variable is set to pdTRUE when the scheduler is started. */ @@ -74,24 +75,14 @@ PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; /*---------------------------------------------------------------------------*/ -/** @brief Returns the smallest valid MPU Region size that can hold a number of bytes. +/** + * @brief Set a FreeRTOS Task's initial context. * - * @ingroup MPU Control - * - * @param ulActualSizeInBytes Number of bytes to find a valid MPU region size for - * @return uint32_t The smallest MPU region size that can hold the requested bytes. - */ -PRIVILEGED_FUNCTION static uint32_t prvGetMPURegionSizeSetting( - uint32_t ulActualSizeInBytes -); - -/** @brief Set a FreeRTOS Task's initial context - * - * @param pxTopOfStack Pointer to where the task's stack starts - * @param pxCode Pointer to the function a task will run - * @param pvParameters Pointer to any arguments to be passed to the task's function + * @param pxTopOfStack Pointer to where the task's stack starts. + * @param pxCode Pointer to the function a task will run. + * @param pvParameters Pointer to any arguments to be passed to the task's function. * @param xRunPrivileged Marks if the task is to be run in a privileged CPU mode. - * @param xMPUSettings MPU settings to be loaded as part of a task's context + * @param xMPUSettings MPU settings to be loaded as part of a task's context. * @return StackType_t* Pointer to where to restore the task's context from. * * @ingroup Task Context @@ -106,125 +97,154 @@ PRIVILEGED_FUNCTION static uint32_t prvGetMPURegionSizeSetting( ) { /** Setup the initial context of the task. The context is set exactly as - * expected by the portRESTORE_CONTEXT() macro. */ - UBaseType_t ulContextIndex = MAX_CONTEXT_SIZE - 1U; + * expected by the portRESTORE_CONTEXT() macro and as described above the + * MAX_CONTEXT_SIZE declaration in portmacro_asm.h */ + UBaseType_t ulIndex = MAX_CONTEXT_SIZE - 1U; + + xSYSTEM_CALL_STACK_INFO * xSysCallInfo = NULL; if( pdTRUE == xRunPrivileged ) { - /* Current Program Status and Control Register */ + /* Current Program Status Register (CPSR) */ xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulTaskFlags |= 0x1F000000; - xMPUSettings->ulContext[ ulContextIndex ] = SYS_MODE; + xMPUSettings->ulContext[ ulIndex ] = SYS_MODE; } else { - /* Current Program Status and Control Register */ + /* Current Program Status Register (CPSR) */ xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulTaskFlags |= 0x10000000; - xMPUSettings->ulContext[ ulContextIndex ] = USER_MODE; + xMPUSettings->ulContext[ ulIndex ] = USER_MODE; } if( 0x0UL != ( ( uint32_t ) pxCode & portTHUMB_MODE_ADDRESS ) ) { /* The task will start in THUMB mode, set the bit in the CPSR. */ - xMPUSettings->ulContext[ ulContextIndex ] |= portTHUMB_MODE_BIT; - xMPUSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG; + xMPUSettings->ulContext[ ulIndex ] |= portTHUMB_MODE_BIT; } - /* Decrement ulContextIndex here after setting the CPSR */ - ulContextIndex--; + /* Decrement ulIndex here after setting the CPSR */ + ulIndex--; - /** First we load the Memory Location of the Task's function. - * Task Program Counter */ - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) pxCode; + /** Set Task Program Counter to provided Task Function */ + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) pxCode; + ulIndex--; /** A FreeRTOS Task is not designed to return or exit from its function. * As such a default Link Register is provided that will return to an - * error handling function. - * Task Link Register */ - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) portTASK_RETURN_ADDRESS; + * error handling function. */ + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) portTASK_RETURN_ADDRESS; + ulIndex--; - /** Set the task's stack pointer to be the bottom of it's stack, since on this - * CPU stacks grow upwards. - * Task Stack Pointer */ - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) pxTopOfStack; /* SP */ + /** CPU Stack Grows up, set Task's Stack Pointer's to bottom of stack */ + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) pxTopOfStack; /* SP */ + ulIndex--; /* Next the General Purpose Registers */ - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0x12121212; /* R12 */ - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0x11111111; /* R11 */ - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0x10101010; /* R10 */ - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0x09090909; /* R9 */ - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0x08080808; /* R8 */ - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0x07070707; /* R7 */ - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0x06060606; /* R6 */ - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0x05050505; /* R5 */ - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0x04040404; /* R4 */ - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0x03030303; /* R3 */ - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0x02020202; /* R2 */ - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0x01010101; /* R1 */ - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) pvParameters; /* R0 */ + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x12121212; /* R12 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x11111111; /* R11 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x10101010; /* R10 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x09090909; /* R9 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x08080808; /* R8 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x07070707; /* R7 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x06060606; /* R6 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x05050505; /* R5 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x04040404; /* R4 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x03030303; /* R3 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x02020202; /* R2 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x01010101; /* R1 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) pvParameters; /* R0 */ + ulIndex--; #ifdef portENABLE_FPU /* Initial Floating Point Context is the Floating Point Registers (FPRs) */ /* There are 16 Double FPRs, D0-D15 on the Cortex-R FPU enabled chips */ /* These map to the Single Precision FPRs, S0-S31 */ - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD0000015; /* S31 */ - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD1500000; /* S30 */ - - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD0000014; /* S29 */ - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD1400000; /* S28 */ - - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD0000013; /* S27 */ - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD1300000; /* S26 */ - - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD0000012; /* S25 */ - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD1200000; /* S24 */ - - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD0000011; /* S23 */ - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD1100000; /* S22 */ - - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD0000010; /* S21 */ - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD1000000; /* S20 */ - - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD0000009; /* S19 */ - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD9000000; /* S18 */ - - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD0000008; /* S17 */ - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD8000000; /* S16 */ - - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD0000007; /* S15 */ - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD7000000; /* S14 */ - - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD0000006; /* S13 */ - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD6000000; /* S12 */ - - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD0000005; /* S11 */ - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD5000000; /* S10 */ - - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD0000004; /* S9 */ - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD4000000; /* S8 */ - - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD0000003; /* S7 */ - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD3000000; /* S6 */ - - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD0000002; /* S5 */ - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD2000000; /* S4 */ - - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD0000001; /* S3 */ - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD1000000; /* S2 */ - - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD0000000; /* S1 */ - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0xD0000000; /* S0 */ + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000015; /* S31 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1500000; /* S30 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000014; /* S29 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1400000; /* S28 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000013; /* S27 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1300000; /* S26 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000012; /* S25 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1200000; /* S24 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000011; /* S23 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1100000; /* S22 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000010; /* S21 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1000000; /* S20 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000009; /* S19 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD9000000; /* S18 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000008; /* S17 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD8000000; /* S16 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000007; /* S15 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD7000000; /* S14 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000006; /* S13 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD6000000; /* S12 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000005; /* S11 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD5000000; /* S10 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000004; /* S9 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD4000000; /* S8 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000003; /* S7 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD3000000; /* S6 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000002; /* S5 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD2000000; /* S4 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000001; /* S3 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1000000; /* S2 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000000; /* S1 */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000000; /* S0 */ + ulIndex--; /* Floating Point Status and Control Register */ - xMPUSettings->ulContext[ ulContextIndex-- ] = ( StackType_t ) 0x00000000; /* FPSR */ + xMPUSettings->ulContext[ ulIndex-- ] = ( StackType_t ) 0x00000000; /* FPSR */ #endif /* portENABLE_FPU */ /* The task will start with a critical nesting count of 0. */ - xMPUSettings->ulContext[ ulContextIndex ] = portNO_CRITICAL_NESTING; + xMPUSettings->ulContext[ ulIndex ] = portNO_CRITICAL_NESTING; /* Ensure that the system call stack is double word aligned. */ - xSYSTEM_CALL_STACK_INFO * xSysCallInfo = &( xMPUSettings->xSystemCallStackInfo ); + xSysCallInfo = &( xMPUSettings->xSystemCallStackInfo ); xSysCallInfo->pulSystemCallStackPointer = &( xSysCallInfo->ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE - 1U ] ); @@ -239,12 +259,21 @@ PRIVILEGED_FUNCTION static uint32_t prvGetMPURegionSizeSetting( xSysCallInfo->pulSystemCallLinkRegister = &vPortSystemCallExit; /* Return the address where the context of this task should be restored from */ - return ( &xMPUSettings->ulContext[ ulContextIndex ] ); + return ( &xMPUSettings->ulContext[ ulIndex ] ); } /*----------------------------------------------------------------------------*/ -/* PRIVILEGED_FUNCTION */ static uint32_t prvGetMPURegionSizeSetting( + +/** + * @brief Determine smallest MPU Region Setting for a number of bytes. + * + * @ingroup MPU Control + * + * @param ulActualSizeInBytes Number of bytes to find a valid MPU region size for. + * @return uint32_t The smallest MPU region size that can hold the requested bytes. + */ +PRIVILEGED_FUNCTION static uint32_t prvGetMPURegionSizeSetting( uint32_t ulActualSizeInBytes ) { @@ -270,7 +299,8 @@ PRIVILEGED_FUNCTION static uint32_t prvGetMPURegionSizeSetting( /*----------------------------------------------------------------------------*/ -/** @brief Stores a FreeRTOS Task's MPU Settings in its TCB +/** + * @brief Stores a FreeRTOS Task's MPU Settings in its TCB. * * @param xMPUSettings The memory location in the TCB to store MPU settings * @param xRegions The MPU settings being requested by the task. @@ -296,8 +326,6 @@ PRIVILEGED_FUNCTION static uint32_t prvGetMPURegionSizeSetting( * exported from linker scripts. */ extern uint32_t * __SRAM_segment_start__; extern uint32_t * __SRAM_segment_end__; - extern uint32_t * __privileged_data_start__; - extern uint32_t * __privileged_data_end__; #else /* Declaration when these variable are exported from linker scripts. */ extern uint32_t __SRAM_segment_start__[]; @@ -309,6 +337,7 @@ PRIVILEGED_FUNCTION static uint32_t prvGetMPURegionSizeSetting( uint32_t ulRegionEnd; uint32_t ulRegionLen; uint32_t ulAlignment; + /* Allow Read/Write from User and Privileged modes */ uint32_t ulRegionAttr = portMPU_PRIV_RW_USER_RW_NOEXEC | portMPU_NORMAL_OIWTNOWA_SHARED; @@ -322,7 +351,10 @@ PRIVILEGED_FUNCTION static uint32_t prvGetMPURegionSizeSetting( ulRegionLen = prvGetMPURegionSizeSetting( ulRegionLen ); ulRegionLen |= portMPU_REGION_ENABLE; - /* Invalidate other MPU regions by using the last configurable region */ + /* MPU Settings is zero'd out in the TCB before reaching this function. + * Set this region as the highest configurable MPU Region so it overrides + * the lower unused regions. + */ ulIndex = portNUM_CONFIGURABLE_REGIONS; xMPUSettings->xRegion[ ulIndex ].ulRegionBaseAddress = ulRegionStart; @@ -333,7 +365,7 @@ PRIVILEGED_FUNCTION static uint32_t prvGetMPURegionSizeSetting( { for( ulIndex = 0UL; ulIndex < portNUM_CONFIGURABLE_REGIONS; ulIndex++ ) { - /* If a length has been provided, the region is in use */ + /* If a length has been provided, the region is in use. */ if( ( xRegions[ ulIndex ] ).ulLengthInBytes > 0UL ) { ulRegionStart = ( uint32_t ) xRegions[ ulIndex ].pvBaseAddress; @@ -366,25 +398,27 @@ PRIVILEGED_FUNCTION static uint32_t prvGetMPURegionSizeSetting( * stack region has already been configured. */ /* Cannot have a task stack of size 0 */ - configASSERT( ulStackDepth != 0x0UL ); - - /* Define the region that allows access to the stack. */ - ulRegionStart = ( uint32_t ) pxBottomOfStack; - ulRegionAttr = portMPU_PRIV_RW_USER_RW_NOEXEC | portMPU_NORMAL_OIWTNOWA_SHARED; - ulRegionLen = prvGetMPURegionSizeSetting( ulStackDepth << 2UL ); - ulRegionLen |= portMPU_REGION_ENABLE; + if( 0x0UL != ulStackDepth ) + { + /* Define the region that allows access to the stack. */ + ulRegionStart = ( uint32_t ) pxBottomOfStack; + ulRegionAttr = portMPU_PRIV_RW_USER_RW_NOEXEC | + portMPU_NORMAL_OIWTNOWA_SHARED; + ulRegionLen = prvGetMPURegionSizeSetting( ulStackDepth << 2UL ); + ulRegionLen |= portMPU_REGION_ENABLE; - /* MPU Regions must be aligned to a power of 2 equal to length */ - ulAlignment = 2UL << ( ulRegionLen >> 1UL ); - configASSERT( 0U == ( ulRegionStart % 2UL ) ); - configASSERT( 0U == ( ulRegionStart % ( ulAlignment ) ) ); + /* MPU Regions must be aligned to a power of 2 equal to length */ + ulAlignment = 2UL << ( ulRegionLen >> 1UL ); + configASSERT( 0U == ( ulRegionStart % 2UL ) ); + configASSERT( 0U == ( ulRegionStart % ( ulAlignment ) ) ); - /* xRegion[portNUM_CONFIGURABLE_REGIONS] is the Task Stack */ - ulIndex = portNUM_CONFIGURABLE_REGIONS; + /* xRegion[portNUM_CONFIGURABLE_REGIONS] is the Task Stack */ + ulIndex = portNUM_CONFIGURABLE_REGIONS; - xMPUSettings->xRegion[ ulIndex ].ulRegionBaseAddress = ulRegionStart; - xMPUSettings->xRegion[ ulIndex ].ulRegionSize = ulRegionLen; - xMPUSettings->xRegion[ ulIndex ].ulRegionAttribute = ulRegionAttr; + xMPUSettings->xRegion[ ulIndex ].ulRegionBaseAddress = ulRegionStart; + xMPUSettings->xRegion[ ulIndex ].ulRegionSize = ulRegionLen; + xMPUSettings->xRegion[ ulIndex ].ulRegionAttribute = ulRegionAttr; + } } } @@ -398,7 +432,7 @@ PRIVILEGED_FUNCTION static uint32_t prvGetMPURegionSizeSetting( * Ensure that the variables used in your linker script match up with the variable names * used at the start of this function. */ -PRIVILEGED_FUNCTION static void prvSetupDefaultMPU( void ) +PRIVILEGED_FUNCTION static void prvSetupMPU( void ) { #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being @@ -442,7 +476,7 @@ PRIVILEGED_FUNCTION static void prvSetupDefaultMPU( void ) uint32_t ulRegionLength; /* Ensure the MPU is disabled */ - prvMPUDisable(); + vMPUDisable(); /* Unprivileged and Privileged Read and Exec MPU Region for Flash */ ulRegionStart = ( uint32_t ) __FLASH_segment_start__; @@ -451,7 +485,7 @@ PRIVILEGED_FUNCTION static void prvSetupDefaultMPU( void ) ulRegionLength = prvGetMPURegionSizeSetting( ulRegionLength ); ulRegionLength |= portMPU_REGION_ENABLE; - prvMpuSetRegion( + vMPUSetRegion( portUNPRIVILEGED_FLASH_REGION, ulRegionStart, ulRegionLength, @@ -465,7 +499,7 @@ PRIVILEGED_FUNCTION static void prvSetupDefaultMPU( void ) ulRegionLength = prvGetMPURegionSizeSetting( ulRegionLength ); ulRegionLength |= portMPU_REGION_ENABLE; - prvMpuSetRegion( + vMPUSetRegion( portPRIVILEGED_FLASH_REGION, ulRegionStart, ulRegionLength, @@ -479,34 +513,35 @@ PRIVILEGED_FUNCTION static void prvSetupDefaultMPU( void ) ulRegionLength = prvGetMPURegionSizeSetting( ulRegionLength ); ulRegionLength |= portMPU_REGION_ENABLE; - prvMpuSetRegion( + vMPUSetRegion( portGENERAL_PERIPHERALS_REGION, ulRegionStart, ulRegionLength, portMPU_PRIV_RW_USER_RW_NOEXEC | portMPU_DEVICE_NONSHAREABLE ); - /* Privileged Write and Read, Unprivileged Read, MPU Region for PRIVILEGED_DATA. */ + /* Privileged Write and Read, Unprivileged no access, MPU Region for PRIVILEGED_DATA. */ ulRegionStart = ( uint32_t ) __privileged_data_start__; ulRegionEnd = ( uint32_t ) __privileged_data_end__; ulRegionLength = ulRegionEnd - ulRegionStart; ulRegionLength = prvGetMPURegionSizeSetting( ulRegionLength ); ulRegionLength |= portMPU_REGION_ENABLE; - prvMpuSetRegion( + vMPUSetRegion( portPRIVILEGED_RAM_REGION, ulRegionStart, ulRegionLength, - portMPU_PRIV_RW_USER_RO_NOEXEC | portMPU_NORMAL_OIWTNOWA_SHARED + portMPU_PRIV_RW_USER_NA_NOEXEC | portMPU_NORMAL_OIWTNOWA_SHARED ); /* After setting default regions, enable the MPU */ - prvMPUEnable(); + vMPUEnable(); } /* ------------------------------------------------------------------------- */ -/** @brief Determine if a FreeRTOS Task has been granted access to a memory region +/** + * @brief Determine if a FreeRTOS Task has been granted access to a memory region. * * @param xTaskMPURegion Pointer to a single set of MPU region registers. * @param ulRegionStart Base address of the memory region access is being requested. @@ -583,13 +618,11 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( } else { + /* Only way to receive a NULL here is if no task has been created, + * but the scheduler has been started. */ xTaskMPUSettings = xTaskGetMPUSettings( NULL ); - if( NULL == xTaskMPUSettings ) - { - xAccessGranted = pdFALSE; - } - else if( xTaskMPUSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) + if( xTaskMPUSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) { /* If a task is privileged it is assumed that it can access the buffer */ xAccessGranted = pdTRUE; @@ -615,7 +648,8 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( /*---------------------------------------------------------------------------*/ -/** @brief Determine if the FreeRTOS Task was created as a privileged task +/** + * @brief Determine if the FreeRTOS Task was created as a privileged task. * * @ingroup MPU Control * @ingroup Task Context @@ -640,8 +674,8 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( return xTaskIsPrivileged; } -/** @brief Start the FreeRTOS-Kernel's control of Tasks by starting the System Tick - * Interrupt. +/** + * @brief Start the System Tick Timer, starting the FreeRTOS-Kernel. * * @ingroup Scheduler * @return BaseType_t This function is not meant to be returned from. @@ -656,7 +690,7 @@ BaseType_t xPortStartScheduler( void ) ulCriticalNesting = 0UL; /* Configure the regions in the MPU that are common to all tasks. */ - prvSetupDefaultMPU(); + prvSetupMPU(); xSchedulerRunning = pdTRUE; @@ -774,13 +808,6 @@ BaseType_t xPortStartScheduler( void ) /*---------------------------------------------------------------------------*/ -/** @brief Function that is used as the default Link Register address for a new Task - * - * @ingroup Task Context - * @note This function is used as the default Link Register address if - * configTASK_RETURN_ADDRESS is not defined in FreeRTOSConfig.h - * - */ void prvTaskExitError( void ) { /* A function that implements a task must not exit or attempt to return to @@ -798,7 +825,8 @@ void prvTaskExitError( void ) /*---------------------------------------------------------------------------*/ -/** @brief Function meant to end the FreeRTOS Scheduler, not implemented on this port. +/** + * @brief Function meant to end the FreeRTOS Scheduler, not implemented on this port. * @ingroup Scheduler */ void vPortEndScheduler( void ) diff --git a/portable/GCC/ARM_CRx_MPU/portASM.S b/portable/GCC/ARM_CRx_MPU/portASM.S index bafc469b5a..7b3b26adc3 100644 --- a/portable/GCC/ARM_CRx_MPU/portASM.S +++ b/portable/GCC/ARM_CRx_MPU/portASM.S @@ -77,7 +77,7 @@ LDR R0, [R0] /* Push the value of ulCriticalNesting into the context, auto-increment the * LR by using the ! operator. */ - STM LR!, {R0} + STM LR!, { R0 } #if ( portENABLE_FPU == 1 ) /* Save the floating point context */ @@ -96,7 +96,7 @@ * the mode selected in the Saved Program Status Register (SPSR) */ STM LR, { R0-R14 }^ /* Not allowed to auto-increment with ! when using banked registers */ - ADD LR, LR, #portGPR_LENGTH + ADD LR, LR, #portREGISTER_LENGTH /* Pop the pushed LR, which is the pre-exception Program Counter (PC) */ POP { R0 } /* Copy the pre-exception Current Program Status Register (CPSR), which, @@ -124,7 +124,7 @@ * For (R5 = portFIRST_CONFIGURABLE_REGION ; R5 <= portSTACK_REGION ; R5++ ) */ 123: /* Load values of struct MPU_REGION_REGISTERS into R2-R4 */ - LDMIA R1!, {R2-R4} + LDMIA R1!, { R2-R4 } /* Load the values set in xMPU_REGION_REGISTERS * R2 Will hold ulRegionSize * R3 will hold ulRegionAttribute @@ -160,17 +160,17 @@ /* Move the saved FPSCR value into the FPSCR */ VMSR FPSCR, R1 /* Restore the Floating Point Registers */ - VLDM LR!, {D0-D15} + VLDM LR!, { D0-D15 } #endif /* portENABLE_FPU*/ - /* Load the value of the CPSR into R1, needed to set the SP and the LR */ - LDR R0, [LR, +#portREGISTER_CONTEXT_LENGTH] + /* Load the value of the CPSR into R0, needed to set the SP and the LR */ + LDR R0, [LR, +#(portREGISTER_LENGTH + 4UL)] /* Move the CPSR the into our SPSR */ MSR SPSR_cxsf, R0 - /* Restore the saved Stack Pointer and Link Register */ - LDM LR, {R0-R14}^ + /* Restore the saved Stack Pointer and Link Register into User Mode */ + LDM LR, { R0-R14 }^ /* Not allowed to auto-increment with ! when using banked registers */ - ADD LR, LR, #portGPR_LENGTH + ADD LR, LR, #portREGISTER_LENGTH /* Load the PC to return from the exception */ RFE LR @@ -267,7 +267,6 @@ SVC_Handler_Exit: /* This instruction loads the SPSR into the CPSR, performing the mode swap */ MOVS PC, LR -/* ----------------------------------------------------------------------------------- */ /* Perform a task swap */ svcPortYield: /* Restore the previously saved R11, R12 */ @@ -279,7 +278,6 @@ svcPortYield: /* Restore the context of the task selected to execute. */ portRESTORE_CONTEXT -/* ----------------------------------------------------------------------------------- */ /* Reset task stack and link register after a FreeRTOS System Call */ svcSystemCallExit: /* Restore the Task Stack Pointer and Link Register */ @@ -290,7 +288,7 @@ svcSystemCallExit: /* Set R11 to be the location of xSystemCallStackInfo inside the TCB */ ADD R11, R11, #portSYSTEM_CALL_INFO_OFFSET /* Restore the user mode Stack Pointer and Link Register */ - LDMIB R11, {R13-R14}^ + LDMIB R11, { R13-R14 }^ /* Zero out R12 so we can set ulTaskStackPointer back to NULL */ AND R12, R12, #0x0 /* Set pulTaskStackPointer to be 0x0 */ @@ -298,7 +296,7 @@ svcSystemCallExit: /* Set pulLinkRegisterAtSystemCallEntry to be 0x0 */ STR R12, [R11, #0x8] /* Load the ulTaskFlag so we can determine if we're going to lower privilege */ - LDM R11, {R12} + LDM R11, { R12 } /* Check if the task is privileged */ CMP R12, #portTASK_IS_PRIVILEGED_FLAG /* If the task is privileged we can leave now */ @@ -312,7 +310,6 @@ svcSystemCallExit: /* Jump back */ B SVC_Handler_Exit -/* ----------------------------------------------------------------------------------- */ /* Save task's SP and LR, swap to ulSystemCallStack Buffer, raise privilege */ svcSystemCallEnter: /* Load the base address of the uxSystemCallImplementations[] table into R14 */ @@ -342,15 +339,15 @@ svcSystemCallEnter: * assert if the ulTaskStackPointer is not null. */ MOVWEQ R0, #0x706F MOVTEQ R0, #0x7274 - MOVEQ R1, #458 + MOVEQ R1, #342 BEQ vAssertCalled /* Store the task's SP and LR to xSYSTEM_CALL_STACK_INFO */ - STM R11, {R13-R14}^ + STM R11, { R13-R14 }^ /* Not allowed to auto-increment with ! when using banked registers */ ADD R11, R11, 0x8 /* Load pulSystemCallStackPointer and pulSystemCallLinkRegister now */ - LDM R11, {R13-R14}^ + LDM R11, { R13-R14 }^ /* Swap the SPSR to SYS_MODE for the System Call. Move SPSR into R12 */ MRS R12, SPSR @@ -437,16 +434,16 @@ vPortEnableInterrupts: /* ----------------------------------------------------------------------------------- */ /** Set MPU Registers using provided values - * Function: void prvMpuSetRegion + * Function: void vMPUSetRegion * Inputs: uint32_t ulRegionNumber * Inputs: uint32_t ulBaseAddress * Inputs: uint32_t ulRegionSize * Inputs: uint32_t ulRegionPermissions */ .align 4 -.global prvMpuSetRegion -.type prvMpuSetRegion, %function -prvMpuSetRegion: +.global vMPUSetRegion +.type vMPUSetRegion, %function +vMPUSetRegion: /* Only 15 possible regions, drop all other bits */ AND R0, R0, #15 /* Select the MPU Region selected by ulRegionNumber */ @@ -463,9 +460,9 @@ prvMpuSetRegion: /* ----------------------------------------------------------------------------------- */ /* Set the Enable bit of the MPU Enable Register to 1. */ .align 4 -.global prvMPUEnable -.type prvMPUEnable, %function -prvMPUEnable: +.global vMPUEnable +.type vMPUEnable, %function +vMPUEnable: /* Read the current MPU control register into R0 */ MRC p15, #0, R0, c1, c0, #0 /* Set the enable bit to high */ @@ -482,9 +479,9 @@ prvMPUEnable: /* ----------------------------------------------------------------------------------- */ /* Set the Enable bit of the MPU Enable Register to 0. */ .align 4 -.global prvMPUDisable -.type prvMPUDisable, %function -prvMPUDisable: +.global vMPUDisable +.type vMPUDisable, %function +vMPUDisable: /* Read the MPU enable register values into R0 */ MRC p15, #0, R0, c1, c0, #0 /* Perform a bitwise AND of R0 and NOT #1, i.e. clear bit 1 */ @@ -510,7 +507,7 @@ FreeRTOS_IRQ_Handler: /* Save the return state to the IRQ stack */ SRSDB SP!, #IRQ_MODE /* Push used registers. */ - PUSH {R0-R3, R12} + PUSH { R0-R3, R12 } /* Load &ulPortInterruptNesting into R0 */ LDR R0, =ulPortInterruptNesting diff --git a/portable/GCC/ARM_CRx_MPU/portmacro.h b/portable/GCC/ARM_CRx_MPU/portmacro.h index 317b5216ba..1371d949bd 100644 --- a/portable/GCC/ARM_CRx_MPU/portmacro.h +++ b/portable/GCC/ARM_CRx_MPU/portmacro.h @@ -29,14 +29,16 @@ #ifndef PORTMACRO_H #define PORTMACRO_H -/** @brief Functions, Defines, and Structs for use in the ARM_CRx_MPU FreeRTOS-Port +/** + * @brief Functions, Defines, and Structs for use in the ARM_CRx_MPU FreeRTOS-Port * @file portmacro.h * @note The settings in this file configure FreeRTOS correctly for the given * hardware and compiler. These settings should not be altered. */ -/** @defgroup MPU Control +/** * @brief APIs and Variables used to control the onboard MPU. + * @defgroup MPU Control */ #ifdef __cplusplus @@ -52,55 +54,37 @@ extern "C" { #include "FreeRTOSConfig.h" #ifndef configENABLE_MPU - #error "This port is only usable with configENABLE_MPU set to 1" + #define configENABLE_MPU 1 #elif( configENABLE_MPU != 1 ) #error "This port is only usable with configENABLE_MPU set to 1" #endif /* configENABLE_MPU */ -#ifndef configUSE_MPU_WRAPPERS_V1 - #define configUSE_MPU_WRAPPERS_V1 0 -#elif( ( configUSE_MPU_WRAPPERS_V1 != 0 ) ) - #error "This port is only usable with configUSE_MPU_WRAPPERS_V1 set to 0" -#endif /* ( configUSE_MPU_WRAPPERS_V1 != 0 ) */ +#ifndef configENABLE_ACCESS_CONTROL_LIST + #define configENABLE_ACCESS_CONTROL_LIST 1 +#endif /* configENABLE_ACCESS_CONTROL_LIST */ -#ifndef configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY - #define configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY 1 -#elif( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY != 1 ) - #error This Port is only usable with configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY set to 1 -#endif /* ( configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY != 1 ) */ +#ifndef configPROTECTED_KERNEL_OBJECT_POOL_SIZE + #error "Set configPROTECTED_KERNEL_OBJECT_POOL_SIZE to at least the number " \ + "of FreeRTOS-Kernel Objects to be created" +#endif /* configPROTECTED_KERNEL_OBJECT_POOL_SIZE */ -#ifndef configENABLE_ACCESS_CONTROL_LIST - #define configENABLE_ACCESS_CONTROL_LIST 0 -#elif( configENABLE_ACCESS_CONTROL_LIST == 1 ) - #ifndef configPROTECTED_KERNEL_OBJECT_POOL_SIZE - #error "Set configPROTECTED_KERNEL_OBJECT_POOL_SIZE to at least the number " \ - "of FreeRTOS-Kernel Objects to be created" - #endif /* configPROTECTED_KERNEL_OBJECT_POOL_SIZE */ -#endif /* configENABLE_ACCESS_CONTROL_LIST */ - -#ifndef configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS - #define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS 0 -#elif( configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS == 1 ) - #error "This port does not support unprivileged tasks to enter a critical section" -#endif /* configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS */ -/* ------------------------- FreeRTOS Config Check ------------------------- */ -/** @brief The size in Bytes that the Privileged System Call Stack should be. +/** + * @brief The size in Bytes that the Privileged System Call Stack should be. * * @ingroup MPU Privilege * - * @note This stack is used when performing FreeRTOS System Calls. The stack pointer - * is changed to use this region when a call to a function is made that goes through - * the MPU Wrappers. - * - * This value should be a size that can be made into a MPU Region. - * + * @note A Stack of this length, in bytes, is used by FreeRTOS APIs when called + * by an unprivileged task. */ #ifndef configSYSTEM_CALL_STACK_SIZE - #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. + #error "configSYSTEM_CALL_STACK_SIZE must be defined to a length, in bytes, " \ + "to use when an unprivileged task makes a FreeRTOS Kernel call. " #endif /* configSYSTEM_CALL_STACK_SIZE */ +/* ------------------------- FreeRTOS Config Check ------------------------- */ + #if( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 ) /* Check the configuration. */ #if( configMAX_PRIORITIES > 32 ) @@ -110,7 +94,8 @@ extern "C" { "priorities as tasks that share a priority will time slice." #endif /* ( configMAX_PRIORITIES > 32 ) */ - /** @brief Mark that a task of the current priority is ready for execution + /** + * @brief Mark that a task of the current priority is ready for execution. * * @ingroup Scheduler * @@ -120,7 +105,8 @@ extern "C" { #define portRECORD_READY_PRIORITY( uxPriority, uxTopReadyPriority ) \ ( uxTopReadyPriority ) |= ( 1UL << ( uxPriority ) ) - /** @brief Mark that a task of the current priority has left the ready state + /** + * @brief Mark that a task of the current priority has left the ready state. * * @ingroup Scheduler * @@ -130,7 +116,8 @@ extern "C" { #define portRESET_READY_PRIORITY( uxPriority, uxTopReadyPriority ) \ ( uxTopReadyPriority ) &= ~( 1UL << ( uxPriority ) ) - /** @brief Determine what the highest priority ready task is. + /** + * @brief Determine what the highest priority ready task is. * * @ingroup Scheduler * @@ -147,16 +134,12 @@ extern "C" { #endif /* configSETUP_TICK_INTERRUPT */ #ifndef configCLEAR_TICK_INTERRUPT - #error configCLEAR_TICK_INTERRUPT must be defined in FreeRTOSConfig.h to clear which ever interrupt was used to generate the tick interrupt. + #error configCLEAR_TICK_INTERRUPT() must be defined in FreeRTOSConfig.h to clear which ever interrupt was used to generate the tick interrupt. #endif /* configCLEAR_TICK_INTERRUPT */ -#ifndef configEOI_ADDRESS - #error Did not define a memrory address to mark the end of an Interrupt -#endif /* configEOI_ADDRESS */ - #ifdef configUSE_TICKLESS_IDLE #if( configUSE_TICKLESS_IDLE != 0 ) - #error This port does not yet support tickless idle + #error This port does not support tickless idle #endif /* ( configUSE_TICKLESS_IDLE != 0 ) */ #endif /* configUSE_TICKLESS_IDLE */ @@ -164,7 +147,8 @@ extern "C" { #include "portmacro_asm.h" -/** @brief Critical section nesting value to mark the end of a critical section. +/** + * @brief Critical section nesting value to mark the end of a critical section. * * @ingroup Critical Sections * @@ -174,17 +158,20 @@ extern "C" { */ #define portNO_CRITICAL_NESTING ( ( uint32_t ) 0x0 ) -/** @brief Bit value used to mark if the CPU is currently executing in Thumb Mode. +/** + * @brief Bit value used to mark if the CPU is currently executing in Thumb Mode. * @ingroup Task Context */ #define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 ) -/** @brief Value used to check if a task's function is a Thumb function. +/** + * @brief Value used to check if a task's function is a Thumb function. * @ingroup Task Context */ #define portTHUMB_MODE_ADDRESS ( 0x01UL ) -/** @brief Unsigned Data type equal to the data word operating size of the CPU. +/** + * @brief Unsigned Data type equal to the data word operating size of the CPU. * * @ingroup Port Interface Specifications * @@ -194,7 +181,8 @@ extern "C" { */ typedef uint32_t StackType_t; -/** @brief Signed Data type equal to the data word operating size of the CPU. +/** + * @brief Signed Data type equal to the data word operating size of the CPU. * * @ingroup Port Interface Specifications * @@ -204,7 +192,8 @@ typedef uint32_t StackType_t; */ typedef int32_t BaseType_t; -/** @brief Unsigned Data type equal to the data word operating size of the CPU. +/** + * @brief Unsigned Data type equal to the data word operating size of the CPU. * * @ingroup Port Interface Specifications * @@ -214,7 +203,8 @@ typedef int32_t BaseType_t; */ typedef uint32_t UBaseType_t; -/** @brief Integer type used for the Tick Counter +/** + * @brief Integer type used for the Tick Counter. * * @note * Use a 32-bit tick type on a 32-bit architecture, so reads of the tick count @@ -222,21 +212,24 @@ typedef uint32_t UBaseType_t; */ typedef uint32_t TickType_t; -/** @brief Marks the direction the stack grows on the targeted CPU. +/** + * @brief Marks the direction the stack grows on the targeted CPU. * * @ingroup Port Interface Specifications * */ #define portSTACK_GROWTH ( -1 ) -/** @brief Specifies at what number of bytes a stack pointer shall be aligned. +/** + * @brief Specifies at what number of bytes a stack pointer shall be aligned. * * @ingroup Port Interface Specifications * */ #define portBYTE_ALIGNMENT 8U -/** @brief Task function prototype macro as described on FreeRTOS.org +/** + * @brief Task function prototype macro as described on FreeRTOS.org. * * @ingroup Port Interface Specifications * @@ -247,7 +240,8 @@ typedef uint32_t TickType_t; #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) \ void vFunction( void * pvParameters ) -/** @brief Task function prototype macro as described on FreeRTOS.org +/** + * @brief Task function prototype macro as described on FreeRTOS.org. * * @ingroup Port Interface Specifications * @@ -257,34 +251,40 @@ typedef uint32_t TickType_t; */ #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) -/** @brief Wrapper for the no-op ARM Assembly Instruction +/** + * @brief Wrapper for the no-op ARM Assembly Instruction. * @ingroup Port Interface Specifications */ #define portNOP() __asm volatile( "NOP" ) -/** @brief Wrapper for the Inline GCC Label +/** + * @brief Wrapper for the Inline GCC Label. * @ingroup Port Interface Specifications */ #define portINLINE __inline -/** @brief Wrapper for the ARM Memory Sync Assembly Instruction +/** + * @brief Wrapper for the ARM Memory Sync Assembly Instruction. * @ingroup Port Interface Specifications */ #define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" ) -/** @brief Defines if the system tick count can be accessed atomically +/** + * @brief Defines if the system tick count can be accessed atomically. * * @ingroup System Clock */ #define portTICK_TYPE_IS_ATOMIC 1 -/** @brief Define the number of miliseconds between system ticks. +/** + * @brief Define the number of miliseconds between system ticks. * * @ingroup System Clock */ #define portTICK_PERIOD_MS ( ( TickType_t ) 1000UL / configTICK_RATE_HZ ) -/** @brief Define the larges possible delay value for a task. +/** + * @brief Define the larges possible delay value for a task. * * @ingroup System Clock */ @@ -292,7 +292,7 @@ typedef uint32_t TickType_t; /* --------------------------- Port Assembly Handlers --------------------------- */ -/** @brief Assembly FreeRTOS Supervisor Call Handler */ +/** @brief Assembly FreeRTOS Supervisor Call Handler. */ void FreeRTOS_SVC_Handler( void ); /** @brief Assembly FreeRTOS Interrupt Handler */ @@ -300,7 +300,8 @@ void FreeRTOS_IRQ_Handler( void ); /* --------------------------- Port Assembly Functions --------------------------- */ -/** @brief Make a Supervisor Call to swap the currently running task out. +/** + * @brief Make a Supervisor Call to swap the currently running task out. * * @ingroup Scheduler * @note The FreeRTOS-Kernel needs a method to swap the current task that is @@ -314,7 +315,8 @@ void vPortYield( void ); /** @brief Raise a Supervisor Call to swap the currently running task out. */ #define portYIELD() vPortYield() -/** @brief Disable IRQs then increment the critical nesting count. +/** + * @brief Disable IRQs then increment the critical nesting count. * @ingroup Critical Section */ void vPortEnterCritical( void ); @@ -322,37 +324,44 @@ void vPortEnterCritical( void ); /** @brief Enter a Critical Section inside of the FreeRTOS-Kernel */ #define portENTER_CRITICAL() vPortEnterCritical() -/** @brief Enable IRQs and decrement the critical nesting count. +/** + * @brief Enable IRQs and decrement the critical nesting count. * @ingroup Critical Section */ void vPortExitCritical( void ); -/** @brief Exit a Critical Section inside of the FreeRTOS-Kernel. +/** + * @brief Exit a Critical Section inside of the FreeRTOS-Kernel. * @ingroup Critical Section */ #define portEXIT_CRITICAL() vPortExitCritical() -/** @brief Set the IRQ bit of the CPSR high, enabling IRQs. +/** + * @brief Set the IRQ bit of the CPSR high, enabling IRQs. * @ingroup Interrupt Management */ void vPortEnableInterrupts( void ); -/** @brief Enable Interrupts by setting the IRQ allowed flag on the CPU +/** + * @brief Enable Interrupts by setting the IRQ allowed flag on the CPU * @ingroup Interrupt Management */ #define portENABLE_INTERRUPTS() vPortEnableInterrupts() -/** @brief Set the IRQ bit of the CPSR low, disabling IRQs. +/** + * @brief Set the IRQ bit of the CPSR low, disabling IRQs. * @ingroup Interrupt Management */ void vPortDisableInterrupts( void ); -/** @brief Enable Interrupts by lowering the IRQ allowed flag on the CPU. +/** + * @brief Enable Interrupts by lowering the IRQ allowed flag on the CPU. * @ingroup Interrupt Management */ #define portDISABLE_INTERRUPTS() vPortDisableInterrupts() -/** @brief Exit the FreeRTOS-Kernel, restoring the task's settings. +/** + * @brief Exit the FreeRTOS-Kernel, restoring the task's settings. * * @ingroup Port Privilege * @@ -360,7 +369,8 @@ void vPortDisableInterrupts( void ); */ void vPortSystemCallExit( void ); -/** @brief Load the context of the first task. +/** + * @brief Load the context of the first task. * * @ingroup Scheduler * @@ -369,23 +379,26 @@ void vPortSystemCallExit( void ); */ void vPortStartFirstTask( void ); -/** @brief Enable the onboard MPU +/** + * @brief Enable the onboard MPU. * * @ingroup MPU Control * * @return void */ -void prvMPUEnable( void ); +void vMPUEnable( void ); -/** @brief Disable the onboard MPU +/** + * @brief Disable the onboard MPU. * * @ingroup MPU Control * * @return VOID */ -void prvMPUDisable( void ); +void vMPUDisable( void ); -/** @brief Assembly routine to set permissions for an MPU Region. +/** + * @brief Assembly routine to set permissions for an MPU Region. * * @ingroup MPU Control * @@ -399,7 +412,7 @@ void prvMPUDisable( void ); * provided values to the relevant MPU Registers. The inputs to this function * are checked internally before it is called in the port.c file. */ -void prvMpuSetRegion( +void vMPUSetRegion( uint32_t ulRegionNumber, uint32_t ulBaseAddress, uint32_t ulRegionSize, @@ -408,7 +421,8 @@ void prvMpuSetRegion( /* ----------------------------- Port C Functions ----------------------------- */ -/** @brief Checks whether or not the processor is privileged. +/** + * @brief Checks whether or not the processor is privileged. * * @ingroup Port Privilege * @@ -423,7 +437,8 @@ void prvMpuSetRegion( */ BaseType_t xPortIsPrivileged( void ); -/** @brief Check if the CPU is currently in a privileged operating mode +/** + * @brief Check if the CPU is currently in a privileged operating mode. * * @ingroup Port Privilege * @@ -434,7 +449,8 @@ BaseType_t xPortIsPrivileged( void ); */ #define portIS_PRIVILEGED() xPortIsPrivileged() -/** @brief Check if ulTaskFlags has portTASK_IS_PRIVILEGED_FLAG. +/** + * @brief Check if ulTaskFlags has portTASK_IS_PRIVILEGED_FLAG. * * @ingroup Port Privilege * @@ -448,7 +464,8 @@ BaseType_t xPortIsPrivileged( void ); */ BaseType_t xPortIsTaskPrivileged( void ); -/** @brief Checks whether or not the currently running task is privileged. +/** + * @brief Checks whether or not the currently running task is privileged. * * @ingroup Port Privilege * @@ -458,10 +475,18 @@ BaseType_t xPortIsTaskPrivileged( void ); */ #define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged() -/** @brief Default return to catch tasks incorrectly exiting their functions. */ +/** + * @brief Default return address for tasks, it is not meant to be called. + * + * @ingroup Task Context + * @note This function is used as the default Link Register address if + * configTASK_RETURN_ADDRESS is not defined in FreeRTOSConfig.h + * + */ void prvTaskExitError( void ); -/** @brief User provided task return function. +/** + * @brief User provided task return function. * * @ingroup Task Context * @@ -475,7 +500,8 @@ void prvTaskExitError( void ); #define configTASK_RETURN_ADDRESS prvTaskExitError #endif /* configTASK_RETURN_ADDRESS */ -/** @brief Address of function a task should execute if it exits its assigned function. +/** + * @brief Address of function a task should execute if it exits its assigned function. * * @ingroup Task Context * @@ -484,16 +510,8 @@ void prvTaskExitError( void ); */ #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS -/** @brief The lowest priority interrupt available on the CPU */ -#define portLOWEST_INTERRUPT_PRIORITY \ - ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL ) - -/** @brief The lowest priority interrupt that is usable by the system. - * @ingroup Interrupt Management - */ -#define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL ) - -/** @brief Returns the number of leading zeros in a 32 bit variable. +/** + * @brief Returns the number of leading zeros in a 32 bit variable. * * @param[in] ulBitmap 32 Bit long number to count zeros of. * @@ -503,7 +521,8 @@ UBaseType_t ulPortCountLeadingZeros( UBaseType_t ulBitmap ); /* ------------------------- Port MPU Definitions ------------------------- */ -/** @brief Mark that this port utilizes the onboard ARM MPU. +/** + * @brief Mark that this port utilizes the onboard ARM MPU. * * @ingroup MPU Control * @@ -514,7 +533,8 @@ UBaseType_t ulPortCountLeadingZeros( UBaseType_t ulBitmap ); */ #define portUSING_MPU_WRAPPERS 1 -/** @brief Used to mark if a task should be created as a privileged task. +/** + * @brief Used to mark if a task should be created as a privileged task. * * @ingroup Task Context * @ingroup MPU Control @@ -525,24 +545,15 @@ UBaseType_t ulPortCountLeadingZeros( UBaseType_t ulBitmap ); */ #define portPRIVILEGE_BIT ( 0x80000000UL ) -/** @brief Mark that a Task has Stack Frame Padding - * - * @ingroup Task Context - * - * @note Flags used for xMPU_SETTINGS.ulTaskFlags member to mark the stack frame is - * padded. */ -#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) - -/** @brief Size of the System Call Buffer in the TCB - * @ingroup Task Context - */ +/** @brief Size of the System Call Buffer in the TCB. */ #define portSYSTEM_CALL_STACK_SIZE configSYSTEM_CALL_STACK_SIZE /* Size of an Access Control List (ACL) entry in bits. */ -#define portACL_ENTRY_SIZE_BITS ( 32U ) +#define portACL_ENTRY_SIZE_BITS ( 32UL ) -/** @brief Structure to hold the MPU Register Values +/** + * @brief Structure to hold the MPU Register Values. * @struct xMPU_REGION_REGISTERS * * @ingroup MPU Control @@ -552,26 +563,30 @@ UBaseType_t ulPortCountLeadingZeros( UBaseType_t ulBitmap ); */ typedef struct MPU_REGION_REGISTERS { - /** @brief Member used to hold the MPU register value for the Region Size + /** + * @brief Member used to hold the MPU register value for the Region Size. * @struct xMPU_REGION_REGISTERS * @ingroup MPU Control */ uint32_t ulRegionSize; - /** @brief Member used to hold the MPU register value for the Region Attributes + /** + * @brief Member used to hold the MPU register value for the Region Attributes. * @struct xMPU_REGION_REGISTERS * @ingroup MPU Control */ uint32_t ulRegionAttribute; - /** @brief Member used to hold the MPU register value for the Region Base Address. + /** + * @brief Member used to hold the MPU register value for the Region Base Address. * @struct xMPU_REGION_REGISTERS * @ingroup MPU Control */ uint32_t ulRegionBaseAddress; } xMPU_REGION_REGISTERS; -/** @brief Structure to hold per-task System Call Stack information +/** + * @brief Structure to hold per-task System Call Stack information. * @struct xSYSTEM_CALL_STACK_INFO * * @ingroup Port Privilege @@ -581,41 +596,47 @@ typedef struct MPU_REGION_REGISTERS */ typedef struct SYSTEM_CALL_STACK_INFO { - /** @brief Stack Pointer of the task when it made a FreeRTOS System Call + /** + * @brief Stack Pointer of the task when it made a FreeRTOS System Call. * @note This will point to the start of ulSystemCallStackBuffer[] * @struct xSYSTEM_CALL_STACK_INFO * @ingroup Port Privilege */ uint32_t * pulTaskStackPointer; - /** @brief Link Register of the task when it made a FreeRTOS System Call + /** + * @brief Link Register of the task when it made a FreeRTOS System Call. * @struct xSYSTEM_CALL_STACK_INFO * @ingroup Port Privilege */ uint32_t * pulLinkRegisterAtSystemCallEntry; - /** @brief Pre-Set Stack Pointer to use when making a FreeRTOS System Call + /** + * @brief Pre-Set Stack Pointer to use when making a FreeRTOS System Call. * @struct xSYSTEM_CALL_STACK_INFO * @ingroup Port Privilege */ uint32_t * pulSystemCallStackPointer; - /** @brief Pre-Set Link Register to exit a FreeRTOS System Call - * @note This value is set in pxPortInitialiseStack to ensure after making - * a FreeRTOS System Call that the last LR jump is to vPortSystemCallExit() + /** + * @brief Pre-Set Link Register to exit a FreeRTOS System Call. * @struct xSYSTEM_CALL_STACK_INFO * @ingroup Port Privilege + * @note This value is set in pxPortInitialiseStack() to ensure after making + * a FreeRTOS System Call that the last LR jump is to vPortSystemCallExit() */ void * pulSystemCallLinkRegister; - /** @brief Buffer to be used when performing a FreeRTOS System Call + /** + * @brief Buffer to be used when performing a FreeRTOS System Call. * @struct xSYSTEM_CALL_STACK_INFO * @ingroup Port Privilege */ uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; } xSYSTEM_CALL_STACK_INFO; -/** @brief Per-Task MPU Settings structure stored in the TCB +/** + * @brief Per-Task MPU Settings structure stored in the TCB * @struct xMPU_SETTINGS * * @ingroup MPU Control @@ -627,29 +648,32 @@ typedef struct SYSTEM_CALL_STACK_INFO */ typedef struct MPU_SETTINGS { - /** @brief Array of Per-Task MPU Register Values. Loaded on Task Context Restore + /** + * @brief Array of Per-Task MPU Register Values. Loaded on Task Context Restore. * @struct xMPU_SETTINGS - * * @ingroup Task Context * @ingroup Port Privilege * @ingroup MPU Control */ xMPU_REGION_REGISTERS xRegion[ portTOTAL_NUM_REGIONS_IN_TCB ]; - /** @brief Buffer that holds a Task's Context when being swapped out + /** + * @brief Buffer that holds a Task's Context when being swapped out. * @struct xMPU_SETTINGS * @ingroup Task Context */ uint32_t ulContext[ MAX_CONTEXT_SIZE ]; - /** @brief Variable to hold FreeRTOS Privilege Settings + /** + * @brief Variable to hold FreeRTOS Privilege Settings. * @struct xMPU_SETTINGS * @ingroup Task Context * @ingroup MPU Control */ uint32_t ulTaskFlags; - /** @brief System Call Info structure that is stored in the TCB + /** + * @brief System Call Info structure that is stored in the TCB. * @struct xMPU_SETTINGS * @ingroup Task Context * @ingroup Port Privilege @@ -658,7 +682,7 @@ typedef struct MPU_SETTINGS #if( configENABLE_ACCESS_CONTROL_LIST == 1 ) uint32_t ulAccessControlList - [ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ]; + [ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1UL ]; #endif } xMPU_SETTINGS; diff --git a/portable/GCC/ARM_CRx_MPU/portmacro_asm.h b/portable/GCC/ARM_CRx_MPU/portmacro_asm.h index 8cfa15eddd..b9bd3e04df 100644 --- a/portable/GCC/ARM_CRx_MPU/portmacro_asm.h +++ b/portable/GCC/ARM_CRx_MPU/portmacro_asm.h @@ -45,7 +45,7 @@ extern "C" { #define portMPU_TOTAL_REGIONS ( 16UL ) #else #error "Set configTOTAL_MPU_REGIONS to the number of MPU regions in FreeRTOSConfig.h" -#endif +#endif /* configTOTAL_MPU_REGIONS */ /** On the ArmV7-R Architecture the Operating mode of the Processor is set using * the Current Program Status and Control Register (CPSR) Mode bits, [4:0] @@ -58,67 +58,86 @@ extern "C" { * * */ -/** @brief CPSR Mode bit field value for User Mode +/** + * @brief CPSR Mode bit field value for User Mode. * @ingroup Port Privilege */ #define USER_MODE 0x10U -/** @brief CPSR Mode bit field value for Fast Interrupt Handler (FIQ) Mode +/** + * @brief CPSR Mode bit field value for Fast Interrupt Handler (FIQ) Mode. * @ingroup Port Privilege */ #define FIQ_MODE 0x11U -/** @brief CPSR Mode bit field value for Interrupt Handler (IRQ) Mode +/** + * @brief CPSR Mode bit field value for Interrupt Handler (IRQ) Mode. * @ingroup Port Privilege */ #define IRQ_MODE 0x12U -/** @brief CPSR Mode bit field value for Supervisor (SVC) Mode +/** + * @brief CPSR Mode bit field value for Supervisor (SVC) Mode. * @ingroup Port Privilege */ #define SVC_MODE 0x13U -/** @brief CPSR Mode bit field value for Monitor (MON) Mode +/** + * @brief CPSR Mode bit field value for Monitor (MON) Mode. * @ingroup Port Privilege */ #define MON_MODE 0x16U -/** @brief CPSR Mode bit field value for Abort (ABT) Mode +/** + * @brief CPSR Mode bit field value for Abort (ABT) Mode. * @ingroup Port Privilege */ #define ABT_MODE 0x17U -/** @brief CPSR Mode bit field value for Hypervisor (HYP) Mode +/** + * @brief CPSR Mode bit field value for Hypervisor (HYP) Mode. * @ingroup Port Privilege */ #define HYP_MODE 0x1AU -/** @brief CPSR Mode bit field value for Undefined (UND) Mode +/** + * @brief CPSR Mode bit field value for Undefined (UND) Mode. * @ingroup Port Privilege */ #define UND_MODE 0x1BU -/** @brief CPSR Mode bit field value for System (SYS) Mode +/** + * @brief CPSR Mode bit field value for System (SYS) Mode. * @ingroup Port Privilege */ #define SYS_MODE 0x1FU -/** @brief Mark that a Task Stack has padding values added +/** + * @brief Used to mark if a task should be created as a privileged task. + * * @ingroup Task Context + * @ingroup MPU Control + * + * @note This is done by performing a bitwise OR of this value and the task priority. + * For example, to create a privileged task at priority 2 the uxPriority + * parameter should be set to ( 2 | portPRIVILEGE_BIT ). */ -#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) +#define portPRIVILEGE_BIT ( 0x80000000UL ) -/** @brief Flag uses to mark that a FreeRTOS Task is privileged +/** + * @brief Flag uses to mark that a FreeRTOS Task is privileged. * @ingroup Port Privilege */ #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/** @brief SVC Number to use when requesting a context swap. +/** + * @brief SVC Number to use when requesting a context swap. * @ingroup Scheduler */ #define portSVC_YIELD 0x0100 -/** @brief SVC Number to use when exiting a FreeRTOS System Call +/** + * @brief SVC Number to use when exiting a FreeRTOS System Call. * @ingroup MPU Control */ #define portSVC_SYSTEM_CALL_EXIT 0x0104 @@ -131,7 +150,7 @@ extern "C" { * */ -/* MPU Sub Region region */ +/* MPU Sub Region settings */ #define portMPU_SUBREGION_0_DISABLE ( 0x1UL << 8UL ) #define portMPU_SUBREGION_1_DISABLE ( 0x1UL << 9UL ) #define portMPU_SUBREGION_2_DISABLE ( 0x1UL << 10UL ) @@ -184,126 +203,25 @@ extern "C" { #define portMPU_SIZE_2GB ( 0x1EUL << 1UL ) #define portMPU_SIZE_4GB ( 0x1FUL << 1UL ) -/** @brief Used to mark if a task should be created as a privileged task. - * - * @ingroup Task Context - * @ingroup MPU Control - * - * @note This is done by performing a bitwise OR of this value and the task priority. - * For example, to create a privileged task at priority 2 the uxPriority - * parameter should be set to ( 2 | portPRIVILEGE_BIT ). - */ -#define portPRIVILEGE_BIT ( 0x80000000UL ) - -/** @brief MPU Setting for a Strongly Ordered Memory Region - * - * @ingroup MPU Control - * - */ +/* MPU Device Memory Types */ #define portMPU_REGION_STRONGLY_ORDERED ( 0x00UL ) - -/** @brief MPU Setting for a Strongly Ordered Memory Region - * - * @ingroup MPU Control - * - */ #define portMPU_REGION_DEVICE ( 0x01UL ) - -/** @brief MPU Setting for a Strongly Ordered Memory Region - * - * @ingroup MPU Control - * - */ #define portMPU_REGION_CACHEABLE_BUFFERABLE ( 0x03UL ) - -/** @brief MPU Setting for a Strongly Ordered Memory Region - * - * @ingroup MPU Control - * - */ #define portMPU_REGION_EXECUTE_NEVER ( 0x01UL << 12UL ) - -/** @brief MPU Setting for a Strongly Ordered and Shareable Memory Region - * - * @ingroup MPU Control - * - */ #define portMPU_STRONGLYORDERED_SHAREABLE ( 0x0000UL ) - -/** @brief MPU Setting for a Device and Shareable Memory Region - * - * @ingroup MPU Control - * - */ #define portMPU_DEVICE_SHAREABLE ( 0x0001UL ) - -/** @brief MPU Setting for a Device and Non-Shareable Memory Region - * - * @ingroup MPU Control - * - */ #define portMPU_DEVICE_NONSHAREABLE ( 0x0010UL ) - -/** @brief MPU Setting for a Normal Outer & Inner Write-Through, No Write Allocate & Non - * Shared - * - * @ingroup MPU Control - * - */ #define portMPU_NORMAL_OIWTNOWA_NONSHARED ( 0x0002UL ) - -/** @brief MPU Setting for a Normal Outer & Inner Write-Back, No Write Allocate & Non - * Shared - * - * @ingroup MPU Control - * - */ #define portMPU_NORMAL_OIWBNOWA_NONSHARED ( 0x0003UL ) - -/** @brief MPU Setting for a Normal Outer & Inner Write-Through, no Write Allocate & - * Shared - * - * @ingroup MPU Control - * - */ #define portMPU_NORMAL_OIWTNOWA_SHARED ( 0x0006UL ) - -/** @brief MPU Setting for a Normal Outer & Inner Write-back, no Write Allocate & Shared - * - * @ingroup MPU Control - * - */ #define portMPU_NORMAL_OIWBNOWA_SHARED ( 0x0007UL ) - -/** @brief MPU Setting for a Normal Outer & Inner Non-Cacheable & Non Shared - * - * @ingroup MPU Control - * - */ #define portMPU_NORMAL_OINC_NONSHARED ( 0x0008UL ) - -/** @brief MPU Setting for a Normal Outer & Inner Write-Back, Write Allocate & Non Shared - * - * @ingroup MPU Control - * - */ #define portMPU_NORMAL_OIWBWA_NONSHARED ( 0x000BUL ) - -/** @brief MPU Setting for a Normal Outer & Inner Non-Cacheable & Shared - * - * @ingroup MPU Control - * - */ #define portMPU_NORMAL_OINC_SHARED ( 0x000CUL ) - -/** @brief MPU Setting for a Normal Outer & Inner Write-Back, Write Allocate & Shared - * - * @ingroup MPU Control - * - */ #define portMPU_NORMAL_OIWBWA_SHARED ( 0x000FUL ) -/** @brief MPU_CTRL value for: No Access and No Execute +/** + * @brief MPU_CTRL value for: No Access and No Execute * * @ingroup MPU Control * @@ -313,7 +231,8 @@ extern "C" { */ #define portMPU_PRIV_NA_USER_NA_NOEXEC ( 0x1000UL ) -/** @brief MPU_CTRL value for Privileged Read and Exec +/** + * @brief MPU_CTRL value for Privileged Read and Exec * * @ingroup MPU Control * @@ -323,7 +242,8 @@ extern "C" { */ #define portMPU_PRIV_RO_USER_NA_EXEC ( 0x0500UL ) -/** @brief MPU_CTRL value for Privileged Read, Write, and Exec +/** + * @brief MPU_CTRL value for Privileged Read, Write, and Exec * * @ingroup MPU Control * @@ -333,7 +253,8 @@ extern "C" { */ #define portMPU_PRIV_RW_USER_NA_EXEC ( 0x0100UL ) -/** @brief MPU_CTRL value for Read Only and Execute +/** + * @brief MPU_CTRL value for Read Only and Execute * * @ingroup MPU Control * @@ -343,7 +264,8 @@ extern "C" { * */ #define portMPU_PRIV_RO_USER_RO_EXEC ( 0x0600UL ) -/** @brief MPU_CTRL value for: Read, Execute, and Privileged Write +/** + * @brief MPU_CTRL value for: Read, Execute, and Privileged Write * * @ingroup MPU Control * @@ -353,7 +275,8 @@ extern "C" { */ #define portMPU_PRIV_RW_USER_RO_EXEC ( 0x0200UL ) -/** @brief MPU_CTRL value for: Read, Write, and Execute +/** + * @brief MPU_CTRL value for: Read, Write, and Execute * * @ingroup MPU Control * @@ -363,7 +286,8 @@ extern "C" { */ #define portMPU_PRIV_RW_USER_RW_EXEC ( 0x0300UL ) -/** @brief MPU_CTRL value for: Privileged Read, Write Only, no Execute +/** + * @brief MPU_CTRL value for: Privileged Read, Write Only, no Execute * * @ingroup MPU Control * @@ -373,7 +297,8 @@ extern "C" { */ #define portMPU_PRIV_RW_USER_NA_NOEXEC ( 0x1100UL ) -/** @brief MPU_CTRL value for: All Read, Privileged Write, no Execute +/** + * @brief MPU_CTRL value for: All Read, Privileged Write, no Execute * * @ingroup MPU Control * @@ -383,7 +308,8 @@ extern "C" { */ #define portMPU_PRIV_RW_USER_RO_NOEXEC ( 0x1200UL ) -/** @brief MPU_CTRL value for: Read, Write, no Execute +/** + * @brief MPU_CTRL value for: Read, Write, no Execute * * @ingroup MPU Control * @@ -393,7 +319,8 @@ extern "C" { */ #define portMPU_PRIV_RW_USER_RW_NOEXEC ( 0x1300UL ) -/** @brief MPU_CTRL value for: Privileged Read Only, No Execute +/** + * @brief MPU_CTRL value for: Privileged Read Only, No Execute * * @ingroup MPU Control * @@ -403,7 +330,8 @@ extern "C" { */ #define portMPU_PRIV_RO_USER_NA_NOEXEC ( 0x1500UL ) -/** @brief MPU_CTRL value for: Read Only, No Execute +/** + * @brief MPU_CTRL value for: Read Only, No Execute * * @ingroup MPU Control * @@ -413,14 +341,12 @@ extern "C" { */ #define portMPU_PRIV_RO_USER_RO_NOEXEC ( 0x1600UL ) -/** @brief MPU_CTRL value to enable an MPU Region +/** + * @brief MPU_CTRL value to enable an MPU Region * @ingroup MPU Control */ #define portMPU_REGION_ENABLE ( 0x01UL ) -/** @brief The lowest priority interrupt that is usable by the system */ -#define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL ) - /** This following section is used to create the proper size for the ulContext array. * This array is where all registers related to a task's context are saved. * The size of this array will depend on if the system is using an integrated @@ -452,17 +378,15 @@ extern "C" { * */ -/** @brief The length in ulContext for the General Purpose Registers in bytes - * @note There are 13 GPRs, R0-R12 each is 32 bits, so 13 registers * 4 Bytes each - */ -#define portGPR_LENGTH ( 15U * 4U ) - -/** @brief The length in ulContext for all the registers in a context - * @note There are the 13 GPRs, the Stack Pointer, and the Link Register +/** + * @brief The length in ulContext for the General Purpose Registers in bytes. + * @note There are 13 GPRs, R0-R12, the SP, and the LR. Each are 32 bits, + * which leads to the 15 registers * 4 in length. */ -#define portREGISTER_CONTEXT_LENGTH ( ( 16 * 4U ) ) +#define portREGISTER_LENGTH ( 15U * 4U ) -/** If you KNOW that your system will not utilize the FPU in any capacity +/** + * If you KNOW that your system will not utilize the FPU in any capacity * you can set portENABLE_FPU to 0, which will reduce the per-task RAM usage * by ( 32 FPRs + 32 bit FPSCR ) * 4 bytes per register = 132, or 0x84, Bytes Per Task * BE CAREFUL DISABLING THIS: Certain APIs will try and optimize themselves @@ -474,7 +398,8 @@ extern "C" { #define configENABLE_FPU 1 #endif /* configENABLE_FPU */ -/** @brief Mark if the Floating Point Registers will be saved. +/** + * @brief Mark if the Floating Point Registers will be saved. * @ingroup Task Context * @note When using the FPU, we must save additional registers into the task's context * These consist of the Floating Point Status and Control Register (FPSCR), @@ -483,7 +408,8 @@ extern "C" { #define portENABLE_FPU configENABLE_FPU #if( portENABLE_FPU == 1 ) - /** @brief Length of a Task's Register Context when using an FPU. + /** + * @brief Length of a Task's Register Context when using an FPU. * @ingroup Task Context * @note Task Context which is stored in ulContext in order, consists of: * ulContext[ 0 ]: Critical Nesting Count: ulCriticalNesting @@ -497,7 +423,8 @@ extern "C" { */ #define MAX_CONTEXT_SIZE 51U #else - /** @brief Length of a Task's Register Context when not using an FPU. + /** + * @brief Length of a Task's Register Context when not using an FPU. * @ingroup Task Context * @note Task Context which is stored in ulContext in order, consists of: * ulContext[ 0 ]: Critical Nesting Count: ulCriticalNesting @@ -510,7 +437,8 @@ extern "C" { #define MAX_CONTEXT_SIZE 18U #endif /* MAX_CONTEXT_SIZE */ -/** @brief Numerical offset from the start of a TCB to xSystemCallStackInfo +/** + * @brief Numerical offset from the start of a TCB to xSystemCallStackInfo. * @note In the exception handlers it is necessary to load this variable from the TCB. * This provides an easy way for the exception handlers to get this structure. * The numerical value here should be equal to: From 9cf6c26a2925cf5f5ac980cf25ba347c62437f91 Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Thu, 1 Feb 2024 12:42:02 -0500 Subject: [PATCH 39/51] Add in functions to enable and disable the MPU background region. Add the calls to it in the MPU Setup function. Change the port's scheduler running variable name so it is different from the Kernels. Fix two incorrect comments SPSR -> CPSR --- .../GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S | 5 ++- portable/GCC/ARM_CRx_MPU/port.c | 16 ++++--- portable/GCC/ARM_CRx_MPU/portASM.S | 43 ++++++++++++++++++- portable/GCC/ARM_CRx_MPU/portmacro.h | 18 +++++++- portable/GCC/ARM_CRx_MPU/portmacro_asm.h | 2 + 5 files changed, 73 insertions(+), 11 deletions(-) diff --git a/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S b/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S index 0bd760f021..258f2db357 100644 --- a/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S +++ b/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S @@ -72,7 +72,7 @@ vPortSystemCallExit: .weak xPortIsPrivileged .type xPortIsPrivileged, %function xPortIsPrivileged: - /* Load value of SPSR into R0 */ + /* Load value of CPSR into R0 */ MRS R0, CPSR /* Get the relevant mode bits */ AND R0, R0, #0x1F @@ -82,6 +82,7 @@ xPortIsPrivileged: MOVEQ R0, #0x0 /* Otherwise set R0 to 1 for the return */ MOVNE R0, #0x01 + /* Return to the caller */ BLX LR /*-------------------------------------------------------------------------------*/ @@ -102,7 +103,7 @@ ulPortCountLeadingZeros: .macro processorInUserMode /* Push R0 before using it */ PUSH {R0} - /* Load value of SPSR into R0 */ + /* Load value of CPSR into R0 */ MRS R0, CPSR /* Get the relevant mode bits */ AND R0, R0, #0x1F diff --git a/portable/GCC/ARM_CRx_MPU/port.c b/portable/GCC/ARM_CRx_MPU/port.c index ee86ba11ca..5d5bcedbce 100644 --- a/portable/GCC/ARM_CRx_MPU/port.c +++ b/portable/GCC/ARM_CRx_MPU/port.c @@ -71,7 +71,7 @@ PRIVILEGED_DATA volatile uint32_t ulPortInterruptNesting = 0UL; * @ingroup Scheduler * @note This variable is set to pdTRUE when the scheduler is started. */ -PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; +PRIVILEGED_DATA static BaseType_t prvPortSchedulerRunning = pdFALSE; /*---------------------------------------------------------------------------*/ @@ -534,6 +534,10 @@ PRIVILEGED_FUNCTION static void prvSetupMPU( void ) portMPU_PRIV_RW_USER_NA_NOEXEC | portMPU_NORMAL_OIWTNOWA_SHARED ); + /* Enable the MPU Background region, allows privileged operating modes access to + * unmapped regions of memory without generating a fault. */ + vMPUEnableBackgroundRegion(); + /* After setting default regions, enable the MPU */ vMPUEnable(); } @@ -611,7 +615,7 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( xMPU_SETTINGS * xTaskMPUSettings = NULL; xMPU_REGION_REGISTERS * xTaskMPURegion = NULL; - if( pdFALSE == xSchedulerRunning ) + if( pdFALSE == prvPortSchedulerRunning ) { /* Before the scheduler starts an unknown task will be pxCurrentTCB */ xAccessGranted = pdTRUE; @@ -692,7 +696,7 @@ BaseType_t xPortStartScheduler( void ) /* Configure the regions in the MPU that are common to all tasks. */ prvSetupMPU(); - xSchedulerRunning = pdTRUE; + prvPortSchedulerRunning = pdTRUE; /* Load the context of the first task, starting the FreeRTOS-Scheduler's control. */ vPortStartFirstTask(); @@ -717,7 +721,7 @@ BaseType_t xPortStartScheduler( void ) BaseType_t xAccessGranted = pdFALSE; const xMPU_SETTINGS * xTaskMpuSettings; - if( pdFALSE == xSchedulerRunning ) + if( pdFALSE == prvPortSchedulerRunning ) { /* Grant access to all the kernel objects before the scheduler * is started. It is necessary because there is no task running @@ -831,10 +835,10 @@ void prvTaskExitError( void ) */ void vPortEndScheduler( void ) { - xSchedulerRunning = pdFALSE; + prvPortSchedulerRunning = pdFALSE; /* Not implemented in ports where there is nothing to return to. * Artificially force an assert. */ - configASSERT( xSchedulerRunning ); + configASSERT( prvPortSchedulerRunning ); } /*---------------------------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CRx_MPU/portASM.S b/portable/GCC/ARM_CRx_MPU/portASM.S index 7b3b26adc3..e793cc5fe8 100644 --- a/portable/GCC/ARM_CRx_MPU/portASM.S +++ b/portable/GCC/ARM_CRx_MPU/portASM.S @@ -121,7 +121,7 @@ /* Load the first per-task MPU region into R5 */ MOV R5, #portFIRST_CONFIGURABLE_REGION /* When creating a loop label in a macro it has to be a numeric label. - * For (R5 = portFIRST_CONFIGURABLE_REGION ; R5 <= portSTACK_REGION ; R5++ ) */ + * For (R5 = portFIRST_CONFIGURABLE_REGION ; R5 <= portNUM_CONFIGURABLE_REGIONS ; R5++ ) */ 123: /* Load values of struct MPU_REGION_REGISTERS into R2-R4 */ LDMIA R1!, { R2-R4 } @@ -142,7 +142,7 @@ /* R5++ */ ADD R5, R5, #1 /* R5 <= R6 */ - CMP R5, #portSTACK_REGION + CMP R5, #portNUM_CONFIGURABLE_REGIONS /* R5 <= R6, loop again */ BLE 123b /* R5 > portSTACK_REGION, all MPU regions have been restored */ @@ -496,6 +496,45 @@ vMPUDisable: /* Return to caller */ BX LR +/* ----------------------------------------------------------------------------------- */ +/* Enable the MPU Background Region */ +.align 4 +.global vMPUEnableBackgroundRegion +.type vMPUEnableBackgroundRegion, %function +vMPUEnableBackgroundRegion: + /* Save value in R0 */ + PUSH { R0 } + /* Read CP15 System Control Register into R0 */ + MRC p15, 0, R0, c1, c0, 0 + /* Set bit 17 so that privileged modes won't trigger unmapped MPU region faults */ + ORR R0, R0, #0x20000 + /* Write the value back out */ + MCR p15, 0, R0, c1, c0, 0 + /* Restore the used register */ + POP { R0 } + /* Return to the caller */ + BX LR + +/* ----------------------------------------------------------------------------------- */ +/* Disable the MPU Background Region */ +.align 4 +.global vMPUDisableBackgroundRegion +.type vMPUDisableBackgroundRegion, %function +vMPUDisableBackgroundRegion: + /* Save value in R0 */ + PUSH { R0 } + /* Read CP15 System Control Register into R0 */ + MRC p15, 0, R0, c1, c0, 0 + /* Clear bit 17 so that privileged modes won't trigger unmapped MPU region faults */ + BIC R0, R0, #0x20000 + /* Write the value back out */ + MCR p15, 0, R0, c1, c0, 0 + /* Restore the used register */ + POP { R0 } + /* Return to the caller */ + BX LR + +/* ----------------------------------------------------------------------------------- */ .align 4 .global FreeRTOS_IRQ_Handler .type FreeRTOS_IRQ_Handler, %function diff --git a/portable/GCC/ARM_CRx_MPU/portmacro.h b/portable/GCC/ARM_CRx_MPU/portmacro.h index 1371d949bd..dbe0475cef 100644 --- a/portable/GCC/ARM_CRx_MPU/portmacro.h +++ b/portable/GCC/ARM_CRx_MPU/portmacro.h @@ -69,7 +69,6 @@ extern "C" { #endif /* configPROTECTED_KERNEL_OBJECT_POOL_SIZE */ - /** * @brief The size in Bytes that the Privileged System Call Stack should be. * @@ -397,6 +396,23 @@ void vMPUEnable( void ); */ void vMPUDisable( void ); +/** + * @brief Enable the MPU Background Region. + * + * @ingroup MPU Control + * + * @return void + */ +void vMPUEnableBackgroundRegion( void ); + +/** + * @brief Disable the MPU Background Region + * + * @ingroup MPU Control + * + * @return void + */ +void vMPUDisableBackgroundRegion( void ); /** * @brief Assembly routine to set permissions for an MPU Region. * diff --git a/portable/GCC/ARM_CRx_MPU/portmacro_asm.h b/portable/GCC/ARM_CRx_MPU/portmacro_asm.h index b9bd3e04df..05e54d5cbb 100644 --- a/portable/GCC/ARM_CRx_MPU/portmacro_asm.h +++ b/portable/GCC/ARM_CRx_MPU/portmacro_asm.h @@ -133,12 +133,14 @@ extern "C" { /** * @brief SVC Number to use when requesting a context swap. * @ingroup Scheduler + * @note This value must not be in use in mpu_syscall_numbers.h */ #define portSVC_YIELD 0x0100 /** * @brief SVC Number to use when exiting a FreeRTOS System Call. * @ingroup MPU Control + * @note This value must not be in use in mpu_syscall_numbers.h */ #define portSVC_SYSTEM_CALL_EXIT 0x0104 From ec1332e1f40c1216cbf0981d7a73864c431ad8cf Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Thu, 1 Feb 2024 15:00:33 -0500 Subject: [PATCH 40/51] Remove the default peripheral MPU region from the port. Add declarations of private functions to the top of port.c --- portable/GCC/ARM_CRx_MPU/port.c | 142 +++++++++++++---------- portable/GCC/ARM_CRx_MPU/portmacro_asm.h | 5 +- 2 files changed, 81 insertions(+), 66 deletions(-) diff --git a/portable/GCC/ARM_CRx_MPU/port.c b/portable/GCC/ARM_CRx_MPU/port.c index 5d5bcedbce..97cfd5488b 100644 --- a/portable/GCC/ARM_CRx_MPU/port.c +++ b/portable/GCC/ARM_CRx_MPU/port.c @@ -53,27 +53,89 @@ * become unmasked before the scheduler starts. As it is stored as part of the * task context it will be set to 0 when the first task is started. */ -PRIVILEGED_DATA volatile uint32_t ulCriticalNesting = 0xFFFF; +PRIVILEGED_DATA volatile UBaseType_t ulCriticalNesting = 0xFFFF; /** @brief Set to 1 to pend a context switch from an ISR. * @ingroup Interrupt Management */ -PRIVILEGED_DATA volatile uint32_t ulPortYieldRequired = pdFALSE; +PRIVILEGED_DATA volatile UBaseType_t ulPortYieldRequired = pdFALSE; /** * @brief Interrupt nesting depth, used to count the number of interrupts to unwind. * @ingroup Interrupt Management */ -PRIVILEGED_DATA volatile uint32_t ulPortInterruptNesting = 0UL; +PRIVILEGED_DATA volatile UBaseType_t ulPortInterruptNesting = 0UL; /** * @brief Variable to track whether or not the scheduler has been started. * @ingroup Scheduler - * @note This variable is set to pdTRUE when the scheduler is started. + * @note This is the port specific version of the Kernel's xSchedulerRunning */ PRIVILEGED_DATA static BaseType_t prvPortSchedulerRunning = pdFALSE; -/*---------------------------------------------------------------------------*/ +/* -------------------------- Private Function Declarations -------------------------- */ + +/** + * @brief Determine if a FreeRTOS Task has been granted access to a memory region. + * + * @param xTaskMPURegion Pointer to a single set of MPU region registers. + * @param ulRegionStart Base address of the memory region access is being requested. + * @param ulRegionLength The length of the memory region that access is being requested. + * @param ulAccessRequested The type of access being requested, either read or write. + * @return BaseType_t pdTRUE if the task can access the region, pdFALSE otherwise + * + * @ingroup Task Context + * @ingroup MPU Control + */ +PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( + const xMPU_REGION_REGISTERS * xTaskMPURegion, + const uint32_t ulRegionStart, + const uint32_t ulRegionLength, + const uint32_t ulAccessRequested +); + +/** + * @brief Determine smallest MPU Region Setting for a number of bytes. + * + * @ingroup MPU Control + * + * @param ulActualSizeInBytes Number of bytes to find a valid MPU region size for. + * @return uint32_t The smallest MPU region size that can hold the requested bytes. + */ +PRIVILEGED_FUNCTION static uint32_t prvGetMPURegionSizeSetting( + uint32_t ulActualSizeInBytes +); + +/** @brief Set up a default MPU memory Map + * @return PRIVILEGED_FUNCTION VOID + * @ingroup MPU Control + * @note This function shall be called before calling vPortStartFirstTask(). + * @note This function works by pulling variables from the linker script. + * Ensure that the variables used in your linker script match up with the variable names + * used at the start of this function. + */ +PRIVILEGED_FUNCTION static void prvSetupMPU( void ); + +/** + * @brief Determine if a FreeRTOS Task has been granted access to a memory region. + * + * @param xTaskMPURegion Pointer to a single set of MPU region registers. + * @param ulRegionStart Base address of the memory region access is being requested. + * @param ulRegionLength The length of the memory region that access is being requested. + * @param ulAccessRequested The type of access being requested, either read or write. + * @return BaseType_t pdTRUE if the task can access the region, pdFALSE otherwise + * + * @ingroup Task Context + * @ingroup MPU Control + */ +PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( + const xMPU_REGION_REGISTERS * xTaskMPURegion, + const uint32_t ulRegionStart, + const uint32_t ulRegionLength, + const uint32_t ulAccessRequested +); + +/* ----------------------------------------------------------------------------------- */ /** * @brief Set a FreeRTOS Task's initial context. @@ -264,16 +326,7 @@ PRIVILEGED_DATA static BaseType_t prvPortSchedulerRunning = pdFALSE; /*----------------------------------------------------------------------------*/ - -/** - * @brief Determine smallest MPU Region Setting for a number of bytes. - * - * @ingroup MPU Control - * - * @param ulActualSizeInBytes Number of bytes to find a valid MPU region size for. - * @return uint32_t The smallest MPU region size that can hold the requested bytes. - */ -PRIVILEGED_FUNCTION static uint32_t prvGetMPURegionSizeSetting( +/* PRIVILEGED_FUNCTION */ static uint32_t prvGetMPURegionSizeSetting( uint32_t ulActualSizeInBytes ) { @@ -424,19 +477,10 @@ PRIVILEGED_FUNCTION static uint32_t prvGetMPURegionSizeSetting( /*----------------------------------------------------------------------------*/ -/** @brief Set up a default MPU memory Map - * @return PRIVILEGED_FUNCTION VOID - * @ingroup MPU Control - * @note This function shall be called before calling vPortStartFirstTask(). - * @note This function works by pulling variables from the linker script. - * Ensure that the variables used in your linker script match up with the variable names - * used at the start of this function. - */ -PRIVILEGED_FUNCTION static void prvSetupMPU( void ) +/* PRIVILEGED_FUNCTION */ static void prvSetupMPU( void ) { #if defined( __ARMCC_VERSION ) - /* Declaration when these variable are defined in code instead of being - * exported from linker scripts. */ + /* Declaration when these variable are defined in code. */ /* Sections used for FLASH */ extern uint32_t * __FLASH_segment_start__; extern uint32_t * __FLASH_segment_end__; @@ -449,10 +493,6 @@ PRIVILEGED_FUNCTION static void prvSetupMPU( void ) extern uint32_t * __privileged_data_start__; extern uint32_t * __privileged_data_end__; - /* Sections used for system peripherals, such as UART */ - extern uint32_t * __peripherals_start__; - extern uint32_t * __peripherals_end__; - #else /* Declaration when these variable are exported from linker scripts. */ /* Sections used for FLASH */ @@ -467,9 +507,6 @@ PRIVILEGED_FUNCTION static void prvSetupMPU( void ) extern uint32_t __privileged_data_start__[]; extern uint32_t __privileged_data_end__[]; - /* Sections used for system peripherals, such as UART */ - extern uint32_t __peripherals_start__[]; - extern uint32_t __peripherals_end__[]; #endif /* if defined( __ARMCC_VERSION ) */ uint32_t ulRegionStart; uint32_t ulRegionEnd; @@ -506,21 +543,7 @@ PRIVILEGED_FUNCTION static void prvSetupMPU( void ) portMPU_PRIV_RO_USER_NA_EXEC | portMPU_NORMAL_OIWTNOWA_SHARED ); - /* MPU Region for Peripheral Usage */ - ulRegionStart = ( uint32_t ) __peripherals_start__; - ulRegionEnd = ( uint32_t ) __peripherals_end__; - ulRegionLength = ulRegionEnd - ulRegionStart; - ulRegionLength = prvGetMPURegionSizeSetting( ulRegionLength ); - ulRegionLength |= portMPU_REGION_ENABLE; - - vMPUSetRegion( - portGENERAL_PERIPHERALS_REGION, - ulRegionStart, - ulRegionLength, - portMPU_PRIV_RW_USER_RW_NOEXEC | portMPU_DEVICE_NONSHAREABLE - ); - - /* Privileged Write and Read, Unprivileged no access, MPU Region for PRIVILEGED_DATA. */ + /* Privileged Write and Read Access for PRIVILEGED_DATA. */ ulRegionStart = ( uint32_t ) __privileged_data_start__; ulRegionEnd = ( uint32_t ) __privileged_data_end__; ulRegionLength = ulRegionEnd - ulRegionStart; @@ -542,21 +565,9 @@ PRIVILEGED_FUNCTION static void prvSetupMPU( void ) vMPUEnable(); } -/* ------------------------------------------------------------------------- */ +/* ----------------------------------------------------------------------------------- */ -/** - * @brief Determine if a FreeRTOS Task has been granted access to a memory region. - * - * @param xTaskMPURegion Pointer to a single set of MPU region registers. - * @param ulRegionStart Base address of the memory region access is being requested. - * @param ulRegionLength The length of the memory region that access is being requested. - * @param ulAccessRequested The type of access being requested, either read or write. - * @return BaseType_t pdTRUE if the task can access the region, pdFALSE otherwise - * - * @ingroup Task Context - * @ingroup MPU Control - */ -PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( +/* PRIVILEGED_FUNCTION */ static BaseType_t prvTaskCanAccessRegion( const xMPU_REGION_REGISTERS * xTaskMPURegion, const uint32_t ulRegionStart, const uint32_t ulRegionLength, @@ -570,6 +581,10 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( uint32_t ulTaskRegionLength = 2UL << ( xTaskMPURegion->ulRegionSize >> 1UL ); uint32_t ulTaskRegionEnd = xTaskMPURegion->ulRegionBaseAddress + ulTaskRegionLength; + /* Perform three different checks: + * 1. Ensure region being accessed is after the start of an MPU Region + * 2. Ensure region being accessed is before the end of the MPU Region + * 3. Ensure region being accessed ends after the start of the MPU region */ if( ( ulRegionStart >= xTaskMPURegion->ulRegionBaseAddress ) && ( ulRegionEnd <= ulTaskRegionEnd ) && ( ulRegionEnd >= ulRegionStart ) ) { @@ -685,7 +700,7 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( * @return BaseType_t This function is not meant to be returned from. * If it does return it returns pdFALSE to mark that the scheduler could not be started. */ -BaseType_t xPortStartScheduler( void ) +/* PRIVILEGED_FUNCTION */ BaseType_t xPortStartScheduler( void ) { /* Start the timer that generates the tick ISR. */ configSETUP_TICK_INTERRUPT(); @@ -696,6 +711,7 @@ BaseType_t xPortStartScheduler( void ) /* Configure the regions in the MPU that are common to all tasks. */ prvSetupMPU(); + /* Mark the port specific scheduler running variable as true */ prvPortSchedulerRunning = pdTRUE; /* Load the context of the first task, starting the FreeRTOS-Scheduler's control. */ diff --git a/portable/GCC/ARM_CRx_MPU/portmacro_asm.h b/portable/GCC/ARM_CRx_MPU/portmacro_asm.h index 05e54d5cbb..a37c62044d 100644 --- a/portable/GCC/ARM_CRx_MPU/portmacro_asm.h +++ b/portable/GCC/ARM_CRx_MPU/portmacro_asm.h @@ -164,9 +164,8 @@ extern "C" { /* Default MPU regions */ #define portFIRST_CONFIGURABLE_REGION ( 0 ) -#define portLAST_CONFIGURABLE_REGION ( portMPU_TOTAL_REGIONS - 6UL ) -#define portSTACK_REGION ( portMPU_TOTAL_REGIONS - 5UL ) -#define portGENERAL_PERIPHERALS_REGION ( portMPU_TOTAL_REGIONS - 4UL ) +#define portLAST_CONFIGURABLE_REGION ( portMPU_TOTAL_REGIONS - 5UL ) +#define portSTACK_REGION ( portMPU_TOTAL_REGIONS - 4UL ) #define portUNPRIVILEGED_FLASH_REGION ( portMPU_TOTAL_REGIONS - 3UL ) #define portPRIVILEGED_FLASH_REGION ( portMPU_TOTAL_REGIONS - 2UL ) #define portPRIVILEGED_RAM_REGION ( portMPU_TOTAL_REGIONS - 1UL ) From 56a51ff9f599bc66863e1520d998b7d413310b90 Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Thu, 1 Feb 2024 16:40:30 -0500 Subject: [PATCH 41/51] Formatting changes, move function declarations around to make the file flow a bit better --- portable/GCC/ARM_CRx_MPU/port.c | 247 +++++++++++------------ portable/GCC/ARM_CRx_MPU/portASM.S | 8 +- portable/GCC/ARM_CRx_MPU/portmacro.h | 80 ++++---- portable/GCC/ARM_CRx_MPU/portmacro_asm.h | 168 +++++++-------- 4 files changed, 246 insertions(+), 257 deletions(-) diff --git a/portable/GCC/ARM_CRx_MPU/port.c b/portable/GCC/ARM_CRx_MPU/port.c index 97cfd5488b..c18dfab66a 100644 --- a/portable/GCC/ARM_CRx_MPU/port.c +++ b/portable/GCC/ARM_CRx_MPU/port.c @@ -202,29 +202,29 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( ulIndex--; /* Next the General Purpose Registers */ - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x12121212; /* R12 */ + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x12121212; /* R12 */ ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x11111111; /* R11 */ + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x11111111; /* R11 */ ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x10101010; /* R10 */ + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x10101010; /* R10 */ ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x09090909; /* R9 */ + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x09090909; /* R9 */ ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x08080808; /* R8 */ + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x08080808; /* R8 */ ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x07070707; /* R7 */ + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x07070707; /* R7 */ ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x06060606; /* R6 */ + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x06060606; /* R6 */ ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x05050505; /* R5 */ + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x05050505; /* R5 */ ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x04040404; /* R4 */ + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x04040404; /* R4 */ ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x03030303; /* R3 */ + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x03030303; /* R3 */ ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x02020202; /* R2 */ + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x02020202; /* R2 */ ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x01010101; /* R1 */ + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x01010101; /* R1 */ ulIndex--; xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) pvParameters; /* R0 */ ulIndex--; @@ -324,33 +324,7 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( return ( &xMPUSettings->ulContext[ ulIndex ] ); } -/*----------------------------------------------------------------------------*/ - -/* PRIVILEGED_FUNCTION */ static uint32_t prvGetMPURegionSizeSetting( - uint32_t ulActualSizeInBytes -) -{ - uint32_t ulRegionSize, ulReturnValue = 4U; - - /* 32 bytes is the smallest valid region for Cortex R4 and R5 CPUs */ - for( ulRegionSize = 0x20UL; ulReturnValue < 0x1FUL; ( ulRegionSize <<= 1UL ) ) - { - if( ulActualSizeInBytes <= ulRegionSize ) - { - break; - } - else - { - ulReturnValue++; - } - } - - /* Shift the code by one before returning so it can be written directly - * into the the correct bit position of the attribute register. */ - return ulReturnValue << 1UL; -} - -/*----------------------------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ /** * @brief Stores a FreeRTOS Task's MPU Settings in its TCB. @@ -454,28 +428,116 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( if( 0x0UL != ulStackDepth ) { /* Define the region that allows access to the stack. */ - ulRegionStart = ( uint32_t ) pxBottomOfStack; - ulRegionAttr = portMPU_PRIV_RW_USER_RW_NOEXEC | - portMPU_NORMAL_OIWTNOWA_SHARED; - ulRegionLen = prvGetMPURegionSizeSetting( ulStackDepth << 2UL ); - ulRegionLen |= portMPU_REGION_ENABLE; + ulRegionStart = ( uint32_t ) pxBottomOfStack; + ulRegionAttr = portMPU_PRIV_RW_USER_RW_NOEXEC | + portMPU_NORMAL_OIWTNOWA_SHARED; + ulRegionLen = prvGetMPURegionSizeSetting( ulStackDepth << 2UL ); + ulRegionLen |= portMPU_REGION_ENABLE; - /* MPU Regions must be aligned to a power of 2 equal to length */ - ulAlignment = 2UL << ( ulRegionLen >> 1UL ); - configASSERT( 0U == ( ulRegionStart % 2UL ) ); - configASSERT( 0U == ( ulRegionStart % ( ulAlignment ) ) ); + /* MPU Regions must be aligned to a power of 2 equal to length */ + ulAlignment = 2UL << ( ulRegionLen >> 1UL ); + configASSERT( 0U == ( ulRegionStart % 2UL ) ); + configASSERT( 0U == ( ulRegionStart % ( ulAlignment ) ) ); - /* xRegion[portNUM_CONFIGURABLE_REGIONS] is the Task Stack */ - ulIndex = portNUM_CONFIGURABLE_REGIONS; + /* xRegion[portNUM_CONFIGURABLE_REGIONS] is the Task Stack */ + ulIndex = portNUM_CONFIGURABLE_REGIONS; - xMPUSettings->xRegion[ ulIndex ].ulRegionBaseAddress = ulRegionStart; - xMPUSettings->xRegion[ ulIndex ].ulRegionSize = ulRegionLen; - xMPUSettings->xRegion[ ulIndex ].ulRegionAttribute = ulRegionAttr; + xMPUSettings->xRegion[ ulIndex ].ulRegionBaseAddress = ulRegionStart; + xMPUSettings->xRegion[ ulIndex ].ulRegionSize = ulRegionLen; + xMPUSettings->xRegion[ ulIndex ].ulRegionAttribute = ulRegionAttr; } } } -/*----------------------------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ + +/** + * @brief Determine if the FreeRTOS Task was created as a privileged task. + * + * @ingroup MPU Control + * @ingroup Task Context + * + * @return pdTRUE if the Task was created as a privileged task. + * pdFALSE if the task was not created as a privileged task. + * + */ +/* PRIVILEGED_FUNCTION */ BaseType_t xPortIsTaskPrivileged( void ) +{ + BaseType_t xTaskIsPrivileged = pdFALSE; + + /* Calling task's MPU settings. */ + const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == + portTASK_IS_PRIVILEGED_FLAG ) + { + xTaskIsPrivileged = pdTRUE; + } + + return xTaskIsPrivileged; +} + +/** + * @brief Start the System Tick Timer, starting the FreeRTOS-Kernel. + * + * @ingroup Scheduler + * @return BaseType_t This function is not meant to be returned from. + * If it does return it returns pdFALSE to mark that the scheduler + * could not be started. + */ +/* PRIVILEGED_FUNCTION */ BaseType_t xPortStartScheduler( void ) +{ + /* Start the timer that generates the tick ISR. */ + configSETUP_TICK_INTERRUPT(); + + /* Reset the critical section nesting count read to execute the first task. */ + ulCriticalNesting = 0UL; + + /* Configure the regions in the MPU that are common to all tasks. */ + prvSetupMPU(); + + /* Mark the port specific scheduler running variable as true */ + prvPortSchedulerRunning = pdTRUE; + + /* Load the context of the first task, starting the FreeRTOS-Scheduler's control. */ + vPortStartFirstTask(); + + /* Will only get here if vTaskStartScheduler() was called with the CPU in + * a non-privileged mode or the binary point register was not set to its lowest + * possible value. prvTaskExitError() is referenced to prevent a compiler + * warning about it being defined but not referenced in the case that the user + * defines their own exit address. */ + ( void ) prvTaskExitError(); + return pdFALSE; +} + +/* ----------------------------------------------------------------------------------- */ + +/* PRIVILEGED_FUNCTION */ static uint32_t prvGetMPURegionSizeSetting( + uint32_t ulActualSizeInBytes +) +{ + uint32_t ulRegionSize, ulReturnValue = 4U; + + /* 32 bytes is the smallest valid region for Cortex R4 and R5 CPUs */ + for( ulRegionSize = 0x20UL; ulReturnValue < 0x1FUL; ( ulRegionSize <<= 1UL ) ) + { + if( ulActualSizeInBytes <= ulRegionSize ) + { + break; + } + else + { + ulReturnValue++; + } + } + + /* Shift the code by one before returning so it can be written directly + * into the the correct bit position of the attribute register. */ + return ulReturnValue << 1UL; +} + +/* ----------------------------------------------------------------------------------- */ /* PRIVILEGED_FUNCTION */ static void prvSetupMPU( void ) { @@ -616,7 +678,7 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( return xAccessGranted; } -/* ------------------------------------------------------------------------- */ +/* ----------------------------------------------------------------------------------- */ /* PRIVILEGED_FUNCTION */ BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, @@ -665,67 +727,7 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( return xAccessGranted; } -/*---------------------------------------------------------------------------*/ - -/** - * @brief Determine if the FreeRTOS Task was created as a privileged task. - * - * @ingroup MPU Control - * @ingroup Task Context - * - * @return pdTRUE if the Task was created as a privileged task. - * pdFALSE if the task was not created as a privileged task. - * - */ -/* PRIVILEGED_FUNCTION */ BaseType_t xPortIsTaskPrivileged( void ) -{ - BaseType_t xTaskIsPrivileged = pdFALSE; - - /* Calling task's MPU settings. */ - const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); - - if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == - portTASK_IS_PRIVILEGED_FLAG ) - { - xTaskIsPrivileged = pdTRUE; - } - - return xTaskIsPrivileged; -} - -/** - * @brief Start the System Tick Timer, starting the FreeRTOS-Kernel. - * - * @ingroup Scheduler - * @return BaseType_t This function is not meant to be returned from. - * If it does return it returns pdFALSE to mark that the scheduler could not be started. - */ -/* PRIVILEGED_FUNCTION */ BaseType_t xPortStartScheduler( void ) -{ - /* Start the timer that generates the tick ISR. */ - configSETUP_TICK_INTERRUPT(); - - /* Reset the critical section nesting count read to execute the first task. */ - ulCriticalNesting = 0UL; - - /* Configure the regions in the MPU that are common to all tasks. */ - prvSetupMPU(); - - /* Mark the port specific scheduler running variable as true */ - prvPortSchedulerRunning = pdTRUE; - - /* Load the context of the first task, starting the FreeRTOS-Scheduler's control. */ - vPortStartFirstTask(); - - /* Will only get here if vTaskStartScheduler() was called with the CPU in - * a non-privileged mode or the binary point register was not set to its lowest - * possible value. prvTaskExitError() is referenced to prevent a compiler - * warning about it being defined but not referenced in the case that the user - * defines their own exit address. */ - ( void ) prvTaskExitError(); - return pdFALSE; -} -/*---------------------------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ #if( configENABLE_ACCESS_CONTROL_LIST == 1 ) @@ -747,7 +749,8 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( } else { - xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + /* Calling task's MPU settings. */ + xTaskMpuSettings = xTaskGetMPUSettings( NULL ); ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); @@ -826,7 +829,7 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( #endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ -/*---------------------------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ void prvTaskExitError( void ) { @@ -843,12 +846,8 @@ void prvTaskExitError( void ) } } -/*---------------------------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ -/** - * @brief Function meant to end the FreeRTOS Scheduler, not implemented on this port. - * @ingroup Scheduler - */ void vPortEndScheduler( void ) { prvPortSchedulerRunning = pdFALSE; @@ -857,4 +856,4 @@ void vPortEndScheduler( void ) configASSERT( prvPortSchedulerRunning ); } -/*---------------------------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ diff --git a/portable/GCC/ARM_CRx_MPU/portASM.S b/portable/GCC/ARM_CRx_MPU/portASM.S index e793cc5fe8..b41982afc2 100644 --- a/portable/GCC/ARM_CRx_MPU/portASM.S +++ b/portable/GCC/ARM_CRx_MPU/portASM.S @@ -121,7 +121,7 @@ /* Load the first per-task MPU region into R5 */ MOV R5, #portFIRST_CONFIGURABLE_REGION /* When creating a loop label in a macro it has to be a numeric label. - * For (R5 = portFIRST_CONFIGURABLE_REGION ; R5 <= portNUM_CONFIGURABLE_REGIONS ; R5++ ) */ + * for( R5 = portFIRST_CONFIGURABLE_REGION ; R5 <= portNUM_CONFIGURABLE_REGIONS ; R5++ ) */ 123: /* Load values of struct MPU_REGION_REGISTERS into R2-R4 */ LDMIA R1!, { R2-R4 } @@ -217,7 +217,7 @@ FreeRTOS_SVC_Handler: /* Push R11-R12 for scratch space */ PUSH { R11-R12 } - /* -------------------- Caller Flash Location Check -------------------- */ + /* ------------------------- Caller Flash Location Check ------------------------- */ /* The address of the caller will be in the Link Register (LR), it will * be the caller's Program Counter (PC). Check this address to ensure the @@ -234,7 +234,7 @@ FreeRTOS_SVC_Handler: /* If the SVC was raised from outside FreeRTOS System Calls exit now */ BGE SVC_Handler_Exit - /* ----------------------- Get Caller SVC Number ----------------------- */ + /* ---------------------------- Get Caller SVC Number ---------------------------- */ /* The SPSR will be the CPSR of the calling task, store it in R11 */ MRS R11, SPSR @@ -245,7 +245,7 @@ FreeRTOS_SVC_Handler: /* Not in Thumb Mode, the instruction 0x4 before holds the SVC numebr */ LDRHEQ R11, [LR, #-0x4] - /* ---------------------------- SVC Routing ---------------------------- */ + /* --------------------------------- SVC Routing --------------------------------- */ /* Determine if the SVC number is below #NUM_SYSTEM_CALLS */ CMP R11, #NUM_SYSTEM_CALLS diff --git a/portable/GCC/ARM_CRx_MPU/portmacro.h b/portable/GCC/ARM_CRx_MPU/portmacro.h index dbe0475cef..d4788e3c42 100644 --- a/portable/GCC/ARM_CRx_MPU/portmacro.h +++ b/portable/GCC/ARM_CRx_MPU/portmacro.h @@ -48,13 +48,13 @@ extern "C" { /* Include stdint for integer types of specific bit widths */ #include -/* ------------------------- FreeRTOS Config Check ------------------------- */ +/* ------------------------------ FreeRTOS Config Check ------------------------------ */ /* Include the FreeRTOS Config file first to get the includes being used */ #include "FreeRTOSConfig.h" #ifndef configENABLE_MPU - #define configENABLE_MPU 1 + #define configENABLE_MPU 1 #elif( configENABLE_MPU != 1 ) #error "This port is only usable with configENABLE_MPU set to 1" #endif /* configENABLE_MPU */ @@ -64,11 +64,10 @@ extern "C" { #endif /* configENABLE_ACCESS_CONTROL_LIST */ #ifndef configPROTECTED_KERNEL_OBJECT_POOL_SIZE - #error "Set configPROTECTED_KERNEL_OBJECT_POOL_SIZE to at least the number " \ - "of FreeRTOS-Kernel Objects to be created" + #error "Set configPROTECTED_KERNEL_OBJECT_POOL_SIZE to at least the " \ + "number of FreeRTOS-Kernel Objects to be created" #endif /* configPROTECTED_KERNEL_OBJECT_POOL_SIZE */ - /** * @brief The size in Bytes that the Privileged System Call Stack should be. * @@ -78,17 +77,17 @@ extern "C" { * by an unprivileged task. */ #ifndef configSYSTEM_CALL_STACK_SIZE - #error "configSYSTEM_CALL_STACK_SIZE must be defined to a length, in bytes, " \ + #error "Define configSYSTEM_CALL_STACK_SIZE to a length, in bytes, " \ "to use when an unprivileged task makes a FreeRTOS Kernel call. " #endif /* configSYSTEM_CALL_STACK_SIZE */ -/* ------------------------- FreeRTOS Config Check ------------------------- */ +/* ------------------------------ FreeRTOS Config Check ------------------------------ */ #if( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 ) /* Check the configuration. */ #if( configMAX_PRIORITIES > 32 ) #error "configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when " \ - "configMAX_PRIORITIES is less than or equal to 32." \ + "configMAX_PRIORITIES is less than or equal to 32. " \ "It is very rare that a system requires more than 10 to 15 difference " \ "priorities as tasks that share a priority will time slice." #endif /* ( configMAX_PRIORITIES > 32 ) */ @@ -129,20 +128,20 @@ extern "C" { #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ #ifndef configSETUP_TICK_INTERRUPT - #error configSETUP_TICK_INTERRUPT() must be defined in FreeRTOSConfig.h to call the function that sets up the tick interrupt. + #error "configSETUP_TICK_INTERRUPT() must be defined in FreeRTOSConfig.h " \ + "to call the function that sets up the tick interrupt." #endif /* configSETUP_TICK_INTERRUPT */ #ifndef configCLEAR_TICK_INTERRUPT - #error configCLEAR_TICK_INTERRUPT() must be defined in FreeRTOSConfig.h to clear which ever interrupt was used to generate the tick interrupt. + #error "configCLEAR_TICK_INTERRUPT() must be defined in FreeRTOSConfig.h " \ + "to clear which ever interrupt was used to generate the tick interrupt." #endif /* configCLEAR_TICK_INTERRUPT */ -#ifdef configUSE_TICKLESS_IDLE - #if( configUSE_TICKLESS_IDLE != 0 ) - #error This port does not support tickless idle - #endif /* ( configUSE_TICKLESS_IDLE != 0 ) */ -#endif /* configUSE_TICKLESS_IDLE */ +#if( configUSE_TICKLESS_IDLE != 0 ) + #error This port does not support tickless idle +#endif /* ( configUSE_TICKLESS_IDLE != 0 ) */ -/* ------------------------- Port Type Definitions ------------------------- */ +/* ------------------------------ Port Type Definitions ------------------------------ */ #include "portmacro_asm.h" @@ -289,7 +288,7 @@ typedef uint32_t TickType_t; */ #define portMAX_DELAY ( TickType_t ) 0xFFFFFFFFUL -/* --------------------------- Port Assembly Handlers --------------------------- */ +/* ----------------------------- Port Assembly Functions ----------------------------- */ /** @brief Assembly FreeRTOS Supervisor Call Handler. */ void FreeRTOS_SVC_Handler( void ); @@ -297,8 +296,6 @@ void FreeRTOS_SVC_Handler( void ); /** @brief Assembly FreeRTOS Interrupt Handler */ void FreeRTOS_IRQ_Handler( void ); -/* --------------------------- Port Assembly Functions --------------------------- */ - /** * @brief Make a Supervisor Call to swap the currently running task out. * @@ -373,8 +370,8 @@ void vPortSystemCallExit( void ); * * @ingroup Scheduler * - * @note This is an assembly function implemented in portASM.s, it loads the context - * of the first task from pxCurrentTCB. + * @note This is an assembly function implemented in portASM.s, it loads the + * context of the first task from pxCurrentTCB. */ void vPortStartFirstTask( void ); @@ -435,7 +432,7 @@ void vMPUSetRegion( uint32_t ulRegionPermissions ); -/* ----------------------------- Port C Functions ----------------------------- */ +/* ------------------------------- Port.c Declarations ------------------------------- */ /** * @brief Checks whether or not the processor is privileged. @@ -517,7 +514,7 @@ void prvTaskExitError( void ); #endif /* configTASK_RETURN_ADDRESS */ /** - * @brief Address of function a task should execute if it exits its assigned function. + * @brief Function a task should execute if it exits its assigned function. * * @ingroup Task Context * @@ -535,7 +532,13 @@ void prvTaskExitError( void ); */ UBaseType_t ulPortCountLeadingZeros( UBaseType_t ulBitmap ); -/* ------------------------- Port MPU Definitions ------------------------- */ +/** + * @brief Function meant to end the FreeRTOS Scheduler, not implemented on this port. + * @ingroup Scheduler + */ +void vPortEndScheduler( void ); + +/* --------------------------------- MPU Definitions --------------------------------- */ /** * @brief Mark that this port utilizes the onboard ARM MPU. @@ -547,7 +550,7 @@ UBaseType_t ulPortCountLeadingZeros( UBaseType_t ulBitmap ); * region information contained in xRegions. * */ -#define portUSING_MPU_WRAPPERS 1 +#define portUSING_MPU_WRAPPERS 1 /** * @brief Used to mark if a task should be created as a privileged task. @@ -559,14 +562,14 @@ UBaseType_t ulPortCountLeadingZeros( UBaseType_t ulBitmap ); * For example, to create a privileged task at priority 2 the uxPriority * parameter should be set to ( 2 | portPRIVILEGE_BIT ). */ -#define portPRIVILEGE_BIT ( 0x80000000UL ) +#define portPRIVILEGE_BIT ( 0x80000000UL ) /** @brief Size of the System Call Buffer in the TCB. */ -#define portSYSTEM_CALL_STACK_SIZE configSYSTEM_CALL_STACK_SIZE +#define portSYSTEM_CALL_STACK_SIZE configSYSTEM_CALL_STACK_SIZE -/* Size of an Access Control List (ACL) entry in bits. */ -#define portACL_ENTRY_SIZE_BITS ( 32UL ) +/** @brief Size of an Access Control List (ACL) entry in bits. */ +#define portACL_ENTRY_SIZE_BITS ( 32UL ) /** * @brief Structure to hold the MPU Register Values. @@ -607,37 +610,33 @@ typedef struct MPU_REGION_REGISTERS * * @ingroup Port Privilege * - * NOTE: Do not modify this structure. The ordering of this structure is expected to be - * this way in the assembly code of the port. + * NOTE: Do not modify this structure. The ordering of this structure is expected + * to be this way in the assembly code of the port. */ typedef struct SYSTEM_CALL_STACK_INFO { /** * @brief Stack Pointer of the task when it made a FreeRTOS System Call. - * @note This will point to the start of ulSystemCallStackBuffer[] * @struct xSYSTEM_CALL_STACK_INFO - * @ingroup Port Privilege */ uint32_t * pulTaskStackPointer; /** * @brief Link Register of the task when it made a FreeRTOS System Call. * @struct xSYSTEM_CALL_STACK_INFO - * @ingroup Port Privilege */ uint32_t * pulLinkRegisterAtSystemCallEntry; /** * @brief Pre-Set Stack Pointer to use when making a FreeRTOS System Call. * @struct xSYSTEM_CALL_STACK_INFO - * @ingroup Port Privilege + * @note This will point to the start of ulSystemCallStackBuffer[] */ uint32_t * pulSystemCallStackPointer; /** * @brief Pre-Set Link Register to exit a FreeRTOS System Call. * @struct xSYSTEM_CALL_STACK_INFO - * @ingroup Port Privilege * @note This value is set in pxPortInitialiseStack() to ensure after making * a FreeRTOS System Call that the last LR jump is to vPortSystemCallExit() */ @@ -646,7 +645,6 @@ typedef struct SYSTEM_CALL_STACK_INFO /** * @brief Buffer to be used when performing a FreeRTOS System Call. * @struct xSYSTEM_CALL_STACK_INFO - * @ingroup Port Privilege */ uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; } xSYSTEM_CALL_STACK_INFO; @@ -667,32 +665,24 @@ typedef struct MPU_SETTINGS /** * @brief Array of Per-Task MPU Register Values. Loaded on Task Context Restore. * @struct xMPU_SETTINGS - * @ingroup Task Context - * @ingroup Port Privilege - * @ingroup MPU Control */ xMPU_REGION_REGISTERS xRegion[ portTOTAL_NUM_REGIONS_IN_TCB ]; /** * @brief Buffer that holds a Task's Context when being swapped out. * @struct xMPU_SETTINGS - * @ingroup Task Context */ uint32_t ulContext[ MAX_CONTEXT_SIZE ]; /** * @brief Variable to hold FreeRTOS Privilege Settings. * @struct xMPU_SETTINGS - * @ingroup Task Context - * @ingroup MPU Control */ uint32_t ulTaskFlags; /** * @brief System Call Info structure that is stored in the TCB. * @struct xMPU_SETTINGS - * @ingroup Task Context - * @ingroup Port Privilege */ xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; diff --git a/portable/GCC/ARM_CRx_MPU/portmacro_asm.h b/portable/GCC/ARM_CRx_MPU/portmacro_asm.h index a37c62044d..087f8b7b2f 100644 --- a/portable/GCC/ARM_CRx_MPU/portmacro_asm.h +++ b/portable/GCC/ARM_CRx_MPU/portmacro_asm.h @@ -62,55 +62,55 @@ extern "C" { * @brief CPSR Mode bit field value for User Mode. * @ingroup Port Privilege */ -#define USER_MODE 0x10U +#define USER_MODE 0x10U /** * @brief CPSR Mode bit field value for Fast Interrupt Handler (FIQ) Mode. * @ingroup Port Privilege */ -#define FIQ_MODE 0x11U +#define FIQ_MODE 0x11U /** * @brief CPSR Mode bit field value for Interrupt Handler (IRQ) Mode. * @ingroup Port Privilege */ -#define IRQ_MODE 0x12U +#define IRQ_MODE 0x12U /** * @brief CPSR Mode bit field value for Supervisor (SVC) Mode. * @ingroup Port Privilege */ -#define SVC_MODE 0x13U +#define SVC_MODE 0x13U /** * @brief CPSR Mode bit field value for Monitor (MON) Mode. * @ingroup Port Privilege */ -#define MON_MODE 0x16U +#define MON_MODE 0x16U /** * @brief CPSR Mode bit field value for Abort (ABT) Mode. * @ingroup Port Privilege */ -#define ABT_MODE 0x17U +#define ABT_MODE 0x17U /** * @brief CPSR Mode bit field value for Hypervisor (HYP) Mode. * @ingroup Port Privilege */ -#define HYP_MODE 0x1AU +#define HYP_MODE 0x1AU /** * @brief CPSR Mode bit field value for Undefined (UND) Mode. * @ingroup Port Privilege */ -#define UND_MODE 0x1BU +#define UND_MODE 0x1BU /** * @brief CPSR Mode bit field value for System (SYS) Mode. * @ingroup Port Privilege */ -#define SYS_MODE 0x1FU +#define SYS_MODE 0x1FU /** * @brief Used to mark if a task should be created as a privileged task. @@ -122,27 +122,27 @@ extern "C" { * For example, to create a privileged task at priority 2 the uxPriority * parameter should be set to ( 2 | portPRIVILEGE_BIT ). */ -#define portPRIVILEGE_BIT ( 0x80000000UL ) +#define portPRIVILEGE_BIT ( 0x80000000UL ) /** * @brief Flag uses to mark that a FreeRTOS Task is privileged. * @ingroup Port Privilege */ -#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) +#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) /** * @brief SVC Number to use when requesting a context swap. * @ingroup Scheduler * @note This value must not be in use in mpu_syscall_numbers.h */ -#define portSVC_YIELD 0x0100 +#define portSVC_YIELD 0x0100 /** * @brief SVC Number to use when exiting a FreeRTOS System Call. * @ingroup MPU Control * @note This value must not be in use in mpu_syscall_numbers.h */ -#define portSVC_SYSTEM_CALL_EXIT 0x0104 +#define portSVC_SYSTEM_CALL_EXIT 0x0104 /** * @addtogroup MPU Control @@ -153,73 +153,73 @@ extern "C" { */ /* MPU Sub Region settings */ -#define portMPU_SUBREGION_0_DISABLE ( 0x1UL << 8UL ) -#define portMPU_SUBREGION_1_DISABLE ( 0x1UL << 9UL ) -#define portMPU_SUBREGION_2_DISABLE ( 0x1UL << 10UL ) -#define portMPU_SUBREGION_3_DISABLE ( 0x1UL << 11UL ) -#define portMPU_SUBREGION_4_DISABLE ( 0x1UL << 12UL ) -#define portMPU_SUBREGION_5_DISABLE ( 0x1UL << 13UL ) -#define portMPU_SUBREGION_6_DISABLE ( 0x1UL << 14UL ) -#define portMPU_SUBREGION_7_DISABLE ( 0x1UL << 15UL ) +#define portMPU_SUBREGION_0_DISABLE ( 0x1UL << 8UL ) +#define portMPU_SUBREGION_1_DISABLE ( 0x1UL << 9UL ) +#define portMPU_SUBREGION_2_DISABLE ( 0x1UL << 10UL ) +#define portMPU_SUBREGION_3_DISABLE ( 0x1UL << 11UL ) +#define portMPU_SUBREGION_4_DISABLE ( 0x1UL << 12UL ) +#define portMPU_SUBREGION_5_DISABLE ( 0x1UL << 13UL ) +#define portMPU_SUBREGION_6_DISABLE ( 0x1UL << 14UL ) +#define portMPU_SUBREGION_7_DISABLE ( 0x1UL << 15UL ) /* Default MPU regions */ -#define portFIRST_CONFIGURABLE_REGION ( 0 ) -#define portLAST_CONFIGURABLE_REGION ( portMPU_TOTAL_REGIONS - 5UL ) -#define portSTACK_REGION ( portMPU_TOTAL_REGIONS - 4UL ) -#define portUNPRIVILEGED_FLASH_REGION ( portMPU_TOTAL_REGIONS - 3UL ) -#define portPRIVILEGED_FLASH_REGION ( portMPU_TOTAL_REGIONS - 2UL ) -#define portPRIVILEGED_RAM_REGION ( portMPU_TOTAL_REGIONS - 1UL ) +#define portFIRST_CONFIGURABLE_REGION ( 0 ) +#define portLAST_CONFIGURABLE_REGION ( portMPU_TOTAL_REGIONS - 5UL ) +#define portSTACK_REGION ( portMPU_TOTAL_REGIONS - 4UL ) +#define portUNPRIVILEGED_FLASH_REGION ( portMPU_TOTAL_REGIONS - 3UL ) +#define portPRIVILEGED_FLASH_REGION ( portMPU_TOTAL_REGIONS - 2UL ) +#define portPRIVILEGED_RAM_REGION ( portMPU_TOTAL_REGIONS - 1UL ) #define portNUM_CONFIGURABLE_REGIONS \ ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1UL ) /* Plus one to make space for the stack region*/ -#define portTOTAL_NUM_REGIONS_IN_TCB ( portNUM_CONFIGURABLE_REGIONS + 1UL ) +#define portTOTAL_NUM_REGIONS_IN_TCB ( portNUM_CONFIGURABLE_REGIONS + 1UL ) /* MPU region sizes */ -#define portMPU_SIZE_32B ( 0x04UL << 1UL ) -#define portMPU_SIZE_64B ( 0x05UL << 1UL ) -#define portMPU_SIZE_128B ( 0x06UL << 1UL ) -#define portMPU_SIZE_256B ( 0x07UL << 1UL ) -#define portMPU_SIZE_512B ( 0x08UL << 1UL ) -#define portMPU_SIZE_1KB ( 0x09UL << 1UL ) -#define portMPU_SIZE_2KB ( 0x0AUL << 1UL ) -#define portMPU_SIZE_4KB ( 0x0BUL << 1UL ) -#define portMPU_SIZE_8KB ( 0x0CUL << 1UL ) -#define portMPU_SIZE_16KB ( 0x0DUL << 1UL ) -#define portMPU_SIZE_32KB ( 0x0EUL << 1UL ) -#define portMPU_SIZE_64KB ( 0x0FUL << 1UL ) -#define portMPU_SIZE_128KB ( 0x10UL << 1UL ) -#define portMPU_SIZE_256KB ( 0x11UL << 1UL ) -#define portMPU_SIZE_512KB ( 0x12UL << 1UL ) -#define portMPU_SIZE_1MB ( 0x13UL << 1UL ) -#define portMPU_SIZE_2MB ( 0x14UL << 1UL ) -#define portMPU_SIZE_4MB ( 0x15UL << 1UL ) -#define portMPU_SIZE_8MB ( 0x16UL << 1UL ) -#define portMPU_SIZE_16MB ( 0x17UL << 1UL ) -#define portMPU_SIZE_32MB ( 0x18UL << 1UL ) -#define portMPU_SIZE_64MB ( 0x19UL << 1UL ) -#define portMPU_SIZE_128MB ( 0x1AUL << 1UL ) -#define portMPU_SIZE_256MB ( 0x1BUL << 1UL ) -#define portMPU_SIZE_512MB ( 0x1CUL << 1UL ) -#define portMPU_SIZE_1GB ( 0x1DUL << 1UL ) -#define portMPU_SIZE_2GB ( 0x1EUL << 1UL ) -#define portMPU_SIZE_4GB ( 0x1FUL << 1UL ) +#define portMPU_SIZE_32B ( 0x04UL << 1UL ) +#define portMPU_SIZE_64B ( 0x05UL << 1UL ) +#define portMPU_SIZE_128B ( 0x06UL << 1UL ) +#define portMPU_SIZE_256B ( 0x07UL << 1UL ) +#define portMPU_SIZE_512B ( 0x08UL << 1UL ) +#define portMPU_SIZE_1KB ( 0x09UL << 1UL ) +#define portMPU_SIZE_2KB ( 0x0AUL << 1UL ) +#define portMPU_SIZE_4KB ( 0x0BUL << 1UL ) +#define portMPU_SIZE_8KB ( 0x0CUL << 1UL ) +#define portMPU_SIZE_16KB ( 0x0DUL << 1UL ) +#define portMPU_SIZE_32KB ( 0x0EUL << 1UL ) +#define portMPU_SIZE_64KB ( 0x0FUL << 1UL ) +#define portMPU_SIZE_128KB ( 0x10UL << 1UL ) +#define portMPU_SIZE_256KB ( 0x11UL << 1UL ) +#define portMPU_SIZE_512KB ( 0x12UL << 1UL ) +#define portMPU_SIZE_1MB ( 0x13UL << 1UL ) +#define portMPU_SIZE_2MB ( 0x14UL << 1UL ) +#define portMPU_SIZE_4MB ( 0x15UL << 1UL ) +#define portMPU_SIZE_8MB ( 0x16UL << 1UL ) +#define portMPU_SIZE_16MB ( 0x17UL << 1UL ) +#define portMPU_SIZE_32MB ( 0x18UL << 1UL ) +#define portMPU_SIZE_64MB ( 0x19UL << 1UL ) +#define portMPU_SIZE_128MB ( 0x1AUL << 1UL ) +#define portMPU_SIZE_256MB ( 0x1BUL << 1UL ) +#define portMPU_SIZE_512MB ( 0x1CUL << 1UL ) +#define portMPU_SIZE_1GB ( 0x1DUL << 1UL ) +#define portMPU_SIZE_2GB ( 0x1EUL << 1UL ) +#define portMPU_SIZE_4GB ( 0x1FUL << 1UL ) /* MPU Device Memory Types */ -#define portMPU_REGION_STRONGLY_ORDERED ( 0x00UL ) -#define portMPU_REGION_DEVICE ( 0x01UL ) -#define portMPU_REGION_CACHEABLE_BUFFERABLE ( 0x03UL ) -#define portMPU_REGION_EXECUTE_NEVER ( 0x01UL << 12UL ) -#define portMPU_STRONGLYORDERED_SHAREABLE ( 0x0000UL ) -#define portMPU_DEVICE_SHAREABLE ( 0x0001UL ) -#define portMPU_DEVICE_NONSHAREABLE ( 0x0010UL ) -#define portMPU_NORMAL_OIWTNOWA_NONSHARED ( 0x0002UL ) -#define portMPU_NORMAL_OIWBNOWA_NONSHARED ( 0x0003UL ) -#define portMPU_NORMAL_OIWTNOWA_SHARED ( 0x0006UL ) -#define portMPU_NORMAL_OIWBNOWA_SHARED ( 0x0007UL ) -#define portMPU_NORMAL_OINC_NONSHARED ( 0x0008UL ) -#define portMPU_NORMAL_OIWBWA_NONSHARED ( 0x000BUL ) -#define portMPU_NORMAL_OINC_SHARED ( 0x000CUL ) -#define portMPU_NORMAL_OIWBWA_SHARED ( 0x000FUL ) +#define portMPU_REGION_STRONGLY_ORDERED ( 0x00UL ) +#define portMPU_REGION_DEVICE ( 0x01UL ) +#define portMPU_REGION_CACHEABLE_BUFFERABLE ( 0x03UL ) +#define portMPU_REGION_EXECUTE_NEVER ( 0x01UL << 12UL ) +#define portMPU_STRONGLYORDERED_SHAREABLE ( 0x0000UL ) +#define portMPU_DEVICE_SHAREABLE ( 0x0001UL ) +#define portMPU_DEVICE_NONSHAREABLE ( 0x0010UL ) +#define portMPU_NORMAL_OIWTNOWA_NONSHARED ( 0x0002UL ) +#define portMPU_NORMAL_OIWBNOWA_NONSHARED ( 0x0003UL ) +#define portMPU_NORMAL_OIWTNOWA_SHARED ( 0x0006UL ) +#define portMPU_NORMAL_OIWBNOWA_SHARED ( 0x0007UL ) +#define portMPU_NORMAL_OINC_NONSHARED ( 0x0008UL ) +#define portMPU_NORMAL_OIWBWA_NONSHARED ( 0x000BUL ) +#define portMPU_NORMAL_OINC_SHARED ( 0x000CUL ) +#define portMPU_NORMAL_OIWBWA_SHARED ( 0x000FUL ) /** * @brief MPU_CTRL value for: No Access and No Execute @@ -230,7 +230,7 @@ extern "C" { * No Access in User Mode * Cannot Execute Code from this region */ -#define portMPU_PRIV_NA_USER_NA_NOEXEC ( 0x1000UL ) +#define portMPU_PRIV_NA_USER_NA_NOEXEC ( 0x1000UL ) /** * @brief MPU_CTRL value for Privileged Read and Exec @@ -241,7 +241,7 @@ extern "C" { * No Read/Write Access in User Mode * Allowed to Execute Code from this region */ -#define portMPU_PRIV_RO_USER_NA_EXEC ( 0x0500UL ) +#define portMPU_PRIV_RO_USER_NA_EXEC ( 0x0500UL ) /** * @brief MPU_CTRL value for Privileged Read, Write, and Exec @@ -252,7 +252,7 @@ extern "C" { * No Access in User Mode * Allowed to Execute Code from this region */ -#define portMPU_PRIV_RW_USER_NA_EXEC ( 0x0100UL ) +#define portMPU_PRIV_RW_USER_NA_EXEC ( 0x0100UL ) /** * @brief MPU_CTRL value for Read Only and Execute @@ -263,7 +263,7 @@ extern "C" { * Read Only in User Mode * Allowed to Execute Code from this region * */ -#define portMPU_PRIV_RO_USER_RO_EXEC ( 0x0600UL ) +#define portMPU_PRIV_RO_USER_RO_EXEC ( 0x0600UL ) /** * @brief MPU_CTRL value for: Read, Execute, and Privileged Write @@ -274,7 +274,7 @@ extern "C" { * Read Only in User Mode * Allowed to Execute Code from this region */ -#define portMPU_PRIV_RW_USER_RO_EXEC ( 0x0200UL ) +#define portMPU_PRIV_RW_USER_RO_EXEC ( 0x0200UL ) /** * @brief MPU_CTRL value for: Read, Write, and Execute @@ -285,7 +285,7 @@ extern "C" { * Read/write in User Mode * Allowed to Execute Code from this region */ -#define portMPU_PRIV_RW_USER_RW_EXEC ( 0x0300UL ) +#define portMPU_PRIV_RW_USER_RW_EXEC ( 0x0300UL ) /** * @brief MPU_CTRL value for: Privileged Read, Write Only, no Execute @@ -296,7 +296,7 @@ extern "C" { * No Access in User Mode * Cannot Execute Code from this region */ -#define portMPU_PRIV_RW_USER_NA_NOEXEC ( 0x1100UL ) +#define portMPU_PRIV_RW_USER_NA_NOEXEC ( 0x1100UL ) /** * @brief MPU_CTRL value for: All Read, Privileged Write, no Execute @@ -307,7 +307,7 @@ extern "C" { * Read Only in User Mode * Cannot Execute Code from this region */ -#define portMPU_PRIV_RW_USER_RO_NOEXEC ( 0x1200UL ) +#define portMPU_PRIV_RW_USER_RO_NOEXEC ( 0x1200UL ) /** * @brief MPU_CTRL value for: Read, Write, no Execute @@ -318,7 +318,7 @@ extern "C" { * Read/Write in User Mode * Cannot Execute Code from this region */ -#define portMPU_PRIV_RW_USER_RW_NOEXEC ( 0x1300UL ) +#define portMPU_PRIV_RW_USER_RW_NOEXEC ( 0x1300UL ) /** * @brief MPU_CTRL value for: Privileged Read Only, No Execute @@ -329,7 +329,7 @@ extern "C" { * No Access in User Mode * Cannot Execute Code from this region */ -#define portMPU_PRIV_RO_USER_NA_NOEXEC ( 0x1500UL ) +#define portMPU_PRIV_RO_USER_NA_NOEXEC ( 0x1500UL ) /** * @brief MPU_CTRL value for: Read Only, No Execute @@ -340,13 +340,13 @@ extern "C" { * Read Only in User Mode * Cannot Execute Code from this region */ -#define portMPU_PRIV_RO_USER_RO_NOEXEC ( 0x1600UL ) +#define portMPU_PRIV_RO_USER_RO_NOEXEC ( 0x1600UL ) /** * @brief MPU_CTRL value to enable an MPU Region * @ingroup MPU Control */ -#define portMPU_REGION_ENABLE ( 0x01UL ) +#define portMPU_REGION_ENABLE ( 0x01UL ) /** This following section is used to create the proper size for the ulContext array. * This array is where all registers related to a task's context are saved. @@ -384,7 +384,7 @@ extern "C" { * @note There are 13 GPRs, R0-R12, the SP, and the LR. Each are 32 bits, * which leads to the 15 registers * 4 in length. */ -#define portREGISTER_LENGTH ( 15U * 4U ) +#define portREGISTER_LENGTH ( 15U * 4U ) /** * If you KNOW that your system will not utilize the FPU in any capacity From 797f2f22bb9993e551d8d63d46eebfe4b4bf7300 Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Thu, 1 Feb 2024 17:04:04 -0500 Subject: [PATCH 42/51] Formatting tweaks for mpu_wrappers_v2_asm.S --- .../GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S | 199 +++++++++--------- 1 file changed, 100 insertions(+), 99 deletions(-) diff --git a/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S b/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S index 258f2db357..4796ca37b6 100644 --- a/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S +++ b/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S @@ -26,7 +26,7 @@ * */ -/*---------------------------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ .arm .syntax unified @@ -37,7 +37,7 @@ #include "mpu_syscall_numbers.h" #undef FREERTOS_ASSEMBLY -/* ------------------ Start of Port Specific System Calls ------------------ */ +/* ----------------------- Start of Port Specific System Calls ----------------------- */ /** * Function: void vPortYield @@ -52,7 +52,7 @@ vPortYield: /* After yielding to another task, resume executing the calling task */ BX LR -/*-------------------------------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ /* vPortSystemCallExit */ .align 4 .global vPortSystemCallExit @@ -63,7 +63,7 @@ vPortSystemCallExit: /* After performing the requested FreeRTOS API, return to the calling task */ BX LR -/*-------------------------------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ /** * Function: BaseType_t xPortIsPrivileged * Inputs: VOID @@ -85,7 +85,7 @@ xPortIsPrivileged: /* Return to the caller */ BLX LR -/*-------------------------------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ /** * Function: UBaseType_t ulPortCountLeadingZeros * Inputs: UBaseType_t ulBitmap @@ -113,7 +113,7 @@ ulPortCountLeadingZeros: POP {R0} .endm -/*---------------------------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ .extern MPU_xTaskGetTickCountImpl /** @@ -128,7 +128,7 @@ MPU_xTaskGetTickCount: SVCEQ #SYSTEM_CALL_xTaskGetTickCount B MPU_xTaskGetTickCountImpl -/*---------------------------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ .extern MPU_uxTaskGetNumberOfTasksImpl /** @@ -143,7 +143,7 @@ MPU_uxTaskGetNumberOfTasks: SVCEQ #SYSTEM_CALL_uxTaskGetNumberOfTasks B MPU_uxTaskGetNumberOfTasksImpl -/*---------------------------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ .extern MPU_vTaskSetTimeOutStateImpl /** @@ -158,7 +158,7 @@ MPU_vTaskSetTimeOutState: SVCEQ #SYSTEM_CALL_vTaskSetTimeOutState B MPU_vTaskSetTimeOutStateImpl -/*---------------------------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ .extern MPU_xTaskCheckForTimeOutImpl /** @@ -174,7 +174,7 @@ MPU_xTaskCheckForTimeOut: SVCEQ #SYSTEM_CALL_xTaskCheckForTimeOut B MPU_xTaskCheckForTimeOutImpl -/*---------------------------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ .extern MPU_xQueueGenericSendImpl /** @@ -192,7 +192,7 @@ MPU_xQueueGenericSend: SVCEQ #SYSTEM_CALL_xQueueGenericSend B MPU_xQueueGenericSendImpl -/*---------------------------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ .extern MPU_uxQueueMessagesWaitingImpl /** @@ -207,7 +207,7 @@ MPU_uxQueueMessagesWaiting: SVCEQ #SYSTEM_CALL_uxQueueMessagesWaiting B MPU_uxQueueMessagesWaitingImpl -/*---------------------------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ .extern MPU_uxQueueSpacesAvailableImpl /** @@ -222,7 +222,7 @@ MPU_uxQueueSpacesAvailable: SVCEQ #SYSTEM_CALL_uxQueueSpacesAvailable B MPU_uxQueueSpacesAvailableImpl -/*---------------------------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ .extern MPU_xQueueReceiveImpl /** @@ -239,7 +239,7 @@ MPU_xQueueReceive: SVCEQ #SYSTEM_CALL_xQueueReceive B MPU_xQueueReceiveImpl -/*---------------------------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ .extern MPU_xQueuePeekImpl /** @@ -256,7 +256,7 @@ MPU_xQueuePeek: SVCEQ #SYSTEM_CALL_xQueuePeek B MPU_xQueuePeekImpl -/*---------------------------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ .extern MPU_xQueueSemaphoreTakeImpl /** @@ -272,7 +272,7 @@ MPU_xQueueSemaphoreTake: SVCEQ #SYSTEM_CALL_xQueueSemaphoreTake B MPU_xQueueSemaphoreTakeImpl -/*---------------------------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ .extern MPU_xEventGroupWaitBitsImpl /** @@ -287,7 +287,7 @@ MPU_xEventGroupWaitBitsEntry: SVCEQ #SYSTEM_CALL_xEventGroupWaitBits B MPU_xEventGroupWaitBitsImpl -/*---------------------------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ .extern MPU_xEventGroupClearBitsImpl /** @@ -303,7 +303,7 @@ MPU_xEventGroupClearBits: SVCEQ #SYSTEM_CALL_xEventGroupClearBits B MPU_xEventGroupClearBitsImpl -/*---------------------------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ .extern MPU_xEventGroupSetBitsImpl /** @@ -319,7 +319,7 @@ MPU_xEventGroupSetBits: SVCEQ #SYSTEM_CALL_xEventGroupSetBits B MPU_xEventGroupSetBitsImpl -/*---------------------------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ .extern MPU_xEventGroupSyncImpl /** @@ -337,7 +337,7 @@ MPU_xEventGroupSync: SVCEQ #SYSTEM_CALL_xEventGroupSync B MPU_xEventGroupSyncImpl -/*---------------------------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ .extern MPU_xStreamBufferSendImpl /** @@ -355,7 +355,7 @@ MPU_xStreamBufferSend: SVCEQ #SYSTEM_CALL_xStreamBufferSend B MPU_xStreamBufferSendImpl -/*---------------------------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ .extern MPU_xStreamBufferReceiveImpl /** @@ -373,7 +373,7 @@ MPU_xStreamBufferReceive: SVCEQ #SYSTEM_CALL_xStreamBufferReceive B MPU_xStreamBufferReceiveImpl -/*---------------------------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ .extern MPU_xStreamBufferIsFullImpl /** @@ -388,7 +388,7 @@ MPU_xStreamBufferIsFull: SVCEQ #SYSTEM_CALL_xStreamBufferIsFull B MPU_xStreamBufferIsFullImpl -/*---------------------------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ .extern MPU_xStreamBufferIsEmptyImpl /** @@ -403,7 +403,7 @@ MPU_xStreamBufferIsEmpty: SVCEQ #SYSTEM_CALL_xStreamBufferIsEmpty B MPU_xStreamBufferIsEmptyImpl -/*---------------------------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ .extern MPU_xStreamBufferSpacesAvailableImpl /** @@ -418,7 +418,7 @@ MPU_xStreamBufferSpacesAvailable: SVCEQ #SYSTEM_CALL_xStreamBufferSpacesAvailable B MPU_xStreamBufferSpacesAvailableImpl -/*---------------------------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ .extern MPU_xStreamBufferBytesAvailableImpl /** @@ -433,7 +433,7 @@ MPU_xStreamBufferBytesAvailable: SVCEQ #SYSTEM_CALL_xStreamBufferBytesAvailable B MPU_xStreamBufferBytesAvailableImpl -/*---------------------------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ .extern MPU_xStreamBufferSetTriggerLevelImpl /** @@ -449,7 +449,7 @@ MPU_xStreamBufferSetTriggerLevel: SVCEQ #SYSTEM_CALL_xStreamBufferSetTriggerLevel B MPU_xStreamBufferSetTriggerLevelImpl -/*---------------------------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ .extern MPU_xStreamBufferNextMessageLengthBytesImpl /** @@ -464,7 +464,7 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_xStreamBufferNextMessageLengthBytes B MPU_xStreamBufferNextMessageLengthBytesImpl -/*---------------------------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ #if INCLUDE_xTaskDelayUntil == 1 .extern MPU_xTaskDelayUntilImpl @@ -481,13 +481,13 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_xTaskDelayUntil B MPU_xTaskDelayUntilImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ #endif /* if ( INCLUDE_xTaskDelayUntil == 1 ) */ #if INCLUDE_xTaskAbortDelay == 1 -/*---------------------------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ .extern MPU_xTaskAbortDelayImpl /** @@ -502,13 +502,13 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_xTaskAbortDelay B MPU_xTaskAbortDelayImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ #endif /* if ( INCLUDE_xTaskAbortDelay == 1 ) */ #if INCLUDE_vTaskDelay == 1 - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_vTaskDelayImpl /** @@ -523,13 +523,13 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_vTaskDelay B MPU_vTaskDelayImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ #endif /* if ( INCLUDE_vTaskDelay == 1 ) */ #if INCLUDE_uxTaskPriorityGet == 1 - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_uxTaskPriorityGetImpl /** @@ -544,13 +544,13 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_uxTaskPriorityGet B MPU_uxTaskPriorityGetImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ #endif /* if ( INCLUDE_uxTaskPriorityGet == 1 ) */ #if INCLUDE_eTaskGetState == 1 - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_eTaskGetStateImpl /** @@ -565,13 +565,13 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_eTaskGetState B MPU_eTaskGetStateImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ #endif /* if ( INCLUDE_eTaskGetState == 1 ) */ #if configUSE_TRACE_FACILITY == 1 - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_vTaskGetInfoImpl /** @@ -589,7 +589,7 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_vTaskGetInfo B MPU_vTaskGetInfoImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_uxTaskGetSystemStateImpl /** @@ -606,7 +606,7 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_uxTaskGetSystemState B MPU_uxTaskGetSystemStateImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_uxEventGroupGetNumberImpl /** @@ -621,7 +621,7 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_uxEventGroupGetNumber B MPU_uxEventGroupGetNumberImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_vEventGroupSetNumberImpl /** @@ -637,12 +637,12 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_vEventGroupSetNumber B MPU_vEventGroupSetNumberImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ #endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ #if INCLUDE_xTaskGetIdleTaskHandle == 1 - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_xTaskGetIdleTaskHandleImpl /** * Function: TaskHandle_t MPU_xTaskGetIdleTaskHandle @@ -656,13 +656,13 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_xTaskGetIdleTaskHandle B MPU_xTaskGetIdleTaskHandleImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ #endif /* if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */ #if INCLUDE_vTaskSuspend == 1 - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_vTaskSuspendImpl /** @@ -677,7 +677,7 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_vTaskSuspend B MPU_vTaskSuspendImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_vTaskResumeImpl /** @@ -692,13 +692,13 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_vTaskResume B MPU_vTaskResumeImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ #endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ #if configGENERATE_RUN_TIME_STATS == 1 - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_ulTaskGetRunTimeCounterImpl /** @@ -713,7 +713,7 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_ulTaskGetRunTimeCounter B MPU_ulTaskGetRunTimeCounterImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_ulTaskGetRunTimePercentImpl /** @@ -728,11 +728,11 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_ulTaskGetRunTimePercent B MPU_ulTaskGetRunTimePercentImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ #if INCLUDE_xTaskGetIdleTaskHandle == 1 - /*-------------------------------------------------------------------*/ + /* --------------------------------------------------------------------------- */ .extern MPU_ulTaskGetIdleRunTimePercentImpl /** @@ -747,7 +747,7 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_ulTaskGetIdleRunTimePercent B MPU_ulTaskGetIdleRunTimePercentImpl - /*-------------------------------------------------------------------*/ + /* --------------------------------------------------------------------------- */ .extern MPU_ulTaskGetIdleRunTimeCounterImpl /** @@ -762,14 +762,15 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_ulTaskGetIdleRunTimeCounter B MPU_ulTaskGetIdleRunTimeCounterImpl - /*-------------------------------------------------------------------*/ + /* --------------------------------------------------------------------------- */ - #endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ -#endif /* configGENERATE_RUN_TIME_STATS */ + #endif /* if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */ + +#endif /* if ( configGENERATE_RUN_TIME_STATS == 1 )*/ #if configUSE_APPLICATION_TASK_TAG == 1 - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_vTaskSetApplicationTaskTagImpl /** @@ -785,7 +786,7 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_vTaskSetApplicationTaskTag B MPU_vTaskSetApplicationTaskTagImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_xTaskGetApplicationTaskTagImpl /** @@ -800,12 +801,12 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_xTaskGetApplicationTaskTag B MPU_xTaskGetApplicationTaskTagImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ #endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ #if configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_vTaskSetThreadLocalStoragePointerImpl /** @@ -822,7 +823,7 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_vTaskSetThreadLocalStoragePointer B MPU_vTaskSetThreadLocalStoragePointerImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_pvTaskGetThreadLocalStoragePointerImpl /** @@ -838,13 +839,13 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer B MPU_pvTaskGetThreadLocalStoragePointerImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ #endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ #if INCLUDE_uxTaskGetStackHighWaterMark == 1 - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_uxTaskGetStackHighWaterMarkImpl /** @@ -859,14 +860,14 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_uxTaskGetStackHighWaterMark B MPU_uxTaskGetStackHighWaterMarkImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ #endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) */ #if INCLUDE_uxTaskGetStackHighWaterMark == 2 - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_uxTaskGetStackHighWaterMark2Impl /** @@ -881,14 +882,14 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_uxTaskGetStackHighWaterMark2 B MPU_uxTaskGetStackHighWaterMark2Impl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ #endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) */ #if INCLUDE_xTaskGetCurrentTaskHandle == 1 || configUSE_MUTEXES == 1 - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_xTaskGetCurrentTaskHandleImpl /** @@ -903,13 +904,13 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_xTaskGetCurrentTaskHandle B MPU_xTaskGetCurrentTaskHandleImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ -#endif /* if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ +#endif /* if( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ #if INCLUDE_xTaskGetSchedulerState == 1 - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_xTaskGetSchedulerStateImpl /** @@ -924,13 +925,13 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_xTaskGetSchedulerState B MPU_xTaskGetSchedulerStateImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ #endif /* if ( INCLUDE_xTaskGetSchedulerState == 1 ) */ #if configUSE_MUTEXES == 1 && INCLUDE_xSemaphoreGetMutexHolder - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_xQueueGetMutexHolderImpl /** @@ -945,13 +946,13 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_xQueueGetMutexHolder B MPU_xQueueGetMutexHolderImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ #endif /* if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) */ #if configUSE_RECURSIVE_MUTEXES == 1 - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_xQueueTakeMutexRecursiveImpl /** @@ -967,7 +968,7 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_xQueueTakeMutexRecursive B MPU_xQueueTakeMutexRecursiveImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_xQueueGiveMutexRecursiveImpl /** @@ -982,13 +983,13 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_xQueueGiveMutexRecursive B MPU_xQueueGiveMutexRecursiveImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ #endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ #if configUSE_QUEUE_SETS == 1 - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_xQueueSelectFromSetImpl /** @@ -1004,7 +1005,7 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_xQueueSelectFromSet B MPU_xQueueSelectFromSetImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_xQueueAddToSetImpl /** @@ -1020,13 +1021,13 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_xQueueAddToSet B MPU_xQueueAddToSetImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ #endif /* if ( configUSE_QUEUE_SETS == 1 ) */ #if configQUEUE_REGISTRY_SIZE == 1 - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_vQueueAddToRegistryImpl /** @@ -1042,7 +1043,7 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_vQueueAddToRegistry B MPU_vQueueAddToRegistryImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_vQueueUnregisterQueueImpl /** @@ -1057,7 +1058,7 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_vQueueUnregisterQueue B MPU_vQueueUnregisterQueueImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_pcQueueGetNameImpl /** @@ -1072,13 +1073,13 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_pcQueueGetName B MPU_pcQueueGetNameImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ #endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ #if configUSE_TIMERS == 1 - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_pvTimerGetTimerIDImpl /** @@ -1093,7 +1094,7 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_pvTimerGetTimerID B MPU_pvTimerGetTimerIDImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_vTimerSetTimerIDImpl /** @@ -1109,7 +1110,7 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_vTimerSetTimerID B MPU_vTimerSetTimerIDImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_xTimerIsTimerActiveImpl /** @@ -1124,7 +1125,7 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_xTimerIsTimerActive B MPU_xTimerIsTimerActiveImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_xTimerGetTimerDaemonTaskHandleImpl /** @@ -1139,7 +1140,7 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle B MPU_xTimerGetTimerDaemonTaskHandleImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_xTimerGenericCommandFromTaskImpl /** @@ -1154,7 +1155,7 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_xTimerGenericCommandFromTask B MPU_xTimerGenericCommandFromTaskImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_pcTimerGetNameImpl @@ -1170,7 +1171,7 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_pcTimerGetName B MPU_pcTimerGetNameImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_vTimerSetReloadModeImpl /** @@ -1186,7 +1187,7 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_vTimerSetReloadMode B MPU_vTimerSetReloadModeImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_xTimerGetReloadModeImpl /** @@ -1201,7 +1202,7 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_xTimerGetReloadMode B MPU_xTimerGetReloadModeImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_uxTimerGetReloadModeImpl /** @@ -1216,7 +1217,7 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_uxTimerGetReloadMode B MPU_uxTimerGetReloadModeImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_xTimerGetPeriodImpl /** @@ -1231,7 +1232,7 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_xTimerGetPeriod B MPU_xTimerGetPeriodImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_xTimerGetExpiryTimeImpl /** @@ -1246,7 +1247,7 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_xTimerGetExpiryTime B MPU_xTimerGetExpiryTimeImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ #endif /* if ( configUSE_TIMERS == 1 ) */ @@ -1264,7 +1265,7 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_xTaskGenericNotify B MPU_xTaskGenericNotifyImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_xTaskGenericNotifyWaitImpl /** @@ -1279,7 +1280,7 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_xTaskGenericNotifyWait B MPU_xTaskGenericNotifyWaitImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_ulTaskGenericNotifyTakeImpl /** @@ -1296,7 +1297,7 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_ulTaskGenericNotifyTake B MPU_ulTaskGenericNotifyTakeImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_xTaskGenericNotifyStateClearImpl /** @@ -1312,7 +1313,7 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_xTaskGenericNotifyStateClear B MPU_xTaskGenericNotifyStateClearImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ .extern MPU_ulTaskGenericNotifyValueClearImpl /** @@ -1329,6 +1330,6 @@ MPU_xStreamBufferNextMessageLengthBytes: SVCEQ #SYSTEM_CALL_ulTaskGenericNotifyValueClear B MPU_ulTaskGenericNotifyValueClearImpl - /*-----------------------------------------------------------------------*/ + /* ------------------------------------------------------------------------------- */ #endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ From db8f23327619f5b49e4c671f640dfb3c6f7f015b Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Fri, 2 Feb 2024 10:59:15 -0500 Subject: [PATCH 43/51] Remove the check for clear tick interrupt. Format comments a little. Set copyright year for 2024 --- .../GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S | 2 +- .../GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.h | 2 +- portable/GCC/ARM_CRx_MPU/port.c | 2 +- portable/GCC/ARM_CRx_MPU/portASM.S | 2 +- portable/GCC/ARM_CRx_MPU/portmacro.h | 7 +--- portable/GCC/ARM_CRx_MPU/portmacro_asm.h | 40 +++++++++---------- 6 files changed, 25 insertions(+), 30 deletions(-) diff --git a/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S b/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S index 4796ca37b6..760ba6881e 100644 --- a/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S +++ b/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.h b/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.h index e4a411adea..1af004ce7b 100644 --- a/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.h +++ b/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CRx_MPU/port.c b/portable/GCC/ARM_CRx_MPU/port.c index c18dfab66a..d3b75a4d38 100644 --- a/portable/GCC/ARM_CRx_MPU/port.c +++ b/portable/GCC/ARM_CRx_MPU/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CRx_MPU/portASM.S b/portable/GCC/ARM_CRx_MPU/portASM.S index b41982afc2..d2e1f3bfd1 100644 --- a/portable/GCC/ARM_CRx_MPU/portASM.S +++ b/portable/GCC/ARM_CRx_MPU/portASM.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CRx_MPU/portmacro.h b/portable/GCC/ARM_CRx_MPU/portmacro.h index d4788e3c42..59376d4bef 100644 --- a/portable/GCC/ARM_CRx_MPU/portmacro.h +++ b/portable/GCC/ARM_CRx_MPU/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -132,11 +132,6 @@ extern "C" { "to call the function that sets up the tick interrupt." #endif /* configSETUP_TICK_INTERRUPT */ -#ifndef configCLEAR_TICK_INTERRUPT - #error "configCLEAR_TICK_INTERRUPT() must be defined in FreeRTOSConfig.h " \ - "to clear which ever interrupt was used to generate the tick interrupt." -#endif /* configCLEAR_TICK_INTERRUPT */ - #if( configUSE_TICKLESS_IDLE != 0 ) #error This port does not support tickless idle #endif /* ( configUSE_TICKLESS_IDLE != 0 ) */ diff --git a/portable/GCC/ARM_CRx_MPU/portmacro_asm.h b/portable/GCC/ARM_CRx_MPU/portmacro_asm.h index 087f8b7b2f..fa4ba85c1c 100644 --- a/portable/GCC/ARM_CRx_MPU/portmacro_asm.h +++ b/portable/GCC/ARM_CRx_MPU/portmacro_asm.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * @@ -47,9 +47,9 @@ extern "C" { #error "Set configTOTAL_MPU_REGIONS to the number of MPU regions in FreeRTOSConfig.h" #endif /* configTOTAL_MPU_REGIONS */ -/** On the ArmV7-R Architecture the Operating mode of the Processor is set using - * the Current Program Status and Control Register (CPSR) Mode bits, [4:0] - * the only registers banked between modes are the CPSR, Stack Pointer (R13), +/** On the ArmV7-R Architecture the Operating mode of the Processor is set + * using the Current Program Status Register (CPSR) Mode bits, [4:0]. + * The only registers banked between modes are the CPSR, Stack Pointer (R13), * and the Link Register (R14). FIQ mode also banks the GPRs R8-R12 * Of note, the only mode not "Privileged" is User Mode * @@ -125,7 +125,7 @@ extern "C" { #define portPRIVILEGE_BIT ( 0x80000000UL ) /** - * @brief Flag uses to mark that a FreeRTOS Task is privileged. + * @brief Flag used to mark that a FreeRTOS Task is privileged. * @ingroup Port Privilege */ #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) @@ -135,14 +135,14 @@ extern "C" { * @ingroup Scheduler * @note This value must not be in use in mpu_syscall_numbers.h */ -#define portSVC_YIELD 0x0100 +#define portSVC_YIELD 0x0100U /** * @brief SVC Number to use when exiting a FreeRTOS System Call. * @ingroup MPU Control * @note This value must not be in use in mpu_syscall_numbers.h */ -#define portSVC_SYSTEM_CALL_EXIT 0x0104 +#define portSVC_SYSTEM_CALL_EXIT 0x0104U /** * @addtogroup MPU Control @@ -381,18 +381,19 @@ extern "C" { /** * @brief The length in ulContext for the General Purpose Registers in bytes. - * @note There are 13 GPRs, R0-R12, the SP, and the LR. Each are 32 bits, - * which leads to the 15 registers * 4 in length. + * @note There are 13 GPRs, R0-R12, the SP, and the LR. Each register is 32 + * bits, so the register context length is 15 registers * 4 bytes = 60 bytes. */ #define portREGISTER_LENGTH ( 15U * 4U ) /** * If you KNOW that your system will not utilize the FPU in any capacity - * you can set portENABLE_FPU to 0, which will reduce the per-task RAM usage - * by ( 32 FPRs + 32 bit FPSCR ) * 4 bytes per register = 132, or 0x84, Bytes Per Task + * you can set portENABLE_FPU to 0. This will reduce the per-task RAM usage + * by ( 32 FPRs + 32 bit FPSCR ) * 4 bytes per register = 132 Bytes Per Task. + * It will also increase context swap speed, as these can then be ignored. * BE CAREFUL DISABLING THIS: Certain APIs will try and optimize themselves - * by using the FPRs. If the FPU context is not saved and this happens it could be - * exceedingly difficult to debug why a strcpy() or other similar function + * by using the FPRs. If the FPU context is not saved and this happens it could + * be exceedingly difficult to debug why a strcpy() or other similar function * seems to randomly fail. */ #ifndef configENABLE_FPU @@ -400,11 +401,10 @@ extern "C" { #endif /* configENABLE_FPU */ /** - * @brief Mark if the Floating Point Registers will be saved. + * @brief Mark if the Floating Point Registers (FPRs) will be saved. * @ingroup Task Context - * @note When using the FPU, we must save additional registers into the task's context - * These consist of the Floating Point Status and Control Register (FPSCR), - * As well as the Floating Point Registers (FPRs) + * @note Using the FPU requires save FPRs into the task's context. As well as + * the Floating Point Status and Control Register (FPSCR). */ #define portENABLE_FPU configENABLE_FPU @@ -440,13 +440,13 @@ extern "C" { /** * @brief Numerical offset from the start of a TCB to xSystemCallStackInfo. - * @note In the exception handlers it is necessary to load this variable from the TCB. + * @note This is used in portASM.S to load xSystemCallStackInfo from the TCB. * This provides an easy way for the exception handlers to get this structure. * The numerical value here should be equal to: - * sizeof( xRegion ) + sizeof( ulContext ) + sizeof( ulTaskFlags) + * sizeof( xRegion ) + sizeof( ulContext ) + sizeof( ulTaskFlags ) */ #define portSYSTEM_CALL_INFO_OFFSET \ - ( ( ( portTOTAL_NUM_REGIONS_IN_TCB * 3U ) + ( MAX_CONTEXT_SIZE ) + 1 ) * 4U ) + ( ( ( portTOTAL_NUM_REGIONS_IN_TCB * 3U ) + ( MAX_CONTEXT_SIZE ) + 1U ) * 4U ) #ifdef __cplusplus } /* extern C */ From 72ee9e302d008e4fe11c36ac3b6a6ba8cd6eb058 Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Wed, 7 Feb 2024 13:13:54 -0800 Subject: [PATCH 44/51] Fix two incorrect ifdef guards in mpu_wrappers_v2_asm.S --- portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S b/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S index 760ba6881e..21f555099a 100644 --- a/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S +++ b/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S @@ -466,7 +466,7 @@ MPU_xStreamBufferNextMessageLengthBytes: /* ----------------------------------------------------------------------------------- */ -#if INCLUDE_xTaskDelayUntil == 1 +#if ( INCLUDE_xTaskDelayUntil == 1 ) || ( INCLUDE_vTaskDelayUntil == 1 ) .extern MPU_xTaskDelayUntilImpl /** * Function: TaskHandle_t MPU_xTaskDelayUntil @@ -483,7 +483,7 @@ MPU_xStreamBufferNextMessageLengthBytes: /* ------------------------------------------------------------------------------- */ -#endif /* if ( INCLUDE_xTaskDelayUntil == 1 ) */ +#endif /* if ( INCLUDE_xTaskDelayUntil == 1 ) || ( INCLUDE_vTaskDelayUntil == 1 ) */ #if INCLUDE_xTaskAbortDelay == 1 @@ -1025,7 +1025,7 @@ MPU_xStreamBufferNextMessageLengthBytes: #endif /* if ( configUSE_QUEUE_SETS == 1 ) */ -#if configQUEUE_REGISTRY_SIZE == 1 +#if configQUEUE_REGISTRY_SIZE > 0 /* ------------------------------------------------------------------------------- */ From 5f5ed08f82431bf1b77076708001c91467d1c0d8 Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Wed, 14 Feb 2024 08:49:40 -0500 Subject: [PATCH 45/51] Slight formatting change to mpu_wrappers files --- .../GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S | 2 +- .../GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.h | 131 +++++++++--------- 2 files changed, 66 insertions(+), 67 deletions(-) diff --git a/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S b/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S index 21f555099a..6819bb2531 100644 --- a/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S +++ b/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S @@ -69,7 +69,7 @@ vPortSystemCallExit: * Inputs: VOID */ .align 4 -.weak xPortIsPrivileged +.global xPortIsPrivileged .type xPortIsPrivileged, %function xPortIsPrivileged: /* Load value of CPSR into R0 */ diff --git a/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.h b/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.h index 1af004ce7b..659bde0ba2 100644 --- a/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.h +++ b/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.h @@ -86,34 +86,34 @@ typedef struct xEventGroupWaitBitsParams TickType_t xTicksToWait; } xEventGroupWaitBitsParams_t; -/*-----------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ extern TickType_t MPU_xTaskGetTickCount( void ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -/*-----------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -/*-----------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -/*-----------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -/*-----------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -/*-----------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, @@ -122,24 +122,24 @@ BaseType_t MPU_xQueueGenericSend( const BaseType_t xCopyPosition ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -/*-----------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -/*-----------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -/*-----------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -/*-----------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, @@ -147,12 +147,12 @@ BaseType_t MPU_xQueuePeek( TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -/*-----------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -/*-----------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, @@ -161,7 +161,7 @@ size_t MPU_xStreamBufferSend( TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -/*-----------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, @@ -170,39 +170,39 @@ size_t MPU_xStreamBufferReceive( TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -/*-----------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -/*-----------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -/*-----------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -/*-----------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -/*-----------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -/*-----------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -/*-----------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, @@ -211,21 +211,21 @@ EventBits_t MPU_xEventGroupWaitBits( const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -/*-----------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -/*-----------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -/*-----------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, @@ -234,7 +234,7 @@ EventBits_t MPU_xEventGroupSync( TickType_t xTicksToWait ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -/*-----------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ #if( INCLUDE_xTaskDelayUntil == 1 ) @@ -243,48 +243,48 @@ BaseType_t MPU_xTaskDelayUntil( const TickType_t xTimeIncrement ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -#endif /* if ( INCLUDE_xTaskDelayUntil == 1 ) */ -/*-----------------------------------------------------------*/ +#endif /* ( INCLUDE_xTaskDelayUntil == 1 ) */ +/* ----------------------------------------------------------------------------------- */ #if( INCLUDE_xTaskAbortDelay == 1 ) BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -#endif /* if ( INCLUDE_xTaskAbortDelay == 1 ) */ -/*-----------------------------------------------------------*/ +#endif /* ( INCLUDE_xTaskAbortDelay == 1 ) */ +/* ----------------------------------------------------------------------------------- */ #if( INCLUDE_vTaskDelay == 1 ) void MPU_vTaskDelay( const TickType_t xTicksToDelay ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -#endif /* if ( INCLUDE_vTaskDelay == 1 ) */ -/*-----------------------------------------------------------*/ +#endif /* ( INCLUDE_vTaskDelay == 1 ) */ +/* ----------------------------------------------------------------------------------- */ #if( INCLUDE_uxTaskPriorityGet == 1 ) UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -#endif /* if ( INCLUDE_uxTaskPriorityGet == 1 ) */ -/*-----------------------------------------------------------*/ +#endif /* ( INCLUDE_uxTaskPriorityGet == 1 ) */ +/* ----------------------------------------------------------------------------------- */ #if( INCLUDE_eTaskGetState == 1 ) eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -#endif /* if ( INCLUDE_eTaskGetState == 1 ) */ -/*-----------------------------------------------------------*/ +#endif /* ( INCLUDE_eTaskGetState == 1 ) */ +/* ----------------------------------------------------------------------------------- */ #if( INCLUDE_xTaskGetIdleTaskHandle == 1 ) TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -#endif /* if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */ -/*-----------------------------------------------------------*/ +#endif /* ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */ +/* ----------------------------------------------------------------------------------- */ #if( INCLUDE_vTaskSuspend == 1 ) @@ -294,8 +294,8 @@ void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) void MPU_vTaskResume( TaskHandle_t xTaskToResume ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -#endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ -/*-----------------------------------------------------------*/ +#endif /* ( INCLUDE_vTaskSuspend == 1 ) */ +/* ----------------------------------------------------------------------------------- */ #if( configGENERATE_RUN_TIME_STATS == 1 ) configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) @@ -309,10 +309,10 @@ configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - #endif /* ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */ + #endif /* ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */ -#endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ -/*-----------------------------------------------------------*/ +#endif /* ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ +/* ----------------------------------------------------------------------------------- */ #if( configUSE_APPLICATION_TASK_TAG == 1 ) @@ -322,8 +322,8 @@ void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHo TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -#endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ -/*-----------------------------------------------------------*/ +#endif /* ( configUSE_APPLICATION_TASK_TAG == 1 ) */ +/* ----------------------------------------------------------------------------------- */ #if( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) @@ -338,41 +338,40 @@ void * MPU_pvTaskGetThreadLocalStoragePointer( BaseType_t xIndex ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -#endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ -/*-----------------------------------------------------------*/ +#endif /* ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ +/* ----------------------------------------------------------------------------------- */ #if( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) */ -/*-----------------------------------------------------------*/ +#endif /* ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) */ +/* ----------------------------------------------------------------------------------- */ #if( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -#endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) */ -/*-----------------------------------------------------------*/ +#endif /* ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) */ +/* ----------------------------------------------------------------------------------- */ #if( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -#endif /* if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) \ - ) */ -/*-----------------------------------------------------------*/ +#endif /* ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ +/* ----------------------------------------------------------------------------------- */ #if( INCLUDE_xTaskGetSchedulerState == 1 ) BaseType_t MPU_xTaskGetSchedulerState( void ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -#endif /* if ( INCLUDE_xTaskGetSchedulerState == 1 ) */ -/*-----------------------------------------------------------*/ +#endif /* ( INCLUDE_xTaskGetSchedulerState == 1 ) */ +/* ----------------------------------------------------------------------------------- */ #if( configUSE_TRACE_FACILITY == 1 ) @@ -395,8 +394,8 @@ UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) void MPU_vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -#endif /*( configUSE_TRACE_FACILITY == 1 )*/ -/*-----------------------------------------------------------*/ +#endif /* ( configUSE_TRACE_FACILITY == 1 ) */ +/* ----------------------------------------------------------------------------------- */ #if( configUSE_TASK_NOTIFICATIONS == 1 ) @@ -423,8 +422,8 @@ uint32_t MPU_ulTaskGenericNotifyValueClear( uint32_t ulBitsToClear ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -#endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ -/*-----------------------------------------------------------*/ +#endif /* ( configUSE_TASK_NOTIFICATIONS == 1 ) */ +/* ----------------------------------------------------------------------------------- */ #if( configUSE_RECURSIVE_MUTEXES == 1 ) @@ -441,8 +440,8 @@ TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) #endif /* ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) */ -#endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ -/*-----------------------------------------------------------*/ +#endif /* ( configUSE_RECURSIVE_MUTEXES == 1 ) */ +/* ----------------------------------------------------------------------------------- */ #if( configUSE_QUEUE_SETS == 1 ) @@ -456,8 +455,8 @@ BaseType_t MPU_xQueueAddToSet( QueueSetHandle_t xQueueSet ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -#endif /* if ( configUSE_QUEUE_SETS == 1 ) */ -/*-----------------------------------------------------------*/ +#endif /* ( configUSE_QUEUE_SETS == 1 ) */ +/* ----------------------------------------------------------------------------------- */ #if( configQUEUE_REGISTRY_SIZE > 0 ) @@ -470,8 +469,8 @@ void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -#endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ -/*-----------------------------------------------------------*/ +#endif /* ( configQUEUE_REGISTRY_SIZE > 0 ) */ +/* ----------------------------------------------------------------------------------- */ #if( configUSE_TIMERS == 1 ) @@ -508,7 +507,7 @@ TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -#endif /* if ( configUSE_TIMERS == 1 ) */ -/*-----------------------------------------------------------*/ +#endif /* ( configUSE_TIMERS == 1 ) */ +/* ----------------------------------------------------------------------------------- */ #endif /* MPU_PROTOTYPES_H */ From 370498fe93c508ec67f5e10d82e5e461045be7b6 Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Wed, 14 Feb 2024 09:08:23 -0500 Subject: [PATCH 46/51] Slight changes to formatting --- portable/GCC/ARM_CRx_MPU/.clang-format | 5 +- .../GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.h | 196 ++++++++---------- portable/GCC/ARM_CRx_MPU/port.c | 148 ++++++------- portable/GCC/ARM_CRx_MPU/portmacro.h | 15 +- 4 files changed, 163 insertions(+), 201 deletions(-) diff --git a/portable/GCC/ARM_CRx_MPU/.clang-format b/portable/GCC/ARM_CRx_MPU/.clang-format index 0ce7b55f18..c745d9c66f 100644 --- a/portable/GCC/ARM_CRx_MPU/.clang-format +++ b/portable/GCC/ARM_CRx_MPU/.clang-format @@ -1,6 +1,6 @@ --- Language: Cpp -AlignAfterOpenBracket: BlockIndent +AlignAfterOpenBracket: Align AlignConsecutiveAssignments: None AlignConsecutiveBitFields: AcrossEmptyLinesAndComments AlignConsecutiveDeclarations: None @@ -41,7 +41,7 @@ BraceWrapping: SplitEmptyFunction: true SplitEmptyRecord: true SplitEmptyNamespace: true -BreakBeforeBinaryOperators: None +BreakBeforeBinaryOperators: NonAssignment BreakBeforeBraces: Custom BreakBeforeConceptDeclarations: true BreakBeforeTernaryOperators: true @@ -62,6 +62,7 @@ IndentExternBlock: NoIndent IndentGotoLabels: true IndentPPDirectives: BeforeHash IndentWidth: 4 +IndentWrappedFunctionNames: true KeepEmptyLinesAtTheStartOfBlocks: false MaxEmptyLinesToKeep: 1 NamespaceIndentation: None diff --git a/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.h b/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.h index 659bde0ba2..17fec8f6c8 100644 --- a/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.h +++ b/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.h @@ -108,19 +108,17 @@ void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) /* ----------------------------------------------------------------------------------- */ -BaseType_t MPU_xTaskCheckForTimeOut( - TimeOut_t * const pxTimeOut, - TickType_t * const pxTicksToWait -) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; /* ----------------------------------------------------------------------------------- */ -BaseType_t MPU_xQueueGenericSend( - QueueHandle_t xQueue, - const void * const pvItemToQueue, - TickType_t xTicksToWait, - const BaseType_t xCopyPosition -) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; /* ----------------------------------------------------------------------------------- */ @@ -134,18 +132,16 @@ UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) /* ----------------------------------------------------------------------------------- */ -BaseType_t MPU_xQueueReceive( - QueueHandle_t xQueue, - void * const pvBuffer, - TickType_t xTicksToWait -) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; /* ----------------------------------------------------------------------------------- */ -BaseType_t MPU_xQueuePeek( - QueueHandle_t xQueue, - void * const pvBuffer, - TickType_t xTicksToWait -) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, + void * const pvBuffer, + TickType_t xTicksToWait ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; /* ----------------------------------------------------------------------------------- */ @@ -154,21 +150,19 @@ BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWai /* ----------------------------------------------------------------------------------- */ -size_t MPU_xStreamBufferSend( - StreamBufferHandle_t xStreamBuffer, - const void * pvTxData, - size_t xDataLengthBytes, - TickType_t xTicksToWait -) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; /* ----------------------------------------------------------------------------------- */ -size_t MPU_xStreamBufferReceive( - StreamBufferHandle_t xStreamBuffer, - void * pvRxData, - size_t xBufferLengthBytes, - TickType_t xTicksToWait -) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void * pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; /* ----------------------------------------------------------------------------------- */ @@ -192,10 +186,9 @@ size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* ----------------------------------------------------------------------------------- */ -BaseType_t MPU_xStreamBufferSetTriggerLevel( - StreamBufferHandle_t xStreamBuffer, - size_t xTriggerLevel -) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; /* ----------------------------------------------------------------------------------- */ @@ -204,44 +197,39 @@ size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuff /* ----------------------------------------------------------------------------------- */ -EventBits_t MPU_xEventGroupWaitBits( - EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToWaitFor, - const BaseType_t xClearOnExit, - const BaseType_t xWaitForAllBits, - TickType_t xTicksToWait -) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, + const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; /* ----------------------------------------------------------------------------------- */ -EventBits_t MPU_xEventGroupClearBits( - EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToClear -) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; /* ----------------------------------------------------------------------------------- */ -EventBits_t MPU_xEventGroupSetBits( - EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet -) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; /* ----------------------------------------------------------------------------------- */ -EventBits_t MPU_xEventGroupSync( - EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet, - const EventBits_t uxBitsToWaitFor, - TickType_t xTicksToWait -) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, + TickType_t xTicksToWait ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; /* ----------------------------------------------------------------------------------- */ #if( INCLUDE_xTaskDelayUntil == 1 ) -BaseType_t MPU_xTaskDelayUntil( - TickType_t * const pxPreviousWakeTime, - const TickType_t xTimeIncrement -) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, + const TickType_t xTimeIncrement ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; #endif /* ( INCLUDE_xTaskDelayUntil == 1 ) */ /* ----------------------------------------------------------------------------------- */ @@ -316,7 +304,8 @@ configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) #if( configUSE_APPLICATION_TASK_TAG == 1 ) -void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ) +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) @@ -327,16 +316,14 @@ TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) #if( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) -void MPU_vTaskSetThreadLocalStoragePointer( - TaskHandle_t xTaskToSet, - BaseType_t xIndex, - void * pvValue -) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, + BaseType_t xIndex, + void * pvValue ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -void * MPU_pvTaskGetThreadLocalStoragePointer( - TaskHandle_t xTaskToQuery, - BaseType_t xIndex -) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, + BaseType_t xIndex ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; #endif /* ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ /* ----------------------------------------------------------------------------------- */ @@ -362,7 +349,8 @@ configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -#endif /* ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ +#endif /* ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) \ + */ /* ----------------------------------------------------------------------------------- */ #if( INCLUDE_xTaskGetSchedulerState == 1 ) @@ -375,18 +363,16 @@ BaseType_t MPU_xTaskGetSchedulerState( void ) #if( configUSE_TRACE_FACILITY == 1 ) -void MPU_vTaskGetInfo( - TaskHandle_t xTask, - TaskStatus_t * pxTaskStatus, - BaseType_t xGetFreeStackSpace, - eTaskState eState -) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskGetInfo( TaskHandle_t xTask, + TaskStatus_t * pxTaskStatus, + BaseType_t xGetFreeStackSpace, + eTaskState eState ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -UBaseType_t MPU_uxTaskGetSystemState( - TaskStatus_t * const pxTaskStatusArray, - const UBaseType_t uxArraySize, - configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime -) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, + const UBaseType_t uxArraySize, + configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; @@ -402,25 +388,23 @@ void MPU_vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumbe BaseType_t MPU_xTaskGenericNotifyEntry( const xTaskGenericNotifyParams_t * pxParams ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -BaseType_t MPU_xTaskGenericNotifyWaitEntry( const xTaskGenericNotifyWaitParams_t * pxParams -) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskGenericNotifyWaitEntry( + const xTaskGenericNotifyWaitParams_t * pxParams ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -uint32_t MPU_ulTaskGenericNotifyTake( - UBaseType_t uxIndexToWaitOn, - BaseType_t xClearCountOnExit, - TickType_t xTicksToWait -) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, + BaseType_t xClearCountOnExit, + TickType_t xTicksToWait ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -BaseType_t MPU_xTaskGenericNotifyStateClear( - TaskHandle_t xTask, - UBaseType_t uxIndexToClear -) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -uint32_t MPU_ulTaskGenericNotifyValueClear( - TaskHandle_t xTask, - UBaseType_t uxIndexToClear, - uint32_t ulBitsToClear -) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, + UBaseType_t uxIndexToClear, + uint32_t ulBitsToClear ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; #endif /* ( configUSE_TASK_NOTIFICATIONS == 1 ) */ /* ----------------------------------------------------------------------------------- */ @@ -445,15 +429,13 @@ TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) #if( configUSE_QUEUE_SETS == 1 ) -QueueSetMemberHandle_t MPU_xQueueSelectFromSet( - QueueSetHandle_t xQueueSet, - const TickType_t xTicksToWait -) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -BaseType_t MPU_xQueueAddToSet( - QueueSetMemberHandle_t xQueueOrSemaphore, - QueueSetHandle_t xQueueSet -) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet ) + __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; #endif /* ( configUSE_QUEUE_SETS == 1 ) */ /* ----------------------------------------------------------------------------------- */ diff --git a/portable/GCC/ARM_CRx_MPU/port.c b/portable/GCC/ARM_CRx_MPU/port.c index d3b75a4d38..fab89eb46d 100644 --- a/portable/GCC/ARM_CRx_MPU/port.c +++ b/portable/GCC/ARM_CRx_MPU/port.c @@ -91,8 +91,7 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( const xMPU_REGION_REGISTERS * xTaskMPURegion, const uint32_t ulRegionStart, const uint32_t ulRegionLength, - const uint32_t ulAccessRequested -); + const uint32_t ulAccessRequested ); /** * @brief Determine smallest MPU Region Setting for a number of bytes. @@ -103,8 +102,7 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( * @return uint32_t The smallest MPU region size that can hold the requested bytes. */ PRIVILEGED_FUNCTION static uint32_t prvGetMPURegionSizeSetting( - uint32_t ulActualSizeInBytes -); + uint32_t ulActualSizeInBytes ); /** @brief Set up a default MPU memory Map * @return PRIVILEGED_FUNCTION VOID @@ -132,8 +130,7 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( const xMPU_REGION_REGISTERS * xTaskMPURegion, const uint32_t ulRegionStart, const uint32_t ulRegionLength, - const uint32_t ulAccessRequested -); + const uint32_t ulAccessRequested ); /* ----------------------------------------------------------------------------------- */ @@ -155,8 +152,7 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( TaskFunction_t pxCode, void * pvParameters, BaseType_t xRunPrivileged, - xMPU_SETTINGS * xMPUSettings -) + xMPU_SETTINGS * xMPUSettings ) { /** Setup the initial context of the task. The context is set exactly as * expected by the portRESTORE_CONTEXT() macro and as described above the @@ -308,11 +304,11 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( /* Ensure that the system call stack is double word aligned. */ xSysCallInfo = &( xMPUSettings->xSystemCallStackInfo ); xSysCallInfo->pulSystemCallStackPointer = &( - xSysCallInfo->ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE - 1U ] - ); + xSysCallInfo->ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE - 1U ] ); xSysCallInfo->pulSystemCallStackPointer = - ( uint32_t * ) ( ( uint32_t ) ( xSysCallInfo->pulSystemCallStackPointer ) & ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + ( uint32_t * ) ( ( uint32_t ) ( xSysCallInfo->pulSystemCallStackPointer ) + & ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); /* This is not NULL only for the duration of a system call. */ xSysCallInfo->pulTaskStackPointer = NULL; @@ -344,8 +340,7 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( xMPU_SETTINGS * xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t * pxBottomOfStack, - uint32_t ulStackDepth -) + uint32_t ulStackDepth ) { #if defined( __ARMCC_VERSION ) @@ -366,8 +361,8 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( uint32_t ulAlignment; /* Allow Read/Write from User and Privileged modes */ - uint32_t ulRegionAttr = portMPU_PRIV_RW_USER_RW_NOEXEC | - portMPU_NORMAL_OIWTNOWA_SHARED; + uint32_t ulRegionAttr = portMPU_PRIV_RW_USER_RW_NOEXEC + | portMPU_NORMAL_OIWTNOWA_SHARED; if( NULL == xRegions ) { @@ -429,8 +424,8 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( { /* Define the region that allows access to the stack. */ ulRegionStart = ( uint32_t ) pxBottomOfStack; - ulRegionAttr = portMPU_PRIV_RW_USER_RW_NOEXEC | - portMPU_NORMAL_OIWTNOWA_SHARED; + ulRegionAttr = portMPU_PRIV_RW_USER_RW_NOEXEC + | portMPU_NORMAL_OIWTNOWA_SHARED; ulRegionLen = prvGetMPURegionSizeSetting( ulStackDepth << 2UL ); ulRegionLen |= portMPU_REGION_ENABLE; @@ -468,8 +463,8 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( /* Calling task's MPU settings. */ const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); - if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == - portTASK_IS_PRIVILEGED_FLAG ) + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) + == portTASK_IS_PRIVILEGED_FLAG ) { xTaskIsPrivileged = pdTRUE; } @@ -514,8 +509,7 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( /* ----------------------------------------------------------------------------------- */ /* PRIVILEGED_FUNCTION */ static uint32_t prvGetMPURegionSizeSetting( - uint32_t ulActualSizeInBytes -) + uint32_t ulActualSizeInBytes ) { uint32_t ulRegionSize, ulReturnValue = 4U; @@ -584,12 +578,10 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( ulRegionLength = prvGetMPURegionSizeSetting( ulRegionLength ); ulRegionLength |= portMPU_REGION_ENABLE; - vMPUSetRegion( - portUNPRIVILEGED_FLASH_REGION, - ulRegionStart, - ulRegionLength, - portMPU_PRIV_RO_USER_RO_EXEC | portMPU_NORMAL_OIWTNOWA_SHARED - ); + vMPUSetRegion( portUNPRIVILEGED_FLASH_REGION, + ulRegionStart, + ulRegionLength, + portMPU_PRIV_RO_USER_RO_EXEC | portMPU_NORMAL_OIWTNOWA_SHARED ); /* Privileged Read and Exec MPU Region for PRIVILEGED_FUNCTIONS. */ ulRegionStart = ( uint32_t ) __privileged_functions_start__; @@ -598,12 +590,10 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( ulRegionLength = prvGetMPURegionSizeSetting( ulRegionLength ); ulRegionLength |= portMPU_REGION_ENABLE; - vMPUSetRegion( - portPRIVILEGED_FLASH_REGION, - ulRegionStart, - ulRegionLength, - portMPU_PRIV_RO_USER_NA_EXEC | portMPU_NORMAL_OIWTNOWA_SHARED - ); + vMPUSetRegion( portPRIVILEGED_FLASH_REGION, + ulRegionStart, + ulRegionLength, + portMPU_PRIV_RO_USER_NA_EXEC | portMPU_NORMAL_OIWTNOWA_SHARED ); /* Privileged Write and Read Access for PRIVILEGED_DATA. */ ulRegionStart = ( uint32_t ) __privileged_data_start__; @@ -612,12 +602,10 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( ulRegionLength = prvGetMPURegionSizeSetting( ulRegionLength ); ulRegionLength |= portMPU_REGION_ENABLE; - vMPUSetRegion( - portPRIVILEGED_RAM_REGION, - ulRegionStart, - ulRegionLength, - portMPU_PRIV_RW_USER_NA_NOEXEC | portMPU_NORMAL_OIWTNOWA_SHARED - ); + vMPUSetRegion( portPRIVILEGED_RAM_REGION, + ulRegionStart, + ulRegionLength, + portMPU_PRIV_RW_USER_NA_NOEXEC | portMPU_NORMAL_OIWTNOWA_SHARED ); /* Enable the MPU Background region, allows privileged operating modes access to * unmapped regions of memory without generating a fault. */ @@ -633,8 +621,7 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( const xMPU_REGION_REGISTERS * xTaskMPURegion, const uint32_t ulRegionStart, const uint32_t ulRegionLength, - const uint32_t ulAccessRequested -) + const uint32_t ulAccessRequested ) { BaseType_t xAccessGranted; uint32_t ulRegionEnd = ulRegionStart + ulRegionLength; @@ -647,20 +634,20 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( * 1. Ensure region being accessed is after the start of an MPU Region * 2. Ensure region being accessed is before the end of the MPU Region * 3. Ensure region being accessed ends after the start of the MPU region */ - if( ( ulRegionStart >= xTaskMPURegion->ulRegionBaseAddress ) && - ( ulRegionEnd <= ulTaskRegionEnd ) && ( ulRegionEnd >= ulRegionStart ) ) + if( ( ulRegionStart >= xTaskMPURegion->ulRegionBaseAddress ) + && ( ulRegionEnd <= ulTaskRegionEnd ) && ( ulRegionEnd >= ulRegionStart ) ) { /* Unprivileged read is MPU Ctrl Access Bit Value bX1X */ - if( ( tskMPU_READ_PERMISSION == ulAccessRequested ) && - ( ( portMPU_PRIV_RW_USER_RO_NOEXEC ) &xTaskMPURegion->ulRegionAttribute ) ) + if( ( tskMPU_READ_PERMISSION == ulAccessRequested ) + && ( ( portMPU_PRIV_RW_USER_RO_NOEXEC ) &xTaskMPURegion->ulRegionAttribute ) ) { xAccessGranted = pdTRUE; } /* Unprivileged Write is MPU Ctrl Access Bit Value b011 */ - else if( ( tskMPU_WRITE_PERMISSION & ulAccessRequested ) && - ( portMPU_PRIV_RW_USER_RW_NOEXEC == - ( portMPU_PRIV_RW_USER_RW_NOEXEC & xTaskMPURegion->ulRegionAttribute ) ) ) + else if( ( tskMPU_WRITE_PERMISSION & ulAccessRequested ) + && ( xTaskMPURegion->ulRegionAttribute & portMPU_PRIV_RW_USER_RW_NOEXEC ) + == ( portMPU_PRIV_RW_USER_RW_NOEXEC ) ) { xAccessGranted = pdTRUE; } @@ -683,8 +670,7 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( /* PRIVILEGED_FUNCTION */ BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, uint32_t ulBufferLength, - uint32_t ulAccessRequested -) + uint32_t ulAccessRequested ) { BaseType_t xAccessGranted; @@ -714,14 +700,12 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( do { xTaskMPURegion = &( xTaskMPUSettings->xRegion[ ulRegionIndex++ ] ); - xAccessGranted = prvTaskCanAccessRegion( - xTaskMPURegion, - ( uint32_t ) pvBuffer, - ulBufferLength, - ulAccessRequested - ); - } while( ( pdFALSE == xAccessGranted ) && - ( ulRegionIndex < portTOTAL_NUM_REGIONS_IN_TCB ) ); + xAccessGranted = prvTaskCanAccessRegion( xTaskMPURegion, + ( uint32_t ) pvBuffer, + ulBufferLength, + ulAccessRequested ); + } while( ( ulRegionIndex < portTOTAL_NUM_REGIONS_IN_TCB ) + && ( pdFALSE == xAccessGranted ) ); } } return xAccessGranted; @@ -732,8 +716,7 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( #if( configENABLE_ACCESS_CONTROL_LIST == 1 ) /* PRIVILEGED_FUNCTION */ BaseType_t xPortIsAuthorizedToAccessKernelObject( - int32_t lInternalIndexOfKernelObject -) + int32_t lInternalIndexOfKernelObject ) { uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; BaseType_t xAccessGranted = pdFALSE; @@ -752,20 +735,21 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( /* Calling task's MPU settings. */ xTaskMpuSettings = xTaskGetMPUSettings( NULL ); - ulAccessControlListEntryIndex = - ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); - ulAccessControlListEntryBit = - ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + 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 ) + if( portTASK_IS_PRIVILEGED_FLAG + == ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) ) { xAccessGranted = pdTRUE; } else { - if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & - ( 1U << ulAccessControlListEntryBit ) ) != 0 ) + if( ( 1U << ulAccessControlListEntryBit ) + & ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] ) + != 0UL ) { xAccessGranted = pdTRUE; } @@ -777,16 +761,15 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( /* PRIVILEGED_FUNCTION */ void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle, - int32_t lInternalIndexOfKernelObject -) + int32_t lInternalIndexOfKernelObject ) { uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; xMPU_SETTINGS * xTaskMpuSettings; - ulAccessControlListEntryIndex = - ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); - ulAccessControlListEntryBit = - ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject + / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject + % portACL_ENTRY_SIZE_BITS ); xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); @@ -796,29 +779,26 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( /* PRIVILEGED_FUNCTION */ void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle, - int32_t lInternalIndexOfKernelObject -) + int32_t lInternalIndexOfKernelObject ) { uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; xMPU_SETTINGS * xTaskMpuSettings; - ulAccessControlListEntryIndex = - ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); - ulAccessControlListEntryBit = - ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject + / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject + % portACL_ENTRY_SIZE_BITS ); xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( - 1U << ulAccessControlListEntryBit - ); + 1U << ulAccessControlListEntryBit ); } #else /* PRIVILEGED_FUNCTION */ BaseType_t xPortIsAuthorizedToAccessKernelObject( - int32_t lInternalIndexOfKernelObject -) + int32_t lInternalIndexOfKernelObject ) { ( void ) lInternalIndexOfKernelObject; diff --git a/portable/GCC/ARM_CRx_MPU/portmacro.h b/portable/GCC/ARM_CRx_MPU/portmacro.h index 59376d4bef..e3e863d8a9 100644 --- a/portable/GCC/ARM_CRx_MPU/portmacro.h +++ b/portable/GCC/ARM_CRx_MPU/portmacro.h @@ -420,12 +420,10 @@ void vMPUDisableBackgroundRegion( void ); * provided values to the relevant MPU Registers. The inputs to this function * are checked internally before it is called in the port.c file. */ -void vMPUSetRegion( - uint32_t ulRegionNumber, - uint32_t ulBaseAddress, - uint32_t ulRegionSize, - uint32_t ulRegionPermissions -); +void vMPUSetRegion( uint32_t ulRegionNumber, + uint32_t ulBaseAddress, + uint32_t ulRegionSize, + uint32_t ulRegionPermissions ); /* ------------------------------- Port.c Declarations ------------------------------- */ @@ -682,8 +680,9 @@ typedef struct MPU_SETTINGS xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; #if( configENABLE_ACCESS_CONTROL_LIST == 1 ) - uint32_t ulAccessControlList - [ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1UL ]; + uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE + / portACL_ENTRY_SIZE_BITS ) + + 1UL ]; #endif } xMPU_SETTINGS; From 153af86d70a9013662eb20498110da264c437519 Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Mon, 19 Feb 2024 11:56:05 -0500 Subject: [PATCH 47/51] Fix an incorrect operating mode word in the portASM.S file, slight formatting tweak, use checkout@v4 to account for new warnings --- .github/workflows/ci.yml | 2 +- .github/workflows/formatting.yml | 2 +- portable/GCC/ARM_CRx_MPU/portASM.S | 7 +++---- portable/GCC/ARM_CRx_MPU/portmacro.h | 11 +++-------- 4 files changed, 8 insertions(+), 14 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5d5b659187..665f85ea5d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,7 +18,7 @@ jobs: port-formatting: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Check Formatting of FreeRTOS-Kernel Files uses: FreeRTOS/CI-CD-Github-Actions/clang-formatting@main with: diff --git a/.github/workflows/formatting.yml b/.github/workflows/formatting.yml index 14d41c9c0c..2f369105aa 100644 --- a/.github/workflows/formatting.yml +++ b/.github/workflows/formatting.yml @@ -19,7 +19,7 @@ jobs: runs-on: ubuntu-20.04 steps: - name: Apply Formatting Fix - id: check-formatting + id: check-formatting uses: FreeRTOS/CI-CD-Github-Actions/formatting-bot@main with: exclude-dirs: portable diff --git a/portable/GCC/ARM_CRx_MPU/portASM.S b/portable/GCC/ARM_CRx_MPU/portASM.S index d2e1f3bfd1..5ebc8b2b0f 100644 --- a/portable/GCC/ARM_CRx_MPU/portASM.S +++ b/portable/GCC/ARM_CRx_MPU/portASM.S @@ -182,7 +182,7 @@ .global vPortStartFirstTask .type vPortStartFirstTask, %function vPortStartFirstTask: - /** This function is called from Supervisor Mode to start the FreeRTOS-Kernel. + /** This function is called from System Mode to start the FreeRTOS-Kernel. * This is done by restoring the context of the first task. * Restoring the context of a task will allow interrupts. * This allows the FreeRTOS Scheduler Tick to start, and therefore @@ -194,9 +194,8 @@ vPortStartFirstTask: portRESTORE_CONTEXT /* ----------------------------------------------------------------------------------- */ -/* Handler for Supervisor Calls (SVCs) when using this FreeRTOS Port */ - -/* Upon entering here the LR, or R14, will hold the address of the following +/* Handler for Supervisor Calls (SVCs) when using this FreeRTOS Port + * Upon entering here the LR, or R14, will hold the address of the following * instruction. This then checks that instruction for the SVC # raised. * Checks: * 1. SVC is raised from the system call section (i.e. application is diff --git a/portable/GCC/ARM_CRx_MPU/portmacro.h b/portable/GCC/ARM_CRx_MPU/portmacro.h index e3e863d8a9..7ef2119046 100644 --- a/portable/GCC/ARM_CRx_MPU/portmacro.h +++ b/portable/GCC/ARM_CRx_MPU/portmacro.h @@ -36,11 +36,6 @@ * hardware and compiler. These settings should not be altered. */ -/** - * @brief APIs and Variables used to control the onboard MPU. - * @defgroup MPU Control - */ - #ifdef __cplusplus extern "C" { #endif @@ -81,7 +76,7 @@ extern "C" { "to use when an unprivileged task makes a FreeRTOS Kernel call. " #endif /* configSYSTEM_CALL_STACK_SIZE */ -/* ------------------------------ FreeRTOS Config Check ------------------------------ */ +/* ----------------------------------------------------------------------------------- */ #if( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 ) /* Check the configuration. */ @@ -465,8 +460,8 @@ BaseType_t xPortIsPrivileged( void ); * or not, this function can return a different value than xPortIsPrivileged. * * @return - * 0 If pxCurrentTCB's !( ulTaskFlags && portTASK_IS_PRIVILEGED_FLAG ) - * 1 If pxCurrentTCB's ( ulTaskFlags && portTASK_IS_PRIVILEGED_FLAG ) + * 0 If pxCurrentTCB's !( ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) + * 1 If pxCurrentTCB's ( ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) */ BaseType_t xPortIsTaskPrivileged( void ); From c195770fe8dcb6824d3b366d51bd38b71bb7ed3e Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Fri, 23 Feb 2024 07:03:37 -0500 Subject: [PATCH 48/51] Apply git review ptach created by @aggarg --- portable/GCC/ARM_CRx_MPU/.clang-format | 104 --- .../GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S | 793 ++++------------ .../GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.h | 495 ---------- portable/GCC/ARM_CRx_MPU/port.c | 866 +++++++++--------- portable/GCC/ARM_CRx_MPU/portASM.S | 655 ++++++------- portable/GCC/ARM_CRx_MPU/portmacro.h | 446 +++------ portable/GCC/ARM_CRx_MPU/portmacro_asm.h | 484 ++++------ 7 files changed, 1152 insertions(+), 2691 deletions(-) delete mode 100644 portable/GCC/ARM_CRx_MPU/.clang-format delete mode 100644 portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.h diff --git a/portable/GCC/ARM_CRx_MPU/.clang-format b/portable/GCC/ARM_CRx_MPU/.clang-format deleted file mode 100644 index c745d9c66f..0000000000 --- a/portable/GCC/ARM_CRx_MPU/.clang-format +++ /dev/null @@ -1,104 +0,0 @@ ---- -Language: Cpp -AlignAfterOpenBracket: Align -AlignConsecutiveAssignments: None -AlignConsecutiveBitFields: AcrossEmptyLinesAndComments -AlignConsecutiveDeclarations: None -AlignConsecutiveMacros: AcrossEmptyLinesAndComments -AlignEscapedNewlines: Left -AlignOperands: AlignAfterOperator -AlignTrailingComments: true -AllowAllArgumentsOnNextLine: false -AllowAllParametersOfDeclarationOnNextLine: false -AllowShortBlocksOnASingleLine: Never -AllowShortCaseLabelsOnASingleLine: false -AllowShortEnumsOnASingleLine: false -AllowShortFunctionsOnASingleLine: None -AllowShortIfStatementsOnASingleLine: false -AllowShortLambdasOnASingleLine: All -AllowShortLoopsOnASingleLine: false -AlwaysBreakAfterReturnType: None -AlwaysBreakBeforeMultilineStrings: false -AlwaysBreakTemplateDeclarations: Yes -BinPackArguments: false -BinPackParameters: false -BitFieldColonSpacing: Both -BraceWrapping: - AfterCaseLabel: true - AfterClass: true - AfterControlStatement: Always - AfterEnum: true - AfterExternBlock: false - AfterFunction: true - AfterNamespace: true - AfterStruct: true - AfterUnion: true - BeforeCatch: true - BeforeElse: true - BeforeLambdaBody: false - BeforeWhile: false - IndentBraces: false - SplitEmptyFunction: true - SplitEmptyRecord: true - SplitEmptyNamespace: true -BreakBeforeBinaryOperators: NonAssignment -BreakBeforeBraces: Custom -BreakBeforeConceptDeclarations: true -BreakBeforeTernaryOperators: true -BreakConstructorInitializers: BeforeColon -BreakInheritanceList: BeforeColon -BreakStringLiterals: true -ColumnLimit: 90 -CompactNamespaces: false -ContinuationIndentWidth: 4 -Cpp11BracedListStyle: false -DerivePointerAlignment: false -EmptyLineBeforeAccessModifier: Always -FixNamespaceComments: true -IncludeBlocks: Preserve -IndentCaseBlocks: false -IndentCaseLabels: true -IndentExternBlock: NoIndent -IndentGotoLabels: true -IndentPPDirectives: BeforeHash -IndentWidth: 4 -IndentWrappedFunctionNames: true -KeepEmptyLinesAtTheStartOfBlocks: false -MaxEmptyLinesToKeep: 1 -NamespaceIndentation: None -PenaltyBreakAssignment: 1000 -PenaltyBreakBeforeFirstCallParameter: 200 -PenaltyBreakComment: 50 -PenaltyBreakFirstLessLess: 120 -PenaltyBreakString: 100 -PenaltyBreakTemplateDeclaration: 10 -PenaltyExcessCharacter: 100 -PenaltyIndentedWhitespace: 0 -PenaltyReturnTypeOnItsOwnLine: 10000 -PointerAlignment: Middle -ReflowComments: true -SortIncludes: false -SortUsingDeclarations: true -SpaceAfterCStyleCast: true -SpaceAfterLogicalNot: false -SpaceAfterTemplateKeyword: false -SpaceBeforeCpp11BracedList: true -SpaceBeforeCtorInitializerColon: false -SpaceBeforeInheritanceColon: false -SpaceBeforeParens: Never -SpaceBeforeRangeBasedForLoopColon: false -SpaceBeforeSquareBrackets: false -SpaceInEmptyBlock: false -SpaceInEmptyParentheses: false -SpacesBeforeTrailingComments: 1 -SpacesInAngles: false -SpacesInConditionalStatement: true -SpacesInContainerLiterals: true -SpacesInCStyleCastParentheses: true -SpacesInParentheses: true -SpacesInSquareBrackets: true -TabWidth: 4 -UseCRLF: false -UseTab: Never -... - diff --git a/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S b/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S index 6819bb2531..297b167845 100644 --- a/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S +++ b/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S @@ -31,6 +31,7 @@ .arm .syntax unified .section freertos_system_calls + #define FREERTOS_ASSEMBLY #include "FreeRTOSConfig.h" #include "portmacro_asm.h" @@ -39,728 +40,457 @@ /* ----------------------- Start of Port Specific System Calls ----------------------- */ -/** - * Function: void vPortYield - * Inputs: VOID -*/ +/* + * void vPortYield( void ); + */ .align 4 .global vPortYield .type vPortYield, %function vPortYield: - /* Make the SVC to swap tasks */ SVC #portSVC_YIELD - /* After yielding to another task, resume executing the calling task */ - BX LR + BX LR /* ----------------------------------------------------------------------------------- */ -/* vPortSystemCallExit */ + +/* + * void vPortSystemCallExit( void ); + */ .align 4 .global vPortSystemCallExit .type vPortSystemCallExit, %function vPortSystemCallExit: - /* Make the SVC to exit a system call */ SVC #portSVC_SYSTEM_CALL_EXIT - /* After performing the requested FreeRTOS API, return to the calling task */ BX LR /* ----------------------------------------------------------------------------------- */ -/** - * Function: BaseType_t xPortIsPrivileged - * Inputs: VOID -*/ + +/* + * BaseType_t xPortIsPrivileged( void ); + * + * According to the Procedure Call Standard for the ARM Architecture (AAPCS): + * - Return value must be in R0. + */ .align 4 .global xPortIsPrivileged .type xPortIsPrivileged, %function xPortIsPrivileged: - /* Load value of CPSR into R0 */ - MRS R0, CPSR - /* Get the relevant mode bits */ - AND R0, R0, #0x1F - /* Check if we're in user mode */ - CMP R0, #USER_MODE - /* If we are in user mode set R0 to 0 for the return */ - MOVEQ R0, #0x0 - /* Otherwise set R0 to 1 for the return */ - MOVNE R0, #0x01 - /* Return to the caller */ - BLX LR + MRS R0, CPSR /* R0 = CPSR. */ + AND R0, R0, #0x1F /* R0 = R0 & 0x1F. Extract mode bits.*/ + CMP R0, #USER_MODE /* If R0 == #USER_MODE. */ + MOVEQ R0, #0x0 /* Then, set R0 to 0 to indicate that the processer is not privileged. */ + MOVNE R0, #0x01 /* Otherwise, set R0 to 1 to indicate that the processer is privileged. */ + BX LR /* ----------------------------------------------------------------------------------- */ -/** - * Function: UBaseType_t ulPortCountLeadingZeros - * Inputs: UBaseType_t ulBitmap -*/ + +/* + * UBaseType_t ulPortCountLeadingZeros( UBaseType_t ulBitmap ); + * + * According to the Procedure Call Standard for the ARM Architecture (AAPCS): + * - Parameter ulBitmap is passed in R0. + * - Return value must be in R0. + */ .align 4 .weak ulPortCountLeadingZeros .type ulPortCountLeadingZeros, %function ulPortCountLeadingZeros: - /* Count the leading zeros and return in R0 */ CLZ R0, R0 BX LR /* ------------------- End of Port Specific System Calls ------------------- */ -.macro processorInUserMode - /* Push R0 before using it */ +.macro INVOKE_SYSTEM_CALL systemCallNumber, systemCallImpl PUSH {R0} - /* Load value of CPSR into R0 */ MRS R0, CPSR - /* Get the relevant mode bits */ AND R0, R0, #0x1F - /* Determine if the CPU is in user mode */ CMP R0, #USER_MODE - /* Restore the pushed register */ POP {R0} + SVCEQ \systemCallNumber + B \systemCallImpl .endm /* ----------------------------------------------------------------------------------- */ .extern MPU_xTaskGetTickCountImpl -/** - * Function: TickType_t MPU_xTaskGetTickCount - * Inputs: void - No Inputs -*/ .align 4 .global MPU_xTaskGetTickCount .type MPU_xTaskGetTickCount, function MPU_xTaskGetTickCount: - processorInUserMode - SVCEQ #SYSTEM_CALL_xTaskGetTickCount - B MPU_xTaskGetTickCountImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskGetTickCount, MPU_xTaskGetTickCountImpl /* ----------------------------------------------------------------------------------- */ .extern MPU_uxTaskGetNumberOfTasksImpl -/** - * Function: UBaseType_t MPU_uxTaskGetNumberOfTasks - * Inputs: void - No Inputs -*/ .align 4 .global MPU_uxTaskGetNumberOfTasks .type MPU_uxTaskGetNumberOfTasks, function MPU_uxTaskGetNumberOfTasks: - processorInUserMode - SVCEQ #SYSTEM_CALL_uxTaskGetNumberOfTasks - B MPU_uxTaskGetNumberOfTasksImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_uxTaskGetNumberOfTasks, MPU_uxTaskGetNumberOfTasksImpl /* ----------------------------------------------------------------------------------- */ .extern MPU_vTaskSetTimeOutStateImpl -/** - * Function: void MPU_vTaskSetTimeOutState - * Inputs: TimeOut_t * const pxTimeOut -*/ .align 4 .global MPU_vTaskSetTimeOutState .type MPU_vTaskSetTimeOutState, function MPU_vTaskSetTimeOutState: - processorInUserMode - SVCEQ #SYSTEM_CALL_vTaskSetTimeOutState - B MPU_vTaskSetTimeOutStateImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_vTaskSetTimeOutState, MPU_vTaskSetTimeOutStateImpl /* ----------------------------------------------------------------------------------- */ .extern MPU_xTaskCheckForTimeOutImpl -/** - * Function: BaseType_t MPU_xTaskCheckForTimeOut - * Inputs: TimeOut_t * const pxTimeOut - * Inputs: TickType_t * const pxTicksToWait -*/ .align 4 .global MPU_xTaskCheckForTimeOut .type MPU_xTaskCheckForTimeOut, function MPU_xTaskCheckForTimeOut: - processorInUserMode - SVCEQ #SYSTEM_CALL_xTaskCheckForTimeOut - B MPU_xTaskCheckForTimeOutImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskCheckForTimeOut, MPU_xTaskCheckForTimeOutImpl /* ----------------------------------------------------------------------------------- */ .extern MPU_xQueueGenericSendImpl -/** - * Function: BaseType_t MPU_xQueueGenericSend - * Inputs: QueueHandle_t xQueue - * Inputs: const void * const pvItemToQueue - * Inputs: TickType_t xTicksToWait - * Inputs: constBaseType_t xCopyPosition -*/ .align 4 .global MPU_xQueueGenericSend .type MPU_xQueueGenericSend, function MPU_xQueueGenericSend: - processorInUserMode - SVCEQ #SYSTEM_CALL_xQueueGenericSend - B MPU_xQueueGenericSendImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xQueueGenericSend, MPU_xQueueGenericSendImpl /* ----------------------------------------------------------------------------------- */ .extern MPU_uxQueueMessagesWaitingImpl -/** - * Function: UBaseType_t MPU_uxQueueMessagesWaiting - * Inputs: const QueueHandle_t xQueue -*/ .align 4 .global MPU_uxQueueMessagesWaiting .type MPU_uxQueueMessagesWaiting, function MPU_uxQueueMessagesWaiting: - processorInUserMode - SVCEQ #SYSTEM_CALL_uxQueueMessagesWaiting - B MPU_uxQueueMessagesWaitingImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_uxQueueMessagesWaiting, MPU_uxQueueMessagesWaitingImpl /* ----------------------------------------------------------------------------------- */ .extern MPU_uxQueueSpacesAvailableImpl -/** - * Function: UBaseType_t MPU_uxQueueSpacesAvailable - * Inputs: const QueueHandle_t xQueue -*/ .align 4 .global MPU_uxQueueSpacesAvailable .type MPU_uxQueueSpacesAvailable, function MPU_uxQueueSpacesAvailable: - processorInUserMode - SVCEQ #SYSTEM_CALL_uxQueueSpacesAvailable - B MPU_uxQueueSpacesAvailableImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_uxQueueSpacesAvailable, MPU_uxQueueSpacesAvailableImpl /* ----------------------------------------------------------------------------------- */ .extern MPU_xQueueReceiveImpl -/** - * Function: BaseType_t MPU_xQueueReceive - * Inputs: QueueHandle_t xQueue - * Inputs: void * const pvBuffer - * Inputs: TickType_t xTicksToWait -*/ .align 4 .global MPU_xQueueReceive .type MPU_xQueueReceive, function MPU_xQueueReceive: - processorInUserMode - SVCEQ #SYSTEM_CALL_xQueueReceive - B MPU_xQueueReceiveImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xQueueReceive, MPU_xQueueReceiveImpl /* ----------------------------------------------------------------------------------- */ .extern MPU_xQueuePeekImpl -/** - * Function: BaseType_t MPU_xQueuePeek - * Inputs: QueueHandle_t xQueue - * Inputs: void * const pvBuffer - * Inputs: TickType_t xTicksToWait -*/ .align 4 .global MPU_xQueuePeek .type MPU_xQueuePeek, function MPU_xQueuePeek: - processorInUserMode - SVCEQ #SYSTEM_CALL_xQueuePeek - B MPU_xQueuePeekImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xQueuePeek, MPU_xQueuePeekImpl /* ----------------------------------------------------------------------------------- */ .extern MPU_xQueueSemaphoreTakeImpl -/** - * Function: BaseType_t MPU_xQueueSemaphoreTake - * Inputs: QueueHandle_t xQueue - * Inputs: TickType_t xTicksToWait -*/ .align 4 .global MPU_xQueueSemaphoreTake .type MPU_xQueueSemaphoreTake, function MPU_xQueueSemaphoreTake: - processorInUserMode - SVCEQ #SYSTEM_CALL_xQueueSemaphoreTake - B MPU_xQueueSemaphoreTakeImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xQueueSemaphoreTake, MPU_xQueueSemaphoreTakeImpl /* ----------------------------------------------------------------------------------- */ .extern MPU_xEventGroupWaitBitsImpl -/** - * Function: EventBits_t MPU_xEventGroupWaitBitsEntry - * Inputs: const xEventGroupWaitBitsParams_t * pxParams -*/ .align 4 .global MPU_xEventGroupWaitBitsEntry .type MPU_xEventGroupWaitBitsEntry, function MPU_xEventGroupWaitBitsEntry: - processorInUserMode - SVCEQ #SYSTEM_CALL_xEventGroupWaitBits - B MPU_xEventGroupWaitBitsImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xEventGroupWaitBits, MPU_xEventGroupWaitBitsImpl /* ----------------------------------------------------------------------------------- */ .extern MPU_xEventGroupClearBitsImpl -/** - * Function: EventBits_t MPU_xEventGroupClearBits - * Inputs: EventGroupHandle_t xEventGroup - * Inputs: constEventBits_t uxBitsToClear -*/ .align 4 .global MPU_xEventGroupClearBits .type MPU_xEventGroupClearBits, function MPU_xEventGroupClearBits: - processorInUserMode - SVCEQ #SYSTEM_CALL_xEventGroupClearBits - B MPU_xEventGroupClearBitsImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xEventGroupClearBits, MPU_xEventGroupClearBitsImpl /* ----------------------------------------------------------------------------------- */ .extern MPU_xEventGroupSetBitsImpl -/** - * Function: EventBits_t MPU_xEventGroupSetBits - * Inputs: EventGroupHandle_t xEventGroup - * Inputs: constEventBits_t uxBitsToSet -*/ .align 4 .global MPU_xEventGroupSetBits .type MPU_xEventGroupSetBits, function MPU_xEventGroupSetBits: - processorInUserMode - SVCEQ #SYSTEM_CALL_xEventGroupSetBits - B MPU_xEventGroupSetBitsImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xEventGroupSetBits, MPU_xEventGroupSetBitsImpl /* ----------------------------------------------------------------------------------- */ .extern MPU_xEventGroupSyncImpl -/** - * Function: EventBits_t MPU_xEventGroupSync - * Inputs: EventGroupHandle_t xEventGroup - * Inputs: constEventBits_t uxBitsToSet - * Inputs: constEventBits_t uxBitsToWaitFor - * Inputs: TickType_t xTicksToWait -*/ .align 4 .global MPU_xEventGroupSync .type MPU_xEventGroupSync, function MPU_xEventGroupSync: - processorInUserMode - SVCEQ #SYSTEM_CALL_xEventGroupSync - B MPU_xEventGroupSyncImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xEventGroupSync, MPU_xEventGroupSyncImpl /* ----------------------------------------------------------------------------------- */ .extern MPU_xStreamBufferSendImpl -/** - * Function: size_t MPU_xStreamBufferSend - * Inputs: StreamBufferHandle_t xStreamBuffer - * Inputs: const void * pvTxData - * Inputs: size_t xDataLengthBytes - * Inputs: TickType_t xTicksToWait -*/ .align 4 .global MPU_xStreamBufferSend .type MPU_xStreamBufferSend, function MPU_xStreamBufferSend: - processorInUserMode - SVCEQ #SYSTEM_CALL_xStreamBufferSend - B MPU_xStreamBufferSendImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xStreamBufferSend, MPU_xStreamBufferSendImpl /* ----------------------------------------------------------------------------------- */ .extern MPU_xStreamBufferReceiveImpl -/** - * Function: size_t MPU_xStreamBufferReceive - * Inputs: StreamBufferHandle_t xStreamBuffer - * Inputs: void * pvRxData - * Inputs: size_t xBufferLengthBytes - * Inputs: TickType_t xTicksToWait -*/ .align 4 .global MPU_xStreamBufferReceive .type MPU_xStreamBufferReceive, function MPU_xStreamBufferReceive: - processorInUserMode - SVCEQ #SYSTEM_CALL_xStreamBufferReceive - B MPU_xStreamBufferReceiveImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xStreamBufferReceive, MPU_xStreamBufferReceiveImpl /* ----------------------------------------------------------------------------------- */ .extern MPU_xStreamBufferIsFullImpl -/** - * Function: BaseType_t MPU_xStreamBufferIsFull - * Inputs: StreamBufferHandle_t xStreamBuffer -*/ .align 4 .global MPU_xStreamBufferIsFull .type MPU_xStreamBufferIsFull, function MPU_xStreamBufferIsFull: - processorInUserMode - SVCEQ #SYSTEM_CALL_xStreamBufferIsFull - B MPU_xStreamBufferIsFullImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xStreamBufferIsFull, MPU_xStreamBufferIsFullImpl /* ----------------------------------------------------------------------------------- */ .extern MPU_xStreamBufferIsEmptyImpl -/** - * Function: BaseType_t MPU_xStreamBufferIsEmpty - * Inputs: StreamBufferHandle_t xStreamBuffer -*/ .align 4 .global MPU_xStreamBufferIsEmpty .type MPU_xStreamBufferIsEmpty, function MPU_xStreamBufferIsEmpty: - processorInUserMode - SVCEQ #SYSTEM_CALL_xStreamBufferIsEmpty - B MPU_xStreamBufferIsEmptyImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xStreamBufferIsEmpty, MPU_xStreamBufferIsEmptyImpl /* ----------------------------------------------------------------------------------- */ .extern MPU_xStreamBufferSpacesAvailableImpl -/** - * Function: size_t MPU_xStreamBufferSpacesAvailable - * Inputs: StreamBufferHandle_t xStreamBuffer -*/ .align 4 .global MPU_xStreamBufferSpacesAvailable .type MPU_xStreamBufferSpacesAvailable, function MPU_xStreamBufferSpacesAvailable: - processorInUserMode - SVCEQ #SYSTEM_CALL_xStreamBufferSpacesAvailable - B MPU_xStreamBufferSpacesAvailableImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xStreamBufferSpacesAvailable, MPU_xStreamBufferSpacesAvailableImpl /* ----------------------------------------------------------------------------------- */ .extern MPU_xStreamBufferBytesAvailableImpl -/** - * Function: size_t MPU_xStreamBufferBytesAvailable - * Inputs: StreamBufferHandle_t xStreamBuffer -*/ .align 4 .global MPU_xStreamBufferBytesAvailable .type MPU_xStreamBufferBytesAvailable, function MPU_xStreamBufferBytesAvailable: - processorInUserMode - SVCEQ #SYSTEM_CALL_xStreamBufferBytesAvailable - B MPU_xStreamBufferBytesAvailableImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xStreamBufferBytesAvailable, MPU_xStreamBufferBytesAvailableImpl /* ----------------------------------------------------------------------------------- */ .extern MPU_xStreamBufferSetTriggerLevelImpl -/** - * Function: BaseType_t MPU_xStreamBufferSetTriggerLevel - * Inputs: StreamBufferHandle_t xStreamBuffer - * Inputs: size_t xTriggerLevel -*/ .align 4 .global MPU_xStreamBufferSetTriggerLevel .type MPU_xStreamBufferSetTriggerLevel, function MPU_xStreamBufferSetTriggerLevel: - processorInUserMode - SVCEQ #SYSTEM_CALL_xStreamBufferSetTriggerLevel - B MPU_xStreamBufferSetTriggerLevelImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xStreamBufferSetTriggerLevel, MPU_xStreamBufferSetTriggerLevelImpl /* ----------------------------------------------------------------------------------- */ .extern MPU_xStreamBufferNextMessageLengthBytesImpl -/** - * Function: size_t MPU_xStreamBufferNextMessageLengthBytes - * Inputs: StreamBufferHandle_t xStreamBuffer -*/ .align 4 .global MPU_xStreamBufferNextMessageLengthBytes .type MPU_xStreamBufferNextMessageLengthBytes, function MPU_xStreamBufferNextMessageLengthBytes: - processorInUserMode - SVCEQ #SYSTEM_CALL_xStreamBufferNextMessageLengthBytes - B MPU_xStreamBufferNextMessageLengthBytesImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xStreamBufferNextMessageLengthBytes, MPU_xStreamBufferNextMessageLengthBytesImpl /* ----------------------------------------------------------------------------------- */ -#if ( INCLUDE_xTaskDelayUntil == 1 ) || ( INCLUDE_vTaskDelayUntil == 1 ) +#if ( ( INCLUDE_xTaskDelayUntil == 1 ) || ( INCLUDE_vTaskDelayUntil == 1 ) ) + .extern MPU_xTaskDelayUntilImpl - /** - * Function: TaskHandle_t MPU_xTaskDelayUntil - * Inputs: TickType_t * const pxPreviousWakeTime - * Inputs: constTickType_t xTimeIncrement - */ .align 4 .global MPU_xTaskDelayUntil .type MPU_xTaskDelayUntil, function MPU_xTaskDelayUntil: - processorInUserMode - SVCEQ #SYSTEM_CALL_xTaskDelayUntil - B MPU_xTaskDelayUntilImpl - - /* ------------------------------------------------------------------------------- */ - -#endif /* if ( INCLUDE_xTaskDelayUntil == 1 ) || ( INCLUDE_vTaskDelayUntil == 1 ) */ + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskDelayUntil, MPU_xTaskDelayUntilImpl -#if INCLUDE_xTaskAbortDelay == 1 +#endif /* if ( ( INCLUDE_xTaskDelayUntil == 1 ) || ( INCLUDE_vTaskDelayUntil == 1 ) ) */ /* ----------------------------------------------------------------------------------- */ +#if ( INCLUDE_xTaskAbortDelay == 1 ) + .extern MPU_xTaskAbortDelayImpl - /** - * Function: TaskHandle_t MPU_xTaskAbortDelay - * Inputs: TaskHandle_t xTask - */ .align 4 .global MPU_xTaskAbortDelay .type MPU_xTaskAbortDelay, function MPU_xTaskAbortDelay: - processorInUserMode - SVCEQ #SYSTEM_CALL_xTaskAbortDelay - B MPU_xTaskAbortDelayImpl - - /* ------------------------------------------------------------------------------- */ + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskAbortDelay, MPU_xTaskAbortDelayImpl #endif /* if ( INCLUDE_xTaskAbortDelay == 1 ) */ -#if INCLUDE_vTaskDelay == 1 +/* ------------------------------------------------------------------------------- */ - /* ------------------------------------------------------------------------------- */ +#if ( INCLUDE_vTaskDelay == 1 ) .extern MPU_vTaskDelayImpl - /** - * Function: void MPU_vTaskDelay - * Inputs: const TickType_t xTicksToDelay - */ .align 4 .global MPU_vTaskDelay .type MPU_vTaskDelay, function MPU_vTaskDelay: - processorInUserMode - SVCEQ #SYSTEM_CALL_vTaskDelay - B MPU_vTaskDelayImpl - - /* ------------------------------------------------------------------------------- */ + INVOKE_SYSTEM_CALL #SYSTEM_CALL_vTaskDelay, MPU_vTaskDelayImpl #endif /* if ( INCLUDE_vTaskDelay == 1 ) */ -#if INCLUDE_uxTaskPriorityGet == 1 +/* ------------------------------------------------------------------------------- */ - /* ------------------------------------------------------------------------------- */ +#if ( INCLUDE_uxTaskPriorityGet == 1 ) .extern MPU_uxTaskPriorityGetImpl - /** - * Function: UBaseType_t MPU_uxTaskPriorityGet - * Inputs: const TaskHandle_t xTask - */ .align 4 .global MPU_uxTaskPriorityGet .type MPU_uxTaskPriorityGet, function MPU_uxTaskPriorityGet: - processorInUserMode - SVCEQ #SYSTEM_CALL_uxTaskPriorityGet - B MPU_uxTaskPriorityGetImpl - - /* ------------------------------------------------------------------------------- */ + INVOKE_SYSTEM_CALL #SYSTEM_CALL_uxTaskPriorityGet, MPU_uxTaskPriorityGetImpl #endif /* if ( INCLUDE_uxTaskPriorityGet == 1 ) */ -#if INCLUDE_eTaskGetState == 1 +/* ------------------------------------------------------------------------------- */ - /* ------------------------------------------------------------------------------- */ +#if ( INCLUDE_eTaskGetState == 1 ) .extern MPU_eTaskGetStateImpl - /** - * Function: eTaskState MPU_eTaskGetState - * Inputs: TaskHandle_t xTask - */ .align 4 .global MPU_eTaskGetState .type MPU_eTaskGetState, function MPU_eTaskGetState: - processorInUserMode - SVCEQ #SYSTEM_CALL_eTaskGetState - B MPU_eTaskGetStateImpl - - /* ------------------------------------------------------------------------------- */ + INVOKE_SYSTEM_CALL #SYSTEM_CALL_eTaskGetState, MPU_eTaskGetStateImpl #endif /* if ( INCLUDE_eTaskGetState == 1 ) */ -#if configUSE_TRACE_FACILITY == 1 +/* ------------------------------------------------------------------------------- */ - /* ------------------------------------------------------------------------------- */ +#if ( configUSE_TRACE_FACILITY == 1 ) .extern MPU_vTaskGetInfoImpl - /** - * Function: void MPU_vTaskGetInfo - * Inputs: TaskHandle_t xTask - * Inputs: TaskStatus_t* pxTaskStatus - * Inputs: TaskHandle_t xGetFreeStackSpace - * Inputs: eTaskState eState - */ .align 4 .global MPU_vTaskGetInfo .type MPU_vTaskGetInfo, function MPU_vTaskGetInfo: - processorInUserMode - SVCEQ #SYSTEM_CALL_vTaskGetInfo - B MPU_vTaskGetInfoImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_vTaskGetInfo, MPU_vTaskGetInfoImpl /* ------------------------------------------------------------------------------- */ .extern MPU_uxTaskGetSystemStateImpl - /** - * Function: UBaseType_t MPU_uxTaskGetSystemState - * Inputs: TaskStatus_t * const pxTaskStatusArray - * Inputs: constUBaseType_t uxArraySize - * Inputs: configRUN_TIME_COUNTER_TYPE* const pulTotalRunTime - */ .align 4 .global MPU_uxTaskGetSystemState .type MPU_uxTaskGetSystemState, function MPU_uxTaskGetSystemState: - processorInUserMode - SVCEQ #SYSTEM_CALL_uxTaskGetSystemState - B MPU_uxTaskGetSystemStateImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_uxTaskGetSystemState, MPU_uxTaskGetSystemStateImpl /* ------------------------------------------------------------------------------- */ .extern MPU_uxEventGroupGetNumberImpl - /** - * Function: UBaseType_t MPU_uxEventGroupGetNumber - * Inputs: void * xEventGroup - */ .align 4 .global MPU_uxEventGroupGetNumber .type MPU_uxEventGroupGetNumber, function MPU_uxEventGroupGetNumber: - processorInUserMode - SVCEQ #SYSTEM_CALL_uxEventGroupGetNumber - B MPU_uxEventGroupGetNumberImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_uxEventGroupGetNumber, MPU_uxEventGroupGetNumberImpl /* ------------------------------------------------------------------------------- */ .extern MPU_vEventGroupSetNumberImpl - /** - * Function: void MPU_vEventGroupSetNumber - * Inputs: void * xEventGroup - * Inputs: UBaseType_t uxEventGroupNumber - */ .align 4 .global MPU_vEventGroupSetNumber .type MPU_vEventGroupSetNumber, function MPU_vEventGroupSetNumber: - processorInUserMode - SVCEQ #SYSTEM_CALL_vEventGroupSetNumber - B MPU_vEventGroupSetNumberImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_vEventGroupSetNumber, MPU_vEventGroupSetNumberImpl /* ------------------------------------------------------------------------------- */ + #endif /* if ( configUSE_TRACE_FACILITY == 1 ) */ -#if INCLUDE_xTaskGetIdleTaskHandle == 1 +/* ------------------------------------------------------------------------------- */ + +#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) - /* ------------------------------------------------------------------------------- */ .extern MPU_xTaskGetIdleTaskHandleImpl - /** - * Function: TaskHandle_t MPU_xTaskGetIdleTaskHandle - * Inputs: void - No Inputs - */ .align 4 .global MPU_xTaskGetIdleTaskHandle .type MPU_xTaskGetIdleTaskHandle, function MPU_xTaskGetIdleTaskHandle: - processorInUserMode - SVCEQ #SYSTEM_CALL_xTaskGetIdleTaskHandle - B MPU_xTaskGetIdleTaskHandleImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskGetIdleTaskHandle, MPU_xTaskGetIdleTaskHandleImpl - /* ------------------------------------------------------------------------------- */ #endif /* if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */ -#if INCLUDE_vTaskSuspend == 1 +/* ------------------------------------------------------------------------------- */ - /* ------------------------------------------------------------------------------- */ +#if ( INCLUDE_vTaskSuspend == 1 ) .extern MPU_vTaskSuspendImpl - /** - * Function: void MPU_vTaskSuspend - * Inputs: TaskHandle_t xTaskToSuspend - */ .align 4 .global MPU_vTaskSuspend .type MPU_vTaskSuspend, function MPU_vTaskSuspend: - processorInUserMode - SVCEQ #SYSTEM_CALL_vTaskSuspend - B MPU_vTaskSuspendImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_vTaskSuspend, MPU_vTaskSuspendImpl /* ------------------------------------------------------------------------------- */ .extern MPU_vTaskResumeImpl - /** - * Function: void MPU_vTaskResume - * Inputs: TaskHandle_t xTaskToResume - */ .align 4 .global MPU_vTaskResume .type MPU_vTaskResume, function MPU_vTaskResume: - processorInUserMode - SVCEQ #SYSTEM_CALL_vTaskResume - B MPU_vTaskResumeImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_vTaskResume, MPU_vTaskResumeImpl /* ------------------------------------------------------------------------------- */ #endif /* if ( INCLUDE_vTaskSuspend == 1 ) */ -#if configGENERATE_RUN_TIME_STATS == 1 +/* ------------------------------------------------------------------------------- */ - /* ------------------------------------------------------------------------------- */ +#if ( configGENERATE_RUN_TIME_STATS == 1 ) .extern MPU_ulTaskGetRunTimeCounterImpl - /** - * Function: configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter - * Inputs: const TaskHandle_t xTask - */ .align 4 .global MPU_ulTaskGetRunTimeCounter .type MPU_ulTaskGetRunTimeCounter, function MPU_ulTaskGetRunTimeCounter: - processorInUserMode - SVCEQ #SYSTEM_CALL_ulTaskGetRunTimeCounter - B MPU_ulTaskGetRunTimeCounterImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_ulTaskGetRunTimeCounter, MPU_ulTaskGetRunTimeCounterImpl /* ------------------------------------------------------------------------------- */ .extern MPU_ulTaskGetRunTimePercentImpl - /** - * Function: configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent - * Inputs: const TaskHandle_t xTask - */ .align 4 .global MPU_ulTaskGetRunTimePercent .type MPU_ulTaskGetRunTimePercent, function MPU_ulTaskGetRunTimePercent: - processorInUserMode - SVCEQ #SYSTEM_CALL_ulTaskGetRunTimePercent - B MPU_ulTaskGetRunTimePercentImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_ulTaskGetRunTimePercent, MPU_ulTaskGetRunTimePercentImpl /* ------------------------------------------------------------------------------- */ - #if INCLUDE_xTaskGetIdleTaskHandle == 1 - - /* --------------------------------------------------------------------------- */ + #if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) .extern MPU_ulTaskGetIdleRunTimePercentImpl - /** - * Function: configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent - * Inputs: void - */ .align 4 .global MPU_ulTaskGetIdleRunTimePercent .type MPU_ulTaskGetIdleRunTimePercent, function MPU_ulTaskGetIdleRunTimePercent: - processorInUserMode - SVCEQ #SYSTEM_CALL_ulTaskGetIdleRunTimePercent - B MPU_ulTaskGetIdleRunTimePercentImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_ulTaskGetIdleRunTimePercent, MPU_ulTaskGetIdleRunTimePercentImpl /* --------------------------------------------------------------------------- */ .extern MPU_ulTaskGetIdleRunTimeCounterImpl - /** - * Function: configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter - * Inputs: void - No Inputs - */ .align 4 .global MPU_ulTaskGetIdleRunTimeCounter .type MPU_ulTaskGetIdleRunTimeCounter, function MPU_ulTaskGetIdleRunTimeCounter: - processorInUserMode - SVCEQ #SYSTEM_CALL_ulTaskGetIdleRunTimeCounter - B MPU_ulTaskGetIdleRunTimeCounterImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_ulTaskGetIdleRunTimeCounter, MPU_ulTaskGetIdleRunTimeCounterImpl /* --------------------------------------------------------------------------- */ @@ -768,568 +498,357 @@ MPU_xStreamBufferNextMessageLengthBytes: #endif /* if ( configGENERATE_RUN_TIME_STATS == 1 )*/ -#if configUSE_APPLICATION_TASK_TAG == 1 +/* --------------------------------------------------------------------------- */ - /* ------------------------------------------------------------------------------- */ +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) .extern MPU_vTaskSetApplicationTaskTagImpl - /** - * Function: void MPU_vTaskSetApplicationTaskTag - * Inputs: TaskHandle_t xTask - * Inputs: TaskHookFunction_tpxHookFunction - */ .align 4 .global MPU_vTaskSetApplicationTaskTag .type MPU_vTaskSetApplicationTaskTag, function MPU_vTaskSetApplicationTaskTag: - processorInUserMode - SVCEQ #SYSTEM_CALL_vTaskSetApplicationTaskTag - B MPU_vTaskSetApplicationTaskTagImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_vTaskSetApplicationTaskTag, MPU_vTaskSetApplicationTaskTagImpl /* ------------------------------------------------------------------------------- */ .extern MPU_xTaskGetApplicationTaskTagImpl - /** - * Function: TaskHookFunction_t MPU_xTaskGetApplicationTaskTag - * Inputs: TaskHandle_t xTask - */ .align 4 .global MPU_xTaskGetApplicationTaskTag .type MPU_xTaskGetApplicationTaskTag, function MPU_xTaskGetApplicationTaskTag: - processorInUserMode - SVCEQ #SYSTEM_CALL_xTaskGetApplicationTaskTag - B MPU_xTaskGetApplicationTaskTagImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskGetApplicationTaskTag, MPU_xTaskGetApplicationTaskTagImpl /* ------------------------------------------------------------------------------- */ + #endif /* if ( configUSE_APPLICATION_TASK_TAG == 1 ) */ -#if configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 +/* ------------------------------------------------------------------------------- */ - /* ------------------------------------------------------------------------------- */ +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) .extern MPU_vTaskSetThreadLocalStoragePointerImpl - /** - * Function: void MPU_vTaskSetThreadLocalStoragePointer - * Inputs: TaskHandle_t xTaskToSet - * Inputs: TaskHandle_t xIndex - * Inputs: void * pvValue - */ .align 4 .global MPU_vTaskSetThreadLocalStoragePointer .type MPU_vTaskSetThreadLocalStoragePointer, function MPU_vTaskSetThreadLocalStoragePointer: - processorInUserMode - SVCEQ #SYSTEM_CALL_vTaskSetThreadLocalStoragePointer - B MPU_vTaskSetThreadLocalStoragePointerImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_vTaskSetThreadLocalStoragePointer, MPU_vTaskSetThreadLocalStoragePointerImpl /* ------------------------------------------------------------------------------- */ .extern MPU_pvTaskGetThreadLocalStoragePointerImpl - /** - * Function: void * MPU_pvTaskGetThreadLocalStoragePointer - * Inputs: TaskHandle_t xTaskToQuery - * Inputs: TaskHandle_t xIndex - */ .align 4 .global MPU_pvTaskGetThreadLocalStoragePointer .type MPU_pvTaskGetThreadLocalStoragePointer, function MPU_pvTaskGetThreadLocalStoragePointer: - processorInUserMode - SVCEQ #SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer - B MPU_pvTaskGetThreadLocalStoragePointerImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer, MPU_pvTaskGetThreadLocalStoragePointerImpl /* ------------------------------------------------------------------------------- */ #endif /* if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ -#if INCLUDE_uxTaskGetStackHighWaterMark == 1 +/* ------------------------------------------------------------------------------- */ - /* ------------------------------------------------------------------------------- */ +#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) .extern MPU_uxTaskGetStackHighWaterMarkImpl - /** - * Function: UBaseType_t MPU_uxTaskGetStackHighWaterMark - * Inputs: TaskHandle_t xTask - */ .align 4 .global MPU_uxTaskGetStackHighWaterMark .type MPU_uxTaskGetStackHighWaterMark, function MPU_uxTaskGetStackHighWaterMark: - processorInUserMode - SVCEQ #SYSTEM_CALL_uxTaskGetStackHighWaterMark - B MPU_uxTaskGetStackHighWaterMarkImpl - - /* ------------------------------------------------------------------------------- */ + INVOKE_SYSTEM_CALL #SYSTEM_CALL_uxTaskGetStackHighWaterMark, MPU_uxTaskGetStackHighWaterMarkImpl #endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) */ +/* ------------------------------------------------------------------------------- */ -#if INCLUDE_uxTaskGetStackHighWaterMark == 2 - - /* ------------------------------------------------------------------------------- */ +#if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) .extern MPU_uxTaskGetStackHighWaterMark2Impl - /** - * Function: configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2 - * Inputs: TaskHandle_t xTask - */ .align 4 .global MPU_uxTaskGetStackHighWaterMark2 .type MPU_uxTaskGetStackHighWaterMark2, function MPU_uxTaskGetStackHighWaterMark2: - processorInUserMode - SVCEQ #SYSTEM_CALL_uxTaskGetStackHighWaterMark2 - B MPU_uxTaskGetStackHighWaterMark2Impl - - /* ------------------------------------------------------------------------------- */ + INVOKE_SYSTEM_CALL #SYSTEM_CALL_uxTaskGetStackHighWaterMark2, MPU_uxTaskGetStackHighWaterMark2Impl #endif /* if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) */ +/* ------------------------------------------------------------------------------- */ -#if INCLUDE_xTaskGetCurrentTaskHandle == 1 || configUSE_MUTEXES == 1 - - /* ------------------------------------------------------------------------------- */ +#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) .extern MPU_xTaskGetCurrentTaskHandleImpl - /** - * Function: TaskHandle_t MPU_xTaskGetCurrentTaskHandle - * Inputs: void - No Inputs - */ .align 4 .global MPU_xTaskGetCurrentTaskHandle .type MPU_xTaskGetCurrentTaskHandle, function MPU_xTaskGetCurrentTaskHandle: - processorInUserMode - SVCEQ #SYSTEM_CALL_xTaskGetCurrentTaskHandle - B MPU_xTaskGetCurrentTaskHandleImpl - - /* ------------------------------------------------------------------------------- */ + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskGetCurrentTaskHandle, MPU_xTaskGetCurrentTaskHandleImpl #endif /* if( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ -#if INCLUDE_xTaskGetSchedulerState == 1 +/* ------------------------------------------------------------------------------- */ - /* ------------------------------------------------------------------------------- */ +#if ( INCLUDE_xTaskGetSchedulerState == 1 ) .extern MPU_xTaskGetSchedulerStateImpl - /** - * Function: TaskHandle_t MPU_xTaskGetSchedulerState - * Inputs: void - No Inputs - */ .align 4 .global MPU_xTaskGetSchedulerState .type MPU_xTaskGetSchedulerState, function MPU_xTaskGetSchedulerState: - processorInUserMode - SVCEQ #SYSTEM_CALL_xTaskGetSchedulerState - B MPU_xTaskGetSchedulerStateImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskGetSchedulerState, MPU_xTaskGetSchedulerStateImpl - /* ------------------------------------------------------------------------------- */ #endif /* if ( INCLUDE_xTaskGetSchedulerState == 1 ) */ -#if configUSE_MUTEXES == 1 && INCLUDE_xSemaphoreGetMutexHolder +/* ------------------------------------------------------------------------------- */ - /* ------------------------------------------------------------------------------- */ +#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) .extern MPU_xQueueGetMutexHolderImpl - /** - * Function: TaskHandle_t MPU_xQueueGetMutexHolder - * Inputs: QueueHandle_t xSemaphore - */ .align 4 .global MPU_xQueueGetMutexHolder .type MPU_xQueueGetMutexHolder, function MPU_xQueueGetMutexHolder: - processorInUserMode - SVCEQ #SYSTEM_CALL_xQueueGetMutexHolder - B MPU_xQueueGetMutexHolderImpl - - /* ------------------------------------------------------------------------------- */ + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xQueueGetMutexHolder, MPU_xQueueGetMutexHolderImpl #endif /* if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) */ -#if configUSE_RECURSIVE_MUTEXES == 1 +/* ------------------------------------------------------------------------------- */ - /* ------------------------------------------------------------------------------- */ +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) .extern MPU_xQueueTakeMutexRecursiveImpl - /** - * Function: TaskHandle_t MPU_xQueueTakeMutexRecursive - * Inputs: QueueHandle_t xMutex - * Inputs: TickType_t xTicksToWait - */ .align 4 .global MPU_xQueueTakeMutexRecursive .type MPU_xQueueTakeMutexRecursive, function MPU_xQueueTakeMutexRecursive: - processorInUserMode - SVCEQ #SYSTEM_CALL_xQueueTakeMutexRecursive - B MPU_xQueueTakeMutexRecursiveImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xQueueTakeMutexRecursive, MPU_xQueueTakeMutexRecursiveImpl /* ------------------------------------------------------------------------------- */ .extern MPU_xQueueGiveMutexRecursiveImpl - /** - * Function: TaskHandle_t MPU_xQueueGiveMutexRecursive - * Inputs: QueueHandle_t pxMutex - */ .align 4 .global MPU_xQueueGiveMutexRecursive .type MPU_xQueueGiveMutexRecursive, function MPU_xQueueGiveMutexRecursive: - processorInUserMode - SVCEQ #SYSTEM_CALL_xQueueGiveMutexRecursive - B MPU_xQueueGiveMutexRecursiveImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xQueueGiveMutexRecursive, MPU_xQueueGiveMutexRecursiveImpl /* ------------------------------------------------------------------------------- */ #endif /* if ( configUSE_RECURSIVE_MUTEXES == 1 ) */ -#if configUSE_QUEUE_SETS == 1 +/* ------------------------------------------------------------------------------- */ - /* ------------------------------------------------------------------------------- */ +#if ( configUSE_QUEUE_SETS == 1 ) .extern MPU_xQueueSelectFromSetImpl - /** - * Function: QueueSetMemberHandle_t MPU_xQueueSelectFromSet - * Inputs: QueueSetHandle_t xQueueSet - * Inputs: constTickType_t xTicksToWait - */ .align 4 .global MPU_xQueueSelectFromSet .type MPU_xQueueSelectFromSet, function MPU_xQueueSelectFromSet: - processorInUserMode - SVCEQ #SYSTEM_CALL_xQueueSelectFromSet - B MPU_xQueueSelectFromSetImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xQueueSelectFromSet, MPU_xQueueSelectFromSetImpl /* ------------------------------------------------------------------------------- */ .extern MPU_xQueueAddToSetImpl - /** - * Function: TaskHandle_t MPU_xQueueAddToSet - * Inputs: QueueSetMemberHandle_t xQueueOrSemaphore - * Inputs: QueueSetHandle_t xQueueSet - */ .align 4 .global MPU_xQueueAddToSet .type MPU_xQueueAddToSet, function MPU_xQueueAddToSet: - processorInUserMode - SVCEQ #SYSTEM_CALL_xQueueAddToSet - B MPU_xQueueAddToSetImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xQueueAddToSet, MPU_xQueueAddToSetImpl /* ------------------------------------------------------------------------------- */ #endif /* if ( configUSE_QUEUE_SETS == 1 ) */ -#if configQUEUE_REGISTRY_SIZE > 0 +/* ------------------------------------------------------------------------------- */ - /* ------------------------------------------------------------------------------- */ +#if ( configQUEUE_REGISTRY_SIZE > 0 ) .extern MPU_vQueueAddToRegistryImpl - /** - * Function: void MPU_vQueueAddToRegistry - * Inputs: QueueHandle_t xQueue - * Inputs: constchar * pcName - */ .align 4 .global MPU_vQueueAddToRegistry .type MPU_vQueueAddToRegistry, function MPU_vQueueAddToRegistry: - processorInUserMode - SVCEQ #SYSTEM_CALL_vQueueAddToRegistry - B MPU_vQueueAddToRegistryImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_vQueueAddToRegistry, MPU_vQueueAddToRegistryImpl /* ------------------------------------------------------------------------------- */ .extern MPU_vQueueUnregisterQueueImpl - /** - * Function: void MPU_vQueueUnregisterQueue - * Inputs: QueueHandle_t xQueue - */ .align 4 .global MPU_vQueueUnregisterQueue .type MPU_vQueueUnregisterQueue, function MPU_vQueueUnregisterQueue: - processorInUserMode - SVCEQ #SYSTEM_CALL_vQueueUnregisterQueue - B MPU_vQueueUnregisterQueueImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_vQueueUnregisterQueue, MPU_vQueueUnregisterQueueImpl /* ------------------------------------------------------------------------------- */ .extern MPU_pcQueueGetNameImpl - /** - * Function: const char * MPU_pcQueueGetName - * Inputs: QueueHandle_t xQueue - */ .align 4 .global MPU_pcQueueGetName .type MPU_pcQueueGetName, function MPU_pcQueueGetName: - processorInUserMode - SVCEQ #SYSTEM_CALL_pcQueueGetName - B MPU_pcQueueGetNameImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_pcQueueGetName, MPU_pcQueueGetNameImpl /* ------------------------------------------------------------------------------- */ #endif /* if ( configQUEUE_REGISTRY_SIZE > 0 ) */ -#if configUSE_TIMERS == 1 +/* ------------------------------------------------------------------------------- */ - /* ------------------------------------------------------------------------------- */ +#if ( configUSE_TIMERS == 1 ) .extern MPU_pvTimerGetTimerIDImpl - /** - * Function: void * MPU_pvTimerGetTimerID - * Inputs: const TimerHandle_t xTimer - */ .align 4 .global MPU_pvTimerGetTimerID .type MPU_pvTimerGetTimerID, function MPU_pvTimerGetTimerID: - processorInUserMode - SVCEQ #SYSTEM_CALL_pvTimerGetTimerID - B MPU_pvTimerGetTimerIDImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_pvTimerGetTimerID, MPU_pvTimerGetTimerIDImpl /* ------------------------------------------------------------------------------- */ .extern MPU_vTimerSetTimerIDImpl - /** - * Function: void MPU_vTimerSetTimerID - * Inputs: TimerHandle_t xTimer - * Inputs: void * pvNewID - */ .align 4 .global MPU_vTimerSetTimerID .type MPU_vTimerSetTimerID, function MPU_vTimerSetTimerID: - processorInUserMode - SVCEQ #SYSTEM_CALL_vTimerSetTimerID - B MPU_vTimerSetTimerIDImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_vTimerSetTimerID, MPU_vTimerSetTimerIDImpl /* ------------------------------------------------------------------------------- */ .extern MPU_xTimerIsTimerActiveImpl - /** - * Function: TaskHandle_t MPU_xTimerIsTimerActive - * Inputs: TimerHandle_t xTimer - */ .align 4 .global MPU_xTimerIsTimerActive .type MPU_xTimerIsTimerActive, function MPU_xTimerIsTimerActive: - processorInUserMode - SVCEQ #SYSTEM_CALL_xTimerIsTimerActive - B MPU_xTimerIsTimerActiveImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTimerIsTimerActive, MPU_xTimerIsTimerActiveImpl /* ------------------------------------------------------------------------------- */ .extern MPU_xTimerGetTimerDaemonTaskHandleImpl - /** - * Function: TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle - * Inputs: void - No Inputs - */ .align 4 .global MPU_xTimerGetTimerDaemonTaskHandle .type MPU_xTimerGetTimerDaemonTaskHandle, function MPU_xTimerGetTimerDaemonTaskHandle: - processorInUserMode - SVCEQ #SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle - B MPU_xTimerGetTimerDaemonTaskHandleImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle, MPU_xTimerGetTimerDaemonTaskHandleImpl /* ------------------------------------------------------------------------------- */ .extern MPU_xTimerGenericCommandFromTaskImpl - /** - * Function: TaskHandle_t MPU_xTimerGenericCommandFromTaskEntry - * Inputs: const xTimerGenericCommandParams_t * pxParams - */ .align 4 .global MPU_xTimerGenericCommandFromTaskEntry .type MPU_xTimerGenericCommandFromTaskEntry, function MPU_xTimerGenericCommandFromTaskEntry: - processorInUserMode - SVCEQ #SYSTEM_CALL_xTimerGenericCommandFromTask - B MPU_xTimerGenericCommandFromTaskImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTimerGenericCommandFromTask, MPU_xTimerGenericCommandFromTaskImpl /* ------------------------------------------------------------------------------- */ - .extern MPU_pcTimerGetNameImpl - /** - * Function: const char * MPU_pcTimerGetName - * Inputs: TimerHandle_t xTimer - */ .align 4 .global MPU_pcTimerGetName .type MPU_pcTimerGetName, function MPU_pcTimerGetName: - processorInUserMode - SVCEQ #SYSTEM_CALL_pcTimerGetName - B MPU_pcTimerGetNameImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_pcTimerGetName, MPU_pcTimerGetNameImpl /* ------------------------------------------------------------------------------- */ .extern MPU_vTimerSetReloadModeImpl - /** - * Function: void MPU_vTimerSetReloadMode - * Inputs: TimerHandle_t xTimer - * Inputs: constBaseType_t uxAutoReload - */ .align 4 .global MPU_vTimerSetReloadMode .type MPU_vTimerSetReloadMode, function MPU_vTimerSetReloadMode: - processorInUserMode - SVCEQ #SYSTEM_CALL_vTimerSetReloadMode - B MPU_vTimerSetReloadModeImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_vTimerSetReloadMode, MPU_vTimerSetReloadModeImpl /* ------------------------------------------------------------------------------- */ .extern MPU_xTimerGetReloadModeImpl - /** - * Function: TaskHandle_t MPU_xTimerGetReloadMode - * Inputs: TimerHandle_t xTimer - */ .align 4 .global MPU_xTimerGetReloadMode .type MPU_xTimerGetReloadMode, function MPU_xTimerGetReloadMode: - processorInUserMode - SVCEQ #SYSTEM_CALL_xTimerGetReloadMode - B MPU_xTimerGetReloadModeImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTimerGetReloadMode, MPU_xTimerGetReloadModeImpl /* ------------------------------------------------------------------------------- */ .extern MPU_uxTimerGetReloadModeImpl - /** - * Function: UBaseType_t MPU_uxTimerGetReloadMode - * Inputs: TimerHandle_t xTimer - */ .align 4 .global MPU_uxTimerGetReloadMode .type MPU_uxTimerGetReloadMode, function MPU_uxTimerGetReloadMode: - processorInUserMode - SVCEQ #SYSTEM_CALL_uxTimerGetReloadMode - B MPU_uxTimerGetReloadModeImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_uxTimerGetReloadMode, MPU_uxTimerGetReloadModeImpl /* ------------------------------------------------------------------------------- */ .extern MPU_xTimerGetPeriodImpl - /** - * Function: TickType_t MPU_xTimerGetPeriod - * Inputs: TimerHandle_t xTimer - */ .align 4 .global MPU_xTimerGetPeriod .type MPU_xTimerGetPeriod, function MPU_xTimerGetPeriod: - processorInUserMode - SVCEQ #SYSTEM_CALL_xTimerGetPeriod - B MPU_xTimerGetPeriodImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTimerGetPeriod, MPU_xTimerGetPeriodImpl /* ------------------------------------------------------------------------------- */ .extern MPU_xTimerGetExpiryTimeImpl - /** - * Function: TickType_t MPU_xTimerGetExpiryTime - * Inputs: TimerHandle_t xTimer - */ .align 4 .global MPU_xTimerGetExpiryTime .type MPU_xTimerGetExpiryTime, function MPU_xTimerGetExpiryTime: - processorInUserMode - SVCEQ #SYSTEM_CALL_xTimerGetExpiryTime - B MPU_xTimerGetExpiryTimeImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTimerGetExpiryTime, MPU_xTimerGetExpiryTimeImpl /* ------------------------------------------------------------------------------- */ #endif /* if ( configUSE_TIMERS == 1 ) */ -#if configUSE_TASK_NOTIFICATIONS == 1 +/* ------------------------------------------------------------------------------- */ + +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + .extern MPU_xTaskGenericNotifyImpl - /** - * Function: TaskHandle_t MPU_xTaskGenericNotifyEntry - * Inputs: const xTaskGenericNotifyParams_t * pxParams - */ .align 4 .global MPU_xTaskGenericNotifyEntry .type MPU_xTaskGenericNotifyEntry, function MPU_xTaskGenericNotifyEntry: - processorInUserMode - SVCEQ #SYSTEM_CALL_xTaskGenericNotify - B MPU_xTaskGenericNotifyImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskGenericNotify, MPU_xTaskGenericNotifyImpl /* ------------------------------------------------------------------------------- */ .extern MPU_xTaskGenericNotifyWaitImpl - /** - * Function: TaskHandle_t MPU_xTaskGenericNotifyWaitEntry - * Inputs: const xTaskGenericNotifyWaitParams_t * pxParams - */ .align 4 .global MPU_xTaskGenericNotifyWaitEntry .type MPU_xTaskGenericNotifyWaitEntry, function MPU_xTaskGenericNotifyWaitEntry: - processorInUserMode - SVCEQ #SYSTEM_CALL_xTaskGenericNotifyWait - B MPU_xTaskGenericNotifyWaitImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskGenericNotifyWait, MPU_xTaskGenericNotifyWaitImpl /* ------------------------------------------------------------------------------- */ .extern MPU_ulTaskGenericNotifyTakeImpl - /** - * Function: uint32_t MPU_ulTaskGenericNotifyTake - * Inputs: UBaseType_t uxIndexToWaitOn - * Inputs: TaskHandle_t xClearCountOnExit - * Inputs: TickType_t xTicksToWait - */ .align 4 .global MPU_ulTaskGenericNotifyTake .type MPU_ulTaskGenericNotifyTake, function MPU_ulTaskGenericNotifyTake: - processorInUserMode - SVCEQ #SYSTEM_CALL_ulTaskGenericNotifyTake - B MPU_ulTaskGenericNotifyTakeImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_ulTaskGenericNotifyTake, MPU_ulTaskGenericNotifyTakeImpl /* ------------------------------------------------------------------------------- */ .extern MPU_xTaskGenericNotifyStateClearImpl - /** - * Function: TaskHandle_t MPU_xTaskGenericNotifyStateClear - * Inputs: TaskHandle_t xTask - * Inputs: UBaseType_t uxIndexToClear - */ .align 4 .global MPU_xTaskGenericNotifyStateClear .type MPU_xTaskGenericNotifyStateClear, function MPU_xTaskGenericNotifyStateClear: - processorInUserMode - SVCEQ #SYSTEM_CALL_xTaskGenericNotifyStateClear - B MPU_xTaskGenericNotifyStateClearImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_xTaskGenericNotifyStateClear, MPU_xTaskGenericNotifyStateClearImpl /* ------------------------------------------------------------------------------- */ .extern MPU_ulTaskGenericNotifyValueClearImpl - /** - * Function: uint32_t MPU_ulTaskGenericNotifyValueClear - * Inputs: TaskHandle_t xTask - * Inputs: UBaseType_t uxIndexToClear - * Inputs: uint32_t ulBitsToClear - */ .align 4 .global MPU_ulTaskGenericNotifyValueClear .type MPU_ulTaskGenericNotifyValueClear, function MPU_ulTaskGenericNotifyValueClear: - processorInUserMode - SVCEQ #SYSTEM_CALL_ulTaskGenericNotifyValueClear - B MPU_ulTaskGenericNotifyValueClearImpl + INVOKE_SYSTEM_CALL #SYSTEM_CALL_ulTaskGenericNotifyValueClear, MPU_ulTaskGenericNotifyValueClearImpl /* ------------------------------------------------------------------------------- */ #endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */ + +/* ------------------------------------------------------------------------------- */ + +.end diff --git a/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.h b/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.h deleted file mode 100644 index 17fec8f6c8..0000000000 --- a/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.h +++ /dev/null @@ -1,495 +0,0 @@ -/* - * FreeRTOS Kernel - * Copyright (C) 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#ifndef MPU_PROTOTYPES_H -#define MPU_PROTOTYPES_H - -#include - -/** Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from - * redefining all the API functions to use the MPU wrappers. That should only - * be done when task.h is included from an application file. */ -#ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE - #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE -#endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ - -/* Scheduler includes. */ -#include "FreeRTOS.h" -#include "task.h" -#include "queue.h" -#include "timers.h" -#include "event_groups.h" -#include "stream_buffer.h" -#include "mpu_prototypes.h" -#include "mpu_syscall_numbers.h" - -#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE - -typedef struct xTaskGenericNotifyParams -{ - TaskHandle_t xTaskToNotify; - UBaseType_t uxIndexToNotify; - uint32_t ulValue; - eNotifyAction eAction; - uint32_t * pulPreviousNotificationValue; -} xTaskGenericNotifyParams_t; - -typedef struct xTaskGenericNotifyWaitParams -{ - UBaseType_t uxIndexToWaitOn; - uint32_t ulBitsToClearOnEntry; - uint32_t ulBitsToClearOnExit; - uint32_t * pulNotificationValue; - TickType_t xTicksToWait; -} xTaskGenericNotifyWaitParams_t; - -typedef struct xTimerGenericCommandParams -{ - TimerHandle_t xTimer; - BaseType_t xCommandID; - TickType_t xOptionalValue; - BaseType_t * pxHigherPriorityTaskWoken; - TickType_t xTicksToWait; -} xTimerGenericCommandParams_t; - -typedef struct xEventGroupWaitBitsParams -{ - EventGroupHandle_t xEventGroup; - EventBits_t uxBitsToWaitFor; - BaseType_t xClearOnExit; - BaseType_t xWaitForAllBits; - TickType_t xTicksToWait; -} xEventGroupWaitBitsParams_t; - -/* ----------------------------------------------------------------------------------- */ - -extern TickType_t MPU_xTaskGetTickCount( void ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -/* ----------------------------------------------------------------------------------- */ - -UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -/* ----------------------------------------------------------------------------------- */ - -char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -/* ----------------------------------------------------------------------------------- */ - -void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -/* ----------------------------------------------------------------------------------- */ - -BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, - TickType_t * const pxTicksToWait ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -/* ----------------------------------------------------------------------------------- */ - -BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, - const void * const pvItemToQueue, - TickType_t xTicksToWait, - const BaseType_t xCopyPosition ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -/* ----------------------------------------------------------------------------------- */ - -UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -/* ----------------------------------------------------------------------------------- */ - -UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -/* ----------------------------------------------------------------------------------- */ - -BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, - void * const pvBuffer, - TickType_t xTicksToWait ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -/* ----------------------------------------------------------------------------------- */ - -BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, - void * const pvBuffer, - TickType_t xTicksToWait ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -/* ----------------------------------------------------------------------------------- */ - -BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -/* ----------------------------------------------------------------------------------- */ - -size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, - const void * pvTxData, - size_t xDataLengthBytes, - TickType_t xTicksToWait ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -/* ----------------------------------------------------------------------------------- */ - -size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, - void * pvRxData, - size_t xBufferLengthBytes, - TickType_t xTicksToWait ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -/* ----------------------------------------------------------------------------------- */ - -BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -/* ----------------------------------------------------------------------------------- */ - -BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -/* ----------------------------------------------------------------------------------- */ - -size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -/* ----------------------------------------------------------------------------------- */ - -size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -/* ----------------------------------------------------------------------------------- */ - -BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, - size_t xTriggerLevel ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -/* ----------------------------------------------------------------------------------- */ - -size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -/* ----------------------------------------------------------------------------------- */ - -EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToWaitFor, - const BaseType_t xClearOnExit, - const BaseType_t xWaitForAllBits, - TickType_t xTicksToWait ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -/* ----------------------------------------------------------------------------------- */ - -EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToClear ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -/* ----------------------------------------------------------------------------------- */ - -EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -/* ----------------------------------------------------------------------------------- */ - -EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet, - const EventBits_t uxBitsToWaitFor, - TickType_t xTicksToWait ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -/* ----------------------------------------------------------------------------------- */ - -#if( INCLUDE_xTaskDelayUntil == 1 ) - -BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime, - const TickType_t xTimeIncrement ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -#endif /* ( INCLUDE_xTaskDelayUntil == 1 ) */ -/* ----------------------------------------------------------------------------------- */ - -#if( INCLUDE_xTaskAbortDelay == 1 ) - -BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -#endif /* ( INCLUDE_xTaskAbortDelay == 1 ) */ -/* ----------------------------------------------------------------------------------- */ - -#if( INCLUDE_vTaskDelay == 1 ) - -void MPU_vTaskDelay( const TickType_t xTicksToDelay ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -#endif /* ( INCLUDE_vTaskDelay == 1 ) */ -/* ----------------------------------------------------------------------------------- */ - -#if( INCLUDE_uxTaskPriorityGet == 1 ) - -UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -#endif /* ( INCLUDE_uxTaskPriorityGet == 1 ) */ -/* ----------------------------------------------------------------------------------- */ - -#if( INCLUDE_eTaskGetState == 1 ) - -eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -#endif /* ( INCLUDE_eTaskGetState == 1 ) */ -/* ----------------------------------------------------------------------------------- */ - -#if( INCLUDE_xTaskGetIdleTaskHandle == 1 ) - -TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -#endif /* ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */ -/* ----------------------------------------------------------------------------------- */ - -#if( INCLUDE_vTaskSuspend == 1 ) - -void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -void MPU_vTaskResume( TaskHandle_t xTaskToResume ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -#endif /* ( INCLUDE_vTaskSuspend == 1 ) */ -/* ----------------------------------------------------------------------------------- */ - -#if( configGENERATE_RUN_TIME_STATS == 1 ) -configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - - #if( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) -configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; -configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - #endif /* ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) */ - -#endif /* ( ( configGENERATE_RUN_TIME_STATS == 1 ) */ -/* ----------------------------------------------------------------------------------- */ - -#if( configUSE_APPLICATION_TASK_TAG == 1 ) - -void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, - TaskHookFunction_t pxHookFunction ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -#endif /* ( configUSE_APPLICATION_TASK_TAG == 1 ) */ -/* ----------------------------------------------------------------------------------- */ - -#if( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) - -void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, - BaseType_t xIndex, - void * pvValue ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, - BaseType_t xIndex ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -#endif /* ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) */ -/* ----------------------------------------------------------------------------------- */ - -#if( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) - -UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -#endif /* ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) */ -/* ----------------------------------------------------------------------------------- */ - -#if( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) - -configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -#endif /* ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) */ -/* ----------------------------------------------------------------------------------- */ - -#if( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) - -TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -#endif /* ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) \ - */ -/* ----------------------------------------------------------------------------------- */ - -#if( INCLUDE_xTaskGetSchedulerState == 1 ) - -BaseType_t MPU_xTaskGetSchedulerState( void ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -#endif /* ( INCLUDE_xTaskGetSchedulerState == 1 ) */ -/* ----------------------------------------------------------------------------------- */ - -#if( configUSE_TRACE_FACILITY == 1 ) - -void MPU_vTaskGetInfo( TaskHandle_t xTask, - TaskStatus_t * pxTaskStatus, - BaseType_t xGetFreeStackSpace, - eTaskState eState ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, - const UBaseType_t uxArraySize, - configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -void MPU_vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -#endif /* ( configUSE_TRACE_FACILITY == 1 ) */ -/* ----------------------------------------------------------------------------------- */ - -#if( configUSE_TASK_NOTIFICATIONS == 1 ) - -BaseType_t MPU_xTaskGenericNotifyEntry( const xTaskGenericNotifyParams_t * pxParams ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -BaseType_t MPU_xTaskGenericNotifyWaitEntry( - const xTaskGenericNotifyWaitParams_t * pxParams ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn, - BaseType_t xClearCountOnExit, - TickType_t xTicksToWait ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask, - UBaseType_t uxIndexToClear ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask, - UBaseType_t uxIndexToClear, - uint32_t ulBitsToClear ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -#endif /* ( configUSE_TASK_NOTIFICATIONS == 1 ) */ -/* ----------------------------------------------------------------------------------- */ - -#if( configUSE_RECURSIVE_MUTEXES == 1 ) - -BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - - #if( INCLUDE_xSemaphoreGetMutexHolder == 1 ) - -TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - - #endif /* ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) */ - -#endif /* ( configUSE_RECURSIVE_MUTEXES == 1 ) */ -/* ----------------------------------------------------------------------------------- */ - -#if( configUSE_QUEUE_SETS == 1 ) - -QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, - const TickType_t xTicksToWait ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, - QueueSetHandle_t xQueueSet ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -#endif /* ( configUSE_QUEUE_SETS == 1 ) */ -/* ----------------------------------------------------------------------------------- */ - -#if( configQUEUE_REGISTRY_SIZE > 0 ) - -void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, const char * pcName ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -#endif /* ( configQUEUE_REGISTRY_SIZE > 0 ) */ -/* ----------------------------------------------------------------------------------- */ - -#if( configUSE_TIMERS == 1 ) - -void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -void MPU_vTimerSetTimerID( TimerHandle_t xTimer, void * pvNewID ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -BaseType_t MPU_xTimerGenericCommandEntry( const xTimerGenericCommandParams_t * pxParams ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, const BaseType_t uxAutoReload ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) - __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; - -#endif /* ( configUSE_TIMERS == 1 ) */ -/* ----------------------------------------------------------------------------------- */ - -#endif /* MPU_PROTOTYPES_H */ diff --git a/portable/GCC/ARM_CRx_MPU/port.c b/portable/GCC/ARM_CRx_MPU/port.c index fab89eb46d..6504c92edf 100644 --- a/portable/GCC/ARM_CRx_MPU/port.c +++ b/portable/GCC/ARM_CRx_MPU/port.c @@ -44,344 +44,335 @@ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +/* Max value that fits in a uint32_t type. */ +#define portUINT32_MAX ( ~( ( uint32_t ) 0 ) ) + +/* Check if adding a and b will result in overflow. */ +#define portADD_UINT32_WILL_OVERFLOW( a, b ) ( ( a ) > ( portUINT32_MAX - ( b ) ) ) +/* ----------------------------------------------------------------------------------- */ + /** * @brief Variable used to keep track of critical section nesting. + * * @ingroup Critical Sections - * @note - * This variable has to be stored as part of the task context and must be - * initialised to a non zero value to ensure interrupts don't inadvertently - * become unmasked before the scheduler starts. As it is stored as part of the - * task context it will be set to 0 when the first task is started. + * + * This variable is stored as part of the task context and must be initialised + * to a non zero value to ensure interrupts don't inadvertently become unmasked + * before the scheduler starts. As it is stored as part of the task context, it + * will be set to 0 when the first task is started. */ PRIVILEGED_DATA volatile UBaseType_t ulCriticalNesting = 0xFFFF; -/** @brief Set to 1 to pend a context switch from an ISR. +/** + * @brief Set to 1 to pend a context switch from an ISR. + * * @ingroup Interrupt Management */ PRIVILEGED_DATA volatile UBaseType_t ulPortYieldRequired = pdFALSE; /** * @brief Interrupt nesting depth, used to count the number of interrupts to unwind. + * * @ingroup Interrupt Management */ PRIVILEGED_DATA volatile UBaseType_t ulPortInterruptNesting = 0UL; /** * @brief Variable to track whether or not the scheduler has been started. + * * @ingroup Scheduler - * @note This is the port specific version of the Kernel's xSchedulerRunning + * + * This is the port specific version of the xSchedulerRunning in tasks.c. */ PRIVILEGED_DATA static BaseType_t prvPortSchedulerRunning = pdFALSE; /* -------------------------- Private Function Declarations -------------------------- */ /** - * @brief Determine if a FreeRTOS Task has been granted access to a memory region. - * - * @param xTaskMPURegion Pointer to a single set of MPU region registers. - * @param ulRegionStart Base address of the memory region access is being requested. - * @param ulRegionLength The length of the memory region that access is being requested. - * @param ulAccessRequested The type of access being requested, either read or write. - * @return BaseType_t pdTRUE if the task can access the region, pdFALSE otherwise + * @brief Determine if the given MPU region settings authorizes the requested + * access to the given buffer. * * @ingroup Task Context * @ingroup MPU Control + * + * @param xTaskMPURegion MPU region settings. + * @param ulBufferStart Start address of the given buffer. + * @param ulBufferLength Length of the given buffer. + * @param ulAccessRequested Access requested. + * + * @return pdTRUE if MPU region settins authorizes the requested access to the + * given buffer, pdFALSE otherwise. */ -PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( - const xMPU_REGION_REGISTERS * xTaskMPURegion, - const uint32_t ulRegionStart, - const uint32_t ulRegionLength, - const uint32_t ulAccessRequested ); +PRIVILEGED_FUNCTION static BaseType_t prvMPURegionAuthorizesBuffer( const xMPU_REGION_REGISTERS * xTaskMPURegion, + const uint32_t ulBufferStart, + const uint32_t ulBufferLength, + const uint32_t ulAccessRequested ); /** - * @brief Determine smallest MPU Region Setting for a number of bytes. + * @brief Determine the smallest MPU Region Size Encoding for the given MPU + * region size. * * @ingroup MPU Control * - * @param ulActualSizeInBytes Number of bytes to find a valid MPU region size for. - * @return uint32_t The smallest MPU region size that can hold the requested bytes. + * @param ulActualMPURegionSize MPU region size in bytes. + * + * @return The smallest MPU Region Size Encoding for the given MPU region size. */ -PRIVILEGED_FUNCTION static uint32_t prvGetMPURegionSizeSetting( - uint32_t ulActualSizeInBytes ); +PRIVILEGED_FUNCTION static uint32_t prvGetMPURegionSizeEncoding( uint32_t ulActualMPURegionSize ); -/** @brief Set up a default MPU memory Map - * @return PRIVILEGED_FUNCTION VOID +/** + * @brief Set up MPU. + * * @ingroup MPU Control - * @note This function shall be called before calling vPortStartFirstTask(). - * @note This function works by pulling variables from the linker script. - * Ensure that the variables used in your linker script match up with the variable names - * used at the start of this function. */ PRIVILEGED_FUNCTION static void prvSetupMPU( void ); +/* -------------------------- Exported Function Declarations -------------------------- */ + /** - * @brief Determine if a FreeRTOS Task has been granted access to a memory region. + * @brief Enter critical section. * - * @param xTaskMPURegion Pointer to a single set of MPU region registers. - * @param ulRegionStart Base address of the memory region access is being requested. - * @param ulRegionLength The length of the memory region that access is being requested. - * @param ulAccessRequested The type of access being requested, either read or write. - * @return BaseType_t pdTRUE if the task can access the region, pdFALSE otherwise + * @ingroup Critical Section + */ +PRIVILEGED_FUNCTION void vPortEnterCritical( void ); + +/** + * @brief Exit critical section. * - * @ingroup Task Context - * @ingroup MPU Control + * @ingroup Critical Section */ -PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( - const xMPU_REGION_REGISTERS * xTaskMPURegion, - const uint32_t ulRegionStart, - const uint32_t ulRegionLength, - const uint32_t ulAccessRequested ); +PRIVILEGED_FUNCTION void vPortExitCritical( void ); /* ----------------------------------------------------------------------------------- */ /** - * @brief Set a FreeRTOS Task's initial context. - * - * @param pxTopOfStack Pointer to where the task's stack starts. - * @param pxCode Pointer to the function a task will run. - * @param pvParameters Pointer to any arguments to be passed to the task's function. - * @param xRunPrivileged Marks if the task is to be run in a privileged CPU mode. - * @param xMPUSettings MPU settings to be loaded as part of a task's context. - * @return StackType_t* Pointer to where to restore the task's context from. + * @brief Setup a FreeRTOS task's initial context. * * @ingroup Task Context - * @note pxTopOfStack must be a region of memory that is a valid MPU region size. + * + * @param pxTopOfStack Top of stack. + * @param pxCode The task function. + * @param pvParameters Argument passed to the task function. + * @param xRunPrivileged Marks if the task is privileged. + * @param xMPUSettings MPU settings of the task. + * + * @return Location where to restore the task's context from. */ -/* PRIVILEGED_FUNCTION */ StackType_t * pxPortInitialiseStack( - StackType_t * pxTopOfStack, - TaskFunction_t pxCode, - void * pvParameters, - BaseType_t xRunPrivileged, - xMPU_SETTINGS * xMPUSettings ) +/* PRIVILEGED_FUNCTION */ +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + TaskFunction_t pxCode, + void * pvParameters, + BaseType_t xRunPrivileged, + xMPU_SETTINGS * xMPUSettings ) { - /** Setup the initial context of the task. The context is set exactly as - * expected by the portRESTORE_CONTEXT() macro and as described above the - * MAX_CONTEXT_SIZE declaration in portmacro_asm.h */ - UBaseType_t ulIndex = MAX_CONTEXT_SIZE - 1U; + /* Setup the initial context of the task. The context is set exactly as + * expected by the portRESTORE_CONTEXT() macro. */ + UBaseType_t ulIndex = CONTEXT_SIZE - 1U; xSYSTEM_CALL_STACK_INFO * xSysCallInfo = NULL; - if( pdTRUE == xRunPrivileged ) + if( xRunPrivileged == pdTRUE ) { - /* Current Program Status Register (CPSR) */ xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; + /* Current Program Status Register (CPSR). */ xMPUSettings->ulContext[ ulIndex ] = SYS_MODE; } else { - /* Current Program Status Register (CPSR) */ xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); + /* Current Program Status Register (CPSR). */ xMPUSettings->ulContext[ ulIndex ] = USER_MODE; } - if( 0x0UL != ( ( uint32_t ) pxCode & portTHUMB_MODE_ADDRESS ) ) + if( ( ( uint32_t ) pxCode & portTHUMB_MODE_ADDRESS ) != 0x0UL ) { - /* The task will start in THUMB mode, set the bit in the CPSR. */ + /* The task will cause the processor to start in THUMB state, set the + * Thumb state bit in the CPSR. */ xMPUSettings->ulContext[ ulIndex ] |= portTHUMB_MODE_BIT; } - /* Decrement ulIndex here after setting the CPSR */ ulIndex--; - /** Set Task Program Counter to provided Task Function */ - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) pxCode; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) pxCode; /* PC. */ ulIndex--; - /** A FreeRTOS Task is not designed to return or exit from its function. - * As such a default Link Register is provided that will return to an - * error handling function. */ - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) portTASK_RETURN_ADDRESS; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ ulIndex--; - /** CPU Stack Grows up, set Task's Stack Pointer's to bottom of stack */ - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) pxTopOfStack; /* SP */ + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) pxTopOfStack; /* SP. */ ulIndex--; - /* Next the General Purpose Registers */ - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x12121212; /* R12 */ - ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x11111111; /* R11 */ - ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x10101010; /* R10 */ - ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x09090909; /* R9 */ - ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x08080808; /* R8 */ - ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x07070707; /* R7 */ - ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x06060606; /* R6 */ - ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x05050505; /* R5 */ - ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x04040404; /* R4 */ - ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x03030303; /* R3 */ - ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x02020202; /* R2 */ - ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x01010101; /* R1 */ - ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) pvParameters; /* R0 */ - ulIndex--; - -#ifdef portENABLE_FPU - /* Initial Floating Point Context is the Floating Point Registers (FPRs) */ - /* There are 16 Double FPRs, D0-D15 on the Cortex-R FPU enabled chips */ - /* These map to the Single Precision FPRs, S0-S31 */ - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000015; /* S31 */ - ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1500000; /* S30 */ - ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000014; /* S29 */ - ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1400000; /* S28 */ - ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000013; /* S27 */ + /* General Purpose Registers. */ + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x12121212; /* R12. */ ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1300000; /* S26 */ + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x11111111; /* R11. */ ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000012; /* S25 */ + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x10101010; /* R10. */ ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1200000; /* S24 */ + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x09090909; /* R9. */ ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000011; /* S23 */ + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x08080808; /* R8. */ ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1100000; /* S22 */ + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x07070707; /* R7. */ ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000010; /* S21 */ + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x06060606; /* R6. */ ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1000000; /* S20 */ + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x05050505; /* R5. */ ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000009; /* S19 */ + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x04040404; /* R4. */ ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD9000000; /* S18 */ + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x03030303; /* R3. */ ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000008; /* S17 */ + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x02020202; /* R2. */ ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD8000000; /* S16 */ + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x01010101; /* R1. */ ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000007; /* S15 */ - ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD7000000; /* S14 */ - ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000006; /* S13 */ - ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD6000000; /* S12 */ - ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000005; /* S11 */ - ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD5000000; /* S10 */ - ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000004; /* S9 */ - ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD4000000; /* S8 */ - ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000003; /* S7 */ - ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD3000000; /* S6 */ - ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000002; /* S5 */ - ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD2000000; /* S4 */ - ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000001; /* S3 */ - ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1000000; /* S2 */ - ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000000; /* S1 */ - ulIndex--; - xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000000; /* S0 */ + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) pvParameters; /* R0. */ ulIndex--; - /* Floating Point Status and Control Register */ - xMPUSettings->ulContext[ ulIndex-- ] = ( StackType_t ) 0x00000000; /* FPSR */ -#endif /* portENABLE_FPU */ + #if( portENABLE_FPU == 1 ) + { + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000015; /* S31. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1500000; /* S30. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000014; /* S29. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1400000; /* S28. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000013; /* S27. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1300000; /* S26. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000012; /* S25. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1200000; /* S24. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000011; /* S23. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1100000; /* S22. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000010; /* S21. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1000000; /* S20. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000009; /* S19. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD9000000; /* S18. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000008; /* S17. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD8000000; /* S16. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000007; /* S15. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD7000000; /* S14. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000006; /* S13. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD6000000; /* S12. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000005; /* S11. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD5000000; /* S10. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000004; /* S9. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD4000000; /* S8. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000003; /* S7. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD3000000; /* S6. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000002; /* S5. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD2000000; /* S4. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000001; /* S3. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD1000000; /* S2. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000000; /* S1. */ + ulIndex--; + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0xD0000000; /* S0. */ + ulIndex--; + + xMPUSettings->ulContext[ ulIndex ] = ( StackType_t ) 0x00000000; /* FPSR. */ + ulIndex--; + } + #endif /* portENABLE_FPU */ /* The task will start with a critical nesting count of 0. */ xMPUSettings->ulContext[ ulIndex ] = portNO_CRITICAL_NESTING; /* Ensure that the system call stack is double word aligned. */ xSysCallInfo = &( xMPUSettings->xSystemCallStackInfo ); - xSysCallInfo->pulSystemCallStackPointer = &( - xSysCallInfo->ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE - 1U ] ); - - xSysCallInfo->pulSystemCallStackPointer = - ( uint32_t * ) ( ( uint32_t ) ( xSysCallInfo->pulSystemCallStackPointer ) - & ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ); + xSysCallInfo->pulSystemCallStackPointer = &( xSysCallInfo->ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE - 1U ] ); + xSysCallInfo->pulSystemCallStackPointer = ( uint32_t * ) ( ( ( uint32_t ) ( xSysCallInfo->pulSystemCallStackPointer ) ) & + ( ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) ) ); /* This is not NULL only for the duration of a system call. */ xSysCallInfo->pulTaskStackPointer = NULL; - /* Set the System Call LR to go directly to vPortSystemCallExit */ - xSysCallInfo->pulSystemCallLinkRegister = &vPortSystemCallExit; + /* Set the System Call to return to vPortSystemCallExit. */ + xSysCallInfo->pulSystemCallExitAddress = ( uint32_t * ) ( &vPortSystemCallExit ); - /* Return the address where the context of this task should be restored from */ - return ( &xMPUSettings->ulContext[ ulIndex ] ); + /* Return the address where this task's context should be restored from. */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } /* ----------------------------------------------------------------------------------- */ /** - * @brief Stores a FreeRTOS Task's MPU Settings in its TCB. - * - * @param xMPUSettings The memory location in the TCB to store MPU settings - * @param xRegions The MPU settings being requested by the task. - * @param pxBottomOfStack The base address of the Task's Stack - * @param ulStackDepth The length of the task's stack. + * @brief Store a FreeRTOS task's MPU settings in its TCB. * * @ingroup Task Context * @ingroup MPU Control * - * @note pxBottomOfStack must be aligned to a region size of length ulStackDepth. - * @note ulStackDepth must be a power of 2 larger than 32 bytes. + * @param xMPUSettings The MPU settings in TCB. + * @param xRegions The updated MPU settings requested by the task. + * @param pxBottomOfStack The base address of the task's Stack. + * @param ulStackDepth The length of the task's stack. */ -/* PRIVILEGED_FUNCTION */ void vPortStoreTaskMPUSettings( - xMPU_SETTINGS * xMPUSettings, - const struct xMEMORY_REGION * const xRegions, - StackType_t * pxBottomOfStack, - uint32_t ulStackDepth ) +/* PRIVILEGED_FUNCTION */ +void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, + const struct xMEMORY_REGION * const xRegions, + StackType_t * pxBottomOfStack, + uint32_t ulStackDepth ) { -#if defined( __ARMCC_VERSION ) + #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being + * exported from linker scripts. */ + extern uint32_t * __SRAM_segment_start__; + extern uint32_t * __SRAM_segment_end__; + #else + /* Declaration when these variable are exported from linker scripts. */ + extern uint32_t __SRAM_segment_start__[]; + extern uint32_t __SRAM_segment_end__[]; + #endif /* if defined( __ARMCC_VERSION ) */ - /* Declaration when these variable are defined in code instead of being - * exported from linker scripts. */ - extern uint32_t * __SRAM_segment_start__; - extern uint32_t * __SRAM_segment_end__; -#else - /* Declaration when these variable are exported from linker scripts. */ - extern uint32_t __SRAM_segment_start__[]; - extern uint32_t __SRAM_segment_end__[]; - -#endif /* if defined( __ARMCC_VERSION ) */ uint32_t ulIndex = 0x0; - uint32_t ulRegionStart; - uint32_t ulRegionEnd; - uint32_t ulRegionLen; - uint32_t ulAlignment; - - /* Allow Read/Write from User and Privileged modes */ - uint32_t ulRegionAttr = portMPU_PRIV_RW_USER_RW_NOEXEC - | portMPU_NORMAL_OIWTNOWA_SHARED; + uint32_t ulRegionLength; + uint32_t ulRegionLengthEncoded; + uint32_t ulRegionLengthDecoded; - if( NULL == xRegions ) + if( xRegions == NULL ) { /* No MPU regions are specified so allow access to all of the RAM. */ - ulRegionStart = ( uint32_t ) __SRAM_segment_start__; - ulRegionEnd = ( uint32_t ) __SRAM_segment_end__; - ulRegionLen = ulRegionEnd - ulRegionStart; - ulRegionLen = prvGetMPURegionSizeSetting( ulRegionLen ); - ulRegionLen |= portMPU_REGION_ENABLE; - - /* MPU Settings is zero'd out in the TCB before reaching this function. - * Set this region as the highest configurable MPU Region so it overrides - * the lower unused regions. - */ - ulIndex = portNUM_CONFIGURABLE_REGIONS; - - xMPUSettings->xRegion[ ulIndex ].ulRegionBaseAddress = ulRegionStart; - xMPUSettings->xRegion[ ulIndex ].ulRegionSize = ulRegionLen; - xMPUSettings->xRegion[ ulIndex ].ulRegionAttribute = ulRegionAttr; + ulRegionLength = ( uint32_t ) __SRAM_segment_end__ - ( uint32_t ) __SRAM_segment_start__; + ulRegionLengthEncoded = prvGetMPURegionSizeEncoding( ulRegionLength ); + ulRegionLength |= portMPU_REGION_ENABLE; + + /* MPU Settings is zero'd out in the TCB before this function is called. + * We, therefore, do not need to explicitly zero out unused MPU regions + * in xMPUSettings. */ + ulIndex = portSTACK_REGION; + + xMPUSettings->xRegion[ ulIndex ].ulRegionBaseAddress = ( uint32_t ) __SRAM_segment_start__; + xMPUSettings->xRegion[ ulIndex ].ulRegionSize = ( ulRegionLengthEncoded | + portMPU_REGION_ENABLE ); + xMPUSettings->xRegion[ ulIndex ].ulRegionAttribute = ( portMPU_REGION_PRIV_RW_USER_RW_NOEXEC | + portMPU_REGION_NORMAL_OIWTNOWA_SHARED ); } else { @@ -390,81 +381,61 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( /* If a length has been provided, the region is in use. */ if( ( xRegions[ ulIndex ] ).ulLengthInBytes > 0UL ) { - ulRegionStart = ( uint32_t ) xRegions[ ulIndex ].pvBaseAddress; - ulRegionAttr = xRegions[ ulIndex ].ulParameters; - - ulRegionLen = xRegions[ ulIndex ].ulLengthInBytes; - ulRegionLen = prvGetMPURegionSizeSetting( ulRegionLen ); - ulRegionLen |= portMPU_REGION_ENABLE; - - /* MPU Regions must be aligned to a power of 2 equal to length */ - ulAlignment = 2UL << ( ulRegionLen >> 1UL ); - configASSERT( 0U == ( ulRegionStart % 2UL ) ); - configASSERT( 0U == ( ulRegionStart % ( ulAlignment ) ) ); + ulRegionLength = xRegions[ ulIndex ].ulLengthInBytes; + ulRegionLengthEncoded = prvGetMPURegionSizeEncoding( ulRegionLength ); + + /* MPU region base address must be aligned to the region size + * boundary. */ + ulRegionLengthDecoded = 2UL << ( ulRegionLengthEncoded >> 1UL ); + configASSERT( ( ( ( uint32_t ) xRegions[ ulIndex ].pvBaseAddress ) % ( ulRegionLengthDecoded ) ) == 0UL ); + + xMPUSettings->xRegion[ ulIndex ].ulRegionBaseAddress = ( uint32_t ) xRegions[ ulIndex ].pvBaseAddress; + xMPUSettings->xRegion[ ulIndex ].ulRegionSize = ( ulRegionLengthEncoded | + portMPU_REGION_ENABLE ); + xMPUSettings->xRegion[ ulIndex ].ulRegionAttribute = xRegions[ ulIndex ].ulParameters; } else { - /* Otherwise ensure the region is zero'd out */ - ulRegionStart = 0x0UL; - ulRegionLen = 0x0UL; - ulRegionAttr = 0x0UL; + xMPUSettings->xRegion[ ulIndex ].ulRegionBaseAddress = 0x0UL; + xMPUSettings->xRegion[ ulIndex ].ulRegionSize = 0x0UL; + xMPUSettings->xRegion[ ulIndex ].ulRegionAttribute = 0x0UL; } - - xMPUSettings->xRegion[ ulIndex ].ulRegionBaseAddress = ulRegionStart; - xMPUSettings->xRegion[ ulIndex ].ulRegionSize = ulRegionLen; - xMPUSettings->xRegion[ ulIndex ].ulRegionAttribute = ulRegionAttr; } + /* This function is called automatically when the task is created - in * which case the stack region parameters will be valid. At all other * times the stack parameters will not be valid and it is assumed that the * stack region has already been configured. */ - - /* Cannot have a task stack of size 0 */ - if( 0x0UL != ulStackDepth ) + if( ulStackDepth != 0x0UL ) { - /* Define the region that allows access to the stack. */ - ulRegionStart = ( uint32_t ) pxBottomOfStack; - ulRegionAttr = portMPU_PRIV_RW_USER_RW_NOEXEC - | portMPU_NORMAL_OIWTNOWA_SHARED; - ulRegionLen = prvGetMPURegionSizeSetting( ulStackDepth << 2UL ); - ulRegionLen |= portMPU_REGION_ENABLE; - - /* MPU Regions must be aligned to a power of 2 equal to length */ - ulAlignment = 2UL << ( ulRegionLen >> 1UL ); - configASSERT( 0U == ( ulRegionStart % 2UL ) ); - configASSERT( 0U == ( ulRegionStart % ( ulAlignment ) ) ); - - /* xRegion[portNUM_CONFIGURABLE_REGIONS] is the Task Stack */ - ulIndex = portNUM_CONFIGURABLE_REGIONS; - - xMPUSettings->xRegion[ ulIndex ].ulRegionBaseAddress = ulRegionStart; - xMPUSettings->xRegion[ ulIndex ].ulRegionSize = ulRegionLen; - xMPUSettings->xRegion[ ulIndex ].ulRegionAttribute = ulRegionAttr; + ulRegionLengthEncoded = prvGetMPURegionSizeEncoding( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ); + + /* MPU region base address must be aligned to the region size + * boundary. */ + ulRegionLengthDecoded = 2UL << ( ulRegionLengthEncoded >> 1UL ); + configASSERT( ( ( uint32_t ) pxBottomOfStack % ( ulRegionLengthDecoded ) ) == 0U ); + + ulIndex = portSTACK_REGION; + xMPUSettings->xRegion[ ulIndex ].ulRegionBaseAddress = ( uint32_t ) pxBottomOfStack; + xMPUSettings->xRegion[ ulIndex ].ulRegionSize = ( ulRegionLengthEncoded | + portMPU_REGION_ENABLE );; + xMPUSettings->xRegion[ ulIndex ].ulRegionAttribute = ( portMPU_REGION_PRIV_RW_USER_RW_NOEXEC | + portMPU_REGION_NORMAL_OIWTNOWA_SHARED ); } } } /* ----------------------------------------------------------------------------------- */ -/** - * @brief Determine if the FreeRTOS Task was created as a privileged task. - * - * @ingroup MPU Control - * @ingroup Task Context - * - * @return pdTRUE if the Task was created as a privileged task. - * pdFALSE if the task was not created as a privileged task. - * - */ -/* PRIVILEGED_FUNCTION */ BaseType_t xPortIsTaskPrivileged( void ) +/* PRIVILEGED_FUNCTION */ +BaseType_t xPortIsTaskPrivileged( void ) { BaseType_t xTaskIsPrivileged = pdFALSE; /* Calling task's MPU settings. */ const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); - if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) - == portTASK_IS_PRIVILEGED_FLAG ) + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) { xTaskIsPrivileged = pdTRUE; } @@ -472,29 +443,20 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( return xTaskIsPrivileged; } -/** - * @brief Start the System Tick Timer, starting the FreeRTOS-Kernel. - * - * @ingroup Scheduler - * @return BaseType_t This function is not meant to be returned from. - * If it does return it returns pdFALSE to mark that the scheduler - * could not be started. - */ -/* PRIVILEGED_FUNCTION */ BaseType_t xPortStartScheduler( void ) +/* ----------------------------------------------------------------------------------- */ + +/* PRIVILEGED_FUNCTION */ +BaseType_t xPortStartScheduler( void ) { /* Start the timer that generates the tick ISR. */ configSETUP_TICK_INTERRUPT(); - /* Reset the critical section nesting count read to execute the first task. */ - ulCriticalNesting = 0UL; - - /* Configure the regions in the MPU that are common to all tasks. */ + /* Configure MPU regions that are common to all tasks. */ prvSetupMPU(); - /* Mark the port specific scheduler running variable as true */ prvPortSchedulerRunning = pdTRUE; - /* Load the context of the first task, starting the FreeRTOS-Scheduler's control. */ + /* Load the context of the first task. */ vPortStartFirstTask(); /* Will only get here if vTaskStartScheduler() was called with the CPU in @@ -508,15 +470,15 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( /* ----------------------------------------------------------------------------------- */ -/* PRIVILEGED_FUNCTION */ static uint32_t prvGetMPURegionSizeSetting( - uint32_t ulActualSizeInBytes ) +/* PRIVILEGED_FUNCTION */ +static uint32_t prvGetMPURegionSizeEncoding( uint32_t ulActualMPURegionSize ) { uint32_t ulRegionSize, ulReturnValue = 4U; - /* 32 bytes is the smallest valid region for Cortex R4 and R5 CPUs */ + /* 32 bytes is the smallest valid region for Cortex R4 and R5 CPUs. */ for( ulRegionSize = 0x20UL; ulReturnValue < 0x1FUL; ( ulRegionSize <<= 1UL ) ) { - if( ulActualSizeInBytes <= ulRegionSize ) + if( ulActualMPURegionSize <= ulRegionSize ) { break; } @@ -533,181 +495,172 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( /* ----------------------------------------------------------------------------------- */ -/* PRIVILEGED_FUNCTION */ static void prvSetupMPU( void ) +/* PRIVILEGED_FUNCTION */ +static void prvSetupMPU( void ) { #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code. */ - /* Sections used for FLASH */ + /* Sections used for FLASH. */ extern uint32_t * __FLASH_segment_start__; extern uint32_t * __FLASH_segment_end__; extern uint32_t * __privileged_functions_start__; extern uint32_t * __privileged_functions_end__; - /* Sections used for RAM */ + /* Sections used for RAM. */ extern uint32_t * __SRAM_segment_start__; extern uint32_t * __SRAM_segment_end__; extern uint32_t * __privileged_data_start__; extern uint32_t * __privileged_data_end__; - #else /* Declaration when these variable are exported from linker scripts. */ - /* Sections used for FLASH */ + /* Sections used for FLASH. */ extern uint32_t __FLASH_segment_start__[]; extern uint32_t __FLASH_segment_end__[]; extern uint32_t __privileged_functions_start__[]; extern uint32_t __privileged_functions_end__[]; - /* Sections used for RAM */ + /* Sections used for RAM. */ extern uint32_t __SRAM_segment_start__[]; extern uint32_t __SRAM_segment_end__[]; extern uint32_t __privileged_data_start__[]; extern uint32_t __privileged_data_end__[]; - #endif /* if defined( __ARMCC_VERSION ) */ - uint32_t ulRegionStart; - uint32_t ulRegionEnd; + uint32_t ulRegionLength; + uint32_t ulRegionLengthEncoded; - /* Ensure the MPU is disabled */ + /* Disable the MPU before programming it. */ vMPUDisable(); - /* Unprivileged and Privileged Read and Exec MPU Region for Flash */ - ulRegionStart = ( uint32_t ) __FLASH_segment_start__; - ulRegionEnd = ( uint32_t ) __FLASH_segment_end__; - ulRegionLength = ulRegionEnd - ulRegionStart; - ulRegionLength = prvGetMPURegionSizeSetting( ulRegionLength ); - ulRegionLength |= portMPU_REGION_ENABLE; - + /* Priv: RX, Unpriv: RX for entire Flash. */ + ulRegionLength = ( uint32_t ) __FLASH_segment_end__ - ( uint32_t ) __FLASH_segment_start__; + ulRegionLengthEncoded = prvGetMPURegionSizeEncoding( ulRegionLength ); vMPUSetRegion( portUNPRIVILEGED_FLASH_REGION, - ulRegionStart, - ulRegionLength, - portMPU_PRIV_RO_USER_RO_EXEC | portMPU_NORMAL_OIWTNOWA_SHARED ); - - /* Privileged Read and Exec MPU Region for PRIVILEGED_FUNCTIONS. */ - ulRegionStart = ( uint32_t ) __privileged_functions_start__; - ulRegionEnd = ( uint32_t ) __privileged_functions_end__; - ulRegionLength = ulRegionEnd - ulRegionStart; - ulRegionLength = prvGetMPURegionSizeSetting( ulRegionLength ); - ulRegionLength |= portMPU_REGION_ENABLE; - + ( uint32_t ) __FLASH_segment_start__, + ( ulRegionLengthEncoded | portMPU_REGION_ENABLE ), + ( portMPU_REGION_PRIV_RO_USER_RO_EXEC | + portMPU_REGION_NORMAL_OIWTNOWA_SHARED ) ); + + /* Priv: RX, Unpriv: No access for privileged functions. */ + ulRegionLength = ( uint32_t ) __privileged_functions_end__ - ( uint32_t ) __privileged_functions_start__; + ulRegionLengthEncoded = prvGetMPURegionSizeEncoding( ulRegionLength ); vMPUSetRegion( portPRIVILEGED_FLASH_REGION, - ulRegionStart, - ulRegionLength, - portMPU_PRIV_RO_USER_NA_EXEC | portMPU_NORMAL_OIWTNOWA_SHARED ); - - /* Privileged Write and Read Access for PRIVILEGED_DATA. */ - ulRegionStart = ( uint32_t ) __privileged_data_start__; - ulRegionEnd = ( uint32_t ) __privileged_data_end__; - ulRegionLength = ulRegionEnd - ulRegionStart; - ulRegionLength = prvGetMPURegionSizeSetting( ulRegionLength ); - ulRegionLength |= portMPU_REGION_ENABLE; - + ( uint32_t ) __privileged_functions_start__, + ( ulRegionLengthEncoded | portMPU_REGION_ENABLE ), + ( portMPU_REGION_PRIV_RO_USER_NA_EXEC | + portMPU_REGION_NORMAL_OIWTNOWA_SHARED ) ); + + /* Priv: RW, Unpriv: No Access for privileged data. */ + ulRegionLength = ( uint32_t ) __privileged_data_end__ - ( uint32_t ) __privileged_data_start__; + ulRegionLengthEncoded = prvGetMPURegionSizeEncoding( ulRegionLength ); vMPUSetRegion( portPRIVILEGED_RAM_REGION, - ulRegionStart, - ulRegionLength, - portMPU_PRIV_RW_USER_NA_NOEXEC | portMPU_NORMAL_OIWTNOWA_SHARED ); + ( uint32_t ) __privileged_data_start__, + ( ulRegionLengthEncoded | portMPU_REGION_ENABLE ), + ( portMPU_REGION_PRIV_RW_USER_NA_NOEXEC | + portMPU_REGION_PRIV_RW_USER_NA_NOEXEC ) ); - /* Enable the MPU Background region, allows privileged operating modes access to - * unmapped regions of memory without generating a fault. */ + /* Enable the MPU background region - it allows privileged operating modes + * access to unmapped regions of memory without generating a fault. */ vMPUEnableBackgroundRegion(); - /* After setting default regions, enable the MPU */ + /* After setting default regions, enable the MPU. */ vMPUEnable(); } /* ----------------------------------------------------------------------------------- */ -/* PRIVILEGED_FUNCTION */ static BaseType_t prvTaskCanAccessRegion( - const xMPU_REGION_REGISTERS * xTaskMPURegion, - const uint32_t ulRegionStart, - const uint32_t ulRegionLength, - const uint32_t ulAccessRequested ) +/* PRIVILEGED_FUNCTION */ +static BaseType_t prvMPURegionAuthorizesBuffer( const xMPU_REGION_REGISTERS * xTaskMPURegion, + const uint32_t ulBufferStart, + const uint32_t ulBufferLength, + const uint32_t ulAccessRequested ) { - BaseType_t xAccessGranted; - uint32_t ulRegionEnd = ulRegionStart + ulRegionLength; - - /* Get Region Size value in words, need to clear the enable bit */ - uint32_t ulTaskRegionLength = 2UL << ( xTaskMPURegion->ulRegionSize >> 1UL ); - uint32_t ulTaskRegionEnd = xTaskMPURegion->ulRegionBaseAddress + ulTaskRegionLength; - - /* Perform three different checks: - * 1. Ensure region being accessed is after the start of an MPU Region - * 2. Ensure region being accessed is before the end of the MPU Region - * 3. Ensure region being accessed ends after the start of the MPU region */ - if( ( ulRegionStart >= xTaskMPURegion->ulRegionBaseAddress ) - && ( ulRegionEnd <= ulTaskRegionEnd ) && ( ulRegionEnd >= ulRegionStart ) ) + BaseType_t xAccessGranted = pdFALSE; + uint32_t ulBufferEnd; + uint32_t ulMPURegionLength; + uint32_t ulMPURegionStart; + uint32_t ulMPURegionEnd; + uint32_t ulMPURegionAccessPermissions; + + if( portADD_UINT32_WILL_OVERFLOW( ulBufferStart, ( ulBufferLength - 1UL ) ) == pdFALSE ) { - /* Unprivileged read is MPU Ctrl Access Bit Value bX1X */ - if( ( tskMPU_READ_PERMISSION == ulAccessRequested ) - && ( ( portMPU_PRIV_RW_USER_RO_NOEXEC ) &xTaskMPURegion->ulRegionAttribute ) ) + ulBufferEnd = ulBufferStart + ulBufferLength - 1UL; + ulMPURegionLength = 2UL << ( xTaskMPURegion->ulRegionSize >> 1UL ); + ulMPURegionStart = xTaskMPURegion->ulRegionBaseAddress; + ulMPURegionEnd = xTaskMPURegion->ulRegionBaseAddress + ulMPURegionLength - 1UL; + + if( ( ulBufferStart >= ulMPURegionStart ) && + ( ulBufferEnd <= ulMPURegionEnd ) && + ( ulBufferStart <= ulBufferEnd ) ) { - xAccessGranted = pdTRUE; - } + ulMPURegionAccessPermissions = xTaskMPURegion->ulRegionAttribute & portMPU_REGION_AP_BITMASK; - /* Unprivileged Write is MPU Ctrl Access Bit Value b011 */ - else if( ( tskMPU_WRITE_PERMISSION & ulAccessRequested ) - && ( xTaskMPURegion->ulRegionAttribute & portMPU_PRIV_RW_USER_RW_NOEXEC ) - == ( portMPU_PRIV_RW_USER_RW_NOEXEC ) ) - { - xAccessGranted = pdTRUE; - } - - else - { - xAccessGranted = pdFALSE; + if( ulAccessRequested == tskMPU_READ_PERMISSION ) /* RO. */ + { + if( ( ulMPURegionAccessPermissions == portMPU_REGION_PRIV_RW_USER_RO ) || + ( ulMPURegionAccessPermissions == portMPU_REGION_PRIV_RO_USER_RO ) ) + { + xAccessGranted = pdTRUE; + } + } + else if( ( ulAccessRequested & tskMPU_WRITE_PERMISSION ) != 0UL ) /* W or RW. */ + { + if( ulMPURegionAccessPermissions == portMPU_REGION_PRIV_RW_USER_RW ) + { + xAccessGranted = pdTRUE; + } + } } } - else - { - xAccessGranted = pdFALSE; - } return xAccessGranted; } /* ----------------------------------------------------------------------------------- */ -/* PRIVILEGED_FUNCTION */ BaseType_t xPortIsAuthorizedToAccessBuffer( - const void * pvBuffer, - uint32_t ulBufferLength, - uint32_t ulAccessRequested ) +/* PRIVILEGED_FUNCTION */ +BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, + uint32_t ulBufferLength, + uint32_t ulAccessRequested ) { - BaseType_t xAccessGranted; - - /* Calling task's MPU settings. */ + BaseType_t xAccessGranted = pdFALSE; + uint32_t ulRegionIndex; xMPU_SETTINGS * xTaskMPUSettings = NULL; - xMPU_REGION_REGISTERS * xTaskMPURegion = NULL; - if( pdFALSE == prvPortSchedulerRunning ) + if( prvPortSchedulerRunning == pdFALSE ) { - /* Before the scheduler starts an unknown task will be pxCurrentTCB */ + /* Grant access to all the memory before the scheduler is started. It is + * necessary because there is no task running yet and therefore, we + * cannot use the permissions of any task. */ xAccessGranted = pdTRUE; } else { - /* Only way to receive a NULL here is if no task has been created, - * but the scheduler has been started. */ + /* Calling task's MPU settings. */ xTaskMPUSettings = xTaskGetMPUSettings( NULL ); - if( xTaskMPUSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) + if( ( xTaskMPUSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) { - /* If a task is privileged it is assumed that it can access the buffer */ + /* Privileged tasks have access to all the memory. */ xAccessGranted = pdTRUE; } else { - uint32_t ulRegionIndex = 0x0UL; - do + for( ulRegionIndex = 0x0UL; ulRegionIndex < portTOTAL_NUM_REGIONS_IN_TCB; ulRegionIndex++ ) { - xTaskMPURegion = &( xTaskMPUSettings->xRegion[ ulRegionIndex++ ] ); - xAccessGranted = prvTaskCanAccessRegion( xTaskMPURegion, - ( uint32_t ) pvBuffer, - ulBufferLength, - ulAccessRequested ); - } while( ( ulRegionIndex < portTOTAL_NUM_REGIONS_IN_TCB ) - && ( pdFALSE == xAccessGranted ) ); + xAccessGranted = prvMPURegionAuthorizesBuffer( &( xTaskMPUSettings->xRegion[ ulRegionIndex ] ), + ( uint32_t ) pvBuffer, + ulBufferLength, + ulAccessRequested ); + + if( xAccessGranted == pdTRUE ) + { + break; + } + } } } + return xAccessGranted; } @@ -715,14 +668,14 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( #if( configENABLE_ACCESS_CONTROL_LIST == 1 ) -/* PRIVILEGED_FUNCTION */ BaseType_t xPortIsAuthorizedToAccessKernelObject( - int32_t lInternalIndexOfKernelObject ) +/* PRIVILEGED_FUNCTION */ +BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) { uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; BaseType_t xAccessGranted = pdFALSE; const xMPU_SETTINGS * xTaskMpuSettings; - if( pdFALSE == prvPortSchedulerRunning ) + if( prvPortSchedulerRunning == pdFALSE ) { /* Grant access to all the kernel objects before the scheduler * is started. It is necessary because there is no task running @@ -740,16 +693,14 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); - if( portTASK_IS_PRIVILEGED_FLAG - == ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) ) + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) { xAccessGranted = pdTRUE; } else { - if( ( 1U << ulAccessControlListEntryBit ) - & ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] ) - != 0UL ) + if( ( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] ) & + ( 1U << ulAccessControlListEntryBit ) ) != 0UL ) { xAccessGranted = pdTRUE; } @@ -759,9 +710,27 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( return xAccessGranted; } -/* PRIVILEGED_FUNCTION */ void vPortGrantAccessToKernelObject( - TaskHandle_t xInternalTaskHandle, - int32_t lInternalIndexOfKernelObject ) +#else + +/* PRIVILEGED_FUNCTION */ +BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) +{ + ( void ) lInternalIndexOfKernelObject; + + /* If Access Control List feature is not used, all the tasks have + * access to all the kernel objects. */ + return pdTRUE; +} + +#endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + +/* ----------------------------------------------------------------------------------- */ + +#if( configENABLE_ACCESS_CONTROL_LIST == 1 ) + +/* PRIVILEGED_FUNCTION */ +void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) { uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; xMPU_SETTINGS * xTaskMpuSettings; @@ -773,13 +742,18 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); - xTaskMpuSettings->ulAccessControlList - [ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit ); + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit ); } -/* PRIVILEGED_FUNCTION */ void vPortRevokeAccessToKernelObject( - TaskHandle_t xInternalTaskHandle, - int32_t lInternalIndexOfKernelObject ) +#endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + +/* ----------------------------------------------------------------------------------- */ + +#if( configENABLE_ACCESS_CONTROL_LIST == 1 ) + +/* PRIVILEGED_FUNCTION */ +void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) { uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; xMPU_SETTINGS * xTaskMpuSettings; @@ -791,20 +765,7 @@ PRIVILEGED_FUNCTION static BaseType_t prvTaskCanAccessRegion( xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); - xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( - 1U << ulAccessControlListEntryBit ); -} - -#else - -/* PRIVILEGED_FUNCTION */ BaseType_t xPortIsAuthorizedToAccessKernelObject( - int32_t lInternalIndexOfKernelObject ) -{ - ( void ) lInternalIndexOfKernelObject; - - /* If Access Control List feature is not used, all the tasks have - * access to all the kernel objects. */ - return pdTRUE; + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit ); } #endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ @@ -831,9 +792,52 @@ void prvTaskExitError( void ) void vPortEndScheduler( void ) { prvPortSchedulerRunning = pdFALSE; - /* Not implemented in ports where there is nothing to return to. - * Artificially force an assert. */ - configASSERT( prvPortSchedulerRunning ); + + /* Not implemented in this port. Artificially force an assert. */ + configASSERT( prvPortSchedulerRunning == pdTRUE ); } /* ----------------------------------------------------------------------------------- */ + +/* PRIVILEGED_FUNCTION */ +void vPortEnterCritical( void ) +{ + portDISABLE_INTERRUPTS(); + + /* Now that interrupts are disabled, ulCriticalNesting can be accessed + * directly. Increment ulCriticalNesting to keep a count of how many times + * portENTER_CRITICAL() has been called. */ + ulCriticalNesting++; + + /* This is not the interrupt safe version of the enter critical function so + * assert() if it is being called from an interrupt context. Only API + * functions that end in "FromISR" can be used in an interrupt. Only assert + * if the critical nesting count is 1 to protect against recursive calls if + * the assert function also uses a critical section. */ + if( ulCriticalNesting == 1 ) + { + configASSERT( ulPortInterruptNesting == 0 ); + } +} +/*-----------------------------------------------------------*/ + +/* PRIVILEGED_FUNCTION */ +void vPortExitCritical( void ) +{ + if( ulCriticalNesting > portNO_CRITICAL_NESTING ) + { + /* Decrement the nesting count as the critical section is being + * exited. */ + ulCriticalNesting--; + + /* If the nesting level has reached zero then all interrupt + * priorities must be re-enabled. */ + if( ulCriticalNesting == portNO_CRITICAL_NESTING ) + { + /* Critical nesting has reached zero so all interrupt priorities + * should be unmasked. */ + portENABLE_INTERRUPTS(); + } + } +} +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CRx_MPU/portASM.S b/portable/GCC/ARM_CRx_MPU/portASM.S index 5ebc8b2b0f..b9cb955402 100644 --- a/portable/GCC/ARM_CRx_MPU/portASM.S +++ b/portable/GCC/ARM_CRx_MPU/portASM.S @@ -28,8 +28,6 @@ .arm .syntax unified - /* All code in the portASM.S file is intended to be run from a prvileged - * operating mode, as such mark the entire file as privileged_functions */ .section privileged_functions #define FREERTOS_ASSEMBLY @@ -37,583 +35,464 @@ #include "mpu_syscall_numbers.h" #undef FREERTOS_ASSEMBLY - /* External FreeRTOS-Kernel Variables */ + /* External FreeRTOS-Kernel variables. */ .extern pxCurrentTCB .extern uxSystemCallImplementations .extern ulPortInterruptNesting .extern ulPortYieldRequired - /* External Linker script variables that are needed by the port */ - .extern __privileged_functions_start__ - .extern __privileged_functions_end__ - .extern __privileged_stacks_start__ - .extern __privileged_stacks_end__ - .extern __syscalls_flash_length__ + /* External Llnker script variables. */ .extern __syscalls_flash_start__ .extern __syscalls_flash_end__ - /* External FreeRTOS-Kernel Functions */ - .extern vAssertCalled + /* External FreeRTOS-Kernel functions. */ .extern vTaskSwitchContext .extern vApplicationIRQHandler /* ----------------------------------------------------------------------------------- */ -/* Save the register context of a FreeRTOS Task. */ + +/* Save the context of a FreeRTOS Task. */ .macro portSAVE_CONTEXT DSB ISB - /* Push R0 and the Link Register (LR) for scratch register space */ + /* Push R0 and LR to the stack for current mode. */ PUSH { R0, LR } - /* Load the pointer to the current task's Task Control Block (TCB) */ - LDR LR, =pxCurrentTCB - /* Load the actual TCB into LR */ - LDR LR, [LR] - /* Set LR to pxTopOfStack, the address of where to save the task context */ - LDR LR, [LR] - - /* Load the address of ulCriticalNesting */ - LDR R0, =ulCriticalNesting - /* Load the value of ulCriticalNesting into R0 */ - LDR R0, [R0] - /* Push the value of ulCriticalNesting into the context, auto-increment the - * LR by using the ! operator. */ - STM LR!, { R0 } + + LDR LR, =pxCurrentTCB /* LR = &( pxCurrentTCB ). */ + LDR LR, [LR] /* LR = pxCurrentTCB. */ + LDR LR, [LR] /* LR = pxTopOfStack i.e. the address where to store the task context. */ + + LDR R0, =ulCriticalNesting /* R0 = &( ulCriticalNesting ). */ + LDR R0, [R0] /* R0 = ulCriticalNesting. */ + STM LR!, { R0 } /* Store ulCriticalNesting. ! increments LR after storing. */ #if ( portENABLE_FPU == 1 ) - /* Save the floating point context */ - /* Copy the Floating Point Status and Control Register (FPSRC) */ - FMRX R0, FPSCR - /* Push the value of FPSCR onto the stack */ - STM LR!, { R0 } - /* Push the 32 Floating Point Registers (FPRs) onto the stack */ - VSTM LR!, { D0-D15 } + VMRS R0, FPSCR /* R0 = FPSCR. */ + STM LR!, { R0 } /* Store FPSCR. */ + VSTM LR!, { D0-D15 } /* Store D0-D15. */ #endif /* ( portENABLE_FPU == 1 ) */ - /* Restore the saved register */ - POP { R0 } - /* Save the General Purpose Registers (GPRs). Also save the pre-exception - * Stack Pointer (SP) and LR. The ^ operator causes this instruction to store - * the mode selected in the Saved Program Status Register (SPSR) */ + POP { R0 } /* Restore R0 to pre-exception value. */ + /* STM (user registers) - In a PL1 mode other than System mode, STM (user + * registers) instruction stores multiple User mode registers to + * consecutive memory locations using an address from a base register. The + * processor reads the base register value normally, using the current mode + * to determine the correct Banked version of the register. This instruction + * cannot writeback to the base register. + * + * The following can be derived from the above description: + * - The macro portSAVE_CONTEXT MUST be called from a PL1 mode other than + * the System mode. + * - Base register LR of the current mode will be used which contains the + * location to store the context. + * - It will store R0-R14 of User mode i.e. pre-exception SP(R13) and LR(R14) + * will be stored. */ STM LR, { R0-R14 }^ - /* Not allowed to auto-increment with ! when using banked registers */ - ADD LR, LR, #portREGISTER_LENGTH - /* Pop the pushed LR, which is the pre-exception Program Counter (PC) */ - POP { R0 } - /* Copy the pre-exception Current Program Status Register (CPSR), which, - * is banked as the SPSR and save it as part of the task context */ - MRS R1, SPSR - /* Store the pre-exception CPSR and PC */ - STM LR!, { R0-R1 } + ADD LR, LR, #60 /* R0-R14 - Total 155 register, each 4 byte wide. */ + + POP { R0 } /* Pre-exception PC is in R0. */ + MRS R1, SPSR /* R1 = Pre-exception CPSR. */ + STM LR!, { R0-R1 } /* Store pre-exception PC and CPSR. */ .endm /* ----------------------------------------------------------------------------------- */ -/* Restore the register context of a FreeRTOS Task. */ + +/* Restore the context of a FreeRTOS Task. */ .macro portRESTORE_CONTEXT - /* Load the pointer to the current task's Task Control Block (TCB) */ - LDR LR, =pxCurrentTCB - /* Load the actual TCB into LR */ - LDR LR, [LR] - /* Set R1 to the second member of the TCB struct, xMPUSettings */ - ADD R1, LR, #0x4 - /* Set LR to pxTopOfStack, the address to restore the task context from */ - LDR LR, [LR] - /* Load the first per-task MPU region into R5 */ - MOV R5, #portFIRST_CONFIGURABLE_REGION + /* Load the pointer to the current task's Task Control Block (TCB). */ + LDR LR, =pxCurrentTCB /* LR = &( pxCurrentTCB ). */ + LDR LR, [LR] /* LR = pxCurrentTCB. */ + ADD R1, LR, #0x4 /* R1 now points to the xMPUSettings in TCB. */ + LDR LR, [LR] /* LR = pxTopOfStack i.e. the address where to restore the task context from. */ + /* When creating a loop label in a macro it has to be a numeric label. * for( R5 = portFIRST_CONFIGURABLE_REGION ; R5 <= portNUM_CONFIGURABLE_REGIONS ; R5++ ) */ + MOV R5, #portFIRST_CONFIGURABLE_REGION 123: - /* Load values of struct MPU_REGION_REGISTERS into R2-R4 */ - LDMIA R1!, { R2-R4 } - /* Load the values set in xMPU_REGION_REGISTERS - * R2 Will hold ulRegionSize - * R3 will hold ulRegionAttribute - * R4 will hold ulRegionBaseAddress - * R5 will hold the MPU Region number */ - - /* Select the MPU Region using R5 */ - MCR p15, #0, R5, c6, c2, #0 - /* Set the MPU Region Base Address using ulRegionBaseAddress */ - MCR p15, #0, R4, c6, c1, #0 - /* Set the MPU Region Access Attributes using ulRegionAttribute */ - MCR p15, #0, R3, c6, c1, #4 - /* Set the MPU Region Size, and if the region is enabled using ulRegionSize */ - MCR p15, #0, R2, c6, c1, #2 - /* R5++ */ + LDMIA R1!, { R2-R4 } /* R2 = ulRegionSize, R3 = ulRegionAttribute, R4 = ulRegionBaseAddress. */ + + MCR p15, #0, R5, c6, c2, #0 /* MPU Region Number Register. */ + MCR p15, #0, R4, c6, c1, #0 /* MPU Region Base Address Register. */ + MCR p15, #0, R3, c6, c1, #4 /* MPU Region Access Control Register. */ + MCR p15, #0, R2, c6, c1, #2 /* MPU Region Size and Enable Register. */ + ADD R5, R5, #1 - /* R5 <= R6 */ CMP R5, #portNUM_CONFIGURABLE_REGIONS - /* R5 <= R6, loop again */ BLE 123b - /* R5 > portSTACK_REGION, all MPU regions have been restored */ - /* Load the address of the ulCriticalNesting variable into R1 */ - LDR R1, =ulCriticalNesting - /* Pop the previously saved value of ulCriticalNesting from ulContext */ - LDM LR!, { R2 } - /* Store the value of ulCriticalNesting into address of ulCriticalNesting */ - STR R2, [R1] + LDR R1, =ulCriticalNesting /* R1 = &( ulCriticalNesting ). */ + LDM LR!, { R2 } /* R2 = Stored ulCriticalNesting. */ + STR R2, [R1] /* Restore ulCriticalNesting. */ #if ( portENABLE_FPU == 1 ) - /* Restore Floating Point Context: Restore previous FPSCR from ulContext */ - LDM LR!, { R1 } - /* Move the saved FPSCR value into the FPSCR */ - VMSR FPSCR, R1 - /* Restore the Floating Point Registers */ - VLDM LR!, { D0-D15 } + LDM LR!, { R1 } /* R1 = Stored FPSCR. */ + VMSR FPSCR, R1 /* Restore FPSCR. */ + VLDM LR!, { D0-D15 } /* Restore D0-D15. */ #endif /* portENABLE_FPU*/ - /* Load the value of the CPSR into R0, needed to set the SP and the LR */ - LDR R0, [LR, +#(portREGISTER_LENGTH + 4UL)] - /* Move the CPSR the into our SPSR */ - MSR SPSR_cxsf, R0 - /* Restore the saved Stack Pointer and Link Register into User Mode */ + /* LDM (User registers) - In a PL1 mode other than System mode, LDM (User + * registers) loads multiple User mode registers from consecutive memory + * locations using an address from a base register. The registers loaded + * cannot include the PC. The processor reads the base register value + * normally, using the current mode to determine the correct Banked version + * of the register. This instruction cannot writeback to the base register. + * + * The following can be derived from the above description: + * - The macro portRESTORE_CONTEXT MUST be called from a PL1 mode other than + * the System mode. + * - Base register LR of the current mode will be used which contains the + * location to restore the context from. + * - It will restore R0-R14 of User mode i.e. SP(R13) and LR(R14) of User + * mode will be restored. + */ LDM LR, { R0-R14 }^ - /* Not allowed to auto-increment with ! when using banked registers */ - ADD LR, LR, #portREGISTER_LENGTH - /* Load the PC to return from the exception */ - RFE LR + ADD LR, LR, #60 /* R0-R14 - Total 155 register, each 4 byte wide. */ + + RFE LR /* Restore PC and CPSR from the context. */ .endm /* ----------------------------------------------------------------------------------- */ -/* Load the context of the first task, starting the FreeRTOS-Scheduler */ + +/* + * void vPortStartFirstTask( void ); + */ .align 4 .global vPortStartFirstTask .type vPortStartFirstTask, %function vPortStartFirstTask: - /** This function is called from System Mode to start the FreeRTOS-Kernel. - * This is done by restoring the context of the first task. - * Restoring the context of a task will allow interrupts. - * This allows the FreeRTOS Scheduler Tick to start, and therefore - * starts the FreeRTOS-Kernel. - */ - /* Swap to SVC Mode for context restore */ + /* This function is called from System Mode to start the FreeRTOS-Kernel. + * As described in the portRESTORE_CONTEXT macro, portRESTORE_CONTEXT cannot + * be called from the System mode. We, therefore, switch to the Supervisor + * mode before calling portRESTORE_CONTEXT. */ CPS #SVC_MODE - /* Load the context of first task, starting the FreeRTOS-Scheduler */ portRESTORE_CONTEXT /* ----------------------------------------------------------------------------------- */ -/* Handler for Supervisor Calls (SVCs) when using this FreeRTOS Port - * Upon entering here the LR, or R14, will hold the address of the following - * instruction. This then checks that instruction for the SVC # raised. - * Checks: - * 1. SVC is raised from the system call section (i.e. application is - * not raising SVC directly). - * 2. pxMpuSettings->xSystemCallStackInfo.pulTaskStack must be NULL as - * it is non-NULL only during the execution of a system call (i.e. - * between system call enter and exit). - * 3. System call is not for a kernel API disabled by the configuration - * in FreeRTOSConfig.h. - * 4. We do not need to check that ucSystemCallNumber is within range - * because the assembly SVC handler checks that before calling - * this function. - */ + .align 4 .global FreeRTOS_SVC_Handler .type FreeRTOS_SVC_Handler, %function FreeRTOS_SVC_Handler: - /* Push R11-R12 for scratch space */ PUSH { R11-R12 } /* ------------------------- Caller Flash Location Check ------------------------- */ - /* The address of the caller will be in the Link Register (LR), it will - * be the caller's Program Counter (PC). Check this address to ensure the - * Supervisor call (SVC) was raised from inside the FreRTOS-Kernel. */ - - /* Get the starting address for FreeRTOS System Calls */ - LDR R12, =__syscalls_flash_start__ - /* Subtract the start point from the Program Counter of the caller */ - SUB R11, LR, R12 - /* Now check if it is less than the length of the section */ - LDR R12, =__syscalls_flash_length__ - /* Check if an SVC was raised after the end of FreeRTOS System Calls */ - CMP R11, R12 - /* If the SVC was raised from outside FreeRTOS System Calls exit now */ - BGE SVC_Handler_Exit + LDR R11, =__syscalls_flash_start__ + LDR R12, =__syscalls_flash_end__ + CMP LR, R11 /* If SVC instruction address is less than __syscalls_flash_start__, exit. */ + BLT svcHandlerExit + CMP LR, R12 /* If SVC instruction address is greater than __syscalls_flash_end__, exit. */ + BGT svcHandlerExit /* ---------------------------- Get Caller SVC Number ---------------------------- */ - /* The SPSR will be the CPSR of the calling task, store it in R11 */ - MRS R11, SPSR - /* Thumb Mode is bit 5 of the CPSR, AND for comparison */ - ANDS R11, R11, #0x20 - /* In Thumb Mode, the instruction 0x2 before holds the SVC numebr */ - LDRHNE R11, [LR, #-0x2] - /* Not in Thumb Mode, the instruction 0x4 before holds the SVC numebr */ - LDRHEQ R11, [LR, #-0x4] + MRS R11, SPSR /* LR = CPSR at the time of SVC. */ + TST R11, #0x20 /* Check Thumb bit (5) in CPSR. */ + LDRHNE R11, [LR, #-0x2] /* If Thumb, load halfword. */ + BICNE R11, R11, #0xFF00 /* And extract immidiate field (i.e. SVC number). */ + LDREQ R11, [LR, #-0x4] /* If ARM, load word. */ + BICEQ R11, R11, #0xFF000000 /* And extract immidiate field (i.e. SVC number). */ /* --------------------------------- SVC Routing --------------------------------- */ - /* Determine if the SVC number is below #NUM_SYSTEM_CALLS */ + /* If SVC Number < #NUM_SYSTEM_CALLS, go to svcSystemCallEnter. */ CMP R11, #NUM_SYSTEM_CALLS - /* If it is go to the entry point for FreeRTOS System Calls */ BLT svcSystemCallEnter - /* Check if the caller is leaving a FreeRTOS System Call */ + /* If SVC Number == #portSVC_SYSTEM_CALL_EXIT, go to svcSystemCallExit. */ CMP R11, #portSVC_SYSTEM_CALL_EXIT BEQ svcSystemCallExit - /* Check if the caller is requesting to yield */ + /* If SVC Number == #portSVC_YIELD, go to svcPortYield. */ CMP R11, #portSVC_YIELD BEQ svcPortYield - /* If one of the above jumps wasn't taken, go straight to the exit */ -SVC_Handler_Exit: - /** Restore the saved R11 and R12, then return to the caller */ +svcHandlerExit: POP { R11-R12 } - /* This instruction loads the SPSR into the CPSR, performing the mode swap */ - MOVS PC, LR + MOVS PC, LR /* Copies the SPSR into the CPSR, performing the mode swap. */ -/* Perform a task swap */ svcPortYield: - /* Restore the previously saved R11, R12 */ POP { R11-R12 } - /* Save the context of the current task and select a new task to run. */ portSAVE_CONTEXT - /* Select a new task to swap to */ BL vTaskSwitchContext - /* Restore the context of the task selected to execute. */ portRESTORE_CONTEXT -/* Reset task stack and link register after a FreeRTOS System Call */ svcSystemCallExit: - /* Restore the Task Stack Pointer and Link Register */ - /* Load the address of pxCurrentTCB into R11 */ - LDR R11, =pxCurrentTCB - /* Load pxCurrentTCB into R11 */ - LDR R11, [R11] - /* Set R11 to be the location of xSystemCallStackInfo inside the TCB */ - ADD R11, R11, #portSYSTEM_CALL_INFO_OFFSET - /* Restore the user mode Stack Pointer and Link Register */ - LDMIB R11, { R13-R14 }^ - /* Zero out R12 so we can set ulTaskStackPointer back to NULL */ - AND R12, R12, #0x0 - /* Set pulTaskStackPointer to be 0x0 */ - STR R12, [R11, #0x4] - /* Set pulLinkRegisterAtSystemCallEntry to be 0x0 */ - STR R12, [R11, #0x8] - /* Load the ulTaskFlag so we can determine if we're going to lower privilege */ - LDM R11, { R12 } - /* Check if the task is privileged */ - CMP R12, #portTASK_IS_PRIVILEGED_FLAG - /* If the task is privileged we can leave now */ - BEQ SVC_Handler_Exit - /* Otherwise, we need to set the SPSR back to USER mode */ + LDR R11, =pxCurrentTCB /* R11 = &( pxCurrentTCB ). */ + LDR R11, [R11] /* R11 = pxCurrentTCB. */ + ADD R11, R11, #portSYSTEM_CALL_INFO_OFFSET /* R11 now points to xSystemCallStackInfo in TCB. */ + + /* Restore the user mode SP and LR. */ + LDM R11, { R13-R14 }^ + + AND R12, R12, #0x0 /* R12 = 0. */ + STR R12, [R11] /* xSystemCallStackInfo.pulTaskStackPointer = NULL. */ + STR R12, [R11, #0x4] /* xSystemCallStackInfo.pulLinkRegisterAtSystemCallEntry = NULL. */ + + LDMDB R11, { R12 } /* R12 = ulTaskFlags. */ + + TST R12, #portTASK_IS_PRIVILEGED_FLAG + /* If the task is privileged, we can exit now. */ + BNE svcHandlerExit + /* Otherwise, we need to switch back to User mode. */ MRS R12, SPSR - /* Clear the last 4 bits, which are the MODE bits */ BIC R12, R12, #0x0F - /* Move the new value into the SPSR */ MSR SPSR_cxsf, R12 - /* Jump back */ - B SVC_Handler_Exit -/* Save task's SP and LR, swap to ulSystemCallStack Buffer, raise privilege */ + B svcHandlerExit + svcSystemCallEnter: - /* Load the base address of the uxSystemCallImplementations[] table into R14 */ - LDR R14, =uxSystemCallImplementations - - /** Shift the value of R11, the SVC number, left by two to get the jump offset - * Add this offset to R14, which holds the jump table address. This is the address - * of the SVC that the relevant function is trying to complete. - * Now when the Link Register is loaded as the Program Counter at the end of this - * handler, the caller will immediately execute the requested function */ - LDR R14, [R14, R11, lsl #2] - - /* Load the address of pxCurrentTCB into R11 */ - LDR R11, =pxCurrentTCB - /* Load pxCurrentTCB into R11 */ - LDR R11, [R11] - /* Set R11 to be the location of xSystemCallStackInfo inside the TCB */ - ADD R11, R11, #portSYSTEM_CALL_INFO_OFFSET - /* Get the value in the TCB for ulTaskStackPointer */ - LDMIB R11!, { R12 } - /* Ensure ulTaskStackPointer is null, signifying initial entry */ - TEQ R12, #0x0 - /* Make sure that the function pointer loaded is not NULL */ - CMPEQ R14, #0x0 - - /* Hard code the ascii value of the function name and line number to call - * assert if the ulTaskStackPointer is not null. */ - MOVWEQ R0, #0x706F - MOVTEQ R0, #0x7274 - MOVEQ R1, #342 - BEQ vAssertCalled - - /* Store the task's SP and LR to xSYSTEM_CALL_STACK_INFO */ + LDR R12, =uxSystemCallImplementations /* R12 = uxSystemCallImplementations. */ + /* R12 = uxSystemCallImplementations[ R12 + ( R11 << 2 ) ]. + * R12 now contains the address of the system call impl function. */ + LDR R12, [R12, R11, lsl #2] + + /* If R12 == NULL, exit. */ + CMP R12, #0x0 + BEQ svcHandlerExit + + /* It is okay to clobber LR here because we do not need to return to the + * SVC enter location anymore. LR now contains the address of the system + * call impl function. */ + MOV LR, R12 + + LDR R11, =pxCurrentTCB /* R11 = &( pxCurrentTCB ). */ + LDR R11, [R11] /* R11 = pxCurrentTCB. */ + ADD R11, R11, #portSYSTEM_CALL_INFO_OFFSET /* R11 now points to xSystemCallStackInfo in TCB. */ + + /* Store User mode SP and LR in xSystemCallStackInfo.pulTaskStackPointer and + * xSystemCallStackInfo.pulLinkRegisterAtSystemCallEntry. */ STM R11, { R13-R14 }^ - /* Not allowed to auto-increment with ! when using banked registers */ ADD R11, R11, 0x8 - /* Load pulSystemCallStackPointer and pulSystemCallLinkRegister now */ + + /* Load User mode SP an LR with xSystemCallStackInfo.pulSystemCallStackPointer + * and xSystemCallStackInfo.pulSystemCallExitAddress. */ LDM R11, { R13-R14 }^ - /* Swap the SPSR to SYS_MODE for the System Call. Move SPSR into R12 */ + /* Change to SYS_MODE for the System Call. */ MRS R12, SPSR - /* Set the MODE bits to SYS_MODE */ ORR R12, R12, #SYS_MODE - /* Assign the new value to SPSR */ MSR SPSR_cxsf, R12 - /* Leave through the SVC Exit */ - B SVC_Handler_Exit -/* ----------------------------------------------------------------------------------- */ -/* Disable IRQs and increment the critical nesting count */ -.align 4 -.global vPortEnterCritical -.type vPortEnterCritical, %function -vPortEnterCritical: - /* Disable IRQs */ - CPSID I - /* Save scratch registers */ - PUSH { R0-R1 } - /* Load address of current critical nesting count */ - LDR R0, =ulCriticalNesting - /* Load value of current critical nesting count */ - LDR R1, [R0] - /* Add one to ulCriticalNesting */ - ADD R1, R1, #1 - /* Store the modified ulCriticalNesting back into RAM */ - STR R1, [R0] - /* Restore pushed registers */ - POP { R0-R1 } - /* Return to caller */ - BX LR + B svcHandlerExit /* ----------------------------------------------------------------------------------- */ -/* Disable IRQs */ + +/* + * void vPortDisableInterrupts( void ); + */ .align 4 .global vPortDisableInterrupts .type vPortDisableInterrupts, %function vPortDisableInterrupts: - /* Disable IRQs */ CPSID I - /* Return to caller */ BX LR /* ----------------------------------------------------------------------------------- */ -/* Enable IRQs and decrement the critical nesting count */ -.align 4 -.global vPortExitCritical -.type vPortExitCritical, %function -vPortExitCritical: - /* Store two scratch registers and LR for IRQ Mode re-entry */ - PUSH { R0-R1, LR } - /* Load address of current critical nesting count */ - LDR R0, =ulCriticalNesting - /* Load value of current critical nesting count */ - LDR R1, [R0] - /* Check if the count is 0 */ - CMP R1, #0 - /* If ulCriticalNesting is greater than 0, Subtract 1 from it */ - SUBGT R1, R1, #1 - /* Store the modified ulCriticalNesting back into RAM */ - STRGT R1, [R0] - /* Enable IRQs */ - CPSIE I - /* Restore Pushed registers */ - POP { R0-R1, LR } - /* Return to caller */ - BX LR -/* ----------------------------------------------------------------------------------- */ -/* Enable IRQs */ +/* + * void vPortEnableInterrupts( void ); + */ .align 4 .global vPortEnableInterrupts .type vPortEnableInterrupts, %function vPortEnableInterrupts: - /* Push LR to account for re-entry in IRQ Mode */ - PUSH { LR } - /* Enable IRQs */ CPSIE I - /* Restore previous LR */ - POP { LR } - /* Return to caller */ BX LR /* ----------------------------------------------------------------------------------- */ -/** Set MPU Registers using provided values - * Function: void vMPUSetRegion - * Inputs: uint32_t ulRegionNumber - * Inputs: uint32_t ulBaseAddress - * Inputs: uint32_t ulRegionSize - * Inputs: uint32_t ulRegionPermissions -*/ + +/* + * void vMPUSetRegion( uint32_t ulRegionNumber, + * uint32_t ulBaseAddress, + * uint32_t ulRegionSize, + * uint32_t ulRegionPermissions ); + * + * According to the Procedure Call Standard for the ARM Architecture (AAPCS), + * paramters are passed in the following registers: + * R0 = ulRegionNumber. + * R1 = ulBaseAddress. + * R2 = ulRegionSize. + * R3 = ulRegionPermissions. + */ .align 4 .global vMPUSetRegion .type vMPUSetRegion, %function vMPUSetRegion: - /* Only 15 possible regions, drop all other bits */ - AND R0, R0, #15 - /* Select the MPU Region selected by ulRegionNumber */ - MCR p15, #0, R0, c6, c2, #0 - /* Set the Base Address to be ulBaseAddress */ - MCR p15, #0, R1, c6, c1, #0 - /* Set the Access Attributes to be ulRegionPermissions */ - MCR p15, #0, R3, c6, c1, #4 - /* Set the Size and Enable bits to be ulRegionSize */ - MCR p15, #0, R2, c6, c1, #2 - /* Return to caller */ + AND R0, R0, #0x0F /* R0 = R0 & 0x0F. Max possible region number is 15. */ + + MCR p15, #0, R0, c6, c2, #0 /* MPU Region Number Register. */ + MCR p15, #0, R1, c6, c1, #0 /* MPU Region Base Address Register. */ + MCR p15, #0, R3, c6, c1, #4 /* MPU Region Access Control Register. */ + MCR p15, #0, R2, c6, c1, #2 /* MPU Region Size and Enable Register. */ + BX LR /* ----------------------------------------------------------------------------------- */ -/* Set the Enable bit of the MPU Enable Register to 1. */ + +/* + * void vMPUEnable( void ); + */ .align 4 .global vMPUEnable .type vMPUEnable, %function vMPUEnable: - /* Read the current MPU control register into R0 */ - MRC p15, #0, R0, c1, c0, #0 - /* Set the enable bit to high */ - ORR R0, R0, #0x1 - /* Data sync */ + PUSH { R0 } + + MRC p15, #0, R0, c1, c0, #0 /* R0 = System Control Register (SCTLR). */ + ORR R0, R0, #0x1 /* R0 = R0 | 0x1. Set the M bit in SCTLR. */ DSB - /* Write out previous MPU control register with a high enable bit */ - MCR p15, #0, R0, c1, c0, #0 - /* Instruction sync */ + MCR p15, #0, R0, c1, c0, #0 /* SCTLR = R0. */ ISB - /* Return to caller */ + + POP { R0 } BX LR /* ----------------------------------------------------------------------------------- */ -/* Set the Enable bit of the MPU Enable Register to 0. */ + +/* + * void vMPUDisable( void ); + */ .align 4 .global vMPUDisable .type vMPUDisable, %function vMPUDisable: - /* Read the MPU enable register values into R0 */ - MRC p15, #0, R0, c1, c0, #0 - /* Perform a bitwise AND of R0 and NOT #1, i.e. clear bit 1 */ - BIC R0, R0, #1 - /* Wait for all pending explicit data accesses to complete */ + PUSH { R0 } + + MRC p15, #0, R0, c1, c0, #0 /* R0 = System Control Register (SCTLR). */ + BIC R0, R0, #1 /* R0 = R0 & ~0x1. Clear the M bit in SCTLR. */ + /* Wait for all pending data accesses to complete. */ DSB - /* Write out to the MPU Enable Register */ - MCR p15, #0, R0, c1, c0, #0 - /* Flushes the pipeline and prefetch buffer(s) in the processor. */ - /* Ensures all following instructions are fetched from cache or memory. */ + MCR p15, #0, R0, c1, c0, #0 /* SCTLR = R0. */ + /* Flush the pipeline and prefetch buffer(s) in the processor to ensure that + * all following instructions are fetched from cache or memory. */ ISB - /* Return to caller */ + + POP { R0 } BX LR /* ----------------------------------------------------------------------------------- */ -/* Enable the MPU Background Region */ + +/* + * void vMPUEnableBackgroundRegion( void ); + */ .align 4 .global vMPUEnableBackgroundRegion .type vMPUEnableBackgroundRegion, %function vMPUEnableBackgroundRegion: - /* Save value in R0 */ PUSH { R0 } - /* Read CP15 System Control Register into R0 */ - MRC p15, 0, R0, c1, c0, 0 - /* Set bit 17 so that privileged modes won't trigger unmapped MPU region faults */ - ORR R0, R0, #0x20000 - /* Write the value back out */ - MCR p15, 0, R0, c1, c0, 0 - /* Restore the used register */ + + MRC p15, #0, R0, c1, c0, #0 /* R0 = System Control Register (SCTLR). */ + ORR R0, R0, #0x20000 /* R0 = R0 | 0x20000. Set the BR bit in SCTLR. */ + MCR p15, #0, R0, c1, c0, #0 /* SCTLR = R0. */ + POP { R0 } - /* Return to the caller */ BX LR /* ----------------------------------------------------------------------------------- */ -/* Disable the MPU Background Region */ + +/* + * void vMPUDisableBackgroundRegion( void ); + */ .align 4 .global vMPUDisableBackgroundRegion .type vMPUDisableBackgroundRegion, %function vMPUDisableBackgroundRegion: - /* Save value in R0 */ PUSH { R0 } - /* Read CP15 System Control Register into R0 */ - MRC p15, 0, R0, c1, c0, 0 - /* Clear bit 17 so that privileged modes won't trigger unmapped MPU region faults */ - BIC R0, R0, #0x20000 - /* Write the value back out */ - MCR p15, 0, R0, c1, c0, 0 - /* Restore the used register */ + + MRC p15, 0, R0, c1, c0, 0 /* R0 = System Control Register (SCTLR). */ + BIC R0, R0, #0x20000 /* R0 = R0 & ~0x20000. Clear the BR bit in SCTLR. */ + MCR p15, 0, R0, c1, c0, 0 /* SCTLR = R0. */ + POP { R0 } - /* Return to the caller */ BX LR /* ----------------------------------------------------------------------------------- */ + .align 4 .global FreeRTOS_IRQ_Handler .type FreeRTOS_IRQ_Handler, %function FreeRTOS_IRQ_Handler: - /* Disable IRQs */ - CPSID I - /* Return to the interrupted instruction. */ - SUB LR, LR, #4 - /* Save the return state to the IRQ stack */ - SRSDB SP!, #IRQ_MODE - /* Push used registers. */ - PUSH { R0-R3, R12 } - - /* Load &ulPortInterruptNesting into R0 */ - LDR R0, =ulPortInterruptNesting - /* Load the value of ulPortInterruptNesting into R1 */ - LDR R1, [R0] - /* R2 = ulPortInterruptNesting + 1 */ - ADD R2, R1, #1 - /* Store the value of ulPortInterruptNesting++ back into the variable */ - STR R2, [R0] - - /* Save Calling Registers */ + SUB LR, LR, #4 /* Return to the interrupted instruction. */ + SRSDB SP!, #IRQ_MODE /* Save return state (i.e. SPSR_irq and LR_irq) to the IRQ stack. */ + + /* Change to supervisor mode to allow reentry. It is necessary to ensure + * that a BL instruction within the interrupt handler code does not + * overwrite LR_irq. */ + CPS #SVC_MODE + + PUSH { R0-R3, R12 } /* Push AAPCS callee saved registers. */ + + /* Update interrupt nesting count. */ + LDR R0, =ulPortInterruptNesting /* R0 = &( ulPortInterruptNesting ). */ + LDR R1, [R0] /* R1 = ulPortInterruptNesting. */ + ADD R2, R1, #1 /* R2 = R1 + 1. */ + STR R2, [R0] /* Store the updated nesting count. */ + + /* Call the application provided IRQ handler. */ PUSH { R0-R3, LR } - /* Call the User provided IRQ handler */ BL vApplicationIRQHandler + POP { R0-R3, LR } - /* Disable IRQs incase vApplicationIRQHandler enabled them for re-entry */ - CPSID I - /* Perform a data and instruction buffer flush */ + /* Disable IRQs incase vApplicationIRQHandler enabled them for re-entry. */ + CPSID I DSB ISB - /* Restore the previous registers */ - POP { R0-R3, LR } - /* R0 holds the address of ulPortInterruptNesting, R1 holds original value */ + /* Restore the old interrupt nesting count. R0 holds the address of + * ulPortInterruptNesting and R1 holds original value of + * ulPortInterruptNesting. */ STR R1, [R0] - /* Check if ulPortInterruptNesting is 0 */ + + /* Context swtich is only performed when interrupt nesting count is 0. */ CMP R1, #0 - /* If ulPortInterruptNesting is not zero, unwind the nested interrupt */ BNE exit_without_switch - /* ulPortInterruptNesting is zero, check if ulPortYieldRequired is set */ - LDR R1, =ulPortYieldRequired - /* Load the value of ulPortYieldRequired */ - LDR R0, [R1] - /* Check if the value of ulPortYieldRequired is zero */ + /* Check ulPortInterruptNesting to see if the interrupt requested a context + * switch. */ + LDR R1, =ulPortYieldRequired /* R1 = &( ulPortYieldRequired ). */ + LDR R0, [R1] /* R0 = ulPortYieldRequired. */ + /* If ulPortYieldRequired != 0, goto switch_before_exit. */ CMP R0, #0 - /* If it is non-zero select a new task to run */ BNE switch_before_exit exit_without_switch: - /* No context switch. Restore used registers, LR_irq and SPSR before returning. */ - POP { R0-R3, R12 } - /* Return from exception, load pre-exception PC and CPSR */ + POP { R0-R3, R12 } /* Restore AAPCS callee saved registers. */ + CPS #IRQ_MODE RFE SP! switch_before_exit: - /* A context swtich is to be performed. Clear the context switch pending flag. */ + /* A context swtich is to be performed. Clear ulPortYieldRequired. R1 holds + * the address of ulPortYieldRequired. */ MOV R0, #0 - /* Set ulPortYieldRequired back to zero */ STR R0, [R1] - /* Restore used registers, LR_irq and SPSR before saving the context */ + /* Restore AAPCS callee saved registers, SPSR_irq and LR_irq before saving + * the task context. */ POP { R0-R3, R12 } - /* Load the pushed SPSR from the stack */ + CPS #IRQ_MODE + /* The contents of the IRQ stack at this point is the following: + * +----------+ + * SP+4 | SPSR_irq | + * +----------+ + * SP | LR_irq | + * +----------+ + */ LDMIB SP!, { LR } - /* Move it into the SPSR */ MSR SPSR_cxsf, LR - /* Load the pushed pre-exception Program Counter into LR_irq */ LDMDB SP, { LR } - /* Increment the Stack Pointer an additional 0x4 */ ADD SP, SP, 0x4 - /* Save the current task's context */ portSAVE_CONTEXT /* Call the function that selects the new task to execute. */ BLX vTaskSwitchContext - /* Restore the context of the selected task, which will start executing. */ + /* Restore the context of, and branch to, the task selected to execute + * next. */ portRESTORE_CONTEXT +/* ----------------------------------------------------------------------------------- */ + .end diff --git a/portable/GCC/ARM_CRx_MPU/portmacro.h b/portable/GCC/ARM_CRx_MPU/portmacro.h index 7ef2119046..6d0eea568b 100644 --- a/portable/GCC/ARM_CRx_MPU/portmacro.h +++ b/portable/GCC/ARM_CRx_MPU/portmacro.h @@ -40,45 +40,29 @@ extern "C" { #endif -/* Include stdint for integer types of specific bit widths */ +/* Include stdint for integer types of specific bit widths. */ #include /* ------------------------------ FreeRTOS Config Check ------------------------------ */ -/* Include the FreeRTOS Config file first to get the includes being used */ -#include "FreeRTOSConfig.h" - -#ifndef configENABLE_MPU - #define configENABLE_MPU 1 -#elif( configENABLE_MPU != 1 ) - #error "This port is only usable with configENABLE_MPU set to 1" -#endif /* configENABLE_MPU */ - -#ifndef configENABLE_ACCESS_CONTROL_LIST - #define configENABLE_ACCESS_CONTROL_LIST 1 -#endif /* configENABLE_ACCESS_CONTROL_LIST */ - -#ifndef configPROTECTED_KERNEL_OBJECT_POOL_SIZE - #error "Set configPROTECTED_KERNEL_OBJECT_POOL_SIZE to at least the " \ - "number of FreeRTOS-Kernel Objects to be created" -#endif /* configPROTECTED_KERNEL_OBJECT_POOL_SIZE */ - -/** - * @brief The size in Bytes that the Privileged System Call Stack should be. - * - * @ingroup MPU Privilege - * - * @note A Stack of this length, in bytes, is used by FreeRTOS APIs when called - * by an unprivileged task. - */ #ifndef configSYSTEM_CALL_STACK_SIZE #error "Define configSYSTEM_CALL_STACK_SIZE to a length, in bytes, " \ "to use when an unprivileged task makes a FreeRTOS Kernel call. " #endif /* configSYSTEM_CALL_STACK_SIZE */ +#if( configUSE_MPU_WRAPPERS_V1 == 1 ) + #error This port is usable with MPU wrappers V2 only. +#endif /* configUSE_MPU_WRAPPERS_V1 */ + +#ifndef configSETUP_TICK_INTERRUPT + #error "configSETUP_TICK_INTERRUPT() must be defined in FreeRTOSConfig.h " \ + "to call the function that sets up the tick interrupt." +#endif /* configSETUP_TICK_INTERRUPT */ + /* ----------------------------------------------------------------------------------- */ #if( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 ) + /* Check the configuration. */ #if( configMAX_PRIORITIES > 32 ) #error "configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when " \ @@ -88,115 +72,95 @@ extern "C" { #endif /* ( configMAX_PRIORITIES > 32 ) */ /** - * @brief Mark that a task of the current priority is ready for execution. + * @brief Mark that a task of the given priority is ready. * * @ingroup Scheduler * - * @param[in] uxPriority Priority of task that can enter the ready state - * @param[out] uxTopReadyPriority Bitmap of tasks that are in the ready state + * @param[in] uxPriority Priority of the task that is ready. + * @param[in] uxTopReadyPriority Bitmap of the ready tasks priorities. */ #define portRECORD_READY_PRIORITY( uxPriority, uxTopReadyPriority ) \ ( uxTopReadyPriority ) |= ( 1UL << ( uxPriority ) ) /** - * @brief Mark that a task of the current priority has left the ready state. + * @brief Mark that a task of the given priority is no longer ready. * * @ingroup Scheduler * - * @param[in] uxPriority Priority of task that is leaving the ready state - * @param[out] uxTopReadyPriority Bitmap of tasks that are in the ready state + * @param[in] uxPriority Priority of the task that is no longer ready. + * @param[in] uxTopReadyPriority Bitmap of the ready tasks priorities. */ #define portRESET_READY_PRIORITY( uxPriority, uxTopReadyPriority ) \ ( uxTopReadyPriority ) &= ~( 1UL << ( uxPriority ) ) /** - * @brief Determine what the highest priority ready task is. + * @brief Determine the highest priority ready task's priority. * * @ingroup Scheduler * - * @param[out] uxTopReadyPriority Bitmap of tasks that are in the ready state - * @param[out] uxTopPriority The highest priority ready task's priority value. + * @param[in] uxTopReadyPriority Bitmap of the ready tasks priorities. + * @param[in] uxTopPriority The highest priority ready task's priority. */ #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxTopReadyPriority ) \ - uxTopPriority = ( 31UL - ulPortCountLeadingZeros( ( uxTopReadyPriority ) ) ) + ( uxTopPriority ) = ( 31UL - ulPortCountLeadingZeros( ( uxTopReadyPriority ) ) ) #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ -#ifndef configSETUP_TICK_INTERRUPT - #error "configSETUP_TICK_INTERRUPT() must be defined in FreeRTOSConfig.h " \ - "to call the function that sets up the tick interrupt." -#endif /* configSETUP_TICK_INTERRUPT */ - -#if( configUSE_TICKLESS_IDLE != 0 ) - #error This port does not support tickless idle -#endif /* ( configUSE_TICKLESS_IDLE != 0 ) */ - /* ------------------------------ Port Type Definitions ------------------------------ */ #include "portmacro_asm.h" /** - * @brief Critical section nesting value to mark the end of a critical section. + * @brief Critical section nesting value. * * @ingroup Critical Sections * - * @note - * A critical section is exited when the critical section nesting count reaches - * this value. When exiting a critical section IRQs are re-enabled. + * A task exits critical section and enables IRQs when its nesting count reaches + * this value. */ #define portNO_CRITICAL_NESTING ( ( uint32_t ) 0x0 ) /** - * @brief Bit value used to mark if the CPU is currently executing in Thumb Mode. + * @brief Bit in Current Program Status Register (CPSR) to indicate that CPU is + * in Thumb State. + * * @ingroup Task Context */ #define portTHUMB_MODE_BIT ( ( StackType_t ) 0x20 ) /** - * @brief Value used to check if a task's function is a Thumb function. + * @brief Bitmask to check if an address is of Thumb Code. + * * @ingroup Task Context */ #define portTHUMB_MODE_ADDRESS ( 0x01UL ) /** - * @brief Unsigned Data type equal to the data word operating size of the CPU. + * @brief Data type used to represent a stack word. * * @ingroup Port Interface Specifications - * - * @note - * The FreeRTOS-Kernel needs to be able to use an unsigned type that is - * the most efficient, natural type for the targeted architecture. */ typedef uint32_t StackType_t; /** - * @brief Signed Data type equal to the data word operating size of the CPU. + * @brief Signed data type equal to the data word operating size of the CPU. * * @ingroup Port Interface Specifications - * - * @note - * The FreeRTOS-Kernel needs to be able to use a signed type that is - * the most efficient, natural type for the targeted architecture. */ typedef int32_t BaseType_t; /** - * @brief Unsigned Data type equal to the data word operating size of the CPU. + * @brief Unsigned data type equal to the data word operating size of the CPU. * * @ingroup Port Interface Specifications - * - * @note - * The FreeRTOS-Kernel needs to be able to use an unsigned type that is - * the most efficient, natural type for the targeted architecture. */ typedef uint32_t UBaseType_t; /** - * @brief Integer type used for the Tick Counter. + * @brief Data type used for the FreeRTOS Tick Counter. * - * @note - * Use a 32-bit tick type on a 32-bit architecture, so reads of the tick count - * do not need to be guarded with a critical section. + * @note Using 32-bit tick type on a 32-bit architecture ensures that reads of + * the tick count do not need to be guarded with a critical section. */ typedef uint32_t TickType_t; @@ -204,15 +168,13 @@ typedef uint32_t TickType_t; * @brief Marks the direction the stack grows on the targeted CPU. * * @ingroup Port Interface Specifications - * */ #define portSTACK_GROWTH ( -1 ) /** - * @brief Specifies at what number of bytes a stack pointer shall be aligned. + * @brief Specifies stack pointer alignment requirements of the target CPU. * * @ingroup Port Interface Specifications - * */ #define portBYTE_ALIGNMENT 8U @@ -221,9 +183,8 @@ typedef uint32_t TickType_t; * * @ingroup Port Interface Specifications * - * @note - * These are not required for this port but included in case common demo code - * that uses these macros is used. + * @note This is not required for this port but included in case common demo + * code uses it. */ #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) \ void vFunction( void * pvParameters ) @@ -233,46 +194,49 @@ typedef uint32_t TickType_t; * * @ingroup Port Interface Specifications * - * @note - * These are not required for this port but included in case common demo code - * that uses these macros is used. + * @note This is not required for this port but included in case common demo + * code uses it. */ -#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) +#define portTASK_FUNCTION( vFunction, pvParameters ) \ + void vFunction( void * pvParameters ) /** - * @brief Wrapper for the no-op ARM Assembly Instruction. + * @brief The no-op ARM assembly instruction. + * * @ingroup Port Interface Specifications */ #define portNOP() __asm volatile( "NOP" ) /** - * @brief Wrapper for the Inline GCC Label. + * @brief The inline GCC label. + * * @ingroup Port Interface Specifications */ #define portINLINE __inline /** - * @brief Wrapper for the ARM Memory Sync Assembly Instruction. + * @brief The memory access synchronization barrier. + * * @ingroup Port Interface Specifications */ #define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" ) /** - * @brief Defines if the system tick count can be accessed atomically. + * @brief Defines if the tick count can be accessed atomically. * * @ingroup System Clock */ #define portTICK_TYPE_IS_ATOMIC 1 /** - * @brief Define the number of miliseconds between system ticks. + * @brief The number of miliseconds between system ticks. * * @ingroup System Clock */ #define portTICK_PERIOD_MS ( ( TickType_t ) 1000UL / configTICK_RATE_HZ ) /** - * @brief Define the larges possible delay value for a task. + * @brief The largest possible delay value for any FreeRTOS API. * * @ingroup System Clock */ @@ -280,88 +244,58 @@ typedef uint32_t TickType_t; /* ----------------------------- Port Assembly Functions ----------------------------- */ -/** @brief Assembly FreeRTOS Supervisor Call Handler. */ -void FreeRTOS_SVC_Handler( void ); - -/** @brief Assembly FreeRTOS Interrupt Handler */ -void FreeRTOS_IRQ_Handler( void ); - /** - * @brief Make a Supervisor Call to swap the currently running task out. + * @brief FreeRTOS Supervisor Call (SVC) Handler. * * @ingroup Scheduler - * @note The FreeRTOS-Kernel needs a method to swap the current task that is - * running. The FreeRTOS-Port needs to ensure that when this happens any - * hardware specific values related to the current task’s context are properly - * saved. A properly saved context can be restored to allow execution of the - * task as if it was not interrupted. */ -void vPortYield( void ); - -/** @brief Raise a Supervisor Call to swap the currently running task out. */ -#define portYIELD() vPortYield() +void FreeRTOS_SVC_Handler( void ); /** - * @brief Disable IRQs then increment the critical nesting count. - * @ingroup Critical Section + * @brief FreeRTOS Interrupt Handler. + * + * @ingroup Scheduler */ -void vPortEnterCritical( void ); - -/** @brief Enter a Critical Section inside of the FreeRTOS-Kernel */ -#define portENTER_CRITICAL() vPortEnterCritical() +void FreeRTOS_IRQ_Handler( void ); /** - * @brief Enable IRQs and decrement the critical nesting count. - * @ingroup Critical Section + * @brief Yield the CPU. + * + * @ingroup Scheduler */ -void vPortExitCritical( void ); +void vPortYield( void ); -/** - * @brief Exit a Critical Section inside of the FreeRTOS-Kernel. - * @ingroup Critical Section - */ -#define portEXIT_CRITICAL() vPortExitCritical() +#define portYIELD() vPortYield() /** - * @brief Set the IRQ bit of the CPSR high, enabling IRQs. + * @brief Enable interrupts. + * * @ingroup Interrupt Management */ void vPortEnableInterrupts( void ); -/** - * @brief Enable Interrupts by setting the IRQ allowed flag on the CPU - * @ingroup Interrupt Management - */ #define portENABLE_INTERRUPTS() vPortEnableInterrupts() /** - * @brief Set the IRQ bit of the CPSR low, disabling IRQs. + * @brief Disable interrupts. + * * @ingroup Interrupt Management */ void vPortDisableInterrupts( void ); -/** - * @brief Enable Interrupts by lowering the IRQ allowed flag on the CPU. - * @ingroup Interrupt Management - */ #define portDISABLE_INTERRUPTS() vPortDisableInterrupts() /** - * @brief Exit the FreeRTOS-Kernel, restoring the task's settings. + * @brief Exit from a FreeRTO System Call. * * @ingroup Port Privilege - * - * @return void */ void vPortSystemCallExit( void ); /** - * @brief Load the context of the first task. + * @brief Start executing first task. * * @ingroup Scheduler - * - * @note This is an assembly function implemented in portASM.s, it loads the - * context of the first task from pxCurrentTCB. */ void vPortStartFirstTask( void ); @@ -369,8 +303,6 @@ void vPortStartFirstTask( void ); * @brief Enable the onboard MPU. * * @ingroup MPU Control - * - * @return void */ void vMPUEnable( void ); @@ -378,8 +310,6 @@ void vMPUEnable( void ); * @brief Disable the onboard MPU. * * @ingroup MPU Control - * - * @return VOID */ void vMPUDisable( void ); @@ -387,33 +317,28 @@ void vMPUDisable( void ); * @brief Enable the MPU Background Region. * * @ingroup MPU Control - * - * @return void */ void vMPUEnableBackgroundRegion( void ); /** - * @brief Disable the MPU Background Region + * @brief Disable the MPU Background Region. * * @ingroup MPU Control - * - * @return void */ void vMPUDisableBackgroundRegion( void ); + /** - * @brief Assembly routine to set permissions for an MPU Region. + * @brief Set permissions for an MPU Region. * * @ingroup MPU Control * - * @param[in] ulRegionNumber The MPU Region Number to change permissions for - * @param[in] ulBaseAddress The base address of the MPU Region - * @param[in] ulRegionSize The number of bytes to make the MPU Region - * @param[in] ulRegionPermissions The permissions to assign to the MPU Region + * @param[in] ulRegionNumber The MPU Region Number to set permissions for. + * @param[in] ulBaseAddress The base address of the MPU Region. + * @param[in] ulRegionSize The size of the MPU Region in bytes. + * @param[in] ulRegionPermissions The permissions associated with the MPU Region. * - * @note This is an Assembly Function implemented in portASM.S. - * This is meant as a purely internal function that performs a raw write of the - * provided values to the relevant MPU Registers. The inputs to this function - * are checked internally before it is called in the port.c file. + * @note This is an internal function and assumes that the inputs to this + * function are checked before calling this function. */ void vMPUSetRegion( uint32_t ulRegionNumber, uint32_t ulBaseAddress, @@ -423,105 +348,82 @@ void vMPUSetRegion( uint32_t ulRegionNumber, /* ------------------------------- Port.c Declarations ------------------------------- */ /** - * @brief Checks whether or not the processor is privileged. + * @brief Enter critical section. * - * @ingroup Port Privilege - * - * @note - * The Privilege level is determined by checking if bits [4:0] of - * the callers Current Program Status Register are in USER_MODE, 0x10 - * - * @return - * 0 If the CPSR Mode Bits are set to 0x10 - * 1 If the CPSR Mode Bits are set to 0x11-0x11F + * @ingroup Critical Section + */ +void vPortEnterCritical( void ); + +#define portENTER_CRITICAL() vPortEnterCritical() + +/** + * @brief Exit critical section. * + * @ingroup Critical Section */ -BaseType_t xPortIsPrivileged( void ); +void vPortExitCritical( void ); + +#define portEXIT_CRITICAL() vPortExitCritical() /** - * @brief Check if the CPU is currently in a privileged operating mode. + * @brief Checks whether or not the processor is privileged. * * @ingroup Port Privilege * - * @return - * 1 If the processor is privileged - * 0 If the processor is not privileged + * @note The processor privilege level is determined by checking if bits [4:0] + * of the Current Program Status Register (CPSR). * + * @return pdTRUE, if the processer is privileged, pdFALSE otherwise. */ +BaseType_t xPortIsPrivileged( void ); + #define portIS_PRIVILEGED() xPortIsPrivileged() /** - * @brief Check if ulTaskFlags has portTASK_IS_PRIVILEGED_FLAG. + * @brief Checks whether or not a task is privileged. * * @ingroup Port Privilege * - * @note - * As this loads pxCurrentTCB to determine if the task's ulTaskFlags is privileged - * or not, this function can return a different value than xPortIsPrivileged. + * A task's privilege level is associated with the task and is different from + * the processor's privilege level returned by xPortIsPrivileged. For example, + * the processor is privileged when an unprivileged task executes a system call. * - * @return - * 0 If pxCurrentTCB's !( ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) - * 1 If pxCurrentTCB's ( ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) + * @return pdTRUE if the task is privileged, pdFALSE otherwise. */ BaseType_t xPortIsTaskPrivileged( void ); -/** - * @brief Checks whether or not the currently running task is privileged. - * - * @ingroup Port Privilege - * - * @return - * pdTRUE if the calling task is privileged - * pdFALSE if the calling task is not privileged - */ #define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged() /** - * @brief Default return address for tasks, it is not meant to be called. + * @brief Default return address for tasks. * * @ingroup Task Context - * @note This function is used as the default Link Register address if - * configTASK_RETURN_ADDRESS is not defined in FreeRTOSConfig.h * + * This function is used as the default return address for tasks if + * configTASK_RETURN_ADDRESS is not defined in FreeRTOSConfig.h. */ void prvTaskExitError( void ); -/** - * @brief User provided task return function. - * - * @ingroup Task Context - * - * @note Let the user override the pre-loading of the initial LR with - * the address of prvTaskExitError() in case it messes up unwinding of - * the stack in the debugger. - */ #ifdef configTASK_RETURN_ADDRESS #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS #else - #define configTASK_RETURN_ADDRESS prvTaskExitError + #define portTASK_RETURN_ADDRESS prvTaskExitError #endif /* configTASK_RETURN_ADDRESS */ -/** - * @brief Function a task should execute if it exits its assigned function. - * - * @ingroup Task Context - * - * @note If configTASK_RETURN_ADDRESS is not defined this value shall be set to - * prvTaskExitError(). - */ -#define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS - /** * @brief Returns the number of leading zeros in a 32 bit variable. * - * @param[in] ulBitmap 32 Bit long number to count zeros of. + * @param[in] ulBitmap 32-Bit number to count leading zeros in. * - * @return The number of leading zeros ulBitmap has. + * @return The number of leading zeros in ulBitmap. */ UBaseType_t ulPortCountLeadingZeros( UBaseType_t ulBitmap ); /** - * @brief Function meant to end the FreeRTOS Scheduler, not implemented on this port. + * @brief End the FreeRTOS scheduler. + * + * Not implemented on this port. + * * @ingroup Scheduler */ void vPortEndScheduler( void ); @@ -532,11 +434,6 @@ void vPortEndScheduler( void ); * @brief Mark that this port utilizes the onboard ARM MPU. * * @ingroup MPU Control - * - * @note The structures and methods of manipulating the MPU are contained - * within the port layer. Fills the xMPUSettings structure with the memory - * region information contained in xRegions. - * */ #define portUSING_MPU_WRAPPERS 1 @@ -546,139 +443,76 @@ void vPortEndScheduler( void ); * @ingroup Task Context * @ingroup MPU Control * - * @note This is done by performing a bitwise OR of this value and the task priority. - * For example, to create a privileged task at priority 2 the uxPriority - * parameter should be set to ( 2 | portPRIVILEGE_BIT ). + * A privileged task is created by performing a bitwise OR of this value and the + * task priority. For example, to create a privileged task at priority 2, the + * uxPriority parameter should be set to ( 2 | portPRIVILEGE_BIT ). */ #define portPRIVILEGE_BIT ( 0x80000000UL ) -/** @brief Size of the System Call Buffer in the TCB. */ - -#define portSYSTEM_CALL_STACK_SIZE configSYSTEM_CALL_STACK_SIZE - -/** @brief Size of an Access Control List (ACL) entry in bits. */ +/** + * @brief Size of an Access Control List (ACL) entry in bits. + */ #define portACL_ENTRY_SIZE_BITS ( 32UL ) /** * @brief Structure to hold the MPU Register Values. + * * @struct xMPU_REGION_REGISTERS * * @ingroup MPU Control * - * NOTE: Do not modify this structure. The ordering of this struct MUST - * line up with the ordering explained in portRESTORE_CONTEXT. + * @note The ordering of this struct MUST be in sync with the ordering in + * portRESTORE_CONTEXT. */ typedef struct MPU_REGION_REGISTERS { - /** - * @brief Member used to hold the MPU register value for the Region Size. - * @struct xMPU_REGION_REGISTERS - * @ingroup MPU Control - */ - uint32_t ulRegionSize; - - /** - * @brief Member used to hold the MPU register value for the Region Attributes. - * @struct xMPU_REGION_REGISTERS - * @ingroup MPU Control - */ - uint32_t ulRegionAttribute; - - /** - * @brief Member used to hold the MPU register value for the Region Base Address. - * @struct xMPU_REGION_REGISTERS - * @ingroup MPU Control - */ - uint32_t ulRegionBaseAddress; + uint32_t ulRegionSize; /* Information for MPU Region Size and Enable Register. */ + uint32_t ulRegionAttribute; /* Information for MPU Region Access Control Register. */ + uint32_t ulRegionBaseAddress; /* Information for MPU Region Base Address Register. */ } xMPU_REGION_REGISTERS; /** * @brief Structure to hold per-task System Call Stack information. + * * @struct xSYSTEM_CALL_STACK_INFO * * @ingroup Port Privilege * - * NOTE: Do not modify this structure. The ordering of this structure is expected - * to be this way in the assembly code of the port. + * @note The ordering of this structure MUST be in sync with the assembly code + * of the port. */ typedef struct SYSTEM_CALL_STACK_INFO { - /** - * @brief Stack Pointer of the task when it made a FreeRTOS System Call. - * @struct xSYSTEM_CALL_STACK_INFO - */ - uint32_t * pulTaskStackPointer; - - /** - * @brief Link Register of the task when it made a FreeRTOS System Call. - * @struct xSYSTEM_CALL_STACK_INFO - */ - uint32_t * pulLinkRegisterAtSystemCallEntry; - - /** - * @brief Pre-Set Stack Pointer to use when making a FreeRTOS System Call. - * @struct xSYSTEM_CALL_STACK_INFO - * @note This will point to the start of ulSystemCallStackBuffer[] - */ - uint32_t * pulSystemCallStackPointer; - - /** - * @brief Pre-Set Link Register to exit a FreeRTOS System Call. - * @struct xSYSTEM_CALL_STACK_INFO - * @note This value is set in pxPortInitialiseStack() to ensure after making - * a FreeRTOS System Call that the last LR jump is to vPortSystemCallExit() - */ - void * pulSystemCallLinkRegister; - - /** - * @brief Buffer to be used when performing a FreeRTOS System Call. - * @struct xSYSTEM_CALL_STACK_INFO - */ - uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; + uint32_t * pulTaskStackPointer; /**< Stack Pointer of the task when it made a FreeRTOS System Call. */ + uint32_t * pulLinkRegisterAtSystemCallEntry; /**< Link Register of the task when it made a FreeRTOS System Call. */ + uint32_t * pulSystemCallStackPointer; /**< Stack Pointer to use for executing a FreeRTOS System Call. */ + uint32_t * pulSystemCallExitAddress; /**< System call exit address. */ + uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; /**< Buffer to be used as stack when performing a FreeRTOS System Call. */ } xSYSTEM_CALL_STACK_INFO; /** - * @brief Per-Task MPU Settings structure stored in the TCB + * @brief Per-Task MPU settings structure stored in the TCB. * @struct xMPU_SETTINGS * * @ingroup MPU Control * @ingroup Task Context * @ingroup Port Privilege * - * NOTE: Do not modify this structure. The ordering of this structure is expected to be - * this way in the assembly code of the port. + * @note The ordering of this structure MUST be in sync with the assembly code + * of the port. */ typedef struct MPU_SETTINGS { - /** - * @brief Array of Per-Task MPU Register Values. Loaded on Task Context Restore. - * @struct xMPU_SETTINGS - */ xMPU_REGION_REGISTERS xRegion[ portTOTAL_NUM_REGIONS_IN_TCB ]; - - /** - * @brief Buffer that holds a Task's Context when being swapped out. - * @struct xMPU_SETTINGS - */ - uint32_t ulContext[ MAX_CONTEXT_SIZE ]; - - /** - * @brief Variable to hold FreeRTOS Privilege Settings. - * @struct xMPU_SETTINGS - */ uint32_t ulTaskFlags; - - /** - * @brief System Call Info structure that is stored in the TCB. - * @struct xMPU_SETTINGS - */ xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + uint32_t ulContext[ CONTEXT_SIZE ]; /**< Buffer used to store task context. */ -#if( configENABLE_ACCESS_CONTROL_LIST == 1 ) - uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE - / portACL_ENTRY_SIZE_BITS ) - + 1UL ]; -#endif + #if( configENABLE_ACCESS_CONTROL_LIST == 1 ) + uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE + / portACL_ENTRY_SIZE_BITS ) + + 1UL ]; + #endif } xMPU_SETTINGS; #ifdef __cplusplus diff --git a/portable/GCC/ARM_CRx_MPU/portmacro_asm.h b/portable/GCC/ARM_CRx_MPU/portmacro_asm.h index fa4ba85c1c..16454d1233 100644 --- a/portable/GCC/ARM_CRx_MPU/portmacro_asm.h +++ b/portable/GCC/ARM_CRx_MPU/portmacro_asm.h @@ -37,8 +37,6 @@ extern "C" { #ifndef configTOTAL_MPU_REGIONS #error "Set configTOTAL_MPU_REGIONS to the humber of MPU regions in FreeRTOSConfig.h" -#elif( configTOTAL_MPU_REGIONS == 8 ) - #define portMPU_TOTAL_REGIONS ( 8UL ) #elif( configTOTAL_MPU_REGIONS == 12 ) #define portMPU_TOTAL_REGIONS ( 12UL ) #elif( configTOTAL_MPU_REGIONS == 16 ) @@ -47,112 +45,74 @@ extern "C" { #error "Set configTOTAL_MPU_REGIONS to the number of MPU regions in FreeRTOSConfig.h" #endif /* configTOTAL_MPU_REGIONS */ -/** On the ArmV7-R Architecture the Operating mode of the Processor is set - * using the Current Program Status Register (CPSR) Mode bits, [4:0]. - * The only registers banked between modes are the CPSR, Stack Pointer (R13), - * and the Link Register (R14). FIQ mode also banks the GPRs R8-R12 - * Of note, the only mode not "Privileged" is User Mode +/* + * The application write can disable Floating Point Unit (FPU) support by + * setting configENABLE_FPU to 0. Floating point context stored in TCB + * comprises of 32 floating point registers (D0-D31) and FPSCR register. + * Disabling FPU, therefore, reduces the per-task RAM usage by + * ( 32 + 1 ) * 4 = 132 bytes per task. + * + * BE CAREFUL DISABLING THIS: Certain standard library APIs try to optimize + * themselves by using the floating point registers. If the FPU support is + * disabled, the use of such APIs may result in memory corruption. + */ +#ifndef configENABLE_FPU + #define configENABLE_FPU 1 +#endif /* configENABLE_FPU */ + +#define portENABLE_FPU configENABLE_FPU + +/* On the ArmV7-R Architecture the Operating mode of the Processor is set + * using the Current Program Status Register (CPSR) Mode bits, [4:0]. The only + * unprivileged mode is User Mode. * * Additional information about the Processor Modes can be found here: * https://developer.arm.com/documentation/ddi0406/cb/System-Level-Architecture/The-System-Level-Programmers--Model/ARM-processor-modes-and-ARM-core-registers/ARM-processor-modes?lang=en * - * */ - -/** - * @brief CPSR Mode bit field value for User Mode. - * @ingroup Port Privilege - */ -#define USER_MODE 0x10U - -/** - * @brief CPSR Mode bit field value for Fast Interrupt Handler (FIQ) Mode. - * @ingroup Port Privilege - */ -#define FIQ_MODE 0x11U - -/** - * @brief CPSR Mode bit field value for Interrupt Handler (IRQ) Mode. - * @ingroup Port Privilege - */ -#define IRQ_MODE 0x12U - -/** - * @brief CPSR Mode bit field value for Supervisor (SVC) Mode. - * @ingroup Port Privilege - */ -#define SVC_MODE 0x13U - -/** - * @brief CPSR Mode bit field value for Monitor (MON) Mode. - * @ingroup Port Privilege - */ -#define MON_MODE 0x16U - -/** - * @brief CPSR Mode bit field value for Abort (ABT) Mode. - * @ingroup Port Privilege */ -#define ABT_MODE 0x17U /** - * @brief CPSR Mode bit field value for Hypervisor (HYP) Mode. - * @ingroup Port Privilege - */ -#define HYP_MODE 0x1AU - -/** - * @brief CPSR Mode bit field value for Undefined (UND) Mode. - * @ingroup Port Privilege - */ -#define UND_MODE 0x1BU - -/** - * @brief CPSR Mode bit field value for System (SYS) Mode. - * @ingroup Port Privilege - */ -#define SYS_MODE 0x1FU - -/** - * @brief Used to mark if a task should be created as a privileged task. + * @brief CPSR bits for various processor modes. * - * @ingroup Task Context - * @ingroup MPU Control - * - * @note This is done by performing a bitwise OR of this value and the task priority. - * For example, to create a privileged task at priority 2 the uxPriority - * parameter should be set to ( 2 | portPRIVILEGE_BIT ). + * @ingroup Port Privilege */ -#define portPRIVILEGE_BIT ( 0x80000000UL ) +#define USER_MODE 0x10U +#define FIQ_MODE 0x11U +#define IRQ_MODE 0x12U +#define SVC_MODE 0x13U +#define MON_MODE 0x16U +#define ABT_MODE 0x17U +#define HYP_MODE 0x1AU +#define UND_MODE 0x1BU +#define SYS_MODE 0x1FU /** * @brief Flag used to mark that a FreeRTOS Task is privileged. + * * @ingroup Port Privilege */ #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) /** - * @brief SVC Number to use when requesting a context swap. + * @brief SVC numbers for various scheduler operations. + * * @ingroup Scheduler - * @note This value must not be in use in mpu_syscall_numbers.h + * + * @note These value must not be used in mpu_syscall_numbers.h. */ #define portSVC_YIELD 0x0100U - -/** - * @brief SVC Number to use when exiting a FreeRTOS System Call. - * @ingroup MPU Control - * @note This value must not be in use in mpu_syscall_numbers.h - */ #define portSVC_SYSTEM_CALL_EXIT 0x0104U /** - * @addtogroup MPU Control - * @note The Region Access Control Register is used to set MPU Region Settings. - * Further information about this register can be found in Arm's documentation + * @brief Macros required to manipulate MPU. + * + * Further information about MPU can be found in Arm's documentation * https://developer.arm.com/documentation/ddi0363/g/System-Control/Register-descriptions/c6--MPU-memory-region-programming-registers * */ -/* MPU Sub Region settings */ +/* MPU sub-region disable settings. This information is encoded in the MPU + * Region Size and Enable Register. */ #define portMPU_SUBREGION_0_DISABLE ( 0x1UL << 8UL ) #define portMPU_SUBREGION_1_DISABLE ( 0x1UL << 9UL ) #define portMPU_SUBREGION_2_DISABLE ( 0x1UL << 10UL ) @@ -162,7 +122,7 @@ extern "C" { #define portMPU_SUBREGION_6_DISABLE ( 0x1UL << 14UL ) #define portMPU_SUBREGION_7_DISABLE ( 0x1UL << 15UL ) -/* Default MPU regions */ +/* Default MPU regions. */ #define portFIRST_CONFIGURABLE_REGION ( 0 ) #define portLAST_CONFIGURABLE_REGION ( portMPU_TOTAL_REGIONS - 5UL ) #define portSTACK_REGION ( portMPU_TOTAL_REGIONS - 4UL ) @@ -171,198 +131,100 @@ extern "C" { #define portPRIVILEGED_RAM_REGION ( portMPU_TOTAL_REGIONS - 1UL ) #define portNUM_CONFIGURABLE_REGIONS \ ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1UL ) -/* Plus one to make space for the stack region*/ +/* Plus one to make space for the stack region. */ #define portTOTAL_NUM_REGIONS_IN_TCB ( portNUM_CONFIGURABLE_REGIONS + 1UL ) -/* MPU region sizes */ -#define portMPU_SIZE_32B ( 0x04UL << 1UL ) -#define portMPU_SIZE_64B ( 0x05UL << 1UL ) -#define portMPU_SIZE_128B ( 0x06UL << 1UL ) -#define portMPU_SIZE_256B ( 0x07UL << 1UL ) -#define portMPU_SIZE_512B ( 0x08UL << 1UL ) -#define portMPU_SIZE_1KB ( 0x09UL << 1UL ) -#define portMPU_SIZE_2KB ( 0x0AUL << 1UL ) -#define portMPU_SIZE_4KB ( 0x0BUL << 1UL ) -#define portMPU_SIZE_8KB ( 0x0CUL << 1UL ) -#define portMPU_SIZE_16KB ( 0x0DUL << 1UL ) -#define portMPU_SIZE_32KB ( 0x0EUL << 1UL ) -#define portMPU_SIZE_64KB ( 0x0FUL << 1UL ) -#define portMPU_SIZE_128KB ( 0x10UL << 1UL ) -#define portMPU_SIZE_256KB ( 0x11UL << 1UL ) -#define portMPU_SIZE_512KB ( 0x12UL << 1UL ) -#define portMPU_SIZE_1MB ( 0x13UL << 1UL ) -#define portMPU_SIZE_2MB ( 0x14UL << 1UL ) -#define portMPU_SIZE_4MB ( 0x15UL << 1UL ) -#define portMPU_SIZE_8MB ( 0x16UL << 1UL ) -#define portMPU_SIZE_16MB ( 0x17UL << 1UL ) -#define portMPU_SIZE_32MB ( 0x18UL << 1UL ) -#define portMPU_SIZE_64MB ( 0x19UL << 1UL ) -#define portMPU_SIZE_128MB ( 0x1AUL << 1UL ) -#define portMPU_SIZE_256MB ( 0x1BUL << 1UL ) -#define portMPU_SIZE_512MB ( 0x1CUL << 1UL ) -#define portMPU_SIZE_1GB ( 0x1DUL << 1UL ) -#define portMPU_SIZE_2GB ( 0x1EUL << 1UL ) -#define portMPU_SIZE_4GB ( 0x1FUL << 1UL ) - -/* MPU Device Memory Types */ -#define portMPU_REGION_STRONGLY_ORDERED ( 0x00UL ) -#define portMPU_REGION_DEVICE ( 0x01UL ) -#define portMPU_REGION_CACHEABLE_BUFFERABLE ( 0x03UL ) -#define portMPU_REGION_EXECUTE_NEVER ( 0x01UL << 12UL ) -#define portMPU_STRONGLYORDERED_SHAREABLE ( 0x0000UL ) -#define portMPU_DEVICE_SHAREABLE ( 0x0001UL ) -#define portMPU_DEVICE_NONSHAREABLE ( 0x0010UL ) -#define portMPU_NORMAL_OIWTNOWA_NONSHARED ( 0x0002UL ) -#define portMPU_NORMAL_OIWBNOWA_NONSHARED ( 0x0003UL ) -#define portMPU_NORMAL_OIWTNOWA_SHARED ( 0x0006UL ) -#define portMPU_NORMAL_OIWBNOWA_SHARED ( 0x0007UL ) -#define portMPU_NORMAL_OINC_NONSHARED ( 0x0008UL ) -#define portMPU_NORMAL_OIWBWA_NONSHARED ( 0x000BUL ) -#define portMPU_NORMAL_OINC_SHARED ( 0x000CUL ) -#define portMPU_NORMAL_OIWBWA_SHARED ( 0x000FUL ) - -/** - * @brief MPU_CTRL value for: No Access and No Execute - * - * @ingroup MPU Control - * - * @brief No Access in a Privileged Operating Mode - * No Access in User Mode - * Cannot Execute Code from this region - */ -#define portMPU_PRIV_NA_USER_NA_NOEXEC ( 0x1000UL ) - -/** - * @brief MPU_CTRL value for Privileged Read and Exec - * - * @ingroup MPU Control - * - * @note Read Only Access in Privileged Operating Modes. - * No Read/Write Access in User Mode - * Allowed to Execute Code from this region - */ -#define portMPU_PRIV_RO_USER_NA_EXEC ( 0x0500UL ) - -/** - * @brief MPU_CTRL value for Privileged Read, Write, and Exec - * - * @ingroup MPU Control - * - * Read/Write in a Privileged Operating Mode - * No Access in User Mode - * Allowed to Execute Code from this region - */ -#define portMPU_PRIV_RW_USER_NA_EXEC ( 0x0100UL ) - -/** - * @brief MPU_CTRL value for Read Only and Execute - * - * @ingroup MPU Control - * - * @note Read Only in a Privileged Operating Mode - * Read Only in User Mode - * Allowed to Execute Code from this region - * */ -#define portMPU_PRIV_RO_USER_RO_EXEC ( 0x0600UL ) - -/** - * @brief MPU_CTRL value for: Read, Execute, and Privileged Write - * - * @ingroup MPU Control - * - * @note Read/Write in a Privileged Operating Mode - * Read Only in User Mode - * Allowed to Execute Code from this region - */ -#define portMPU_PRIV_RW_USER_RO_EXEC ( 0x0200UL ) - -/** - * @brief MPU_CTRL value for: Read, Write, and Execute - * - * @ingroup MPU Control - * - * @note Read/Write in a Privileged Operating Mode - * Read/write in User Mode - * Allowed to Execute Code from this region - */ -#define portMPU_PRIV_RW_USER_RW_EXEC ( 0x0300UL ) - -/** - * @brief MPU_CTRL value for: Privileged Read, Write Only, no Execute - * - * @ingroup MPU Control - * - * @note Read/Write in a Privileged Operating Mode - * No Access in User Mode - * Cannot Execute Code from this region - */ -#define portMPU_PRIV_RW_USER_NA_NOEXEC ( 0x1100UL ) - -/** - * @brief MPU_CTRL value for: All Read, Privileged Write, no Execute - * - * @ingroup MPU Control - * - * Read/Write in a Privileged Operating Mode - * Read Only in User Mode - * Cannot Execute Code from this region - */ -#define portMPU_PRIV_RW_USER_RO_NOEXEC ( 0x1200UL ) - -/** - * @brief MPU_CTRL value for: Read, Write, no Execute - * - * @ingroup MPU Control - * - * @note Read/Write in a Privileged Operating Mode - * Read/Write in User Mode - * Cannot Execute Code from this region - */ -#define portMPU_PRIV_RW_USER_RW_NOEXEC ( 0x1300UL ) - -/** - * @brief MPU_CTRL value for: Privileged Read Only, No Execute - * - * @ingroup MPU Control - * - * @note Read Only in a Privileged Operating Mode - * No Access in User Mode - * Cannot Execute Code from this region - */ -#define portMPU_PRIV_RO_USER_NA_NOEXEC ( 0x1500UL ) - -/** - * @brief MPU_CTRL value for: Read Only, No Execute - * - * @ingroup MPU Control - * - * @note Read Only in a Privileged Operating Mode - * Read Only in User Mode - * Cannot Execute Code from this region - */ -#define portMPU_PRIV_RO_USER_RO_NOEXEC ( 0x1600UL ) +/* MPU region sizes. This information is encoded in the MPU Region Size and + * Enable Register. */ +#define portMPU_REGION_SIZE_32B ( 0x04UL << 1UL ) +#define portMPU_REGION_SIZE_64B ( 0x05UL << 1UL ) +#define portMPU_REGION_SIZE_128B ( 0x06UL << 1UL ) +#define portMPU_REGION_SIZE_256B ( 0x07UL << 1UL ) +#define portMPU_REGION_SIZE_512B ( 0x08UL << 1UL ) +#define portMPU_REGION_SIZE_1KB ( 0x09UL << 1UL ) +#define portMPU_REGION_SIZE_2KB ( 0x0AUL << 1UL ) +#define portMPU_REGION_SIZE_4KB ( 0x0BUL << 1UL ) +#define portMPU_REGION_SIZE_8KB ( 0x0CUL << 1UL ) +#define portMPU_REGION_SIZE_16KB ( 0x0DUL << 1UL ) +#define portMPU_REGION_SIZE_32KB ( 0x0EUL << 1UL ) +#define portMPU_REGION_SIZE_64KB ( 0x0FUL << 1UL ) +#define portMPU_REGION_SIZE_128KB ( 0x10UL << 1UL ) +#define portMPU_REGION_SIZE_256KB ( 0x11UL << 1UL ) +#define portMPU_REGION_SIZE_512KB ( 0x12UL << 1UL ) +#define portMPU_REGION_SIZE_1MB ( 0x13UL << 1UL ) +#define portMPU_REGION_SIZE_2MB ( 0x14UL << 1UL ) +#define portMPU_REGION_SIZE_4MB ( 0x15UL << 1UL ) +#define portMPU_REGION_SIZE_8MB ( 0x16UL << 1UL ) +#define portMPU_REGION_SIZE_16MB ( 0x17UL << 1UL ) +#define portMPU_REGION_SIZE_32MB ( 0x18UL << 1UL ) +#define portMPU_REGION_SIZE_64MB ( 0x19UL << 1UL ) +#define portMPU_REGION_SIZE_128MB ( 0x1AUL << 1UL ) +#define portMPU_REGION_SIZE_256MB ( 0x1BUL << 1UL ) +#define portMPU_REGION_SIZE_512MB ( 0x1CUL << 1UL ) +#define portMPU_REGION_SIZE_1GB ( 0x1DUL << 1UL ) +#define portMPU_REGION_SIZE_2GB ( 0x1EUL << 1UL ) +#define portMPU_REGION_SIZE_4GB ( 0x1FUL << 1UL ) + +/* MPU memory types. This information is encoded in the TEX, S, C and B bits + * of the MPU Region Access Control Register. */ +#define portMPU_REGION_STRONGLY_ORDERED_SHAREABLE ( 0x00UL ) /* TEX=000, S=NA, C=0, B=0. */ +#define portMPU_REGION_DEVICE_SHAREABLE ( 0x01UL ) /* TEX=000, S=NA, C=0, B=1. */ +#define portMPU_REGION_NORMAL_OIWTNOWA_NONSHARED ( 0x02UL ) /* TEX=000, S=0, C=1, B=0. */ +#define portMPU_REGION_NORMAL_OIWTNOWA_SHARED ( 0x06UL ) /* TEX=000, S=1, C=1, B=0. */ +#define portMPU_REGION_NORMAL_OIWBNOWA_NONSHARED ( 0x03UL ) /* TEX=000, S=0, C=1, B=1. */ +#define portMPU_REGION_NORMAL_OIWBNOWA_SHARED ( 0x07UL ) /* TEX=000, S=1, C=1, B=1. */ +#define portMPU_REGION_NORMAL_OINC_NONSHARED ( 0x08UL ) /* TEX=001, S=0, C=0, B=0. */ +#define portMPU_REGION_NORMAL_OINC_SHARED ( 0x0CUL ) /* TEX=001, S=1, C=0, B=0. */ +#define portMPU_REGION_NORMAL_OIWBWA_NONSHARED ( 0x0BUL ) /* TEX=001, S=0, C=1, B=1. */ +#define portMPU_REGION_NORMAL_OIWBWA_SHARED ( 0x0FUL ) /* TEX=001, S=1, C=1, B=1. */ +#define portMPU_REGION_DEVICE_NONSHAREABLE ( 0x10UL ) /* TEX=010, S=NA, C=0, B=0. */ + +/* MPU access permissions. This information is encoded in the XN and AP bits of + * the MPU Region Access Control Register. */ +#define portMPU_REGION_AP_BITMASK ( 0x07UL << 8UL ) +#define portMPU_REGION_XN_BITMASK ( 0x01UL << 12UL ) + +#define portMPU_REGION_PRIV_NA_USER_NA ( 0x00UL << 8UL ) +#define portMPU_REGION_PRIV_NA_USER_NA_EXEC ( portMPU_REGION_PRIV_NA_USER_NA ) /* Priv: X, Unpriv: X. */ +#define portMPU_REGION_PRIV_NA_USER_NA_NOEXEC ( portMPU_REGION_PRIV_NA_USER_NA | \ + portMPU_REGION_XN_BITMASK ) /* Priv: No Access, Unpriv: No Access. */ + +#define portMPU_REGION_PRIV_RW_USER_NA ( 0x01UL << 8UL ) +#define portMPU_REGION_PRIV_RW_USER_NA_EXEC ( portMPU_REGION_PRIV_RW_USER_NA ) /* Priv: RWX, Unpriv: X. */ +#define portMPU_REGION_PRIV_RW_USER_NA_NOEXEC ( portMPU_REGION_PRIV_RW_USER_NA | \ + portMPU_REGION_XN_BITMASK ) /* Priv: RW, Unpriv: No access. */ + +#define portMPU_REGION_PRIV_RW_USER_RO ( 0x02UL << 8UL ) +#define portMPU_REGION_PRIV_RW_USER_RO_EXEC ( portMPU_REGION_PRIV_RW_USER_RO ) /* Priv: RWX, Unpriv: RX. */ +#define portMPU_REGION_PRIV_RW_USER_RO_NOEXEC ( portMPU_REGION_PRIV_RW_USER_RO | \ + portMPU_REGION_XN_BITMASK ) /* Priv: RW, Unpriv: R. */ + +#define portMPU_REGION_PRIV_RW_USER_RW ( 0x03UL << 8UL ) +#define portMPU_REGION_PRIV_RW_USER_RW_EXEC ( portMPU_REGION_PRIV_RW_USER_RW ) /* Priv: RWX, Unpriv: RWX. */ +#define portMPU_REGION_PRIV_RW_USER_RW_NOEXEC ( portMPU_REGION_PRIV_RW_USER_RW | \ + portMPU_REGION_XN_BITMASK ) /* Priv: RW, Unpriv: RW. */ + +#define portMPU_REGION_PRIV_RO_USER_NA ( 0x05UL << 8UL ) +#define portMPU_REGION_PRIV_RO_USER_NA_EXEC ( portMPU_REGION_PRIV_RO_USER_NA ) /* Priv: RX, Unpriv: X. */ +#define portMPU_REGION_PRIV_RO_USER_NA_NOEXEC ( portMPU_REGION_PRIV_RO_USER_NA | \ + portMPU_REGION_XN_BITMASK ) /* Priv: R, Unpriv: No access. */ + +#define portMPU_REGION_PRIV_RO_USER_RO ( 0x06UL << 8UL ) +#define portMPU_REGION_PRIV_RO_USER_RO_EXEC ( portMPU_REGION_PRIV_RO_USER_RO ) /* Priv: RX, Unpriv: RX. */ +#define portMPU_REGION_PRIV_RO_USER_RO_NOEXEC ( portMPU_REGION_PRIV_RO_USER_RO | \ + portMPU_REGION_XN_BITMASK ) /* Priv: R, Unpriv: R. */ + +/* MPU region management. */ +#define portMPU_REGION_EXECUTE_NEVER ( 0x01UL << 12UL ) +#define portMPU_REGION_ENABLE ( 0x01UL ) /** - * @brief MPU_CTRL value to enable an MPU Region - * @ingroup MPU Control - */ -#define portMPU_REGION_ENABLE ( 0x01UL ) - -/** This following section is used to create the proper size for the ulContext array. - * This array is where all registers related to a task's context are saved. - * The size of this array will depend on if the system is using an integrated - * Floating Point Unit (FPU) or not. If we are using the FPU we must save the - * Floating Point Status and Control Register (FPSCR), - * and the Floating Point Registers (FPRs). The FPSCR holds the conditional bits - * used for floating point calculations. The FPRs hold the actual floating point bits. - * The remainder of a task's context consists of the General Purpose Registers (GPRs). - * General Purpose Registers are used to manipulate almost all variables. - * The Current Program Status and Control Register, which holds the operating mode - * and bits that correspond to any conditional checks, such as if statements. - * And the Critical Nesting Depth of the task. + * @brief The size (in words) of a task context. * + * An array of this size is allocated in TCB where a task's context is saved + * when it is switched out. * - * For more information about the FPU, FPSCR, and FPRs please reference ARM's website: + * Information about Floating Point Unit (FPU): * https://developer.arm.com/documentation/den0042/a/Floating-Point * * Additional information related to the Cortex R4-F's FPU Implementation: @@ -371,7 +233,7 @@ extern "C" { * Additional information related to the Cortex R5-F's FPU Implementation: * https://developer.arm.com/documentation/ddi0460/d/FPU-Programmers-Model * - * Additional information related to the ArmV7-R CPSR + * Additional information related to the ArmV7-R CPSR: * https://developer.arm.com/documentation/ddi0406/cb/Application-Level-Architecture/Application-Level-Programmers--Model/The-Application-Program-Status-Register--APSR-?lang=en * * Additional information related to the GPRs: @@ -379,74 +241,36 @@ extern "C" { * */ -/** - * @brief The length in ulContext for the General Purpose Registers in bytes. - * @note There are 13 GPRs, R0-R12, the SP, and the LR. Each register is 32 - * bits, so the register context length is 15 registers * 4 bytes = 60 bytes. - */ -#define portREGISTER_LENGTH ( 15U * 4U ) - -/** - * If you KNOW that your system will not utilize the FPU in any capacity - * you can set portENABLE_FPU to 0. This will reduce the per-task RAM usage - * by ( 32 FPRs + 32 bit FPSCR ) * 4 bytes per register = 132 Bytes Per Task. - * It will also increase context swap speed, as these can then be ignored. - * BE CAREFUL DISABLING THIS: Certain APIs will try and optimize themselves - * by using the FPRs. If the FPU context is not saved and this happens it could - * be exceedingly difficult to debug why a strcpy() or other similar function - * seems to randomly fail. - */ -#ifndef configENABLE_FPU - #define configENABLE_FPU 1 -#endif /* configENABLE_FPU */ - -/** - * @brief Mark if the Floating Point Registers (FPRs) will be saved. - * @ingroup Task Context - * @note Using the FPU requires save FPRs into the task's context. As well as - * the Floating Point Status and Control Register (FPSCR). - */ -#define portENABLE_FPU configENABLE_FPU - #if( portENABLE_FPU == 1 ) - /** - * @brief Length of a Task's Register Context when using an FPU. - * @ingroup Task Context - * @note Task Context which is stored in ulContext in order, consists of: - * ulContext[ 0 ]: Critical Nesting Count: ulCriticalNesting - * ulContext[ 1 ]: Floating Point Status and Control Register - * ulContext[ 2 - 33 ]: Floating Point Registers: S0-S31 - * ulContext[ 34 - 46 ]: General Purpose Registers: R0-R12 - * ulContext[ 48 ]: Stack Pointer - * ulContext[ 49 ]: Link Register - * ulContext[ 50 ]: Program Counter - * ulContext[ 51 ]: Current Program Status and Control Register + /* + * +-------------------+-------+----------+--------+----------+----------+----------+------+ + * | ulCriticalNesting | FPSCR | S0-S31 | R0-R12 | SP (R13) | LR (R14) | PC (R15) | CPSR | + * +-------------------+-------+----------+--------+----------+----------+----------+------+ + * + * <------------------><------><---------><--------><---------><--------><----------><-----> + * 1 1 32 13 1 1 1 1 */ - #define MAX_CONTEXT_SIZE 51U + #define CONTEXT_SIZE 51U #else - /** - * @brief Length of a Task's Register Context when not using an FPU. - * @ingroup Task Context - * @note Task Context which is stored in ulContext in order, consists of: - * ulContext[ 0 ]: Critical Nesting Count: ulCriticalNesting - * ulContext[ 1 - 13 ]: General Purpose Registers: R0-R12 - * ulContext[ 14 ]: Stack Pointer - * ulContext[ 15 ]: Link Register - * ulContext[ 16 ]: Program Counter - * ulContext[ 17 ]: Current Program Status and Control Register + /* + * +-------------------+--------+----------+----------+----------+------+ + * | ulCriticalNesting | R0-R12 | SP (R13) | LR (R14) | PC (R15) | CPSR | + * +-------------------+--------+----------+----------+----------+------+ + * + * <------------------><--------><---------><--------><----------><-----> + * 1 13 1 1 1 1 */ - #define MAX_CONTEXT_SIZE 18U -#endif /* MAX_CONTEXT_SIZE */ + #define CONTEXT_SIZE 18U +#endif /* CONTEXT_SIZE */ /** - * @brief Numerical offset from the start of a TCB to xSystemCallStackInfo. - * @note This is used in portASM.S to load xSystemCallStackInfo from the TCB. - * This provides an easy way for the exception handlers to get this structure. - * The numerical value here should be equal to: - * sizeof( xRegion ) + sizeof( ulContext ) + sizeof( ulTaskFlags ) + * @brief Offset of xSystemCallStackInfo from the start of a TCB. */ -#define portSYSTEM_CALL_INFO_OFFSET \ - ( ( ( portTOTAL_NUM_REGIONS_IN_TCB * 3U ) + ( MAX_CONTEXT_SIZE ) + 1U ) * 4U ) +#define portSYSTEM_CALL_INFO_OFFSET \ + ( ( 1U /* pxTopOfStack. */ + \ + ( portTOTAL_NUM_REGIONS_IN_TCB * 3U ) + \ + 1U /* ulTaskFlags. */ \ + ) * 4U ) #ifdef __cplusplus } /* extern C */ From 2ef0b5d795515e8578f56a15e6cf91ed24a3435f Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Fri, 23 Feb 2024 07:04:46 -0500 Subject: [PATCH 49/51] Remove clang format of the ARM_CRx_MPU Port --- .github/workflows/ci.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 665f85ea5d..bc6d8802b3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,15 +15,6 @@ jobs: with: exclude-dirs: portable - port-formatting: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Check Formatting of FreeRTOS-Kernel Files - uses: FreeRTOS/CI-CD-Github-Actions/clang-formatting@main - with: - path: portable/GCC/ARM_CRx_MPU - spell-check: runs-on: ubuntu-latest steps: From ecd936bcdb5e4304b32dcd106a7ea982d42b7d12 Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Fri, 23 Feb 2024 07:11:21 -0500 Subject: [PATCH 50/51] Fix a grammar issue, use longer function ends in port.c. Use @note in a few more places --- portable/GCC/ARM_CRx_MPU/port.c | 4 ++-- portable/GCC/ARM_CRx_MPU/portmacro.h | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/portable/GCC/ARM_CRx_MPU/port.c b/portable/GCC/ARM_CRx_MPU/port.c index 6504c92edf..cd03d27b85 100644 --- a/portable/GCC/ARM_CRx_MPU/port.c +++ b/portable/GCC/ARM_CRx_MPU/port.c @@ -819,7 +819,7 @@ void vPortEnterCritical( void ) configASSERT( ulPortInterruptNesting == 0 ); } } -/*-----------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ /* PRIVILEGED_FUNCTION */ void vPortExitCritical( void ) @@ -840,4 +840,4 @@ void vPortExitCritical( void ) } } } -/*-----------------------------------------------------------*/ +/* ----------------------------------------------------------------------------------- */ diff --git a/portable/GCC/ARM_CRx_MPU/portmacro.h b/portable/GCC/ARM_CRx_MPU/portmacro.h index 6d0eea568b..9ed35c9582 100644 --- a/portable/GCC/ARM_CRx_MPU/portmacro.h +++ b/portable/GCC/ARM_CRx_MPU/portmacro.h @@ -115,8 +115,8 @@ extern "C" { * * @ingroup Critical Sections * - * A task exits critical section and enables IRQs when its nesting count reaches - * this value. + * @note A task exits critical section and enables IRQs when its nesting count + * reaches this value. */ #define portNO_CRITICAL_NESTING ( ( uint32_t ) 0x0 ) @@ -370,8 +370,8 @@ void vPortExitCritical( void ); * * @ingroup Port Privilege * - * @note The processor privilege level is determined by checking if bits [4:0] - * of the Current Program Status Register (CPSR). + * @note The processor privilege level is determined by checking the + * mode bits [4:0] of the Current Program Status Register (CPSR). * * @return pdTRUE, if the processer is privileged, pdFALSE otherwise. */ @@ -384,7 +384,7 @@ BaseType_t xPortIsPrivileged( void ); * * @ingroup Port Privilege * - * A task's privilege level is associated with the task and is different from + * @note A task's privilege level is associated with the task and is different from * the processor's privilege level returned by xPortIsPrivileged. For example, * the processor is privileged when an unprivileged task executes a system call. * @@ -399,7 +399,7 @@ BaseType_t xPortIsTaskPrivileged( void ); * * @ingroup Task Context * - * This function is used as the default return address for tasks if + * @note This function is used as the default return address for tasks if * configTASK_RETURN_ADDRESS is not defined in FreeRTOSConfig.h. */ void prvTaskExitError( void ); @@ -443,8 +443,8 @@ void vPortEndScheduler( void ); * @ingroup Task Context * @ingroup MPU Control * - * A privileged task is created by performing a bitwise OR of this value and the - * task priority. For example, to create a privileged task at priority 2, the + * @note A privileged task is created by performing a bitwise OR of this value and + * the task priority. For example, to create a privileged task at priority 2, the * uxPriority parameter should be set to ( 2 | portPRIVILEGE_BIT ). */ #define portPRIVILEGE_BIT ( 0x80000000UL ) From d8fdd4e2f8c2d203ed6013a45d74b5badeae5f11 Mon Sep 17 00:00:00 2001 From: Soren Ptak Date: Mon, 26 Feb 2024 12:29:14 -0500 Subject: [PATCH 51/51] Remove duplicate space from the copyright header --- portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S | 2 +- portable/GCC/ARM_CRx_MPU/port.c | 2 +- portable/GCC/ARM_CRx_MPU/portASM.S | 2 +- portable/GCC/ARM_CRx_MPU/portmacro.h | 2 +- portable/GCC/ARM_CRx_MPU/portmacro_asm.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S b/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S index 297b167845..8d0f769bb3 100644 --- a/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S +++ b/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CRx_MPU/port.c b/portable/GCC/ARM_CRx_MPU/port.c index cd03d27b85..bef3a78543 100644 --- a/portable/GCC/ARM_CRx_MPU/port.c +++ b/portable/GCC/ARM_CRx_MPU/port.c @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CRx_MPU/portASM.S b/portable/GCC/ARM_CRx_MPU/portASM.S index b9cb955402..cac0fc4068 100644 --- a/portable/GCC/ARM_CRx_MPU/portASM.S +++ b/portable/GCC/ARM_CRx_MPU/portASM.S @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CRx_MPU/portmacro.h b/portable/GCC/ARM_CRx_MPU/portmacro.h index 9ed35c9582..4ca649f6ef 100644 --- a/portable/GCC/ARM_CRx_MPU/portmacro.h +++ b/portable/GCC/ARM_CRx_MPU/portmacro.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * diff --git a/portable/GCC/ARM_CRx_MPU/portmacro_asm.h b/portable/GCC/ARM_CRx_MPU/portmacro_asm.h index 16454d1233..a113ac02d4 100644 --- a/portable/GCC/ARM_CRx_MPU/portmacro_asm.h +++ b/portable/GCC/ARM_CRx_MPU/portmacro_asm.h @@ -1,6 +1,6 @@ /* * FreeRTOS Kernel - * Copyright (C) 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright (C) 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT *