/*\r
- * FreeRTOS Kernel V10.0.1\r
- * Copyright (C) 2017 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
*/\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
/* 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
* 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
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
uint8_t ucDelayAborted;\r
#endif\r
\r
+ #if( configUSE_POSIX_ERRNO == 1 )\r
+ int iTaskErrno;\r
+ #endif\r
+\r
} tskTCB;\r
\r
/* The old tskTCB name is maintained above then typedefed to the new TCB_t name\r
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
\r
#endif\r
\r
+/* Global POSIX errno. Its value is changed upon context switching to match\r
+the errno of the currently running task. */\r
+#if ( configUSE_POSIX_ERRNO == 1 )\r
+ int FreeRTOS_errno = 0;\r
+#endif\r
+\r
/* Other file private variables. --------------------------------*/\r
PRIVILEGED_DATA static volatile UBaseType_t uxCurrentNumberOfTasks = ( UBaseType_t ) 0U;\r
PRIVILEGED_DATA static volatile TickType_t xTickCount = ( TickType_t ) configINITIAL_TICK_COUNT;\r
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
* 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
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
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
/* 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
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
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
#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
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
#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
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
\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 = ( TCB_t * ) 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
#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
/* If xTask is NULL then we are calling our own task hook. */\r
if( xTask == NULL )\r
{\r
- xTCB = ( TCB_t * ) pxCurrentTCB;\r
+ xTCB = pxCurrentTCB;\r
}\r
else\r
{\r
\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
/* Check for stack overflow, if configured. */\r
taskCHECK_FOR_STACK_OVERFLOW();\r
\r
+ /* Before the currently running task is switched out, save its errno. */\r
+ #if( configUSE_POSIX_ERRNO == 1 )\r
+ {\r
+ pxCurrentTCB->iTaskErrno = FreeRTOS_errno;\r
+ }\r
+ #endif\r
+\r
/* Select a new task to run using either the generic C or port\r
optimised asm code. */\r
taskSELECT_HIGHEST_PRIORITY_TASK(); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */\r
traceTASK_SWITCHED_IN();\r
\r
+ /* After the new task is switched in, update the global errno. */\r
+ #if( configUSE_POSIX_ERRNO == 1 )\r
+ {\r
+ FreeRTOS_errno = pxCurrentTCB->iTaskErrno;\r
+ }\r
+ #endif\r
+\r
#if ( configUSE_NEWLIB_REENTRANT == 1 )\r
{\r
/* Switch Newlib's _impure_ptr variable to point to the _reent\r
{\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
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
\r
if( xTask != NULL )\r
{\r
- pxTCB = ( TCB_t * ) xTask;\r
+ pxTCB = xTask;\r
uxReturn = pxTCB->uxTaskNumber;\r
}\r
else\r
\r
if( xTask != NULL )\r
{\r
- pxTCB = ( TCB_t * ) xTask;\r
+ pxTCB = xTask;\r
pxTCB->uxTaskNumber = uxHandle;\r
}\r
}\r
/* 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
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
#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
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
\r
/* Write the rest of the string. */\r
sprintf( pcWriteBuffer, "\t%c\t%u\t%u\t%u\r\n", cStatus, ( unsigned int ) pxTaskStatusArray[ x ].uxCurrentPriority, ( unsigned int ) pxTaskStatusArray[ x ].usStackHighWaterMark, ( unsigned int ) pxTaskStatusArray[ x ].xTaskNumber ); /*lint !e586 sprintf() allowed as this is compiled with many compilers and this is a utility function only - not part of the core kernel implementation. */\r
- pcWriteBuffer += strlen( pcWriteBuffer ); /*lint !e9016 Pointer arithmetic ok on char pointers. */\r
+ pcWriteBuffer += strlen( pcWriteBuffer ); /*lint !e9016 Pointer arithmetic ok on char pointers especially as in this case where it best denotes the intent of the code. */\r
}\r
\r
/* Free the array again. NOTE! If configSUPPORT_DYNAMIC_ALLOCATION\r
#endif\r
}\r
\r
- pcWriteBuffer += strlen( pcWriteBuffer ); /*lint !e9016 Pointer arithmetic ok on char pointers. */\r
+ pcWriteBuffer += strlen( pcWriteBuffer ); /*lint !e9016 Pointer arithmetic ok on char pointers especially as in this case where it best denotes the intent of the code. */\r
}\r
}\r
else\r
\r
#if ( configUSE_MUTEXES == 1 )\r
\r
- void *pvTaskIncrementMutexHeldCount( void )\r
+ TaskHandle_t pvTaskIncrementMutexHeldCount( void )\r
{\r
/* If xSemaphoreCreateMutex() is called before any tasks have been created\r
then pxCurrentTCB will be NULL. */\r
uint8_t ucOriginalNotifyState;\r
\r
configASSERT( xTaskToNotify );\r
- pxTCB = ( TCB_t * ) xTaskToNotify;\r
+ pxTCB = xTaskToNotify;\r
\r
taskENTER_CRITICAL();\r
{\r
\r
default:\r
/* Should not get here if all enums are handled.\r
- Artificially force an assert. */\r
- configASSERT( ( volatile uint32_t ) 0 );\r
+ Artificially force an assert by testing a value the\r
+ compiler can't assume is const. */\r
+ configASSERT( pxTCB->ulNotifiedValue == ~0UL );\r
\r
break;\r
}\r
http://www.freertos.org/RTOS-Cortex-M3-M4.html */\r
portASSERT_IF_INTERRUPT_PRIORITY_INVALID();\r
\r
- pxTCB = ( TCB_t * ) xTaskToNotify;\r
+ pxTCB = xTaskToNotify;\r
\r
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();\r
{\r
\r
default:\r
/* Should not get here if all enums are handled.\r
- Artificially force an assert. */\r
- configASSERT( ( volatile uint32_t ) 0 );\r
+ Artificially force an assert by testing a value the\r
+ compiler can't assume is const. */\r
+ configASSERT( pxTCB->ulNotifiedValue == ~0UL );\r
break;\r
}\r
\r
http://www.freertos.org/RTOS-Cortex-M3-M4.html */\r
portASSERT_IF_INTERRUPT_PRIORITY_INVALID();\r
\r
- pxTCB = ( TCB_t * ) xTaskToNotify;\r
+ pxTCB = xTaskToNotify;\r
\r
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();\r
{\r
#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
\r
#include "freertos_tasks_c_additions.h"\r
\r
- static void freertos_tasks_c_additions_init( void )\r
- {\r
- #ifdef FREERTOS_TASKS_C_ADDITIONS_INIT\r
+ #ifdef FREERTOS_TASKS_C_ADDITIONS_INIT\r
+ static void freertos_tasks_c_additions_init( void )\r
+ {\r
FREERTOS_TASKS_C_ADDITIONS_INIT();\r
- #endif\r
- }\r
+ }\r
+ #endif\r
\r
#endif\r
\r