mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-05-03 11:50:59 -04:00
Update the GCC Cortex-A9 port to introduce a version of the IRQ handler that saves the FPU registers.
This commit is contained in:
parent
ac67c39be9
commit
345819d550
|
@ -147,7 +147,14 @@ void vClearTickInterrupt( void )
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vApplicationIRQHandler( uint32_t ulICCIAR )
|
||||
/* This is the callback function which is called by the FreeRTOS Cortex-A port
|
||||
layer in response to an interrupt. If the function is called
|
||||
vApplicationFPUSafeIRQHandler() then it is called after the floating point
|
||||
registers have been saved. If the function is called vApplicationIRQHandler()
|
||||
then it will be called without first having saved the FPU registers. See
|
||||
http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html for
|
||||
more information */
|
||||
void vApplicationFPUSafeIRQHandler( uint32_t ulICCIAR )
|
||||
{
|
||||
extern const XScuGic_Config XScuGic_ConfigTable[];
|
||||
static const XScuGic_VectorTableEntry *pxVectorTable = XScuGic_ConfigTable[ XPAR_SCUGIC_SINGLE_DEVICE_ID ].HandlerTable;
|
||||
|
@ -155,7 +162,7 @@ uint32_t ulInterruptID;
|
|||
const XScuGic_VectorTableEntry *pxVectorEntry;
|
||||
|
||||
/* Re-enable interrupts. */
|
||||
__asm ( "cpsie i" );
|
||||
__asm ( "cpsie i" );
|
||||
|
||||
/* The ID of the interrupt is obtained by bitwise anding the ICCIAR value
|
||||
with 0x3FF. */
|
||||
|
|
|
@ -202,6 +202,27 @@ extern void vPortRestoreTaskContext( void );
|
|||
*/
|
||||
static void prvTaskExitError( void );
|
||||
|
||||
/*
|
||||
* If the application provides an implementation of vApplicationIRQHandler(),
|
||||
* then it will get called directly without saving the FPU registers on
|
||||
* interrupt entry, and this weak implementation of
|
||||
* vApplicationFPUSafeIRQHandler() is just provided to remove linkage errors -
|
||||
* it should never actually get called so its implementation contains a
|
||||
* call to configASSERT() that will always fail.
|
||||
*
|
||||
* If the application provides its own implementation of
|
||||
* vApplicationFPUSafeIRQHandler() then the implementation of
|
||||
* vApplicationIRQHandler() provided in portASM.S will save the FPU registers
|
||||
* before calling it.
|
||||
*
|
||||
* Therefore, if the application writer wants FPU registers to be saved on
|
||||
* interrupt entry their IRQ handler must be called
|
||||
* vApplicationFPUSafeIRQHandler(), and if the application writer does not want
|
||||
* FPU registers to be saved on interrupt entry their IRQ handler must be
|
||||
* called vApplicationIRQHandler().
|
||||
*/
|
||||
void vApplicationFPUSafeIRQHandler( uint32_t ulICCIAR ) __attribute__((weak) );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* A variable is used to keep track of the critical section nesting. This
|
||||
|
@ -387,7 +408,7 @@ uint32_t ulAPSR;
|
|||
}
|
||||
}
|
||||
|
||||
/* Will only get here if xTaskStartScheduler() 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
|
||||
|
@ -555,3 +576,7 @@ uint32_t ulReturn;
|
|||
#endif /* configASSERT_DEFINED */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vApplicationFPUSafeIRQHandler( uint32_t ulICCIAR )
|
||||
{
|
||||
configASSERT( ( volatile void * ) NULL );
|
||||
}
|
||||
|
|
|
@ -289,6 +289,46 @@ switch_before_exit:
|
|||
next. */
|
||||
portRESTORE_CONTEXT
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* If the application provides an implementation of vApplicationIRQHandler(),
|
||||
* then it will get called directly without saving the FPU registers on
|
||||
* interrupt entry, and this weak implementation of
|
||||
* vApplicationIRQHandler() will not get called.
|
||||
*
|
||||
* If the application provides its own implementation of
|
||||
* vApplicationFPUSafeIRQHandler() then this implementation of
|
||||
* vApplicationIRQHandler() will be called, save the FPU registers, and then
|
||||
* call vApplicationFPUSafeIRQHandler().
|
||||
*
|
||||
* Therefore, if the application writer wants FPU registers to be saved on
|
||||
* interrupt entry their IRQ handler must be called
|
||||
* vApplicationFPUSafeIRQHandler(), and if the application writer does not want
|
||||
* 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}
|
||||
FMRX R1, FPSCR
|
||||
VPUSH {D0-D15}
|
||||
VPUSH {D16-D31}
|
||||
PUSH {R1}
|
||||
|
||||
LDR r1, vApplicationFPUSafeIRQHandlerConst
|
||||
BLX r1
|
||||
|
||||
POP {R0}
|
||||
VPOP {D16-D31}
|
||||
VPOP {D0-D15}
|
||||
VMSR FPSCR, R0
|
||||
|
||||
POP {PC}
|
||||
|
||||
|
||||
ulICCIARConst: .word ulICCIAR
|
||||
ulICCEOIRConst: .word ulICCEOIR
|
||||
ulICCPMRConst: .word ulICCPMR
|
||||
|
@ -299,6 +339,7 @@ ulMaxAPIPriorityMaskConst: .word ulMaxAPIPriorityMask
|
|||
vTaskSwitchContextConst: .word vTaskSwitchContext
|
||||
vApplicationIRQHandlerConst: .word vApplicationIRQHandler
|
||||
ulPortInterruptNestingConst: .word ulPortInterruptNesting
|
||||
vApplicationFPUSafeIRQHandlerConst: .word vApplicationFPUSafeIRQHandler
|
||||
|
||||
.end
|
||||
|
||||
|
|
|
@ -178,7 +178,7 @@ static void prvPortStartFirstTask( void ) __attribute__ (( naked ));
|
|||
/*
|
||||
* Function to enable the VFP.
|
||||
*/
|
||||
static void vPortEnableVFP( void ) __attribute__ (( naked ));
|
||||
static void vPortEnableVFP( void ) __attribute__ (( naked ));
|
||||
|
||||
/*
|
||||
* Used to catch tasks that attempt to return from their implementing function.
|
||||
|
|
|
@ -353,7 +353,7 @@ uint32_t ulAPSR;
|
|||
}
|
||||
}
|
||||
|
||||
/* Will only get here if xTaskStartScheduler() 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. */
|
||||
return 0;
|
||||
|
|
Loading…
Reference in a new issue