【FreeRtos任务状态查询】

本文深入介绍了FreeRTOS中任务管理的相关API,包括任务优先级获取与设置、任务状态查询、堆栈使用情况检查等。通过示例代码展示了如何使用这些API来获取任务信息、检查任务状态以及获取系统整体运行状态。实验结果显示了任务的优先级、状态、堆栈使用情况等关键信息。
摘要由CSDN通过智能技术生成

FreeRtos任务状态查询


前言

本篇内容进行分享的是FreeRtos中其他任务API函数,并通过Demo对常用的API进行演示。


一、其他API函数介绍

在这里插入图片描述

1.uxTaskPriorityGet()

此函数用来获取指定任务的优先级,使用INCLUDE_uxTaskPriorityGet函数的话 应该定义为 1

//函数原型
 UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask )

在这里插入图片描述

参数:要查询任务的句柄
返回值:获取对应的任务优秀级

2.函数 vTaskPrioritySet()

此 函 数 用 于 改 变 某 一 个 任 务 的 任 务 优 先 级 , 要 使 用 此 函 数 的 话 宏INCLUDE_vTaskPrioritySet 应该定义为 1

在这里插入图片描述

//函数原型
 void vTaskPrioritySet( TaskHandle_t xTask,UBaseType_t uxNewPriority )

参数:要查找的任务的任务句柄
uxNewPriority: 任务要使用的新的优先级,可以是 0~ configMAX_PRIORITIES – 1
返回值:无

3.uxTaskGetSystemState()

此函数用于获取系统中所有任务的任务壮态,每个任务的壮态信息保存在一个 TaskStatus_t类型的结构体里面,这个结构体里面包含了任务的任务句柄、任务名字、堆栈、优先级等信息,要使用此函数的话宏 configUSE_TRACE_FACILITY 应该定义为 1。

//函数原型
 UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray,
                                      const UBaseType_t uxArraySize,
                                      uint32_t * const pulTotalRunTime )


参数:
pxTaskStatusArray: 指向 TaskStatus_t 结构体类型的数组首地址,每个任务至少需要一个
TaskStatus_t 结 构 体 , 任 务 的 数 量 可 以 使 用 函 数uxTaskGetNumberOfTasks()

uxArraySize: 保存任务壮态数组的数组的大小。 

pulTotalRunTime: 如果 configGENERATE_RUN_TIME_STATS 为 1 的话此参数用来保存系
统总的运行时间。 
 
返回值: 统计到的任务壮态的个数,也就是填写到数组 pxTaskStatusArray 中的个
数,此值应该等于函数 uxTaskGetNumberOfTasks()的返回值。如果参数
uxArraySize 太小的话返回值可能为 0

在这里插入图片描述

4.vTaskGetInfo()

此函数也是用来获取任务壮态的,但是是获取指定的单个任务的壮态的,任务的壮态信息填充到参数 pxTaskStatus 中,这个参数也是 TaskStatus_t 类型的。要使用此函数的话宏configUSE_TRACE_FACILITY 要定义为 1

//函数原型
 void vTaskGetInfo( TaskHandle_t xTask,
                       TaskStatus_t * pxTaskStatus,
                       BaseType_t xGetFreeStackSpace,
                       eTaskState eState )



参数: 
xTask: 要查找的任务的任务句柄。 
pxTaskStatus: 指向类型为 TaskStatus_t 的结构体变量。 
xGetFreeStackSpace: 在结构体 TaskStatus_t 中有个字段 usStackHighWaterMark 来保存自任务
运行以来任务堆栈剩余的历史最小大小,这个值越小说明越接近堆栈溢出,但是计算这个值需要花费一点时间, 所以我们可以通过将xGetFreeStackSpace设置为pdFALSE来跳过这个步骤,当设置为pdTRUE的时候就会检查堆栈的历史剩余最小值。 
eState: 结构体 TaskStatus_t 中有个字段 eCurrentState 用来保存任务运行壮态,
这个字段是 eTaskState 类型的,这是个枚举类型

在这里插入图片描述

5.函数 xTaskGetHandle()

此函数根据任务名字获取任务的任务句柄,在使用函数 xTaskCreate()或 xTaskCreateStatic()创建任务的时候都会给任务分配一个任务名,函数 xTaskGetHandle()就是使用这个任务名字来查询其对应的任务句柄的。要使用此函数的话宏 INCLUDE_xTaskGetHandle 应该设置为 1。

//函数原型
TaskHandle_t xTaskGetHandle( const char * pcNameToQuery )

pcNameToQuery: 任务名,C 语言字符串 也就是我们任务的名称
NULL: 没有任务名 pcNameToQuery 所对应的任务。 
其他值: 任务名 pcNameToQuery 所对应的任务句柄 

6.函数 uxTaskGetStackHighWaterMark()

每个任务都有自己的堆栈,堆栈的总大小在创建任务的时候就确定了,此函数用于检查任务从创建好到现在的历史剩余最小值,这个值越小说明任务堆栈溢出的可能性就越大!FreeRTOS 把这个历史剩余最小值叫做“高水位线”要使用此函数的话宏INCLUDE_uxTaskGetStackHighWaterMark 必须为 1。

//函数原型
 UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask )

xTask: 要查询的任务的任务句柄,当这个参数为 NULL 的话说明查询自身任务(即调用
函数 uxTaskGetStackHighWaterMark()的任务)的“高水位线”。 
 
返回值: 任务堆栈的“高水位线”值,也就是堆栈的历史剩余最小值

7.函数 eTaskGetState()

此函数用于查询某个任务的运行壮态,比如:运行态、阻塞态、挂起态、就绪态等,返回值是个枚举类型。
要使用此函数的话宏 INCLUDE_eTaskGetState 必须为 1

//函数原型
 eTaskState eTaskGetState( TaskHandle_t xTask )
xTask: 要查询的任务的任务句柄。 
 
返回值: 返回值为 eTaskState 类型,这是个枚举类型,在task.h有定义

8.函数 vTaskList()

此函数会创建一个表格来描述每个任务的详细信息
表中的信息如下:
Name: 创建任务的时候给任务分配的名字。
State: 任务的壮态信息,B 是阻塞态,R 是就绪态,S 是挂起态,D 是删除态。
Priority:任务优先级。
Stack: 任务堆栈的“高水位线”,就是堆栈历史最小剩余大小。
Num: 任务编号,这个编号是唯一的,当多个任务使用同一个任务名的时候可以通过此 编号来做区分。

//函数原型
 void vTaskList( char * pcWriteBuffer )
pcWriteBuffer: 保存任务壮态信息表的存储区。存储区要足够大来保存任务状态信息表。 
 
返回值: 无

二、demo API函数演示

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "FreeRTOS.h"
#include "task.h"


//任务优先级
#define START_TASK_PRIO		1
//任务堆栈大小	
#define START_STK_SIZE 		128  
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);

//任务优先级
#define LED0_TASK_PRIO		2
//任务堆栈大小	
#define LED0_STK_SIZE 		50  
//任务句柄
TaskHandle_t LED0Task_Handler;
//任务函数
void led0_task(void *pvParameters);

//任务优先级
#define QUERY_TASK_PRIO		3
//任务堆栈大小	
#define QUERY_STK_SIZE 		256
//任务句柄
TaskHandle_t QUERYTask_Handler;
//任务函数
void query_task(void *pvParameters);

char InfoBuffer[256];

int main(void)
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4	 
	delay_init();	    				//延时函数初始化	  
	uart_init(115200);					//初始化串口
	LED_Init();		  					//初始化LED
	 
	//创建开始任务
    xTaskCreate((TaskFunction_t )start_task,            //任务函数
                (const char*    )"start_task",          //任务名称
                (uint16_t       )START_STK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传递给任务函数的参数
                (UBaseType_t    )START_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&StartTask_Handler);   //任务句柄              
    vTaskStartScheduler();          //开启任务调度
}

//开始任务任务函数
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           //进入临界区
    //创建LED0任务
    xTaskCreate((TaskFunction_t )led0_task,     	
                (const char*    )"led0_task",   	
                (uint16_t       )LED0_STK_SIZE, 
                (void*          )NULL,				
                (UBaseType_t    )LED0_TASK_PRIO,	
                (TaskHandle_t*  )&LED0Task_Handler);   
    //创建LED1任务
    xTaskCreate((TaskFunction_t )query_task,     
                (const char*    )"query_task",   
                (uint16_t       )QUERY_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )QUERY_TASK_PRIO,
                (TaskHandle_t*  )&QUERYTask_Handler);         
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
}


void led0_task(void *pvParameters)
{

    while(1)
    {
  			
			LED0=~LED0;
       vTaskDelay(500);
			 // printf("led1 is running\r\n");
			
			
    }
}   

//query任务函数
void query_task(void *pvParameters)
{
  
	uint8_t i =0 ;
	uint32_t TotalRunTime;
	UBaseType_t Priority;
	TaskStatus_t *StatusArray;
	UBaseType_t  ArraySize;
	TaskHandle_t  TestHandler;  //查询任务的句柄
	
	
	UBaseType_t   MinStackSize;
	eTaskState    TaskState;  //任务状态

	//查询优秀级
	printf("----------------------任务优秀级--------------------\r\n");
	Priority = uxTaskPriorityGet(QUERYTask_Handler);  
	printf("Task Priority = %d\n",(int)Priority);
	

	printf("------------------------任务信息--------------------\r\n");
	//获取当前系统中存在的任务数量
	ArraySize = uxTaskGetNumberOfTasks();
	//为数组申请空间
	StatusArray = pvPortMalloc(ArraySize * sizeof(TaskStatus_t));         //分配内存
	if(NULL != StatusArray)   //内存申请成功后来获取信息
	{
		//获取系统中任务状态
		ArraySize  = 	uxTaskGetSystemState( (TaskStatus_t *) StatusArray,
                                      ( UBaseType_t )ArraySize,
                                      (uint32_t * ) &TotalRunTime );
		//统计完成后输出信息
		printf("TaskName\t\tPriority\t\tTaskNumber\t\t\r\n");
		for(i = 0;i< ArraySize;i++)
		{
			printf("%s\t\t%d\t\t%d\t\t\t\r\r\n",StatusArray[i].pcTaskName,
																					(int)StatusArray[i].uxCurrentPriority,
																					(int)StatusArray[i].xTaskNumber);
		
		}
		
	}

	printf("----------------------任务查找--------------------\r\n");
	//根据任务名字查找某个任务的句柄 
	TestHandler = xTaskGetHandle("query_task");
	printf("TestHandler = %#x\r\n",(unsigned int)TestHandler);
	printf("TestHandler = %#x\r\n",(unsigned int )QUERYTask_Handler);
	
	
	printf("----------------------任务状态--------------------\r\n");
	//获取某个任务的壮态,这个壮态是 eTaskState 类型。 
	TaskState = eTaskGetState(QUERYTask_Handler);
	printf("TaskState = %d\r\n",TaskState);
	
	
	//以一种表格的形式输出当前系统中所有任务的详细信息
	printf("----------------------任务信息--------------------\r\n");
	vTaskList(InfoBuffer);
	printf("%s\r\n",InfoBuffer);
	while(1)
    {
        LED1 = ~LED1;
		  	vTaskDelay(500);
			 //获取任务的堆栈的历史剩余最小值,FreeRTOS 中叫做“高水位线”
			printf("------------------任务高水位线----------------\r\n");
			  MinStackSize = uxTaskGetStackHighWaterMark(QUERYTask_Handler);
			  printf("MinStackSize = %d\r\n",(int)MinStackSize);
			  vTaskDelay(1000);
				//printf(1000);("led2 is running\r\n");
    }
}

实验结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小殷学长

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值