FreeRTOS学习笔记-基于stm32(7)任务状态查询与任务时间统计API函数

1、FreeRTOS任务相关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() | 获取线程本地存储指针 |

2、任务相关API函数的使用

使用每个API函数的时候,都右键转到定义位置,如下图:

然后查看函数的使用条件,比如这个函数要使用的话必须将宏 INCLUDE_uxTaskPriorityGet 置1;

然后以同样的操作转到这个宏的位置将其置1。然后再开始调用API函数

如下为几个常用API函数的使用:

cs 复制代码
	uint8_t i=0;
	UBaseType_t priority_num=0;
	UBaseType_t task_num=0;
	UBaseType_t task_num2=0;
	TaskStatus_t * status_array=0;
	TaskStatus_t * status_array2=0;
	TaskHandle_t task_handle=0;
	UBaseType_t task_stack_min=0;
	eTaskState task_state=0;
	char pcWriteBuffer[300];
	
	//获取任务优先级
	priority_num = uxTaskPriorityGet( task2_handler );
	printf("task2的任务优先级=%ld\r\n",priority_num);
	
	//设置任务优先级
	vTaskPrioritySet( task2_handler,6 );
	priority_num = uxTaskPriorityGet( task2_handler );
	printf("task2的任务优先级=%ld\r\n",priority_num);
	
	//获取系统任务数量
	task_num = uxTaskGetNumberOfTasks();
	printf("系统任务数量=%ld\r\n",task_num);
	
	//获取系统所有任务的任务状态信息
	status_array=pvPortMalloc(sizeof(TaskStatus_t)*task_num);
	task_num2 = uxTaskGetSystemState(status_array,task_num,NULL);
	printf("任务名\t\t任务优先级\t\t任务编号\r\n");
	for(i=0;i<task_num2;i++){
		printf("%s\t\t%ld\t%ld\r\n",status_array[i].pcTaskName,
									status_array[i].uxCurrentPriority,
									status_array[i].xTaskNumber);
	}
	
	//获取指定任务的任务状态
	status_array2=pvPortMalloc(sizeof(TaskStatus_t));
	vTaskGetInfo(task2_handler,status_array2,pdTRUE,eInvalid);
	printf("任务名:%s\r\n",status_array2->pcTaskName);
	printf("任务优先级:%ld\r\n",status_array2->uxCurrentPriority);
	printf("任务编号:%ld\r\n",status_array2->xTaskNumber);
	printf("任务状态:%d\r\n",status_array2->eCurrentState);
	
	//根据任务名获取任务句柄
	task_handle = xTaskGetHandle("task2");
	printf("任务句柄为:%#x\r\n",(int)task_handle);
	printf("任务句柄为:%#x\r\n",(int)task2_handler);
	
	//查询某个任务的运行状态
	task_state = eTaskGetState(task2_handler);
	printf("task2的任务状态为%d\r\n",task_state);
	
	//获取系统中任务信息
	vTaskList(pcWriteBuffer);
	printf("%s\r\n",pcWriteBuffer);

3、任务时间统计API函数 vTaskGetRunTimeStats()

cs 复制代码
void vTaskGetRunTimeStats( char *pcWriteBuffer )

该函数与获取系统任务信息类似,参数是一个数组用来存放任务信息。如下代码是统计系统任务的运行时间并打印出来。

cs 复制代码
void task2( void * pvParameters )
{
	u8 key=0;
	while(1)
	{
		key=KEY_Scan(0);
		if(key==KEY1_PRES){
			vTaskGetRunTimeStats(pcWriteBuffer);
			printf("任务名\t\t\t运行时间\t运行所占百分比\r\n");
			printf("%s\r\n",pcWriteBuffer);
		}
		vTaskDelay(100);
	}
}

使用该函数需要注意的点:

1、需要将宏configGENERATE_RUN_TIME_STATS 置1;

2、需要将宏 configUSE_STATS_FORMATTING_FUNCTIONS 置1;

3、在将1完成后需要实现 portCONFIGURE_TIMER_FOdR_RUN_TIME_STATS() 宏和portGET_RUN_TIME_COUNTER_VALUE() 宏;

portCONFIGURE_TIMER_FOdR_RUN_TIME_STATS() 用来初始化用于配置任务运行时间统计的时基定时器,时基定时器的精度必须高于系统时钟节拍精度的10到100倍。系统时钟节拍如果是1ms,时基定时器节拍就得在10us到100us之间。

portGET_RUN_TIME_COUNTER_VALUE() 用于获取定时器计数的计数值。

定时器使用stm32的内部定时器3,在 ConfigureTimeForRunTimeStats() 中初始化定时器并配置为每10us中断一次,然后在中断服务函数中将 FreeRTOSRunTimeTicks++,从而达到计时的目的。宏的实现如下代码:

timer.c:

cs 复制代码
#include "timer.h"
#include "led.h"
#include "led.h"
#include "usart.h"

volatile unsigned long long FreeRTOSRunTimeTicks;

//初始化TIM3使其为FreeRTOS的时间统计提供时基
void ConfigureTimeForRunTimeStats(void)
{
	//定时器3初始化,定时器时钟为72M,分频系数为72-1,所以定时器3的频率
	//为72M/72=1M,自动重装载为10-1,那么定时器周期就是10us
	FreeRTOSRunTimeTicks=0;
	TIM3_Int_Init(10-1,72-1);	//初始化TIM3
}

//通用定时器3中断初始化
//这里时钟选择为APB1的2倍,而APB1为36M
//arr:自动重装值。
//psc:时钟预分频数
//这里使用的是定时器3!
void TIM3_Int_Init(u16 arr,u16 psc)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
	
	//定时器TIM3初始化
	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值	
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位
 
	TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断

	//中断优先级NVIC设置
	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 4;  //先占优先级4级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  //从优先级0级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
	NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器

	TIM_Cmd(TIM3, ENABLE);  //使能TIMx					 
}

//定时器3中断服务函数
void TIM3_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断
	{
		FreeRTOSRunTimeTicks++;
	}
	TIM_ClearITPendingBit(TIM3,TIM_IT_Update);  //清除中断标志位
}

timer.h:

cs 复制代码
#ifndef __TIMER_H
#define __TIMER_H
#include "sys.h" 

void ConfigureTimeForRunTimeStats(void);
extern volatile unsigned long long FreeRTOSRunTimeTicks;
void TIM3_Int_Init(u16 arr,u16 psc);
void TIM5_Int_Init(u16 arr,u16 psc);
#endif
相关推荐
努力小周39 分钟前
STM32智能安防系统
c语言·stm32·单片机·嵌入式硬件·物联网·计算机网络·pcb工艺
袁小皮皮不皮1 小时前
1.HCIP BFD 学习笔记(优化版)
服务器·网络·笔记·网络协议·学习·智能路由器·ip
装不满的克莱因瓶1 小时前
【自动驾驶领域】学习 Cityscapes 数据集——城市街景语义理解的标准基准
人工智能·pytorch·python·深度学习·学习·机器学习·自动驾驶
清辞8532 小时前
产品经理需求推进流程
大数据·深度学习·学习·产品经理
华科大胡子2 小时前
在STM32上跑通TinyML
stm32·单片机·嵌入式硬件
YM52e3 小时前
鸿蒙PC ArkTS 声明合并问题深度解析与最佳实践
学习·华为·harmonyos·鸿蒙·鸿蒙系统
海兰4 小时前
【实用程序】电商销售分析仪表盘 — 从零搭建一个AI参与的全栈数据洞察系统
人工智能·学习·算法
iCxhust4 小时前
C#进程管理程序
开发语言·汇编·stm32·单片机·c#·微机原理
ken22324 小时前
在 Libreoffice Calc中输入自定义表情字符时,需要保存之后,才能正常显示
学习
zwenqiyu4 小时前
P5283 [十二省联考 2019] 异或粽子题解
c++·学习·算法