\r
#if ( configUSE_TRACE_FACILITY == 1 )\r
unsigned portBASE_TYPE uxTCBNumber; /*< This is used for tracing the scheduler and making debugging easier only. */\r
- #endif \r
- \r
+ #endif\r
+\r
#if ( configUSE_MUTEXES == 1 )\r
unsigned portBASE_TYPE uxBasePriority; /*< The priority last assigned to the task - used by the priority inheritance mechanism. */\r
#endif\r
#if ( configGENERATE_RUN_TIME_STATS == 1 )\r
unsigned portLONG ulRunTimeCounter; /*< Used for calculating how much CPU time each task is utilising. */\r
#endif\r
- \r
+\r
} tskTCB;\r
\r
/*\r
\r
/*lint -e956 */\r
\r
-tskTCB * volatile pxCurrentTCB = NULL; \r
+tskTCB * volatile pxCurrentTCB = NULL;\r
\r
/* Lists for ready and blocked tasks. --------------------*/\r
\r
} \\r
vListInsertEnd( ( xList * ) &( pxReadyTasksLists[ pxTCB->uxPriority ] ), &( pxTCB->xGenericListItem ) ); \\r
}\r
-/*-----------------------------------------------------------*/ \r
+/*-----------------------------------------------------------*/\r
\r
/*\r
* Macro that looks at the list of tasks that are currently delayed to see if\r
pxNewTCB = prvAllocateTCBAndStack( usStackDepth );\r
\r
if( pxNewTCB != NULL )\r
- { \r
+ {\r
portSTACK_TYPE *pxTopOfStack;\r
\r
/* Setup the newly allocated TCB with the initial state of the task. */\r
}\r
#else\r
{\r
- pxTopOfStack = pxNewTCB->pxStack; \r
+ pxTopOfStack = pxNewTCB->pxStack;\r
\r
/* If we want to use stack checking on architectures that use\r
a positive stack growth direction then we also need to store the\r
prvInitialiseTaskLists();\r
}\r
else\r
- { \r
+ {\r
/* If the scheduler is not already running, make this task the\r
current task if it is the highest priority task to be created\r
so far. */\r
{\r
if( pxCurrentTCB->uxPriority <= uxPriority )\r
{\r
- pxCurrentTCB = pxNewTCB; \r
+ pxCurrentTCB = pxNewTCB;\r
}\r
}\r
- } \r
+ }\r
\r
/* Remember the top priority to make context switching faster. Use\r
the priority in pxNewTCB as this has been capped to a valid value. */\r
scheduler for the TCB and stack. */\r
vListRemove( &( pxTCB->xGenericListItem ) );\r
\r
- /* Is the task waiting on an event also? */ \r
+ /* Is the task waiting on an event also? */\r
if( pxTCB->xEventListItem.pvContainer )\r
{\r
vListRemove( &( pxTCB->xEventListItem ) );\r
++uxTasksDeleted;\r
\r
/* Increment the uxTaskNumberVariable also so kernel aware debuggers\r
- can detect that the task lists need re-generating. */ \r
+ can detect that the task lists need re-generating. */\r
uxTaskNumber++;\r
}\r
taskEXIT_CRITICAL();\r
{\r
taskYIELD();\r
}\r
- } \r
- \r
+ }\r
+\r
#endif\r
/*-----------------------------------------------------------*/\r
\r
scheduler is suspended will not get placed in the ready\r
list or removed from the blocked list until the scheduler\r
is resumed.\r
- \r
+\r
This task cannot be in an event list as it is the currently\r
executing task. */\r
\r
}\r
xAlreadyYielded = xTaskResumeAll();\r
}\r
- \r
+\r
/* Force a reschedule if xTaskResumeAll has not already done so, we may\r
have put ourselves to sleep. */\r
if( !xAlreadyYielded )\r
taskYIELD();\r
}\r
}\r
- \r
+\r
#endif\r
/*-----------------------------------------------------------*/\r
\r
/* If null is passed in here then we are changing the\r
priority of the calling function. */\r
pxTCB = prvGetTCBFromHandle( pxTask );\r
- \r
+\r
traceTASK_PRIORITY_SET( pxTask, uxNewPriority );\r
\r
#if ( configUSE_MUTEXES == 1 )\r
task of higher priority that is ready to execute. */\r
xYieldRequired = pdTRUE;\r
}\r
- \r
- \r
+\r
+\r
\r
#if ( configUSE_MUTEXES == 1 )\r
{\r
{\r
pxTCB->uxPriority = uxNewPriority;\r
}\r
- \r
+\r
/* The base priority gets set whatever. */\r
- pxTCB->uxBasePriority = uxNewPriority; \r
+ pxTCB->uxBasePriority = uxNewPriority;\r
}\r
#else\r
{\r
can do this even if the scheduler is suspended. */\r
vListRemove( &( pxTCB->xGenericListItem ) );\r
prvAddTaskToReadyQueue( pxTCB );\r
- } \r
- \r
+ }\r
+\r
if( xYieldRequired == pdTRUE )\r
{\r
taskYIELD();\r
- } \r
+ }\r
}\r
}\r
taskEXIT_CRITICAL();\r
/* Remove task from the ready/delayed list and place in the suspended list. */\r
vListRemove( &( pxTCB->xGenericListItem ) );\r
\r
- /* Is the task waiting on an event also? */ \r
+ /* Is the task waiting on an event also? */\r
if( pxTCB->xEventListItem.pvContainer )\r
{\r
vListRemove( &( pxTCB->xEventListItem ) );\r
{\r
/* Has the task already been resumed from within an ISR? */\r
if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) != pdTRUE )\r
- { \r
+ {\r
/* Is it in the suspended list because it is in the\r
Suspended state? It is possible to be in the suspended\r
list because it is blocked on a task with no timeout\r
if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )\r
{\r
xYieldRequired = ( pxTCB->uxPriority >= pxCurrentTCB->uxPriority );\r
- vListRemove( &( pxTCB->xGenericListItem ) ); \r
+ vListRemove( &( pxTCB->xGenericListItem ) );\r
prvAddTaskToReadyQueue( pxTCB );\r
}\r
else\r
the created tasks contain a status word with interrupts switched on\r
so interrupts will automatically get re-enabled when the first task\r
starts to run.\r
- \r
+\r
STEPPING THROUGH HERE USING A DEBUGGER CAN CAUSE BIG PROBLEMS IF THE\r
DEBUGGER ALLOWS INTERRUPTS TO BE PROCESSED. */\r
portDISABLE_INTERRUPTS();\r
--uxSchedulerSuspended;\r
\r
if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )\r
- { \r
+ {\r
if( uxCurrentNumberOfTasks > ( unsigned portBASE_TYPE ) 0 )\r
{\r
portBASE_TYPE xYieldRequired = pdFALSE;\r
- \r
+\r
/* Move any readied tasks from the pending list into the\r
appropriate ready list. */\r
while( ( pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( ( xList * ) &xPendingReadyList ) ) ) != NULL )\r
vListRemove( &( pxTCB->xEventListItem ) );\r
vListRemove( &( pxTCB->xGenericListItem ) );\r
prvAddTaskToReadyQueue( pxTCB );\r
- \r
+\r
/* If we have moved a task that has a priority higher than\r
the current task then we should yield. */\r
if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )\r
}\r
#endif\r
}\r
- \r
+\r
if( ( xYieldRequired == pdTRUE ) || ( xMissedYield == pdTRUE ) )\r
{\r
xAlreadyYielded = pdTRUE;\r
\r
if( !listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxQueue ] ) ) )\r
{\r
- prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) &( pxReadyTasksLists[ uxQueue ] ), tskREADY_CHAR ); \r
+ prvListTaskWithinSingleList( pcWriteBuffer, ( xList * ) &( pxReadyTasksLists[ uxQueue ] ), tskREADY_CHAR );\r
}\r
}while( uxQueue > ( unsigned portSHORT ) tskIDLE_PRIORITY );\r
\r
vTaskSuspendAll();\r
{\r
/* Run through all the lists that could potentially contain a TCB,\r
- generating a table of run timer percentages in the provided \r
+ generating a table of run timer percentages in the provided\r
buffer. */\r
\r
pcWriteBuffer[ 0 ] = ( signed portCHAR ) 0x00;\r
vListRemove( ( xListItem * ) &( pxTCB->xGenericListItem ) );\r
\r
prvDeleteTCB( ( tskTCB * ) pxTCB );\r
- } \r
+ }\r
}\r
\r
#endif\r
{\r
xTCB = ( tskTCB * ) xTask;\r
}\r
- \r
+\r
/* Save the hook function in the TCB. A critical section is required as\r
the value can be accessed from an interrupt. */\r
portENTER_CRITICAL();\r
xTCB->pxTaskTag = pxTagValue;\r
portEXIT_CRITICAL();\r
}\r
- \r
+\r
#endif\r
/*-----------------------------------------------------------*/\r
\r
\r
return xReturn;\r
}\r
- \r
+\r
#endif\r
/*-----------------------------------------------------------*/\r
\r
void vTaskSwitchContext( void )\r
{\r
+ if( uxSchedulerSuspended != ( unsigned portBASE_TYPE ) pdFALSE )\r
+ {\r
+ /* The scheduler is currently suspended - do not allow a context\r
+ switch. */\r
+ xMissedYield = pdTRUE;\r
+ return;\r
+ }\r
+\r
traceTASK_SWITCHED_OUT();\r
\r
#if ( configGENERATE_RUN_TIME_STATS == 1 )\r
unsigned portLONG ulTempCounter = portGET_RUN_TIME_COUNTER_VALUE();\r
\r
/* Add the amount of time the task has been running to the accumulated\r
- time so far. The time the task started running was stored in \r
+ time so far. The time the task started running was stored in\r
ulTaskSwitchedInTime. Note that there is no overflow protection here\r
so count values are only valid until the timer overflows. Generally\r
this will be about 1 hour assuming a 1uS timer increment. */\r
}\r
#endif\r
\r
-\r
- if( uxSchedulerSuspended != ( unsigned portBASE_TYPE ) pdFALSE )\r
- {\r
- /* The scheduler is currently suspended - do not allow a context\r
- switch. */\r
- xMissedYield = pdTRUE;\r
- return;\r
- }\r
-\r
taskFIRST_CHECK_FOR_STACK_OVERFLOW();\r
taskSECOND_CHECK_FOR_STACK_OVERFLOW();\r
\r
\r
\r
#if ( INCLUDE_vTaskSuspend == 1 )\r
- { \r
+ {\r
if( xTicksToWait == portMAX_DELAY )\r
{\r
/* Add ourselves to the suspended task list instead of a delayed task\r
/* Calculate the time at which the task should be woken if the event does\r
not occur. This may overflow but this doesn't matter. */\r
xTimeToWake = xTickCount + xTicksToWait;\r
- \r
+\r
listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake );\r
- \r
+\r
if( xTimeToWake < xTickCount )\r
{\r
/* Wake time has overflowed. Place this item in the overflow list. */\r
/* Calculate the time at which the task should be woken if the event does\r
not occur. This may overflow but this doesn't matter. */\r
xTimeToWake = xTickCount + xTicksToWait;\r
- \r
+\r
listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake );\r
- \r
+\r
if( xTimeToWake < xTickCount )\r
{\r
/* Wake time has overflowed. Place this item in the overflow list. */\r
/* The event list is sorted in priority order, so we can remove the\r
first in the list, remove the TCB from the delayed list, and add\r
it to the ready list.\r
- \r
+\r
If an event is for a queue that is locked then this function will never\r
get called - the lock count on the queue will get modified instead. This\r
means we can always expect exclusive access to the event list here. */\r
see if any other task has become available. If we are using\r
preemption we don't need to do this as any task becoming available\r
will automatically get the processor anyway. */\r
- taskYIELD(); \r
+ taskYIELD();\r
}\r
#endif\r
\r
timesliced. If a task that is sharing the idle priority is ready\r
to run then the idle task should yield before the end of the\r
timeslice.\r
- \r
+\r
A critical region is not required here as we are just reading from\r
the list, and an occasional incorrect value will not matter. If\r
the ready list at the idle priority contains more than one task\r
{\r
pxTCB->pxTaskTag = NULL;\r
}\r
- #endif \r
+ #endif\r
\r
#if ( configGENERATE_RUN_TIME_STATS == 1 )\r
{\r
/*-----------------------------------------------------------*/\r
\r
static void prvCheckTasksWaitingTermination( void )\r
-{ \r
+{\r
#if ( INCLUDE_vTaskDelete == 1 )\r
- { \r
+ {\r
portBASE_TYPE xListIsEmpty;\r
\r
/* ucTasksDeleted is used to prevent vTaskSuspendAll() being called\r
if( uxTasksDeleted > ( unsigned portBASE_TYPE ) 0 )\r
{\r
vTaskSuspendAll();\r
- xListIsEmpty = listLIST_IS_EMPTY( &xTasksWaitingTermination ); \r
+ xListIsEmpty = listLIST_IS_EMPTY( &xTasksWaitingTermination );\r
xTaskResumeAll();\r
\r
if( !xListIsEmpty )\r
tskTCB *pxTCB;\r
\r
portENTER_CRITICAL();\r
- { \r
+ {\r
pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( ( xList * ) &xTasksWaitingTermination ) );\r
vListRemove( &( pxTCB->xGenericListItem ) );\r
--uxCurrentNumberOfTasks;\r
if( pxNewTCB->pxStack == NULL )\r
{\r
/* Could not allocate the stack. Delete the allocated TCB. */\r
- vPortFree( pxNewTCB ); \r
- pxNewTCB = NULL; \r
- } \r
+ vPortFree( pxNewTCB );\r
+ pxNewTCB = NULL;\r
+ }\r
else\r
{\r
/* Just to help debugging. */\r
listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList );\r
do\r
{\r
+ /* Get next TCB in from the list. */\r
listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList );\r
\r
- ulStatsAsPercentage = ( 100UL * pxNextTCB->ulRunTimeCounter ) / ulTotalRunTime;\r
-\r
- if( ulStatsAsPercentage > 0UL )\r
+ /* Divide by zero check. */\r
+ if( ulTotalRunTime > 0UL )\r
{\r
- sprintf( pcStatsString, ( portCHAR * ) "%s\t\t\t%lu\t\t\t%lu%%\r\n", pxNextTCB->pcTaskName, pxNextTCB->ulRunTimeCounter, ulStatsAsPercentage );\r
- }\r
- else\r
- {\r
- sprintf( pcStatsString, ( portCHAR * ) "%s\t\t\t%lu\t\t\t< 1%%\r\n", pxNextTCB->pcTaskName, pxNextTCB->ulRunTimeCounter );\r
- }\r
+ /* Has the task run at all? */\r
+ if( pxNextTCB->ulRunTimeCounter == 0 )\r
+ {\r
+ /* The task has used no CPU time at all. */\r
+ sprintf( pcStatsString, ( portCHAR * ) "%s\t\t0\t\t0%%\r\n", pxNextTCB->pcTaskName );\r
+ }\r
+ else\r
+ {\r
+ /* What percentage of the total run time as the task used?\r
+ This will always be rounded down to the nearest integer. */\r
+ ulStatsAsPercentage = ( 100UL * pxNextTCB->ulRunTimeCounter ) / ulTotalRunTime;\r
+\r
+ if( ulStatsAsPercentage > 0UL )\r
+ {\r
+ sprintf( pcStatsString, ( portCHAR * ) "%s\t\t%u\t\t%u%%\r\n", pxNextTCB->pcTaskName, pxNextTCB->ulRunTimeCounter, ulStatsAsPercentage );\r
+ }\r
+ else\r
+ {\r
+ /* If the percentage is zero here then the task has\r
+ consumed less than 1% of the total run time. */
+ sprintf( pcStatsString, ( portCHAR * ) "%s\t\t%u\t\t<1%%\r\n", pxNextTCB->pcTaskName, pxNextTCB->ulRunTimeCounter );\r
+ }\r
+ }\r
\r
- strcat( ( portCHAR * ) pcWriteBuffer, ( portCHAR * ) pcStatsString );\r
+ strcat( ( portCHAR * ) pcWriteBuffer, ( portCHAR * ) pcStatsString );\r
+ }\r
\r
} while( pxNextTCB != pxFirstTCB );\r
}\r
portBASE_TYPE xTaskGetSchedulerState( void )\r
{\r
portBASE_TYPE xReturn;\r
- \r
+\r
if( xSchedulerRunning == pdFALSE )\r
{\r
xReturn = taskSCHEDULER_NOT_STARTED;\r
xReturn = taskSCHEDULER_SUSPENDED;\r
}\r
}\r
- \r
+\r
return xReturn;\r
}\r
\r
/*-----------------------------------------------------------*/\r
\r
#if ( configUSE_MUTEXES == 1 )\r
- \r
+\r
void vTaskPriorityInherit( xTaskHandle * const pxMutexHolder )\r
{\r
tskTCB * const pxTCB = ( tskTCB * ) pxMutexHolder;\r
#endif\r
/*-----------------------------------------------------------*/\r
\r
-#if ( configUSE_MUTEXES == 1 ) \r
+#if ( configUSE_MUTEXES == 1 )\r
\r
void vTaskPriorityDisinherit( xTaskHandle * const pxMutexHolder )\r
{\r
/*-----------------------------------------------------------*/\r
\r
\r
- \r
+\r
\r