summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>2013-09-01 19:53:24 +0000
committerrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>2013-09-01 19:53:24 +0000
commita5b7736e101fc2638528e2d938953063fedfa7a0 (patch)
tree9d806fb46ec31aa86a69c7cecd0646f9f7b2b858
parent7ff65a76f259d74cb8502f543f050acc5ff92fd5 (diff)
downloadfreertos-a5b7736e101fc2638528e2d938953063fedfa7a0.tar.gz
Make Cortex-M0 set/clear interrupt flag from ISR functions nestable.
Don't reset the stack location when starting the scheduler in Cortex-M0 ports as the vector offset register is not implemented and XMC1000 devices have their application vector address somewhere other than 0x00. git-svn-id: http://svn.code.sf.net/p/freertos/code/trunk@2015 1d2547de-c912-0410-9cb9-b8ca96c0e9e2
-rw-r--r--FreeRTOS/Source/portable/GCC/ARM_CM0/port.c36
-rw-r--r--FreeRTOS/Source/portable/GCC/ARM_CM0/portmacro.h13
-rw-r--r--FreeRTOS/Source/portable/GCC/CORTUS_APS3/port.c7
-rw-r--r--FreeRTOS/Source/portable/GCC/CORTUS_APS3/portmacro.h8
-rw-r--r--FreeRTOS/Source/portable/IAR/ARM_CM0/port.c6
-rw-r--r--FreeRTOS/Source/portable/IAR/ARM_CM0/portasm.s101
-rw-r--r--FreeRTOS/Source/portable/IAR/ARM_CM0/portmacro.h11
-rw-r--r--FreeRTOS/Source/portable/RVDS/ARM_CM0/port.c52
-rw-r--r--FreeRTOS/Source/portable/RVDS/ARM_CM0/portmacro.h14
9 files changed, 146 insertions, 102 deletions
diff --git a/FreeRTOS/Source/portable/GCC/ARM_CM0/port.c b/FreeRTOS/Source/portable/GCC/ARM_CM0/port.c
index 8c4d78ead..6966c848e 100644
--- a/FreeRTOS/Source/portable/GCC/ARM_CM0/port.c
+++ b/FreeRTOS/Source/portable/GCC/ARM_CM0/port.c
@@ -158,14 +158,14 @@ void vPortSVCHandler( void )
void vPortStartFirstTask( void )
{
+ /* The MSP stack is not reset as, unlike on M3/4 parts, there is no vector
+ table offset register that can be used to locate the initial stack value.
+ Not all M0 parts have the application vector table at address 0. */
__asm volatile(
- " movs r0, #0x00 \n" /* Locate the top of stack. */
- " ldr r0, [r0] \n"
- " msr msp, r0 \n" /* Set the msp back to the start of the stack. */
" cpsie i \n" /* Globally enable interrupts. */
" svc 0 \n" /* System call to start first task. */
" nop \n"
- );
+ );
}
/*-----------------------------------------------------------*/
@@ -231,6 +231,28 @@ void vPortExitCritical( void )
}
/*-----------------------------------------------------------*/
+unsigned long ulSetInterruptMaskFromISR( void )
+{
+ __asm volatile(
+ " mrs r0, PRIMASK \n"
+ " cpsid i \n"
+ " bx lr "
+ );
+
+ /* To avoid compiler warnings. This line will never be reached. */
+ return 0;
+}
+/*-----------------------------------------------------------*/
+
+void vClearInterruptMaskFromISR( unsigned long ulMask )
+{
+ __asm volatile(
+ " msr PRIMASK, r0 \n"
+ " bx lr "
+ );
+}
+/*-----------------------------------------------------------*/
+
void xPortPendSVHandler( void )
{
/* This is a naked function. */
@@ -281,9 +303,9 @@ void xPortPendSVHandler( void )
void xPortSysTickHandler( void )
{
-unsigned long ulDummy;
+unsigned long ulPreviousMask;
- ulDummy = portSET_INTERRUPT_MASK_FROM_ISR();
+ ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
{
/* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE )
@@ -292,7 +314,7 @@ unsigned long ulDummy;
*(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;
}
}
- portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy );
+ portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );
}
/*-----------------------------------------------------------*/
diff --git a/FreeRTOS/Source/portable/GCC/ARM_CM0/portmacro.h b/FreeRTOS/Source/portable/GCC/ARM_CM0/portmacro.h
index d641bacfe..bc5c72f9d 100644
--- a/FreeRTOS/Source/portable/GCC/ARM_CM0/portmacro.h
+++ b/FreeRTOS/Source/portable/GCC/ARM_CM0/portmacro.h
@@ -118,12 +118,13 @@ extern void vPortYield( void );
/* Critical section management. */
extern void vPortEnterCritical( void );
extern void vPortExitCritical( void );
-#define portSET_INTERRUPT_MASK() __asm volatile ( " cpsid i " )
-#define portCLEAR_INTERRUPT_MASK() __asm volatile ( " cpsie i " )
-#define portSET_INTERRUPT_MASK_FROM_ISR() 0;portSET_INTERRUPT_MASK()
-#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) portCLEAR_INTERRUPT_MASK();(void)x
-#define portDISABLE_INTERRUPTS() portSET_INTERRUPT_MASK()
-#define portENABLE_INTERRUPTS() portCLEAR_INTERRUPT_MASK()
+extern unsigned long ulSetInterruptMaskFromISR( void ) __attribute__((naked));
+extern void vClearInterruptMaskFromISR( unsigned long ulMask ) __attribute__((naked));
+
+#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR()
+#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x )
+#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " )
+#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " )
#define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()
diff --git a/FreeRTOS/Source/portable/GCC/CORTUS_APS3/port.c b/FreeRTOS/Source/portable/GCC/CORTUS_APS3/port.c
index 0e0d9ab5f..22dbb38ce 100644
--- a/FreeRTOS/Source/portable/GCC/CORTUS_APS3/port.c
+++ b/FreeRTOS/Source/portable/GCC/CORTUS_APS3/port.c
@@ -92,7 +92,7 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE * pxTopOfStack, pdTASK_COD
pxTopOfStack -= 20;
/* Fill the registers with known values to assist debugging. */
- pxTopOfStack[ 16 ] = portKERNEL_INTERRUPT_PRIORITY_LEVEL;
+ pxTopOfStack[ 16 ] = 0;
pxTopOfStack[ 15 ] = portINITIAL_PSR;
pxTopOfStack[ 14 ] = ( unsigned long ) pxCode;
pxTopOfStack[ 13 ] = 0x00000000UL; /* R15. */
@@ -119,10 +119,6 @@ portBASE_TYPE xPortStartScheduler( void )
/* Set-up the timer interrupt. */
prvSetupTimerInterrupt();
- /* Enable the TRAP yield. */
- irq[ portIRQ_TRAP_YIELD ].ien = 1;
- irq[ portIRQ_TRAP_YIELD ].ipl = portKERNEL_INTERRUPT_PRIORITY_LEVEL;
-
/* Integrated Interrupt Controller: Enable all interrupts. */
ic->ien = 1;
@@ -143,7 +139,6 @@ static void prvSetupTimerInterrupt( void )
/* Set the IRQ Handler priority and enable it. */
irq[ IRQ_COUNTER1 ].ien = 1;
- irq[ IRQ_COUNTER1 ].ipl = portKERNEL_INTERRUPT_PRIORITY_LEVEL;
}
/*-----------------------------------------------------------*/
diff --git a/FreeRTOS/Source/portable/GCC/CORTUS_APS3/portmacro.h b/FreeRTOS/Source/portable/GCC/CORTUS_APS3/portmacro.h
index 1e7f2d23f..d0418266e 100644
--- a/FreeRTOS/Source/portable/GCC/CORTUS_APS3/portmacro.h
+++ b/FreeRTOS/Source/portable/GCC/CORTUS_APS3/portmacro.h
@@ -69,7 +69,7 @@
extern "C" {
#endif
-#include <machine/ic.h>
+#include <machine/cpu.h>
/*-----------------------------------------------------------
* Port specific definitions.
@@ -106,8 +106,6 @@ extern "C" {
#define portNOP() __asm__ volatile ( "mov r0, r0" )
#define portCRITICAL_NESTING_IN_TCB 1
#define portIRQ_TRAP_YIELD 31
-#define portKERNEL_INTERRUPT_PRIORITY_LEVEL 0
-#define portSYSTEM_INTERRUPT_PRIORITY_LEVEL 0
/*-----------------------------------------------------------*/
/* Task utilities. */
@@ -126,8 +124,8 @@ extern void vTaskExitCritical( void );
/*---------------------------------------------------------------------------*/
/* Critical section management. */
-#define portDISABLE_INTERRUPTS() ic->cpl = ( portSYSTEM_INTERRUPT_PRIORITY_LEVEL + 1 )
-#define portENABLE_INTERRUPTS() ic->cpl = portKERNEL_INTERRUPT_PRIORITY_LEVEL
+#define portDISABLE_INTERRUPTS() cpu_int_disable()
+#define portENABLE_INTERRUPTS() cpu_int_enable()
/*---------------------------------------------------------------------------*/
diff --git a/FreeRTOS/Source/portable/IAR/ARM_CM0/port.c b/FreeRTOS/Source/portable/IAR/ARM_CM0/port.c
index a652ea9a7..6b3cc4162 100644
--- a/FreeRTOS/Source/portable/IAR/ARM_CM0/port.c
+++ b/FreeRTOS/Source/portable/IAR/ARM_CM0/port.c
@@ -198,9 +198,9 @@ void vPortExitCritical( void )
void xPortSysTickHandler( void )
{
-unsigned long ulDummy;
+unsigned long ulPreviousMask;
- ulDummy = portSET_INTERRUPT_MASK_FROM_ISR();
+ ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
{
/* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE )
@@ -209,7 +209,7 @@ unsigned long ulDummy;
*(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;
}
}
- portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy );
+ portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );
}
/*-----------------------------------------------------------*/
diff --git a/FreeRTOS/Source/portable/IAR/ARM_CM0/portasm.s b/FreeRTOS/Source/portable/IAR/ARM_CM0/portasm.s
index 6bc3c8eff..741a2c605 100644
--- a/FreeRTOS/Source/portable/IAR/ARM_CM0/portasm.s
+++ b/FreeRTOS/Source/portable/IAR/ARM_CM0/portasm.s
@@ -64,14 +64,6 @@
#include <FreeRTOSConfig.h>
-/* For backward compatibility, ensure configKERNEL_INTERRUPT_PRIORITY is
-defined. The value zero should also ensure backward compatibility.
-FreeRTOS.org versions prior to V4.3.0 did not include this definition. */
-#ifndef configKERNEL_INTERRUPT_PRIORITY
- #define configKERNEL_INTERRUPT_PRIORITY 0
-#endif
-
-
RSEG CODE:CODE(2)
thumb
@@ -83,52 +75,53 @@ FreeRTOS.org versions prior to V4.3.0 did not include this definition. */
PUBLIC xPortPendSVHandler
PUBLIC vPortSVCHandler
PUBLIC vPortStartFirstTask
-
+ PUBLIC ulSetInterruptMaskFromISR
+ PUBLIC vClearInterruptMaskFromISR
/*-----------------------------------------------------------*/
vSetMSP
msr msp, r0
bx lr
-
+
/*-----------------------------------------------------------*/
xPortPendSVHandler:
- mrs r0, psp
-
+ mrs r0, psp
+
ldr r3, =pxCurrentTCB /* Get the location of the current TCB. */
- ldr r2, [r3]
-
+ ldr r2, [r3]
+
subs r0, r0, #32 /* Make space for the remaining low registers. */
str r0, [r2] /* Save the new top of stack. */
stmia r0!, {r4-r7} /* Store the low registers that are not saved automatically. */
mov r4, r8 /* Store the high registers. */
- mov r5, r9
- mov r6, r10
- mov r7, r11
- stmia r0!, {r4-r7}
-
- push {r3, r14}
- cpsid i
- bl vTaskSwitchContext
- cpsie i
+ mov r5, r9
+ mov r6, r10
+ mov r7, r11
+ stmia r0!, {r4-r7}
+
+ push {r3, r14}
+ cpsid i
+ bl vTaskSwitchContext
+ cpsie i
pop {r2, r3} /* lr goes in r3. r2 now holds tcb pointer. */
-
- ldr r1, [r2]
+
+ ldr r1, [r2]
ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */
adds r0, r0, #16 /* Move to the high registers. */
ldmia r0!, {r4-r7} /* Pop the high registers. */
- mov r8, r4
- mov r9, r5
- mov r10, r6
- mov r11, r7
-
+ mov r8, r4
+ mov r9, r5
+ mov r10, r6
+ mov r11, r7
+
msr psp, r0 /* Remember the new top of stack for the task. */
-
+
subs r0, r0, #32 /* Go back for the low registers that are not automatically restored. */
ldmia r0!, {r4-r7} /* Pop low registers. */
-
- bx r3
+
+ bx r3
/*-----------------------------------------------------------*/
@@ -138,29 +131,41 @@ vPortSVCHandler;
ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */
adds r0, r0, #16 /* Move to the high registers. */
ldmia r0!, {r4-r7} /* Pop the high registers. */
- mov r8, r4
- mov r9, r5
- mov r10, r6
- mov r11, r7
-
+ mov r8, r4
+ mov r9, r5
+ mov r10, r6
+ mov r11, r7
+
msr psp, r0 /* Remember the new top of stack for the task. */
-
+
subs r0, r0, #32 /* Go back for the low registers that are not automatically restored. */
ldmia r0!, {r4-r7} /* Pop low registers. */
mov r1, r14 /* OR R14 with 0x0d. */
- movs r0, #0x0d
- orrs r1, r0
- bx r1
+ movs r0, #0x0d
+ orrs r1, r0
+ bx r1
/*-----------------------------------------------------------*/
vPortStartFirstTask
- movs r0, #0x00 /* Locate the top of stack. */
- ldr r0, [r0]
- msr msp, r0 /* Set the msp back to the start of the stack. */
+ /* The MSP stack is not reset as, unlike on M3/4 parts, there is no vector
+ table offset register that can be used to locate the initial stack value.
+ Not all M0 parts have the application vector table at address 0. */
cpsie i /* Globally enable interrupts. */
svc 0 /* System call to start first task. */
- nop
-
+ nop
+
+/*-----------------------------------------------------------*/
+
+ulSetInterruptMaskFromISR
+ mrs r0, PRIMASK
+ cpsid i
+ bx lr
+
+/*-----------------------------------------------------------*/
+
+vClearInterruptMaskFromISR
+ msr PRIMASK, r0
+ bx lr
+
END
- \ No newline at end of file
diff --git a/FreeRTOS/Source/portable/IAR/ARM_CM0/portmacro.h b/FreeRTOS/Source/portable/IAR/ARM_CM0/portmacro.h
index f9577b296..4f46d038e 100644
--- a/FreeRTOS/Source/portable/IAR/ARM_CM0/portmacro.h
+++ b/FreeRTOS/Source/portable/IAR/ARM_CM0/portmacro.h
@@ -119,13 +119,15 @@ extern void vPortYield( void );
extern void vPortEnterCritical( void );
extern void vPortExitCritical( void );
+extern unsigned long ulSetInterruptMaskFromISR( void );
+extern void vClearInterruptMaskFromISR( unsigned long ulMask );
#define portDISABLE_INTERRUPTS() __asm volatile( "cpsid i" )
#define portENABLE_INTERRUPTS() __asm volatile( "cpsie i" )
#define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()
-#define portSET_INTERRUPT_MASK_FROM_ISR() 0;portDISABLE_INTERRUPTS()
-#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) portENABLE_INTERRUPTS();(void)x
+#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR()
+#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x )
/*-----------------------------------------------------------*/
@@ -135,6 +137,11 @@ extern void vPortExitCritical( void );
#define portNOP()
+/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in
+the source code because to do so would cause other compilers to generate
+warnings. */
+#pragma diag_suppress=Pa082
+
#ifdef __cplusplus
}
#endif
diff --git a/FreeRTOS/Source/portable/RVDS/ARM_CM0/port.c b/FreeRTOS/Source/portable/RVDS/ARM_CM0/port.c
index 4cee00c39..2c0169f7e 100644
--- a/FreeRTOS/Source/portable/RVDS/ARM_CM0/port.c
+++ b/FreeRTOS/Source/portable/RVDS/ARM_CM0/port.c
@@ -108,7 +108,7 @@ void vPortSVCHandler( void );
/*
* Start first task is a separate function so it can be tested in isolation.
*/
-static void vPortStartFirstTask( void );
+static void prvPortStartFirstTask( void );
/*-----------------------------------------------------------*/
@@ -137,11 +137,11 @@ __asm void vPortSVCHandler( void )
PRESERVE8
- ldr r3, =pxCurrentTCB /* Restore the context. */
- ldr r1, [r3] /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */
+ ldr r3, =pxCurrentTCB /* Obtain location of pxCurrentTCB. */
+ ldr r1, [r3]
ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */
- adds r0, #16 /* Move to the high registers. */
- ldmia r0!, {r4-r7} /* Pop the high registers. */
+ adds r0, #16 /* Pop the high registers. */
+ ldmia r0!, {r4-r7}
mov r8, r4
mov r9, r5
mov r10, r6
@@ -155,20 +155,20 @@ __asm void vPortSVCHandler( void )
movs r0, #0x0d
orrs r1, r0
bx r1
- nop
+ ALIGN
}
/*-----------------------------------------------------------*/
-__asm void vPortStartFirstTask( void )
+__asm void prvPortStartFirstTask( void )
{
PRESERVE8
-
- movs r0, #0x00 /* Locate the top of stack. */
- ldr r0, [r0]
- msr msp, r0 /* Set the msp back to the start of the stack. */
- cpsie i /* Globally enable interrupts. */
- svc 0 /* System call to start first task. */
- nop
+
+ /* The MSP stack is not reset as, unlike on M3/4 parts, there is no vector
+ table offset register that can be used to locate the initial stack value.
+ Not all M0 parts have the application vector table at address 0. */
+ cpsie i /* Globally enable interrupts. */
+ svc 0 /* System call to start first task. */
+ ALIGN
}
/*-----------------------------------------------------------*/
@@ -189,7 +189,7 @@ portBASE_TYPE xPortStartScheduler( void )
uxCriticalNesting = 0;
/* Start the first task. */
- vPortStartFirstTask();
+ prvPortStartFirstTask();
/* Should not get here! */
return 0;
@@ -234,6 +234,21 @@ void vPortExitCritical( void )
}
/*-----------------------------------------------------------*/
+__asm unsigned long ulSetInterruptMaskFromISR( void )
+{
+ mrs r0, PRIMASK
+ cpsid i
+ bx lr
+}
+/*-----------------------------------------------------------*/
+
+__asm void vClearInterruptMaskFromISR( unsigned long ulMask )
+{
+ msr PRIMASK, r0
+ bx lr
+}
+/*-----------------------------------------------------------*/
+
__asm void xPortPendSVHandler( void )
{
extern vTaskSwitchContext
@@ -276,14 +291,15 @@ __asm void xPortPendSVHandler( void )
ldmia r0!, {r4-r7} /* Pop low registers. */
bx r3
+ ALIGN
}
/*-----------------------------------------------------------*/
void xPortSysTickHandler( void )
{
-unsigned long ulDummy;
+unsigned long ulPreviousMask;
- ulDummy = portSET_INTERRUPT_MASK_FROM_ISR();
+ ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
{
/* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE )
@@ -292,7 +308,7 @@ unsigned long ulDummy;
*(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;
}
}
- portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy );
+ portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );
}
/*-----------------------------------------------------------*/
diff --git a/FreeRTOS/Source/portable/RVDS/ARM_CM0/portmacro.h b/FreeRTOS/Source/portable/RVDS/ARM_CM0/portmacro.h
index 8ab2dc79d..56d357d7e 100644
--- a/FreeRTOS/Source/portable/RVDS/ARM_CM0/portmacro.h
+++ b/FreeRTOS/Source/portable/RVDS/ARM_CM0/portmacro.h
@@ -114,16 +114,16 @@ extern void vPortYield( void );
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/
-
/* Critical section management. */
extern void vPortEnterCritical( void );
extern void vPortExitCritical( void );
-#define portSET_INTERRUPT_MASK() __disable_irq()
-#define portCLEAR_INTERRUPT_MASK() __enable_irq()
-#define portSET_INTERRUPT_MASK_FROM_ISR() 0;portSET_INTERRUPT_MASK()
-#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) portCLEAR_INTERRUPT_MASK();(void)x
-#define portDISABLE_INTERRUPTS() portSET_INTERRUPT_MASK()
-#define portENABLE_INTERRUPTS() portCLEAR_INTERRUPT_MASK()
+extern unsigned long ulSetInterruptMaskFromISR( void );
+extern void vClearInterruptMaskFromISR( unsigned long ulMask );
+
+#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR()
+#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x )
+#define portDISABLE_INTERRUPTS() __disable_irq()
+#define portENABLE_INTERRUPTS() __enable_irq()
#define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()