mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-19 21:11:57 -04:00
Enable building the GCC Cortex-R5 port without an FPU (#586)
* Ensure configUSE_TASK_FPU_SUPPORT option is set correctly If one does enable the FPU of the Cortex-R5 processor, then the GCC compiler will define the macro __ARM_FP. This can be used to ensure, that the configUSE_TASK_FPU_SUPPORT is set accordingly. * Enable the implementation of vPortTaskUsesFPU only if configUSE_TASK_FPU_SUPPORT is set to 1 * Remove error case in pxPortInitialiseStack The case of configUSE_TASK_FPU_SUPPORT is 0 is now handled * Enable access to FPU registers only if FPU is enabled * Make minor formating changes * Format ARM Cortex-R5 port * Address review comments from @ChristosZosi * Minor code review suggestions Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com> --------- Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com> Co-authored-by: Christos Zosimidis <christos.zosimidis@gmail.com> Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> Co-authored-by: Gaurav Aggarwal <aggarg@amazon.com>
This commit is contained in:
parent
563c57e7da
commit
7b26ea6263
|
@ -74,25 +74,52 @@
|
|||
#error configMAX_API_CALL_INTERRUPT_PRIORITY must be greater than ( configUNIQUE_INTERRUPT_PRIORITIES / 2 )
|
||||
#endif
|
||||
|
||||
/* Some vendor specific files default configCLEAR_TICK_INTERRUPT() in
|
||||
* portmacro.h. */
|
||||
/*
|
||||
* __ARM_FP is defined by the c preprocessor when FPU support is enabled,
|
||||
* usually with the -mfpu= argument and -mfloat-abi=.
|
||||
*
|
||||
* Note: Some implementations of the c standard library may use FPU registers
|
||||
* for generic memory operations (memcpy, etc).
|
||||
* When setting configUSE_TASK_FPU_SUPPORT == 1, care must be taken to
|
||||
* ensure that the FPU registers are not used without an FPU context.
|
||||
*/
|
||||
#if ( configUSE_TASK_FPU_SUPPORT == 0 )
|
||||
#ifdef __ARM_FP
|
||||
#error __ARM_FP is defined, so configUSE_TASK_FPU_SUPPORT must be set to either to 1 or 2.
|
||||
#endif /* __ARM_FP */
|
||||
#elif ( configUSE_TASK_FPU_SUPPORT == 1 ) || ( configUSE_TASK_FPU_SUPPORT == 2 )
|
||||
#ifndef __ARM_FP
|
||||
#error __ARM_FP is not defined, so configUSE_TASK_FPU_SUPPORT must be set to 0.
|
||||
#endif /* __ARM_FP */
|
||||
#endif /* configUSE_TASK_FPU_SUPPORT */
|
||||
|
||||
/*
|
||||
* Some vendor specific files default configCLEAR_TICK_INTERRUPT() in
|
||||
* portmacro.h.
|
||||
*/
|
||||
#ifndef configCLEAR_TICK_INTERRUPT
|
||||
#define configCLEAR_TICK_INTERRUPT()
|
||||
#endif
|
||||
|
||||
/* A critical section is exited when the critical section nesting count reaches
|
||||
* this value. */
|
||||
/*
|
||||
* A critical section is exited when the critical section nesting count reaches
|
||||
* this value.
|
||||
*/
|
||||
#define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
|
||||
|
||||
/* In all GICs 255 can be written to the priority mask register to unmask all
|
||||
* (but the lowest) interrupt priority. */
|
||||
/*
|
||||
* In all GICs 255 can be written to the priority mask register to unmask all
|
||||
* (but the lowest) interrupt priority.
|
||||
*/
|
||||
#define portUNMASK_VALUE ( 0xFFUL )
|
||||
|
||||
/* Tasks are not created with a floating point context, but can be given a
|
||||
/*
|
||||
* Tasks are not created with a floating point context, but can be given a
|
||||
* floating point context after they have been created. A variable is stored as
|
||||
* part of the tasks context that holds portNO_FLOATING_POINT_CONTEXT if the task
|
||||
* does not have an FPU context, or any other value if the task does have an FPU
|
||||
* context. */
|
||||
* context.
|
||||
*/
|
||||
#define portNO_FLOATING_POINT_CONTEXT ( ( StackType_t ) 0 )
|
||||
|
||||
/* Constants required to setup the initial task context. */
|
||||
|
@ -101,8 +128,10 @@
|
|||
#define portINTERRUPT_ENABLE_BIT ( 0x80UL )
|
||||
#define portTHUMB_MODE_ADDRESS ( 0x01UL )
|
||||
|
||||
/* Used by portASSERT_IF_INTERRUPT_PRIORITY_INVALID() when ensuring the binary
|
||||
* point is zero. */
|
||||
/*
|
||||
* Used by portASSERT_IF_INTERRUPT_PRIORITY_INVALID() when ensuring the binary
|
||||
* point is zero.
|
||||
*/
|
||||
#define portBINARY_POINT_BITS ( ( uint8_t ) 0x03 )
|
||||
|
||||
/* Masks all bits in the APSR other than the mode bits. */
|
||||
|
@ -140,15 +169,19 @@
|
|||
#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff )
|
||||
#define portBIT_0_SET ( ( uint8_t ) 0x01 )
|
||||
|
||||
/* Let the user override the pre-loading of the initial LR with the address of
|
||||
/*
|
||||
* Let the user override the pre-loading of the initial LR with the address of
|
||||
* prvTaskExitError() in case is messes up unwinding of the stack in the
|
||||
* debugger. */
|
||||
* debugger.
|
||||
*/
|
||||
#ifdef configTASK_RETURN_ADDRESS
|
||||
#define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS
|
||||
#else
|
||||
#define portTASK_RETURN_ADDRESS prvTaskExitError
|
||||
#endif
|
||||
|
||||
#if ( configUSE_TASK_FPU_SUPPORT != 0 )
|
||||
|
||||
/*
|
||||
* The space on the stack required to hold the FPU registers.
|
||||
*
|
||||
|
@ -160,7 +193,8 @@
|
|||
* the size of the bank remains the same. The FPU has also a 32-bit
|
||||
* status register.
|
||||
*/
|
||||
#define portFPU_REGISTER_WORDS ( ( 16 * 2 ) + 1 )
|
||||
#define portFPU_REGISTER_WORDS ( ( 16 * 2 ) + 1 )
|
||||
#endif /* configUSE_TASK_FPU_SUPPORT != 0 */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -175,6 +209,8 @@ extern void vPortRestoreTaskContext( void );
|
|||
*/
|
||||
static void prvTaskExitError( void );
|
||||
|
||||
#if ( configUSE_TASK_FPU_SUPPORT != 0 )
|
||||
|
||||
/*
|
||||
* If the application provides an implementation of vApplicationIRQHandler(),
|
||||
* then it will get called directly without saving the FPU registers on
|
||||
|
@ -194,26 +230,36 @@ static void prvTaskExitError( void );
|
|||
* FPU registers to be saved on interrupt entry their IRQ handler must be
|
||||
* called vApplicationIRQHandler().
|
||||
*/
|
||||
void vApplicationFPUSafeIRQHandler( uint32_t ulICCIAR ) __attribute__((weak) );
|
||||
void vApplicationFPUSafeIRQHandler( uint32_t ulICCIAR ) __attribute__( ( weak ) );
|
||||
#endif /* configUSE_TASK_FPU_SUPPORT != 0 */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* A variable is used to keep track of the critical section nesting. This
|
||||
/*
|
||||
* A variable is used to keep track of the critical section nesting. 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
|
||||
* automatically be set to 0 when the first task is started. */
|
||||
* automatically be set to 0 when the first task is started.
|
||||
*/
|
||||
volatile uint32_t ulCriticalNesting = 9999UL;
|
||||
|
||||
/* Saved as part of the task context. If ulPortTaskHasFPUContext is non-zero then
|
||||
* a floating point context must be saved and restored for the task. */
|
||||
uint32_t ulPortTaskHasFPUContext = pdFALSE;
|
||||
#if ( configUSE_TASK_FPU_SUPPORT != 0 )
|
||||
|
||||
/*
|
||||
* Saved as part of the task context. If ulPortTaskHasFPUContext is non-zero then
|
||||
* a floating point context must be saved and restored for the task.
|
||||
*/
|
||||
uint32_t ulPortTaskHasFPUContext = pdFALSE;
|
||||
#endif /* configUSE_TASK_FPU_SUPPORT != 0 */
|
||||
|
||||
/* Set to 1 to pend a context switch from an ISR. */
|
||||
uint32_t ulPortYieldRequired = pdFALSE;
|
||||
|
||||
/* Counts the interrupt nesting depth. A context switch is only performed if
|
||||
* if the nesting depth is 0. */
|
||||
/*
|
||||
* Counts the interrupt nesting depth. A context switch is only performed if
|
||||
* if the nesting depth is 0.
|
||||
*/
|
||||
uint32_t ulPortInterruptNesting = 0UL;
|
||||
|
||||
/* Used in asm code. */
|
||||
|
@ -231,12 +277,14 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
|||
TaskFunction_t pxCode,
|
||||
void * pvParameters )
|
||||
{
|
||||
/* Setup the initial stack of the task. The stack is set exactly as
|
||||
/*
|
||||
* Setup the initial stack of the task. The stack is set exactly as
|
||||
* expected by the portRESTORE_CONTEXT() macro.
|
||||
*
|
||||
* The fist real value on the stack is the status register, which is set for
|
||||
* system mode, with interrupts enabled. A few NULLs are added first to ensure
|
||||
* GDB does not try decoding a non-existent return address. */
|
||||
* GDB does not try decoding a non-existent return address.
|
||||
*/
|
||||
*pxTopOfStack = ( StackType_t ) NULL;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) NULL;
|
||||
|
@ -285,24 +333,31 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
|||
*pxTopOfStack = ( StackType_t ) 0x01010101; /* R1 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* The task will start with a critical nesting count of 0 as interrupts are
|
||||
* enabled. */
|
||||
/*
|
||||
* The task will start with a critical nesting count of 0 as interrupts are
|
||||
* enabled.
|
||||
*/
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = portNO_CRITICAL_NESTING;
|
||||
|
||||
#if( configUSE_TASK_FPU_SUPPORT == 1 )
|
||||
#if ( configUSE_TASK_FPU_SUPPORT == 1 )
|
||||
{
|
||||
/* The task will start without a floating point context. A task that
|
||||
uses the floating point hardware must call vPortTaskUsesFPU() before
|
||||
executing any floating point instructions. */
|
||||
/*
|
||||
* The task will start without a floating point context.
|
||||
* A task that uses the floating point hardware must call
|
||||
* vPortTaskUsesFPU() before executing any floating point
|
||||
* instructions.
|
||||
*/
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
|
||||
}
|
||||
#elif( configUSE_TASK_FPU_SUPPORT == 2 )
|
||||
#elif ( configUSE_TASK_FPU_SUPPORT == 2 )
|
||||
{
|
||||
/* The task will start with a floating point context. Leave enough
|
||||
space for the registers - and ensure they are initialized to 0. */
|
||||
/*
|
||||
* The task will start with a floating point context. Leave enough
|
||||
* space for the registers and ensure they are initialized to 0.
|
||||
*/
|
||||
pxTopOfStack -= portFPU_REGISTER_WORDS;
|
||||
memset( pxTopOfStack, 0x00, portFPU_REGISTER_WORDS * sizeof( StackType_t ) );
|
||||
|
||||
|
@ -310,9 +365,9 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
|||
*pxTopOfStack = pdTRUE;
|
||||
ulPortTaskHasFPUContext = pdTRUE;
|
||||
}
|
||||
#else
|
||||
#elif ( configUSE_TASK_FPU_SUPPORT != 0 )
|
||||
{
|
||||
#error Invalid configUSE_TASK_FPU_SUPPORT setting - configUSE_TASK_FPU_SUPPORT must be set to 1, 2, or left undefined.
|
||||
#error Invalid configUSE_TASK_FPU_SUPPORT setting - configUSE_TASK_FPU_SUPPORT must be set to 0, 1, or 2.
|
||||
}
|
||||
#endif /* configUSE_TASK_FPU_SUPPORT */
|
||||
|
||||
|
@ -322,12 +377,14 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
|||
|
||||
static void prvTaskExitError( void )
|
||||
{
|
||||
/* A function that implements a task must not exit or attempt to return to
|
||||
/*
|
||||
* 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. */
|
||||
* defined, then stop here so application writers can catch the error.
|
||||
*/
|
||||
configASSERT( ulPortInterruptNesting == ~0UL );
|
||||
portDISABLE_INTERRUPTS();
|
||||
|
||||
|
@ -337,11 +394,15 @@ static void prvTaskExitError( void )
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vApplicationFPUSafeIRQHandler( uint32_t ulICCIAR )
|
||||
{
|
||||
#if ( configUSE_TASK_FPU_SUPPORT != 0 )
|
||||
|
||||
void vApplicationFPUSafeIRQHandler( uint32_t ulICCIAR ) /* __attribute__( ( weak ) ) */
|
||||
{
|
||||
( void ) ulICCIAR;
|
||||
configASSERT( ( volatile void * ) NULL );
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* configUSE_TASK_FPU_SUPPORT != 0 */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
|
@ -354,13 +415,16 @@ BaseType_t xPortStartScheduler( void )
|
|||
volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + portINTERRUPT_PRIORITY_REGISTER_OFFSET );
|
||||
volatile uint8_t ucMaxPriorityValue;
|
||||
|
||||
/* Determine how many priority bits are implemented in the GIC.
|
||||
*
|
||||
* Save the interrupt priority value that is about to be clobbered. */
|
||||
/*
|
||||
* Determine how many priority bits are implemented in the GIC.
|
||||
* Save the interrupt priority value that is about to be clobbered.
|
||||
*/
|
||||
ulOriginalPriority = *pucFirstUserPriorityRegister;
|
||||
|
||||
/* Determine the number of priority bits available. First write to
|
||||
* all possible bits. */
|
||||
/*
|
||||
* Determine the number of priority bits available. First write to
|
||||
* all possible bits.
|
||||
*/
|
||||
*pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
|
||||
|
||||
/* Read the value back to see how many bits stuck. */
|
||||
|
@ -371,8 +435,10 @@ BaseType_t xPortStartScheduler( void )
|
|||
{
|
||||
ucMaxPriorityValue >>= ( uint8_t ) 0x01;
|
||||
|
||||
/* If ulCycles reaches 0 then ucMaxPriorityValue must have been
|
||||
* read as 0, indicating a misconfiguration. */
|
||||
/*
|
||||
* If ulCycles reaches 0 then ucMaxPriorityValue must have been
|
||||
* read as 0, indicating a misconfiguration.
|
||||
*/
|
||||
ulCycles--;
|
||||
|
||||
if( ulCycles == 0 )
|
||||
|
@ -381,35 +447,45 @@ BaseType_t xPortStartScheduler( void )
|
|||
}
|
||||
}
|
||||
|
||||
/* Sanity check configUNIQUE_INTERRUPT_PRIORITIES matches the read
|
||||
* value. */
|
||||
/*
|
||||
* Sanity check configUNIQUE_INTERRUPT_PRIORITIES matches the read
|
||||
* value.
|
||||
*/
|
||||
configASSERT( ucMaxPriorityValue == portLOWEST_INTERRUPT_PRIORITY );
|
||||
|
||||
/* Restore the clobbered interrupt priority register to its original
|
||||
* value. */
|
||||
/*
|
||||
* Restore the clobbered interrupt priority register to its original
|
||||
* value.
|
||||
*/
|
||||
*pucFirstUserPriorityRegister = ulOriginalPriority;
|
||||
}
|
||||
#endif /* configASSERT_DEFINED */
|
||||
|
||||
/* Only continue if the CPU is not in User mode. The CPU must be in a
|
||||
* Privileged mode for the scheduler to start. */
|
||||
/*
|
||||
* Only continue if the CPU is not in User mode. The CPU must be in a
|
||||
* Privileged mode for the scheduler to start.
|
||||
*/
|
||||
__asm volatile ( "MRS %0, APSR" : "=r" ( ulAPSR )::"memory" );
|
||||
ulAPSR &= portAPSR_MODE_BITS_MASK;
|
||||
configASSERT( ulAPSR != portAPSR_USER_MODE );
|
||||
|
||||
if( ulAPSR != portAPSR_USER_MODE )
|
||||
{
|
||||
/* Only continue if the binary point value is set to its lowest possible
|
||||
/*
|
||||
* Only continue if the binary point value is set to its lowest possible
|
||||
* setting. See the comments in vPortValidateInterruptPriority() below for
|
||||
* more information. */
|
||||
* more information.
|
||||
*/
|
||||
configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE );
|
||||
|
||||
if( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE )
|
||||
{
|
||||
/* Interrupts are turned off in the CPU itself to ensure tick does
|
||||
/*
|
||||
* Interrupts are turned off in the CPU itself to ensure tick does
|
||||
* not execute while the scheduler is being started. Interrupts are
|
||||
* automatically turned back on in the CPU when the first task starts
|
||||
* executing. */
|
||||
* executing.
|
||||
*/
|
||||
portCPU_IRQ_DISABLE();
|
||||
|
||||
/* Start the timer that generates the tick ISR. */
|
||||
|
@ -420,20 +496,25 @@ BaseType_t xPortStartScheduler( void )
|
|||
}
|
||||
}
|
||||
|
||||
/* Will only get here if vTaskStartScheduler() was called with the CPU in
|
||||
/*
|
||||
* 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. */
|
||||
* defines their own exit address.
|
||||
*/
|
||||
( void ) prvTaskExitError;
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* Not implemented in ports where there is nothing to return to.
|
||||
* Artificially force an assert. */
|
||||
/*
|
||||
* Not implemented in ports where there is nothing to return to.
|
||||
* Artificially force an assert.
|
||||
*/
|
||||
configASSERT( ulCriticalNesting == 1000UL );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
@ -443,16 +524,20 @@ void vPortEnterCritical( void )
|
|||
/* Mask interrupts up to the max syscall interrupt priority. */
|
||||
ulPortSetInterruptMask();
|
||||
|
||||
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||
/*
|
||||
* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||
* directly. Increment ulCriticalNesting to keep a count of how many times
|
||||
* portENTER_CRITICAL() has been called. */
|
||||
* portENTER_CRITICAL() has been called.
|
||||
*/
|
||||
ulCriticalNesting++;
|
||||
|
||||
/* This is not the interrupt safe version of the enter critical function so
|
||||
/*
|
||||
* 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. */
|
||||
* assert function also uses a critical section.
|
||||
*/
|
||||
if( ulCriticalNesting == 1 )
|
||||
{
|
||||
configASSERT( ulPortInterruptNesting == 0 );
|
||||
|
@ -464,16 +549,19 @@ void vPortExitCritical( void )
|
|||
{
|
||||
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
|
||||
{
|
||||
/* Decrement the nesting count as the critical section is being
|
||||
* exited. */
|
||||
/* 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 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. */
|
||||
/*
|
||||
* Critical nesting has reached zero so all interrupt priorities
|
||||
* should be unmasked.
|
||||
*/
|
||||
portCLEAR_INTERRUPT_MASK();
|
||||
}
|
||||
}
|
||||
|
@ -482,11 +570,13 @@ void vPortExitCritical( void )
|
|||
|
||||
void FreeRTOS_Tick_Handler( void )
|
||||
{
|
||||
/* Set interrupt mask before altering scheduler structures. The tick
|
||||
/*
|
||||
* Set interrupt mask before altering scheduler structures. The tick
|
||||
* handler runs at the lowest priority, so interrupts cannot already be masked,
|
||||
* so there is no need to save and restore the current mask value. It is
|
||||
* necessary to turn off interrupts in the CPU itself while the ICCPMR is being
|
||||
* updated. */
|
||||
* updated.
|
||||
*/
|
||||
portCPU_IRQ_DISABLE();
|
||||
portICCPMR_PRIORITY_MASK_REGISTER = ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );
|
||||
__asm volatile ( "dsb \n"
|
||||
|
@ -505,21 +595,23 @@ void FreeRTOS_Tick_Handler( void )
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configUSE_TASK_FPU_SUPPORT != 2 )
|
||||
#if ( configUSE_TASK_FPU_SUPPORT == 1 )
|
||||
|
||||
void vPortTaskUsesFPU( void )
|
||||
{
|
||||
uint32_t ulInitialFPSCR = 0;
|
||||
|
||||
/* A task is registering the fact that it needs an FPU context. Set the
|
||||
* FPU flag (which is saved as part of the task context). */
|
||||
/*
|
||||
* A task is registering the fact that it needs an FPU context. Set the
|
||||
* FPU flag (which is saved as part of the task context).
|
||||
*/
|
||||
ulPortTaskHasFPUContext = pdTRUE;
|
||||
|
||||
/* Initialise the floating point status register. */
|
||||
__asm volatile ( "FMXR FPSCR, %0" ::"r" ( ulInitialFPSCR ) : "memory" );
|
||||
}
|
||||
|
||||
#endif /* configUSE_TASK_FPU_SUPPORT */
|
||||
#endif /* configUSE_TASK_FPU_SUPPORT == 1 */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortClearInterruptMask( uint32_t ulNewMaskValue )
|
||||
|
@ -535,8 +627,7 @@ uint32_t ulPortSetInterruptMask( void )
|
|||
{
|
||||
uint32_t ulReturn;
|
||||
|
||||
/* Interrupt in the CPU must be turned off while the ICCPMR is being
|
||||
* updated. */
|
||||
/* Interrupts must be masked while ICCPMR is updated. */
|
||||
portCPU_IRQ_DISABLE();
|
||||
|
||||
if( portICCPMR_PRIORITY_MASK_REGISTER == ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) )
|
||||
|
@ -562,7 +653,8 @@ uint32_t ulPortSetInterruptMask( void )
|
|||
|
||||
void vPortValidateInterruptPriority( void )
|
||||
{
|
||||
/* The following assertion will fail if a service routine (ISR) for
|
||||
/*
|
||||
* The following assertion will fail if a service routine (ISR) for
|
||||
* an interrupt that has been assigned a priority above
|
||||
* configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
|
||||
* function. ISR safe FreeRTOS API functions must *only* be called
|
||||
|
@ -575,11 +667,13 @@ uint32_t ulPortSetInterruptMask( void )
|
|||
* configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||
*
|
||||
* FreeRTOS maintains separate thread and ISR API functions to ensure
|
||||
* interrupt entry is as fast and simple as possible. */
|
||||
* interrupt entry is as fast and simple as possible.
|
||||
*/
|
||||
|
||||
configASSERT( portICCRPR_RUNNING_PRIORITY_REGISTER >= ( uint32_t ) ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) );
|
||||
|
||||
/* Priority grouping: The interrupt controller (GIC) allows the bits
|
||||
/*
|
||||
* Priority grouping: The interrupt controller (GIC) allows the bits
|
||||
* that define each interrupt's priority to be split between bits that
|
||||
* define the interrupt's pre-emption priority bits and bits that define
|
||||
* the interrupt's sub-priority. For simplicity all bits must be defined
|
||||
|
@ -588,7 +682,8 @@ uint32_t ulPortSetInterruptMask( void )
|
|||
*
|
||||
* The priority grouping is configured by the GIC's binary point register
|
||||
* (ICCBPR). Writing 0 to ICCBPR will ensure it is set to its lowest
|
||||
* possible value (which may be above 0). */
|
||||
* possible value (which may be above 0).
|
||||
*/
|
||||
configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE );
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,10 @@
|
|||
.extern vTaskSwitchContext
|
||||
.extern vApplicationIRQHandler
|
||||
.extern ulPortInterruptNesting
|
||||
|
||||
#if defined( __ARM_FP )
|
||||
.extern ulPortTaskHasFPUContext
|
||||
#endif /* __ARM_FP */
|
||||
|
||||
.global FreeRTOS_IRQ_Handler
|
||||
.global FreeRTOS_SWI_Handler
|
||||
|
@ -64,6 +67,7 @@
|
|||
LDR R1, [R2]
|
||||
PUSH {R1}
|
||||
|
||||
#if defined( __ARM_FP )
|
||||
/* Does the task have a floating point context that needs saving? If
|
||||
ulPortTaskHasFPUContext is 0 then no. */
|
||||
LDR R2, ulPortTaskHasFPUContextConst
|
||||
|
@ -73,11 +77,11 @@
|
|||
/* Save the floating point context, if any. */
|
||||
FMRXNE R1, FPSCR
|
||||
VPUSHNE {D0-D15}
|
||||
/*VPUSHNE {D16-D31}*/
|
||||
PUSHNE {R1}
|
||||
|
||||
/* Save ulPortTaskHasFPUContext itself. */
|
||||
PUSH {R3}
|
||||
#endif /* __ARM_FP */
|
||||
|
||||
/* Save the stack pointer in the TCB. */
|
||||
LDR R0, pxCurrentTCBConst
|
||||
|
@ -95,8 +99,11 @@
|
|||
LDR R1, [R0]
|
||||
LDR SP, [R1]
|
||||
|
||||
/* Is there a floating point context to restore? If the restored
|
||||
ulPortTaskHasFPUContext is zero then no. */
|
||||
#if defined( __ARM_FP )
|
||||
/*
|
||||
* Is there a floating point context to restore? If the restored
|
||||
* ulPortTaskHasFPUContext is zero then no.
|
||||
*/
|
||||
LDR R0, ulPortTaskHasFPUContextConst
|
||||
POP {R1}
|
||||
STR R1, [R0]
|
||||
|
@ -104,9 +111,9 @@
|
|||
|
||||
/* Restore the floating point context, if any. */
|
||||
POPNE {R0}
|
||||
/*VPOPNE {D16-D31}*/
|
||||
VPOPNE {D0-D15}
|
||||
VMSRNE FPSCR, R0
|
||||
#endif /* __ARM_FP */
|
||||
|
||||
/* Restore the critical section nesting depth. */
|
||||
LDR R0, ulCriticalNestingConst
|
||||
|
@ -132,8 +139,6 @@
|
|||
.endm
|
||||
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* SVC handler is used to start the scheduler.
|
||||
*****************************************************************************/
|
||||
|
@ -279,12 +284,14 @@ switch_before_exit:
|
|||
* FPU registers to be saved on interrupt entry their IRQ handler must be
|
||||
* called vApplicationIRQHandler().
|
||||
*****************************************************************************/
|
||||
|
||||
.align 4
|
||||
.weak vApplicationIRQHandler
|
||||
.type vApplicationIRQHandler, %function
|
||||
vApplicationIRQHandler:
|
||||
|
||||
PUSH {LR}
|
||||
|
||||
#if defined( __ARM_FP )
|
||||
FMRX R1, FPSCR
|
||||
VPUSH {D0-D15}
|
||||
PUSH {R1}
|
||||
|
@ -295,6 +302,7 @@ vApplicationIRQHandler:
|
|||
POP {R0}
|
||||
VPOP {D0-D15}
|
||||
VMSR FPSCR, R0
|
||||
#endif /* __ARM_FP */
|
||||
|
||||
POP {PC}
|
||||
|
||||
|
@ -303,11 +311,15 @@ ulICCEOIRConst: .word ulICCEOIR
|
|||
ulICCPMRConst: .word ulICCPMR
|
||||
pxCurrentTCBConst: .word pxCurrentTCB
|
||||
ulCriticalNestingConst: .word ulCriticalNesting
|
||||
ulPortTaskHasFPUContextConst: .word ulPortTaskHasFPUContext
|
||||
|
||||
#if defined( __ARM_FP )
|
||||
ulPortTaskHasFPUContextConst: .word ulPortTaskHasFPUContext
|
||||
vApplicationFPUSafeIRQHandlerConst: .word vApplicationFPUSafeIRQHandler
|
||||
#endif /* __ARM_FP */
|
||||
|
||||
ulMaxAPIPriorityMaskConst: .word ulMaxAPIPriorityMask
|
||||
vTaskSwitchContextConst: .word vTaskSwitchContext
|
||||
vApplicationIRQHandlerConst: .word vApplicationIRQHandler
|
||||
ulPortInterruptNestingConst: .word ulPortInterruptNesting
|
||||
vApplicationFPUSafeIRQHandlerConst: .word vApplicationFPUSafeIRQHandler
|
||||
|
||||
.end
|
||||
|
|
|
@ -27,11 +27,13 @@
|
|||
*/
|
||||
|
||||
#ifndef PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Port specific definitions.
|
||||
|
@ -44,34 +46,34 @@
|
|||
*/
|
||||
|
||||
/* Type definitions. */
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE long
|
||||
#define portCHAR char
|
||||
#define portFLOAT float
|
||||
#define portDOUBLE double
|
||||
#define portLONG long
|
||||
#define portSHORT short
|
||||
#define portSTACK_TYPE uint32_t
|
||||
#define portBASE_TYPE long
|
||||
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
typedef portSTACK_TYPE StackType_t;
|
||||
typedef long BaseType_t;
|
||||
typedef unsigned long UBaseType_t;
|
||||
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
typedef uint32_t TickType_t;
|
||||
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Hardware specifics. */
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 8
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task utilities. */
|
||||
|
||||
/* Called at the end of an ISR that can cause a context switch. */
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
||||
{ \
|
||||
extern uint32_t ulPortYieldRequired; \
|
||||
\
|
||||
|
@ -81,64 +83,75 @@
|
|||
} \
|
||||
}
|
||||
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
#define portYIELD() __asm volatile ( "SWI 0" ::: "memory" );
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
#define portYIELD() __asm volatile ( "SWI 0" ::: "memory" );
|
||||
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Critical section control
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
extern void vPortEnterCritical( void );
|
||||
extern void vPortExitCritical( void );
|
||||
extern uint32_t ulPortSetInterruptMask( void );
|
||||
extern void vPortClearInterruptMask( uint32_t ulNewMaskValue );
|
||||
extern void vPortInstallFreeRTOSVectorTable( void );
|
||||
extern void vPortEnterCritical( void );
|
||||
extern void vPortExitCritical( void );
|
||||
extern uint32_t ulPortSetInterruptMask( void );
|
||||
extern void vPortClearInterruptMask( uint32_t ulNewMaskValue );
|
||||
extern void vPortInstallFreeRTOSVectorTable( void );
|
||||
|
||||
/* These macros do not globally disable/enable interrupts. They do mask off
|
||||
* interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY. */
|
||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||
#define portDISABLE_INTERRUPTS() ulPortSetInterruptMask()
|
||||
#define portENABLE_INTERRUPTS() vPortClearInterruptMask( 0 )
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask()
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortClearInterruptMask( x )
|
||||
/*
|
||||
* These macros do not globally disable/enable interrupts. They do mask off
|
||||
* interrupts that have a priority below configMAX_API_CALL_INTERRUPT_PRIORITY.
|
||||
*/
|
||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||
#define portDISABLE_INTERRUPTS() ulPortSetInterruptMask()
|
||||
#define portENABLE_INTERRUPTS() vPortClearInterruptMask( 0 )
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask()
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vPortClearInterruptMask( x )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task function macros as described on the FreeRTOS.org WEB site. These are
|
||||
/*
|
||||
* Task function macros as described on the FreeRTOS.org WEB site. 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 )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
* macros is used.
|
||||
*/
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||
|
||||
/* Prototype of the FreeRTOS tick handler. This must be installed as the
|
||||
* handler for whichever peripheral is used to generate the RTOS tick. */
|
||||
void FreeRTOS_Tick_Handler( void );
|
||||
/*
|
||||
* Prototype of the FreeRTOS tick handler. This must be installed as the
|
||||
* handler for whichever peripheral is used to generate the RTOS tick.
|
||||
*/
|
||||
void FreeRTOS_Tick_Handler( void );
|
||||
|
||||
/* If configUSE_TASK_FPU_SUPPORT is set to 1 (or left undefined) then tasks are
|
||||
created without an FPU context and must call vPortTaskUsesFPU() to give
|
||||
themselves an FPU context before using any FPU instructions. If
|
||||
configUSE_TASK_FPU_SUPPORT is set to 2 then all tasks will have an FPU context
|
||||
by default. */
|
||||
#if( configUSE_TASK_FPU_SUPPORT != 2 )
|
||||
/*
|
||||
* If configUSE_TASK_FPU_SUPPORT is set to 1, then tasks are created without an
|
||||
* FPU context and must call vPortTaskUsesFPU() to allocate an FPU context
|
||||
* prior to any FPU instructions. If configUSE_TASK_FPU_SUPPORT is set to 2,
|
||||
* then all tasks have an FPU context allocated by default.
|
||||
*/
|
||||
#if ( configUSE_TASK_FPU_SUPPORT == 1 )
|
||||
void vPortTaskUsesFPU( void );
|
||||
#else
|
||||
/* Each task has an FPU context already, so define this function away to
|
||||
nothing to prevent it being called accidentally. */
|
||||
#define vPortTaskUsesFPU()
|
||||
#endif /* configUSE_TASK_FPU_SUPPORT */
|
||||
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
|
||||
#elif ( configUSE_TASK_FPU_SUPPORT == 2 )
|
||||
|
||||
#define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL )
|
||||
#define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL )
|
||||
/*
|
||||
* Each task has an FPU context already, so define this function away to
|
||||
* prevent it being called accidentally.
|
||||
*/
|
||||
#define vPortTaskUsesFPU()
|
||||
#define portTASK_USES_FLOATING_POINT()
|
||||
#endif /* configUSE_TASK_FPU_SUPPORT */
|
||||
|
||||
#define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL )
|
||||
#define portLOWEST_USABLE_INTERRUPT_PRIORITY ( portLOWEST_INTERRUPT_PRIORITY - 1UL )
|
||||
|
||||
/* Architecture specific optimisations. */
|
||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||
|
||||
/* Store/clear the ready priorities in a bit map. */
|
||||
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||
|
@ -148,57 +161,60 @@ by default. */
|
|||
|
||||
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __builtin_clz( uxReadyPriorities ) )
|
||||
|
||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||
|
||||
#ifdef configASSERT
|
||||
#ifdef configASSERT
|
||||
void vPortValidateInterruptPriority( void );
|
||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||
#endif /* configASSERT */
|
||||
#endif /* configASSERT */
|
||||
|
||||
#define portNOP() __asm volatile ( "NOP" )
|
||||
#define portNOP() __asm volatile ( "NOP" )
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern C */
|
||||
#endif
|
||||
|
||||
|
||||
/* The number of bits to shift for an interrupt priority is dependent on the
|
||||
* number of bits implemented by the interrupt controller. */
|
||||
#if configUNIQUE_INTERRUPT_PRIORITIES == 16
|
||||
/*
|
||||
* The number of bits to shift for an interrupt priority is dependent on the
|
||||
* number of bits implemented by the interrupt controller.
|
||||
*/
|
||||
#if configUNIQUE_INTERRUPT_PRIORITIES == 16
|
||||
#define portPRIORITY_SHIFT 4
|
||||
#define portMAX_BINARY_POINT_VALUE 3
|
||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 32
|
||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 32
|
||||
#define portPRIORITY_SHIFT 3
|
||||
#define portMAX_BINARY_POINT_VALUE 2
|
||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 64
|
||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 64
|
||||
#define portPRIORITY_SHIFT 2
|
||||
#define portMAX_BINARY_POINT_VALUE 1
|
||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 128
|
||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 128
|
||||
#define portPRIORITY_SHIFT 1
|
||||
#define portMAX_BINARY_POINT_VALUE 0
|
||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 256
|
||||
#elif configUNIQUE_INTERRUPT_PRIORITIES == 256
|
||||
#define portPRIORITY_SHIFT 0
|
||||
#define portMAX_BINARY_POINT_VALUE 0
|
||||
#else /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */
|
||||
#else /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */
|
||||
#error Invalid configUNIQUE_INTERRUPT_PRIORITIES setting. configUNIQUE_INTERRUPT_PRIORITIES must be set to the number of unique priorities implemented by the target hardware
|
||||
#endif /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */
|
||||
#endif /* if configUNIQUE_INTERRUPT_PRIORITIES == 16 */
|
||||
|
||||
/* Interrupt controller access addresses. */
|
||||
#define portICCPMR_PRIORITY_MASK_OFFSET ( 0x04 )
|
||||
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET ( 0x0C )
|
||||
#define portICCEOIR_END_OF_INTERRUPT_OFFSET ( 0x10 )
|
||||
#define portICCBPR_BINARY_POINT_OFFSET ( 0x08 )
|
||||
#define portICCRPR_RUNNING_PRIORITY_OFFSET ( 0x14 )
|
||||
#define portICCPMR_PRIORITY_MASK_OFFSET ( 0x04 )
|
||||
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET ( 0x0C )
|
||||
#define portICCEOIR_END_OF_INTERRUPT_OFFSET ( 0x10 )
|
||||
#define portICCBPR_BINARY_POINT_OFFSET ( 0x08 )
|
||||
#define portICCRPR_RUNNING_PRIORITY_OFFSET ( 0x14 )
|
||||
|
||||
#define portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET )
|
||||
#define portICCPMR_PRIORITY_MASK_REGISTER ( *( ( volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET ) ) )
|
||||
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET )
|
||||
#define portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCEOIR_END_OF_INTERRUPT_OFFSET )
|
||||
#define portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET )
|
||||
#define portICCBPR_BINARY_POINT_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCBPR_BINARY_POINT_OFFSET ) ) )
|
||||
#define portICCRPR_RUNNING_PRIORITY_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCRPR_RUNNING_PRIORITY_OFFSET ) ) )
|
||||
#define portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET )
|
||||
#define portICCPMR_PRIORITY_MASK_REGISTER ( *( ( volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET ) ) )
|
||||
#define portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCIAR_INTERRUPT_ACKNOWLEDGE_OFFSET )
|
||||
#define portICCEOIR_END_OF_INTERRUPT_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCEOIR_END_OF_INTERRUPT_OFFSET )
|
||||
#define portICCPMR_PRIORITY_MASK_REGISTER_ADDRESS ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCPMR_PRIORITY_MASK_OFFSET )
|
||||
#define portICCBPR_BINARY_POINT_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCBPR_BINARY_POINT_OFFSET ) ) )
|
||||
#define portICCRPR_RUNNING_PRIORITY_REGISTER ( *( ( const volatile uint32_t * ) ( portINTERRUPT_CONTROLLER_CPU_INTERFACE_ADDRESS + portICCRPR_RUNNING_PRIORITY_OFFSET ) ) )
|
||||
|
||||
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
||||
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
} /* extern C */
|
||||
#endif
|
||||
/* *INDENT-ON* */
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
|
Loading…
Reference in a new issue