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
相关推荐
王的宝库17 分钟前
Linux 性能优化入门
linux·学习
公爵爱学习1 小时前
无人机定点飞行-介绍
开发语言·图像处理·python·学习·线性回归·无人机
浔溺1 小时前
al+大数据每日学习笔记33
大数据·笔记·学习
lifallen1 小时前
Agent 框架不是 API 包装器,而是一个微型操作系统内核
人工智能·学习·ai·ai编程
ACP广源盛139246256731 小时前
M6/M5 Pro Mac mini 端侧 AI 落地@ACP#IX6024 PCIe2.0 交换芯片在轻量化 AI 服务中的机会与应用场景
大数据·数据库·人工智能·嵌入式硬件·macos·开源
是隼人1 小时前
buuctf-pwn pwnable_start(ret2shellcode)题解(学习过程持续更新)
c语言·学习·安全·pwn入门·ctf入门
码力斜杠哥1 小时前
Docker Compose快速入门笔记
笔记·docker·eureka
my05921 小时前
跳出单一信息工具局限:奥米豆构建认知与心智并行的学习范式
大数据·人工智能·python·学习
却道天凉_好个秋2 小时前
音视频学习(一百零五):Access Unit (AU)和RTP分包
学习·音视频·access unit·rtp分包
知产xiao_xin2 小时前
版权的精神权利
经验分享·笔记·知识产权