]> 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 a605b99f2a380651a0a2c766ca17a2a39bd5f7a5..ade94f971c015798db82c2183e0f9d25e553f756 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.7.0 - Copyright (C) 2003-2007 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
+    * 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
-       Also see http://www.SafeRTOS.com a version that has been certified for use\r
-       in safety critical systems, plus commercial licensing, development and\r
-       support options.\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
-       + Added API function vTaskDelayUntil().\r
-       + Added INCLUDE_vTaskDelay conditional compilation.\r
-\r
-Changes from V2.6.0\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
-\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
+       Please ensure to read the configuration and relevant port sections of the\r
+       online documentation.\r
 \r
-Changes from V3.1.1\r
+       http://www.FreeRTOS.org - Documentation, latest information, license and \r
+       contact details.\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
+       http://www.SafeRTOS.com - A version that is certified for use in safety \r
+       critical systems.\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
-\r
-Changes from V4.1.2\r
-       \r
-       + Tasks that block on events with a timeout of portMAX_DELAY are now\r
-         blocked indefinitely if configINCLUDE_vTaskSuspend is defined. \r
-         Previously portMAX_DELAY was just the longest block time possible.\r
-\r
-Changes from V4.1.3\r
-\r
-       + Very small change made to xTaskCheckForTimeout() as a result of the \r
-       SafeRTOS testing.  This corrects the case where the function can return an\r
-       invalid value - but only in an extremely unlikely scenario.\r
-\r
-Changes since V4.3.1:\r
-\r
-       + Added xTaskGetSchedulerState() function.\r
-       + Added prvIsTaskSuspended() to take into account the Occurrence of\r
-         vTaskResume() or vTaskResumeFromISR() being called passing in the\r
-         handle of a task that appears in the Suspended list only because it\r
-         is blocked on an event without a timeout being specified.\r
-       + Updated xTaskCheckForTimeout() to take into account that tasks blocked\r
-         using the Suspended list should never time out.\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
@@ -222,31 +61,6 @@ Changes since V4.3.1:
 #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 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
-#ifndef INCLUDE_xTaskGetSchedulerState\r
-       #define INCLUDE_xTaskGetSchedulerState 0\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
@@ -260,6 +74,10 @@ typedef struct tskTaskControlBlock
        portSTACK_TYPE                  *pxStack;                       /*< Points to the start of the stack. */\r
        signed portCHAR                 pcTaskName[ configMAX_TASK_NAME_LEN ];/*< Descriptive name given to the task when created.  Facilitates debugging only. */\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
@@ -267,6 +85,10 @@ typedef struct tskTaskControlBlock
        #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
@@ -335,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
@@ -372,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
@@ -388,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
@@ -414,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
@@ -498,7 +397,7 @@ 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
 \r
@@ -518,8 +417,6 @@ static tskTCB *prvAllocateTCBAndStack( unsigned portSHORT usStackDepth );
 \r
 \r
 \r
-\r
-\r
 /*-----------------------------------------------------------\r
  * TASK CREATION API documented in task.h\r
  *----------------------------------------------------------*/\r
@@ -610,12 +507,14 @@ tskTCB * pxNewTCB;
                        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
@@ -651,7 +550,7 @@ tskTCB * pxNewTCB;
 \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
@@ -661,6 +560,8 @@ tskTCB * pxNewTCB;
                        /* 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
@@ -683,7 +584,7 @@ tskTCB * pxNewTCB;
                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
@@ -743,6 +644,8 @@ tskTCB * pxNewTCB;
 \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
@@ -790,6 +693,8 @@ tskTCB * pxNewTCB;
                {\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
@@ -874,10 +779,17 @@ tskTCB * pxNewTCB;
 \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
                        \r
+                       traceTASK_PRIORITY_SET( pxTask, uxNewPriority );\r
+\r
                        #if ( configUSE_MUTEXES == 1 )\r
                        {\r
                                uxCurrentPriority = pxTCB->uxBasePriority;\r
@@ -892,7 +804,7 @@ tskTCB * pxNewTCB;
                        {\r
                                /* The priority change may have readied a task of higher\r
                                priority than the calling task. */\r
-                               if( uxNewPriority > uxCurrentPriority ) \r
+                               if( uxNewPriority > uxCurrentPriority )\r
                                {\r
                                        if( pxTask != NULL )\r
                                        {\r
@@ -965,7 +877,7 @@ tskTCB * pxNewTCB;
 \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
@@ -975,6 +887,8 @@ tskTCB * pxNewTCB;
                        /* 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
@@ -1040,12 +954,14 @@ tskTCB * pxNewTCB;
 \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
                                if( prvIsTaskSuspended( pxTCB ) == pdTRUE )\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
@@ -1079,6 +995,8 @@ tskTCB * pxNewTCB;
 \r
                if( prvIsTaskSuspended( pxTCB ) == pdTRUE )\r
                {\r
+                       traceTASK_RESUME_FROM_ISR( pxTCB );\r
+\r
                        if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )\r
                        {\r
                                xYieldRequired = ( pxTCB->uxPriority >= pxCurrentTCB->uxPriority );\r
@@ -1213,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
@@ -1329,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
@@ -1365,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
@@ -1377,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
@@ -1393,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
@@ -1416,6 +1338,8 @@ inline void vTaskIncrementTick( void )
                }\r
        }\r
        #endif\r
+\r
+       traceTASK_INCREMENT_TICK( xTickCount );\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
@@ -1472,8 +1396,67 @@ inline void vTaskIncrementTick( void )
 #endif\r
 /*-----------------------------------------------------------*/\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
@@ -1482,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
@@ -1491,6 +1476,8 @@ 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
@@ -1514,7 +1501,7 @@ portTickType xTimeToWake;
 \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
@@ -1623,36 +1610,40 @@ portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType * const pxTimeOut, portTickType
 {\r
 portBASE_TYPE xReturn;\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
+       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 /* 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
+               else\r
+               {\r
+                       xReturn = pdTRUE;\r
+               }\r
+       }\r
+       portEXIT_CRITICAL();\r
 \r
     return xReturn;\r
 }\r
@@ -1768,6 +1759,18 @@ static void prvInitialiseTCBVariables( tskTCB *pxTCB, const signed portCHAR * co
        /* 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
@@ -1893,7 +1896,8 @@ tskTCB *pxNewTCB;
 #endif\r
 /*-----------------------------------------------------------*/\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
        {\r
        register unsigned portSHORT usCount = 0;\r
@@ -1908,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
@@ -1973,6 +1989,7 @@ tskTCB *pxNewTCB;
        }\r
 \r
 #endif\r
+/*-----------------------------------------------------------*/\r
 \r
 #if ( configUSE_MUTEXES == 1 )\r
        \r
@@ -1985,7 +2002,7 @@ tskTCB *pxNewTCB;
                        /* 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 read state it will need to\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
@@ -2004,6 +2021,7 @@ tskTCB *pxNewTCB;
        }\r
 \r
 #endif\r
+/*-----------------------------------------------------------*/\r
 \r
 #if ( configUSE_MUTEXES == 1 ) \r
 \r
@@ -2029,8 +2047,44 @@ tskTCB *pxNewTCB;
        }\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
 \r