]> git.sur5r.net Git - freertos/blobdiff - Source/tasks.c
Added code to allow a vTaskPrioritySet() caller to pass in the current TCB as well...
[freertos] / Source / tasks.c
index 3eef9f0beb0d7dcb2273c97f0dcc2316e2cdc72b..ade94f971c015798db82c2183e0f9d25e553f756 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.1.1 - Copyright (C) 2003-2006 Richard Barry.\r
+       FreeRTOS.org V5.0.0 - Copyright (C) 2003-2008 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \r
        of http://www.FreeRTOS.org for full details of how and when the exception\r
        can be applied.\r
 \r
-       ***************************************************************************\r
-       See http://www.FreeRTOS.org for documentation, latest information, license\r
-       and contact details.  Please ensure to read the configuration and relevant\r
-       port sections of the online documentation.\r
-       ***************************************************************************\r
-*/\r
-\r
-/*\r
-Changes from V1.00:\r
-       \r
-       + Call to portRESTORE_CONTEXT has been removed.  The first context\r
-         switch is now performed within sPortStartScheduler().\r
-\r
-Changes from V1.01:\r
-\r
-       + More use of 8bit data types.\r
-       + Function name prefixes changed where the data type returned has changed.\r
-       + configUSE_TRACE_FACILITY is no longer defined by default.\r
-\r
-Changes from V1.2.0\r
-\r
-       + Introduced ucTopReadyPriority.  This tracks the highest priority ready\r
-         queue that contains a valid TCB and thus makes the context switch\r
-         slightly faster.\r
-\r
-       + prvAddTaskToReadyQueue() has been made a macro.\r
-\r
-Changes from V1.2.6\r
-\r
-       + Added conditional compilation directives.\r
-       + Extended API.\r
-       + Rearranged function order.\r
-       + Creating a task now causes a context switch if the task being created\r
-         has a higher priority than the calling task - assuming the kernel is\r
-         running.\r
-       + vTaskDelete() now only causes a context switch if the calling task is\r
-         the task being deleted.\r
-\r
-Changes from V2.0.0\r
-\r
-       + Allow the type of the tick count to be 16 or 32 bits.\r
-       + Introduce xPendingReadyList feature to allow the time interrupts have to\r
-         be disabled to be minimised.\r
-       + Remove the #if( INCLUDE_vTaskSuspendAll ) statements.  vTaskSuspendAll()\r
-         is now always included as it is used by the scheduler itself.\r
-\r
-Changes from V2.1.0\r
-\r
-       + Bug fix - pxCurrentTCB is now initialised before the call to\r
-         prvInitializeTaskLists().  Previously pxCurrentTCB could be accessed\r
-         while null.\r
-\r
-Changed from V2.1.1\r
-\r
-       + Change to where lStackSize is declared within sTaskCreate() to prevent\r
-         compiler warnings with 8051 port.\r
-\r
-Changes from V2.2.0\r
-\r
-       + Explicit use of 'signed' qualifier on portCHAR types added.\r
-       + Changed odd calculation of initial pxTopOfStack value when\r
-         portSTACK_GROWTH < 0.\r
-       + Removed pcVersionNumber definition.\r
-\r
-Changes from V2.5.3\r
-\r
-       + cTaskResumeAll() modified to ensure it can be called prior to the task\r
-         lists being initialised.\r
-\r
-Changes from V2.5.5\r
+    ***************************************************************************\r
+    ***************************************************************************\r
+    *                                                                         *\r
+    * SAVE TIME AND MONEY!  We can port FreeRTOS.org to your own hardware,    *\r
+    * and even write all or part of your application on your behalf.          *\r
+    * See http://www.OpenRTOS.com for details of the services we provide to   *\r
+    * expedite your project.                                                  *\r
+    *                                                                         *\r
+    ***************************************************************************\r
+    ***************************************************************************\r
 \r
-       + Added API function vTaskDelayUntil().\r
-       + Added INCLUDE_vTaskDelay conditional compilation.\r
+       Please ensure to read the configuration and relevant port sections of the\r
+       online documentation.\r
 \r
-Changes from V2.6.0\r
+       http://www.FreeRTOS.org - Documentation, latest information, license and \r
+       contact details.\r
 \r
-       + Updated the vWriteTraceToBuffer macro to always be 4 byte aligned so it\r
-         can be used on ARM architectures.\r
-       + tskMAX_TASK_NAME_LEN definition replaced with the port specific\r
-         configMAX_TASK_NAME_LEN definition.\r
-       + Removed the call to strcpy when copying across the task name into the\r
-         TCB.\r
-       + Added ucTasksDeleted variable to prevent vTaskSuspendAll() being called\r
-         too often in the idle task.\r
+       http://www.SafeRTOS.com - A version that is certified for use in safety \r
+       critical systems.\r
 \r
-Changes between V3.0.0 and V2.6.1\r
-\r
-       + When resuming the scheduler a yield is performed if either a tick has\r
-         been missed, or a task is moved from the pending ready list into a ready\r
-         list.  Previously a yield was not performed on this second condition.\r
-       + Introduced the type portBASE_TYPE.  This necessitates several API\r
-         changes.\r
-       + Removed the sUsingPreemption variable.  The constant defined in\r
-         portmacro.h is now used directly.\r
-       + The idle task can now include an optional hook function - and no longer\r
-         completes its time slice if other tasks with equal priority to it are\r
-         ready to run.\r
-       + See the FreeRTOS.org documentation for more information on V2.x.x to\r
-         V3.x.x modifications.\r
-\r
-Changes from V3.1.1\r
-\r
-       + Modified vTaskPrioritySet() and vTaskResume() to allow these functions to\r
-         be called while the scheduler is suspended.\r
-       + Corrected the task ordering within event lists.\r
-\r
-Changes from V3.2.0\r
-\r
-       + Added function xTaskGetCurrentTaskHandle().\r
-\r
-Changes from V3.2.4\r
-\r
-       + Changed the volatile declarations on some variables to reflect the \r
-         changes to the list definitions.\r
-       + Changed the order of the TCB definition so there is commonality between\r
-         the task control block and a co-routine control block.\r
-       + Allow the scheduler to be started even if no tasks other than the idle\r
-         task has been created.  This allows co-routines to run even when no tasks\r
-         have been created.\r
-       + The need for a context switch is now signalled if a task woken by an \r
-         event has a priority greater or equal to the currently running task.\r
-         Previously this was only greater than.\r
-\r
-Changes from V4.0.0\r
-\r
-       + Added the xMissedYield handling.\r
-\r
-Changes from V4.0.1\r
-\r
-       + The function vTaskList() now suspends the scheduler rather than disabling\r
-         interrupts during the creation of the task list.  \r
-       + Allow a task to delete itself by passing in its own handle.  Previously \r
-         this could only be done by passing in NULL.\r
-       + The tick hook function is now called only within a tick isr.  Previously\r
-         it was also called when the tick function was called during the scheduler\r
-         unlocking process.\r
-\r
-Changes from V4.0.3\r
-\r
-       + Extra checks have been placed in vTaskPrioritySet() to avoid unnecessary\r
-         yields.\r
-\r
-Changed from V4.0.4\r
-\r
-       + Bug fix:  The 'value' of the event list item is updated when the priority\r
-         of a task is changed.  Previously only the priority of the TCB itself was\r
-         changed.\r
-       + When resuming a task a check is first made to see if the task is actually\r
-         suspended.\r
-       + vTaskPrioritySet() and vTaskResume() no longer use the event list item.\r
-         This has not been necessary since V4.0.1 when the xMissedYield handling\r
-         was added.\r
-       + Implement xTaskResumeFromISR().\r
-\r
-Changes from V4.0.5\r
-\r
-       + Added utility functions and xOverflowCount variable to facilitate the\r
-         queue.c changes.\r
+       http://www.OpenRTOS.com - Commercial support, development, porting, \r
+       licensing and training services.\r
 */\r
 \r
+\r
 #include <stdio.h>\r
 #include <stdlib.h>\r
 #include <string.h>\r
@@ -196,31 +61,6 @@ Changes from V4.0.5
 #define tskIDLE_STACK_SIZE     configMINIMAL_STACK_SIZE\r
 \r
 \r
-/*\r
- * Default a definitions for backwards compatibility with old\r
- * portmacro.h files.\r
- */\r
-#ifndef configMAX_TASK_NAME_LEN\r
-       #define configMAX_TASK_NAME_LEN 16\r
-#endif\r
-\r
-#ifndef INCLUDE_xTaskGetCurrentTaskHandle\r
-       #define INCLUDE_xTaskGetCurrentTaskHandle 0\r
-#endif\r
-\r
-#ifndef configIDLE_SHOULD_YIELD\r
-       #define configIDLE_SHOULD_YIELD         1\r
-#endif\r
-\r
-#if configMAX_TASK_NAME_LEN < 1\r
-       #undef configMAX_TASK_NAME_LEN\r
-       #define configMAX_TASK_NAME_LEN 1\r
-#endif\r
-\r
-#ifndef INCLUDE_xTaskResumeFromISR\r
-       #define INCLUDE_xTaskResumeFromISR 1\r
-#endif \r
-\r
 /*\r
  * Task control block.  A task control block (TCB) is allocated to each task,\r
  * and stores the context of the task.\r
@@ -232,9 +72,24 @@ typedef struct tskTaskControlBlock
        xListItem                               xEventListItem;         /*< List item used to place the TCB in event lists. */\r
        unsigned portBASE_TYPE  uxPriority;                     /*< The priority of the task where 0 is the lowest priority. */\r
        portSTACK_TYPE                  *pxStack;                       /*< Points to the start of the stack. */\r
-       unsigned portBASE_TYPE  uxTCBNumber;            /*< This is used for tracing the scheduler and making debugging easier only. */\r
        signed portCHAR                 pcTaskName[ configMAX_TASK_NAME_LEN ];/*< Descriptive name given to the task when created.  Facilitates debugging only. */\r
-       unsigned portSHORT              usStackDepth;           /*< Total depth of the stack (when empty).  This is defined as the number of variables the stack can hold, not the number of bytes. */\r
+\r
+       #if ( portCRITICAL_NESTING_IN_TCB == 1 )\r
+               unsigned portBASE_TYPE uxCriticalNesting;\r
+       #endif\r
+\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
+       #if ( configUSE_MUTEXES == 1 )\r
+               unsigned portBASE_TYPE uxBasePriority;\r
+       #endif\r
+\r
+       #if ( configUSE_APPLICATION_TASK_TAG == 1 )\r
+               pdTASK_HOOK_CODE pxTaskTag;\r
+       #endif\r
+               \r
 } tskTCB;\r
 \r
 /*lint -e956 */\r
@@ -302,6 +157,8 @@ static volatile portBASE_TYPE xNumOfOverflows                                       = ( portBASE_TYPE ) 0;
 \r
 #endif\r
 \r
+/*-----------------------------------------------------------*/\r
+\r
 /*\r
  * Macro that writes a trace of scheduler activity to a buffer.  This trace\r
  * shows which task is running when and is very useful as a debugging tool.\r
@@ -339,7 +196,7 @@ static volatile portBASE_TYPE xNumOfOverflows                                       = ( portBASE_TYPE ) 0;
        #define vWriteTraceToBuffer()\r
 \r
 #endif\r
-\r
+/*-----------------------------------------------------------*/\r
 \r
 /*\r
  * Place the task represented by pxTCB into the appropriate ready queue for\r
@@ -355,7 +212,8 @@ static volatile portBASE_TYPE xNumOfOverflows                                       = ( portBASE_TYPE ) 0;
                uxTopReadyPriority = pxTCB->uxPriority;                                                                                                                                 \\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
@@ -381,9 +239,83 @@ register tskTCB *pxTCB;                                                                                                                                                                                            \
                {                                                                                                                                                                                                                       \\r
                        vListRemove( &( pxTCB->xEventListItem ) );                                                                                                                              \\r
                }                                                                                                                                                                                                                       \\r
-               prvAddTaskToReadyQueue( pxTCB );                                                                                                                \\r
+               prvAddTaskToReadyQueue( pxTCB );                                                                                                                                                        \\r
        }                                                                                                                                                                                                                               \\r
-}                                                                                                                                                                                      \r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Call the stack overflow hook function if the stack of the task being swapped\r
+ * out is currently overflowed, or looks like it might have overflowed in the\r
+ * past.\r
+ *\r
+ * Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check\r
+ * the current stack state only - comparing the current top of stack value to\r
+ * the stack limit.  Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1\r
+ * will also cause the last few stack bytes to be checked to ensure the value\r
+ * to which the bytes were set when the task was created have not been \r
+ * overwritten.  Note this second test does not guarantee that an overflowed\r
+ * stack will always be recognised.\r
+ */\r
+\r
+#if( configCHECK_FOR_STACK_OVERFLOW == 0 )\r
+\r
+       /* FreeRTOSConfig.h is not set to check for stack overflows. */\r
+       #define taskCHECK_FOR_STACK_OVERFLOW()\r
+\r
+#endif /* configCHECK_FOR_STACK_OVERFLOW == 0 */\r
+\r
+#if( ( configCHECK_FOR_STACK_OVERFLOW > 0 ) && ( portSTACK_GROWTH >= 0 ) )\r
+\r
+       /* This is an invalid setting. */\r
+       #error configCHECK_FOR_STACK_OVERFLOW can only be set to a non zero value on architectures where the stack grows down from high memory.\r
+\r
+#endif /* ( configCHECK_FOR_STACK_OVERFLOW > 0 ) && ( portSTACK_GROWTH >= 0 ) */\r
+\r
+#if( configCHECK_FOR_STACK_OVERFLOW == 1 )\r
+\r
+       /* Only the current stack state is to be checked. */\r
+       #define taskCHECK_FOR_STACK_OVERFLOW()                                                                                                                          \\r
+       {                                                                                                                                                                                                       \\r
+       extern void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed portCHAR *pcTaskName );          \\r
+                                                                                                                                                                                                               \\r
+               /* Is the currently saved stack pointer within the stack limit? */                                                              \\r
+               if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack )                                                                               \\r
+               {                                                                                                                                                                                               \\r
+                       vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName );        \\r
+               }                                                                                                                                                                                               \\r
+       }\r
+\r
+#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */\r
+\r
+#if( configCHECK_FOR_STACK_OVERFLOW > 1 )\r
+\r
+       /* Both the current statck state and the stack fill bytes are to be checked. */\r
+       #define taskCHECK_FOR_STACK_OVERFLOW()                                                                                                                                                                                                                  \\r
+       {                                                                                                                                                                                                                                                                                               \\r
+       extern void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed portCHAR *pcTaskName );                                                                                                  \\r
+       static const unsigned portCHAR ucExpectedStackBytes[] = {       tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE,         \\r
+                                                                                                                               tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE,         \\r
+                                                                                                                               tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE,         \\r
+                                                                                                                               tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE,         \\r
+                                                                                                                               tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE };       \\r
+                                                                                                                                                                                                                                                                                                       \\r
+               /* Is the currently saved stack pointer within the stack limit? */                                                                                                                                                      \\r
+               if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack )                                                                                                                                                                       \\r
+               {                                                                                                                                                                                                                                                                                       \\r
+                       vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName );                                                                                                \\r
+               }                                                                                                                                                                                                                                                                                       \\r
+                                                                                                                                                                                                                                                                                                       \\r
+               /* Has the extremity of the task stack ever been written over? */                                                                                                                                                       \\r
+               if( memcmp( ( void * ) pxCurrentTCB->pxStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 )                                          \\r
+               {                                                                                                                                                                                                                                                                                       \\r
+                       vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName );                                                                                                \\r
+               }                                                                                                                                                                                                                                                                                       \\r
+       }\r
+\r
+#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */\r
+\r
+/*-----------------------------------------------------------*/\r
 \r
 /*\r
  * Several functions take an xTaskHandle parameter that can optionally be NULL,\r
@@ -400,7 +332,7 @@ register tskTCB *pxTCB;                                                                                                                                                                                             \
  * Utility to ready a TCB for a given task.  Mainly just copies the parameters\r
  * into the TCB structure.\r
  */\r
-static void prvInitialiseTCBVariables( tskTCB *pxTCB, unsigned portSHORT usStackDepth, const signed portCHAR * const pcName, unsigned portBASE_TYPE uxPriority );\r
+static void prvInitialiseTCBVariables( tskTCB *pxTCB, const signed portCHAR * const pcName, unsigned portBASE_TYPE uxPriority );\r
 \r
 /*\r
  * Utility to ready all the lists used by the scheduler.  This is called\r
@@ -456,7 +388,7 @@ static tskTCB *prvAllocateTCBAndStack( unsigned portSHORT usStackDepth );
  */\r
 #if ( configUSE_TRACE_FACILITY == 1 )\r
 \r
-       static void prvListTaskWithinSingleList( signed portCHAR *pcWriteBuffer, xList *pxList, signed portCHAR cStatus );\r
+       static void prvListTaskWithinSingleList( const signed portCHAR *pcWriteBuffer, xList *pxList, signed portCHAR cStatus );\r
 \r
 #endif\r
 \r
@@ -465,15 +397,23 @@ static tskTCB *prvAllocateTCBAndStack( unsigned portSHORT usStackDepth );
  * This function determines the 'high water mark' of the task stack by\r
  * determining how much of the stack remains at the original preset value.\r
  */\r
-#if ( configUSE_TRACE_FACILITY == 1 )\r
+#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )\r
 \r
-       unsigned portSHORT usTaskCheckFreeStackSpace( const unsigned portCHAR *pucStackByte );\r
+       unsigned portSHORT usTaskCheckFreeStackSpace( const unsigned portCHAR * pucStackByte );\r
 \r
 #endif\r
 \r
-/*lint +e956 */\r
+/*\r
+ * Checks that a task being resumed (unsuspended) is actually in the Suspended\r
+ * state.\r
+ */\r
+#if ( INCLUDE_vTaskSuspend == 1 )\r
 \r
+       static portBASE_TYPE prvIsTaskSuspended( const tskTCB * const pxTCB );  \r
 \r
+#endif\r
+\r
+/*lint +e956 */\r
 \r
 \r
 \r
@@ -485,7 +425,9 @@ signed portBASE_TYPE xTaskCreate( pdTASK_CODE pvTaskCode, const signed portCHAR
 {\r
 signed portBASE_TYPE xReturn;\r
 tskTCB * pxNewTCB;\r
-static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberate - this is guarded before use. */\r
+#if ( configUSE_TRACE_FACILITY == 1 )\r
+       static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberate - this is guarded before use. */\r
+#endif\r
 \r
        /* Allocate the memory required by the TCB and stack for the new task.\r
        checking that the allocation was successful. */\r
@@ -496,7 +438,7 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
                portSTACK_TYPE *pxTopOfStack;\r
 \r
                /* Setup the newly allocated TCB with the initial state of the task. */\r
-               prvInitialiseTCBVariables( pxNewTCB, usStackDepth, pcName, uxPriority );\r
+               prvInitialiseTCBVariables( pxNewTCB, pcName, uxPriority );\r
 \r
                /* Calculate the top of stack address.  This depends on whether the\r
                stack grows from high memory to low (as per the 80x86) or visa versa.\r
@@ -504,7 +446,7 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
                required by the port. */\r
                #if portSTACK_GROWTH < 0\r
                {\r
-                       pxTopOfStack = pxNewTCB->pxStack + ( pxNewTCB->usStackDepth - 1 );\r
+                       pxTopOfStack = pxNewTCB->pxStack + ( usStackDepth - 1 );\r
                }\r
                #else\r
                {\r
@@ -554,19 +496,25 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
                                uxTopUsedPriority = pxNewTCB->uxPriority;\r
                        }\r
 \r
-                       /* Add a counter into the TCB for tracing only. */\r
-                       pxNewTCB->uxTCBNumber = uxTaskNumber;\r
-                       uxTaskNumber++;\r
+                       #if ( configUSE_TRACE_FACILITY == 1 )\r
+                       {\r
+                               /* Add a counter into the TCB for tracing only. */\r
+                               pxNewTCB->uxTCBNumber = uxTaskNumber;\r
+                               uxTaskNumber++;\r
+                       }\r
+                       #endif\r
 \r
                        prvAddTaskToReadyQueue( pxNewTCB );\r
 \r
                        xReturn = pdPASS;\r
+                       traceTASK_CREATE( pxNewTCB );\r
                }\r
                portEXIT_CRITICAL();\r
        }\r
        else\r
        {\r
                xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;\r
+               traceTASK_CREATE_FAILED( pxNewTCB );\r
        }\r
 \r
        if( xReturn == pdPASS )\r
@@ -602,7 +550,7 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
 \r
                taskENTER_CRITICAL();\r
                {\r
-                       /* Ensure a yield is performed if the current task is being \r
+                       /* Ensure a yield is performed if the current task is being\r
                        deleted. */\r
                        if( pxTaskToDelete == pxCurrentTCB )\r
                        {\r
@@ -612,6 +560,8 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
                        /* If null is passed in here then we are deleting ourselves. */\r
                        pxTCB = prvGetTCBFromHandle( pxTaskToDelete );\r
 \r
+                       traceTASK_DELETE( pxTCB );\r
+\r
                        /* Remove task from the ready list and place in the     termination list.\r
                        This will stop the task from be scheduled.  The idle task will check\r
                        the termination list and free up any memory allocated by the\r
@@ -634,7 +584,7 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
                taskEXIT_CRITICAL();\r
 \r
                /* Force a reschedule if we have just deleted the current task. */\r
-               if( xSchedulerRunning != pdFALSE ) \r
+               if( xSchedulerRunning != pdFALSE )\r
                {\r
                        if( ( void * ) pxTaskToDelete == NULL )\r
                        {\r
@@ -656,7 +606,7 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
 \r
 #if ( INCLUDE_vTaskDelayUntil == 1 )\r
 \r
-       void vTaskDelayUntil( portTickType *pxPreviousWakeTime, portTickType xTimeIncrement )\r
+       void vTaskDelayUntil( portTickType * const pxPreviousWakeTime, portTickType xTimeIncrement )\r
        {\r
        portTickType xTimeToWake;\r
        portBASE_TYPE xAlreadyYielded, xShouldDelay = pdFALSE;\r
@@ -694,6 +644,8 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
 \r
                        if( xShouldDelay )\r
                        {\r
+                               traceTASK_DELAY_UNTIL();\r
+\r
                                /* We must remove ourselves from the ready list before adding\r
                                ourselves to the blocked list as the same list item is used for\r
                                both lists. */\r
@@ -741,6 +693,8 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
                {\r
                        vTaskSuspendAll();\r
                        {\r
+                               traceTASK_DELAY();\r
+\r
                                /* A task that is removed from the event list while the\r
                                scheduler is suspended will not get placed in the ready\r
                                list or removed from the blocked list until the scheduler\r
@@ -825,16 +779,32 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
 \r
                taskENTER_CRITICAL();\r
                {\r
+                       if( pxTask == pxCurrentTCB )\r
+                       {\r
+                               pxTask = NULL;\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
-                       uxCurrentPriority = pxTCB->uxPriority;\r
+                       \r
+                       traceTASK_PRIORITY_SET( pxTask, uxNewPriority );\r
+\r
+                       #if ( configUSE_MUTEXES == 1 )\r
+                       {\r
+                               uxCurrentPriority = pxTCB->uxBasePriority;\r
+                       }\r
+                       #else\r
+                       {\r
+                               uxCurrentPriority = pxTCB->uxPriority;\r
+                       }\r
+                       #endif\r
 \r
                        if( uxCurrentPriority != uxNewPriority )\r
                        {\r
                                /* The priority change may have readied a task of higher\r
                                priority than the calling task. */\r
-                               if( uxNewPriority > pxCurrentTCB->uxPriority ) \r
+                               if( uxNewPriority > uxCurrentPriority )\r
                                {\r
                                        if( pxTask != NULL )\r
                                        {\r
@@ -852,8 +822,27 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
                                        xYieldRequired = pdTRUE;\r
                                }\r
                        \r
-                               pxTCB->uxPriority = uxNewPriority;\r
-                               listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) uxNewPriority );\r
+                               \r
+\r
+                               #if ( configUSE_MUTEXES == 1 )\r
+                               {\r
+                                       /* Only change the priority being used if the task is not\r
+                                       currently using an inherited priority. */\r
+                                       if( pxTCB->uxBasePriority == pxTCB->uxPriority )\r
+                                       {\r
+                                               pxTCB->uxPriority = uxNewPriority;\r
+                                       }\r
+                                       \r
+                                       /* The base priority gets set whatever. */\r
+                                       pxTCB->uxBasePriority = uxNewPriority;                                  \r
+                               }\r
+                               #else\r
+                               {\r
+                                       pxTCB->uxPriority = uxNewPriority;\r
+                               }\r
+                               #endif\r
+\r
+                               listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( configMAX_PRIORITIES - ( portTickType ) uxNewPriority ) );\r
 \r
                                /* If the task is in the blocked or suspended list we need do\r
                                nothing more than change it's priority variable. However, if\r
@@ -888,7 +877,7 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
 \r
                taskENTER_CRITICAL();\r
                {\r
-                       /* Ensure a yield is performed if the current task is being \r
+                       /* Ensure a yield is performed if the current task is being\r
                        suspended. */\r
                        if( pxTaskToSuspend == pxCurrentTCB )\r
                        {\r
@@ -898,6 +887,8 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
                        /* If null is passed in here then we are suspending ourselves. */\r
                        pxTCB = prvGetTCBFromHandle( pxTaskToSuspend );\r
 \r
+                       traceTASK_SUSPEND( pxTaskToSuspend );\r
+\r
                        /* Remove task from the ready/delayed list and place in the     suspended list. */\r
                        vListRemove( &( pxTCB->xGenericListItem ) );\r
 \r
@@ -921,6 +912,36 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
 #endif\r
 /*-----------------------------------------------------------*/\r
 \r
+#if ( INCLUDE_vTaskSuspend == 1 )\r
+\r
+       static portBASE_TYPE prvIsTaskSuspended( const tskTCB * const pxTCB )\r
+       {\r
+       portBASE_TYPE xReturn = pdFALSE;\r
+\r
+               /* Is the task we are attempting to resume actually in the\r
+               suspended list? */\r
+               if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ) != pdFALSE )\r
+               {\r
+                       /* Has the task already been resumed from within an ISR? */\r
+                       if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) != pdTRUE )\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
+                               specified. */\r
+                               if( listIS_CONTAINED_WITHIN( NULL, &( pxTCB->xEventListItem ) ) == pdTRUE )\r
+                               {\r
+                                       xReturn = pdTRUE;\r
+                               }\r
+                       }\r
+               }\r
+\r
+               return xReturn;\r
+       }\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
 #if ( INCLUDE_vTaskSuspend == 1 )\r
 \r
        void vTaskResume( xTaskHandle pxTaskToResume )\r
@@ -933,28 +954,25 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
 \r
                /* The parameter cannot be NULL as it is impossible to resume the\r
                currently executing task. */\r
-               if( pxTCB != NULL )\r
+               if( ( pxTCB != NULL ) && ( pxTCB != pxCurrentTCB ) )\r
                {\r
                        taskENTER_CRITICAL();\r
                        {\r
-                               /* Is the task we are attempting to resume actually suspended? */\r
-                               if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ) != pdFALSE )\r
+                               if( prvIsTaskSuspended( pxTCB ) == pdTRUE )\r
                                {\r
-                                       /* Has the task already been resumed from within an ISR? */\r
-                                       if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) != pdTRUE )\r
-                                       {                       \r
-                                               /* As we are in a critical section we can access the ready \r
-                                               lists even if the scheduler is suspended. */\r
-                                               vListRemove(  &( pxTCB->xGenericListItem ) );\r
-                                               prvAddTaskToReadyQueue( pxTCB );\r
-\r
-                                               /* We may have just resumed a higher priority task. */\r
-                                               if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )\r
-                                               {\r
-                                                       /* This yield may not cause the task just resumed to run, but\r
-                                                       will leave the lists in the correct state for the next yield. */\r
-                                                       taskYIELD();\r
-                                               }\r
+                                       traceTASK_RESUME( pxTCB );\r
+\r
+                                       /* As we are in a critical section we can access the ready\r
+                                       lists even if the scheduler is suspended. */\r
+                                       vListRemove(  &( pxTCB->xGenericListItem ) );\r
+                                       prvAddTaskToReadyQueue( pxTCB );\r
+\r
+                                       /* We may have just resumed a higher priority task. */\r
+                                       if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )\r
+                                       {\r
+                                               /* This yield may not cause the task just resumed to run, but\r
+                                               will leave the lists in the correct state for the next yield. */\r
+                                               taskYIELD();\r
                                        }\r
                                }\r
                        }\r
@@ -975,25 +993,22 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
 \r
                pxTCB = ( tskTCB * ) pxTaskToResume;\r
 \r
-               /* Is the task we are attempting to resume actually suspended? */\r
-               if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ) != pdFALSE )\r
+               if( prvIsTaskSuspended( pxTCB ) == pdTRUE )\r
                {\r
-                       /* Has the task already been resumed from within an ISR? */\r
-                       if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) != pdTRUE )\r
+                       traceTASK_RESUME_FROM_ISR( pxTCB );\r
+\r
+                       if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )\r
                        {\r
-                               if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )\r
-                               {\r
-                                       xYieldRequired = ( pxTCB->uxPriority >= pxCurrentTCB->uxPriority );\r
-                                       vListRemove(  &( pxTCB->xGenericListItem ) );   \r
-                                       prvAddTaskToReadyQueue( pxTCB );\r
-                               }\r
-                               else\r
-                               {\r
-                                       /* We cannot access the delayed or ready lists, so will hold this\r
-                                       task pending until the scheduler is resumed, at which point a \r
-                                       yield will be preformed if necessary. */\r
-                                       vListInsertEnd( ( xList * ) &( xPendingReadyList ), &( pxTCB->xEventListItem ) );\r
-                               }\r
+                               xYieldRequired = ( pxTCB->uxPriority >= pxCurrentTCB->uxPriority );\r
+                               vListRemove(  &( pxTCB->xGenericListItem ) );   \r
+                               prvAddTaskToReadyQueue( pxTCB );\r
+                       }\r
+                       else\r
+                       {\r
+                               /* We cannot access the delayed or ready lists, so will hold this\r
+                               task pending until the scheduler is resumed, at which point a\r
+                               yield will be performed if necessary. */\r
+                               vListInsertEnd( ( xList * ) &( xPendingReadyList ), &( pxTCB->xEventListItem ) );\r
                        }\r
                }\r
 \r
@@ -1116,7 +1131,11 @@ signed portBASE_TYPE xAlreadyYielded = pdFALSE;
                                        /* As we have processed some ticks it is appropriate to yield\r
                                        to ensure the highest priority task that is ready to run is\r
                                        the task actually running. */\r
-                                       xYieldRequired = pdTRUE;\r
+                                       #if configUSE_PREEMPTION == 1\r
+                                       {\r
+                                               xYieldRequired = pdTRUE;\r
+                                       }\r
+                                       #endif\r
                                }\r
                                \r
                                if( ( xYieldRequired == pdTRUE ) || ( xMissedYield == pdTRUE ) )\r
@@ -1232,7 +1251,7 @@ unsigned portBASE_TYPE uxNumberOfTasks;
        {\r
                portENTER_CRITICAL();\r
                {\r
-                       pcTraceBuffer = ( volatile signed portCHAR * volatile )pcBuffer;\r
+                       pcTraceBuffer = ( signed portCHAR * )pcBuffer;\r
                        pcTraceBufferStart = pcBuffer;\r
                        pcTraceBufferEnd = pcBuffer + ( ulBufferSize - tskSIZE_OF_EACH_TRACE_LINE );\r
                        xTracing = pdTRUE;\r
@@ -1268,7 +1287,7 @@ unsigned portBASE_TYPE uxNumberOfTasks;
  *----------------------------------------------------------*/\r
 \r
 \r
-inline void vTaskIncrementTick( void )\r
+void vTaskIncrementTick( void )\r
 {\r
        /* Called by the portable layer each time a tick interrupt occurs.\r
        Increments the tick then checks to see if the new tick value will cause any\r
@@ -1280,8 +1299,8 @@ inline void vTaskIncrementTick( void )
                {\r
                        xList *pxTemp;\r
 \r
-                       /* Tick count has overflowed so we need to swap the delay lists.  \r
-                       If there are any items in pxDelayedTaskList here then there is \r
+                       /* Tick count has overflowed so we need to swap the delay lists.\r
+                       If there are any items in pxDelayedTaskList here then there is\r
                        an error! */\r
                        pxTemp = pxDelayedTaskList;\r
                        pxDelayedTaskList = pxOverflowDelayedTaskList;\r
@@ -1296,7 +1315,7 @@ inline void vTaskIncrementTick( void )
        {\r
                ++uxMissedTicks;\r
 \r
-               /* The tick hook gets called at regular intervals, even if the \r
+               /* The tick hook gets called at regular intervals, even if the\r
                scheduler is locked. */\r
                #if ( configUSE_TICK_HOOK == 1 )\r
                {\r
@@ -1319,6 +1338,8 @@ inline void vTaskIncrementTick( void )
                }\r
        }\r
        #endif\r
+\r
+       traceTASK_INCREMENT_TICK( xTickCount );\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
@@ -1370,21 +1391,72 @@ inline void vTaskIncrementTick( void )
 \r
                        prvDeleteTCB( ( tskTCB * ) pxTCB );\r
                }               \r
+       }\r
 \r
-               while( !listLIST_IS_EMPTY( &xPendingReadyList ) )\r
-               {\r
-                       listGET_OWNER_OF_NEXT_ENTRY( pxTCB, &xPendingReadyList );\r
-                       vListRemove( ( xListItem * ) &( pxTCB->xGenericListItem ) );\r
+#endif\r
+/*-----------------------------------------------------------*/\r
 \r
-                       prvDeleteTCB( ( tskTCB * ) pxTCB );\r
-               }               \r
+#if ( configUSE_APPLICATION_TASK_TAG == 1 )\r
+\r
+       void vTaskSetApplicationTaskTag( xTaskHandle xTask, pdTASK_HOOK_CODE pxTagValue )\r
+       {\r
+       tskTCB *xTCB;\r
+\r
+               /* If xTask is NULL then we are setting our own task hook. */\r
+               if( xTask == NULL )\r
+               {\r
+                       xTCB = ( tskTCB * ) pxCurrentTCB;\r
+               }\r
+               else\r
+               {\r
+                       xTCB = ( tskTCB * ) xTask;\r
+               }\r
+               \r
+               /* Save the hook function in the TCB. */\r
+               portENTER_CRITICAL();\r
+                       xTCB->pxTaskTag = pxTagValue;\r
+               portEXIT_CRITICAL();\r
        }\r
+       \r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( configUSE_APPLICATION_TASK_TAG == 1 )\r
+\r
+       portBASE_TYPE xTaskCallApplicationTaskHook( xTaskHandle xTask, void *pvParameter )\r
+       {\r
+       tskTCB *xTCB;\r
+       portBASE_TYPE xReturn;\r
+\r
+               /* If xTask is NULL then we are calling our own task hook. */\r
+               if( xTask == NULL )\r
+               {\r
+                       xTCB = ( tskTCB * ) pxCurrentTCB;\r
+               }\r
+               else\r
+               {\r
+                       xTCB = ( tskTCB * ) xTask;\r
+               }\r
 \r
+               if( xTCB->pxTaskTag != NULL )\r
+               {\r
+                       xReturn = xTCB->pxTaskTag( pvParameter );\r
+               }\r
+               else\r
+               {\r
+                       xReturn = pdFAIL;\r
+               }\r
+\r
+               return xReturn;\r
+       }\r
+       \r
 #endif\r
 /*-----------------------------------------------------------*/\r
 \r
 void vTaskSwitchContext( void )\r
 {\r
+       traceTASK_SWITCHED_OUT();\r
+\r
        if( uxSchedulerSuspended != ( unsigned portBASE_TYPE ) pdFALSE )\r
        {\r
                /* The scheduler is currently suspended - do not allow a context\r
@@ -1393,6 +1465,8 @@ void vTaskSwitchContext( void )
                return;\r
        }\r
 \r
+       taskCHECK_FOR_STACK_OVERFLOW();\r
+\r
        /* Find the highest priority queue that contains ready tasks. */\r
        while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopReadyPriority ] ) ) )\r
        {\r
@@ -1402,11 +1476,13 @@ void vTaskSwitchContext( void )
        /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the tasks of the\r
        same priority get an equal share of the processor time. */\r
        listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopReadyPriority ] ) );\r
+\r
+       traceTASK_SWITCHED_IN();\r
        vWriteTraceToBuffer();\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-void vTaskPlaceOnEventList( xList *pxEventList, portTickType xTicksToWait )\r
+void vTaskPlaceOnEventList( const xList * const pxEventList, portTickType xTicksToWait )\r
 {\r
 portTickType xTimeToWake;\r
 \r
@@ -1418,31 +1494,65 @@ portTickType xTimeToWake;
        is the first to be woken by the event. */\r
        vListInsert( ( xList * ) pxEventList, ( xListItem * ) &( pxCurrentTCB->xEventListItem ) );\r
 \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
        /* We must remove ourselves from the ready list before adding ourselves\r
        to the blocked list as the same list item is used for both lists.  We have\r
        exclusive access to the ready lists as the scheduler is locked. */\r
        vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
 \r
-       listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake );\r
 \r
-       if( xTimeToWake < xTickCount )\r
-       {\r
-               /* Wake time has overflowed.  Place this item in the overflow list. */\r
-               vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
+       #if ( INCLUDE_vTaskSuspend == 1 )\r
+       {                       \r
+               if( xTicksToWait == portMAX_DELAY )\r
+               {\r
+                       /* Add ourselves to the suspended task list instead of a delayed task\r
+                       list to ensure we are not woken by a timing event.  We will block\r
+                       indefinitely. */\r
+                       vListInsertEnd( ( xList * ) &xSuspendedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
+               }\r
+               else\r
+               {\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
+                       listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake );\r
+               \r
+                       if( xTimeToWake < xTickCount )\r
+                       {\r
+                               /* Wake time has overflowed.  Place this item in the overflow list. */\r
+                               vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
+                       }\r
+                       else\r
+                       {\r
+                               /* The wake time has not overflowed, so we can use the current block list. */\r
+                               vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
+                       }\r
+               }\r
        }\r
-       else\r
+       #else\r
        {\r
-               /* The wake time has not overflowed, so we can use the current block list. */\r
-               vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\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
+                       listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake );\r
+               \r
+                       if( xTimeToWake < xTickCount )\r
+                       {\r
+                               /* Wake time has overflowed.  Place this item in the overflow list. */\r
+                               vListInsert( ( xList * ) pxOverflowDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
+                       }\r
+                       else\r
+                       {\r
+                               /* The wake time has not overflowed, so we can use the current block list. */\r
+                               vListInsert( ( xList * ) pxDelayedTaskList, ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
+                       }\r
        }\r
+       #endif\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-signed portBASE_TYPE xTaskRemoveFromEventList( const xList *pxEventList )\r
+signed portBASE_TYPE xTaskRemoveFromEventList( const xList * const pxEventList )\r
 {\r
 tskTCB *pxUnblockedTCB;\r
 portBASE_TYPE xReturn;\r
@@ -1489,36 +1599,51 @@ portBASE_TYPE xReturn;
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-void vTaskSetTimeOutState( xTimeOutType *pxTimeOut )\r
+void vTaskSetTimeOutState( xTimeOutType * const pxTimeOut )\r
 {\r
     pxTimeOut->xOverflowCount = xNumOfOverflows;\r
     pxTimeOut->xTimeOnEntering = xTickCount;\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType *pxTimeOut, portTickType *pxTicksToWait )\r
+portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType * const pxTimeOut, portTickType * const pxTicksToWait )\r
 {\r
 portBASE_TYPE xReturn;\r
 \r
-    if( ( xNumOfOverflows != pxTimeOut->xOverflowCount ) && ( xTickCount > pxTimeOut->xTimeOnEntering ) )\r
-    {\r
-        /* The tick count is greater than the time at which vTaskSetTimeout() \r
-               was called, but has also overflowed since vTaskSetTimeOut() was called.\r
-        It must have wrapped all the way around and gone past us again. This\r
-        passed since vTaskSetTimeout() was called. */\r
-        xReturn = pdTRUE;\r
-    }\r
-    else if( ( xTickCount - pxTimeOut->xTimeOnEntering ) < *pxTicksToWait )\r
-    {\r
-        /* Not a genuine timeout. Adjust parameters for time remaining. */\r
-        *pxTicksToWait -= ( xTickCount - pxTimeOut->xTimeOnEntering );\r
-        vTaskSetTimeOutState( pxTimeOut );\r
-        xReturn = pdFALSE;\r
-    }\r
-    else\r
-    {\r
-        xReturn = pdTRUE;\r
-    }\r
+       portENTER_CRITICAL();\r
+       {\r
+               #if ( INCLUDE_vTaskSuspend == 1 )\r
+                       /* If INCLUDE_vTaskSuspend is set to 1 and the block time specified is\r
+                       the maximum block time then the task should block indefinitely, and\r
+                       therefore never time out. */\r
+                       if( *pxTicksToWait == portMAX_DELAY )\r
+                       {\r
+                               xReturn = pdFALSE;\r
+                       }\r
+                       else /* We are not blocking indefinitely, perform the checks below. */\r
+               #endif\r
+\r
+               if( ( xNumOfOverflows != pxTimeOut->xOverflowCount ) && ( xTickCount >= pxTimeOut->xTimeOnEntering ) )\r
+               {\r
+                       /* The tick count is greater than the time at which vTaskSetTimeout()\r
+                       was called, but has also overflowed since vTaskSetTimeOut() was called.\r
+                       It must have wrapped all the way around and gone past us again. This\r
+                       passed since vTaskSetTimeout() was called. */\r
+                       xReturn = pdTRUE;\r
+               }\r
+               else if( ( xTickCount - pxTimeOut->xTimeOnEntering ) < *pxTicksToWait )\r
+               {\r
+                       /* Not a genuine timeout. Adjust parameters for time remaining. */\r
+                       *pxTicksToWait -= ( xTickCount - pxTimeOut->xTimeOnEntering );\r
+                       vTaskSetTimeOutState( pxTimeOut );\r
+                       xReturn = pdFALSE;\r
+               }\r
+               else\r
+               {\r
+                       xReturn = pdTRUE;\r
+               }\r
+       }\r
+       portEXIT_CRITICAL();\r
 \r
     return xReturn;\r
 }\r
@@ -1605,10 +1730,8 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters )
 \r
 \r
 \r
-static void prvInitialiseTCBVariables( tskTCB *pxTCB, unsigned portSHORT usStackDepth, const signed portCHAR * const pcName, unsigned portBASE_TYPE uxPriority )\r
+static void prvInitialiseTCBVariables( tskTCB *pxTCB, const signed portCHAR * const pcName, unsigned portBASE_TYPE uxPriority )\r
 {\r
-       pxTCB->usStackDepth = usStackDepth;\r
-\r
        /* Store the function name in the TCB. */\r
        strncpy( ( char * ) pxTCB->pcTaskName, ( const char * ) pcName, ( unsigned portSHORT ) configMAX_TASK_NAME_LEN );\r
        pxTCB->pcTaskName[ ( unsigned portSHORT ) configMAX_TASK_NAME_LEN - ( unsigned portSHORT ) 1 ] = '\0';\r
@@ -1620,6 +1743,11 @@ static void prvInitialiseTCBVariables( tskTCB *pxTCB, unsigned portSHORT usStack
        }\r
 \r
        pxTCB->uxPriority = uxPriority;\r
+       #if ( configUSE_MUTEXES == 1 )\r
+       {\r
+               pxTCB->uxBasePriority = uxPriority;\r
+       }\r
+       #endif\r
 \r
        vListInitialiseItem( &( pxTCB->xGenericListItem ) );\r
        vListInitialiseItem( &( pxTCB->xEventListItem ) );\r
@@ -1631,6 +1759,18 @@ static void prvInitialiseTCBVariables( tskTCB *pxTCB, unsigned portSHORT usStack
        /* Event lists are always in priority order. */\r
        listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) uxPriority );\r
        listSET_LIST_ITEM_OWNER( &( pxTCB->xEventListItem ), pxTCB );\r
+\r
+       #if ( portCRITICAL_NESTING_IN_TCB == 1 )\r
+       {\r
+               pxTCB->uxCriticalNesting = ( unsigned portBASE_TYPE ) 0;\r
+       }\r
+       #endif\r
+\r
+       #if ( configUSE_APPLICATION_TASK_TAG == 1 )\r
+       {\r
+               pxTCB->pxTaskTag = NULL;\r
+       }\r
+       #endif  \r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
@@ -1735,7 +1875,7 @@ tskTCB *pxNewTCB;
 \r
 #if ( configUSE_TRACE_FACILITY == 1 )\r
 \r
-       static void prvListTaskWithinSingleList( signed portCHAR *pcWriteBuffer, xList *pxList, signed portCHAR cStatus )\r
+       static void prvListTaskWithinSingleList( const signed portCHAR *pcWriteBuffer, xList *pxList, signed portCHAR cStatus )\r
        {\r
        volatile tskTCB *pxNextTCB, *pxFirstTCB;\r
        static portCHAR pcStatusString[ 50 ];\r
@@ -1756,8 +1896,9 @@ tskTCB *pxNewTCB;
 #endif\r
 /*-----------------------------------------------------------*/\r
 \r
-#if ( configUSE_TRACE_FACILITY == 1 )\r
-       unsigned portSHORT usTaskCheckFreeStackSpace( const unsigned portCHAR *pucStackByte )\r
+#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )\r
+\r
+       unsigned portSHORT usTaskCheckFreeStackSpace( const unsigned portCHAR * pucStackByte )\r
        {\r
        register unsigned portSHORT usCount = 0;\r
 \r
@@ -1771,10 +1912,22 @@ tskTCB *pxNewTCB;
 \r
                return usCount;\r
        }\r
+\r
 #endif\r
 /*-----------------------------------------------------------*/\r
 \r
+#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 )\r
+\r
+       unsigned portBASE_TYPE uxTaskGetStackHighWaterMark( xTaskHandle xTask )\r
+       {\r
+       tskTCB *pxTCB;\r
 \r
+               pxTCB = prvGetTCBFromHandle( xTask );\r
+               return usTaskCheckFreeStackSpace( ( unsigned portCHAR * ) pxTCB->pxStack );\r
+       }\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
 \r
 #if ( ( INCLUDE_vTaskDelete == 1 ) || ( INCLUDE_vTaskCleanUpResources == 1 ) )\r
 \r
@@ -1808,7 +1961,130 @@ tskTCB *pxNewTCB;
 \r
 #endif\r
 \r
+/*-----------------------------------------------------------*/\r
 \r
+#if ( INCLUDE_xTaskGetSchedulerState == 1 )\r
 \r
+       portBASE_TYPE xTaskGetSchedulerState( void )\r
+       {\r
+       portBASE_TYPE xReturn;\r
+       \r
+               if( xSchedulerRunning == pdFALSE )\r
+               {\r
+                       xReturn = taskSCHEDULER_NOT_STARTED;\r
+               }\r
+               else\r
+               {\r
+                       if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )\r
+                       {\r
+                               xReturn = taskSCHEDULER_RUNNING;\r
+                       }\r
+                       else\r
+                       {\r
+                               xReturn = taskSCHEDULER_SUSPENDED;\r
+                       }\r
+               }\r
+               \r
+               return xReturn;\r
+       }\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( configUSE_MUTEXES == 1 )\r
+       \r
+       void vTaskPriorityInherit( xTaskHandle * const pxMutexHolder )\r
+       {\r
+       tskTCB * const pxTCB = ( tskTCB * ) pxMutexHolder;\r
+\r
+               if( pxTCB->uxPriority < pxCurrentTCB->uxPriority )\r
+               {\r
+                       /* Adjust the mutex holder state to account for its new priority. */\r
+                       listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) pxCurrentTCB->uxPriority );\r
 \r
+                       /* If the task being modified is in the ready state it will need to\r
+                       be moved in to a new list. */\r
+                       if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ pxTCB->uxPriority ] ), &( pxTCB->xGenericListItem ) ) )\r
+                       {\r
+                               vListRemove( &( pxTCB->xGenericListItem ) );\r
+\r
+                               /* Inherit the priority before being moved into the new list. */\r
+                               pxTCB->uxPriority = pxCurrentTCB->uxPriority;\r
+                               prvAddTaskToReadyQueue( pxTCB );\r
+                       }\r
+                       else\r
+                       {\r
+                               /* Just inherit the priority. */\r
+                               pxTCB->uxPriority = pxCurrentTCB->uxPriority;\r
+                       }\r
+               }\r
+       }\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( configUSE_MUTEXES == 1 ) \r
+\r
+       void vTaskPriorityDisinherit( xTaskHandle * const pxMutexHolder )\r
+       {\r
+       tskTCB * const pxTCB = ( tskTCB * ) pxMutexHolder;\r
+\r
+               if( pxMutexHolder != NULL )\r
+               {\r
+                       if( pxTCB->uxPriority != pxTCB->uxBasePriority )\r
+                       {\r
+                               /* We must be the running task to be able to give the mutex back.\r
+                               Remove ourselves from the ready list we currently appear in. */\r
+                               vListRemove( &( pxTCB->xGenericListItem ) );\r
+\r
+                               /* Disinherit the priority before adding ourselves into the new\r
+                               ready list. */\r
+                               pxTCB->uxPriority = pxTCB->uxBasePriority;\r
+                               listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) pxTCB->uxPriority );\r
+                               prvAddTaskToReadyQueue( pxTCB );\r
+                       }\r
+               }\r
+       }\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( portCRITICAL_NESTING_IN_TCB == 1 )\r
+\r
+       void vTaskEnterCritical( void )\r
+       {\r
+               portDISABLE_INTERRUPTS();\r
+\r
+               if( xSchedulerRunning != pdFALSE )\r
+               {\r
+                       pxCurrentTCB->uxCriticalNesting++;\r
+               }\r
+       }\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( portCRITICAL_NESTING_IN_TCB == 1 )\r
+\r
+void vTaskExitCritical( void )\r
+{\r
+       if( xSchedulerRunning != pdFALSE )\r
+       {\r
+               if( pxCurrentTCB->uxCriticalNesting > 0 )\r
+               {\r
+                       pxCurrentTCB->uxCriticalNesting--;\r
+\r
+                       if( pxCurrentTCB->uxCriticalNesting == 0 )\r
+                       {\r
+                               portENABLE_INTERRUPTS();\r
+                       }\r
+               }\r
+       }\r
+}\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+\r
+       \r
 \r