ESP32 FreeRTOS-调试任务实用工具(4)

提示:好记性不如烂笔头。本博客作为学习笔记,有错误的地方希望指正

ESP32-FreeRTOS序列:

ESP32 FreeRTOS-任务的创建与删除 (1)
ESP32 FreeRTOS-任务输入参数(2)
ESP32 FreeRTOS-任务优先级(3)
ESP32 FreeRTOS-调试任务实用工具(4)

前言:

  参考资料:FreeRTOS API参考
  对于多任务的调试,FreeRTOS也给出了许多的API,方便我们在调试的时候查看任务各方面的资源。

一、获取系统状态uxTaskGetSystemState()

API原型:

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

  configUSE_TRACE_FACILITY必须在FreeRTOSConfig.h中定义为1,uxTaskGetSystemState()才可用。
  uxTaskGetSystemState()为系统中的每个任务填充一个 TaskStatus_t 结构。TaskStatus_t结构包含了任务句柄、任务名称、任务优先级、任务状态和任务所消耗的总运行时间等成员。
  参见vTaskGetInfo(),该版本为单个任务,而不是每个任务填充TaskStatus_t结构。
  注意:该函数仅用于调试,因为它的使用会导致调度器在很长一段时间内保持暂停。
参数:

  • pxTaskStatusArray: 一个指向TaskStatus_t结构阵列的指针。该数组必须包含每个在RTOS控制下的任务的至少一个TaskStatus_t结构。在RTOS控制下的任务数量可以通过uxTaskGetNumberOfTasks()API函数来确定。
  • uxArraySize: 由pxTaskStatusArray参数指向的数组的大小。该大小被指定为数组中的索引数(数组中包含的TaskStatus_t结构数),而不是数组中的字节数。
  • pulTotalRunTime: 如果在FreeRTOSConfig.h中configGENERATE_RUN_TIME_STATS被设置为1,那么*pulTotalRunTime被uxTaskGetSystemState()设置为目标启动后的总运行时间(由运行时间统计时钟定义)。 pulTotalRunTime可以被设置为NULL,省略总运行时间值。
    返回:
      由uxTaskGetSystemState()填充的TaskStatus_t结构的数量。这应该等于uxTaskGetNumberOfTasks()API函数返回的数量,但如果uxArraySize参数中传递的值太小,则为零。
    使用范例:
    TaskStatus_t的定义:
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 );
   }
}

  需要使用该API需要打开sdkconfig打开USE_TRACE_FACILITY和GENERATE_RUN_TIME_STATS的配置。
在这里插入图片描述
在这里插入图片描述

二、获取任务信息vTaskGetInfo()

API原型:

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

  configUSE_TRACE_FACILITY必须在FreeRTOSConfig.h中定义为1,vTaskGetInfo()才可用。
  uxTaskGetSystemState()为系统中的每个任务填充一个TaskStatus_t结构,而vTaskGetInfo()只为单个任务填充一个TaskStatus_t结构。TaskStatus_t结构包含了任务句柄、任务名称、任务优先级、任务状态和任务所消耗的总运行时间等成员。
  注意:该函数仅用于调试,因为它的使用会导致调度器长时间悬浮。
参数:

  • xTask: 被查询的任务的句柄。将xTask设置为NULL将返回调用任务的信息。
  • pxTaskStatus: 由pxTaskStatus指向的TaskStatus_t结构将被填入由xTask参数中传递的句柄引用的任务信息。
  • xGetFreeStackSpace: TaskStatus_t结构包含一个成员,报告被查询任务的堆栈高水位。堆栈高水位线是曾经存在的最小的堆栈空间,所以数字越接近于零,任务就越接近于溢出其堆栈。计算堆栈高水位线需要相对较长的时间,并可能使系统暂时没有反应–所以提供xGetFreeStackSpace参数,允许跳过高水位线检查。只有当xGetFreeStackSpace没有被设置为pdFALSE时,高水位标记值才会被写入TaskStatus_t结构。
  • eState: TaskStatus_t 结构包含一个成员,用于报告被查询任务的状态。获取任务状态并不像简单的赋值那么快–所以提供eState参数是为了允许从TaskStatus_t结构中省略状态信息。要获得状态信息,就把eState设置为eInvalid–否则eState中传递的值将被报告为TaskStatus_t结构中的任务状态。
    TaskStatus_t的定义:
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 );
}

  需要使用该API需要打开sdkconfig打开USE_TRACE_FACILITY的配置。
在这里插入图片描述

三、获取应用任务标签xTaskGetApplicationTaskTag() xTaskGetApplicationTaskTagFromISR()

API原型:

TaskHookFunction_t xTaskGetApplicationTaskTag( TaskHandle_t xTask );
TaskHookFunction_t xTaskGetApplicationTaskTagFromISR( TaskHandle_t xTask );

  configUSE_APPLICATION_TASK_TAG必须被定义为1,这些功能才可用。更多信息请参见RTOS配置文档。
  xTaskGetApplicationTaskTagFromISR()是xTaskGetApplicationTaskTag()的一个版本,可以从中断服务程序(ISR)中调用。
  返回与一个任务相关的 "标签 "值。标签值的含义和用途由应用程序编写者定义。RTOS内核本身通常不会访问标签值。
  这个函数只为高级用户准备。
参数:
  xTask 被查询的任务的句柄。一个任务可以通过使用NULL作为参数值来查询自己的标签值。
返回:
  被查询的任务的 "标签 "值。
使用示例:

/* In this example, an integer is set as the task tag value. */
void vATask( void *pvParameters )
{
    
    
    /* Assign a tag value of 1 to the currently executing task.
    The (void *) cast is used to prevent compiler warnings. */
    vTaskSetApplicationTaskTag( NULL, ( void * ) 1 );

    for( ;; )
    {
    
    
        /* Rest of task code goes here. */
    }
}

void vAFunction( void )
{
    
    
TaskHandle_t xHandle;
int iReturnedTaskHandle;

   /* Create a task from the vATask() function, storing the handle to the
   created task in the xTask variable. */

   /* Create the task. */
   if( xTaskCreate(
             vATask,         /* Pointer to the function that implements
                                the task. */
             "Demo task",    /* Text name given to the task. */
             STACK_SIZE,     /* The size of the stack that should be created
                                for the task.  This is defined in words, not
                                bytes. */
             NULL,           /* The task does not use the
                              parameter. */
             TASK_PRIORITY,  /* The priority to assign to the newly created
                                task. */
             &xHandle        /* The handle to the task being created will be
                                placed in xHandle. */
             ) == pdPASS )
   {
    
    
       /* The task was created successfully.  Delay for a short period to allow
       the task to run. */
       vTaskDelay( 100 );

       /* What tag value is assigned to the task?  The returned tag value is
       stored in an integer, so cast to an integer to prevent compiler
       warnings. */
       iReturnedTaskHandle = ( int ) xTaskGetApplicationTaskTag( xHandle );
   }
}

四、获取任务当前句柄xTaskGetCurrentTaskHandle()

API原型:

TaskHandle_t xTaskGetCurrentTaskHandle( void );

  INCLUDE_xTaskGetCurrentTaskHandle必须被设置为1才能使用这个函数。
返回:
  当前运行(调用)的任务的句柄。

五、获取任务状态eTaskGetState()

API原型:

eTaskState eTaskGetState( TaskHandle_t xTask );

  作为一个枚举类型返回任务在执行eTaskGetState()时存在的状态。INCLUDE_eTaskGetState必须在FreeRTOSConfig.h中被设置为1,以便eTaskGetState()可用。参见vTaskGetInfo()。
参数:

  • xTask: 主题任务(被查询的任务)的句柄。

返回:
  下表列出了eTaskGetState()对xTask参数所引用的任务可能存在的每种状态的返回值。

状态 返回值
Ready eRead(就绪)
Running eRunning (the calling task is querying its own priority)(运行)
Blocked eBlocked(堵塞)
Suspended eSuspended(挂起)
Deleted eDeleted (the tasks TCB is waiting to be cleaned up(删除)

  关于任务的状态准备在下一篇中介绍。

六、获取任务名字pcTaskGetName()

API原型:

char * pcTaskGetName( TaskHandle_t xTaskToQuery );

  从一个任务的句柄中查找该任务的名称。
参数:
  xTaskToQuery 被查询的任务的句柄。xTaskToQuery可以被设置为NULL来查询调用任务的名称。
返回:
  一个指向主题任务名称的指针,它是一个标准的以NULL结尾的C语言字符串。

七、获取任务句柄xTaskGetHandle()

API原型:

TaskHandle_t xTaskGetHandle( const char *pcNameToQuery );

  从任务的名称中查找任务的句柄。
  注意:这个函数需要较长的时间来完成,对每个任务只应调用一次。一旦获得一个任务的句柄,就可以将其保存在本地以便再次使用。
  INCLUDE_xTaskGetHandle必须在FreeRTOSConfig.h中设置为1,才能使用xTaskGetHandle()。
参数:

  • pcNameToQuery: 将被返回句柄的任务的文本名称(作为标准的C语言NULL结束的字符串)。
    参见xTaskCreate()和xTaskCreateStatic()API函数的pcName参数,以了解关于设置任务文本名称的信息。

返回:
  如果可以找到一个具有pcNameToQuery中传递的名称的任务,那么将返回该任务的句柄,否则将返回NULL。

八、获取任务滴答计数xTaskGetTickCount()

API原型:

volatile TickType_t xTaskGetTickCount( void );

  这个函数不能从ISR中调用。请使用xTaskGetTickCountFromISR()代替。
返回:
  自vTaskStartScheduler被调用后的刻度计数。

九、中断中获取任务滴答计数xTaskGetTickCountFromISR()

API原型:

volatile TickType_t xTaskGetTickCountFromISR( void );

  xTaskGetTickCount()的一个版本,可以从ISR中调用。
返回:
  自vTaskStartScheduler被调用后的刻度计数。

十、获取任务调度状态xTaskGetSchedulerState()

API原型:

BaseType_t xTaskGetSchedulerState( void );

返回:
  以下常量之一(在task.h中定义):taskSCHEDULER_NOT_STARTED, taskSCHEDULER_RUNNING, taskSCHEDULER_SUSPENDED。
  INCLUDE_xTaskGetSchedulerState或configUSE_TIMERS必须在FreeRTOSConfig.h中设置为1才能使用此函数。

十一、获取总任务数量uxTaskGetNumberOfTasks()

API原型:

UBaseType_t uxTaskGetNumberOfTasks( void );

返回:
  实时操作系统内核目前正在管理的任务数量。这包括所有准备好的、阻塞的和暂停的任务。一个已经被删除但尚未被空闲任务释放的任务也将被包括在这个计数中。

十二、任务列表vTaskList()

API原型:

void vTaskList( char *pcWriteBuffer );

  configUSE_TRACE_FACILITY 和 configUSE_STATS_FORMATTING_FUNCTIONS 必须在 FreeRTOSConfig.h 中定义为 1 才能使用此函数。更多信息请参见配置部分。
  注意:这个函数将在其持续时间内禁用中断。它不打算用于正常的应用程序的运行,而是作为一个调试辅助工具。
  vTaskList()调用uxTaskGetSystemState(),然后将uxTaskGetSystemState()生成的原始数据格式化为人类可读的(ASCII)表格,显示每个任务的状态,包括任务的堆栈高水位线(高水位线数字越小,任务越接近堆栈溢出)。点击这里可以看到生成的输出示例。
  在ASCII表中,以下字母用来表示任务的状态。

  • ‘B’–阻塞的
  • ’R’- 准备就绪
  • ‘D’- 已删除(等待清理)。
  • ‘S’ - 暂停,或没有超时的阻塞
      vTaskList()是一个只为方便而提供的实用函数。它不被认为是内核的一部分。参见vTaskGetRunTimeStats(),该函数可以生成一个类似的运行时任务利用信息表。

参数:

  • pcWriteBuffer: 一个缓冲区,上述的细节将以ASCII形式写入其中。这个缓冲区被假定为足够大,以包含生成的报告。每个任务大约有40个字节应该足够了。

十三、任务开始跟踪vTaskStartTrace()

API原型:

void vTaskStartTrace( char * pcBuffer, unsigned long ulBufferSize );

  该功能与传统的跟踪工具有关--在FreeRTOS V7.1.0中被移除--用户可能会发现较新的Trace Hook Macros更容易使用,也更强大。
  启动一个RTOS内核活动跟踪。追踪记录了哪个任务在什么时候运行的身份。
  追踪文件是以二进制格式存储的。一个单独的DOS工具叫做convtrce.exe,用来将其转换为一个以制表符分隔的文本文件,可以在电子表格中查看和绘制。
参数:

  • pcBuffer: 将被写入跟踪的缓冲区。
  • ulBufferSize: pcBuffer的大小,字节数。追踪将持续到缓冲区满了,或者调用ulTaskEndTrace()。

十四、 任务结束追踪ulTaskEndTrace()

API原型:

unsigned long ulTaskEndTrace( void );

  [该功能与传统的跟踪工具有关--在FreeRTOS V7.1.0中被删除--用户可能会发现较新的Trace Hook Macros使用起来更方便、更强大。]
  停止一个RTOS内核活动跟踪。参见vTaskStartTrace()。
返回:
  已经写入跟踪缓冲区的字节数。

十五、获取任务运行时间统计信息vTaskGetRunTimeStats()

API原型:

void vTaskGetRunTimeStats( char *pcWriteBuffer );

  关于该功能的完整描述,请参见运行时间统计页面。
  configGENERATE_RUN_TIME_STATS、configUSE_STATS_FORMATTING_FUNCTIONS 和 configSUPPORT_DYNAMIC_ALLOCATION 都必须定义为 1 才能使用这个功能。然后,应用程序还必须提供portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()和portGET_RUN_TIME_COUNTER_VALUE的定义,以配置一个外设定时器/计数器,并分别返回定时器的当前计数值。计数器的频率应该至少是滴答计数的10倍。
  注意:这个函数将在其持续时间内禁用中断。它不打算用于正常的应用程序运行时,而是作为一种调试辅助工具。
  vTaskGetRunTimeStats()调用uxTaskGetSystemState(),然后将uxTaskGetSystemState()生成的原始数据格式化为人类可读的(ASCII)表格,显示每个任务在运行状态下花费的时间(每个任务消耗了多少CPU时间)。该数据以绝对值和百分比值的形式提供。绝对值的分辨率取决于应用程序提供的运行时间统计时钟的频率。
  vTaskGetRunTimeStats()是一个实用的函数,只为方便而提供。它不被认为是内核的一部分。参见vTaskList(),它是一个生成每个任务的状态信息的实用函数。
参数:

  • pcWriteBuffer: 一个缓冲区,执行时间将以ASCII形式写入其中。这个缓冲区被假定为足够大,以包含生成的报告。每个任务大约40个字节应该足够了。

返回:

十六、获取任务空闲运行时间计数器vTaskGetIdleRunTimeCounter()

API原型:

TickType_t xTaskGetIdleRunTimeCounter( void );

  返回空闲任务的运行时间计数器。这个函数可以用来确定空闲任务获得多少CPU时间。关于运行时间统计功能的完整描述,请参见运行时间统计页面。
  configGENERATE_RUN_TIME_STATS和INCLUDE_xTaskGetIdleTaskHandle必须都定义为1,这个函数才可用。然后,应用程序还必须提供portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()和portGET_RUN_TIME_COUNTER_VALUE的定义,以便分别配置外设的定时器/计数器和返回定时器的当前计数值。建议使定时器的频率至少是滴答计数的10倍。

十七、综合示例

示例代码:

/**
 * @file 4_Task_Utilities.c
 * @author WSP
 * @brief  调试任务实用工具
 * @version 0.1
 * @date 2022-10-08
 * 
 * @copyright Copyright (c) 2022
 * 
 */
#include "System_Include.h"

const static char * TAG = "Task_Parameter";
//  APP_task 任务的一些变量
TaskHandle_t APP_task_Utilities_handle = NULL;

// 根据宏定义来修改测试代码中不同部分
#define User_xTaskGetIdleRunTimeCounter    1

/**
 * @brief APP_task
 * @param arg 任务传入的参数
 * @return NULL
 */
void APP_task_Utilities(void * arg)
{
    
    
    while (1){
    
    
        vTaskDelay(1000/portTICK_PERIOD_MS);
        ESP_LOGI(TAG,"APP_task_Utilities");
    }
}
/**
 * @brief   创建函数初始化
 * @param   NULL
 * @return  NULL
 */
void Task_Utilities_Init(void)
{
    
    
    // 创建任务二
    xTaskCreate(APP_task_Utilities,             // 创建任务
                "Task_Utilities",           // 创建任务名
                2048,                           // 任务堆栈
                NULL,                           // 任务参数
                3 ,                             // 任务优先级
                &APP_task_Utilities_handle);    // 任务句柄
    vTaskDelay(5000/portTICK_PERIOD_MS);        // 延时等待

    while (1){
    
    
        #if User_uxTaskGetSystemState
            char *  pcWriteBuffer  = (char *)malloc (512);
            TaskStatus_t *pxTaskStatusArray ;                   // 与uxTaskGetSystemState()函数一起使用,返回每个任务的状态。
            volatile UBaseType_t uxArraySize, x;                // volatile确保本条指令不会被编译器的优化而忽略
            uint32_t ulTotalRunTime, ulStatsAsPercentage;       // 定义时间变量、百分比
            uxArraySize = uxTaskGetNumberOfTasks();             // 获取任务数量
            /* 为每个任务分配一个TaskStatus_t结构。 一个数组可以在编译时静态地分配。*/
            pxTaskStatusArray = pvPortMalloc(uxArraySize * sizeof( TaskStatus_t ));
            printf("------------------------ begin output task info----------------------------\n\r");
            if(pxTaskStatusArray != NULL){
    
    
                uxArraySize = uxTaskGetSystemState(pxTaskStatusArray, uxArraySize,&ulTotalRunTime);
                printf("\tuxArraySize:%d   RunTime:%u\n\r",uxArraySize,ulTotalRunTime);
                printf("\tfunction name:  ArraySize:          RunTime\n\r");
                if(ulTotalRunTime != 0){
    
    
                    for (x = 0; x < uxArraySize; x++){
    
    
                        /* 该任务使用了总运行时间的多少百分比?这将总是向下四舍五入到最接近的整数。ulTotalRunTimeDiv100已经被除以100了。*/
                        ulStatsAsPercentage = pxTaskStatusArray[x].ulRunTimeCounter / ulTotalRunTime;
                        if(ulStatsAsPercentage > 0){
    
    
                            printf("\t%s\t\t%d\t\t%u\n\r",
                                                    pxTaskStatusArray[x].pcTaskName,            //任务名
                                                    pxTaskStatusArray[x].ulRunTimeCounter,      //任务运行时间
                                                    ulStatsAsPercentage);                       //任务占用率
                        }
                        else{
    
    
                            /* 如果这里的百分比为零,那么该任务所消耗的时间不到总运行时间的1%。消耗的时间不到总运行时间的1%。*/
                            printf("\t%s\t\t%u\t\t\n\r",
                                                    pxTaskStatusArray[ x ].pcTaskName,          //任务名
                                                    pxTaskStatusArray[ x ].ulRunTimeCounter);   //任务运行时间
                        }
                    }
                }
            }
            free(pcWriteBuffer);
            vPortFree( pxTaskStatusArray );
            printf("------------------------ end output task info----------------------------\n\r\n\r");
        #elif   User_vTaskGetInfo   
            TaskHandle_t xHandle;
            TaskStatus_t xTaskDetails;
            xHandle = xTaskGetHandle("Task_Utilities");
            vTaskGetInfo(xHandle,&xTaskDetails,pdTRUE,eInvalid); //APP_task_Utilities_handle
            printf("pcTaskName:%s xTaskNumber:%d eCurrentState:%d uxCurrentPriority:%d uxBasePriority:%d usStackHighWaterMark:%d\n\r",  
                                                xTaskDetails.pcTaskName,
                                                xTaskDetails.xTaskNumber,
                                                xTaskDetails.eCurrentState,
                                                xTaskDetails.uxCurrentPriority,
                                                xTaskDetails.uxBasePriority,
                                                xTaskDetails.usStackHighWaterMark);
        #elif User_eTaskGetState
            // Typedef enum
            // {
    
    
            //     eRunning = 0,/* 一个任务正在查询自己的状态,所以必须正在运行。*/
            //     eReady,      /* 被查询的任务处于已读或待定的准备列表中。*/
            //     eBlocked,    /* 被查询的任务处于阻塞状态。*/
            //     eSuspended,  /* 被查询的任务处于暂停状态,或者处于无限期超时的阻塞状态。*/
            //     eDeleted,    /* 被查询的任务已被删除,但其TCB尚未被释放。*/
            //     eInvalid     /* 用作 "无效状态 "值。*/
            // } eTaskState;
            printf("Get Task State:%d\n\r",eTaskGetState(APP_task_Utilities_handle));   //获取任务状态
        #elif User_pcTaskGetName
            printf("Get Task Name:%s\n\r",pcTaskGetName(APP_task_Utilities_handle));    //获取任务名称
        #elif User_xTaskGetHandle
            TaskHandle_t Task_Utilities_Handle = xTaskGetHandle("Task_Utilities");      //获取任务句柄
            // 验证获取的句柄是否正确
            printf("Get Task Name:%s\n\r",pcTaskGetName(Task_Utilities_Handle));
        #elif User_xTaskGetTickCount
            printf("Get Task TickCount:%d\n\r",xTaskGetTickCount());                    //获取任务滴答计数
        #elif User_xTaskGetSchedulerState
             printf("Get Task Scheduler State:%d\n\r",xTaskGetSchedulerState());        //获取调度状态
        #elif User_uxTaskGetNumberOfTasks
            printf("Task Get Number Of Tasks:%d\n\r",uxTaskGetNumberOfTasks());
        #elif User_vTaskList
            printf("------------------------ begain vTaskList info----------------------------\n\r");
            char * vTaskList_Buffer = (char *)malloc(512);
            vTaskList(vTaskList_Buffer);
            printf(vTaskList_Buffer);
            free(vTaskList_Buffer);
            printf("------------------------ end vTaskList info----------------------------\n\r\n\r");
        #elif User_vTaskGetRunTimeStats
            printf("------------------------ begain vTaskGetRunTimeStats info----------------------------\n\r");
            char * vTaskList_Buffer = (char *)malloc(512);
            vTaskGetRunTimeStats(vTaskList_Buffer);         //获取任务运行时间统计信息
            printf(vTaskList_Buffer);
            free(vTaskList_Buffer);
            printf("------------------------ end vTaskGetRunTimeStats info----------------------------\n\r\n\r");
        #elif User_xTaskGetIdleRunTimeCounter
            printf("xTaskGetIdleRunTimeCounter:%u\n\r",xTaskGetIdleRunTimeCounter()); 
        #endif  
        // StartTask_Key(NULL);
        vTaskDelay(1000/portTICK_PERIOD_MS);
    }   
}

猜你喜欢

转载自blog.csdn.net/believe666/article/details/126803586
今日推荐