mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-19 21:11:57 -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
|
@ -158,14 +158,14 @@ void vPortSVCHandler( void )
|
||||||
|
|
||||||
void vPortStartFirstTask( 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(
|
__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. */
|
" cpsie i \n" /* Globally enable interrupts. */
|
||||||
" svc 0 \n" /* System call to start first task. */
|
" svc 0 \n" /* System call to start first task. */
|
||||||
" nop \n"
|
" 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 )
|
void xPortPendSVHandler( void )
|
||||||
{
|
{
|
||||||
/* This is a naked function. */
|
/* This is a naked function. */
|
||||||
|
@ -281,9 +303,9 @@ void xPortPendSVHandler( void )
|
||||||
|
|
||||||
void xPortSysTickHandler( 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. */
|
/* Increment the RTOS tick. */
|
||||||
if( xTaskIncrementTick() != pdFALSE )
|
if( xTaskIncrementTick() != pdFALSE )
|
||||||
|
@ -292,7 +314,7 @@ unsigned long ulDummy;
|
||||||
*(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;
|
*(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. */
|
/* Critical section management. */
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
#define portSET_INTERRUPT_MASK() __asm volatile ( " cpsid i " )
|
extern unsigned long ulSetInterruptMaskFromISR( void ) __attribute__((naked));
|
||||||
#define portCLEAR_INTERRUPT_MASK() __asm volatile ( " cpsie i " )
|
extern void vClearInterruptMaskFromISR( unsigned long ulMask ) __attribute__((naked));
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() 0;portSET_INTERRUPT_MASK()
|
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) portCLEAR_INTERRUPT_MASK();(void)x
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR()
|
||||||
#define portDISABLE_INTERRUPTS() portSET_INTERRUPT_MASK()
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x )
|
||||||
#define portENABLE_INTERRUPTS() portCLEAR_INTERRUPT_MASK()
|
#define portDISABLE_INTERRUPTS() __asm volatile ( " cpsid i " )
|
||||||
|
#define portENABLE_INTERRUPTS() __asm volatile ( " cpsie i " )
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,7 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE * pxTopOfStack, pdTASK_COD
|
||||||
pxTopOfStack -= 20;
|
pxTopOfStack -= 20;
|
||||||
|
|
||||||
/* Fill the registers with known values to assist debugging. */
|
/* Fill the registers with known values to assist debugging. */
|
||||||
pxTopOfStack[ 16 ] = portKERNEL_INTERRUPT_PRIORITY_LEVEL;
|
pxTopOfStack[ 16 ] = 0;
|
||||||
pxTopOfStack[ 15 ] = portINITIAL_PSR;
|
pxTopOfStack[ 15 ] = portINITIAL_PSR;
|
||||||
pxTopOfStack[ 14 ] = ( unsigned long ) pxCode;
|
pxTopOfStack[ 14 ] = ( unsigned long ) pxCode;
|
||||||
pxTopOfStack[ 13 ] = 0x00000000UL; /* R15. */
|
pxTopOfStack[ 13 ] = 0x00000000UL; /* R15. */
|
||||||
|
@ -119,10 +119,6 @@ portBASE_TYPE xPortStartScheduler( void )
|
||||||
/* Set-up the timer interrupt. */
|
/* Set-up the timer interrupt. */
|
||||||
prvSetupTimerInterrupt();
|
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. */
|
/* Integrated Interrupt Controller: Enable all interrupts. */
|
||||||
ic->ien = 1;
|
ic->ien = 1;
|
||||||
|
|
||||||
|
@ -143,7 +139,6 @@ static void prvSetupTimerInterrupt( void )
|
||||||
|
|
||||||
/* Set the IRQ Handler priority and enable it. */
|
/* Set the IRQ Handler priority and enable it. */
|
||||||
irq[ IRQ_COUNTER1 ].ien = 1;
|
irq[ IRQ_COUNTER1 ].ien = 1;
|
||||||
irq[ IRQ_COUNTER1 ].ipl = portKERNEL_INTERRUPT_PRIORITY_LEVEL;
|
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,7 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <machine/ic.h>
|
#include <machine/cpu.h>
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* Port specific definitions.
|
* Port specific definitions.
|
||||||
|
@ -106,8 +106,6 @@ extern "C" {
|
||||||
#define portNOP() __asm__ volatile ( "mov r0, r0" )
|
#define portNOP() __asm__ volatile ( "mov r0, r0" )
|
||||||
#define portCRITICAL_NESTING_IN_TCB 1
|
#define portCRITICAL_NESTING_IN_TCB 1
|
||||||
#define portIRQ_TRAP_YIELD 31
|
#define portIRQ_TRAP_YIELD 31
|
||||||
#define portKERNEL_INTERRUPT_PRIORITY_LEVEL 0
|
|
||||||
#define portSYSTEM_INTERRUPT_PRIORITY_LEVEL 0
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task utilities. */
|
/* Task utilities. */
|
||||||
|
@ -126,8 +124,8 @@ extern void vTaskExitCritical( void );
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/* Critical section management. */
|
/* Critical section management. */
|
||||||
#define portDISABLE_INTERRUPTS() ic->cpl = ( portSYSTEM_INTERRUPT_PRIORITY_LEVEL + 1 )
|
#define portDISABLE_INTERRUPTS() cpu_int_disable()
|
||||||
#define portENABLE_INTERRUPTS() ic->cpl = portKERNEL_INTERRUPT_PRIORITY_LEVEL
|
#define portENABLE_INTERRUPTS() cpu_int_enable()
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
|
@ -198,9 +198,9 @@ void vPortExitCritical( void )
|
||||||
|
|
||||||
void xPortSysTickHandler( 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. */
|
/* Increment the RTOS tick. */
|
||||||
if( xTaskIncrementTick() != pdFALSE )
|
if( xTaskIncrementTick() != pdFALSE )
|
||||||
|
@ -209,7 +209,7 @@ unsigned long ulDummy;
|
||||||
*(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;
|
*(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy );
|
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
|
@ -64,14 +64,6 @@
|
||||||
|
|
||||||
#include <FreeRTOSConfig.h>
|
#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)
|
RSEG CODE:CODE(2)
|
||||||
thumb
|
thumb
|
||||||
|
|
||||||
|
@ -83,52 +75,53 @@ FreeRTOS.org versions prior to V4.3.0 did not include this definition. */
|
||||||
PUBLIC xPortPendSVHandler
|
PUBLIC xPortPendSVHandler
|
||||||
PUBLIC vPortSVCHandler
|
PUBLIC vPortSVCHandler
|
||||||
PUBLIC vPortStartFirstTask
|
PUBLIC vPortStartFirstTask
|
||||||
|
PUBLIC ulSetInterruptMaskFromISR
|
||||||
|
PUBLIC vClearInterruptMaskFromISR
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
vSetMSP
|
vSetMSP
|
||||||
msr msp, r0
|
msr msp, r0
|
||||||
bx lr
|
bx lr
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
xPortPendSVHandler:
|
xPortPendSVHandler:
|
||||||
mrs r0, psp
|
mrs r0, psp
|
||||||
|
|
||||||
ldr r3, =pxCurrentTCB /* Get the location of the current TCB. */
|
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. */
|
subs r0, r0, #32 /* Make space for the remaining low registers. */
|
||||||
str r0, [r2] /* Save the new top of stack. */
|
str r0, [r2] /* Save the new top of stack. */
|
||||||
stmia r0!, {r4-r7} /* Store the low registers that are not saved automatically. */
|
stmia r0!, {r4-r7} /* Store the low registers that are not saved automatically. */
|
||||||
mov r4, r8 /* Store the high registers. */
|
mov r4, r8 /* Store the high registers. */
|
||||||
mov r5, r9
|
mov r5, r9
|
||||||
mov r6, r10
|
mov r6, r10
|
||||||
mov r7, r11
|
mov r7, r11
|
||||||
stmia r0!, {r4-r7}
|
stmia r0!, {r4-r7}
|
||||||
|
|
||||||
push {r3, r14}
|
push {r3, r14}
|
||||||
cpsid i
|
cpsid i
|
||||||
bl vTaskSwitchContext
|
bl vTaskSwitchContext
|
||||||
cpsie i
|
cpsie i
|
||||||
pop {r2, r3} /* lr goes in r3. r2 now holds tcb pointer. */
|
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. */
|
ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */
|
||||||
adds r0, r0, #16 /* Move to the high registers. */
|
adds r0, r0, #16 /* Move to the high registers. */
|
||||||
ldmia r0!, {r4-r7} /* Pop the high registers. */
|
ldmia r0!, {r4-r7} /* Pop the high registers. */
|
||||||
mov r8, r4
|
mov r8, r4
|
||||||
mov r9, r5
|
mov r9, r5
|
||||||
mov r10, r6
|
mov r10, r6
|
||||||
mov r11, r7
|
mov r11, r7
|
||||||
|
|
||||||
msr psp, r0 /* Remember the new top of stack for the task. */
|
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. */
|
subs r0, r0, #32 /* Go back for the low registers that are not automatically restored. */
|
||||||
ldmia r0!, {r4-r7} /* Pop low registers. */
|
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. */
|
ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */
|
||||||
adds r0, r0, #16 /* Move to the high registers. */
|
adds r0, r0, #16 /* Move to the high registers. */
|
||||||
ldmia r0!, {r4-r7} /* Pop the high registers. */
|
ldmia r0!, {r4-r7} /* Pop the high registers. */
|
||||||
mov r8, r4
|
mov r8, r4
|
||||||
mov r9, r5
|
mov r9, r5
|
||||||
mov r10, r6
|
mov r10, r6
|
||||||
mov r11, r7
|
mov r11, r7
|
||||||
|
|
||||||
msr psp, r0 /* Remember the new top of stack for the task. */
|
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. */
|
subs r0, r0, #32 /* Go back for the low registers that are not automatically restored. */
|
||||||
ldmia r0!, {r4-r7} /* Pop low registers. */
|
ldmia r0!, {r4-r7} /* Pop low registers. */
|
||||||
mov r1, r14 /* OR R14 with 0x0d. */
|
mov r1, r14 /* OR R14 with 0x0d. */
|
||||||
movs r0, #0x0d
|
movs r0, #0x0d
|
||||||
orrs r1, r0
|
orrs r1, r0
|
||||||
bx r1
|
bx r1
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
vPortStartFirstTask
|
vPortStartFirstTask
|
||||||
movs r0, #0x00 /* Locate the top of stack. */
|
/* The MSP stack is not reset as, unlike on M3/4 parts, there is no vector
|
||||||
ldr r0, [r0]
|
table offset register that can be used to locate the initial stack value.
|
||||||
msr msp, r0 /* Set the msp back to the start of the stack. */
|
Not all M0 parts have the application vector table at address 0. */
|
||||||
cpsie i /* Globally enable interrupts. */
|
cpsie i /* Globally enable interrupts. */
|
||||||
svc 0 /* System call to start first task. */
|
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
|
END
|
||||||
|
|
|
@ -119,13 +119,15 @@ extern void vPortYield( void );
|
||||||
|
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
|
extern unsigned long ulSetInterruptMaskFromISR( void );
|
||||||
|
extern void vClearInterruptMaskFromISR( unsigned long ulMask );
|
||||||
|
|
||||||
#define portDISABLE_INTERRUPTS() __asm volatile( "cpsid i" )
|
#define portDISABLE_INTERRUPTS() __asm volatile( "cpsid i" )
|
||||||
#define portENABLE_INTERRUPTS() __asm volatile( "cpsie i" )
|
#define portENABLE_INTERRUPTS() __asm volatile( "cpsie i" )
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() 0;portDISABLE_INTERRUPTS()
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR()
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) portENABLE_INTERRUPTS();(void)x
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x )
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -135,6 +137,11 @@ extern void vPortExitCritical( void );
|
||||||
|
|
||||||
#define portNOP()
|
#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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -108,7 +108,7 @@ void vPortSVCHandler( void );
|
||||||
/*
|
/*
|
||||||
* Start first task is a separate function so it can be tested in isolation.
|
* 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
|
PRESERVE8
|
||||||
|
|
||||||
ldr r3, =pxCurrentTCB /* Restore the context. */
|
ldr r3, =pxCurrentTCB /* Obtain location of pxCurrentTCB. */
|
||||||
ldr r1, [r3] /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */
|
ldr r1, [r3]
|
||||||
ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */
|
ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */
|
||||||
adds r0, #16 /* Move to the high registers. */
|
adds r0, #16 /* Pop the high registers. */
|
||||||
ldmia r0!, {r4-r7} /* Pop the high registers. */
|
ldmia r0!, {r4-r7}
|
||||||
mov r8, r4
|
mov r8, r4
|
||||||
mov r9, r5
|
mov r9, r5
|
||||||
mov r10, r6
|
mov r10, r6
|
||||||
|
@ -155,20 +155,20 @@ __asm void vPortSVCHandler( void )
|
||||||
movs r0, #0x0d
|
movs r0, #0x0d
|
||||||
orrs r1, r0
|
orrs r1, r0
|
||||||
bx r1
|
bx r1
|
||||||
nop
|
ALIGN
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
__asm void vPortStartFirstTask( void )
|
__asm void prvPortStartFirstTask( void )
|
||||||
{
|
{
|
||||||
PRESERVE8
|
PRESERVE8
|
||||||
|
|
||||||
movs r0, #0x00 /* Locate the top of stack. */
|
/* The MSP stack is not reset as, unlike on M3/4 parts, there is no vector
|
||||||
ldr r0, [r0]
|
table offset register that can be used to locate the initial stack value.
|
||||||
msr msp, r0 /* Set the msp back to the start of the stack. */
|
Not all M0 parts have the application vector table at address 0. */
|
||||||
cpsie i /* Globally enable interrupts. */
|
cpsie i /* Globally enable interrupts. */
|
||||||
svc 0 /* System call to start first task. */
|
svc 0 /* System call to start first task. */
|
||||||
nop
|
ALIGN
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -189,7 +189,7 @@ portBASE_TYPE xPortStartScheduler( void )
|
||||||
uxCriticalNesting = 0;
|
uxCriticalNesting = 0;
|
||||||
|
|
||||||
/* Start the first task. */
|
/* Start the first task. */
|
||||||
vPortStartFirstTask();
|
prvPortStartFirstTask();
|
||||||
|
|
||||||
/* Should not get here! */
|
/* Should not get here! */
|
||||||
return 0;
|
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 )
|
__asm void xPortPendSVHandler( void )
|
||||||
{
|
{
|
||||||
extern vTaskSwitchContext
|
extern vTaskSwitchContext
|
||||||
|
@ -276,14 +291,15 @@ __asm void xPortPendSVHandler( void )
|
||||||
ldmia r0!, {r4-r7} /* Pop low registers. */
|
ldmia r0!, {r4-r7} /* Pop low registers. */
|
||||||
|
|
||||||
bx r3
|
bx r3
|
||||||
|
ALIGN
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void xPortSysTickHandler( 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. */
|
/* Increment the RTOS tick. */
|
||||||
if( xTaskIncrementTick() != pdFALSE )
|
if( xTaskIncrementTick() != pdFALSE )
|
||||||
|
@ -292,7 +308,7 @@ unsigned long ulDummy;
|
||||||
*(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;
|
*(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy );
|
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
|
@ -114,16 +114,16 @@ extern void vPortYield( void );
|
||||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/* Critical section management. */
|
/* Critical section management. */
|
||||||
extern void vPortEnterCritical( void );
|
extern void vPortEnterCritical( void );
|
||||||
extern void vPortExitCritical( void );
|
extern void vPortExitCritical( void );
|
||||||
#define portSET_INTERRUPT_MASK() __disable_irq()
|
extern unsigned long ulSetInterruptMaskFromISR( void );
|
||||||
#define portCLEAR_INTERRUPT_MASK() __enable_irq()
|
extern void vClearInterruptMaskFromISR( unsigned long ulMask );
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() 0;portSET_INTERRUPT_MASK()
|
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) portCLEAR_INTERRUPT_MASK();(void)x
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR()
|
||||||
#define portDISABLE_INTERRUPTS() portSET_INTERRUPT_MASK()
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x )
|
||||||
#define portENABLE_INTERRUPTS() portCLEAR_INTERRUPT_MASK()
|
#define portDISABLE_INTERRUPTS() __disable_irq()
|
||||||
|
#define portENABLE_INTERRUPTS() __enable_irq()
|
||||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue