]> git.sur5r.net Git - freertos/blobdiff - Source/tasks.c
Remove casts that were generating warnings (even though the casts were added to remov...
[freertos] / Source / tasks.c
index 3b699035543e16e8927423c4e175ae82fb53a81b..5eaebe2abadc038d8a46c9c5bd30bdaa05975660 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-       FreeRTOS.org V4.1.2 - Copyright (C) 2003-2006 Richard Barry.\r
+       FreeRTOS.org V4.7.1 - Copyright (C) 2003-2008 Richard Barry.\r
 \r
        This file is part of the FreeRTOS.org distribution.\r
 \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
+       Please ensure to read the configuration and relevant port sections of the \r
+       online documentation.\r
+\r
+       +++ http://www.FreeRTOS.org +++\r
+       Documentation, latest information, license and contact details.  \r
+\r
+       +++ http://www.SafeRTOS.com +++\r
+       A version that is certified for use in safety critical systems.\r
+\r
+       +++ http://www.OpenRTOS.com +++\r
+       Commercial support, development, porting, licensing and training services.\r
+\r
        ***************************************************************************\r
 */\r
 \r
@@ -184,9 +194,25 @@ Changes from V4.0.5
 \r
 Changes from V4.1.2\r
        \r
-       + Tasks that block with a timeout of portMAX_DELAY are now blocked \r
-         indefinitely.  Previously portMAX_DELAY was just the longest block time\r
-         possible.\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
 */\r
 \r
 #include <stdio.h>\r
@@ -210,10 +236,6 @@ Changes from V4.1.2
        #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
@@ -225,7 +247,11 @@ Changes from V4.1.2
 \r
 #ifndef INCLUDE_xTaskResumeFromISR\r
        #define INCLUDE_xTaskResumeFromISR 1\r
-#endif \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
@@ -238,9 +264,16 @@ 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 ( 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
 } tskTCB;\r
 \r
 /*lint -e956 */\r
@@ -406,7 +439,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
@@ -462,7 +495,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
@@ -473,7 +506,17 @@ static tskTCB *prvAllocateTCBAndStack( unsigned portSHORT usStackDepth );
  */\r
 #if ( configUSE_TRACE_FACILITY == 1 )\r
 \r
-       unsigned portSHORT usTaskCheckFreeStackSpace( const unsigned portCHAR *pucStackByte );\r
+       unsigned portSHORT usTaskCheckFreeStackSpace( const unsigned portCHAR * pucStackByte );\r
+\r
+#endif\r
+\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
@@ -491,7 +534,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
@@ -502,7 +547,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
@@ -510,7 +555,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
@@ -560,9 +605,13 @@ 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
@@ -662,7 +711,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
@@ -834,13 +883,22 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
                        /* 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
+                       #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
@@ -858,8 +916,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
@@ -927,6 +1004,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
@@ -943,24 +1050,19 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
                {\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
+                                       /* 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
@@ -981,25 +1083,20 @@ 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
+                       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
@@ -1122,7 +1219,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
@@ -1238,7 +1339,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
@@ -1376,14 +1477,6 @@ inline void vTaskIncrementTick( void )
 \r
                        prvDeleteTCB( ( tskTCB * ) pxTCB );\r
                }               \r
-\r
-               while( !listLIST_IS_EMPTY( &xPendingReadyList ) )\r
-               {\r
-                       listGET_OWNER_OF_NEXT_ENTRY( pxTCB, &xPendingReadyList );\r
-                       vListRemove( ( xListItem * ) &( pxTCB->xGenericListItem ) );\r
-\r
-                       prvDeleteTCB( ( tskTCB * ) pxTCB );\r
-               }               \r
        }\r
 \r
 #endif\r
@@ -1412,7 +1505,7 @@ void vTaskSwitchContext( void )
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-void vTaskPlaceOnEventList( xList *pxEventList, portTickType xTicksToWait )\r
+void vTaskPlaceOnEventList( const xList * const pxEventList, portTickType xTicksToWait )\r
 {\r
 portTickType xTimeToWake;\r
 \r
@@ -1482,7 +1575,7 @@ portTickType xTimeToWake;
 }\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
@@ -1529,20 +1622,31 @@ 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
+       #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
+        /* 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
@@ -1645,10 +1749,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
@@ -1660,6 +1762,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
@@ -1775,7 +1882,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
@@ -1797,7 +1904,7 @@ tskTCB *pxNewTCB;
 /*-----------------------------------------------------------*/\r
 \r
 #if ( configUSE_TRACE_FACILITY == 1 )\r
-       unsigned portSHORT usTaskCheckFreeStackSpace( const unsigned portCHAR *pucStackByte )\r
+       unsigned portSHORT usTaskCheckFreeStackSpace( const unsigned portCHAR * pucStackByte )\r
        {\r
        register unsigned portSHORT usCount = 0;\r
 \r
@@ -1848,7 +1955,92 @@ 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
+#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
+#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
+\r
+       \r
 \r