mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-08-01 08:54:14 -04:00
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:
parent
ed399e801e
commit
73606369c4
9 changed files with 146 additions and 102 deletions
|
@ -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 );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue