\r
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )\r
{\r
+ unsigned long ulCalculatedLoadValue;\r
+ \r
/* The tick interrupt has already executed, and the SysTick\r
count reloaded with ulReloadValue. Reset the\r
portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick\r
period. */\r
- portNVIC_SYSTICK_LOAD_REG = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );\r
-\r
+ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );\r
+\r
+ /* Don't allow a tiny value, or values that have somehow \r
+ underflowed because the post sleep hook did something \r
+ that took too long. */\r
+ if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) )\r
+ {\r
+ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL );\r
+ }\r
+ \r
+ portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue;\r
+ \r
/* The tick interrupt handler will already have pended the tick\r
processing in the kernel. As the pending tick will be\r
processed as soon as this function exits, the tick value\r
\r
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )\r
{\r
+ unsigned long ulCalculatedLoadValue;\r
+ \r
/* The tick interrupt has already executed, and the SysTick\r
count reloaded with ulReloadValue. Reset the\r
portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick\r
period. */\r
- portNVIC_SYSTICK_LOAD_REG = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );\r
-\r
+ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );\r
+\r
+ /* Don't allow a tiny value, or values that have somehow \r
+ underflowed because the post sleep hook did something \r
+ that took too long. */\r
+ if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) )\r
+ {\r
+ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL );\r
+ }\r
+ \r
+ portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue;\r
+ \r
/* The tick interrupt handler will already have pended the tick\r
processing in the kernel. As the pending tick will be\r
processed as soon as this function exits, the tick value\r
\r
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )\r
{\r
+ unsigned long ulCalculatedLoadValue;\r
+ \r
/* The tick interrupt has already executed, and the SysTick\r
count reloaded with ulReloadValue. Reset the\r
portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick\r
period. */\r
- portNVIC_SYSTICK_LOAD_REG = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );\r
-\r
+ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );\r
+\r
+ /* Don't allow a tiny value, or values that have somehow \r
+ underflowed because the post sleep hook did something \r
+ that took too long. */\r
+ if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) )\r
+ {\r
+ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL );\r
+ }\r
+ \r
+ portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue;\r
+ \r
/* The tick interrupt handler will already have pended the tick\r
processing in the kernel. As the pending tick will be\r
processed as soon as this function exits, the tick value\r
*/\r
extern void vPortEnableVFP( void );\r
\r
+/*\r
+ * Used to catch tasks that attempt to return from their implementing function.\r
+ */\r
+static void prvTaskExitError( void );\r
+\r
/*-----------------------------------------------------------*/\r
\r
/*\r
pxTopOfStack--;\r
*pxTopOfStack = ( portSTACK_TYPE ) pxCode; /* PC */\r
pxTopOfStack--;\r
- *pxTopOfStack = 0; /* LR */\r
+ *pxTopOfStack = ( portSTACK_TYPE ) prvTaskExitError; /* LR */\r
\r
/* Save code space by skipping register initialisation. */\r
pxTopOfStack -= 5; /* R12, R3, R2 and R1. */\r
}\r
/*-----------------------------------------------------------*/\r
\r
+static void prvTaskExitError( void )\r
+{\r
+ /* A function that implements a task must not exit or attempt to return to\r
+ its caller as there is nothing to return to. If a task wants to exit it\r
+ should instead call vTaskDelete( NULL ).\r
+\r
+ Artificially force an assert() to be triggered if configASSERT() is\r
+ defined, then stop here so application writers can catch the error. */\r
+ configASSERT( uxCriticalNesting == ~0UL );\r
+ portDISABLE_INTERRUPTS();\r
+ for( ;; );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
/*\r
* See header file for description.\r
*/\r
to be unsuspended then abandon the low power entry. */\r
if( eTaskConfirmSleepModeStatus() == eAbortSleep )\r
{\r
+ /* Restart from whatever is left in the count register to complete\r
+ this tick period. */\r
+ portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;\r
+\r
/* Restart SysTick. */\r
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;\r
\r
+ /* Reset the reload register to the value required for normal tick\r
+ periods. */\r
+ portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;\r
+\r
/* Re-enable interrupts - see comments above __disable_interrupt()\r
call above. */\r
__enable_interrupt();\r
\r
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )\r
{\r
+ unsigned long ulCalculatedLoadValue;\r
+ \r
/* The tick interrupt has already executed, and the SysTick\r
count reloaded with ulReloadValue. Reset the\r
portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick\r
period. */\r
- portNVIC_SYSTICK_LOAD_REG = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );\r
-\r
+ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );\r
+\r
+ /* Don't allow a tiny value, or values that have somehow \r
+ underflowed because the post sleep hook did something \r
+ that took too long. */\r
+ if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) )\r
+ {\r
+ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL );\r
+ }\r
+ \r
+ portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue;\r
+ \r
/* The tick interrupt handler will already have pended the tick\r
processing in the kernel. As the pending tick will be\r
processed as soon as this function exits, the tick value\r
\r
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )\r
{\r
+ unsigned long ulCalculatedLoadValue;\r
+ \r
/* The tick interrupt has already executed, and the SysTick\r
count reloaded with ulReloadValue. Reset the\r
portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick\r
period. */\r
- portNVIC_SYSTICK_LOAD_REG = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );\r
-\r
+ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );\r
+\r
+ /* Don't allow a tiny value, or values that have somehow \r
+ underflowed because the post sleep hook did something \r
+ that took too long. */\r
+ if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) )\r
+ {\r
+ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL );\r
+ }\r
+ \r
+ portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue;\r
+ \r
/* The tick interrupt handler will already have pended the tick\r
processing in the kernel. As the pending tick will be\r
processed as soon as this function exits, the tick value\r
\r
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )\r
{\r
+ unsigned long ulCalculatedLoadValue;\r
+ \r
/* The tick interrupt has already executed, and the SysTick\r
count reloaded with ulReloadValue. Reset the\r
portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick\r
period. */\r
- portNVIC_SYSTICK_LOAD_REG = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );\r
-\r
+ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );\r
+\r
+ /* Don't allow a tiny value, or values that have somehow \r
+ underflowed because the post sleep hook did something \r
+ that took too long. */\r
+ if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) )\r
+ {\r
+ ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL );\r
+ }\r
+ \r
+ portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue;\r
+ \r
/* The tick interrupt handler will already have pended the tick\r
processing in the kernel. As the pending tick will be\r
processed as soon as this function exits, the tick value\r