(3) FreeRTOS mission control (1)

1. Get information about all tasks uxTaskGetSystemState()

//task.h

UBaseType_t uxTaskGetSystemState(
                       TaskStatus_t * const pxTaskStatusArray,
                       const UBaseType_t uxArraySize,
                       unsigned long * const pulTotalRunTime );

configUSE_TRACE_FACILITY must be defined to 1 in FreeRTOSConfig.h to use uxTaskGetSystemState().

uxTaskGetSystemState() populates the TaskStatus_t structure for each task in the system. The TaskStatus_t structure contains, among other things, members the task handle, task name, task priority, task status, and the total amount of run time consumed by the task.

Note: This function is for debugging only, as using this function will cause the scheduler to hang for a long time.

Parameters:

pxTaskStatusArray< /em> Pointer to the TaskStatus_t structure array. This array must contain at least one TaskStatus_t structure for each task under RTOS control. You can use the uxTaskGetNumberOfTasks() API function to determine the number of tasks managed by the RTOS.
uxArraySize The size of the array pointed to by the pxTaskStatusArray parameter. The size is specified by the number of indices in the array (the number of TaskStatus_t structures contained in the array), not by the number of bytes in the array.
pulTotalRunTime If configGENERATE_RUN_TIME_STATS is set in FreeRTOSConfig.h is 1, uxTaskGetSystemState() sets *pulTotalRunTime to the total run time since the target was started (as defined by the run time statistics clock). pulTotalRunTime can be set to NULL to omit the total run time value.

Return to:

The number of TaskStatus_t structures populated by uxTaskGetSystemState(). This value should be equal to the number returned by the uxTaskGetNumberOfTasks() API function, but will be zero if the value passed in the uxArraySize parameter is too small.

Usage examples:

typedef struct xTASK_STATUS
{
   /* The handle of the task to which the rest of the information in the
   structure relates. */
   TaskHandle_t xHandle;

   /* A pointer to the task's name. This value will be invalid if the task was
   deleted since the structure was populated! */
   const signed char *pcTaskName;

   /* A number unique to the task. */
   UBaseType_t xTaskNumber;

   /* The state in which the task existed when the structure was populated. */
   eTaskState eCurrentState;

   /* The priority at which the task was running (may be inherited) when the
   structure was populated. */
   UBaseType_t uxCurrentPriority;

   /* The priority to which the task will return if the task's current priority
   has been inherited to avoid unbounded priority inversion when obtaining a
   mutex. Only valid if configUSE_MUTEXES is defined as 1 in
   FreeRTOSConfig.h. */
   UBaseType_t uxBasePriority;

   /* The total run time allocated to the task so far, as defined by the run
   time stats clock. Only valid when configGENERATE_RUN_TIME_STATS is
   defined as 1 in FreeRTOSConfig.h. */
   unsigned long ulRunTimeCounter;

   /* Points to the lowest address of the task's stack area. */
   StackType_t *pxStackBase;

   /* The minimum amount of stack space that has remained for the task since
   the task was created. The closer this value is to zero the closer the task
   has come to overflowing its stack. */
   configSTACK_DEPTH_TYPE usStackHighWaterMark;
} TaskStatus_t;


/* This example demonstrates how a human readable table of run time stats
information is generated from raw data provided by uxTaskGetSystemState().
The human readable table is written to pcWriteBuffer. (see the vTaskList()
API function which actually does just this). */
void vTaskGetRunTimeStats(signed char *pcWriteBuffer)
{
TaskStatus_t *pxTaskStatusArray;
volatile UBaseType_t uxArraySize, x;
unsigned long ulTotalRunTime, ulStatsAsPercentage;

   /* Make sure the write buffer does not contain a string. */
   *pcWriteBuffer = 0x00;

   /* Take a snapshot of the number of tasks in case it changes while this
   function is executing. */
   uxArraySize = uxTaskGetNumberOfTasks();

   /* Allocate a TaskStatus_t structure for each task. An array could be
   allocated statically at compile time. */
   pxTaskStatusArray = pvPortMalloc( uxArraySize * sizeof( TaskStatus_t ) );

   if( pxTaskStatusArray != NULL )
   {
      /* Generate raw status information about each task. */
      uxArraySize = uxTaskGetSystemState( pxTaskStatusArray,
                                 uxArraySize,
                                  &ulTotalRunTime );

      /* For percentage calculations. */
      ulTotalRunTime /= 100UL;

      /* Avoid divide by zero errors. */
      if(ulTotalRunTime > 0)
      {
         /* For each populated position in the pxTaskStatusArray array,
         format the raw data as human readable ASCII data. */
         for( x = 0; x < uxArraySize; x + + )
         {
            /* What percentage of the total run time has the task used?
            This will always be rounded down to the nearest integer.
            ulTotalRunTimeDiv100 has already been divided by 100. */
            ulStatsAsPercentage =
                  pxTaskStatusArray[x].ulRunTimeCounter / ulTotalRunTime;

            if(ulStatsAsPercentage > 0UL)
            {
               sprintf( pcWriteBuffer, "%stt%lutt%lu%%rn",
                                 pxTaskStatusArray[ x ].pcTaskName,
                                 pxTaskStatusArray[ x ].ulRunTimeCounter,
                                 ulStatsAsPercentage );
            }
            else
            {
               /* If the percentage is zero here then the task has
               consumed less than 1% of the total run time. */
               sprintf( pcWriteBuffer, "%stt%lutt<1%%rn",
                                 pxTaskStatusArray[ x ].pcTaskName,
                                 pxTaskStatusArray[ x ].ulRunTimeCounter );
            }

            pcWriteBuffer + = strlen( ( char * ) pcWriteBuffer );
         }
      }

      /* The array is no longer needed, free the memory it consumes. */
      vPortFree(pxTaskStatusArray);
   }
}

2. Get information about a single task vTaskGetInfo()

//task.h

void vTaskGetInfo( TaskHandle_t xTask,
                   TaskStatus_t *pxTaskStatus,
                   BaseType_t xGetFreeStackSpace,
                   eTaskState eState );

configUSE_TRACE_FACILITY must be defined to 1 in FreeRTOSConfig.h for vTaskGetInfo() to be available.

uxTaskGetSystemState() populates the TaskStatus_t structure for each task in the system, while vTaskGetInfo() only populates the TaskStatus_t structure for a single task. The TaskStatus_t structure contains members of the task handle, task name, task priority, task status, and the total running time consumed by the task.

NOTE: Using this function can cause the scheduler to hang for a long time, so this function is for debugging purposes only.

Parameters:

xTask The handle of the task being queried. Setting xTask to NULL returns information about the calling task.
pxTaskStatus The TaskStatus_t structure pointed to by pxTaskStatus will be filled in Information about the task referenced by the handle passed in the xTask parameter.
xGetFreeStackSpace TaskStatus_t structure contains the queried report A member of the task’s stack high water mark. The stack high water mark refers to the historical remaining minimum value of the stack space. The closer this value is to zero, the closer the task is to a stack overflow. Calculating the stack high-water mark takes a relatively long time and may cause the system to become temporarily unresponsive, so the xGetFreeStackSpace parameter is provided to allow the high-water mark check to be skipped. If xGetFreeStackSpace is not set to pdFALSE, the high watermark value will only be written to the TaskStatus_t structure.
eState TaskStatus_t structure contains the queried report Member of the task’s status. Obtaining the task status is not as fast as simple assignment, so the eState parameter is provided to allow the TaskStatus_t structure to omit status information. To obtain status information, set eState to eInvalid, otherwise the value passed in eState will be reported as the task status in the TaskStatus_t structure.

Usage examples:

typedef struct xTASK_STATUS
{
   /* The handle of the task to which the rest of the information in the
   structure relates. */
   TaskHandle_t xHandle;

   /* A pointer to the task's name. This value will be invalid if the task was
   deleted since the structure was populated! */
   const signed char *pcTaskName;

   /* A number unique to the task. */
   UBaseType_t xTaskNumber;

   /* The state in which the task existed when the structure was populated. */
   eTaskState eCurrentState;

   /* The priority at which the task was running (may be inherited) when the
   structure was populated. */
   UBaseType_t uxCurrentPriority;

   /* The priority to which the task will return if the task's current priority
   has been inherited to avoid unbounded priority inversion when obtaining a
   mutex. Only valid if configUSE_MUTEXES is defined as 1 in
   FreeRTOSConfig.h. */
   UBaseType_t uxBasePriority;

   /* The total run time allocated to the task so far, as defined by the run
   time stats clock. Only valid when configGENERATE_RUN_TIME_STATS is
   defined as 1 in FreeRTOSConfig.h. */
   unsigned long ulRunTimeCounter;

   /* Points to the lowest address of the task's stack area. */
   StackType_t *pxStackBase;

   /* The minimum amount of stack space that has remained for the task since
   the task was created. The closer this value is to zero the closer the task
   has come to overflowing its stack. */
   configSTACK_DEPTH_TYPE usStackHighWaterMark;
} TaskStatus_t;



void vAFunction(void)
{
TaskHandle_t xHandle;
TaskStatus_t xTaskDetails;

    /* Obtain the handle of a task from its name. */
    xHandle = xTaskGetHandle( "Task_Name" );

    /* Check the handle is not NULL. */
    configASSERT(xHandle);

    /* Use the handle to obtain further information about the task. */
    vTaskGetInfo( /* The handle of the task being queried. */
                  xHandle,
                  /* The TaskStatus_t structure to complete with information
                  on xTask. */
                   &xTaskDetails,
                  /* Include the stack high water mark value in the
                  TaskStatus_t structure. */
                  pdTRUE,
                  /* Include the task state in the TaskStatus_t structure. */
                  eInvalid );
}