+ void vTaskExitCritical( void )\r
+ {\r
+ if( xSchedulerRunning != pdFALSE )\r
+ {\r
+ if( pxCurrentTCB->uxCriticalNesting > 0U )\r
+ {\r
+ ( pxCurrentTCB->uxCriticalNesting )--;\r
+\r
+ if( pxCurrentTCB->uxCriticalNesting == 0U )\r
+ {\r
+ portENABLE_INTERRUPTS();\r
+ }\r
+ else\r
+ {\r
+ mtCOVERAGE_TEST_MARKER();\r
+ }\r
+ }\r
+ else\r
+ {\r
+ mtCOVERAGE_TEST_MARKER();\r
+ }\r
+ }\r
+ else\r
+ {\r
+ mtCOVERAGE_TEST_MARKER();\r
+ }\r
+ }\r
+\r
+#endif /* portCRITICAL_NESTING_IN_TCB */\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) )\r
+\r
+ void vTaskList( char * pcWriteBuffer )\r
+ {\r
+ TaskStatus_t *pxTaskStatusArray;\r
+ volatile UBaseType_t uxArraySize, x;\r
+ char cStatus;\r
+\r
+ /*\r
+ * PLEASE NOTE:\r
+ *\r
+ * This function is provided for convenience only, and is used by many\r
+ * of the demo applications. Do not consider it to be part of the\r
+ * scheduler.\r
+ *\r
+ * vTaskList() calls uxTaskGetSystemState(), then formats part of the\r
+ * uxTaskGetSystemState() output into a human readable table that\r
+ * displays task names, states and stack usage.\r
+ *\r
+ * vTaskList() has a dependency on the sprintf() C library function that\r
+ * might bloat the code size, use a lot of stack, and provide different\r
+ * results on different platforms. An alternative, tiny, third party,\r
+ * and limited functionality implementation of sprintf() is provided in\r
+ * many of the FreeRTOS/Demo sub-directories in a file called\r
+ * printf-stdarg.c (note printf-stdarg.c does not provide a full\r
+ * snprintf() implementation!).\r
+ *\r
+ * It is recommended that production systems call uxTaskGetSystemState()\r
+ * directly to get access to raw stats data, rather than indirectly\r
+ * through a call to vTaskList().\r
+ */\r
+\r
+\r
+ /* Make sure the write buffer does not contain a string. */\r
+ *pcWriteBuffer = 0x00;\r
+\r
+ /* Take a snapshot of the number of tasks in case it changes while this\r
+ function is executing. */\r
+ uxArraySize = uxCurrentNumberOfTasks;\r
+\r
+ /* Allocate an array index for each task. */\r
+ pxTaskStatusArray = pvPortMalloc( uxCurrentNumberOfTasks * sizeof( TaskStatus_t ) );\r
+\r
+ if( pxTaskStatusArray != NULL )\r
+ {\r
+ /* Generate the (binary) data. */\r
+ uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, NULL );\r
+\r
+ /* Create a human readable table from the binary data. */\r
+ for( x = 0; x < uxArraySize; x++ )\r
+ {\r
+ switch( pxTaskStatusArray[ x ].eCurrentState )\r
+ {\r
+ case eReady: cStatus = tskREADY_CHAR;\r
+ break;\r
+\r
+ case eBlocked: cStatus = tskBLOCKED_CHAR;\r
+ break;\r
+\r
+ case eSuspended: cStatus = tskSUSPENDED_CHAR;\r
+ break;\r
+\r
+ case eDeleted: cStatus = tskDELETED_CHAR;\r
+ break;\r
+\r
+ default: /* Should not get here, but it is included\r
+ to prevent static checking errors. */\r
+ cStatus = 0x00;\r
+ break;\r
+ }\r
+\r
+ sprintf( pcWriteBuffer, "%s\t\t%c\t%u\t%u\t%u\r\n", pxTaskStatusArray[ x ].pcTaskName, cStatus, ( unsigned int ) pxTaskStatusArray[ x ].uxCurrentPriority, ( unsigned int ) pxTaskStatusArray[ x ].usStackHighWaterMark, ( unsigned int ) pxTaskStatusArray[ x ].xTaskNumber );\r
+ pcWriteBuffer += strlen( pcWriteBuffer );\r
+ }\r
+\r
+ /* Free the array again. */\r
+ vPortFree( pxTaskStatusArray );\r
+ }\r
+ else\r
+ {\r
+ mtCOVERAGE_TEST_MARKER();\r
+ }\r
+ }\r
+\r
+#endif /* ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) ) */\r
+/*----------------------------------------------------------*/\r
+\r
+#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) )\r
+\r
+ void vTaskGetRunTimeStats( char *pcWriteBuffer )\r