]> git.sur5r.net Git - freertos/commitdiff
Update the GCC Cortex-A9 port to introduce a version of the IRQ handler that saves...
authorrtel <rtel@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Sat, 23 Apr 2016 10:53:57 +0000 (10:53 +0000)
committerrtel <rtel@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Sat, 23 Apr 2016 10:53:57 +0000 (10:53 +0000)
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2447 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/FreeRTOS_tick_config.c
FreeRTOS/Source/portable/GCC/ARM_CA9/port.c
FreeRTOS/Source/portable/GCC/ARM_CA9/portASM.S
FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c
FreeRTOS/Source/portable/RVDS/ARM_CA9/port.c

index 24ed53b182dd86c36a5d369746b03c5e0d3c4db0..0b2507acc889f6b984b6cccb6aec0eacff4cb69f 100644 (file)
@@ -147,7 +147,14 @@ void vClearTickInterrupt( void )
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-void vApplicationIRQHandler( uint32_t ulICCIAR )\r
+/* This is the callback function which is called by the FreeRTOS Cortex-A port\r
+layer in response to an interrupt.  If the function is called\r
+vApplicationFPUSafeIRQHandler() then it is called after the floating point\r
+registers have been saved.  If the function is called vApplicationIRQHandler()\r
+then it will be called without first having saved the FPU registers.  See\r
+http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html for\r
+more information */\r
+void vApplicationFPUSafeIRQHandler( uint32_t ulICCIAR )\r
 {\r
 extern const XScuGic_Config XScuGic_ConfigTable[];\r
 static const XScuGic_VectorTableEntry *pxVectorTable = XScuGic_ConfigTable[ XPAR_SCUGIC_SINGLE_DEVICE_ID ].HandlerTable;\r
@@ -155,7 +162,7 @@ uint32_t ulInterruptID;
 const XScuGic_VectorTableEntry *pxVectorEntry;\r
 \r
        /* Re-enable interrupts. */\r
-    __asm ( "cpsie i" );\r
+       __asm ( "cpsie i" );\r
 \r
        /* The ID of the interrupt is obtained by bitwise anding the ICCIAR value\r
        with 0x3FF. */\r
index cb66a01c35a872eb561ec6f4fb8ef76c376fed6c..3e4d72cecd1ee1f094ab37a799e19edaa6655cba 100644 (file)
@@ -202,6 +202,27 @@ extern void vPortRestoreTaskContext( void );
  */\r
 static void prvTaskExitError( void );\r
 \r
+/*\r
+ * If the application provides an implementation of vApplicationIRQHandler(),\r
+ * then it will get called directly without saving the FPU registers on\r
+ * interrupt entry, and this weak implementation of \r
+ * vApplicationFPUSafeIRQHandler() is just provided to remove linkage errors -\r
+ * it should never actually get called so its implementation contains a\r
+ * call to configASSERT() that will always fail.\r
+ *\r
+ * If the application provides its own implementation of \r
+ * vApplicationFPUSafeIRQHandler() then the implementation of \r
+ * vApplicationIRQHandler() provided in portASM.S will save the FPU registers\r
+ * before calling it.\r
+ *\r
+ * Therefore, if the application writer wants FPU registers to be saved on\r
+ * interrupt entry their IRQ handler must be called \r
+ * vApplicationFPUSafeIRQHandler(), and if the application writer does not want\r
+ * FPU registers to be saved on interrupt entry their IRQ handler must be\r
+ * called vApplicationIRQHandler().\r
+ */\r
+void vApplicationFPUSafeIRQHandler( uint32_t ulICCIAR ) __attribute__((weak) );\r
+\r
 /*-----------------------------------------------------------*/\r
 \r
 /* A variable is used to keep track of the critical section nesting.  This\r
@@ -387,7 +408,7 @@ uint32_t ulAPSR;
                }\r
        }\r
 \r
-       /* Will only get here if xTaskStartScheduler() was called with the CPU in\r
+       /* Will only get here if vTaskStartScheduler() was called with the CPU in\r
        a non-privileged mode or the binary point register was not set to its lowest\r
        possible value.  prvTaskExitError() is referenced to prevent a compiler\r
        warning about it being defined but not referenced in the case that the user\r
@@ -555,3 +576,7 @@ uint32_t ulReturn;
 #endif /* configASSERT_DEFINED */\r
 /*-----------------------------------------------------------*/\r
 \r
+void vApplicationFPUSafeIRQHandler( uint32_t ulICCIAR )\r
+{\r
+       configASSERT( ( volatile void * ) NULL );\r
+}\r
index 6fbde1ea06d81e3989e7fd1ad5ec3de7ee9a0b6a..c561b7e584a68a9b8f1d41e3feff356a3f4a1291 100644 (file)
@@ -289,6 +289,46 @@ switch_before_exit:
        next. */\r
        portRESTORE_CONTEXT\r
 \r
+\r
+/******************************************************************************\r
+ * If the application provides an implementation of vApplicationIRQHandler(),\r
+ * then it will get called directly without saving the FPU registers on\r
+ * interrupt entry, and this weak implementation of\r
+ * vApplicationIRQHandler() will not get called.\r
+ *\r
+ * If the application provides its own implementation of\r
+ * vApplicationFPUSafeIRQHandler() then this implementation of\r
+ * vApplicationIRQHandler() will be called, save the FPU registers, and then\r
+ * call vApplicationFPUSafeIRQHandler().\r
+ *\r
+ * Therefore, if the application writer wants FPU registers to be saved on\r
+ * interrupt entry their IRQ handler must be called\r
+ * vApplicationFPUSafeIRQHandler(), and if the application writer does not want\r
+ * FPU registers to be saved on interrupt entry their IRQ handler must be\r
+ * called vApplicationIRQHandler().\r
+ *****************************************************************************/\r
+\r
+.align 4\r
+.weak vApplicationIRQHandler\r
+.type vApplicationIRQHandler, %function\r
+vApplicationIRQHandler:\r
+       PUSH    {LR}\r
+       FMRX    R1,  FPSCR\r
+       VPUSH   {D0-D15}\r
+       VPUSH   {D16-D31}\r
+       PUSH    {R1}\r
+\r
+       LDR             r1, vApplicationFPUSafeIRQHandlerConst\r
+       BLX             r1\r
+\r
+       POP             {R0}\r
+       VPOP    {D16-D31}\r
+       VPOP    {D0-D15}\r
+       VMSR    FPSCR, R0\r
+\r
+       POP {PC}\r
+\r
+\r
 ulICCIARConst: .word ulICCIAR\r
 ulICCEOIRConst:        .word ulICCEOIR\r
 ulICCPMRConst: .word ulICCPMR\r
@@ -299,6 +339,7 @@ ulMaxAPIPriorityMaskConst: .word ulMaxAPIPriorityMask
 vTaskSwitchContextConst: .word vTaskSwitchContext\r
 vApplicationIRQHandlerConst: .word vApplicationIRQHandler\r
 ulPortInterruptNestingConst: .word ulPortInterruptNesting\r
+vApplicationFPUSafeIRQHandlerConst: .word vApplicationFPUSafeIRQHandler\r
 \r
 .end\r
 \r
index 855a3b746f8a4fa70f9206c5069e379e01e10fc5..45a0e69e73aa75bc208ba713dbf814e5f5b3036d 100644 (file)
@@ -178,7 +178,7 @@ static void prvPortStartFirstTask( void ) __attribute__ (( naked ));
 /*\r
  * Function to enable the VFP.\r
  */\r
- static void vPortEnableVFP( void ) __attribute__ (( naked ));\r
+static void vPortEnableVFP( void ) __attribute__ (( naked ));\r
 \r
 /*\r
  * Used to catch tasks that attempt to return from their implementing function.\r
index 565a77832001c26ef67529f2e821ba4b48e7194e..007ecfcaca2c991176fdb890a02ad581b3214b03 100644 (file)
@@ -353,7 +353,7 @@ uint32_t ulAPSR;
                }\r
        }\r
 \r
-       /* Will only get here if xTaskStartScheduler() was called with the CPU in\r
+       /* Will only get here if vTaskStartScheduler() was called with the CPU in\r
        a non-privileged mode or the binary point register was not set to its lowest\r
        possible value. */\r
        return 0;\r