responsible for resulting newlib operation. User must be familiar with\r
newlib and must provide system-wide implementations of the necessary\r
stubs. Be warned that (at the time of writing) the current newlib design\r
- implements a system-wide malloc() that must be provided with locks. */\r
+ implements a system-wide malloc() that must be provided with locks.\r
+\r
+ See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html\r
+ for additional information. */\r
struct _reent xNewLib_reent;\r
#endif\r
\r
PRIVILEGED_DATA static volatile TickType_t xTickCount = ( TickType_t ) configINITIAL_TICK_COUNT;\r
PRIVILEGED_DATA static volatile UBaseType_t uxTopReadyPriority = tskIDLE_PRIORITY;\r
PRIVILEGED_DATA static volatile BaseType_t xSchedulerRunning = pdFALSE;\r
-PRIVILEGED_DATA static volatile UBaseType_t uxPendedTicks = ( UBaseType_t ) 0U;\r
+PRIVILEGED_DATA static volatile TickType_t xPendedTicks = ( TickType_t ) 0U;\r
PRIVILEGED_DATA static volatile BaseType_t xYieldPending = pdFALSE;\r
PRIVILEGED_DATA static volatile BaseType_t xNumOfOverflows = ( BaseType_t ) 0;\r
PRIVILEGED_DATA static UBaseType_t uxTaskNumber = ( UBaseType_t ) 0U;\r
\r
#if ( configUSE_NEWLIB_REENTRANT == 1 )\r
{\r
- /* Initialise this task's Newlib reent structure. */\r
+ /* Initialise this task's Newlib reent structure.\r
+ See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html\r
+ for additional information. */\r
_REENT_INIT_PTR( ( &( pxNewTCB->xNewLib_reent ) ) );\r
}\r
#endif\r
check the xTasksWaitingTermination list. */\r
++uxDeletedTasksWaitingCleanUp;\r
\r
+ /* Call the delete hook before portPRE_TASK_DELETE_HOOK() as\r
+ portPRE_TASK_DELETE_HOOK() does not return in the Win32 port. */\r
+ traceTASK_DELETE( pxTCB );\r
+\r
/* The pre-delete hook is primarily for the Windows simulator,\r
in which Windows specific clean up operations are performed,\r
after which it is not possible to yield away from this task -\r
else\r
{\r
--uxCurrentNumberOfTasks;\r
+ traceTASK_DELETE( pxTCB );\r
prvDeleteTCB( pxTCB );\r
\r
/* Reset the next expected unblock time in case it referred to\r
the task that has just been deleted. */\r
prvResetNextTaskUnblockTime();\r
}\r
-\r
- traceTASK_DELETE( pxTCB );\r
}\r
taskEXIT_CRITICAL();\r
\r
#if ( configUSE_NEWLIB_REENTRANT == 1 )\r
{\r
/* Switch Newlib's _impure_ptr variable to point to the _reent\r
- structure specific to the task that will run first. */\r
+ structure specific to the task that will run first.\r
+ See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html\r
+ for additional information. */\r
_impure_ptr = &( pxCurrentTCB->xNewLib_reent );\r
}\r
#endif /* configUSE_NEWLIB_REENTRANT */\r
{\r
TCB_t *pxTCB = NULL;\r
BaseType_t xAlreadyYielded = pdFALSE;\r
+TickType_t xTicksToNextUnblockTime;\r
\r
/* If uxSchedulerSuspended is zero then this function does not match a\r
previous call to vTaskSuspendAll(). */\r
they should be processed now. This ensures the tick count does\r
not slip, and that any delayed tasks are resumed at the correct\r
time. */\r
+ while( xPendedTicks > ( TickType_t ) 0 )\r
{\r
- UBaseType_t uxPendedCounts = uxPendedTicks; /* Non-volatile copy. */\r
+ /* Calculate how far into the future the next task will\r
+ leave the Blocked state because its timeout expired. If\r
+ there are no tasks due to leave the blocked state between\r
+ the time now and the time at which the tick count overflows\r
+ then xNextTaskUnblockTime will the tick overflow time.\r
+ This means xNextTaskUnblockTime can never be less than\r
+ xTickCount, and the following can therefore not\r
+ underflow. */\r
+ configASSERT( xNextTaskUnblockTime >= xTickCount );\r
+ xTicksToNextUnblockTime = xNextTaskUnblockTime - xTickCount;\r
\r
- if( uxPendedCounts > ( UBaseType_t ) 0U )\r
+ /* Don't want to move the tick count more than the number\r
+ of ticks that are pending, so cap if necessary. */\r
+ if( xTicksToNextUnblockTime > xPendedTicks )\r
{\r
- do\r
- {\r
- if( xTaskIncrementTick() != pdFALSE )\r
- {\r
- xYieldPending = pdTRUE;\r
- }\r
- else\r
- {\r
- mtCOVERAGE_TEST_MARKER();\r
- }\r
- --uxPendedCounts;\r
- } while( uxPendedCounts > ( UBaseType_t ) 0U );\r
+ xTicksToNextUnblockTime = xPendedTicks;\r
+ }\r
\r
- uxPendedTicks = 0;\r
+ if( xTicksToNextUnblockTime == 0 )\r
+ {\r
+ /* xTicksToNextUnblockTime could be zero if the tick\r
+ count is about to overflow and xTicksToNetUnblockTime\r
+ holds the time at which the tick count will overflow\r
+ (rather than the time at which the next task will\r
+ unblock). Set to 1 otherwise xPendedTicks won't be\r
+ decremented below. */\r
+ xTicksToNextUnblockTime = ( TickType_t ) 1;\r
}\r
- else\r
+ else if( xTicksToNextUnblockTime > ( TickType_t ) 1 )\r
{\r
- mtCOVERAGE_TEST_MARKER();\r
+ /* Move the tick count one short of the next unblock\r
+ time, then call xTaskIncrementTick() to move the tick\r
+ count up to the next unblock time to unblock the task,\r
+ if any. This will also swap the blocked task and\r
+ overflow blocked task lists if necessary. */\r
+ xTickCount += ( xTicksToNextUnblockTime - ( TickType_t ) 1 );\r
}\r
+ xYieldPending |= xTaskIncrementTick();\r
+\r
+ /* Adjust for the number of ticks just added to\r
+ xTickCount and go around the loop again if\r
+ xTicksToCatchUp is still greater than 0. */\r
+ xPendedTicks -= xTicksToNextUnblockTime;\r
}\r
\r
if( xYieldPending != pdFALSE )\r
#endif /* configUSE_TICKLESS_IDLE */\r
/*----------------------------------------------------------*/\r
\r
+BaseType_t xTaskCatchUpTicks( TickType_t xTicksToCatchUp )\r
+{\r
+BaseType_t xYieldRequired = pdFALSE;\r
+\r
+ /* Must not be called with the scheduler suspended as the implementation\r
+ relies on xPendedTicks being wound down to 0 in xTaskResumeAll(). */\r
+ configASSERT( uxSchedulerSuspended == 0 );\r
+\r
+ /* Use xPendedTicks to mimic xTicksToCatchUp number of ticks occuring when\r
+ the scheduler is suspended so the ticks are executed in xTaskResumeAll(). */\r
+ vTaskSuspendAll();\r
+ xPendedTicks += xTicksToCatchUp;\r
+ xYieldRequired = xTaskResumeAll();\r
+\r
+ return xYieldRequired;\r
+}\r
+/*----------------------------------------------------------*/\r
+\r
#if ( INCLUDE_xTaskAbortDelay == 1 )\r
\r
BaseType_t xTaskAbortDelay( TaskHandle_t xTask )\r
{\r
/* Guard against the tick hook being called when the pended tick\r
count is being unwound (when the scheduler is being unlocked). */\r
- if( uxPendedTicks == ( UBaseType_t ) 0U )\r
+ if( xPendedTicks == ( TickType_t ) 0 )\r
{\r
vApplicationTickHook();\r
}\r
}\r
}\r
#endif /* configUSE_TICK_HOOK */\r
+\r
+ #if ( configUSE_PREEMPTION == 1 )\r
+ {\r
+ if( xYieldPending != pdFALSE )\r
+ {\r
+ xSwitchRequired = pdTRUE;\r
+ }\r
+ else\r
+ {\r
+ mtCOVERAGE_TEST_MARKER();\r
+ }\r
+ }\r
+ #endif /* configUSE_PREEMPTION */\r
}\r
else\r
{\r
- ++uxPendedTicks;\r
+ ++xPendedTicks;\r
\r
/* The tick hook gets called at regular intervals, even if the\r
scheduler is locked. */\r
#endif\r
}\r
\r
- #if ( configUSE_PREEMPTION == 1 )\r
- {\r
- if( xYieldPending != pdFALSE )\r
- {\r
- xSwitchRequired = pdTRUE;\r
- }\r
- else\r
- {\r
- mtCOVERAGE_TEST_MARKER();\r
- }\r
- }\r
- #endif /* configUSE_PREEMPTION */\r
-\r
return xSwitchRequired;\r
}\r
/*-----------------------------------------------------------*/\r
#if ( configUSE_NEWLIB_REENTRANT == 1 )\r
{\r
/* Switch Newlib's _impure_ptr variable to point to the _reent\r
- structure specific to this task. */\r
+ structure specific to this task.\r
+ See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html\r
+ for additional information. */\r
_impure_ptr = &( pxCurrentTCB->xNewLib_reent );\r
}\r
#endif /* configUSE_NEWLIB_REENTRANT */\r
portCLEAN_UP_TCB( pxTCB );\r
\r
/* Free up the memory allocated by the scheduler for the task. It is up\r
- to the task to free any memory allocated at the application level. */\r
+ to the task to free any memory allocated at the application level.\r
+ See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html\r
+ for additional information. */\r
#if ( configUSE_NEWLIB_REENTRANT == 1 )\r
{\r
_reclaim_reent( &( pxTCB->xNewLib_reent ) );\r
\r
#if( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) )\r
\r
- TickType_t xTaskGetIdleRunTimeCounter( void )\r
+ uint32_t ulTaskGetIdleRunTimeCounter( void )\r
{\r
return xIdleTaskHandle->ulRunTimeCounter;\r
}\r