static void __interrupt __far prvPreemptiveTick( void )\r
{\r
/* Get the scheduler to update the task states following the tick. */\r
- vTaskIncrementTick();\r
-\r
- /* Switch in the context of the next task to be run. */\r
- portSWITCH_CONTEXT();\r
+ if( xTaskIncrementTick() != pdFALSE )\r
+ {\r
+ /* Switch in the context of the next task to be run. */\r
+ portSWITCH_CONTEXT();\r
+ }\r
\r
/* Reset the PIC ready for the next time. */\r
portRESET_PIC();\r
{\r
/* Same as preemptive tick, but the cooperative scheduler is being used\r
so we don't have to switch in the context of the next task. */\r
- vTaskIncrementTick();\r
+ xTaskIncrementTick();\r
portRESET_PIC();\r
}\r
#endif\r
static void __interrupt __far prvPreemptiveTick( void )\r
{\r
/* Get the scheduler to update the task states following the tick. */\r
- vTaskIncrementTick();\r
-\r
- /* Switch in the context of the next task to be run. */\r
- portSWITCH_CONTEXT();\r
+ if( xTaskIncrementTick() != pdFALSE )\r
+ {\r
+ /* Switch in the context of the next task to be run. */\r
+ portSWITCH_CONTEXT();\r
+ }\r
\r
/* Reset the PIC ready for the next time. */\r
prvPortResetPIC();\r
{\r
/* Same as preemptive tick, but the cooperative scheduler is being used\r
so we don't have to switch in the context of the next task. */\r
- vTaskIncrementTick();\r
+ xTaskIncrementTick();\r
prvPortResetPIC();\r
}\r
#endif\r
\r
.include data_model.h\r
\r
- .global vTaskIncrementTick\r
+ .global xTaskIncrementTick\r
.global vTaskSwitchContext\r
.global vPortSetupTimerInterrupt\r
.global pxCurrentTCB\r
push.w sr\r
portSAVE_CONTEXT\r
\r
- call_x #vTaskIncrementTick\r
+ call_x #xTaskIncrementTick\r
call_x #vTaskSwitchContext\r
\r
portRESTORE_CONTEXT\r
push.w sr\r
portSAVE_CONTEXT\r
\r
- call_x #vTaskIncrementTick\r
+ call_x #xTaskIncrementTick\r
\r
portRESTORE_CONTEXT\r
\r
/* Increment the RTOS tick. */\r
ulSavedInterruptMask = portSET_INTERRUPT_MASK_FROM_ISR();\r
{\r
- vTaskIncrementTick();\r
+ if( xTaskIncrementTick() != pdFALSE )\r
+ {\r
+ taskYIELD();\r
+ }\r
}\r
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulSavedInterruptMask );\r
-\r
- /* If we are using the pre-emptive scheduler then also request a\r
- context switch as incrementing the tick could have unblocked a task. */\r
- #if configUSE_PREEMPTION == 1\r
- {\r
- taskYIELD();\r
- }\r
- #endif\r
}\r
\r
portSAVE_CONTEXT();\r
\r
/* Increment the tick ... */\r
- vTaskIncrementTick();\r
-\r
- /* ... then see if the new tick value has necessitated a\r
- context switch. */\r
- vTaskSwitchContext();\r
+ if( xTaskIncrementTick() != pdFALSE )\r
+ {\r
+ vTaskSwitchContext();\r
+ }\r
\r
TFLG1 = 1; \r
\r
}\r
#else\r
{\r
- vTaskIncrementTick();\r
+ xTaskIncrementTick();\r
TFLG1 = 1;\r
}\r
#endif\r
/* Clear tick timer interrupt indication. */\r
ulDummy = portTIMER_REG_BASE_PTR->TC_SR; \r
\r
- vTaskIncrementTick();\r
+ xTaskIncrementTick();\r
\r
/* Acknowledge the interrupt at AIC level... */\r
AT91C_BASE_AIC->AIC_EOICR = portCLEAR_AIC_INTERRUPT;\r
\r
/* Increment the RTOS tick count, then look for the highest priority \r
task that is ready to run. */\r
- vTaskIncrementTick();\r
- vTaskSwitchContext();\r
+ if( xTaskIncrementTick() != pdFALSE )\r
+ {\r
+ vTaskSwitchContext();\r
+ }\r
\r
/* Acknowledge the interrupt at AIC level... */\r
AT91C_BASE_AIC->AIC_EOICR = portCLEAR_AIC_INTERRUPT;\r
/* Increment the tick count - which may wake some tasks but as the\r
preemptive scheduler is not being used any woken task is not given\r
processor time no matter what its priority. */\r
- vTaskIncrementTick();\r
+ xTaskIncrementTick();\r
\r
/* Clear the PIT interrupt. */\r
ulDummy = AT91C_BASE_PITC->PITC_PIVR;\r
portSAVE_CONTEXT(); \r
\r
/* Increment the tick count - this may wake a task. */\r
- vTaskIncrementTick();\r
-\r
- /* Find the highest priority task that is ready to run. */\r
- vTaskSwitchContext();\r
+ if( xTaskIncrementTick() != pdFALSE )\r
+ {\r
+ /* Find the highest priority task that is ready to run. */\r
+ vTaskSwitchContext();\r
+ }\r
\r
/* End the interrupt in the AIC. */\r
AT91C_BASE_AIC->AIC_EOICR = AT91C_BASE_PITC->PITC_PIVR;;\r
\r
/* Increment the RTOS tick count, then look for the highest priority \r
task that is ready to run. */\r
- __asm volatile( "bl vTaskIncrementTick" );\r
+ __asm volatile( "bl xTaskIncrementTick" );\r
\r
#if configUSE_PREEMPTION == 1\r
__asm volatile( "bl vTaskSwitchContext" );\r
void vNonPreemptiveTick( void ) __attribute__ ((interrupt ("IRQ")));\r
void vNonPreemptiveTick( void )\r
{ \r
- vTaskIncrementTick();\r
+ xTaskIncrementTick();\r
T0IR = 2;\r
VICVectAddr = portCLEAR_VIC_INTERRUPT;\r
}\r
\r
/* Increment the RTOS tick count, then look for the highest priority \r
task that is ready to run. */\r
- __asm volatile( "bl vTaskIncrementTick" );\r
+ __asm volatile( "bl xTaskIncrementTick" );\r
__asm volatile( "bl vTaskSwitchContext" );\r
\r
/* Ready for the next interrupt. */\r
{\r
unsigned long ulDummy;\r
\r
- /* If using preemption, also force a context switch. */\r
- #if configUSE_PREEMPTION == 1\r
- *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;\r
- #endif\r
-\r
ulDummy = portSET_INTERRUPT_MASK_FROM_ISR();\r
{\r
- vTaskIncrementTick();\r
+ /* Increment the RTOS tick. */\r
+ if( xTaskIncrementTick() != pdFALSE )\r
+ {\r
+ /* Pend a context switch. */\r
+ *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;\r
+ }\r
}\r
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy );\r
}\r
\r
void xPortSysTickHandler( void )\r
{\r
- /* If using preemption, also force a context switch. */\r
- #if configUSE_PREEMPTION == 1\r
- portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;\r
- #endif\r
-\r
/* Only reset the systick load register if configUSE_TICKLESS_IDLE is set to\r
1. If it is set to 0 tickless idle is not being used. If it is set to a\r
value other than 0 or 1 then a timer other than the SysTick is being used\r
portNVIC_SYSTICK_LOAD_REG = ulTimerReloadValueForOneTick;\r
#endif\r
\r
+ /* The SysTick runs at the lowest interrupt priority, so when this interrupt\r
+ executes all interrupts must be unmasked. There is therefore no need to\r
+ save and then restore the interrupt mask value as its value is already\r
+ known. */\r
( void ) portSET_INTERRUPT_MASK_FROM_ISR();\r
{\r
- vTaskIncrementTick();\r
+ if( xTaskIncrementTick() != pdFALSE )\r
+ {\r
+ /* A context switch is required. Context switching is performed in\r
+ the PendSV interrupt. Pend the PendSV interrupt. */\r
+ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;\r
+ }\r
}\r
portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );\r
}\r
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );\r
if( xModifiableIdleTime > 0 )\r
{\r
- __asm volatile( "wfi" );\r
__asm volatile( "dsb" );\r
+ __asm volatile( "wfi" );\r
__asm volatile( "isb" );\r
}\r
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );\r
{\r
unsigned long ulDummy;\r
\r
- /* If using preemption, also force a context switch. */\r
- #if configUSE_PREEMPTION == 1\r
- *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;\r
- #endif\r
-\r
ulDummy = portSET_INTERRUPT_MASK_FROM_ISR();\r
{\r
- vTaskIncrementTick();\r
+ /* Increment the RTOS tick. */\r
+ if( xTaskIncrementTick() != pdFALSE )\r
+ {\r
+ /* Pend a context switch. */\r
+ *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;\r
+ }\r
}\r
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy );\r
}\r
\r
void xPortSysTickHandler( void )\r
{\r
- /* If using preemption, also force a context switch. */\r
- #if configUSE_PREEMPTION == 1\r
- portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;\r
- #endif\r
-\r
/* Only reset the systick load register if configUSE_TICKLESS_IDLE is set to\r
1. If it is set to 0 tickless idle is not being used. If it is set to a\r
value other than 0 or 1 then a timer other than the SysTick is being used\r
\r
( void ) portSET_INTERRUPT_MASK_FROM_ISR();\r
{\r
- vTaskIncrementTick();\r
+ /* Increment the RTOS tick count. */\r
+ if( xTaskIncrementTick() != pdFALSE )\r
+ {\r
+ /* Pend a context switch. */\r
+ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;\r
+ }\r
}\r
portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );\r
}\r
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );\r
if( xModifiableIdleTime > 0 )\r
{\r
- __asm volatile( "wfi" );\r
__asm volatile( "dsb" );\r
+ __asm volatile( "wfi" );\r
__asm volatile( "isb" );\r
}\r
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );\r
void vPortYieldFromTick( void )\r
{\r
portSAVE_CONTEXT();\r
- vTaskIncrementTick();\r
- vTaskSwitchContext();\r
+ if( xTaskIncrementTick() != pdFALSE )\r
+ {\r
+ vTaskSwitchContext();\r
+ }\r
portRESTORE_CONTEXT();\r
\r
asm volatile ( "ret" );\r
void SIG_OUTPUT_COMPARE1A( void ) __attribute__ ( ( signal ) );\r
void SIG_OUTPUT_COMPARE1A( void )\r
{\r
- vTaskIncrementTick();\r
+ xTaskIncrementTick();\r
}\r
#endif\r
\r
/* Because FreeRTOS is not supposed to run with nested interrupts, put all OS\r
calls in a critical section . */\r
portENTER_CRITICAL();\r
- vTaskIncrementTick();\r
+ xTaskIncrementTick();\r
portEXIT_CRITICAL();\r
\r
/* Restore the context of the "elected task". */\r
static void prvProcessTick( void ) __attribute__((noinline));\r
static void prvProcessTick( void )\r
{\r
- vTaskIncrementTick();\r
-\r
- #if configUSE_PREEMPTION == 1\r
+ if( xTaskIncrementTick() != pdFALSE )\r
+ {\r
vTaskSwitchContext();\r
- #endif\r
-\r
+ }\r
+ \r
/* Clear the Tick Interrupt. */\r
counter1->expired = 0;\r
}\r
{\r
portSAVE_STACK_POINTER();\r
\r
- vTaskIncrementTick();\r
- vTaskSwitchContext();\r
+ if( xTaskIncrementTick() != pdFALSE )\r
+ {\r
+ vTaskSwitchContext();\r
+ }\r
\r
/* Clear the interrupt. */\r
TSR1 &= ~0x01;\r
void vTickISR( void ) __attribute__ ( ( interrupt_handler ) );\r
void vTickISR( void )\r
{\r
- vTaskIncrementTick();\r
+ xTaskIncrementTick();\r
\r
/* Clear the interrupt. */\r
TSR1 &= ~0x01;\r
portSAVE_CONTEXT();\r
\r
/* Increment the tick ... */\r
- vTaskIncrementTick();\r
-\r
- /* ... then see if the new tick value has necessitated a\r
- context switch. */\r
- vTaskSwitchContext();\r
+ if( xTaskIncrementTick() != pdFALSE )\r
+ {\r
+ /* A context switch is necessary. */\r
+ vTaskSwitchContext();\r
+ }\r
\r
/* Restore the context of a task - which may be a different task\r
to that interrupted. */\r
}\r
#else\r
{\r
- vTaskIncrementTick();\r
+ xTaskIncrementTick();\r
}\r
#endif\r
\r
* simply increment the system tick.\r
*/\r
\r
- vTaskIncrementTick( );\r
+ xTaskIncrementTick();\r
MCF_PIT_PCSR0 |= MCF_PIT_PCSR_PIF;\r
}\r
\r
#endif\r
portSAVE_CONTEXT( );\r
MCF_PIT_PCSR0 |= MCF_PIT_PCSR_PIF;\r
- vTaskIncrementTick( );\r
- vTaskSwitchContext( );\r
+ if( xTaskIncrementTick() != pdFALSE )\r
+ {\r
+ vTaskSwitchContext( );\r
+ }\r
portRESTORE_CONTEXT( );\r
}\r
#endif\r
unsigned long ulCSR;\r
\r
/* Increment the RTOS tick - this might cause a task to unblock. */\r
- vTaskIncrementTick();\r
+ if( xTaskIncrementTick() != pdFALSE )\r
+ {\r
+ vTaskSwitchContext();\r
+ }\r
\r
/* Clear the timer interrupt */\r
ulCSR = XTmrCtr_mGetControlStatusReg(XPAR_OPB_TIMER_1_BASEADDR, 0); \r
XTmrCtr_mSetControlStatusReg( XPAR_OPB_TIMER_1_BASEADDR, portCOUNTER_0, ulCSR );\r
-\r
- /* If we are using the preemptive scheduler then we also need to determine\r
- if this tick should cause a context switch. */\r
- #if configUSE_PREEMPTION == 1\r
- vTaskSwitchContext();\r
- #endif\r
}\r
/*-----------------------------------------------------------*/\r
\r
vApplicationClearTimerInterrupt();\r
\r
/* Increment the RTOS tick - this might cause a task to unblock. */\r
- vTaskIncrementTick();\r
-\r
- /* If the preemptive scheduler is being used then a context switch should be\r
- requested in case incrementing the tick unblocked a task, or a time slice\r
- should cause another task to enter the Running state. */\r
- #if configUSE_PREEMPTION == 1\r
+ if( xTaskIncrementTick() != pdFALSE )\r
+ {\r
/* Force vTaskSwitchContext() to be called as the interrupt exits. */\r
ulTaskSwitchRequested = 1;\r
- #endif\r
+ }\r
}\r
/*-----------------------------------------------------------*/\r
\r
\r
void xPortSysTickHandler( void )\r
{\r
- /* If using preemption, also force a context switch. */\r
- #if configUSE_PREEMPTION == 1\r
- portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;\r
- #endif\r
-\r
/* Only reset the systick load register if configUSE_TICKLESS_IDLE is set to\r
1. If it is set to 0 tickless idle is not being used. If it is set to a\r
value other than 0 or 1 then a timer other than the SysTick is being used\r
\r
( void ) portSET_INTERRUPT_MASK_FROM_ISR();\r
{\r
- vTaskIncrementTick();\r
+ if( xTaskIncrementTick() != pdFALSE )\r
+ {\r
+ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;\r
+ }\r
}\r
portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );\r
}\r
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );\r
if( xModifiableIdleTime > 0 )\r
{\r
- __WFI();\r
__DSB();\r
+ __WFI();\r
__ISB();\r
}\r
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );\r
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );\r
if( xModifiableIdleTime > 0 )\r
{\r
- __WFI();\r
__DSB();\r
+ __WFI();\r
__ISB();\r
}\r
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );\r
***************************************************************************\r
\r
\r
- http://www.FreeRTOS.org - Documentation, books, training, latest versions, \r
+ http://www.FreeRTOS.org - Documentation, books, training, latest versions,\r
license and Real Time Engineers Ltd. contact details.\r
\r
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
including FreeRTOS+Trace - an indispensable productivity tool, and our new\r
fully thread aware and reentrant UDP/IP stack.\r
\r
- http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High \r
- Integrity Systems, who sell the code with commercial support, \r
+ http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High\r
+ Integrity Systems, who sell the code with commercial support,\r
indemnification and middleware, under the OpenRTOS brand.\r
- \r
- http://www.SafeRTOS.com - High Integrity Systems also provide a safety \r
- engineered and independently SIL3 certified version for use in safety and \r
+\r
+ http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
+ engineered and independently SIL3 certified version for use in safety and\r
mission critical applications that require provable dependability.\r
*/\r
\r
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )\r
{\r
/* R0 is not included as it is the stack pointer. */\r
- \r
+\r
*pxTopOfStack = 0x00;\r
pxTopOfStack--;\r
*pxTopOfStack = portINITIAL_PSW;\r
pxTopOfStack--;\r
*pxTopOfStack = ( portSTACK_TYPE ) pxCode;\r
- \r
+\r
/* When debugging it can be useful if every register is set to a known\r
value. Otherwise code space can be saved by just setting the registers\r
that need to be set. */\r
pxTopOfStack -= 15;\r
}\r
#endif\r
- \r
+\r
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R1 */\r
- pxTopOfStack--; \r
+ pxTopOfStack--;\r
*pxTopOfStack = portINITIAL_FPSW;\r
pxTopOfStack--;\r
*pxTopOfStack = 0x12345678; /* Accumulator. */\r
use. A demo application is provided to show a suitable example. */\r
vApplicationSetupTimerInterrupt();\r
\r
- /* Enable the software interrupt. */ \r
+ /* Enable the software interrupt. */\r
_IEN( _ICU_SWINT ) = 1;\r
- \r
+\r
/* Ensure the software interrupt is clear. */\r
_IR( _ICU_SWINT ) = 0;\r
- \r
+\r
/* Ensure the software interrupt is set to the kernel priority. */\r
_IPR( _ICU_SWINT ) = configKERNEL_INTERRUPT_PRIORITY;\r
\r
{\r
/* Re-enable interrupts. */\r
__enable_interrupt();\r
- \r
+\r
/* Increment the tick, and perform any processing the new tick value\r
necessitates. */\r
__set_interrupt_level( configMAX_SYSCALL_INTERRUPT_PRIORITY );\r
{\r
- vTaskIncrementTick();\r
+ if( xTaskIncrementTick() != pdFALSE )\r
+ {\r
+ taskYIELD();\r
+ }\r
}\r
__set_interrupt_level( configKERNEL_INTERRUPT_PRIORITY );\r
- \r
- /* Only select a new task if the preemptive scheduler is being used. */\r
- #if( configUSE_PREEMPTION == 1 )\r
- taskYIELD();\r
- #endif\r
}\r
/*-----------------------------------------------------------*/\r
\r
unsigned long ulSwitchRequired;\r
\r
/* Process the tick itself. */\r
- vTaskIncrementTick();\r
- #if( configUSE_PREEMPTION != 0 )\r
- {\r
- /* A context switch is only automatically performed from the tick\r
- interrupt if the pre-emptive scheduler is being used. */\r
- ulSwitchRequired = pdTRUE;\r
- }\r
- #else\r
- {\r
- ulSwitchRequired = pdFALSE;\r
- }\r
- #endif\r
+ ulSwitchRequired = ( unsigned long ) xTaskIncrementTick();\r
\r
return ulSwitchRequired;\r
}\r
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );\r
if( xModifiableIdleTime > 0 )\r
{\r
- __wfi();\r
__dsb( portSY_FULL_READ_WRITE );\r
+ __wfi();\r
__isb( portSY_FULL_READ_WRITE );\r
}\r
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );\r
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );\r
if( xModifiableIdleTime > 0 )\r
{\r
- __wfi();\r
__dsb( portSY_FULL_READ_WRITE );\r
+ __wfi();\r
__isb( portSY_FULL_READ_WRITE );\r
}\r
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );\r