Convert some ports to use xTaskIncrementTick() in place of vTaskIncrementTick().

Move DSB instructions to before WFI instructions in line with ARM recommendations.
This commit is contained in:
Richard Barry 2013-06-06 15:46:40 +00:00
parent 4e9374ad90
commit 686d190798
27 changed files with 128 additions and 142 deletions

View File

@ -195,10 +195,11 @@ is being used. */
static void __interrupt __far prvPreemptiveTick( void )
{
/* Get the scheduler to update the task states following the tick. */
vTaskIncrementTick();
/* Switch in the context of the next task to be run. */
portSWITCH_CONTEXT();
if( xTaskIncrementTick() != pdFALSE )
{
/* Switch in the context of the next task to be run. */
portSWITCH_CONTEXT();
}
/* Reset the PIC ready for the next time. */
portRESET_PIC();
@ -208,7 +209,7 @@ is being used. */
{
/* Same as preemptive tick, but the cooperative scheduler is being used
so we don't have to switch in the context of the next task. */
vTaskIncrementTick();
xTaskIncrementTick();
portRESET_PIC();
}
#endif

View File

@ -216,10 +216,11 @@ scheduler is being used. */
static void __interrupt __far prvPreemptiveTick( void )
{
/* Get the scheduler to update the task states following the tick. */
vTaskIncrementTick();
/* Switch in the context of the next task to be run. */
portSWITCH_CONTEXT();
if( xTaskIncrementTick() != pdFALSE )
{
/* Switch in the context of the next task to be run. */
portSWITCH_CONTEXT();
}
/* Reset the PIC ready for the next time. */
prvPortResetPIC();
@ -229,7 +230,7 @@ scheduler is being used. */
{
/* Same as preemptive tick, but the cooperative scheduler is being used
so we don't have to switch in the context of the next task. */
vTaskIncrementTick();
xTaskIncrementTick();
prvPortResetPIC();
}
#endif

View File

@ -57,7 +57,7 @@
.include data_model.h
.global vTaskIncrementTick
.global xTaskIncrementTick
.global vTaskSwitchContext
.global vPortSetupTimerInterrupt
.global pxCurrentTCB
@ -112,7 +112,7 @@ vPortPreemptiveTickISR: .asmfunc
push.w sr
portSAVE_CONTEXT
call_x #vTaskIncrementTick
call_x #xTaskIncrementTick
call_x #vTaskSwitchContext
portRESTORE_CONTEXT
@ -128,7 +128,7 @@ vPortCooperativeTickISR: .asmfunc
push.w sr
portSAVE_CONTEXT
call_x #vTaskIncrementTick
call_x #xTaskIncrementTick
portRESTORE_CONTEXT

View File

@ -220,16 +220,11 @@ unsigned long ulSavedInterruptMask;
/* Increment the RTOS tick. */
ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR();
{
vTaskIncrementTick();
if( xTaskIncrementTick() != pdFALSE )
{
taskYIELD();
}
}
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask );
/* If we are using the pre-emptive scheduler then also request a
context switch as incrementing the tick could have unblocked a task. */
#if configUSE_PREEMPTION == 1
{
taskYIELD();
}
#endif
}

View File

@ -260,11 +260,10 @@ void interrupt vPortTickInterrupt( void )
portSAVE_CONTEXT();
/* Increment the tick ... */
vTaskIncrementTick();
/* ... then see if the new tick value has necessitated a
context switch. */
vTaskSwitchContext();
if( xTaskIncrementTick() != pdFALSE )
{
vTaskSwitchContext();
}
TFLG1 = 1;
@ -274,7 +273,7 @@ void interrupt vPortTickInterrupt( void )
}
#else
{
vTaskIncrementTick();
xTaskIncrementTick();
TFLG1 = 1;
}
#endif

View File

@ -161,7 +161,7 @@ void vPortYieldProcessor( void )
/* Clear tick timer interrupt indication. */
ulDummy = portTIMER_REG_BASE_PTR->TC_SR;
vTaskIncrementTick();
xTaskIncrementTick();
/* Acknowledge the interrupt at AIC level... */
AT91C_BASE_AIC->AIC_EOICR = portCLEAR_AIC_INTERRUPT;
@ -186,8 +186,10 @@ void vPortYieldProcessor( void )
/* Increment the RTOS tick count, then look for the highest priority
task that is ready to run. */
vTaskIncrementTick();
vTaskSwitchContext();
if( xTaskIncrementTick() != pdFALSE )
{
vTaskSwitchContext();
}
/* Acknowledge the interrupt at AIC level... */
AT91C_BASE_AIC->AIC_EOICR = portCLEAR_AIC_INTERRUPT;

View File

@ -163,7 +163,7 @@ void vPortYieldProcessor( void )
/* Increment the tick count - which may wake some tasks but as the
preemptive scheduler is not being used any woken task is not given
processor time no matter what its priority. */
vTaskIncrementTick();
xTaskIncrementTick();
/* Clear the PIT interrupt. */
ulDummy = AT91C_BASE_PITC->PITC_PIVR;
@ -183,10 +183,11 @@ void vPortYieldProcessor( void )
portSAVE_CONTEXT();
/* Increment the tick count - this may wake a task. */
vTaskIncrementTick();
/* Find the highest priority task that is ready to run. */
vTaskSwitchContext();
if( xTaskIncrementTick() != pdFALSE )
{
/* Find the highest priority task that is ready to run. */
vTaskSwitchContext();
}
/* End the interrupt in the AIC. */
AT91C_BASE_AIC->AIC_EOICR = AT91C_BASE_PITC->PITC_PIVR;;

View File

@ -166,7 +166,7 @@ void vTickISR( void )
/* Increment the RTOS tick count, then look for the highest priority
task that is ready to run. */
__asm volatile( "bl vTaskIncrementTick" );
__asm volatile( "bl xTaskIncrementTick" );
#if configUSE_PREEMPTION == 1
__asm volatile( "bl vTaskSwitchContext" );

View File

@ -150,7 +150,7 @@ void vPortYieldProcessor( void )
void vNonPreemptiveTick( void ) __attribute__ ((interrupt ("IRQ")));
void vNonPreemptiveTick( void )
{
vTaskIncrementTick();
xTaskIncrementTick();
T0IR = 2;
VICVectAddr = portCLEAR_VIC_INTERRUPT;
}
@ -167,7 +167,7 @@ void vPortYieldProcessor( void )
/* Increment the RTOS tick count, then look for the highest priority
task that is ready to run. */
__asm volatile( "bl vTaskIncrementTick" );
__asm volatile( "bl xTaskIncrementTick" );
__asm volatile( "bl vTaskSwitchContext" );
/* Ready for the next interrupt. */

View File

@ -293,14 +293,14 @@ void xPortSysTickHandler( void )
{
unsigned long ulDummy;
/* If using preemption, also force a context switch. */
#if configUSE_PREEMPTION == 1
*(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;
#endif
ulDummy = portSET_INTERRUPT_MASK_FROM_ISR();
{
vTaskIncrementTick();
/* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE )
{
/* Pend a context switch. */
*(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;
}
}
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy );
}

View File

@ -354,11 +354,6 @@ void xPortPendSVHandler( void )
void xPortSysTickHandler( void )
{
/* If using preemption, also force a context switch. */
#if configUSE_PREEMPTION == 1
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
#endif
/* Only reset the systick load register if configUSE_TICKLESS_IDLE is set to
1. If it is set to 0 tickless idle is not being used. If it is set to a
value other than 0 or 1 then a timer other than the SysTick is being used
@ -367,9 +362,18 @@ void xPortSysTickHandler( void )
portNVIC_SYSTICK_LOAD_REG = ulTimerReloadValueForOneTick;
#endif
/* The SysTick runs at the lowest interrupt priority, so when this interrupt
executes all interrupts must be unmasked. There is therefore no need to
save and then restore the interrupt mask value as its value is already
known. */
( void ) portSET_INTERRUPT_MASK_FROM_ISR();
{
vTaskIncrementTick();
if( xTaskIncrementTick() != pdFALSE )
{
/* A context switch is required. Context switching is performed in
the PendSV interrupt. Pend the PendSV interrupt. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
}
}
portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );
}
@ -444,8 +448,8 @@ void xPortSysTickHandler( void )
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
if( xModifiableIdleTime > 0 )
{
__asm volatile( "wfi" );
__asm volatile( "dsb" );
__asm volatile( "wfi" );
__asm volatile( "isb" );
}
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );

View File

@ -452,14 +452,14 @@ void xPortSysTickHandler( void )
{
unsigned long ulDummy;
/* If using preemption, also force a context switch. */
#if configUSE_PREEMPTION == 1
*(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;
#endif
ulDummy = portSET_INTERRUPT_MASK_FROM_ISR();
{
vTaskIncrementTick();
/* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE )
{
/* Pend a context switch. */
*(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;
}
}
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy );
}

View File

@ -387,11 +387,6 @@ void xPortPendSVHandler( void )
void xPortSysTickHandler( void )
{
/* If using preemption, also force a context switch. */
#if configUSE_PREEMPTION == 1
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
#endif
/* Only reset the systick load register if configUSE_TICKLESS_IDLE is set to
1. If it is set to 0 tickless idle is not being used. If it is set to a
value other than 0 or 1 then a timer other than the SysTick is being used
@ -402,7 +397,12 @@ void xPortSysTickHandler( void )
( void ) portSET_INTERRUPT_MASK_FROM_ISR();
{
vTaskIncrementTick();
/* Increment the RTOS tick count. */
if( xTaskIncrementTick() != pdFALSE )
{
/* Pend a context switch. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
}
}
portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );
}
@ -477,8 +477,8 @@ void xPortSysTickHandler( void )
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
if( xModifiableIdleTime > 0 )
{
__asm volatile( "wfi" );
__asm volatile( "dsb" );
__asm volatile( "wfi" );
__asm volatile( "isb" );
}
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );

View File

@ -393,8 +393,10 @@ void vPortYieldFromTick( void ) __attribute__ ( ( naked ) );
void vPortYieldFromTick( void )
{
portSAVE_CONTEXT();
vTaskIncrementTick();
vTaskSwitchContext();
if( xTaskIncrementTick() != pdFALSE )
{
vTaskSwitchContext();
}
portRESTORE_CONTEXT();
asm volatile ( "ret" );
@ -463,7 +465,7 @@ unsigned char ucHighByte, ucLowByte;
void SIG_OUTPUT_COMPARE1A( void ) __attribute__ ( ( signal ) );
void SIG_OUTPUT_COMPARE1A( void )
{
vTaskIncrementTick();
xTaskIncrementTick();
}
#endif

View File

@ -254,7 +254,7 @@ __attribute__((__naked__)) static void vTick( void )
/* Because FreeRTOS is not supposed to run with nested interrupts, put all OS
calls in a critical section . */
portENTER_CRITICAL();
vTaskIncrementTick();
xTaskIncrementTick();
portEXIT_CRITICAL();
/* Restore the context of the "elected task". */

View File

@ -170,12 +170,11 @@ void interrupt31_handler( void )
static void prvProcessTick( void ) __attribute__((noinline));
static void prvProcessTick( void )
{
vTaskIncrementTick();
#if configUSE_PREEMPTION == 1
if( xTaskIncrementTick() != pdFALSE )
{
vTaskSwitchContext();
#endif
}
/* Clear the Tick Interrupt. */
counter1->expired = 0;
}

View File

@ -293,8 +293,10 @@ void vPortYield( void )
{
portSAVE_STACK_POINTER();
vTaskIncrementTick();
vTaskSwitchContext();
if( xTaskIncrementTick() != pdFALSE )
{
vTaskSwitchContext();
}
/* Clear the interrupt. */
TSR1 &= ~0x01;
@ -312,7 +314,7 @@ void vPortYield( void )
void vTickISR( void ) __attribute__ ( ( interrupt_handler ) );
void vTickISR( void )
{
vTaskIncrementTick();
xTaskIncrementTick();
/* Clear the interrupt. */
TSR1 &= ~0x01;

View File

@ -263,11 +263,11 @@ void vPortTickInterrupt( void )
portSAVE_CONTEXT();
/* Increment the tick ... */
vTaskIncrementTick();
/* ... then see if the new tick value has necessitated a
context switch. */
vTaskSwitchContext();
if( xTaskIncrementTick() != pdFALSE )
{
/* A context switch is necessary. */
vTaskSwitchContext();
}
/* Restore the context of a task - which may be a different task
to that interrupted. */
@ -275,7 +275,7 @@ void vPortTickInterrupt( void )
}
#else
{
vTaskIncrementTick();
xTaskIncrementTick();
}
#endif

View File

@ -194,7 +194,7 @@ prvPortPreemptiveTick ( void )
* simply increment the system tick.
*/
vTaskIncrementTick( );
xTaskIncrementTick();
MCF_PIT_PCSR0 |= MCF_PIT_PCSR_PIF;
}
@ -209,8 +209,10 @@ prvPortPreemptiveTick( void )
#endif
portSAVE_CONTEXT( );
MCF_PIT_PCSR0 |= MCF_PIT_PCSR_PIF;
vTaskIncrementTick( );
vTaskSwitchContext( );
if( xTaskIncrementTick() != pdFALSE )
{
vTaskSwitchContext( );
}
portRESTORE_CONTEXT( );
}
#endif

View File

@ -359,17 +359,14 @@ void vTickISR( void *pvBaseAddress )
unsigned long ulCSR;
/* Increment the RTOS tick - this might cause a task to unblock. */
vTaskIncrementTick();
if( xTaskIncrementTick() != pdFALSE )
{
vTaskSwitchContext();
}
/* Clear the timer interrupt */
ulCSR = XTmrCtr_mGetControlStatusReg(XPAR_OPB_TIMER_1_BASEADDR, 0);
XTmrCtr_mSetControlStatusReg( XPAR_OPB_TIMER_1_BASEADDR, portCOUNTER_0, ulCSR );
/* If we are using the preemptive scheduler then we also need to determine
if this tick should cause a context switch. */
#if configUSE_PREEMPTION == 1
vTaskSwitchContext();
#endif
}
/*-----------------------------------------------------------*/

View File

@ -433,15 +433,11 @@ extern void vApplicationClearTimerInterrupt( void );
vApplicationClearTimerInterrupt();
/* Increment the RTOS tick - this might cause a task to unblock. */
vTaskIncrementTick();
/* If the preemptive scheduler is being used then a context switch should be
requested in case incrementing the tick unblocked a task, or a time slice
should cause another task to enter the Running state. */
#if configUSE_PREEMPTION == 1
if( xTaskIncrementTick() != pdFALSE )
{
/* Force vTaskSwitchContext() to be called as the interrupt exits. */
ulTaskSwitchRequested = 1;
#endif
}
}
/*-----------------------------------------------------------*/

View File

@ -250,11 +250,6 @@ void vPortExitCritical( void )
void xPortSysTickHandler( void )
{
/* If using preemption, also force a context switch. */
#if configUSE_PREEMPTION == 1
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
#endif
/* Only reset the systick load register if configUSE_TICKLESS_IDLE is set to
1. If it is set to 0 tickless idle is not being used. If it is set to a
value other than 0 or 1 then a timer other than the SysTick is being used
@ -265,7 +260,10 @@ void xPortSysTickHandler( void )
( void ) portSET_INTERRUPT_MASK_FROM_ISR();
{
vTaskIncrementTick();
if( xTaskIncrementTick() != pdFALSE )
{
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
}
}
portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );
}
@ -340,8 +338,8 @@ void xPortSysTickHandler( void )
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
if( xModifiableIdleTime > 0 )
{
__WFI();
__DSB();
__WFI();
__ISB();
}
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );

View File

@ -365,8 +365,8 @@ void xPortSysTickHandler( void )
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
if( xModifiableIdleTime > 0 )
{
__WFI();
__DSB();
__WFI();
__ISB();
}
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );

View File

@ -56,19 +56,19 @@
***************************************************************************
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
license and Real Time Engineers Ltd. contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, and our new
fully thread aware and reentrant UDP/IP stack.
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems, who sell the code with commercial support,
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems, who sell the code with commercial support,
indemnification and middleware, under the OpenRTOS brand.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability.
*/
@ -119,13 +119,13 @@ extern void *pxCurrentTCB;
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
{
/* R0 is not included as it is the stack pointer. */
*pxTopOfStack = 0x00;
pxTopOfStack--;
*pxTopOfStack = portINITIAL_PSW;
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) pxCode;
/* When debugging it can be useful if every register is set to a known
value. Otherwise code space can be saved by just setting the registers
that need to be set. */
@ -166,9 +166,9 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE
pxTopOfStack -= 15;
}
#endif
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R1 */
pxTopOfStack--;
pxTopOfStack--;
*pxTopOfStack = portINITIAL_FPSW;
pxTopOfStack--;
*pxTopOfStack = 0x12345678; /* Accumulator. */
@ -191,12 +191,12 @@ extern void vApplicationSetupTimerInterrupt( void );
use. A demo application is provided to show a suitable example. */
vApplicationSetupTimerInterrupt();
/* Enable the software interrupt. */
/* Enable the software interrupt. */
_IEN( _ICU_SWINT ) = 1;
/* Ensure the software interrupt is clear. */
_IR( _ICU_SWINT ) = 0;
/* Ensure the software interrupt is set to the kernel priority. */
_IPR( _ICU_SWINT ) = configKERNEL_INTERRUPT_PRIORITY;
@ -214,19 +214,17 @@ __interrupt void vTickISR( void )
{
/* Re-enable interrupts. */
__enable_interrupt();
/* Increment the tick, and perform any processing the new tick value
necessitates. */
__set_interrupt_level( configMAX_SYSCALL_INTERRUPT_PRIORITY );
{
vTaskIncrementTick();
if( xTaskIncrementTick() != pdFALSE )
{
taskYIELD();
}
}
__set_interrupt_level( configKERNEL_INTERRUPT_PRIORITY );
/* Only select a new task if the preemptive scheduler is being used. */
#if( configUSE_PREEMPTION == 1 )
taskYIELD();
#endif
}
/*-----------------------------------------------------------*/

View File

@ -301,18 +301,7 @@ static unsigned long prvProcessTickInterrupt( void )
unsigned long ulSwitchRequired;
/* Process the tick itself. */
vTaskIncrementTick();
#if( configUSE_PREEMPTION != 0 )
{
/* A context switch is only automatically performed from the tick
interrupt if the pre-emptive scheduler is being used. */
ulSwitchRequired = pdTRUE;
}
#else
{
ulSwitchRequired = pdFALSE;
}
#endif
ulSwitchRequired = ( unsigned long ) xTaskIncrementTick();
return ulSwitchRequired;
}

View File

@ -417,8 +417,8 @@ void xPortSysTickHandler( void )
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
if( xModifiableIdleTime > 0 )
{
__wfi();
__dsb( portSY_FULL_READ_WRITE );
__wfi();
__isb( portSY_FULL_READ_WRITE );
}
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );

View File

@ -480,8 +480,8 @@ void xPortSysTickHandler( void )
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
if( xModifiableIdleTime > 0 )
{
__wfi();
__dsb( portSY_FULL_READ_WRITE );
__wfi();
__isb( portSY_FULL_READ_WRITE );
}
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );