FreeRTOS任务相关API函数
函数 | 描述 |
uxTaskPriorityGet() | 获取任务优先级 |
vTaskPrioritySet() | 设置任务优先级 |
uxTaskGetNumberOfTasks() | 获取系统中任务的数量 |
uxTaskGetSystemState() | 获取所有任务状态信息 |
vTaskGetInfo() | 获取指定单个的任务信息 |
xTaskGetCurrentTaskHandle() | 获取当前任务的任务句柄 |
xTaskGetHandle() | 根据任务名获取该任务的任务句柄 |
uxTaskGetStackHighWaterMark() | 获取任务的任务栈历史剩余最小值 |
eTaskGetState() | 获取任务状态 |
vTaskList() | 以“表格”形式获取所有任务的信息 |
vTaskGetRunTimeStats() | 获取任务的运行时间 |
uxTaskPriorityGet ( )
UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask);
此函数用于获取指定任务的任务优先级,使用该函数需将
宏 INCLUDE_uxTaskPriorityGet 置 1
参数 | xTask | 要查找的任务句柄,NULL代表任务自身 |
返回值 | UBaseType_t (整数) | 任务优先级数值 |
vTaskPrioritySet ( )
void vTaskPrioritySet( TaskHandle_t xTask , UBaseType_t uxNewPriority );
此函数用于改变某个任务的任务优先级,使用该函数需将
宏 INCLUDE_vTaskPrioritySet 为 1
形参 | 描述 |
xTask | 任务句柄,NULL代表任务自身 |
uxNewPriority | 需要设置的任务优先级 |
uxTaskGetNumberOfTasks ( )
UBaseType_t uxTaskGetNumberOfTasks( void );
此函数用于获取系统中任务的任务数量
返回值 | 描述 |
整型 | 系统中任务的数量 |
uxTaskGetSystemState ( )
UBaseType_t uxTaskGetSystemState(TaskStatus_t * const pxTaskStatusArray,
const UBaseType_t uxArraySize,
configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime );
此函数用于获取系统中所有任务的任务状态信息,使用该函数需将
宏 configUSE_TRACE_FACILITY 置 1
形参 | 描述 |
xTaskStatusArray | 指向TaskStatus_t 结构体数组首地址 |
uxArraySize | 接收信息的数组大小 |
pulTotalRunTime | 系统总运行时间,为NULL 则省略总运行时间值 |
返回值 | 描述 |
整型 | 获取信息的任务数量 |
vTaskGetInfo ( )
void vTaskGetInfo(TaskHandle_t xTask,
TaskStatus_t * pxTaskStatus,
BaseType_t xGetFreeStackSpace,
eTaskState eState ) ;
此函数用于获取指定的单个任务的状态信息,使用该函数需将
宏 configUSE_TRACE_FACILITY 置 1
形参 | 描述 |
xTask | 指定获取信息的任务的句柄 |
pxTaskStatus | 接收任务信息的变量 |
xGetFreeStackSpace | 任务栈历史剩余最小值, 当为“pdFALSE” 则跳过这个步骤, 当为“pdTRUE”则检查历史剩余最小堆栈 |
eState | 任务状态,可直接赋值,如想获取代入“eInvalid” |
任务状态
typedef enum
{
eRunning = 0, /* 运行态 */
eReady /* 就绪态 */
eBlocked, /* 阻塞态 */
eSuspended, /* 挂起态 */
eDeleted, /* 任务被删除 */
eInvalid /* 无效 */
} eTaskState
xTaskGetCurrentTaskHandle ( )
TaskHandle_t xTaskGetCurrentTaskHandle(void);
此函数用于获取当前任务的任务句柄, 使用该函数需将宏 INCLUDE_xTaskGetCurrentTaskHandle 置 1
返回值 | 描述 |
TaskHandle_t | 当前任务的任务句柄 |
xTaskGetHandle ( )
TaskHandle_t xTaskGetHandle(const char * pcNameToQuery);
此函数用于通过任务名获取任务句柄 , 使用该函数需将
宏 INCLUDE_xTaskGetHandle 置 1
形参 | 描述 |
pcNameToQuery | 任务名 |
返回值 | 描述 |
TaskHandle | 任务句柄 |
uxTaskGetStackHighWaterMark ( )
UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask );
此函数用于获取指定任务的任务栈历史最小剩余堆栈;使用该函数需将
宏 INCLUDE_uxTaskGetStackHighWaterMark 置 1
形参 | 描述 |
xTask | 任务句柄 |
返回值 | 描述 |
UBaseType_t | 任务栈的历史剩余最小值 |
eTaskGetState ( )
eTaskState eTaskGetState(TaskHandle_t xTask);
此函数用于查询某个任务的运行状态,使用此函数需
将宏 INCLUDE_eTaskGetState 置1
形参 | 描述 |
xTask | 待获取状态任务的任务句柄 |
返回值 | 描述 |
eTaskState | 任务状态 |
vTaskList ( )
void vTaskList(char * pcWriteBuffer);
此函数用于以 “表格” 的形式获取系统中任务的信息 ;使用此函数需
将宏 configUSE_TRACE_FACILITY 和configUSE_STATS_FORMATTING_FUNCTIONS 置1
形参 | 描述 |
pcWriteBuffer | 接收任务信息的缓存指针 |
Name : 创建任务的时候给任务分配的名字。
State : 任务的壮态信息, B 是阻塞态, R 是就绪态, S 是挂起态, D 是删除态
Priority : 任务优先级。
Stack : 任务堆栈的 “高水位线”,就是堆栈历史最小剩余大小。
Num : 任务编号,这个编号是唯一的,当多个任务使用同一个任务名的时候可以通过此编号来做区分
vTaskGetRunTimeStats ( )
Void vTaskGetRunTimeStats( char * pcWriteBuffer );
此函数用于统计任务的运行时间信息,使用此函数需
将宏 configGENERATE_RUN_TIME_STATS 、configUSE_STATS_FORMATTING_FUNCTIONS 置1
当将此宏 configGENERATE_RUN_TIME_STAT 置1之后,还需要实现2个宏定义:
- portCONFIGURE_TIMER_FOR_RUNTIME_STATE() :用于初始化用于配置任务运行时间统计的时基定时器;注意:这个时基定时器的计时精度需高于系统时钟节拍精度的10至100倍!
- portGET_RUN_TIME_COUNTER_VALUE():用于获取该功能时基硬件定时器计数的计数值 。
形参 | 描述 |
pcWriteBuffer | 接收任务运行时间信息的缓存指针 |
实验
学习 FreeRTOS 任务状态与信息的查询API函数
实验设计:
将设计三个任务:start_task、task1、task2
三个任务的功能如下:
- start_task:用来创建其他的2个任务
- task1:LED0每500ms闪烁一次,提示程序正在运行
- task2:用于展示任务状态信息查询相关API函数的使用
任务基础部分
#include "freertos_demo.h"
#include "./SYSTEM/usart/usart.h"
#include "./BSP/LED/led.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/KEY/key.h"
#include "./SYSTEM/delay/delay.h"
#include "./MALLOC/malloc.h"
#include "string.h"
#include "FreeRTOS.h"
#include "task.h"
#define START_TASK_PRIO 1 //任务优先级为 1
#define START_TASK_STACK_SIZE 128 //开始任务堆栈定义128 字
TaskHandle_t start_task_handler; //定义任务句柄
void start_task(void * pvParameters); //前面声明
#define TASK1_PRIO 2 //任务优先级为 2
#define TASK1_STACK_SIZE 128
TaskHandle_t task1_handler;
void task1(void * pvParameters);
#define TASK2_PRIO 3 //任务优先级为 3
#define TASK2_STACK_SIZE 128
TaskHandle_t task2_handler;
void task2(void * pvParameters);
void freertos_demo(void)
{
xTaskCreate( (TaskFunction_t ) start_task,
(char * ) "start_task",
(uint16_t ) START_TASK_STACK_SIZE,
(void * ) NULL,
(unsigned long ) START_TASK_PRIO,
(TaskHandle_t * ) &start_task_handler );
vTaskStartScheduler(); //开启调度器
}
void start_task(void * pvParameters)
{
taskENTER_CRITICAL(); //进入临界区
xTaskCreate( (TaskFunction_t ) task1,
(const char * ) "task1",
(configSTACK_DEPTH_TYPE ) TASK1_STACK_SIZE,
(void * ) NULL,
(UBaseType_t ) TASK1_PRIO,
(TaskHandle_t * ) &task1_handler );
xTaskCreate( (TaskFunction_t ) task2 ,
(const char * ) "task2",
(configSTACK_DEPTH_TYPE ) TASK2_STACK_SIZE,
(void * ) NULL,
(UBaseType_t ) TASK2_PRIO,
(TaskHandle_t * ) &task2_handler );
vTaskDelete(NULL); //传入NULL删除自身
taskEXIT_CRITICAL(); //退出临界区
}
void task1(void * pvParameters)
{
while(1)
{
LED0_TOGGLE();
vTaskDelay(1000);
}
}
uxTaskPriorityGet ( )
/* 第一步:函数uxTaskPriorityGet()的使用 */
printf("/********第一步:函数uxTaskPriorityGet()的使用**********/\r\n");
printf("/* 将宏 INCLUDE_uxTaskPriorityGet 为 1的使用 */\r\n");
UBaseType_t uxTaskPriorityGet_num = 0;
uxTaskPriorityGet_num = uxTaskPriorityGet(task1_handler);
printf("任务当前优先级:\t\t%ld\r\n", uxTaskPriorityGet_num);
printf("/******************************************************/\r\n");
vTaskPrioritySet ( )
/* 第二步:函数vTaskPrioritySet ( )的使用 */
printf("/********第二步:函数vTaskPrioritySet ( )的使用**********/\r\n");
printf("/* 将宏 INCLUDE_vTaskPrioritySet 为 1的使用 */\r\n");
vTaskPrioritySet (task1_handler,1);
uxTaskPriorityGet_num = uxTaskPriorityGet(task1_handler);
printf("任务当前优先级:\t\t%ld\r\n", uxTaskPriorityGet_num);
printf("/******************************************************/\r\n");
uxTaskGetNumberOfTasks ( )
/* 第三步:函数uxTaskGetNumberOfTasks( )的使用 */
printf("/********第三步:uxTaskGetNumberOfTasks( )的使用**********/\r\n");
UBaseType_t uxTaskGetNumberOfTasks_num = 0;
uxTaskGetNumberOfTasks_num = uxTaskGetNumberOfTasks( );
printf("系统中任务的任务数量:\t%lu\r\n", uxTaskGetNumberOfTasks_num);
printf("/******************************************************/\r\n");
uxTaskGetSystemState ( )
/* 第四步:函数uxTaskGetSystemState()的使用 */
printf("/********第四步:函数uxTaskGetSystemState()的使用**********/\r\n");
printf("/* 宏 configUSE_TRACE_FACILITY 置 1 */\r\n");
uint32_t i = 0;
UBaseType_t task_num = 0;
TaskStatus_t *status_array = NULL;
task_num = uxTaskGetNumberOfTasks(); /* 获取系统任务数量 */
status_array = mymalloc(SRAMIN, task_num * sizeof(TaskStatus_t));
task_num = uxTaskGetSystemState((TaskStatus_t* ) status_array, /* 任务状态信息buffer */
(UBaseType_t ) task_num, /* buffer大小 */
(uint32_t* ) NULL); /* 不获取任务运行时间信息 */
printf("任务名\t\t优先级\t\t任务编号\r\n");
for (i=0; i<task_num; i++)
{
printf("%s\t%s%ld\t\t%ld\r\n",
status_array[i].pcTaskName,
strlen(status_array[i].pcTaskName) > 7 ? "": "\t",
status_array[i].uxCurrentPriority,
status_array[i].xTaskNumber);
}
printf("/*****************************************************/\r\n");
vTaskGetInfo ( )
/* 第五步:函数vTaskGetInfo()的使用 */
printf("/************第五步:函数vTaskGetInfo()的使用**************/\r\n");
printf("/* 宏 configUSE_TRACE_FACILITY 置 1 */\r\n");
TaskHandle_t task_handle = NULL;
TaskStatus_t *task_info = NULL;
eTaskState task_state = eInvalid;
task_info = mymalloc(SRAMIN, sizeof(TaskStatus_t));
task_handle = xTaskGetHandle("task2"); /* 获取任务句柄 */
vTaskGetInfo((TaskHandle_t )task_handle, /* 任务句柄 */
(TaskStatus_t* )task_info, /* 任务信息buffer */
(BaseType_t )pdTRUE, /* 允许统计任务堆栈历史最小值 */
(eTaskState )eInvalid); /* 获取任务运行状态 */
printf("任务名:\t\t\t%s\r\n", task_info->pcTaskName);
printf("任务编号:\t\t%ld\r\n", task_info->xTaskNumber);
printf("任务壮态:\t\t%d\r\n", task_info->eCurrentState);
printf("任务当前优先级:\t\t%ld\r\n", task_info->uxCurrentPriority);
printf("任务基优先级:\t\t%ld\r\n", task_info->uxBasePriority);
printf("任务堆栈基地址:\t\t0x%p\r\n", task_info->pxStackBase);
printf("任务堆栈历史剩余最小值:\t%d\r\n", task_info->usStackHighWaterMark);
printf("/*****************************************************/\r\n");
xTaskGetCurrentTaskHandle ( )
/* 第六步:函数xTaskGetCurrentTaskHandle()的使用 */
printf("/********第六步:函数xTaskGetCurrentTaskHandle()的使用**********/\r\n");
printf("/* 将宏 INCLUDE_xTaskGetCurrentTaskHandle 为 1的使用 */\r\n");
TaskHandle_t task_handle1 = NULL;
task_handle1 = xTaskGetCurrentTaskHandle();
printf("任务控制权柄地址:\t\t%p\r\n", task_handle1);
printf("任务二的任务控制权柄地址:\t\t%p\r\n", task2_handler);
printf("/******************************************************/\r\n");
xTaskGetHandle ( )
/* 第七步:函数xTaskGetHandle ( )的使用 */
printf("/********第七步:函数xTaskGetHandle()的使用**********/\r\n");
printf("/* 将宏 INCLUDE_xTaskGetHandle 为 1的使用 */\r\n");
TaskHandle_t task_handle2 = NULL;
task_handle2 = xTaskGetHandle ("task2");
printf("获取指定任务二控制权柄地址:\t\t%p\r\n", task_handle2);
printf("任务二的任务控制权柄地址:\t\t%p\r\n", task2_handler);
printf("/******************************************************/\r\n");
uxTaskGetStackHighWaterMark ( )
/* 第八步:函数uxTaskGetStackHighWaterMark ( )的使用 */
printf("/********第八步:函数uxTaskGetStackHighWaterMark()的使用**********/\r\n");
printf("/* 宏 INCLUDE_uxTaskGetStackHighWaterMark 置 1的使用 */\r\n");
UBaseType_t uxTaskGetStackHighWaterMark_num;
uxTaskGetStackHighWaterMark_num = uxTaskGetStackHighWaterMark (task2_handler);
printf("任务堆栈历史剩余最小值:\t%ld\r\n", uxTaskGetStackHighWaterMark_num);
printf("/******************************************************/\r\n");
eTaskGetState ( )
/* 第九步:函数eTaskGetState()的使用 */
printf("/***********第九步:函数eTaskGetState()的使用*************/\r\n");
printf("/* 将宏 INCLUDE_eTaskGetState 置1 使用 */\r\n");
char *task_state_str = NULL;
task_state_str = mymalloc(SRAMIN, 10);
task_handle = xTaskGetHandle("task1");
task_state = eTaskGetState(task_handle); /* 获取任务运行状态 */
sprintf(task_state_str, task_state == eRunning ? "Runing" :
task_state == eReady ? "Ready" :
task_state == eBlocked ? "Blocked" :
task_state == eSuspended ? "Suspended" :
task_state == eDeleted ? "Deleted" :
task_state == eInvalid ? "Invalid" :
"");
printf("任务状态值: %d,对应状态为: %s\r\n", task_state, task_state_str);
printf("/*****************************************************/\r\n");
vTaskList ( )
/* 第十步:函数vTaskList()的使用 */
printf("/*************第十步:函数vTaskList()的使用*************/\r\n");
printf("/* 将宏 configUSE_TRACE_FACILITY 和configUSE_STATS_FORMATTING_FUNCTIONS 置1 */\r\n");
char *task_info_buf = NULL;
task_info_buf = mymalloc(SRAMIN, 500);
vTaskList(task_info_buf); /* 获取所有任务的信息 */
printf("任务名\t\t状态\t优先级\t剩余栈\t任务序号\r\n");
printf("%s\r\n", task_info_buf);
myfree(SRAMIN, task_info_buf);
printf("/***************************************************/\r\n");
vTaskGetRunTimeStats ( )
配置
- portCONFIGURE_TIMER_FOR_RUNTIME_STATE() :用于初始化用于配置任务运行时间统计的时基定时器;注意:这个时基定时器的计时精度需高于系统时钟节拍精度的10至100倍!
- portGET_RUN_TIME_COUNTER_VALUE():用于获取该功能时基硬件定时器计数的计数值。
需要在 btim.c 中配置 ,配置后在 btim.h 中声明
uint32_t FreeRTOSRunTimeTicks; /* FreeRTOS时间统计所用的节拍计数器 */
void ConfigureTimeForRunTimeStats(void)
{
FreeRTOSRunTimeTicks = 0; /* 节拍计数器初始化为0 */
btim_timx_int_init(10-1, 72-1); /* 初始化TIM3 */
}
/**
* @brief 定时器更新中断回调函数
* @param htim:定时器句柄
* @retval 无
*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim == (&g_timx_handle))
{
FreeRTOSRunTimeTicks++;
}
}
主代码
/* 第十一步:函数vTaskGetRunTimeStats ( )的使用 */
printf("/********第十一步:函数vTaskGetRunTimeStats()的使用**********/\r\n");
printf("/* 将宏 configGENERATE_RUN_TIME_STATS 、configUSE_STATS_FORMATTING_FUNCTIONS 置1*/\r\n");
printf("/* portCONFIGURE_TIMER_FOR_RUNTIME_STATE、portGET_RUN_TIME_COUNTER_VALUE置1:*/\r\n");
char *runtime_info = NULL;
runtime_info = mymalloc(SRAMIN, 100);
vTaskGetRunTimeStats(runtime_info); /* 获取任务运行时间信息 */
printf("任务名\t\t运行时间\t运行所占百分比\r\n");
printf("%s\r\n", runtime_info);
printf("/******************************************************/\r\n");