]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS/Source/tasks.c
Fix potential memory leak in the Win32 FreeRTOS+TCP network interface initialisation...
[freertos] / FreeRTOS / Source / tasks.c
index d9d2b5824af320cb3f115849df5b26f907161264..13aaf135c04f32433086f929bfc21490591ce250 100644 (file)
@@ -1,6 +1,6 @@
 /*\r
- * FreeRTOS Kernel V10.1.0\r
- * Copyright (C) 2018 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
+ * FreeRTOS Kernel V10.2.0\r
+ * Copyright (C) 2019 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
  *\r
  * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
  * this software and associated documentation files (the "Software"), to deal in\r
@@ -75,24 +75,7 @@ functions but without including stdio.h here. */
  */\r
 #define tskSTACK_FILL_BYTE     ( 0xa5U )\r
 \r
-/* Sometimes the FreeRTOSConfig.h settings only allow a task to be created using\r
-dynamically allocated RAM, in which case when any task is deleted it is known\r
-that both the task's stack and TCB need to be freed.  Sometimes the\r
-FreeRTOSConfig.h settings only allow a task to be created using statically\r
-allocated RAM, in which case when any task is deleted it is known that neither\r
-the task's stack or TCB should be freed.  Sometimes the FreeRTOSConfig.h\r
-settings allow a task to be created using either statically or dynamically\r
-allocated RAM, in which case a member of the TCB is used to record whether the\r
-stack and/or TCB were allocated statically or dynamically, so when a task is\r
-deleted the RAM that was allocated dynamically is freed again and no attempt is\r
-made to free the RAM that was allocated statically.\r
-tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE is only true if it is possible for a\r
-task to be created using either statically or dynamically allocated RAM.  Note\r
-that if portUSING_MPU_WRAPPERS is 1 then a protected task can be created with\r
-a statically allocated stack and a dynamically allocated TCB.\r
-!!!NOTE!!! If the definition of tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE is\r
-changed then the definition of StaticTask_t must also be updated. */\r
-#define tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE      ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )\r
+/* Bits used to recored how a task's stack and TCB were allocated. */\r
 #define tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB                 ( ( uint8_t ) 0 )\r
 #define tskSTATICALLY_ALLOCATED_STACK_ONLY                     ( ( uint8_t ) 1 )\r
 #define tskSTATICALLY_ALLOCATED_STACK_AND_TCB          ( ( uint8_t ) 2 )\r
@@ -100,7 +83,7 @@ changed then the definition of StaticTask_t must also be updated. */
 /* If any of the following are set then task stacks are filled with a known\r
 value so the high water mark can be determined.  If none of the following are\r
 set then don't fill the stack so there is no unnecessary dependency on memset. */\r
-#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) || ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )\r
+#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) || ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) )\r
        #define tskSET_NEW_STACKS_TO_KNOWN_VALUE        1\r
 #else\r
        #define tskSET_NEW_STACKS_TO_KNOWN_VALUE        0\r
@@ -266,7 +249,7 @@ to its original value when it is released. */
  * and stores task state information, including a pointer to the task's context\r
  * (the task's run time environment, including register values)\r
  */\r
-typedef struct TaskControlBlock_t\r
+typedef struct tskTaskControlBlock                     /* The old naming convention is used to prevent breaking kernel aware debuggers. */\r
 {\r
        volatile StackType_t    *pxTopOfStack;  /*< Points to the location of the last item placed on the tasks stack.  THIS MUST BE THE FIRST MEMBER OF THE TCB STRUCT. */\r
 \r
@@ -326,7 +309,7 @@ typedef struct TaskControlBlock_t
                volatile uint8_t ucNotifyState;\r
        #endif\r
 \r
-       /* See the comments above the definition of\r
+       /* See the comments in FreeRTOS.h with the definition of\r
        tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE. */\r
        #if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e731 !e9029 Macro has been consolidated for readability reasons. */\r
                uint8_t ucStaticallyAllocated;          /*< Set to pdTRUE if the task is a statically allocated to ensure no attempt is made to free the memory. */\r
@@ -350,8 +333,13 @@ typedef tskTCB TCB_t;
 which static variables must be declared volatile. */\r
 PRIVILEGED_DATA TCB_t * volatile pxCurrentTCB = NULL;\r
 \r
-/* Lists for ready and blocked tasks. --------------------*/\r
+/* Lists for ready and blocked tasks. --------------------\r
+xDelayedTaskList1 and xDelayedTaskList2 could be move to function scople but\r
+doing so breaks some kernel aware debuggers and debuggers that rely on removing\r
+the static qualifier. */\r
 PRIVILEGED_DATA static List_t pxReadyTasksLists[ configMAX_PRIORITIES ];/*< Prioritised ready tasks. */\r
+PRIVILEGED_DATA static List_t xDelayedTaskList1;                                               /*< Delayed tasks. */\r
+PRIVILEGED_DATA static List_t xDelayedTaskList2;                                               /*< Delayed tasks (two lists are used - one for delays that have overflowed the current tick count. */\r
 PRIVILEGED_DATA static List_t * volatile pxDelayedTaskList;                            /*< Points to the delayed task list currently being used. */\r
 PRIVILEGED_DATA static List_t * volatile pxOverflowDelayedTaskList;            /*< Points to the delayed task list currently being used to hold tasks that have overflowed the current tick count. */\r
 PRIVILEGED_DATA static List_t xPendingReadyList;                                               /*< Tasks that have been readied while the scheduler was suspended.  They will be moved to the ready list when the scheduler is resumed. */\r
@@ -397,6 +385,15 @@ when the scheduler is unsuspended.  The pending ready list itself can only be
 accessed from a critical section. */\r
 PRIVILEGED_DATA static volatile UBaseType_t uxSchedulerSuspended       = ( UBaseType_t ) pdFALSE;\r
 \r
+#if ( configGENERATE_RUN_TIME_STATS == 1 )\r
+\r
+       /* Do not move these variables to function scope as doing so prevents the\r
+       code working with debuggers that need to remove the static qualifier. */\r
+       PRIVILEGED_DATA static uint32_t ulTaskSwitchedInTime = 0UL;     /*< Holds the value of a timer/counter the last time a task was switched in. */\r
+       PRIVILEGED_DATA static uint32_t ulTotalRunTime = 0UL;           /*< Holds the total amount of execution time as defined by the run time counter clock. */\r
+\r
+#endif\r
+\r
 /*lint -restore */\r
 \r
 /*-----------------------------------------------------------*/\r
@@ -507,7 +504,7 @@ static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, const BaseT
  * 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 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )\r
+#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) )\r
 \r
        static configSTACK_DEPTH_TYPE prvTaskCheckFreeStackSpace( const uint8_t * pucStackByte ) PRIVILEGED_FUNCTION;\r
 \r
@@ -617,7 +614,7 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB ) PRIVILEGED_FUNCTION;
                                task was created statically in case the task is later deleted. */\r
                                pxNewTCB->ucStaticallyAllocated = tskSTATICALLY_ALLOCATED_STACK_AND_TCB;\r
                        }\r
-                       #endif /* configSUPPORT_DYNAMIC_ALLOCATION */\r
+                       #endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */\r
 \r
                        prvInitialiseNewTask( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, &xReturn, pxNewTCB, NULL );\r
                        prvAddNewTaskToReadyList( pxNewTCB );\r
@@ -659,7 +656,7 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB ) PRIVILEGED_FUNCTION;
                                task was created statically in case the task is later deleted. */\r
                                pxNewTCB->ucStaticallyAllocated = tskSTATICALLY_ALLOCATED_STACK_AND_TCB;\r
                        }\r
-                       #endif /* configSUPPORT_DYNAMIC_ALLOCATION */\r
+                       #endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */\r
 \r
                        prvInitialiseNewTask(   pxTaskDefinition->pvTaskCode,\r
                                                                        pxTaskDefinition->pcName,\r
@@ -700,14 +697,14 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB ) PRIVILEGED_FUNCTION;
                                /* Store the stack location in the TCB. */\r
                                pxNewTCB->pxStack = pxTaskDefinition->puxStackBuffer;\r
 \r
-                               #if( configSUPPORT_STATIC_ALLOCATION == 1 )\r
+                               #if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 )\r
                                {\r
                                        /* Tasks can be created statically or dynamically, so note\r
                                        this task had a statically allocated stack in case it is\r
                                        later deleted.  The TCB was allocated dynamically. */\r
                                        pxNewTCB->ucStaticallyAllocated = tskSTATICALLY_ALLOCATED_STACK_ONLY;\r
                                }\r
-                               #endif\r
+                               #endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */\r
 \r
                                prvInitialiseNewTask(   pxTaskDefinition->pvTaskCode,\r
                                                                                pxTaskDefinition->pcName,\r
@@ -804,7 +801,7 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB ) PRIVILEGED_FUNCTION;
                                task was created dynamically in case it is later deleted. */\r
                                pxNewTCB->ucStaticallyAllocated = tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB;\r
                        }\r
-                       #endif /* configSUPPORT_STATIC_ALLOCATION */\r
+                       #endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */\r
 \r
                        prvInitialiseNewTask( pxTaskCode, pcName, ( uint32_t ) usStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB, NULL );\r
                        prvAddNewTaskToReadyList( pxNewTCB );\r
@@ -847,8 +844,6 @@ UBaseType_t x;
                uxPriority &= ~portPRIVILEGE_BIT;\r
        #endif /* portUSING_MPU_WRAPPERS == 1 */\r
 \r
-       configASSERT( pcName );\r
-\r
        /* Avoid dependency on memset() if it is not required. */\r
        #if( tskSET_NEW_STACKS_TO_KNOWN_VALUE == 1 )\r
        {\r
@@ -891,26 +886,35 @@ UBaseType_t x;
        #endif /* portSTACK_GROWTH */\r
 \r
        /* Store the task name in the TCB. */\r
-       for( x = ( UBaseType_t ) 0; x < ( UBaseType_t ) configMAX_TASK_NAME_LEN; x++ )\r
+       if( pcName != NULL )\r
        {\r
-               pxNewTCB->pcTaskName[ x ] = pcName[ x ];\r
-\r
-               /* Don't copy all configMAX_TASK_NAME_LEN if the string is shorter than\r
-               configMAX_TASK_NAME_LEN characters just in case the memory after the\r
-               string is not accessible (extremely unlikely). */\r
-               if( pcName[ x ] == ( char ) 0x00 )\r
-               {\r
-                       break;\r
-               }\r
-               else\r
+               for( x = ( UBaseType_t ) 0; x < ( UBaseType_t ) configMAX_TASK_NAME_LEN; x++ )\r
                {\r
-                       mtCOVERAGE_TEST_MARKER();\r
+                       pxNewTCB->pcTaskName[ x ] = pcName[ x ];\r
+\r
+                       /* Don't copy all configMAX_TASK_NAME_LEN if the string is shorter than\r
+                       configMAX_TASK_NAME_LEN characters just in case the memory after the\r
+                       string is not accessible (extremely unlikely). */\r
+                       if( pcName[ x ] == ( char ) 0x00 )\r
+                       {\r
+                               break;\r
+                       }\r
+                       else\r
+                       {\r
+                               mtCOVERAGE_TEST_MARKER();\r
+                       }\r
                }\r
-       }\r
 \r
-       /* Ensure the name string is terminated in the case that the string length\r
-       was greater or equal to configMAX_TASK_NAME_LEN. */\r
-       pxNewTCB->pcTaskName[ configMAX_TASK_NAME_LEN - 1 ] = '\0';\r
+               /* Ensure the name string is terminated in the case that the string length\r
+               was greater or equal to configMAX_TASK_NAME_LEN. */\r
+               pxNewTCB->pcTaskName[ configMAX_TASK_NAME_LEN - 1 ] = '\0';\r
+       }\r
+       else\r
+       {\r
+               /* The task has not been given a name, so just ensure there is a NULL\r
+               terminator when it is read out. */\r
+               pxNewTCB->pcTaskName[ 0 ] = 0x00;\r
+       }\r
 \r
        /* This is used as an array index so must ensure it's not too large.  First\r
        remove the privilege bit if one is present. */\r
@@ -1006,11 +1010,49 @@ UBaseType_t x;
        the top of stack variable is updated. */\r
        #if( portUSING_MPU_WRAPPERS == 1 )\r
        {\r
-               pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters, xRunPrivileged );\r
+               /* If the port has capability to detect stack overflow,\r
+               pass the stack end address to the stack initialization\r
+               function as well. */\r
+               #if( portHAS_STACK_OVERFLOW_CHECKING == 1 )\r
+               {\r
+                       #if( portSTACK_GROWTH < 0 )\r
+                       {\r
+                               pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxNewTCB->pxStack, pxTaskCode, pvParameters, xRunPrivileged );\r
+                       }\r
+                       #else /* portSTACK_GROWTH */\r
+                       {\r
+                               pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxNewTCB->pxEndOfStack, pxTaskCode, pvParameters, xRunPrivileged );\r
+                       }\r
+                       #endif /* portSTACK_GROWTH */\r
+               }\r
+               #else /* portHAS_STACK_OVERFLOW_CHECKING */\r
+               {\r
+                       pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters, xRunPrivileged );\r
+               }\r
+               #endif /* portHAS_STACK_OVERFLOW_CHECKING */\r
        }\r
        #else /* portUSING_MPU_WRAPPERS */\r
        {\r
-               pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters );\r
+               /* If the port has capability to detect stack overflow,\r
+               pass the stack end address to the stack initialization\r
+               function as well. */\r
+               #if( portHAS_STACK_OVERFLOW_CHECKING == 1 )\r
+               {\r
+                       #if( portSTACK_GROWTH < 0 )\r
+                       {\r
+                               pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxNewTCB->pxStack, pxTaskCode, pvParameters );\r
+                       }\r
+                       #else /* portSTACK_GROWTH */\r
+                       {\r
+                               pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxNewTCB->pxEndOfStack, pxTaskCode, pvParameters );\r
+                       }\r
+                       #endif /* portSTACK_GROWTH */\r
+               }\r
+               #else /* portHAS_STACK_OVERFLOW_CHECKING */\r
+               {\r
+                       pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters );\r
+               }\r
+               #endif /* portHAS_STACK_OVERFLOW_CHECKING */\r
        }\r
        #endif /* portUSING_MPU_WRAPPERS */\r
 \r
@@ -1331,7 +1373,7 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB )
 #endif /* INCLUDE_vTaskDelay */\r
 /*-----------------------------------------------------------*/\r
 \r
-#if( ( INCLUDE_eTaskGetState == 1 ) || ( configUSE_TRACE_FACILITY == 1 ) )\r
+#if( ( INCLUDE_eTaskGetState == 1 ) || ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_xTaskAbortDelay == 1 ) )\r
 \r
        eTaskState eTaskGetState( TaskHandle_t xTask )\r
        {\r
@@ -2062,6 +2104,7 @@ void vTaskSuspendAll( void )
        post in the FreeRTOS support forum before reporting this as a bug! -\r
        http://goo.gl/wu4acr */\r
        ++uxSchedulerSuspended;\r
+       portMEMORY_BARRIER();\r
 }\r
 /*----------------------------------------------------------*/\r
 \r
@@ -2824,24 +2867,17 @@ BaseType_t xSwitchRequired = pdFALSE;
 \r
        TaskHookFunction_t xTaskGetApplicationTaskTag( TaskHandle_t xTask )\r
        {\r
-       TCB_t *xTCB;\r
+       TCB_t *pxTCB;\r
        TaskHookFunction_t xReturn;\r
 \r
-               /* If xTask is NULL then we are setting our own task hook. */\r
-               if( xTask == NULL )\r
-               {\r
-                       xTCB = ( TCB_t * ) pxCurrentTCB;\r
-               }\r
-               else\r
-               {\r
-                       xTCB = xTask;\r
-               }\r
+               /* If xTask is NULL then set the calling task's hook. */\r
+               pxTCB = prvGetTCBFromHandle( xTask );\r
 \r
                /* Save the hook function in the TCB.  A critical section is required as\r
                the value can be accessed from an interrupt. */\r
                taskENTER_CRITICAL();\r
                {\r
-                       xReturn = xTCB->pxTaskTag;\r
+                       xReturn = pxTCB->pxTaskTag;\r
                }\r
                taskEXIT_CRITICAL();\r
 \r
@@ -2851,6 +2887,31 @@ BaseType_t xSwitchRequired = pdFALSE;
 #endif /* configUSE_APPLICATION_TASK_TAG */\r
 /*-----------------------------------------------------------*/\r
 \r
+#if ( configUSE_APPLICATION_TASK_TAG == 1 )\r
+\r
+       TaskHookFunction_t xTaskGetApplicationTaskTagFromISR( TaskHandle_t xTask )\r
+       {\r
+       TCB_t *pxTCB;\r
+       TaskHookFunction_t xReturn;\r
+       UBaseType_t uxSavedInterruptStatus;\r
+\r
+               /* If xTask is NULL then set the calling task's hook. */\r
+               pxTCB = prvGetTCBFromHandle( xTask );\r
+\r
+               /* Save the hook function in the TCB.  A critical section is required as\r
+               the value can be accessed from an interrupt. */\r
+               uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();\r
+               {\r
+                       xReturn = pxTCB->pxTaskTag;\r
+               }\r
+               portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );\r
+\r
+               return xReturn;\r
+       }\r
+\r
+#endif /* configUSE_APPLICATION_TASK_TAG */\r
+/*-----------------------------------------------------------*/\r
+\r
 #if ( configUSE_APPLICATION_TASK_TAG == 1 )\r
 \r
        BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter )\r
@@ -2898,31 +2959,28 @@ void vTaskSwitchContext( void )
 \r
                #if ( configGENERATE_RUN_TIME_STATS == 1 )\r
                {\r
-                       PRIVILEGED_DATA static uint32_t ulTaskSwitchedInTime = 0UL;     /*< Holds the value of a timer/counter the last time a task was switched in. */\r
-                       PRIVILEGED_DATA static uint32_t ulTotalRunTime = 0UL;           /*< Holds the total amount of execution time as defined by the run time counter clock. */\r
-\r
-                               #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE\r
-                                       portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalRunTime );\r
-                               #else\r
-                                       ulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE();\r
-                               #endif\r
+                       #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE\r
+                               portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalRunTime );\r
+                       #else\r
+                               ulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE();\r
+                       #endif\r
 \r
-                               /* Add the amount of time the task has been running to the\r
-                               accumulated time so far.  The time the task started running was\r
-                               stored in ulTaskSwitchedInTime.  Note that there is no overflow\r
-                               protection here so count values are only valid until the timer\r
-                               overflows.  The guard against negative values is to protect\r
-                               against suspect run time stat counter implementations - which\r
-                               are provided by the application, not the kernel. */\r
-                               if( ulTotalRunTime > ulTaskSwitchedInTime )\r
-                               {\r
-                                       pxCurrentTCB->ulRunTimeCounter += ( ulTotalRunTime - ulTaskSwitchedInTime );\r
-                               }\r
-                               else\r
-                               {\r
-                                       mtCOVERAGE_TEST_MARKER();\r
-                               }\r
-                               ulTaskSwitchedInTime = ulTotalRunTime;\r
+                       /* Add the amount of time the task has been running to the\r
+                       accumulated time so far.  The time the task started running was\r
+                       stored in ulTaskSwitchedInTime.  Note that there is no overflow\r
+                       protection here so count values are only valid until the timer\r
+                       overflows.  The guard against negative values is to protect\r
+                       against suspect run time stat counter implementations - which\r
+                       are provided by the application, not the kernel. */\r
+                       if( ulTotalRunTime > ulTaskSwitchedInTime )\r
+                       {\r
+                               pxCurrentTCB->ulRunTimeCounter += ( ulTotalRunTime - ulTaskSwitchedInTime );\r
+                       }\r
+                       else\r
+                       {\r
+                               mtCOVERAGE_TEST_MARKER();\r
+                       }\r
+                       ulTaskSwitchedInTime = ulTotalRunTime;\r
                }\r
                #endif /* configGENERATE_RUN_TIME_STATS */\r
 \r
@@ -3059,6 +3117,20 @@ BaseType_t xReturn;
        {\r
                ( void ) uxListRemove( &( pxUnblockedTCB->xStateListItem ) );\r
                prvAddTaskToReadyList( pxUnblockedTCB );\r
+\r
+               #if( configUSE_TICKLESS_IDLE != 0 )\r
+               {\r
+                       /* If a task is blocked on a kernel object then xNextTaskUnblockTime\r
+                       might be set to the blocked task's time out time.  If the task is\r
+                       unblocked for a reason other than a timeout xNextTaskUnblockTime is\r
+                       normally left unchanged, because it is automatically reset to a new\r
+                       value when the tick count equals xNextTaskUnblockTime.  However if\r
+                       tickless idling is used it might be more important to enter sleep mode\r
+                       at the earliest possible time - so reset xNextTaskUnblockTime here to\r
+                       ensure it is updated at the earliest possible time. */\r
+                       prvResetNextTaskUnblockTime();\r
+               }\r
+               #endif\r
        }\r
        else\r
        {\r
@@ -3083,20 +3155,6 @@ BaseType_t xReturn;
                xReturn = pdFALSE;\r
        }\r
 \r
-       #if( configUSE_TICKLESS_IDLE != 0 )\r
-       {\r
-               /* If a task is blocked on a kernel object then xNextTaskUnblockTime\r
-               might be set to the blocked task's time out time.  If the task is\r
-               unblocked for a reason other than a timeout xNextTaskUnblockTime is\r
-               normally left unchanged, because it is automatically reset to a new\r
-               value when the tick count equals xNextTaskUnblockTime.  However if\r
-               tickless idling is used it might be more important to enter sleep mode\r
-               at the earliest possible time - so reset xNextTaskUnblockTime here to\r
-               ensure it is updated at the earliest possible time. */\r
-               prvResetNextTaskUnblockTime();\r
-       }\r
-       #endif\r
-\r
        return xReturn;\r
 }\r
 /*-----------------------------------------------------------*/\r
@@ -3284,7 +3342,7 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters )
        /* In case a task that has a secure context deletes itself, in which case\r
        the idle task is responsible for deleting the task's secure context, if\r
        any. */\r
-       portTASK_CALLS_SECURE_FUNCTIONS();\r
+       portALLOCATE_SECURE_CONTEXT( configMINIMAL_SECURE_STACK_SIZE );\r
 \r
        for( ;; )\r
        {\r
@@ -3488,8 +3546,6 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters )
 static void prvInitialiseTaskLists( void )\r
 {\r
 UBaseType_t uxPriority;\r
-PRIVILEGED_DATA static List_t xDelayedTaskList1;       /*< Delayed tasks. */\r
-PRIVILEGED_DATA static List_t xDelayedTaskList2;       /*< Delayed tasks (two lists are used - one for delays that have overflowed the current tick count. */\r
 \r
        for( uxPriority = ( UBaseType_t ) 0U; uxPriority < ( UBaseType_t ) configMAX_PRIORITIES; uxPriority++ )\r
        {\r
@@ -3677,7 +3733,7 @@ static void prvCheckTasksWaitingTermination( void )
 #endif /* configUSE_TRACE_FACILITY */\r
 /*-----------------------------------------------------------*/\r
 \r
-#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )\r
+#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) )\r
 \r
        static configSTACK_DEPTH_TYPE prvTaskCheckFreeStackSpace( const uint8_t * pucStackByte )\r
        {\r
@@ -3694,7 +3750,47 @@ static void prvCheckTasksWaitingTermination( void )
                return ( configSTACK_DEPTH_TYPE ) ulCount;\r
        }\r
 \r
-#endif /* ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) */\r
+#endif /* ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) ) */\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 )\r
+\r
+       /* uxTaskGetStackHighWaterMark() and uxTaskGetStackHighWaterMark2() are the\r
+       same except for their return type.  Using configSTACK_DEPTH_TYPE allows the\r
+       user to determine the return type.  It gets around the problem of the value\r
+       overflowing on 8-bit types without breaking backward compatibility for\r
+       applications that expect an 8-bit return type. */\r
+       configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask )\r
+       {\r
+       TCB_t *pxTCB;\r
+       uint8_t *pucEndOfStack;\r
+       configSTACK_DEPTH_TYPE uxReturn;\r
+\r
+               /* uxTaskGetStackHighWaterMark() and uxTaskGetStackHighWaterMark2() are\r
+               the same except for their return type.  Using configSTACK_DEPTH_TYPE\r
+               allows the user to determine the return type.  It gets around the\r
+               problem of the value overflowing on 8-bit types without breaking\r
+               backward compatibility for applications that expect an 8-bit return\r
+               type. */\r
+\r
+               pxTCB = prvGetTCBFromHandle( xTask );\r
+\r
+               #if portSTACK_GROWTH < 0\r
+               {\r
+                       pucEndOfStack = ( uint8_t * ) pxTCB->pxStack;\r
+               }\r
+               #else\r
+               {\r
+                       pucEndOfStack = ( uint8_t * ) pxTCB->pxEndOfStack;\r
+               }\r
+               #endif\r
+\r
+               uxReturn = prvTaskCheckFreeStackSpace( pucEndOfStack );\r
+\r
+               return uxReturn;\r
+       }\r
+\r
+#endif /* INCLUDE_uxTaskGetStackHighWaterMark2 */\r
 /*-----------------------------------------------------------*/\r
 \r
 #if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 )\r
@@ -4974,6 +5070,13 @@ TickType_t uxReturn;
 #endif /* configUSE_TASK_NOTIFICATIONS */\r
 /*-----------------------------------------------------------*/\r
 \r
+#if( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) )\r
+       TickType_t xTaskGetIdleRunTimeCounter( void )\r
+       {\r
+               return xIdleTaskHandle->ulRunTimeCounter;\r
+       }\r
+#endif\r
+/*-----------------------------------------------------------*/\r
 \r
 static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, const BaseType_t xCanBlockIndefinitely )\r
 {\r