callback before their expiry time, but a margin is permissible for calling\r
their callback after their expiry time. If exact timing is required then\r
configTIMER_TASK_PRIORITY must be set to ensure the timer service task\r
- is the highest priority task in the system. */\r
+ is the highest priority task in the system.\r
+\r
+ This function is called from the tick hook. The tick hook is called\r
+ even when the scheduler is suspended. Therefore it is possible that the\r
+ uxTick count maintained in this function is temporarily ahead of the tick\r
+ count maintained by the kernel. When this is the case a message posted from\r
+ this function will assume a time stamp in advance of the real time stamp,\r
+ which can result in a timer being processed before this function expects it\r
+ to. For example, if the kernel's tick count was 100, and uxTick was 102,\r
+ then this function will not expect the timer to have expired until the\r
+ kernel's tick count is (102 + xBasePeriod), whereas in reality the timer\r
+ will expire when the kernel's tick count is (100 + xBasePeriod). For this\r
+ reason xMargin is used as an allowable margin for premature timer expiries\r
+ as well as late timer expiries. */\r
const portTickType xMargin = 5;\r
#else\r
const portTickType xMargin = 2;\r
#endif\r
\r
+\r
uxTick++;\r
\r
if( uxTick == 0 )\r
}\r
}\r
}\r
- else if( uxTick == xBasePeriod )\r
+ else if( uxTick == ( xBasePeriod - xMargin ) )\r
{\r
/* Neither timer should have expired yet. */\r
if( ( ucISRAutoReloadTimerCounter != 0 ) || ( ucISROneShotTimerCounter != 0 ) )\r
configASSERT( xTestStatus );\r
}\r
}\r
- else if( uxTick == ( 2 * xBasePeriod ) )\r
+ else if( uxTick == ( ( 2 * xBasePeriod ) - xMargin ) )\r
{\r
/* The auto reload timer will still be active, but the one shot timer\r
should now have stopped - however, at this time neither of the timers\r
a few ticks ago. */\r
xTimerStopFromISR( xISRAutoReloadTimer, NULL );\r
} \r
- else if( uxTick == ( 4 * xBasePeriod ) )\r
+ else if( uxTick == ( 4 * ( xBasePeriod - xMargin ) ) )\r
{\r
/* The auto reload timer is now stopped, and the one shot timer is\r
active, but at this time neither timer should have expired since the\r
configASSERT( xTestStatus );\r
}\r
} \r
- else if( uxTick == ( ( 8 * xBasePeriod ) + xMargin ) )\r
+ else if( uxTick == ( 8 * xBasePeriod ) )\r
{\r
/* The auto reload timer is now stopped, and the one shot timer has\r
already expired and then stopped itself. Both callback counters should\r
/* Now reset the one shot timer. */\r
xTimerResetFromISR( xISROneShotTimer, NULL );\r
} \r
- else if( uxTick == ( 9 * xBasePeriod ) )\r
+ else if( uxTick == ( ( 9 * xBasePeriod ) - xMargin ) )\r
{\r
/* Only the one shot timer should be running, but it should not have\r
expired since the last test. Check the callback counters have not\r
\r
xTimerResetFromISR( xISROneShotTimer, NULL );\r
} \r
- else if( uxTick == ( 10 * xBasePeriod ) )\r
+ else if( uxTick == ( ( 10 * xBasePeriod ) - ( 2 * xMargin ) ) )\r
{\r
/* Only the one shot timer should be running, but it should not have\r
expired since the last test. Check the callback counters have not\r
\r
xTimerResetFromISR( xISROneShotTimer, NULL );\r
}\r
- else if( uxTick == ( 11 * xBasePeriod ) )\r
+ else if( uxTick == ( ( 11 * xBasePeriod ) - ( 3 * xMargin ) ) )\r
{\r
/* Only the one shot timer should be running, but it should not have\r
expired since the last test. Check the callback counters have not\r
\r
xTimerResetFromISR( xISROneShotTimer, NULL );\r
} \r
- else if( uxTick == ( ( 12 * xBasePeriod ) + xMargin ) )\r
+ else if( uxTick == ( ( 12 * xBasePeriod ) - ( 2 * xMargin ) ) )\r
{\r
/* Only the one shot timer should have been running and this time it\r
should have expired. Check its callback count has been incremented.\r