FreeRTOS任务查询和信息统计API函数(四)

FreeRTOS学习总结


前言

这节我们来学习辅助有关的API函数


提示:以下是本篇文章正文内容,下面案例可供参考

一、其他API函数合集

在这里插入图片描述

uxTaskPriorityGet() 查询某个任务的优先级。 vTaskPrioritySet() 改变某个任务的任务优先级。
uxTaskGetSystemState() 获取系统中任务状态。
vTaskGetInfo() 获取某个任务信息。
xTaskGetApplicationTaskTag() 获取某个任务的标签(Tag)值。 xTaskGetCurrentTaskHandle() 获取当前正在运行的任务的任务句柄。
xTaskGetHandle() 根据任务名字查找某个任务的句柄
xTaskGetIdleTaskHandle() 获取空闲任务的任务句柄。
uxTaskGetStackHighWaterMark()
获取任务的堆栈的历史剩余最小值,FreeRTOS 中叫做“高
水位线”
eTaskGetState() 获取某个任务的壮态,这个壮态是 eTaskState 类型。
pcTaskGetName() 获取某个任务的任务名字。
xTaskGetTickCount() 获取系统时间计数器值。
xTaskGetTickCountFromISR() 在中断服务函数中获取时间计数器值
xTaskGetSchedulerState() 获取任务调度器的壮态,开启或未开启。
uxTaskGetNumberOfTasks() 获取当前系统中存在的任务数量。
vTaskList()
以一种表格的形式输出当前系统中所有任务的详细信
息。
vTaskGetRunTimeStats() 获取每个任务的运行时间。
vTaskSetApplicationTaskTag() 设置任务标签(Tag)值。
SetThreadLocalStoragePointer() 设置线程本地存储指针
GetThreadLocalStoragePointer() 获取线程本地存储指针

二、函数详解

1.函数 uxTaskPriorityGet()

此函数用来获取指定任务的优先级,要使用此函数的话宏 INCLUDE_uxTaskPriorityGet
该定义为 1,函数原型如下:

UBaseType_t uxTaskPriorityGet( TaskHandle_t xTask )

参数:xTask: 要查找的任务的任务句柄。
返回值: 获取到的对应的任务的优先级。

2.函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()。

结构体 TaskStatus_t 在文件 task.h 中有如下
定义:

typedef struct xTASK_STATUS
{
TaskHandle_t xHandle; //任务句柄
const char * pcTaskName; //任务名字
UBaseType_t xTaskNumber; //任务编号
eTaskState eCurrentState; //当前任务壮态,eTaskState 是一个枚举类型
UBaseType_t uxCurrentPriority; //任务当前的优先级
UBaseType_t uxBasePriority; //任务基础优先级
uint32_t ulRunTimeCounter;//任务运行的总时间
StackType_t * pxStackBase; //堆栈基地址
uint16_t usStackHighWaterMark;//从任务创建以来任务堆栈剩余的最小大小,此
//值如果太小的话说明堆栈有溢出的风险。
} TaskStatus_t;

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

二、任务运行时间统计实践

***注意:***计时任务时间,不用系统时钟,比较慢,用定时器
在这里插入图片描述
在这里插入图片描述

1.函数vTaskGetRunTimeStats()

FreeRTOS 可以通过相关的配置来统计任务的运行时间信息,任务的运行时间信息提供了
每个任务获取到 CPU 使用权总的时间。函数 vTaskGetRunTimeStats()会将统计到的信息填充到
一个表里面,表里面提供了每个任务的运行时间和其所占总时间的百分比。
在这里插入图片描述
使用这个函数并不是简单的调用, 要 使 用 此 函 数 的 话 宏
configGENERATE_RUN_TIME_STATS 和 configUSE_STATS_FORMATTING_FUNCTIONS 必须
都为 1。如果宏 configGENERATE_RUN_TIME_STATS 为 1 的话还需要实现一下几个宏定义:
● portCONFIGURE_TIMER_FOR_RUN_TIME_STATS(),此宏用来初始化一个外设来
提供时间统计功能所需的时基,一般是定时器/计数器。这个时基的分辨率一定要比 FreeRTOS
的系统时钟高,一般这个时基的时钟精度比系统时钟的高 10~20 倍就可以了。

● portGET_RUN_TIME_COUNTER_VALUE()或者
portALT_GET_RUN_TIME_COUNTER_VALUE(Time),这两个宏实现其中一个就行
了,这两个宏用于提供当前的时基的时间值。

void vTaskGetRunTimeStats( char *pcWriteBuffer )

参数:
pcWriteBuffer: 保存任务时间信息的存储区。存储区要足够大来保存任务时间信息。
宏的定义:
在这里插入图片描述
char RunTimeInfo[400]; //保存任务运行时间
调用函数vTaskGetRunTimeStats(RunTimeInfo)
代码展示:

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "timer.h"
#include "key.h"
#include "string.h"
#include "FreeRTOS.h"
#include "task.h"
/************************************************
 ALIENTEK ¾«Ó¢STM32F103¿ª·¢°å FreeRTOSʵÑé11-2
 FreeRTOSÈÎÎñÔËÐÐʱ¼äͳ¼Æ-¿âº¯Êý°æ±¾
 ¼¼ÊõÖ§³Ö£ºwww.openedv.com
 ÌÔ±¦µêÆÌ£ºhttp://eboard.taobao.com 
 ¹Øע΢ÐŹ«ÖÚƽ̨΢Ðźţº"ÕýµãÔ­×Ó"£¬Ãâ·Ñ»ñÈ¡STM32×ÊÁÏ¡£
 ¹ãÖÝÊÐÐÇÒíµç×ӿƼ¼ÓÐÏÞ¹«Ë¾  
 ×÷ÕߣºÕýµãÔ­×Ó @ALIENTEK
************************************************/

//ÈÎÎñÓÅÏȼ¶
#define START_TASK_PRIO		1
//ÈÎÎñ¶ÑÕ»´óС	
#define START_STK_SIZE 		128  
//ÈÎÎñ¾ä±ú
TaskHandle_t StartTask_Handler;
//ÈÎÎñº¯Êý
void start_task(void *pvParameters);

//ÈÎÎñÓÅÏȼ¶
#define TASK1_TASK_PRIO		2
//ÈÎÎñ¶ÑÕ»´óС	
#define TASK1_STK_SIZE 		128  
//ÈÎÎñ¾ä±ú
TaskHandle_t Task1Task_Handler;
//ÈÎÎñº¯Êý
void task1_task(void *pvParameters);

//ÈÎÎñÓÅÏȼ¶
#define TASK2_TASK_PRIO		3
//ÈÎÎñ¶ÑÕ»´óС	
#define TASK2_STK_SIZE 		128  
//ÈÎÎñ¾ä±ú
TaskHandle_t Task2Task_Handler;
//ÈÎÎñº¯Êý
void task2_task(void *pvParameters);

//ÈÎÎñÓÅÏȼ¶
#define RUNTIMESTATS_TASK_PRIO	4
//ÈÎÎñ¶ÑÕ»´óС	
#define RUNTIMESTATS_STK_SIZE 	128  
//ÈÎÎñ¾ä±ú
TaskHandle_t RunTimeStats_Handler;
//ÈÎÎñº¯Êý
void RunTimeStats_task(void *pvParameters);

char RunTimeInfo[400];		//±£´æÈÎÎñÔËÐÐʱ¼äÐÅÏ¢


int main(void)
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//ÉèÖÃϵͳÖжÏÓÅÏȼ¶·Ö×é4	 
	delay_init();	    				//ÑÓʱº¯Êý³õʼ»¯	 
	uart_init(115200);					//³õʼ»¯´®¿Ú
	LED_Init();		  					//³õʼ»¯LED
	KEY_Init();							//³õʼ»¯°´¼ü

	
	//´´½¨¿ªÊ¼ÈÎÎñ
    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();           //½øÈëÁÙ½çÇø
    //´´½¨TASK1ÈÎÎñ
    xTaskCreate((TaskFunction_t )task1_task,             
                (const char*    )"task1_task",           
                (uint16_t       )TASK1_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )TASK1_TASK_PRIO,        
                (TaskHandle_t*  )&Task1Task_Handler);   
    //´´½¨TASK2ÈÎÎñ
    xTaskCreate((TaskFunction_t )task2_task,     
                (const char*    )"task2_task",   
                (uint16_t       )TASK2_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )TASK2_TASK_PRIO,
                (TaskHandle_t*  )&Task2Task_Handler); 
	//´´½¨RunTimeStatsÈÎÎñ
	xTaskCreate((TaskFunction_t )RunTimeStats_task,     
                (const char*    )"RunTimeStats_task",   
                (uint16_t       )RUNTIMESTATS_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )RUNTIMESTATS_TASK_PRIO,
                (TaskHandle_t*  )&RunTimeStats_Handler); 
    vTaskDelete(StartTask_Handler); //ɾ³ý¿ªÊ¼ÈÎÎñ
    taskEXIT_CRITICAL();            //Í˳öÁÙ½çÇø
}

//task1ÈÎÎñº¯Êý
void task1_task(void *pvParameters)
{
	u8 task1_num=0;

	while(1)
	{
		task1_num++;	//ÈÎÎñÖ´1ÐдÎÊý¼Ó1 ×¢Òâtask1_num1¼Óµ½255µÄʱºò»áÇåÁ㣡£¡
		LED0=!LED0;
        vTaskDelay(1000);                           //ÑÓʱ1s£¬Ò²¾ÍÊÇ1000¸öʱÖÓ½ÚÅÄ	
	}
}

//task2ÈÎÎñº¯Êý
void task2_task(void *pvParameters)
{
	u8 task2_num=0;
	
	while(1)
	{
		task2_num++;	//ÈÎÎñ2Ö´ÐдÎÊý¼Ó1 ×¢Òâtask1_num2¼Óµ½255µÄʱºò»áÇåÁ㣡£¡
        LED1=!LED1;
        vTaskDelay(1000);                           //ÑÓʱ1s£¬Ò²¾ÍÊÇ1000¸öʱÖÓ½ÚÅÄ	
	}
}

//RunTimeStatsÈÎÎñ
void RunTimeStats_task(void *pvParameters)
{
	u8 key=0;
	while(1)
	{
		key=KEY_Scan(0);
		if(key==WKUP_PRES)
		{
			memset(RunTimeInfo,0,400);				//ÐÅÏ¢»º³åÇøÇåÁã
			vTaskGetRunTimeStats(RunTimeInfo);		//»ñÈ¡ÈÎÎñÔËÐÐʱ¼äÐÅÏ¢
			printf("ÈÎÎñÃû\t\t\tÔËÐÐʱ¼ä\tÔËÐÐËùÕ¼°Ù·Ö±È\r\n");
			printf("%s\r\n",RunTimeInfo);
		}
		vTaskDelay(10);                           	//ÑÓʱ10ms£¬Ò²¾ÍÊÇ1000¸öʱÖÓ½ÚÅÄ	
	}
}




总结

今天又学了一个FreeRTOS任务管理API的辅助函数,它可以更加方便的调试和管理代码,但要注意,在任务运行时间统计实验中,注意数据存储的大小。
加油!!!

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值