一、FreeRTOS任务相关API函数介绍
二、实验
1.获取指定任务的任务优先级
UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask ) ;
代码:
main.c
#include "stm32f10x.h"
#include "FreeRTOS.h"
#include "task.h"
#include "freertos_demo.h"
#include "Delay.h"
#include "sys.h"
#include "usart.h"
#include "LED.h"
#include "Key.h"
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组 4
uart_init(115200);
delay_init();
LED_Init();
// 创建任务
FrrrRTOS_Demo();
}
freertos_demo.c
#include "FreeRTOS.h"
#include "task.h"
#include "LED.h"
#include "Key.h"
#include "usart.h"
#include "delay.h"
/******************************************************************任务配置****************************************************/
//任务优先级
#define START_TASK_PRIO 1
//任务堆栈大小
#define START_TASK_STACK_SIZE 128
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);
//任务优先级
#define TASK1_PRIO 2
//任务堆栈大小
#define TASK1_STACK_SIZE 128
//任务句柄
TaskHandle_t Task1_Handler;
//任务函数
void task1(void *pvParameters);
//任务优先级
#define TASK2_PRIO 2
//任务堆栈大小
#define TASK2_STACK_SIZE 128
//任务句柄
TaskHandle_t Task2_Handler;
//任务函数
void task2(void *pvParameters);
/******************************************************************任务函数****************************************************/
void FrrrRTOS_Demo(void)
{
//创建开始任务
xTaskCreate((TaskFunction_t )start_task, //任务函数
( char* )"start_task", //任务名称
(uint16_t )START_TASK_STACK_SIZE, //任务堆栈大小
(void* )NULL, //传递给任务函数的参数
(UBaseType_t )START_TASK_PRIO, //任务优先级
(TaskHandle_t* )&StartTask_Handler); //任务句柄
// 启动任务调度
vTaskStartScheduler();
}
void start_task(void *pvParameters)
{
taskENTER_CRITICAL(); //进入临界区
//创建1任务
xTaskCreate((TaskFunction_t )task1,
(const char* )"task1",
(uint16_t )TASK1_STACK_SIZE,
(void* )NULL,
(UBaseType_t )TASK1_PRIO,
(TaskHandle_t* )&Task1_Handler);
//创建2任务
xTaskCreate((TaskFunction_t )task2,
(const char* )"task2",
(uint16_t )TASK2_STACK_SIZE,
(void* )NULL,
(UBaseType_t )TASK2_PRIO,
(TaskHandle_t* )&Task2_Handler);
vTaskDelete(NULL); //删除开始任务
taskEXIT_CRITICAL(); //退出临界区
}
//1 任务函数
void task1(void *pvParameters)
{
while(1)
{
LED1_Turn();
vTaskDelay(500);
}
}
//2 任务函数
void task2(void *pvParameters)
{
UBaseType_t priority;
priority = uxTaskPriorityGet(Task1_Handler);
printf("任务一的优先级为:%ld\r\n",priority);
vTaskDelay(1000);
}
实验结果:
传入空句柄获取自身任务优先级;
uxTaskPriorityGet(NULL);
2.改变某个任务优先级
void vTaskPrioritySet( TaskHandle_t xTask,UBaseType_t uxNewPriority );
代码:
freertos_demo.c
#include "FreeRTOS.h"
#include "task.h"
#include "LED.h"
#include "Key.h"
#include "usart.h"
#include "delay.h"
/******************************************************************任务配置****************************************************/
//任务优先级
#define START_TASK_PRIO 1
//任务堆栈大小
#define START_TASK_STACK_SIZE 128
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);
//任务优先级
#define TASK1_PRIO 2
//任务堆栈大小
#define TASK1_STACK_SIZE 128
//任务句柄
TaskHandle_t Task1_Handler;
//任务函数
void task1(void *pvParameters);
//任务优先级
#define TASK2_PRIO 2
//任务堆栈大小
#define TASK2_STACK_SIZE 128
//任务句柄
TaskHandle_t Task2_Handler;
//任务函数
void task2(void *pvParameters);
/******************************************************************任务函数****************************************************/
void FrrrRTOS_Demo(void)
{
//创建开始任务
xTaskCreate((TaskFunction_t )start_task, //任务函数
( char* )"start_task", //任务名称
(uint16_t )START_TASK_STACK_SIZE, //任务堆栈大小
(void* )NULL, //传递给任务函数的参数
(UBaseType_t )START_TASK_PRIO, //任务优先级
(TaskHandle_t* )&StartTask_Handler); //任务句柄
// 启动任务调度
vTaskStartScheduler();
}
void start_task(void *pvParameters)
{
taskENTER_CRITICAL(); //进入临界区
//创建1任务
xTaskCreate((TaskFunction_t )task1,
(const char* )"task1",
(uint16_t )TASK1_STACK_SIZE,
(void* )NULL,
(UBaseType_t )TASK1_PRIO,
(TaskHandle_t* )&Task1_Handler);
//创建2任务
xTaskCreate((TaskFunction_t )task2,
(const char* )"task2",
(uint16_t )TASK2_STACK_SIZE,
(void* )NULL,
(UBaseType_t )TASK2_PRIO,
(TaskHandle_t* )&Task2_Handler);
vTaskDelete(NULL); //删除开始任务
taskEXIT_CRITICAL(); //退出临界区
}
//1 任务函数
void task1(void *pvParameters)
{
while(1)
{
LED1_Turn();
vTaskDelay(500);
}
}
//2 任务函数
void task2(void *pvParameters)
{
UBaseType_t priority;
vTaskPrioritySet(Task2_Handler,4);
priority = uxTaskPriorityGet(NULL);
printf("任务二的优先级为:%ld\r\n",priority);
vTaskDelay(1000);
}
实验结果:
此宏决定可以设置的最大任务优先级
#define configMAX_PRIORITIES ( 5 ) // 最大任务优先级数
3.获取系统中任务的任务数量
UBaseType_t uxTaskGetNumberOfTasks( void );
代码:
freertos_demo.c
#include "FreeRTOS.h"
#include "task.h"
#include "LED.h"
#include "Key.h"
#include "usart.h"
#include "delay.h"
/******************************************************************任务配置****************************************************/
//任务优先级
#define START_TASK_PRIO 1
//任务堆栈大小
#define START_TASK_STACK_SIZE 128
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);
//任务优先级
#define TASK1_PRIO 2
//任务堆栈大小
#define TASK1_STACK_SIZE 128
//任务句柄
TaskHandle_t Task1_Handler;
//任务函数
void task1(void *pvParameters);
//任务优先级
#define TASK2_PRIO 2
//任务堆栈大小
#define TASK2_STACK_SIZE 128
//任务句柄
TaskHandle_t Task2_Handler;
//任务函数
void task2(void *pvParameters);
/******************************************************************任务函数****************************************************/
void FrrrRTOS_Demo(void)
{
//创建开始任务
xTaskCreate((TaskFunction_t )start_task, //任务函数
( char* )"start_task", //任务名称
(uint16_t )START_TASK_STACK_SIZE, //任务堆栈大小
(void* )NULL, //传递给任务函数的参数
(UBaseType_t )START_TASK_PRIO, //任务优先级
(TaskHandle_t* )&StartTask_Handler); //任务句柄
// 启动任务调度
vTaskStartScheduler();
}
void start_task(void *pvParameters)
{
taskENTER_CRITICAL(); //进入临界区
//创建1任务
xTaskCreate((TaskFunction_t )task1,
(const char* )"task1",
(uint16_t )TASK1_STACK_SIZE,
(void* )NULL,
(UBaseType_t )TASK1_PRIO,
(TaskHandle_t* )&Task1_Handler);
//创建2任务
xTaskCreate((TaskFunction_t )task2,
(const char* )"task2",
(uint16_t )TASK2_STACK_SIZE,
(void* )NULL,
(UBaseType_t )TASK2_PRIO,
(TaskHandle_t* )&Task2_Handler);
vTaskDelete(NULL); //删除开始任务
taskEXIT_CRITICAL(); //退出临界区
}
//1 任务函数
void task1(void *pvParameters)
{
while(1)
{
LED1_Turn();
vTaskDelay(500);
}
}
//2 任务函数
void task2(void *pvParameters)
{
UBaseType_t priority = 0;
UBaseType_t task_num = 0;
vTaskPrioritySet(Task2_Handler,4);
priority = uxTaskPriorityGet(NULL);
task_num = uxTaskGetNumberOfTasks();
printf("任务数量:%ld\r\n",task_num);
printf("任务二的优先级为:%ld\r\n",priority);
while(1)
{
vTaskDelay(1000);
}
}
实验结果:
首先自己创建的3个任务,然后启动任务调度器函数vTaskStartScheduler();内部创建的2个任务:空闲任务和定时器任务,一共是5个任务。
如果是4个任务,那是因为FreeRTOSConfig.c文件里面没有启用软件定时器功能,添加下面宏即可:
/*-------------------------------- FreeRTOS 定时器配置 --------------------------------*/
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES - 1) // 定时器任务优先级
#define configTIMER_QUEUE_LENGTH 10 // 定时器队列长度
#define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE * 2) // 定时器任务堆栈大小
4.获取系统中所有任务的任务状态信息
UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray,
const UBaseType_t uxArraySize,
configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime );
这个宏默认是0,所以要修改一下:
#define configUSE_TRACE_FACILITY 1 // 禁用可视化跟踪调试功能
代码:
freertos_demo.c
#include "FreeRTOS.h"
#include "task.h"
#include "LED.h"
#include "Key.h"
#include "usart.h"
#include "delay.h"
/******************************************************************任务配置****************************************************/
//任务优先级
#define START_TASK_PRIO 1
//任务堆栈大小
#define START_TASK_STACK_SIZE 128
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);
//任务优先级
#define TASK1_PRIO 2
//任务堆栈大小
#define TASK1_STACK_SIZE 128
//任务句柄
TaskHandle_t Task1_Handler;
//任务函数
void task1(void *pvParameters);
//任务优先级
#define TASK2_PRIO 2
//任务堆栈大小
#define TASK2_STACK_SIZE 128
//任务句柄
TaskHandle_t Task2_Handler;
//任务函数
void task2(void *pvParameters);
/******************************************************************任务函数****************************************************/
void FrrrRTOS_Demo(void)
{
//创建开始任务
xTaskCreate((TaskFunction_t )start_task, //任务函数
( char* )"start_task", //任务名称
(uint16_t )START_TASK_STACK_SIZE, //任务堆栈大小
(void* )NULL, //传递给任务函数的参数
(UBaseType_t )START_TASK_PRIO, //任务优先级
(TaskHandle_t* )&StartTask_Handler); //任务句柄
// 启动任务调度
vTaskStartScheduler();
}
void start_task(void *pvParameters)
{
taskENTER_CRITICAL(); //进入临界区
//创建1任务
xTaskCreate((TaskFunction_t )task1,
(const char* )"task1",
(uint16_t )TASK1_STACK_SIZE,
(void* )NULL,
(UBaseType_t )TASK1_PRIO,
(TaskHandle_t* )&Task1_Handler);
//创建2任务
xTaskCreate((TaskFunction_t )task2,
(const char* )"task2",
(uint16_t )TASK2_STACK_SIZE,
(void* )NULL,
(UBaseType_t )TASK2_PRIO,
(TaskHandle_t* )&Task2_Handler);
vTaskDelete(NULL); //删除开始任务
taskEXIT_CRITICAL(); //退出临界区
}
//1 任务函数
void task1(void *pvParameters)
{
while(1)
{
LED1_Turn();
vTaskDelay(500);
}
}
// 任务2 函数
void task2(void *pvParameters)
{
UBaseType_t priority = 0; // 用于存储任务优先级
UBaseType_t task_num = 0; // 用于存储系统中任务的总数
UBaseType_t task2_num = 0; // 用于存储实际获取到的任务状态数量
TaskStatus_t *status_array = 0; // 用于存储任务状态信息的数组
uint8_t i = 0; // 循环计数器
// 设置任务2的优先级为4
vTaskPrioritySet(Task2_Handler, 4);
// 获取当前任务(任务2)的优先级
priority = uxTaskPriorityGet(NULL);
printf("\r\n任务二的优先级为:%ld\r\n", priority);
// 获取系统中任务的总数
task_num = uxTaskGetNumberOfTasks();
printf("任务数量:%ld\r\n", task_num);
printf("----------------------------\r\n");
// 为 status_array 分配内存,用于存储任务状态信息
// 分配的内存大小为 task_num * sizeof(TaskStatus_t) = 5 * 需要分配内存块的大小 TaskStatus_t 是 FreeRTOS 中用于存储任务状态信息的结构体
status_array = (TaskStatus_t *)pvPortMalloc(task_num * sizeof(TaskStatus_t));
if (status_array == NULL) // 检查内存是否分配成功
{
printf("内存分配失败!\r\n");
return; // 如果分配失败,直接返回
}
// 获取系统中所有任务的状态信息
// 将任务状态信息存储到 status_array 中,并返回实际获取到的任务数量
task2_num = uxTaskGetSystemState(status_array, task_num, NULL);
// 打印任务状态信息
for (i = 0; i < task2_num; i++)
{
printf("任务名称: %s\r\n", status_array[i].pcTaskName); // 打印任务名称
printf("任务编号: %ld\r\n", status_array[i].xTaskNumber); // 打印任务编号
printf("任务优先级: %ld\r\n", status_array[i].uxCurrentPriority); // 打印任务优先级
printf("----------------------------\r\n");
}
// 释放 status_array 的内存
vPortFree(status_array);
// 任务主循环
while (1)
{
vTaskDelay(1000); // 任务延时 1000 个 tick(根据 configTICK_RATE_HZ 决定具体时间)
}
}
实验结果:
与自己创建的任务优先级、编号等都一样;
FreeRTOS申请内存的函数:
void * pvPortMalloc( size_t xWantedSize );
参数:需要分配内存块的大小
返回值:成功返回指向分配内存块的指针;失败返回NULL
status_array = (TaskStatus_t *)pvPortMalloc(task_num * sizeof(TaskStatus_t));
if (status_array == NULL) // 检查内存是否分配成功
{
printf("内存分配失败!\r\n");
return;
}
vPortFree(status_array); // 释放 status_array 的内存
还可以打印这些信息:
typedef struct xTASK_STATUS
{
TaskHandle_t xHandle; /* 任务句柄,表示该结构体描述的任务。 */
const char * pcTaskName; /* 指向任务名称的指针。如果任务在结构体填充后被删除,该值将无效! */ /*lint !e971 允许未限定的 char 类型仅用于字符串和单个字符。 */
UBaseType_t xTaskNumber; /* 任务的唯一编号。 */
eTaskState eCurrentState; /* 结构体填充时任务的状态。 */
UBaseType_t uxCurrentPriority; /* 结构体填充时任务的运行优先级(可能被继承)。 */
UBaseType_t uxBasePriority; /* 如果任务的当前优先级被继承以避免无界优先级反转(当获取互斥锁时),任务将返回的基础优先级。仅在 FreeRTOSConfig.h 中定义了 configUSE_MUTEXES 为 1 时有效。 */
configRUN_TIME_COUNTER_TYPE ulRunTimeCounter; /* 任务到目前为止分配的总运行时间,由运行时间统计时钟定义。参见 https://www.FreeRTOS.org/rtos-run-time-stats.html。仅在 FreeRTOSConfig.h 中定义了 configGENERATE_RUN_TIME_STATS 为 1 时有效。 */
StackType_t * pxStackBase; /* 指向任务堆栈区域的最低地址。 */
#if ( ( portSTACK_GROWTH > 0 ) && ( configRECORD_STACK_HIGH_ADDRESS == 1 ) )
StackType_t * pxTopOfStack; /* 指向任务堆栈区域的最高地址。 */
StackType_t * pxEndOfStack; /* 指向任务堆栈区域的结束地址。 */
#endif
configSTACK_DEPTH_TYPE usStackHighWaterMark; /* 自任务创建以来,任务堆栈剩余的最小空间量。该值越接近零,任务堆栈溢出的风险越大。 */
} TaskStatus_t;
5.获取指定的单个任务的状态信息
void vTaskGetInfo( TaskHandle_t xTask,
TaskStatus_t * pxTaskStatus,
BaseType_t xGetFreeStackSpace,
eTaskState eState );
代码:
#include "FreeRTOS.h"
#include "task.h"
#include "LED.h"
#include "Key.h"
#include "usart.h"
#include "delay.h"
/******************************************************************任务配置****************************************************/
//任务优先级
#define START_TASK_PRIO 1
//任务堆栈大小
#define START_TASK_STACK_SIZE 128
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);
//任务优先级
#define TASK1_PRIO 2
//任务堆栈大小
#define TASK1_STACK_SIZE 128
//任务句柄
TaskHandle_t Task1_Handler;
//任务函数
void task1(void *pvParameters);
//任务优先级
#define TASK2_PRIO 2
//任务堆栈大小
#define TASK2_STACK_SIZE 128
//任务句柄
TaskHandle_t Task2_Handler;
//任务函数
void task2(void *pvParameters);
/******************************************************************任务函数****************************************************/
void FrrrRTOS_Demo(void)
{
//创建开始任务
xTaskCreate((TaskFunction_t )start_task, //任务函数
( char* )"start_task", //任务名称
(uint16_t )START_TASK_STACK_SIZE, //任务堆栈大小
(void* )NULL, //传递给任务函数的参数
(UBaseType_t )START_TASK_PRIO, //任务优先级
(TaskHandle_t* )&StartTask_Handler); //任务句柄
// 启动任务调度
vTaskStartScheduler();
}
void start_task(void *pvParameters)
{
taskENTER_CRITICAL(); //进入临界区
//创建1任务
xTaskCreate((TaskFunction_t )task1,
(const char* )"task1",
(uint16_t )TASK1_STACK_SIZE,
(void* )NULL,
(UBaseType_t )TASK1_PRIO,
(TaskHandle_t* )&Task1_Handler);
//创建2任务
xTaskCreate((TaskFunction_t )task2,
(const char* )"task2",
(uint16_t )TASK2_STACK_SIZE,
(void* )NULL,
(UBaseType_t )TASK2_PRIO,
(TaskHandle_t* )&Task2_Handler);
vTaskDelete(NULL); //删除开始任务
taskEXIT_CRITICAL(); //退出临界区
}
//1 任务函数
void task1(void *pvParameters)
{
while(1)
{
LED1_Turn();
vTaskDelay(500);
}
}
// 任务2 函数
void task2(void *pvParameters)
{
UBaseType_t priority = 0; // 用于存储任务优先级
UBaseType_t task_num = 0; // 用于存储系统中任务的总数
UBaseType_t task2_num = 0; // 用于存储实际获取到的任务状态数量
TaskStatus_t *status_array = 0; // 用于存储任务状态信息的数组
TaskStatus_t *status2_array = 0;
uint8_t i = 0; // 循环计数器
/*****************************************获取当前任务(任务2)的优先级*************************************************************/
// 设置任务2的优先级为4
vTaskPrioritySet(Task2_Handler, 4);
priority = uxTaskPriorityGet(NULL);
printf("\r\n任务二的优先级为:%ld\r\n", priority);
/***********************************************获取系统中任务的总数***************************************************************/
task_num = uxTaskGetNumberOfTasks();
printf("任务数量:%ld\r\n", task_num);
printf("----------------------------\r\n");
/*************************************************获取所有任务的状态信息*****************************************************/
// 为 status_array 分配内存,用于存储任务状态信息
// 分配的内存大小为 task_num * sizeof(TaskStatus_t) = 5 * 需要分配内存块的大小 TaskStatus_t 是 FreeRTOS 中用于存储任务状态信息的结构体
status_array = (TaskStatus_t *)pvPortMalloc(task_num * sizeof(TaskStatus_t));
if (status_array == NULL)
{
printf("status_array内存分配失败!\r\n");
return;
}
task2_num = uxTaskGetSystemState(status_array, task_num, NULL);
for (i = 0; i < task2_num; i++)
{
printf("任务名称: %s\r\n", status_array[i].pcTaskName); // 打印任务名称
printf("任务编号: %ld\r\n", status_array[i].xTaskNumber); // 打印任务编号
printf("任务优先级: %ld\r\n", status_array[i].uxCurrentPriority); // 打印任务优先级
printf("----------------------------\r\n");
}
vPortFree(status_array); // 释放 status_array 的内存
/************************************************获取任务2的状态信息****************************************************/
status2_array = (TaskStatus_t *)pvPortMalloc(task_num * sizeof(TaskStatus_t));
if (status2_array == NULL)
{
printf("status2_array内存分配失败!\r\n");
return;
}
vTaskGetInfo( Task2_Handler,status2_array,pdTRUE,eInvalid);
printf("任务名称: %s\r\n", status2_array->pcTaskName); // 打印任务名称
printf("任务编号: %ld\r\n", status2_array->xTaskNumber); // 打印任务编号
printf("任务优先级: %ld\r\n", status2_array->uxCurrentPriority); // 打印任务优先级
printf("任务状态: %d\r\n", status2_array->eCurrentState); // 任务状态
printf("----------------------------\r\n");
vPortFree(status2_array);
// 任务主循环
while (1)
{
vTaskDelay(1000); // 任务延时 1000 个 tick(根据 configTICK_RATE_HZ 决定具体时间)
}
}
实验现象:
任务2,正在运行所以状态是0;与上面一致
获取所有任务信息:
UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray,
const UBaseType_t uxArraySize,
configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime );
获取单个任务信息 :
void vTaskGetInfo( TaskHandle_t xTask,
TaskStatus_t * pxTaskStatus,
BaseType_t xGetFreeStackSpace,
eTaskState eState )
两个函数很像,但是第一个函数的第一个参数是结构体指针,第二个函数的第一个参数是结构体;
6.获取当前任务的任务句柄
TaskHandle_t xTaskGetCurrentTaskHandle( void );
代码:
#include "FreeRTOS.h"
#include "task.h"
#include "LED.h"
#include "Key.h"
#include "usart.h"
#include "delay.h"
/******************************************************************任务配置****************************************************/
//任务优先级
#define START_TASK_PRIO 1
//任务堆栈大小
#define START_TASK_STACK_SIZE 128
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);
//任务优先级
#define TASK1_PRIO 2
//任务堆栈大小
#define TASK1_STACK_SIZE 128
//任务句柄
TaskHandle_t Task1_Handler;
//任务函数
void task1(void *pvParameters);
//任务优先级
#define TASK2_PRIO 2
//任务堆栈大小
#define TASK2_STACK_SIZE 128
//任务句柄
TaskHandle_t Task2_Handler;
//任务函数
void task2(void *pvParameters);
/******************************************************************任务函数****************************************************/
void FrrrRTOS_Demo(void)
{
//创建开始任务
xTaskCreate((TaskFunction_t )start_task, //任务函数
( char* )"start_task", //任务名称
(uint16_t )START_TASK_STACK_SIZE, //任务堆栈大小
(void* )NULL, //传递给任务函数的参数
(UBaseType_t )START_TASK_PRIO, //任务优先级
(TaskHandle_t* )&StartTask_Handler); //任务句柄
// 启动任务调度
vTaskStartScheduler();
}
void start_task(void *pvParameters)
{
taskENTER_CRITICAL(); //进入临界区
//创建1任务
xTaskCreate((TaskFunction_t )task1,
(const char* )"task1",
(uint16_t )TASK1_STACK_SIZE,
(void* )NULL,
(UBaseType_t )TASK1_PRIO,
(TaskHandle_t* )&Task1_Handler);
//创建2任务
xTaskCreate((TaskFunction_t )task2,
(const char* )"task2",
(uint16_t )TASK2_STACK_SIZE,
(void* )NULL,
(UBaseType_t )TASK2_PRIO,
(TaskHandle_t* )&Task2_Handler);
vTaskDelete(NULL); //删除开始任务
taskEXIT_CRITICAL(); //退出临界区
}
//1 任务函数
void task1(void *pvParameters)
{
while(1)
{
LED1_Turn();
vTaskDelay(500);
}
}
// 任务2 函数
void task2(void *pvParameters)
{
UBaseType_t priority = 0; // 用于存储任务优先级
UBaseType_t task_num = 0; // 用于存储系统中任务的总数
UBaseType_t task2_num = 0; // 用于存储实际获取到的任务状态数量
TaskStatus_t *status_array = 0; // 用于存储任务状态信息的数组
TaskStatus_t *status2_array = 0;
TaskHandle_t TaskHandle; //用于存储任务句柄
uint8_t i = 0; // 循环计数器
/*****************************************获取当前任务(任务2)的优先级*************************************************************/
// 设置任务2的优先级为4
vTaskPrioritySet(Task2_Handler, 4);
priority = uxTaskPriorityGet(NULL);
printf("\r\n任务二的优先级为:%ld\r\n", priority);
/***********************************************获取系统中任务的总数***************************************************************/
task_num = uxTaskGetNumberOfTasks();
printf("任务数量:%ld\r\n", task_num);
printf("----------------------------\r\n");
/*************************************************获取所有任务的状态信息*****************************************************/
// 为 status_array 分配内存,用于存储任务状态信息
// 分配的内存大小为 task_num * sizeof(TaskStatus_t) = 5 * 需要分配内存块的大小 TaskStatus_t 是 FreeRTOS 中用于存储任务状态信息的结构体
status_array = (TaskStatus_t *)pvPortMalloc(task_num * sizeof(TaskStatus_t));
if (status_array == NULL)
{
printf("status_array内存分配失败!\r\n");
return;
}
task2_num = uxTaskGetSystemState(status_array, task_num, NULL);
for (i = 0; i < task2_num; i++)
{
printf("任务名称: %s\r\n", status_array[i].pcTaskName); // 打印任务名称
printf("任务编号: %ld\r\n", status_array[i].xTaskNumber); // 打印任务编号
printf("任务优先级: %ld\r\n", status_array[i].uxCurrentPriority); // 打印任务优先级
printf("----------------------------\r\n");
}
vPortFree(status_array); // 释放 status_array 的内存
/************************************************获取任务2的状态信息****************************************************/
status2_array = (TaskStatus_t *)pvPortMalloc(task_num * sizeof(TaskStatus_t));
if (status2_array == NULL)
{
printf("status2_array内存分配失败!\r\n");
return;
}
vTaskGetInfo( Task2_Handler,status2_array,pdTRUE,eInvalid);
printf("任务名称: %s\r\n", status2_array->pcTaskName); // 打印任务名称
printf("任务编号: %ld\r\n", status2_array->xTaskNumber); // 打印任务编号
printf("任务优先级: %ld\r\n", status2_array->uxCurrentPriority); // 打印任务优先级
printf("任务状态: %d\r\n", status2_array->eCurrentState); // 任务状态
printf("----------------------------\r\n");
vPortFree(status2_array);
/************************************************获取当前任务句柄****************************************************/
TaskHandle = xTaskGetCurrentTaskHandle();
printf("当前任务句柄: %p\r\n", (void *)TaskHandle); // 打印任务句柄地址
// 任务主循环
while (1)
{
vTaskDelay(1000); // 任务延时 1000 个 tick(根据 configTICK_RATE_HZ 决定具体时间)
}
}
实验结果:
7.通过任务名获取任务句柄
TaskHandle_t xTaskGetHandle(const char * pcNameToQuery);
默认不是1需要置1 :
#define INCLUDE_xTaskGetHandle 1
代码:
#include "FreeRTOS.h"
#include "task.h"
#include "LED.h"
#include "Key.h"
#include "usart.h"
#include "delay.h"
/******************************************************************任务配置****************************************************/
//任务优先级
#define START_TASK_PRIO 1
//任务堆栈大小
#define START_TASK_STACK_SIZE 128
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);
//任务优先级
#define TASK1_PRIO 2
//任务堆栈大小
#define TASK1_STACK_SIZE 128
//任务句柄
TaskHandle_t Task1_Handler;
//任务函数
void task1(void *pvParameters);
//任务优先级
#define TASK2_PRIO 2
//任务堆栈大小
#define TASK2_STACK_SIZE 128
//任务句柄
TaskHandle_t Task2_Handler;
//任务函数
void task2(void *pvParameters);
/******************************************************************任务函数****************************************************/
void FrrrRTOS_Demo(void)
{
//创建开始任务
xTaskCreate((TaskFunction_t )start_task, //任务函数
( char* )"start_task", //任务名称
(uint16_t )START_TASK_STACK_SIZE, //任务堆栈大小
(void* )NULL, //传递给任务函数的参数
(UBaseType_t )START_TASK_PRIO, //任务优先级
(TaskHandle_t* )&StartTask_Handler); //任务句柄
// 启动任务调度
vTaskStartScheduler();
}
void start_task(void *pvParameters)
{
taskENTER_CRITICAL(); //进入临界区
//创建1任务
xTaskCreate((TaskFunction_t )task1,
(const char* )"task1",
(uint16_t )TASK1_STACK_SIZE,
(void* )NULL,
(UBaseType_t )TASK1_PRIO,
(TaskHandle_t* )&Task1_Handler);
//创建2任务
xTaskCreate((TaskFunction_t )task2,
(const char* )"task2",
(uint16_t )TASK2_STACK_SIZE,
(void* )NULL,
(UBaseType_t )TASK2_PRIO,
(TaskHandle_t* )&Task2_Handler);
vTaskDelete(NULL); //删除开始任务
taskEXIT_CRITICAL(); //退出临界区
}
//1 任务函数
void task1(void *pvParameters)
{
while(1)
{
LED1_Turn();
vTaskDelay(500);
}
}
// 任务2 函数
void task2(void *pvParameters)
{
UBaseType_t priority = 0; // 用于存储任务优先级
UBaseType_t task_num = 0; // 用于存储系统中任务的总数
UBaseType_t task2_num = 0; // 用于存储实际获取到的任务状态数量
TaskStatus_t *status_array = 0; // 用于存储任务状态信息的数组
TaskStatus_t *status2_array = 0;
TaskHandle_t TaskHandle; //用于存储任务句柄
uint8_t i = 0; // 循环计数器
/*****************************************获取当前任务(任务2)的优先级*************************************************************/
// 设置任务2的优先级为4
vTaskPrioritySet(Task2_Handler, 4);
priority = uxTaskPriorityGet(NULL);
printf("\r\n任务二的优先级为:%ld\r\n", priority);
printf("----------------------------\r\n");
/***********************************************获取系统中任务的总数***************************************************************/
task_num = uxTaskGetNumberOfTasks();
printf("任务数量:%ld\r\n", task_num);
printf("----------------------------\r\n");
/*************************************************获取所有任务的状态信息*****************************************************/
// 为 status_array 分配内存,用于存储任务状态信息
// 分配的内存大小为 task_num * sizeof(TaskStatus_t) = 5 * 需要分配内存块的大小 TaskStatus_t 是 FreeRTOS 中用于存储任务状态信息的结构体
status_array = (TaskStatus_t *)pvPortMalloc(task_num * sizeof(TaskStatus_t));
if (status_array == NULL)
{
printf("status_array内存分配失败!\r\n");
return;
}
task2_num = uxTaskGetSystemState(status_array, task_num, NULL);
for (i = 0; i < task2_num; i++)
{
printf("任务名称: %s\r\n", status_array[i].pcTaskName); // 打印任务名称
printf("任务编号: %ld\r\n", status_array[i].xTaskNumber); // 打印任务编号
printf("任务优先级: %ld\r\n", status_array[i].uxCurrentPriority); // 打印任务优先级
printf("----------------------------\r\n");
}
vPortFree(status_array); // 释放 status_array 的内存
/************************************************获取任务2的状态信息****************************************************/
status2_array = (TaskStatus_t *)pvPortMalloc(task_num * sizeof(TaskStatus_t));
if (status2_array == NULL)
{
printf("status2_array内存分配失败!\r\n");
return;
}
vTaskGetInfo( Task2_Handler,status2_array,pdTRUE,eInvalid);
printf("任务名称: %s\r\n", status2_array->pcTaskName); // 打印任务名称
printf("任务编号: %ld\r\n", status2_array->xTaskNumber); // 打印任务编号
printf("任务优先级: %ld\r\n", status2_array->uxCurrentPriority); // 打印任务优先级
printf("任务状态: %d\r\n", status2_array->eCurrentState); // 任务状态
printf("----------------------------\r\n");
vPortFree(status2_array);
/************************************************获取当前任务句柄****************************************************/
TaskHandle = xTaskGetCurrentTaskHandle();
printf("当前任务句柄: %p\r\n", (void *)TaskHandle); // 打印任务句柄地址
printf("----------------------------\r\n");
/************************************************通过任务名获取任务句柄****************************************************/
TaskHandle = xTaskGetHandle("task2");
printf("当前任务句柄: %p\r\n", (void *)TaskHandle); // 打印任务句柄地址
printf("----------------------------\r\n");
// 任务主循环
while (1)
{
vTaskDelay(1000); // 任务延时 1000 个 tick(根据 configTICK_RATE_HZ 决定具体时间)
}
}
实验结果:
8.获取指定任务的任务栈历史最小剩余堆栈
UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask )
默认不是1需置1:
#define INCLUDE_uxTaskGetStackHighWaterMark 1
代码:
#include "FreeRTOS.h"
#include "task.h"
#include "LED.h"
#include "Key.h"
#include "usart.h"
#include "delay.h"
/******************************************************************任务配置****************************************************/
//任务优先级
#define START_TASK_PRIO 1
//任务堆栈大小
#define START_TASK_STACK_SIZE 128
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);
//任务优先级
#define TASK1_PRIO 2
//任务堆栈大小
#define TASK1_STACK_SIZE 128
//任务句柄
TaskHandle_t Task1_Handler;
//任务函数
void task1(void *pvParameters);
//任务优先级
#define TASK2_PRIO 2
//任务堆栈大小
#define TASK2_STACK_SIZE 128
//任务句柄
TaskHandle_t Task2_Handler;
//任务函数
void task2(void *pvParameters);
/******************************************************************任务函数****************************************************/
void FrrrRTOS_Demo(void)
{
//创建开始任务
xTaskCreate((TaskFunction_t )start_task, //任务函数
( char* )"start_task", //任务名称
(uint16_t )START_TASK_STACK_SIZE, //任务堆栈大小
(void* )NULL, //传递给任务函数的参数
(UBaseType_t )START_TASK_PRIO, //任务优先级
(TaskHandle_t* )&StartTask_Handler); //任务句柄
// 启动任务调度
vTaskStartScheduler();
}
void start_task(void *pvParameters)
{
taskENTER_CRITICAL(); //进入临界区
//创建1任务
xTaskCreate((TaskFunction_t )task1,
(const char* )"task1",
(uint16_t )TASK1_STACK_SIZE,
(void* )NULL,
(UBaseType_t )TASK1_PRIO,
(TaskHandle_t* )&Task1_Handler);
//创建2任务
xTaskCreate((TaskFunction_t )task2,
(const char* )"task2",
(uint16_t )TASK2_STACK_SIZE,
(void* )NULL,
(UBaseType_t )TASK2_PRIO,
(TaskHandle_t* )&Task2_Handler);
vTaskDelete(NULL); //删除开始任务
taskEXIT_CRITICAL(); //退出临界区
}
//1 任务函数
void task1(void *pvParameters)
{
while(1)
{
LED1_Turn();
vTaskDelay(500);
}
}
// 任务2 函数
void task2(void *pvParameters)
{
UBaseType_t priority = 0; // 用于存储任务优先级
UBaseType_t task_num = 0; // 用于存储系统中任务的总数
UBaseType_t task2_num = 0; // 用于存储实际获取到的任务状态数量
TaskStatus_t *status_array = 0; // 用于存储任务状态信息的数组
TaskStatus_t *status2_array = 0;
TaskHandle_t TaskHandle; //用于存储任务句柄
UBaseType_t task2_stack_min = 0; //用于储存堆栈大小
uint8_t i = 0; // 循环计数器
/*****************************************获取当前任务(任务2)的优先级*************************************************************/
// 设置任务2的优先级为4
vTaskPrioritySet(Task2_Handler, 4);
priority = uxTaskPriorityGet(NULL);
printf("\r\n任务二的优先级为:%ld\r\n", priority);
printf("----------------------------\r\n");
/***********************************************获取系统中任务的总数***************************************************************/
task_num = uxTaskGetNumberOfTasks();
printf("任务数量:%ld\r\n", task_num);
printf("----------------------------\r\n");
/*************************************************获取所有任务的状态信息*****************************************************/
// 为 status_array 分配内存,用于存储任务状态信息
// 分配的内存大小为 task_num * sizeof(TaskStatus_t) = 5 * 需要分配内存块的大小 TaskStatus_t 是 FreeRTOS 中用于存储任务状态信息的结构体
status_array = (TaskStatus_t *)pvPortMalloc(task_num * sizeof(TaskStatus_t));
if (status_array == NULL)
{
printf("status_array内存分配失败!\r\n");
return;
}
task2_num = uxTaskGetSystemState(status_array, task_num, NULL);
for (i = 0; i < task2_num; i++)
{
printf("任务名称: %s\r\n", status_array[i].pcTaskName); // 打印任务名称
printf("任务编号: %ld\r\n", status_array[i].xTaskNumber); // 打印任务编号
printf("任务优先级: %ld\r\n", status_array[i].uxCurrentPriority); // 打印任务优先级
printf("----------------------------\r\n");
}
vPortFree(status_array); // 释放 status_array 的内存
/************************************************获取任务2的状态信息****************************************************/
status2_array = (TaskStatus_t *)pvPortMalloc(task_num * sizeof(TaskStatus_t));
if (status2_array == NULL)
{
printf("status2_array内存分配失败!\r\n");
return;
}
vTaskGetInfo( Task2_Handler,status2_array,pdTRUE,eInvalid);
printf("任务名称: %s\r\n", status2_array->pcTaskName); // 打印任务名称
printf("任务编号: %ld\r\n", status2_array->xTaskNumber); // 打印任务编号
printf("任务优先级: %ld\r\n", status2_array->uxCurrentPriority); // 打印任务优先级
printf("任务状态: %d\r\n", status2_array->eCurrentState); // 任务状态
printf("----------------------------\r\n");
vPortFree(status2_array);
/************************************************获取当前任务句柄****************************************************/
TaskHandle = xTaskGetCurrentTaskHandle();
printf("当前任务句柄: %p\r\n", (void *)TaskHandle); // 打印任务句柄地址
printf("----------------------------\r\n");
/************************************************通过任务名获取任务句柄****************************************************/
TaskHandle = xTaskGetHandle("task2");
printf("当前任务句柄: %p\r\n", (void *)TaskHandle); // 打印任务句柄地址
printf("----------------------------\r\n");
/************************************************通过任务名获取任务句柄****************************************************/
task2_stack_min = uxTaskGetStackHighWaterMark(Task2_Handler);
printf("task2历史剩余最小堆栈位: %ld\r\n", task2_stack_min); // 打印任务句柄地址
printf("----------------------------\r\n");
// 任务主循环
while (1)
{
vTaskDelay(1000); // 任务延时 1000 个 tick(根据 configTICK_RATE_HZ 决定具体时间)
}
}
实验结果:
如果创建任务时,堆栈分配很小,就会溢出打印0;
9.查询某个任务的运行状态
eTaskState eTaskGetState(TaskHandle_t xTask)
默认不是1需置1:
#define INCLUDE_eTaskGetState 1
代码:
#include "FreeRTOS.h"
#include "task.h"
#include "LED.h"
#include "Key.h"
#include "usart.h"
#include "delay.h"
/******************************************************************任务配置****************************************************/
//任务优先级
#define START_TASK_PRIO 1
//任务堆栈大小
#define START_TASK_STACK_SIZE 128
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);
//任务优先级
#define TASK1_PRIO 2
//任务堆栈大小
#define TASK1_STACK_SIZE 128
//任务句柄
TaskHandle_t Task1_Handler;
//任务函数
void task1(void *pvParameters);
//任务优先级
#define TASK2_PRIO 2
//任务堆栈大小
#define TASK2_STACK_SIZE 128
//任务句柄
TaskHandle_t Task2_Handler;
//任务函数
void task2(void *pvParameters);
/******************************************************************任务函数****************************************************/
void FrrrRTOS_Demo(void)
{
//创建开始任务
xTaskCreate((TaskFunction_t )start_task, //任务函数
( char* )"start_task", //任务名称
(uint16_t )START_TASK_STACK_SIZE, //任务堆栈大小
(void* )NULL, //传递给任务函数的参数
(UBaseType_t )START_TASK_PRIO, //任务优先级
(TaskHandle_t* )&StartTask_Handler); //任务句柄
// 启动任务调度
vTaskStartScheduler();
}
void start_task(void *pvParameters)
{
taskENTER_CRITICAL(); //进入临界区
//创建1任务
xTaskCreate((TaskFunction_t )task1,
(const char* )"task1",
(uint16_t )TASK1_STACK_SIZE,
(void* )NULL,
(UBaseType_t )TASK1_PRIO,
(TaskHandle_t* )&Task1_Handler);
//创建2任务
xTaskCreate((TaskFunction_t )task2,
(const char* )"task2",
(uint16_t )TASK2_STACK_SIZE,
(void* )NULL,
(UBaseType_t )TASK2_PRIO,
(TaskHandle_t* )&Task2_Handler);
vTaskDelete(NULL); //删除开始任务
taskEXIT_CRITICAL(); //退出临界区
}
//1 任务函数
void task1(void *pvParameters)
{
while(1)
{
LED1_Turn();
vTaskDelay(500);
}
}
// 任务2 函数
void task2(void *pvParameters)
{
UBaseType_t priority = 0; // 用于存储任务优先级
UBaseType_t task_num = 0; // 用于存储系统中任务的总数
UBaseType_t task2_num = 0; // 用于存储实际获取到的任务状态数量
TaskStatus_t *status_array = 0; // 用于存储任务状态信息的数组
TaskStatus_t *status2_array = 0;
TaskHandle_t TaskHandle; //用于存储任务句柄
UBaseType_t task2_stack_min = 0; //用于储存堆栈大小
eTaskState task_state; // 用于存储任务状态
uint8_t i = 0; // 循环计数器
/*****************************************获取当前任务(任务2)的优先级*************************************************************/
// 设置任务2的优先级为4
vTaskPrioritySet(Task2_Handler, 4);
priority = uxTaskPriorityGet(NULL);
printf("\r\n任务二的优先级为:%ld\r\n", priority);
printf("----------------------------\r\n");
/***********************************************获取系统中任务的总数***************************************************************/
task_num = uxTaskGetNumberOfTasks();
printf("任务数量:%ld\r\n", task_num);
printf("----------------------------\r\n");
/*************************************************获取所有任务的状态信息*****************************************************/
// 为 status_array 分配内存,用于存储任务状态信息
// 分配的内存大小为 task_num * sizeof(TaskStatus_t) = 5 * 需要分配内存块的大小 TaskStatus_t 是 FreeRTOS 中用于存储任务状态信息的结构体
status_array = (TaskStatus_t *)pvPortMalloc(task_num * sizeof(TaskStatus_t));
if (status_array == NULL)
{
printf("status_array内存分配失败!\r\n");
return;
}
task2_num = uxTaskGetSystemState(status_array, task_num, NULL);
for (i = 0; i < task2_num; i++)
{
printf("任务名称: %s\r\n", status_array[i].pcTaskName); // 打印任务名称
printf("任务编号: %ld\r\n", status_array[i].xTaskNumber); // 打印任务编号
printf("任务优先级: %ld\r\n", status_array[i].uxCurrentPriority); // 打印任务优先级
printf("----------------------------\r\n");
}
vPortFree(status_array); // 释放 status_array 的内存
/************************************************获取任务2的状态信息****************************************************/
status2_array = (TaskStatus_t *)pvPortMalloc(task_num * sizeof(TaskStatus_t));
if (status2_array == NULL)
{
printf("status2_array内存分配失败!\r\n");
return;
}
vTaskGetInfo( Task2_Handler,status2_array,pdTRUE,eInvalid);
printf("任务名称: %s\r\n", status2_array->pcTaskName); // 打印任务名称
printf("任务编号: %ld\r\n", status2_array->xTaskNumber); // 打印任务编号
printf("任务优先级: %ld\r\n", status2_array->uxCurrentPriority); // 打印任务优先级
printf("任务状态: %d\r\n", status2_array->eCurrentState); // 任务状态
printf("----------------------------\r\n");
vPortFree(status2_array);
/************************************************获取当前任务句柄****************************************************/
TaskHandle = xTaskGetCurrentTaskHandle();
printf("当前任务句柄: %p\r\n", (void *)TaskHandle); // 打印任务句柄地址
printf("----------------------------\r\n");
/************************************************通过任务名获取任务句柄****************************************************/
TaskHandle = xTaskGetHandle("task2");
printf("当前任务句柄: %p\r\n", (void *)TaskHandle); // 打印任务句柄地址
printf("----------------------------\r\n");
/************************************************通过任务名获取任务句柄****************************************************/
task2_stack_min = uxTaskGetStackHighWaterMark(Task2_Handler);
printf("task2历史剩余最小堆栈位: %ld\r\n", task2_stack_min); // 打印任务句柄地址
printf("----------------------------\r\n");
/************************************************查询某个任务的运行状态?****************************************************/
task_state = eTaskGetState(Task2_Handler);
printf("task2任务的状态: %d\r\n", task_state); // 打印任务句柄地址
printf("----------------------------\r\n");
// 任务主循环
while (1)
{
vTaskDelay(1000); // 任务延时 1000 个 tick(根据 configTICK_RATE_HZ 决定具体时间)
}
}
实验结果:
0:运行态
1:就绪态
10.以“表格”的形式获取系统中任务的信息
void vTaskList(char * pcWriteBuffer)
默认不是1需置1:
#define configUSE_STATS_FORMATTING_FUNCTIONS 1
代码:
#include "FreeRTOS.h"
#include "task.h"
#include "LED.h"
#include "Key.h"
#include "usart.h"
#include "delay.h"
/******************************************************************任务配置****************************************************/
//任务优先级
#define START_TASK_PRIO 1
//任务堆栈大小
#define START_TASK_STACK_SIZE 128
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);
//任务优先级
#define TASK1_PRIO 2
//任务堆栈大小
#define TASK1_STACK_SIZE 128
//任务句柄
TaskHandle_t Task1_Handler;
//任务函数
void task1(void *pvParameters);
//任务优先级
#define TASK2_PRIO 2
//任务堆栈大小
#define TASK2_STACK_SIZE 128
//任务句柄
TaskHandle_t Task2_Handler;
//任务函数
void task2(void *pvParameters);
char task_buffer[500]; //用于存储系统中任务信息表格
/******************************************************************任务函数****************************************************/
void FrrrRTOS_Demo(void)
{
//创建开始任务
xTaskCreate((TaskFunction_t )start_task, //任务函数
( char* )"start_task", //任务名称
(uint16_t )START_TASK_STACK_SIZE, //任务堆栈大小
(void* )NULL, //传递给任务函数的参数
(UBaseType_t )START_TASK_PRIO, //任务优先级
(TaskHandle_t* )&StartTask_Handler); //任务句柄
// 启动任务调度
vTaskStartScheduler();
}
void start_task(void *pvParameters)
{
taskENTER_CRITICAL(); //进入临界区
//创建1任务
xTaskCreate((TaskFunction_t )task1,
(const char* )"task1",
(uint16_t )TASK1_STACK_SIZE,
(void* )NULL,
(UBaseType_t )TASK1_PRIO,
(TaskHandle_t* )&Task1_Handler);
//创建2任务
xTaskCreate((TaskFunction_t )task2,
(const char* )"task2",
(uint16_t )TASK2_STACK_SIZE,
(void* )NULL,
(UBaseType_t )TASK2_PRIO,
(TaskHandle_t* )&Task2_Handler);
vTaskDelete(NULL); //删除开始任务
taskEXIT_CRITICAL(); //退出临界区
}
//1 任务函数
void task1(void *pvParameters)
{
while(1)
{
LED1_Turn();
vTaskDelay(500);
}
}
// 任务2 函数
void task2(void *pvParameters)
{
UBaseType_t priority = 0; // 用于存储任务优先级
UBaseType_t task_num = 0; // 用于存储系统中任务的总数
UBaseType_t task2_num = 0; // 用于存储实际获取到的任务状态数量
TaskStatus_t *status_array = 0; // 用于存储任务状态信息的数组
TaskStatus_t *status2_array = 0;
TaskHandle_t TaskHandle; //用于存储任务句柄
UBaseType_t task2_stack_min = 0; //用于储存堆栈大小
eTaskState task_state; // 用于存储任务状态
uint8_t i = 0; // 循环计数器
/*****************************************获取当前任务(任务2)的优先级*************************************************************/
// 设置任务2的优先级为4
vTaskPrioritySet(Task2_Handler, 4);
priority = uxTaskPriorityGet(NULL);
printf("\r\n任务二的优先级为:%ld\r\n", priority);
printf("----------------------------\r\n");
/***********************************************获取系统中任务的总数***************************************************************/
task_num = uxTaskGetNumberOfTasks();
printf("任务数量:%ld\r\n", task_num);
printf("----------------------------\r\n");
/*************************************************获取所有任务的状态信息*****************************************************/
// 为 status_array 分配内存,用于存储任务状态信息
// 分配的内存大小为 task_num * sizeof(TaskStatus_t) = 5 * 需要分配内存块的大小 TaskStatus_t 是 FreeRTOS 中用于存储任务状态信息的结构体
status_array = (TaskStatus_t *)pvPortMalloc(task_num * sizeof(TaskStatus_t));
if (status_array == NULL)
{
printf("status_array内存分配失败!\r\n");
return;
}
task2_num = uxTaskGetSystemState(status_array, task_num, NULL);
for (i = 0; i < task2_num; i++)
{
printf("任务名称: %s\r\n", status_array[i].pcTaskName); // 打印任务名称
printf("任务编号: %ld\r\n", status_array[i].xTaskNumber); // 打印任务编号
printf("任务优先级: %ld\r\n", status_array[i].uxCurrentPriority); // 打印任务优先级
printf("----------------------------\r\n");
}
vPortFree(status_array); // 释放 status_array 的内存
/************************************************获取任务2的状态信息****************************************************/
status2_array = (TaskStatus_t *)pvPortMalloc(task_num * sizeof(TaskStatus_t));
if (status2_array == NULL)
{
printf("status2_array内存分配失败!\r\n");
return;
}
vTaskGetInfo( Task2_Handler,status2_array,pdTRUE,eInvalid);
printf("任务名称: %s\r\n", status2_array->pcTaskName); // 打印任务名称
printf("任务编号: %ld\r\n", status2_array->xTaskNumber); // 打印任务编号
printf("任务优先级: %ld\r\n", status2_array->uxCurrentPriority); // 打印任务优先级
printf("任务状态: %d\r\n", status2_array->eCurrentState); // 任务状态
printf("----------------------------\r\n");
vPortFree(status2_array);
/************************************************获取当前任务句柄****************************************************/
TaskHandle = xTaskGetCurrentTaskHandle();
printf("当前任务句柄: %p\r\n", (void *)TaskHandle); // 打印任务句柄地址
printf("----------------------------\r\n");
/************************************************通过任务名获取任务句柄****************************************************/
TaskHandle = xTaskGetHandle("task2");
printf("当前任务句柄: %p\r\n", (void *)TaskHandle); // 打印任务句柄地址
printf("----------------------------\r\n");
/************************************************通过任务名获取任务句柄****************************************************/
task2_stack_min = uxTaskGetStackHighWaterMark(Task2_Handler);
printf("task2历史剩余最小堆栈位: %ld\r\n", task2_stack_min); // 打印任务句柄地址
printf("----------------------------\r\n");
/************************************************查询某个任务的运行状态?****************************************************/
task_state = eTaskGetState(Task2_Handler);
printf("task2任务的状态: %d\r\n", task_state); // 打印任务句柄地址
printf("----------------------------\r\n");
/************************************************以“表格”的形式获取系统中任务的信息****************************************************/
vTaskList( task_buffer );
printf("%s\r\n",task_buffer);
// 任务主循环
while (1)
{
vTaskDelay(1000); // 任务延时 1000 个 tick(根据 configTICK_RATE_HZ 决定具体时间)
}
}