\r
void vPortStartFirstTask( void )\r
{\r
+ /* The MSP stack is not reset as, unlike on M3/4 parts, there is no vector\r
+ table offset register that can be used to locate the initial stack value.\r
+ Not all M0 parts have the application vector table at address 0. */\r
__asm volatile(\r
- " movs r0, #0x00 \n" /* Locate the top of stack. */\r
- " ldr r0, [r0] \n"\r
- " msr msp, r0 \n" /* Set the msp back to the start of the stack. */\r
" cpsie i \n" /* Globally enable interrupts. */\r
" svc 0 \n" /* System call to start first task. */\r
" nop \n"\r
- );\r
+ );\r
}\r
/*-----------------------------------------------------------*/\r
\r
}\r
/*-----------------------------------------------------------*/\r
\r
+unsigned long ulSetInterruptMaskFromISR( void )\r
+{\r
+ __asm volatile(\r
+ " mrs r0, PRIMASK \n"\r
+ " cpsid i \n"\r
+ " bx lr "\r
+ );\r
+\r
+ /* To avoid compiler warnings. This line will never be reached. */\r
+ return 0;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vClearInterruptMaskFromISR( unsigned long ulMask )\r
+{\r
+ __asm volatile(\r
+ " msr PRIMASK, r0 \n"\r
+ " bx lr "\r
+ );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
void xPortPendSVHandler( void )\r
{\r
/* This is a naked function. */\r
\r
void xPortSysTickHandler( void )\r
{\r
-unsigned long ulDummy;\r
+unsigned long ulPreviousMask;\r
\r
- ulDummy = portSET_INTERRUPT_MASK_FROM_ISR();\r
+ ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();\r
{\r
/* Increment the RTOS tick. */\r
if( xTaskIncrementTick() != pdFALSE )\r
*(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;\r
}\r
}\r
- portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy );\r
+ portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );\r
}\r
/*-----------------------------------------------------------*/\r
\r
/* Critical section management. */\r
extern void vPortEnterCritical( void );\r
extern void vPortExitCritical( void );\r
-#define portSET_INTERRUPT_MASK() __asm volatile ( " cpsid i " )\r
-#define portCLEAR_INTERRUPT_MASK() __asm volatile ( " cpsie i " )\r
-#define portSET_INTERRUPT_MASK_FROM_ISR() 0;portSET_INTERRUPT_MASK()\r
-#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) portCLEAR_INTERRUPT_MASK();(void)x\r
-#define portDISABLE_INTERRUPTS() portSET_INTERRUPT_MASK()\r
-#define portENABLE_INTERRUPTS() portCLEAR_INTERRUPT_MASK()\r
+extern unsigned long ulSetInterruptMaskFromISR( void ) __attribute__((naked));\r
+extern void vClearInterruptMaskFromISR( unsigned long ulMask ) __attribute__((naked));\r
+\r
+#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR()\r
+#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x )\r
+#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " )\r
+#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " )\r
#define portENTER_CRITICAL() vPortEnterCritical()\r
#define portEXIT_CRITICAL() vPortExitCritical()\r
\r
pxTopOfStack -= 20;\r
\r
/* Fill the registers with known values to assist debugging. */\r
- pxTopOfStack[ 16 ] = portKERNEL_INTERRUPT_PRIORITY_LEVEL;\r
+ pxTopOfStack[ 16 ] = 0;\r
pxTopOfStack[ 15 ] = portINITIAL_PSR;\r
pxTopOfStack[ 14 ] = ( unsigned long ) pxCode;\r
pxTopOfStack[ 13 ] = 0x00000000UL; /* R15. */\r
/* Set-up the timer interrupt. */\r
prvSetupTimerInterrupt();\r
\r
- /* Enable the TRAP yield. */\r
- irq[ portIRQ_TRAP_YIELD ].ien = 1;\r
- irq[ portIRQ_TRAP_YIELD ].ipl = portKERNEL_INTERRUPT_PRIORITY_LEVEL;\r
-\r
/* Integrated Interrupt Controller: Enable all interrupts. */\r
ic->ien = 1;\r
\r
\r
/* Set the IRQ Handler priority and enable it. */\r
irq[ IRQ_COUNTER1 ].ien = 1;\r
- irq[ IRQ_COUNTER1 ].ipl = portKERNEL_INTERRUPT_PRIORITY_LEVEL;\r
}\r
/*-----------------------------------------------------------*/\r
\r
extern "C" {\r
#endif\r
\r
-#include <machine/ic.h>\r
+#include <machine/cpu.h>\r
\r
/*-----------------------------------------------------------\r
* Port specific definitions.\r
#define portNOP() __asm__ volatile ( "mov r0, r0" )\r
#define portCRITICAL_NESTING_IN_TCB 1\r
#define portIRQ_TRAP_YIELD 31\r
-#define portKERNEL_INTERRUPT_PRIORITY_LEVEL 0\r
-#define portSYSTEM_INTERRUPT_PRIORITY_LEVEL 0\r
/*-----------------------------------------------------------*/\r
\r
/* Task utilities. */\r
/*---------------------------------------------------------------------------*/\r
\r
/* Critical section management. */\r
-#define portDISABLE_INTERRUPTS() ic->cpl = ( portSYSTEM_INTERRUPT_PRIORITY_LEVEL + 1 )\r
-#define portENABLE_INTERRUPTS() ic->cpl = portKERNEL_INTERRUPT_PRIORITY_LEVEL\r
+#define portDISABLE_INTERRUPTS() cpu_int_disable()\r
+#define portENABLE_INTERRUPTS() cpu_int_enable()\r
\r
/*---------------------------------------------------------------------------*/\r
\r
\r
void xPortSysTickHandler( void )\r
{\r
-unsigned long ulDummy;\r
+unsigned long ulPreviousMask;\r
\r
- ulDummy = portSET_INTERRUPT_MASK_FROM_ISR();\r
+ ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();\r
{\r
/* Increment the RTOS tick. */\r
if( xTaskIncrementTick() != pdFALSE )\r
*(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;\r
}\r
}\r
- portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy );\r
+ portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );\r
}\r
/*-----------------------------------------------------------*/\r
\r
\r
#include <FreeRTOSConfig.h>\r
\r
-/* For backward compatibility, ensure configKERNEL_INTERRUPT_PRIORITY is\r
-defined. The value zero should also ensure backward compatibility.\r
-FreeRTOS.org versions prior to V4.3.0 did not include this definition. */\r
-#ifndef configKERNEL_INTERRUPT_PRIORITY\r
- #define configKERNEL_INTERRUPT_PRIORITY 0\r
-#endif\r
-\r
- \r
RSEG CODE:CODE(2)\r
thumb\r
\r
PUBLIC xPortPendSVHandler\r
PUBLIC vPortSVCHandler\r
PUBLIC vPortStartFirstTask\r
-\r
+ PUBLIC ulSetInterruptMaskFromISR\r
+ PUBLIC vClearInterruptMaskFromISR\r
\r
/*-----------------------------------------------------------*/\r
\r
vSetMSP\r
msr msp, r0\r
bx lr\r
- \r
+\r
/*-----------------------------------------------------------*/\r
\r
xPortPendSVHandler:\r
- mrs r0, psp \r
- \r
+ mrs r0, psp\r
+\r
ldr r3, =pxCurrentTCB /* Get the location of the current TCB. */\r
- ldr r2, [r3] \r
- \r
+ ldr r2, [r3]\r
+\r
subs r0, r0, #32 /* Make space for the remaining low registers. */\r
str r0, [r2] /* Save the new top of stack. */\r
stmia r0!, {r4-r7} /* Store the low registers that are not saved automatically. */\r
mov r4, r8 /* Store the high registers. */\r
- mov r5, r9 \r
- mov r6, r10 \r
- mov r7, r11 \r
- stmia r0!, {r4-r7} \r
- \r
- push {r3, r14} \r
- cpsid i \r
- bl vTaskSwitchContext \r
- cpsie i \r
+ mov r5, r9\r
+ mov r6, r10\r
+ mov r7, r11\r
+ stmia r0!, {r4-r7}\r
+\r
+ push {r3, r14}\r
+ cpsid i\r
+ bl vTaskSwitchContext\r
+ cpsie i\r
pop {r2, r3} /* lr goes in r3. r2 now holds tcb pointer. */\r
- \r
- ldr r1, [r2] \r
+\r
+ ldr r1, [r2]\r
ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */\r
adds r0, r0, #16 /* Move to the high registers. */\r
ldmia r0!, {r4-r7} /* Pop the high registers. */\r
- mov r8, r4 \r
- mov r9, r5 \r
- mov r10, r6 \r
- mov r11, r7 \r
- \r
+ mov r8, r4\r
+ mov r9, r5\r
+ mov r10, r6\r
+ mov r11, r7\r
+\r
msr psp, r0 /* Remember the new top of stack for the task. */\r
- \r
+\r
subs r0, r0, #32 /* Go back for the low registers that are not automatically restored. */\r
ldmia r0!, {r4-r7} /* Pop low registers. */\r
- \r
- bx r3 \r
+\r
+ bx r3\r
\r
/*-----------------------------------------------------------*/\r
\r
ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */\r
adds r0, r0, #16 /* Move to the high registers. */\r
ldmia r0!, {r4-r7} /* Pop the high registers. */\r
- mov r8, r4 \r
- mov r9, r5 \r
- mov r10, r6 \r
- mov r11, r7 \r
- \r
+ mov r8, r4\r
+ mov r9, r5\r
+ mov r10, r6\r
+ mov r11, r7\r
+\r
msr psp, r0 /* Remember the new top of stack for the task. */\r
- \r
+\r
subs r0, r0, #32 /* Go back for the low registers that are not automatically restored. */\r
ldmia r0!, {r4-r7} /* Pop low registers. */\r
mov r1, r14 /* OR R14 with 0x0d. */\r
- movs r0, #0x0d \r
- orrs r1, r0 \r
- bx r1 \r
+ movs r0, #0x0d\r
+ orrs r1, r0\r
+ bx r1\r
\r
/*-----------------------------------------------------------*/\r
\r
vPortStartFirstTask\r
- movs r0, #0x00 /* Locate the top of stack. */\r
- ldr r0, [r0] \r
- msr msp, r0 /* Set the msp back to the start of the stack. */\r
+ /* The MSP stack is not reset as, unlike on M3/4 parts, there is no vector\r
+ table offset register that can be used to locate the initial stack value.\r
+ Not all M0 parts have the application vector table at address 0. */\r
cpsie i /* Globally enable interrupts. */\r
svc 0 /* System call to start first task. */\r
- nop \r
- \r
+ nop\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+ulSetInterruptMaskFromISR\r
+ mrs r0, PRIMASK\r
+ cpsid i\r
+ bx lr\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+vClearInterruptMaskFromISR\r
+ msr PRIMASK, r0\r
+ bx lr\r
+\r
END\r
-
\ No newline at end of file
\r
extern void vPortEnterCritical( void );\r
extern void vPortExitCritical( void );\r
+extern unsigned long ulSetInterruptMaskFromISR( void );\r
+extern void vClearInterruptMaskFromISR( unsigned long ulMask );\r
\r
#define portDISABLE_INTERRUPTS() __asm volatile( "cpsid i" )\r
#define portENABLE_INTERRUPTS() __asm volatile( "cpsie i" )\r
#define portENTER_CRITICAL() vPortEnterCritical()\r
#define portEXIT_CRITICAL() vPortExitCritical()\r
-#define portSET_INTERRUPT_MASK_FROM_ISR() 0;portDISABLE_INTERRUPTS()\r
-#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) portENABLE_INTERRUPTS();(void)x\r
+#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR()\r
+#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x )\r
\r
/*-----------------------------------------------------------*/\r
\r
\r
#define portNOP()\r
\r
+/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in\r
+the source code because to do so would cause other compilers to generate\r
+warnings. */\r
+#pragma diag_suppress=Pa082\r
+\r
#ifdef __cplusplus\r
}\r
#endif\r
/*\r
* Start first task is a separate function so it can be tested in isolation.\r
*/\r
-static void vPortStartFirstTask( void );\r
+static void prvPortStartFirstTask( void );\r
\r
/*-----------------------------------------------------------*/\r
\r
\r
PRESERVE8\r
\r
- ldr r3, =pxCurrentTCB /* Restore the context. */\r
- ldr r1, [r3] /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */\r
+ ldr r3, =pxCurrentTCB /* Obtain location of pxCurrentTCB. */\r
+ ldr r1, [r3] \r
ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */\r
- adds r0, #16 /* Move to the high registers. */\r
- ldmia r0!, {r4-r7} /* Pop the high registers. */\r
+ adds r0, #16 /* Pop the high registers. */\r
+ ldmia r0!, {r4-r7} \r
mov r8, r4\r
mov r9, r5\r
mov r10, r6\r
movs r0, #0x0d\r
orrs r1, r0\r
bx r1\r
- nop\r
+ ALIGN\r
}\r
/*-----------------------------------------------------------*/\r
\r
-__asm void vPortStartFirstTask( void )\r
+__asm void prvPortStartFirstTask( void )\r
{\r
PRESERVE8\r
-\r
- movs r0, #0x00 /* Locate the top of stack. */\r
- ldr r0, [r0]\r
- msr msp, r0 /* Set the msp back to the start of the stack. */\r
- cpsie i /* Globally enable interrupts. */\r
- svc 0 /* System call to start first task. */\r
- nop\r
+ \r
+ /* The MSP stack is not reset as, unlike on M3/4 parts, there is no vector\r
+ table offset register that can be used to locate the initial stack value.\r
+ Not all M0 parts have the application vector table at address 0. */\r
+ cpsie i /* Globally enable interrupts. */\r
+ svc 0 /* System call to start first task. */\r
+ ALIGN\r
}\r
/*-----------------------------------------------------------*/\r
\r
uxCriticalNesting = 0;\r
\r
/* Start the first task. */\r
- vPortStartFirstTask();\r
+ prvPortStartFirstTask();\r
\r
/* Should not get here! */\r
return 0;\r
}\r
/*-----------------------------------------------------------*/\r
\r
+__asm unsigned long ulSetInterruptMaskFromISR( void )\r
+{\r
+ mrs r0, PRIMASK\r
+ cpsid i\r
+ bx lr\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+__asm void vClearInterruptMaskFromISR( unsigned long ulMask )\r
+{\r
+ msr PRIMASK, r0\r
+ bx lr\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
__asm void xPortPendSVHandler( void )\r
{\r
extern vTaskSwitchContext\r
ldmia r0!, {r4-r7} /* Pop low registers. */\r
\r
bx r3\r
+ ALIGN\r
}\r
/*-----------------------------------------------------------*/\r
\r
void xPortSysTickHandler( void )\r
{\r
-unsigned long ulDummy;\r
+unsigned long ulPreviousMask;\r
\r
- ulDummy = portSET_INTERRUPT_MASK_FROM_ISR();\r
+ ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();\r
{\r
/* Increment the RTOS tick. */\r
if( xTaskIncrementTick() != pdFALSE )\r
*(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;\r
}\r
}\r
- portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy );\r
+ portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );\r
}\r
/*-----------------------------------------------------------*/\r
\r
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )\r
/*-----------------------------------------------------------*/\r
\r
-\r
/* Critical section management. */\r
extern void vPortEnterCritical( void );\r
extern void vPortExitCritical( void );\r
-#define portSET_INTERRUPT_MASK() __disable_irq()\r
-#define portCLEAR_INTERRUPT_MASK() __enable_irq()\r
-#define portSET_INTERRUPT_MASK_FROM_ISR() 0;portSET_INTERRUPT_MASK()\r
-#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) portCLEAR_INTERRUPT_MASK();(void)x\r
-#define portDISABLE_INTERRUPTS() portSET_INTERRUPT_MASK()\r
-#define portENABLE_INTERRUPTS() portCLEAR_INTERRUPT_MASK()\r
+extern unsigned long ulSetInterruptMaskFromISR( void );\r
+extern void vClearInterruptMaskFromISR( unsigned long ulMask );\r
+\r
+#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR()\r
+#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x )\r
+#define portDISABLE_INTERRUPTS() __disable_irq()\r
+#define portENABLE_INTERRUPTS() __enable_irq()\r
#define portENTER_CRITICAL() vPortEnterCritical()\r
#define portEXIT_CRITICAL() vPortExitCritical()\r
\r