mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-08-19 17:48:33 -04:00
Introduce the prvTaskExitError() function for all ARM_CMn ports.
Introduce the configTASK_RETURN_ADDRESS macro for the GCC ARM_CMn ports. Improve time slippage penalty when entering tickless mode is abandoned.
This commit is contained in:
parent
81e141ad86
commit
aedf7824cb
7 changed files with 217 additions and 29 deletions
|
@ -154,6 +154,11 @@ void vPortSVCHandler( void );
|
|||
*/
|
||||
static void prvStartFirstTask( void );
|
||||
|
||||
/*
|
||||
* Used to catch tasks that attempt to return from their implementing function.
|
||||
*/
|
||||
static void prvTaskExitError( void );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
|
@ -204,7 +209,8 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE
|
|||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) pxCode; /* PC */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0; /* LR */
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) prvTaskExitError; /* LR */
|
||||
|
||||
pxTopOfStack -= 5; /* R12, R3, R2 and R1. */
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */
|
||||
pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */
|
||||
|
@ -213,6 +219,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( ;; );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
__asm void vPortSVCHandler( void )
|
||||
{
|
||||
PRESERVE8
|
||||
|
@ -442,8 +462,16 @@ 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 __disable_irq() call
|
||||
above. */
|
||||
|
|
|
@ -163,6 +163,12 @@ static void prvStartFirstTask( void );
|
|||
* Functions defined in portasm.s to enable the VFP.
|
||||
*/
|
||||
static void prvEnableVFP( void );
|
||||
|
||||
/*
|
||||
* Used to catch tasks that attempt to return from their implementing function.
|
||||
*/
|
||||
static void prvTaskExitError( void );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
|
@ -217,7 +223,7 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE
|
|||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) pxCode; /* PC */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0; /* LR */
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) prvTaskExitError; /* LR */
|
||||
|
||||
/* Save code space by skipping register initialisation. */
|
||||
pxTopOfStack -= 5; /* R12, R3, R2 and R1. */
|
||||
|
@ -234,6 +240,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( ;; );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
__asm void vPortSVCHandler( void )
|
||||
{
|
||||
PRESERVE8
|
||||
|
@ -444,6 +464,14 @@ __asm void xPortPendSVHandler( void )
|
|||
vldmiaeq r0!, {s16-s31}
|
||||
|
||||
msr psp, r0
|
||||
|
||||
#ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata */
|
||||
#if WORKAROUND_PMU_CM001 == 1
|
||||
push { r14 }
|
||||
pop { pc }
|
||||
#endif
|
||||
#endif
|
||||
|
||||
bx r14
|
||||
nop
|
||||
}
|
||||
|
@ -505,8 +533,16 @@ 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 __disable_irq() call
|
||||
above. */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue