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.
This commit is contained in:
Richard Barry 2013-09-01 19:53:24 +00:00
parent ed399e801e
commit 73606369c4
9 changed files with 146 additions and 102 deletions

View file

@ -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 );
}
/*-----------------------------------------------------------*/

View file

@ -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()