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