|
|
|
@ -120,6 +120,15 @@ occurred while the SysTick counter is stopped during tickless idle
|
|
|
|
|
calculations. */
|
|
|
|
|
#define portMISSED_COUNTS_FACTOR ( 45UL )
|
|
|
|
|
|
|
|
|
|
/* Let the user override the pre-loading of the initial LR with the address of
|
|
|
|
|
prvTaskExitError() in case is messes up unwinding of the stack in the
|
|
|
|
|
debugger. */
|
|
|
|
|
#ifdef configTASK_RETURN_ADDRESS
|
|
|
|
|
#define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS
|
|
|
|
|
#else
|
|
|
|
|
#define portTASK_RETURN_ADDRESS prvTaskExitError
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* Each task maintains its own interrupt status in the critical nesting
|
|
|
|
|
variable. */
|
|
|
|
|
static unsigned portBASE_TYPE uxCriticalNesting = 0xaaaaaaaa;
|
|
|
|
@ -148,6 +157,11 @@ static void prvPortStartFirstTask( void ) __attribute__ (( naked ));
|
|
|
|
|
*/
|
|
|
|
|
static void vPortEnableVFP( void ) __attribute__ (( naked ));
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Used to catch tasks that attempt to return from their implementing function.
|
|
|
|
|
*/
|
|
|
|
|
static void prvTaskExitError( void );
|
|
|
|
|
|
|
|
|
|
/*-----------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@ -174,7 +188,7 @@ static void prvPortStartFirstTask( void ) __attribute__ (( naked ));
|
|
|
|
|
#endif /* configUSE_TICKLESS_IDLE */
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure
|
|
|
|
|
* Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure
|
|
|
|
|
* FreeRTOS API functions are not called from interrupts that have been assigned
|
|
|
|
|
* a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
|
|
|
|
*/
|
|
|
|
@ -202,7 +216,7 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE
|
|
|
|
|
pxTopOfStack--;
|
|
|
|
|
*pxTopOfStack = ( portSTACK_TYPE ) pxCode; /* PC */
|
|
|
|
|
pxTopOfStack--;
|
|
|
|
|
*pxTopOfStack = 0; /* LR */
|
|
|
|
|
*pxTopOfStack = ( portSTACK_TYPE ) portTASK_RETURN_ADDRESS; /* LR */
|
|
|
|
|
|
|
|
|
|
/* Save code space by skipping register initialisation. */
|
|
|
|
|
pxTopOfStack -= 5; /* R12, R3, R2 and R1. */
|
|
|
|
@ -219,6 +233,20 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE
|
|
|
|
|
}
|
|
|
|
|
/*-----------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
static void prvTaskExitError( void )
|
|
|
|
|
{
|
|
|
|
|
/* A function that implements a task must not exit or attempt to return to
|
|
|
|
|
its caller as there is nothing to return to. If a task wants to exit it
|
|
|
|
|
should instead call vTaskDelete( NULL ).
|
|
|
|
|
|
|
|
|
|
Artificially force an assert() to be triggered if configASSERT() is
|
|
|
|
|
defined, then stop here so application writers can catch the error. */
|
|
|
|
|
configASSERT( uxCriticalNesting == ~0UL );
|
|
|
|
|
portDISABLE_INTERRUPTS();
|
|
|
|
|
for( ;; );
|
|
|
|
|
}
|
|
|
|
|
/*-----------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
void vPortSVCHandler( void )
|
|
|
|
|
{
|
|
|
|
|
__asm volatile (
|
|
|
|
@ -406,7 +434,7 @@ void xPortPendSVHandler( void )
|
|
|
|
|
(
|
|
|
|
|
" mrs r0, psp \n"
|
|
|
|
|
" \n"
|
|
|
|
|
" ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */
|
|
|
|
|
" ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */
|
|
|
|
|
" ldr r2, [r3] \n"
|
|
|
|
|
" \n"
|
|
|
|
|
" tst r14, #0x10 \n" /* Is the task using the FPU context? If so, push high vfp registers. */
|
|
|
|
@ -435,6 +463,14 @@ void xPortPendSVHandler( void )
|
|
|
|
|
" vldmiaeq r0!, {s16-s31} \n"
|
|
|
|
|
" \n"
|
|
|
|
|
" msr psp, r0 \n"
|
|
|
|
|
" \n"
|
|
|
|
|
#ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata workaround. */
|
|
|
|
|
#if WORKAROUND_PMU_CM001 == 1
|
|
|
|
|
" push { r14 } \n"
|
|
|
|
|
" pop { pc } \n"
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
" \n"
|
|
|
|
|
" bx r14 \n"
|
|
|
|
|
" \n"
|
|
|
|
|
" .align 2 \n"
|
|
|
|
@ -500,9 +536,17 @@ void xPortSysTickHandler( void )
|
|
|
|
|
to be unsuspended then abandon the low power entry. */
|
|
|
|
|
if( eTaskConfirmSleepModeStatus() == eAbortSleep )
|
|
|
|
|
{
|
|
|
|
|
/* Restart from whatever is left in the count register to complete
|
|
|
|
|
this tick period. */
|
|
|
|
|
portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;
|
|
|
|
|
|
|
|
|
|
/* Restart SysTick. */
|
|
|
|
|
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
|
|
|
|
|
|
|
|
|
|
/* Reset the reload register to the value required for normal tick
|
|
|
|
|
periods. */
|
|
|
|
|
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
|
|
|
|
|
|
|
|
|
/* Re-enable interrupts - see comments above the cpsid instruction()
|
|
|
|
|
above. */
|
|
|
|
|
__asm volatile( "cpsie i" );
|
|
|
|
|