]> git.sur5r.net Git - freertos/commitdiff
Performance optimisation.
authorrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Sun, 23 Mar 2008 15:53:37 +0000 (15:53 +0000)
committerrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Sun, 23 Mar 2008 15:53:37 +0000 (15:53 +0000)
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@251 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

Source/portable/IAR/ARM_CM3/port.c
Source/portable/IAR/ARM_CM3/portasm.s

index 87caec32d2cbefd0a7f710b780da2d1c6ba3fe0a..1a744bcf5787288edc4e23dc79685ea2dea3c45a 100644 (file)
 \r
        ***************************************************************************\r
 \r
-       Please ensure to read the configuration and relevant port sections of the \r
+       Please ensure to read the configuration and relevant port sections of the\r
        online documentation.\r
 \r
        +++ http://www.FreeRTOS.org +++\r
-       Documentation, latest information, license and contact details.  \r
+       Documentation, latest information, license and contact details.\r
 \r
        +++ http://www.SafeRTOS.com +++\r
        A version that is certified for use in safety critical systems.\r
@@ -60,7 +60,6 @@
 #define portNVIC_SYSTICK_LOAD          ( ( volatile unsigned portLONG *) 0xe000e014 )\r
 #define portNVIC_INT_CTRL                      ( ( volatile unsigned portLONG *) 0xe000ed04 )\r
 #define portNVIC_SYSPRI2                       ( ( volatile unsigned portLONG *) 0xe000ed20 )\r
-#define portNVIC_SYSPRI1                       ( ( volatile unsigned portLONG *) 0xe000ed1c )\r
 #define portNVIC_SYSTICK_CLK           0x00000004\r
 #define portNVIC_SYSTICK_INT           0x00000002\r
 #define portNVIC_SYSTICK_ENABLE                0x00000001\r
@@ -88,16 +87,14 @@ unsigned portBASE_TYPE uxCriticalNesting = 0xaaaaaaaa;
 static void prvSetupTimerInterrupt( void );\r
 \r
 /*\r
- * Set the MSP/PSP to a known value.\r
+ * Exception handlers.\r
  */\r
-extern void vSetMSP( unsigned long ulValue );\r
-extern void vSetPSP( unsigned long ulValue );\r
+void xPortSysTickHandler( void );\r
 \r
 /*\r
- * Utilities called from the assembler code.\r
+ * Start first task is a separate function so it can be tested in isolation.\r
  */\r
-void vPortSwitchContext( void );\r
-void vPortIncrementTick( void );\r
+extern void vPortStartFirstTask( unsigned portLONG ulValue );\r
 \r
 /*-----------------------------------------------------------*/\r
 \r
@@ -112,7 +109,7 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE
        pxTopOfStack--;\r
        *pxTopOfStack = ( portSTACK_TYPE ) pxCode;      /* PC */\r
        pxTopOfStack--;\r
-       *pxTopOfStack = 0xfffffffd;     /* LR */\r
+       *pxTopOfStack = 0     /* LR */\r
        pxTopOfStack -= 5;      /* R12, R3, R2 and R1. */\r
        *pxTopOfStack = ( portSTACK_TYPE ) pvParameters;        /* R0 */\r
        pxTopOfStack -= 9;      /* R11, R10, R9, R8, R7, R6, R5 and R4. */\r
@@ -136,12 +133,7 @@ portBASE_TYPE xPortStartScheduler( void )
        prvSetupTimerInterrupt();\r
        \r
        /* Start the first task. */\r
-       vSetPSP( 0 );\r
-       vSetMSP( *((unsigned portLONG *) 0 ) );\r
-       *(portNVIC_INT_CTRL) |= portNVIC_PENDSVSET;\r
-\r
-       /* Enable interrupts */\r
-       portENABLE_INTERRUPTS();\r
+       vPortStartFirstTask( *((unsigned portLONG *) 0 ) );\r
 \r
        /* Should not get here! */\r
        return 0;\r
@@ -183,6 +175,16 @@ void vPortExitCritical( void )
 }\r
 /*-----------------------------------------------------------*/\r
 \r
+void xPortSysTickHandler( void )\r
+{\r
+       vTaskIncrementTick();\r
+       \r
+       /* If using preemption, also force a context switch. */\r
+       #if configUSE_PREEMPTION == 1\r
+               *(portNVIC_INT_CTRL) |= portNVIC_PENDSVSET;     \r
+       #endif\r
+}\r
+/*-----------------------------------------------------------*/\r
 \r
 /*\r
  * Setup the systick timer to generate the tick interrupts at the required\r
@@ -196,19 +198,3 @@ void prvSetupTimerInterrupt( void )
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-void vPortSwitchContext( void )\r
-{\r
-       vPortSetInterruptMask();\r
-       vTaskSwitchContext();\r
-       vPortClearInterruptMask();\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-void vPortIncrementTick( void )\r
-{\r
-       vPortSetInterruptMask();\r
-       vTaskIncrementTick();\r
-       vPortClearInterruptMask();\r
-}\r
-\r
-\r
index 32e79796b7f18fc872cd3bc08b538034d399d50b..ad2cde1fe9cbf345d49a1820e4edec9829cfe342 100644 (file)
 \r
        ***************************************************************************\r
 \r
-       Please ensure to read the configuration and relevant port sections of the \r
+       Please ensure to read the configuration and relevant port sections of the\r
        online documentation.\r
 \r
        +++ http://www.FreeRTOS.org +++\r
-       Documentation, latest information, license and contact details.  \r
+       Documentation, latest information, license and contact details.\r
 \r
        +++ http://www.SafeRTOS.com +++\r
        A version that is certified for use in safety critical systems.\r
@@ -61,23 +61,18 @@ FreeRTOS.org versions prior to V4.3.0 did not include this definition. */
        thumb\r
 \r
        EXTERN vPortYieldFromISR\r
-       EXTERN vPortSwitchContext\r
-       EXTERN vPortIncrementTick\r
        EXTERN uxCriticalNesting\r
        EXTERN pxCurrentTCB\r
+       EXTERN vTaskSwitchContext\r
 \r
-       PUBLIC vSetPSP\r
        PUBLIC vSetMSP\r
        PUBLIC xPortPendSVHandler\r
-       PUBLIC xPortSysTickHandler\r
        PUBLIC vPortSetInterruptMask\r
        PUBLIC vPortClearInterruptMask\r
+       PUBLIC vPortSVCHandler\r
+       PUBLIC vPortStartFirstTask\r
 \r
 \r
-vSetPSP:\r
-       msr psp, r0\r
-       bx lr\r
-       \r
 /*-----------------------------------------------------------*/\r
 \r
 vSetMSP\r
@@ -88,67 +83,34 @@ vSetMSP
 \r
 xPortPendSVHandler:\r
        mrs r0, psp                                             \r
-       cbz r0, no_save                                 \r
-       /* Save the context into the TCB. */\r
-       stmdb r0!, {r4-r11}                             \r
-       sub r0, r0, #0x04                                       \r
-       ldr r1, =uxCriticalNesting\r
-       ldr r2, =pxCurrentTCB           \r
-       ldr r1, [r1]                                    \r
-       ldr r2, [r2]                                    \r
-       str r1, [r0]                                    \r
-       str r0, [r2]                                    \r
-                                                                       \r
-no_save:\r
-       push {r14}                                              \r
-       bl vPortSwitchContext                   \r
-       pop {r14}                                               \r
-       /* Restore the context. */              \r
-       ldr r1, =pxCurrentTCB\r
+       ldr     r3, =pxCurrentTCB                       /* Get the location of the current TCB. */\r
+       ldr     r2, [r3]                                                \r
+\r
+       ldr r1, =uxCriticalNesting              /* Save the remaining registers and the critical nesting count onto the task stack. */\r
        ldr r1, [r1]                                    \r
-       ldr r0, [r1]                                    \r
-       ldmia r0!, {r1, r4-r11}                 \r
-       ldr r2, =uxCriticalNesting\r
-       str r1, [r2]                                    \r
+       stmdb r0!, {r1,r4-r11}                  \r
+       str r0, [r2]                                    /* Save the new top of stack into the first member of the TCB. */\r
+\r
+       stmdb sp!, {r3, r14}                    \r
+       bl vTaskSwitchContext                   \r
+       ldmia sp!, {r3, r14}                    \r
+\r
+       ldr r1, [r3]                                    \r
+       ldr r2, =uxCriticalNesting      \r
+       ldr r0, [r1]                                    /* The first item in pxCurrentTCB is the task top of stack. */\r
+       ldmia r0!, {r1, r4-r11}                 /* Pop the registers and the critical nesting count. */\r
+       str r1, [r2]                                    /* Save the new critical nesting value into ulCriticalNesting. */\r
        msr psp, r0                                             \r
-       orr r14, r14, #0xd                                      \r
-       /* Exit with interrupts in the state required by the task. */\r
-       cbnz r1, sv_disable_interrupts  \r
+       orr r14, r14, #13                       \r
+\r
+       cbnz r1, sv_disable_interrupts  /* If the nesting count is greater than 0 we need to exit with interrupts masked. */\r
        bx r14                                                  \r
-                                                                       \r
+\r
 sv_disable_interrupts:                         \r
        mov     r1, #configKERNEL_INTERRUPT_PRIORITY\r
-       msr     basepri, R1\r
+       msr     basepri, r1\r
        bx r14                                                  \r
 \r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-xPortSysTickHandler:\r
-       /* Call the scheduler tick function. */\r
-       push {r14}\r
-       bl vPortIncrementTick\r
-       pop {r14}\r
-       \r
-       /* If using preemption, also force a context switch. */\r
-       #if configUSE_PREEMPTION == 1\r
-               push {r14}\r
-               bl vPortYieldFromISR\r
-               pop {r14}\r
-       #endif\r
-\r
-       /* Exit with interrupts in the correct state. */\r
-    ldr r2, =uxCriticalNesting\r
-       ldr r2, [r2]\r
-       cbnz r2, tick_disable_interrupts\r
-       bx r14\r
-\r
-tick_disable_interrupts:\r
-       mov     r1, #configKERNEL_INTERRUPT_PRIORITY\r
-       msr     basepri, R1\r
-       \r
-       bx r14\r
-\r
 /*-----------------------------------------------------------*/\r
 \r
 vPortSetInterruptMask:\r
@@ -171,5 +133,23 @@ vPortClearInterruptMask:
 \r
 /*-----------------------------------------------------------*/\r
 \r
+vPortSVCHandler;\r
+       ldr     r3, =pxCurrentTCB\r
+       ldr r1, [r3]\r
+       ldr r0, [r1]\r
+       ldmia r0!, {r1, r4-r11}\r
+       ldr r2, =uxCriticalNesting\r
+       str r1, [r2]\r
+       msr psp, r0\r
+       orr r14, r14, #13\r
+       bx r14\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+vPortStartFirstTask\r
+       msr msp, r0\r
+       svc 0\r
+\r
+\r
        END\r
        
\ No newline at end of file