mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-12-07 05:34:59 -05:00
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
This commit is contained in:
parent
2f445ee7f1
commit
91d4d2416a
4 changed files with 153 additions and 145 deletions
|
|
@ -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;
|
||||
ulRegionStart = ( uint32_t ) __SRAM_segment_start__;
|
||||
ulRegionEnd = ( uint32_t ) __SRAM_segment_end__;
|
||||
ulRegionLen = ulRegionEnd - ulRegionStart;
|
||||
ulRegionLen = prvGetMPURegionSizeSetting( ulRegionLen );
|
||||
ulRegionLen |= portMPU_REGION_ENABLE;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
/* 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
|
||||
{
|
||||
for( ulIndex = 0UL; ulIndex < portNUM_CONFIGURABLE_REGIONS; ulIndex++ )
|
||||
{
|
||||
/* 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 ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Otherwise ensure the region is zero'd out */
|
||||
ulRegionStart = 0x0UL;
|
||||
ulRegionLen = 0x0UL;
|
||||
ulRegionAttr = 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. */
|
||||
|
||||
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;
|
||||
}
|
||||
/* Cannot have a task stack of size 0 */
|
||||
configASSERT( ulStackDepth != 0x0UL );
|
||||
|
||||
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;
|
||||
}
|
||||
/* 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;
|
||||
|
||||
lIndex++;
|
||||
}
|
||||
/* 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
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue