]> git.sur5r.net Git - freertos/commitdiff
Continue work on GCC/Cortex-A port layer.
authorrtel <rtel@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Fri, 24 Jan 2014 13:27:56 +0000 (13:27 +0000)
committerrtel <rtel@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Fri, 24 Jan 2014 13:27:56 +0000 (13:27 +0000)
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2177 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

FreeRTOS/Source/portable/GCC/ARM_CA9/port.c
FreeRTOS/Source/portable/GCC/ARM_CA9/portASM.S

index b05eedecf8da40e0415ffea7690b1fa10f886800..5c6c49b0b1b8810b733575fbcc34d2378269aa12 100644 (file)
@@ -147,18 +147,28 @@ point is zero. */
 mode. */\r
 #define portAPSR_USER_MODE                             ( 0x10 )\r
 \r
+/* The critical section macros only mask interrupts up to an application\r
+determined priority level.  Sometimes it is necessary to turn interrupt off in\r
+the CPU itself before modifying certain hardware registers. */\r
+#define portCPU_IRQ_DISABLE()                                                                          \\r
+       __asm volatile ( "CPSID i" );                                                                                   \\r
+       __asm volatile ( "DSB" );                                                                                               \\r
+       __asm volatile ( "ISB" );\r
+\r
+#define portCPU_IRQ_ENABLE()                                                                           \\r
+       __asm volatile ( "CPSIE i" );                                                                                   \\r
+       __asm volatile ( "DSB" );                                                                                               \\r
+       __asm volatile ( "ISB" );\r
+\r
+\r
 /* Macro to unmask all interrupt priorities. */\r
 #define portCLEAR_INTERRUPT_MASK()                                                                                     \\r
 {                                                                                                                                                      \\r
-       __asm volatile ( "cpsid i" );                                                                                   \\r
-       __asm volatile ( "dsb" );                                                                                               \\r
-       __asm volatile ( "isb" );                                                                                               \\r
+       portCPU_IRQ_DISABLE();                                                                                  \\r
        portICCPMR_PRIORITY_MASK_REGISTER = portUNMASK_VALUE;                                   \\r
        __asm(  "DSB            \n"                                                                                                     \\r
                        "ISB            \n" );                                                                                          \\r
-       __asm volatile( "cpsie i" );                                                                                    \\r
-       __asm volatile ( "dsb" );                                                                                               \\r
-       __asm volatile ( "isb" );                                                                                               \\r
+       portCPU_IRQ_ENABLE();                                                                                   \\r
 }\r
 \r
 #define portINTERRUPT_PRIORITY_REGISTER_OFFSET         0x400UL\r
@@ -322,6 +332,8 @@ uint32_t ulAPSR;
 \r
        #if configINSTALL_FREERTOS_VECTOR_TABLE == 1\r
        {\r
+               extern void vPortInstallFreeRTOSVectorTable( void );\r
+\r
                vPortInstallFreeRTOSVectorTable();\r
        }\r
        #endif\r
@@ -336,11 +348,12 @@ uint32_t ulAPSR;
 \r
                if( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE )\r
                {\r
-                       /* Start the timer that generates the tick ISR. */\r
-                       __asm volatile( "cpsid i" );\r
+                       /* Start the timer that generates the tick ISR.  Interrupts are\r
+                       turned off in the CPU itself to ensure the tick does not execute\r
+                       while the scheduler is being started.  Interrupts are automatically\r
+                       turned back on in the CPU when the first task starts executing. */\r
+                       portCPU_IRQ_DISABLE();\r
                        configSETUP_TICK_INTERRUPT();\r
-\r
-//                     __asm volatile( "cpsie i" );\r
                        vPortRestoreTaskContext();\r
                }\r
        }\r
@@ -362,7 +375,7 @@ void vPortEndScheduler( void )
 \r
 void vPortEnterCritical( void )\r
 {\r
-       /* Disable interrupts as per portDISABLE_INTERRUPTS();  */\r
+       /* Mask interrupts up to the max syscall interrupt priority. */\r
        ulPortSetInterruptMask();\r
 \r
        /* Now interrupts are disabled ulCriticalNesting can be accessed\r
@@ -396,16 +409,14 @@ void FreeRTOS_Tick_Handler( void )
 {\r
        /* Set interrupt mask before altering scheduler structures.   The tick\r
        handler runs at the lowest priority, so interrupts cannot already be masked,\r
-       so there is no need to save and restore the current mask value. */\r
-       __asm volatile( "cpsid i" );\r
-       __asm volatile ( "dsb" );\r
-       __asm volatile ( "isb" );\r
+       so there is no need to save and restore the current mask value.  It is\r
+       necessary to turn off interrupts in the CPU itself while the ICCPMR is being\r
+       updated. */\r
+       portCPU_IRQ_DISABLE();\r
        portICCPMR_PRIORITY_MASK_REGISTER = ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT );\r
        __asm(  "dsb            \n"\r
-                       "isb            \n"\r
-                       "cpsie i        \n"\r
-                       "dsb            \n"\r
-                       "isb" );\r
+                       "isb            \n" );\r
+       portCPU_IRQ_ENABLE();\r
 \r
        /* Increment the RTOS tick. */\r
        if( xTaskIncrementTick() != pdFALSE )\r
@@ -444,9 +455,9 @@ uint32_t ulPortSetInterruptMask( void )
 {\r
 uint32_t ulReturn;\r
 \r
-       __asm volatile ( "cpsid i" );\r
-       __asm volatile ( "dsb" );\r
-       __asm volatile ( "isb" );\r
+       /* Interrupt in the CPU must be turned off while the ICCPMR is being\r
+       updated. */\r
+       portCPU_IRQ_DISABLE();\r
        if( portICCPMR_PRIORITY_MASK_REGISTER == ( configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT ) )\r
        {\r
                /* Interrupts were already masked. */\r
@@ -459,9 +470,7 @@ uint32_t ulReturn;
                __asm(  "dsb            \n"\r
                                "isb            \n" );\r
        }\r
-       __asm volatile ( "cpsie i" );\r
-       __asm volatile ( "dsb" );\r
-       __asm volatile ( "isb" );\r
+       portCPU_IRQ_ENABLE();\r
 \r
        return ulReturn;\r
 }\r
index eb8320a81ad6e6aafb887082d1f8f5de4fe48f74..27cf67abdc5eeb89af2650ed56b2e59ff0581fb0 100644 (file)
@@ -256,6 +256,8 @@ FreeRTOS_IRQ_Handler:
        ADD             sp, sp, r2\r
 \r
        CPSID   i\r
+       DSB\r
+       ISB\r
 \r
        /* Write the value read from ICCIAR to ICCEOIR. */\r
        LDR     r4, ulICCEOIRConst\r