FreeRTOS专栏7:任务状态信息查询

任务状态相关API函数

1 获取任务优先级

测试代码如下:

#define LED_TASK_SIZE       128
#define LED_TASK_PRIO       2
TaskHandle_t led_task_Handle;

#define QUERY_TASK_SIZE     128
#define QUERY_TASK_PRIO     3
TaskHandle_t query_task_Handle;

void query_task(void *pvParameters)
{
  UBaseType_t task_priority;
  for (;;)
  {
    // 打印led任务优先级
    task_priority = uxTaskPriorityGet(led_task_Handle);
    printf("\nled_task priority = %d\n", task_priority);
    // 打印查询任务优先级
    task_priority = uxTaskPriorityGet(query_task_Handle);
    printf("query_task priority = %d\n", task_priority);
    vTaskDelay(500);
  }
}

结果如下所示:

2 修改任务优先级

用户尽量不要调用函数来这个修改优先级,供内核使用。

3 获取系统中所有任务的任务状态

测试程序:

void query_task(void *pvParameters)
{
  UBaseType_t task_priority;
  UBaseType_t i, arraySize;
  TaskStatus_t *StatusArray; // 定义任务状态指针
  uint32_t totalRunTime;

  /* 查询任务优先级 */
  task_priority = uxTaskPriorityGet(led_task_Handle); // 打印led任务优先级
  printf("\nled_task priority = %ld\n", task_priority);

  task_priority = uxTaskPriorityGet(query_task_Handle); // 打印查询任务优先级
  printf("query_task priority = %ld\n", task_priority);

  arraySize = uxTaskGetNumberOfTasks();                         // 获取任务个数
  StatusArray = pvPortMalloc(arraySize * sizeof(TaskStatus_t)); // 指针分配内存
  /* 内存分配成功 */
  if (StatusArray != NULL)
  {
    arraySize = uxTaskGetSystemState((TaskStatus_t *)StatusArray,
                                     (UBaseType_t)arraySize,
                                     (uint32_t *)&totalRunTime);

    printf("TaskName\t\tPriority\t\tTaskNumber\t\tStackHighWater\t\t\r\n");
    for (i = 0; i < arraySize; i++)
    {
      // 串口打印出获取到的系统任务有关信息:如任务名称、任务优先级、任务编号、剩余堆栈
      printf("%s\t\t%d\t\t\t%d\t\t\t%d\t\t\t\r\n",
             StatusArray[i].pcTaskName,
             StatusArray[i].uxCurrentPriority,
             StatusArray[i].xTaskNumber,
             StatusArray[i].usStackHighWaterMark);
    }
    vPortFree(StatusArray);
  }

  for (;;)
  {
    vTaskDelay(500);
  }
}

主要就是创建指针+申请内存+获取任务状态+释放内存,测试结果如下:

任务编号就是创建任务的顺序,可以看到,开始任务时第一个创建的任务,编号为1;空闲任务再任务调度器中创建,编号为2;开始任务调度后,在开始任务函数主体中分别创建led_task(编号3)和query_task(编号4)。由于query_task中运行的代码比较多,该任务的剩余堆栈也比较少,能够方便我们进行调试。

4 获取单个任务状态

测试程序:

// 查询单个任务状态信息
TaskStatus_t test_task_status;
printf("\n************查询单个任务的状态信息**************\n");
vTaskGetInfo(query_task_Handle, &test_task_status, !pdFALSE, eInvalid);
printf("任务名                  %s\n", test_task_status.pcTaskName);
printf("任务编号                %d\n", test_task_status.xTaskNumber);
printf("任务状态                %d\n", test_task_status.eCurrentState);
printf("任务当前优先级          %d\n", test_task_status.uxCurrentPriority);
printf("任务堆栈基地址          %p\n", test_task_status.pxStackBase);
printf("任务历史剩余堆栈        %d\n", test_task_status.usStackHighWaterMark);

程序执行结果:

5 获取当前任务的任务句柄

6 根据任务名字获取任务句柄 / 获取空闲任务句柄

7 获取任务的历史剩余堆栈大小(水位线)

8 查询任务的运行状态

测试程序:

// 通过任务名查询任务句柄
TaskHandle_t testHandle;
testHandle = xTaskGetHandle("query_task");

printf("\n************通过任务名查询任务句柄**************\n");
printf("test_handle = %p\n", testHandle);
printf("query_task_handle = %p\n", query_task_Handle);

printf("\n************查询任务历史剩余堆栈大小**************\n");
UBaseType_t left_stack;
left_stack = uxTaskGetStackHighWaterMark(query_task_Handle); // 获取剩余堆栈
printf("query_task left %ld stack\n", left_stack);

printf("\n*****************查询任务状态*******************\n");
eTaskState task_state;
task_state = eTaskGetState(led_task_Handle);
printf("led_task state = %d\n", task_state);

task_state = eTaskGetState(query_task_Handle);
printf("query_task state = %d\t", task_state);

switch (task_state)
{
case eRunning:
  printf("running\n");
  break;

case eReady:
  printf("ready\n");
  break;

case eBlocked:
  printf("blocked\n");
  break;

case eSuspended:
  printf("suspended\n");
  break;

case eDeleted:
  printf("deleted\n");
  break;

case eInvalid:
  printf("invalid\n");
  break;

default:
  break;
}

程序运行结果:

9 获取任务调度器状态

10 获取系统当前存在的任务个数

11 任务列表打印函数

测试程序:

// 测试打印列表函数
printf("\n*****************测试列表打印函数*******************\n");
char *plist;
plist = pvPortMalloc(1024 * 2 * sizeof(char));  // 申请1024 * 2字节内存
vTaskList(plist);
printf("%s", plist);
vPortFree(plist);     // 释放内存

测试结果:

全部测试程序:

void query_task(void *pvParameters)
{
  UBaseType_t task_priority;
  UBaseType_t i, arraySize;
  TaskStatus_t *StatusArray; // 定义任务状态指针
  uint32_t totalRunTime;

  /* 查询任务优先级 */
  printf("\n**************查询任务优先级****************\n");
  task_priority = uxTaskPriorityGet(led_task_Handle); // 打印led任务优先级
  printf("led_task priority = %ld\n", task_priority);

  task_priority = uxTaskPriorityGet(query_task_Handle); // 打印查询任务优先级
  printf("query_task priority = %ld\n", task_priority);

  arraySize = uxTaskGetNumberOfTasks();                         // 获取任务个数
  StatusArray = pvPortMalloc(arraySize * sizeof(TaskStatus_t)); // 指针分配内存
  /* 内存分配成功 */
  if (StatusArray != NULL)
  {
    arraySize = uxTaskGetSystemState((TaskStatus_t *)StatusArray,
                                     (UBaseType_t)arraySize,
                                     (uint32_t *)&totalRunTime);

    printf("\n**************获取任务有关信息****************\n");
    printf("TaskName\t\tPriority\t\tTaskNumber\t\tStackHighWater\t\t\r\n");
    for (i = 0; i < arraySize; i++)
    {
      // 串口打印出获取到的系统任务有关信息:如任务名称、任务优先级、任务编号、剩余堆栈
      printf("%s\t\t%d\t\t\t%d\t\t\t%d\t\t\t\r\n",
             StatusArray[i].pcTaskName,
             StatusArray[i].uxCurrentPriority,
             StatusArray[i].xTaskNumber,
             StatusArray[i].usStackHighWaterMark);
    }
    vPortFree(StatusArray);
  }

  // 查询单个任务状态信息
  TaskStatus_t test_task_status;
  printf("\n************查询单个任务的状态信息**************\n");
  vTaskGetInfo(query_task_Handle, &test_task_status, !pdFALSE, eInvalid);
  printf("任务名                  %s\n", test_task_status.pcTaskName);
  printf("任务编号                %d\n", test_task_status.xTaskNumber);
  printf("任务状态                %d\n", test_task_status.eCurrentState);
  printf("任务当前优先级          %d\n", test_task_status.uxCurrentPriority);
  printf("任务堆栈基地址          %p\n", test_task_status.pxStackBase);
  printf("任务历史剩余堆栈        %d\n", test_task_status.usStackHighWaterMark);

  // 通过任务名查询任务句柄
  TaskHandle_t testHandle;
  testHandle = xTaskGetHandle("query_task");

  printf("\n************通过任务名查询任务句柄**************\n");
  printf("test_handle = %p\n", testHandle);
  printf("query_task_handle = %p\n", query_task_Handle);

  printf("\n************查询任务历史剩余堆栈大小**************\n");
  UBaseType_t left_stack;
  left_stack = uxTaskGetStackHighWaterMark(query_task_Handle); // 获取剩余堆栈
  printf("query_task left %ld stack\n", left_stack);

  printf("\n*****************查询任务状态*******************\n");
  eTaskState task_state;
  task_state = eTaskGetState(led_task_Handle);
  printf("led_task state = %d\n", task_state);

  task_state = eTaskGetState(query_task_Handle);
  printf("query_task state = %d\t", task_state);

  switch (task_state)
  {
  case eRunning:
    printf("running\n");
    break;

  case eReady:
    printf("ready\n");
    break;

  case eBlocked:
    printf("blocked\n");
    break;

  case eSuspended:
    printf("suspended\n");
    break;

  case eDeleted:
    printf("deleted\n");
    break;

  case eInvalid:
    printf("invalid\n");
    break;

  default:
    break;
  }

  // 测试打印列表函数
  printf("\n*****************测试列表打印函数*******************\n");
  char *plist;
  plist = pvPortMalloc(1024 * 2 * sizeof(char));  // 申请1024 * 2字节内存
  vTaskList(plist);
  printf("%s", plist);
  vPortFree(plist);     // 释放内存

  for (;;)
  {
    vTaskDelay(1000);
  }
}

测试结果如下所示:

发布了184 篇原创文章 · 获赞 100 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/dingyc_ee/article/details/104080243