FreeRTOS学习(五) 任务相关API函数

声明及感谢: 跟随正点原子资料学习, 在此作为学习的记录和总结
环境 keil , stm32f103

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. UBaseType_t uxTaskPriorityGet( TaskHandle_t xTask ) // 获取某个任务的优先级
参数: xTask 传入任务句柄

	unsigned portBASE_TYPE Priority;
	Priority = uxTaskPriorityGet(Led0Task_Handler);  

// 打印 Priority 即可看到 Led0Task_Handler 任务的优先级

2. vTaskPrioritySet()
设置任务的优先级

	vTaskPrioritySet(Led0Task_Handler, 10);

// 给 Led0Task_Handler 任务句柄的任务设置优先级为10;
// 可以使用步骤1查看任务修改后的优先级.

3.uxTaskGetSystemState
// 获取系统所有任务的状态.

	u32 TotalRunTime;               // 系统总运行时间
	UBaseType_t ArraySize,x; // 
	TaskStatus_t *StatusArray;

ArraySize = uxTaskGetNumberOfTasks();		// 获取系统任务数量
StatusArray = pvPortMalloc(ArraySize*sizeof(TaskStatus_t));  // 申请内存

	if(StatusArray!=NULL)					// 内存申请成功
	{
		ArraySize=uxTaskGetSystemState((TaskStatus_t* 	)StatusArray, 	// 任务信息存储区域地址
									   (UBaseType_t		)ArraySize, 	//  任务信息数组大小
								       (uint32_t*		)&TotalRunTime); // 系统运行总时间

		for(x=0;x<ArraySize;x++)
		{
			printf("%s\t\t%d\t\t\t%d\t\t\t\r\n",				
					StatusArray[x].pcTaskName,               // 打印任务名称
					(int)StatusArray[x].uxCurrentPriority,   // 任务优先级  程序员定义决定
					(int)StatusArray[x].xTaskNumber);      // 任务编号, 由任务创建先后顺序决定
			
		}
	}

可以看出任务的信息主要类型 主要看 TaskStatus_t 类型的结构体成员. 观察成员, 即可 知道可以了解什么信息.
注意,这个函数仅用来调试用,调用此函数会挂起所有任务,直到函数最后才恢复挂起的任务,因此任务可能被挂起很长时间。在文件FreeRTOSConfig.h中,宏configUSE_TRACE_FACILITY必须设置为1,此函数才有效。

4.vTaskGetInfo():获取某个任务信息

/*
* TaskHandle_t xTaskGetHandle( const char *pcNameToQuery )
* void vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, 
*                    BaseType_t xGetFreeStackSpace, eTaskState eState )
*/
TaskHandle_t TaskHandle;    
TaskStatus_t TaskStatus;

TaskHandle=xTaskGetHandle("led0_task");         //根据任务名获取任务句柄

//获取LED0_Task的任务信息
vTaskGetInfo((TaskHandle_t  )TaskHandle,        //任务句柄
             (TaskStatus_t* )&TaskStatus,       //任务信息结构体
             (BaseType_t    )pdTRUE,            //允许统计任务堆栈历史最小剩余大小
             (eTaskState    )eInvalid);         //函数自己获取任务运行壮态

printf("任务名:                %s\r\n",TaskStatus.pcTaskName);
printf("任务编号:              %d\r\n",(int)TaskStatus.xTaskNumber);
printf("任务壮态:              %d\r\n",TaskStatus.eCurrentState);
printf("任务当前优先级:        %d\r\n",(int)TaskStatus.uxCurrentPriority);
printf("任务基优先级:          %d\r\n",(int)TaskStatus.uxBasePriority);
printf("任务堆栈基地址:        %#x\r\n",(int)TaskStatus.pxStackBase);
printf("任务堆栈历史剩余最小值: %d\r\n",TaskStatus.usStackHighWaterMark);

// 实验现象
任务名:                led0_task
任务编号:              4
任务壮态:              2
任务当前优先级:         2
任务基优先级:           2
任务堆栈基地址:         0x200012e8
任务堆栈历史剩余最小值:  108

5.eTaskGetState
// 获取某个任务的状态

eTaskState TaskState;
TaskState=eTaskGetState(TaskHandle);    // 传参是 任务句柄

返回值为 此枚举类型
typedef enum
{
eRunning = 0, // 运行
eReady, // 就绪
eBlocked, // 阻塞
eSuspended, // 暂停
eDeleted, // 删除
eInvalid // 无效的
} eTaskState;

6.vTaskList():
以一种表格的形式输出当前系统中所有任务的详细信息

char InfoBuffer[1000];
vTaskList(InfoBuffer);	    // 获取系统任务的信息保存在InfoBuffer 数组中 

打印 InfoBuffer 会看到如下信息
query_task R 3 192 5
IDLE R 0 108 2
led0_task B 2 108 4
Tmr Svc S 31 236 3

信息中每一列代表含义
任务名称 任务状态 任务优先级 任务剩余堆栈大小 任务编号

使用此功能需要 将这两个宏定义
configUSE_TRACE_FACILITY 1
configUSE_STATS_FORMATTING_FUNCTIONS 1

最后 在任务状态中
R 表示 就绪
B 表示 阻塞
S 表示 暂停

7.xTaskGetHandle()
// 根据任务名称获取任务句柄
TaskHandle_t TaskHandle;
TaskHandle=xTaskGetHandle(“query_task”); // 参数传入任务名称 ,返回值 为任务句柄

8.vTaskGetRunTimeStats
统计任务的运行时间信息

要使用此函数的话需要将
configGENERATE_RUN_TIME_STATS 和 configUSE_STATS_FORMATTING_FUNCTIONS
的宏定义定为1.

需要实现 两个宏
portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()
portGET_RUN_TIME_COUNTER_VALUE()

// 首先注意这两个宏虽然不需要传参数, 但是需要括号的。
portCONFIGURE_TIMER_FOR_RUN_TIME_STATS 这个宏用来初始化时间统计功能所需的时基, 一般是定时器/计数器。
这个时钟时基比系统时钟高10~20倍。
portGET_RUN_TIME_COUNTER_VALUE 这个宏 是当前时基的值。
示例:
宏定义设置

#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()  ConfigureTimeForRunTimeStats() //  定时器3 提供时间统计的时基, 频率为20K                                    即周期为50us
#define portGET_RUN_TIME_COUNTER_VALUE()		FreeRTOSRunTimeTicks	// 获取时间统计值 ,一个全局变量

宏定义实现

// FreeRTOS时间统计所有的节拍计数器
volatile unsigned long long FreeRTOSRunTimeTicks;   // 使用 unsigned long long 防止溢出

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

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

具体使用

// 在任务中使用
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("%s\r\n",RunTimeInfo);  // 打印出信息
		}
		vTaskDelay(10);                        // 延时10ms
	}
}

// 串口输出信息

在这里插入图片描述
一共三列, 分别表示 任务名称, 任务运行时间。 运行所占百分比
在运行时间中,需要将其值 * 时基

vTaskGetRunTimeStats 此功能只能在调式阶段使用, 因为实现此功能较占系统时间。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值