FreeRTOS 其他任务 API 函数

news2024/11/14 15:01:08

文章目录

  • 一、任务相关 API 函数预览
  • 二、任务相关 API 函数详解
    • 1. 函数 uxTaskPriorityGet()
    • 2. 函数 vTaskPrioritySet()
    • 3. uxTaskGetSystemState()
    • 4. 函数 vTaskGetInfo()
    • 5. 函数 xTaskGetApplicationTaskTag()
    • 6. 函数 xTaskGetCurrentTaskHandle()
    • 7. 函数 xTaskGetHandle()
    • 8. 函数 xTaskGetIdleTaskHandle()
    • 9. 函数 uxTaskGetStackHighWaterMark()
    • 10. 函数 eTaskGetState()
    • 11. 函数 pcTaskGetName()
    • 12. 函数 xTaskGetTickCount()
    • 13. 函数 xTaskGetTickCountFromISR()
    • 14. 函数 xTaskGetSchedulerState()
    • 15. 函数 uxTaskGetNumberOfTasks()
    • 16. 函数 vTaskList()
    • 17. 函数 vTaskGetRunTimeStats()
    • 18. 函数 vTaskSetApplicationTaskTag()
    • 19. 函数 SetThreadLocalStoragePointer()
    • 20. 函数 GetThreadLocalStoragePointer()
  • 三、任务壮态查询 API 函数实验


一、任务相关 API 函数预览

在这里插入图片描述

二、任务相关 API 函数详解

1. 函数 uxTaskPriorityGet()

此函数用来获取指定任务的优先级,要使用此函数的话宏 INCLUDE_uxTaskPriorityGet 应
该定义为 1,函数原型如下:

UBaseType_t uxTaskPriorityGet( TaskHandle_t xTask )

参数:
xTask: 要查找的任务的任务句柄。
返回值: 获取到的对应的任务的优先级。

2. 函数 vTaskPrioritySet()

此函数用于改变某一个任务的任务优先级,要使用此函数的话宏
INCLUDE_vTaskPrioritySet 应该定义为 1,函数原型如下:

void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority )

参数:
xTask: 要查找的任务的任务句柄。
uxNewPriority: 任务要使用的新的优先级,可以是 0~ configMAX_PRIORITIES – 1。
返回值: 无。

3. uxTaskGetSystemState()

此函数用于获取系统中所有任务的任务壮态,每个任务的壮态信息保存在一个 TaskStatus_t
类型的结构体里面,这个结构体里面包含了任务的任务句柄、任务名字、堆栈、优先级等信息,要使用此函数的话宏 configUSE_TRACE_FACILITY 应该定义为 1,函数原型如下:

UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, 
								  const UBaseType_t uxArraySize, 
								  uint32_t * const pulTotalRunTime )

参数:
pxTaskStatusArray: 指向 TaskStatus_t 结构体类型的数组首地址,每个任务至少需要一个TaskStatus_t结构体 , 任务的数量可以使用函数uxTaskGetNumberOfTasks()。结构体 TaskStatus_t 在文件 task.h 中有如下定义:

typedef struct xTASK_STATUS
{
	TaskHandle_t xHandle; //任务句柄
	const char * pcTaskName; //任务名字
	UBaseType_t xTaskNumber; //任务编号
	eTaskState eCurrentState; //当前任务壮态,eTaskState 是一个枚举类型
	UBaseType_t uxCurrentPriority; //任务当前的优先级
	UBaseType_t uxBasePriority; //任务基础优先级
	uint32_t ulRunTimeCounter;//任务运行的总时间
	StackType_t * pxStackBase; //堆栈基地址
	uint16_t usStackHighWaterMark;//从任务创建以来任务堆栈剩余的最小大小,此
	//值如果太小的话说明堆栈有溢出的风险。
} TaskStatus_t;

uxArraySize: 保存任务壮态数组的数组的大小。
pulTotalRunTime: 如果 configGENERATE_RUN_TIME_STATS 为 1 的话此参数用来保存系统总的运行时间。
返回值: 统计到的任务壮态的个数,也就是填写到数组 pxTaskStatusArray 中的个数,此值应该等于函数 uxTaskGetNumberOfTasks()的返回值。如果参数uxArraySize 太小的话返回值可能为 0。

4. 函数 vTaskGetInfo()

此函数也是用来获取任务壮态的,但是是获取指定的单个任务的壮态的,任务的壮态信息
填充到参数 pxTaskStatus 中,这个参数也是 TaskStatus_t 类型的。要使用此函数的话宏
configUSE_TRACE_FACILITY 要定义为 1,函数原型如下:

void vTaskGetInfo( TaskHandle_t xTask, 
				   TaskStatus_t * pxTaskStatus, 
				   BaseType_t xGetFreeStackSpace, 
				   eTaskState eState )

参数:
xTask: 要查找的任务的任务句柄。
pxTaskStatus: 指向类型为 TaskStatus_t 的结构体变量。
xGetFreeStackSpace: 在结构体 TaskStatus_t 中有个字段 usStackHighWaterMark 来保存自任务运行以来任务堆栈剩余的历史最小大小,这个值越小说明越接近堆栈溢出,但是计算这个值需要花费一点时间,所以我们可以通过将xGetFreeStackSpace设置为pdFALSE来跳过这个步骤,当设置为pdTRUE的时候就会检查堆栈的历史剩余最小值。
eState: 结构体 TaskStatus_t 中有个字段 eCurrentState 用来保存任务运行壮态,这个字段是 eTaskState 类型的,这是个枚举类型,在 task.h 中有如下定义:

typedef enum
{
	eRunning = 0, //运行壮态
	eReady, //就绪态
	eBlocked, //阻塞态
	eSuspended, //挂起态
	eDeleted, //任务被删除
	eInvalid //无效
} eTaskState;

获取任务运行壮态会耗费不少时间,所以为了加快函数 vTaskGetInfo()的执行速度结构体 TaskStatus_t 中的字段 eCurrentState 就可以由用户直接赋值,参数 eState 就是要赋的值。如果不在乎这点时间,那么可以将 eState 设置为eInvalid,这样任务的壮态信息就由函数 vTaskGetInfo()去想办法获取。
返回值: 无。

5. 函数 xTaskGetApplicationTaskTag()

此函数用于获取任务的 Tag(标签)值,任务控制块中有个成员变量 pxTaskTag 来保存任务的
标签值。标签的功能由用户自行决定,此函数就是用来获取这个标签值的,FreeRTOS 系统内核是不会使用到这个标签的。要使用此函数的话宏configUSE_APPLICATION_TASK_TAG 必须为1,函数原型如下:

TaskHookFunction_t xTaskGetApplicationTaskTag( TaskHandle_t xTask )

参数:
xTask: 要获取标签值的任务对应的任务句柄,如果为 NULL 的话就获取当前正在运
行的任务标签值。
返回值: 任务的标签值。

6. 函数 xTaskGetCurrentTaskHandle()

此函数用于获取当前任务的任务句柄,其实获取到的就是任务控制块,在前面讲解任务创
建 函 数 的 时 候 说 过 任 务 句 柄 就 是 任 务 控制。 如 果 要 使 用 此 函 数 的 话 宏
INCLUDE_xTaskGetCurrentTaskHandle 应该为 1,函数原型如下:

TaskHandle_t xTaskGetCurrentTaskHandle( void )

参数:
返回值: 当前任务的任务句柄。

7. 函数 xTaskGetHandle()

此函数根据任务名字获取任务的任务句柄,在使用函数 xTaskCreate()或 xTaskCreateStatic()
创建任务的时候都会给任务分配一个任务名,函数 xTaskGetHandle()就是使用这个任务名字来查询其对应的任务句柄的。要使用此函数的话宏 INCLUDE_xTaskGetHandle 应该设置为 1,此函数原型如下:

TaskHandle_t xTaskGetHandle( const char * pcNameToQuery )

参数:
pcNameToQuery: 任务名,C 语言字符串。
返回值:
NULL: 没有任务名 pcNameToQuery 所对应的任务。
其他值: 任务名 pcNameToQuery 所对应的任务句柄

8. 函数 xTaskGetIdleTaskHandle()

此 函 数 用 于 返 回 空 闲 任 务 的 任 务 句 柄 , 要 使 用 此 函 数 的 话 宏
INCLUDE_xTaskGetIdleTaskHandle 必须为 1,函数原型如下:

TaskHandle_t xTaskGetIdleTaskHandle( void )

参数:
返回值: 空闲任务的任务句柄。

9. 函数 uxTaskGetStackHighWaterMark()

每个任务都有自己的堆栈,堆栈的总大小在创建任务的时候就确定了,此函数用于检查任
务从创建好到现在的历史剩余最小值,这个值越小说明任务堆栈溢出的可能性就越大!
FreeRTOS 把这个历史剩余最小值叫做“高水位线”。此函数相对来说会多耗费一点时间,所以在代码调试阶段可以使用,产品发布的时候最好不要使用。要使用此函数的话宏
INCLUDE_uxTaskGetStackHighWaterMark 必须为 1,此函数原型如下:

UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask )

参数:
xTask: 要查询的任务的任务句柄,当这个参数为 NULL 的话说明查询自身任务(即调用
函数 uxTaskGetStackHighWaterMark()的任务)的“高水位线”。
返回值: 任务堆栈的“高水位线”值,也就是堆栈的历史剩余最小值。

10. 函数 eTaskGetState()

此函数用于查询某个任务的运行壮态,比如:运行态、阻塞态、挂起态、就绪态等,返回
值是个枚举类型。要使用此函数的话宏 INCLUDE_eTaskGetState 必须为 1,函数原型如下:

eTaskState eTaskGetState( TaskHandle_t xTask )

参数:
xTask: 要查询的任务的任务句柄。
返回值: 返回值为 eTaskState 类型(枚举类型)

11. 函数 pcTaskGetName()

根据某个任务的任务句柄来查询这个任务对应的任务名,函数原型如下:

char *pcTaskGetName( TaskHandle_t xTaskToQuery )

参数:
xTaskToQuery: 要查询的任务的任务句柄,此参数为 NULL 的话表示查询自身任务(调
用函数 pcTaskGetName())的任务名字
返回值: 返回任务所对应的任务名。

12. 函数 xTaskGetTickCount()

此函数用于查询任务调度器从启动到现在时间计数器 xTickCount 的值。xTickCount 是系统
的时钟节拍值,并不是真实的时间值。每个滴答定时器中断 xTickCount 就会加 1,一秒钟滴答定时器中断多少次取决于宏 configTICK_RATE_HZ。理论上 xTickCount 存在溢出的问题,但是这个溢出对于 FreeRTOS 的内核没有影响,但是如果用户的应用程序有使用到的话就要考虑溢出了。什么时候溢出取决于宏 configUSE_16_BIT_TICKS,当此宏为 1 的时候 xTixkCount 就是个 16 位的变量,当为 0 的时候就是个 32 位的变量。函数原型如下:

TickType_t xTaskGetTickCount( void )

参数: 无。
返回值: 时间计数器 xTickCount 的值。

13. 函数 xTaskGetTickCountFromISR()

此函数是 xTaskGetTickCount()的中断级版本,用于在中断服务函数中获取时间计数器
xTickCount 的值,函数原型如下:

TickType_t xTaskGetTickCountFromISR( void )

参数: 无。
返回值: 时间计数器 xTickCount 的值。

14. 函数 xTaskGetSchedulerState()

此函数用于获取 FreeRTOS 的任务调度器运行情况:运行?关闭?还是挂起!要使用此函
数的话宏 INCLUDE_xTaskGetSchedulerState 必须为 1,此函数原型如下:

BaseType_t xTaskGetSchedulerState( void )

参数: 无。
返回值:
taskSCHEDULER_NOT_STARTED: 调 度 器 未 启 动 , 调 度 器 的 启 动 是 通 过 函 数vTaskStartScheduler() 来完成,所以在函数vTaskStartScheduler() 未调用之前调用函数xTaskGetSchedulerState()的话就会返回此值。

taskSCHEDULER_RUNNING: 调度器正在运行。
taskSCHEDULER_SUSPENDED: 调度器挂起。

15. 函数 uxTaskGetNumberOfTasks()

此函数用于查询系统当前存在的任务数量,函数原型如下:

UBaseType_t uxTaskGetNumberOfTasks( void )

参数: 无。
返回值: 当前系统中存在的任务数量, 此值=挂起态的任务+阻塞态的任务+就绪态的任务 +空闲任务+运行态的任务。

16. 函数 vTaskList()

此函数会创建一个表格来描述每个任务的详细信息,如下图所示:
在这里插入图片描述
表中的信息如下:
Name: 创建任务的时候给任务分配的名字。
State: 任务的壮态信息,B 是阻塞态,R 是就绪态,S 是挂起态,D 是删除态。
Priority:任务优先级。
Stack: 任务堆栈的“高水位线”,就是堆栈历史最小剩余大小。
Num: 任务编号,这个编号是唯一的,当多个任务使用同一个任务名的时候可以通过此
编号来做区分。

函数原型如下:

void vTaskList( char * pcWriteBuffer )

参数:
pcWriteBuffer: 保存任务壮态信息表的存储区。存储区要足够大来保存任务状态信息表。
返回值:

17. 函数 vTaskGetRunTimeStats()

FreeRTOS 可以通过相关的配置来统计任务的运行时间信息,任务的运行时间信息提供了
每个任务获取到 CPU 使用权总的时间。函数 vTaskGetRunTimeStats()会将统计到的信息填充到一个表里面,表里面提供了每个任务的运行时间和其所占总时间的百分比,如下图所示:
在这里插入图片描述函 数 vTaskGetRunTimeStats() 是 一 个 很 实 用 的 函 数 , 要 使 用 此 函 数 的 话 宏
configGENERATE_RUN_TIME_STATS 和configUSE_STATS_FORMATTING_FUNCTIONS 必须都为 1。如果宏 configGENERATE_RUN_TIME_STATS 为 1 的话还需要实现一下几个宏定义:
● portCONFIGURE_TIMER_FOR_RUN_TIME_STATS(),此宏用来初始化一个外设来
提供时间统计功能所需的时基,一般是定时器/计数器。这个时基的分辨率一定要比 FreeRTOS的系统时钟高,一般这个时基的时钟精度比系统时钟的高 10~20 倍就可以了。
● portGET_RUN_TIME_COUNTER_VALUE()或者portALT_GET_RUN_TIME_COUNTER_VALUE(Time),这两个宏实现其中一个就行
了,这两个宏用于提供当前的时基的时间值。

函数原型如下:

void vTaskGetRunTimeStats( char *pcWriteBuffer )

参数:
pcWriteBuffer: 保存任务时间信息的存储区。存储区要足够大来保存任务时间信息。
返回值:

18. 函数 vTaskSetApplicationTaskTag()

此函数是为高级用户准备的,此函数用于设置某个任务的标签值 ,这个标签值的具体函数
和用法由用户自行决定,FreeRTOS 内核不会使用这个标签值,如果要使用此函数的话宏
configUSE_APPLICATION_TASK_TAG 必须为 1,函数原型如下:

void vTaskSetApplicationTaskTag( TaskHandle_t xTask, 
								 TaskHookFunction_t pxHookFunction )

参数:
xTask: 要设置标签值的任务,此值为 NULL 的话表示设置自身任务的标签值。
pxHookFunction: 要设置的标签值,这是一个 TaskHookFunction_t 类型的函数指针,但是也可以设置为其他值。
返回值:

19. 函数 SetThreadLocalStoragePointer()

此函数用于设置线程本地存储指针的值,每个任务都有它自己的指针数组来作为线程本地
存储,使用这些线程本地存储可以用来在任务控制块中存储一些应用信息,这些信息只属于任务 自 己 的 。 线 程 本 地 存 储 指 针 数 组 的 大 小 由 宏
configNUM_THREAD_LOCAL_STORAGE_POINTERS 来决定的。如果要使用此函数的话宏configNUM_THREAD_LOCAL_STORAGE_POINTERS 不能为 0,宏的具体值是本地存储指针数组的大小,函数原型如下:

void vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, 
										BaseType_t xIndex, 
										void * pvValue )

参数:
xTaskToSet: 要设置线程本地存储指针的任务的任务句柄,如果是 NULL 的话表示设置任务自身的线程本地存储指针。
xIndex: 要设置的线程本地存储指针数组的索引。
pvValue: 要存储的值。
返回值:

20. 函数 GetThreadLocalStoragePointer()

此函数用于获取线程本地存储指针的值, 如 果 要 使 用 此 函 数 的 话 宏
configNUM_THREAD_LOCAL_STORAGE_POINTERS 不能为 0,函数原型如下:

void *pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, 
										  BaseType_t xIndex )

参数:
xTaskToSet: 要获取的线程本地存储指针的任务句柄,如果是 NULL 的话表示获取任务自身的线程本地存储指针。
xIndex: 要获取的线程本地存储指针数组的索引。
返回值: 获取到的线程本地存储指针的值。

三、任务壮态查询 API 函数实验

FreeRTOS 与任务相关的 API 函数中有很多是与任务壮态或者信息查询有关的,比如函数
uxTaskGetSystemState()、vTaskGetInfo()、eTaskGetState()和 vTaskList()。

1. 实验目的
学习使用FreeRTOS与任务壮态或者信息查询有关的API函数,包uxTaskGetSystemState()、
vTaskGetInfo()、eTaskGetState()和 vTaskList()。

2. 实验设计
本实验设计三个任务:start_task、led0_task 和 query_task ,这三个任务的任务功能如下:
start_task:用来创建其他 2 个任务。
led0_task :控制 LED0 灯闪烁,提示系统正在运行。
query_task :任务壮态和信息查询任务,在此任务中学习使用与任务的壮态和信息查询有
关的 API 函数。
实验需要一个按键 KEY_UP,这个按键的功能如下:
KEY_UP: 控制程序的运行步骤。

3. 实验程序与分析

●任务设置
实验中任务优先级、堆栈大小和任务句柄等的设置如下:

#define START_TASK_PRIO 1 //任务优先级
#define START_STK_SIZE 128 //任务堆栈大小
TaskHandle_t StartTask_Handler; //任务句柄
void start_task(void *pvParameters); //任务函数
#define LED0_TASK_PRIO 2 //任务优先级
#define LED0_STK_SIZE 128 //任务堆栈大小
TaskHandle_t Led0Task_Handler; //任务句柄
void led0_task(void *pvParameters); //任务函数
#define QUERY_TASK_PRIO 3 //任务优先级
#define QUERY_STK_SIZE 256 //任务堆栈大小
TaskHandle_t QueryTask_Handler; //任务句柄
void query_task(void *pvParameters); //任务函数
char InfoBuffer[1000]; //保存信息的数组

● main()函数

int main(void)
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组 4
	delay_init(); //延时函数初始化
	uart_init(115200); //初始化串口
	LED_Init(); //初始化 LED
	KEY_Init(); //初始化按键
	LCD_Init(); //初始化 LCD
	POINT_COLOR = RED;
	LCD_ShowString(30,10,200,16,16,"ATK STM32F103/407");
	LCD_ShowString(30,30,200,16,16,"FreeRTOS Examp 11-1");
	LCD_ShowString(30,50,200,16,16,"Task Info Query");
	LCD_ShowString(30,70,200,16,16,"ATOM@ALIENTEK");
	LCD_ShowString(30,90,200,16,16,"2016/11/25");
	
	 //创建开始任务
	 xTaskCreate((TaskFunction_t )start_task, //任务函数
	 (const char* )"start_task", //任务名称
	 (uint16_t )START_STK_SIZE, //任务堆栈大小
	 (void* )NULL, //传递给任务函数的参数
	 (UBaseType_t )START_TASK_PRIO, //任务优先级
	 (TaskHandle_t* )&StartTask_Handler); //任务句柄 
	 vTaskStartScheduler(); //开启任务调度
}

在 main 函数中我们主要完成硬件的初始化,在硬件初始化完成以后创建了任务 start_task()
并且开启了 FreeRTOS 的任务调度。

● 任务函数

//led0 任务函数
void led0_task(void *pvParameters)
{
	while(1)
	{
		 LED0=~LED0;
		 vTaskDelay(500); //延时 500ms,也就是 500 个时钟节拍
	}
}

//query 任务函数
void query_task(void *pvParameters)
{
	u32 TotalRunTime;
	UBaseType_t ArraySize,x;
	TaskStatus_t *StatusArray;
	//第一步:函数 uxTaskGetSystemState()的使用
	printf("/********第一步:函数 uxTaskGetSystemState()的使用**********/\r\n");
	ArraySize=uxTaskGetNumberOfTasks(); //获取系统任务数量 (1)
	StatusArray=pvPortMalloc(ArraySize*sizeof(TaskStatus_t)); //申请内存 (2)
	if(StatusArray!=NULL) //内存申请成功
	{
		ArraySize=uxTaskGetSystemState((TaskStatus_t* )StatusArray, (3)
		(UBaseType_t )ArraySize, 
		(uint32_t* )&TotalRunTime);
		printf("TaskName\t\tPriority\t\tTaskNumber\t\t\r\n");
		for(x=0;x<ArraySize;x++)
		{
			//通过串口打印出获取到的系统任务的有关信息,比如任务名称、
			//任务优先级和任务编号。
			printf("%s\t\t%d\t\t\t%d\t\t\t\r\n", (4)
			StatusArray[x].pcTaskName,
			(int)StatusArray[x].uxCurrentPriority,
			(int)StatusArray[x].xTaskNumber);
		}
	}
	vPortFree(StatusArray); //释放内存 (5)
	printf("/**************************结束***************************/\r\n");
	printf("按下 KEY_UP 键继续!\r\n\r\n\r\n");
	while(KEY_Scan(0)!=WKUP_PRES) delay_ms(10); //等待 KEY_UP 键按下
	
	//第二步:函数 vTaskGetInfo()的使用
	TaskHandle_t TaskHandle;
	TaskStatus_t TaskStatus;
	printf("/************第二步:函数 vTaskGetInfo()的使用**************/\r\n");
	TaskHandle=xTaskGetHandle("led0_task"); //根据任务名获取任务句柄。 (6)
	//获取 LED0_Task 的任务信息
	vTaskGetInfo((TaskHandle_t )TaskHandle, //任务句柄 (7)
	(TaskStatus_t* )&TaskStatus, //任务信息结构体
	(BaseType_t )pdTRUE, //允许统计任务堆栈历史最小剩余大小
	 (eTaskState )eInvalid); //函数自己获取任务运行壮态
	//通过串口打印出指定任务的有关信息。
	printf("任务名: %s\r\n",TaskStatus.pcTaskName); (8)
	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);
	printf("/**************************结束***************************/\r\n");
	printf("按下 KEY_UP 键继续!\r\n\r\n\r\n");
	while(KEY_Scan(0)!=WKUP_PRES) delay_ms(10); //等待 KEY_UP 键按下
	
	//第三步:函数 eTaskGetState()的使用
	eTaskState TaskState;
	char TaskInfo[10];
	printf("/***********第三步:函数 eTaskGetState()的使用*************/\r\n");
	TaskHandle=xTaskGetHandle("query_task"); //根据任务名获取任务句柄。 (9)
	TaskState=eTaskGetState(TaskHandle); //获取 query_task 任务的任务壮态 (10)
	memset(TaskInfo,0,10); //数组清零
	switch((int)TaskState) (11)
	{
		case 0:sprintf(TaskInfo,"Running");break;
		case 1:sprintf(TaskInfo,"Ready");break;
		case 2:sprintf(TaskInfo,"Suspend");break;
		case 3:sprintf(TaskInfo,"Delete");break;
		case 4:sprintf(TaskInfo,"Invalid");break;
	}
	printf("任务壮态值:%d,对应的壮态为:%s\r\n",TaskState,TaskInfo); (12)
	printf("/**************************结束**************************/\r\n");
	printf("按下 KEY_UP 键继续!\r\n\r\n\r\n");
	while(KEY_Scan(0)!=WKUP_PRES) delay_ms(10); //等待 KEY_UP 键按下
	
	//第四步:函数 vTaskList()的使用
	printf("/*************第三步:函数 vTaskList()的使用*************/\r\n");
	vTaskList(InfoBuffer); //获取所有任务的信息 (13)
	printf("%s\r\n",InfoBuffer); //通过串口打印所有任务的信息 (14)
	while(1)
	{
		 LED1=~LED1;
		 vTaskDelay(1000); //延时 1s,也就是 1000 个时钟节拍
	}
}

(1)、使用函数 uxTaskGetNumberOfTasks()获取当前系统中的任务数量,因为要根据任务数
量给任务信息数组 StatusArray 分配内存。注意,这里 StatusArray 是个指向 TaskStatus_t 类型的指针,但是在使用的时候会把他当作一个数组来用。

(2)、调用函数 pvPortMalloc()给任务信息数组 StatusArray 分配内存,数组是 TaskStatus_t 类型。

(3)、调用函数 uxTaskGetSystemState()获取系统中所有任务的信息,并将获取到的信息保存在 StatusArray 中。

(4)、通过串口将获取到的所有任务的部分信息打印出来,这里并没有把所获取到的信息都
输出,只是将任务的任务名、任务优先级和任务编号做了输出。

(5)、任务信息数组 StatusArray 使用完毕,释放其内存。

(6)、调用函数xTaskGetHandle()根据任务名来获取任务句柄,这里获取任务名为“led0_task”
的任务句柄。我们在创建任务的时候一般都会保存任务的句柄,如果保存了任务句柄的话就可以直接使用。

(7)、调用函数 vTaskGetInfo()获取任务名为“led0_task”的任务信息,任务信息保存在
TaskStatus 中。获取任务信息的时候允许统计任务堆栈历史最小剩余大小,任务的运行壮态也是由函数 vTaskGetInfo()来统计。

(8)、通过串口输出获取到的任务 led0_task 的任务信息。

(9)、通过函数 xTaskGetHandle()获取任务名为“query_task”的任务句柄。

(10)、调用函数 eTaskGetState()获取任务的运行壮态。

(11)、通过函数 eTaskGetState()获取到的任务运行壮态是个枚举类型:eTaskState,枚举类型不同的值表示不同的含义,这里用字符串来描述这些枚举值的含义。

(12)、通过串口输出任务 query_task 的运行壮态信息。

(13)、调用函数 vTaskList()统计所有任务的信息,统计出来的任务信息存储在缓冲区
InfoBuffer 中,这些任务信息以表格的形式呈现,

(14)、通过串口输出保存在缓冲区 InfoBuffer 中的任务信息。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/447894.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

(十二)rk3568 NPU 中部署自己训练的模型,(1)使用yolov5训练自己的数据集-模型训练部分

一、rknn的demo中已经给了yolov5的后处理demo。但是这个后处理只适合yolov5特定版本(v5.0),还有下载特定的分支,如下为下载位置:。 下载地址 ONNX > CoreML > TFLite">GitHub - ultralytics/yolov5: YOLOv5 🚀 in PyTorch > ONNX > CoreML > T…

LeetCode 27.移除元素

文章目录 &#x1f4a1;题目分析&#x1f4a1;解题思路&#x1f6a9;思路1:暴力求解 --- 遍历&#x1f514;接口源码&#xff1a;&#x1f6a9;思路2:空间换时间&#x1f514;接口源码&#xff1a;&#x1f6a9;思路3:双指针&#xff08;快慢指针&#xff09;&#x1f514;接口…

Linux系统之部署Samba服务

Linux系统之部署Samba服务 一、Samba服务介绍1.Samba服务简介2.NFS和CIFS简介3.Smaba服务相关包4.samba监听端口4.samba相关工具及命令 二、环境规划介绍1.环境规划2.本次实践介绍 三、Samba服务端配置1.检查yum仓库2.安装smaba相关软件包3.创建共享目录4.设置共享目录权限5.新…

Adobe认证证书

Adobe认证证书是Adobe公司颁发的一种专业认证证书&#xff0c;用于证明持有人在相关Adobe软件的使用和应用方面具有专业水平。该证书是业内公认的专业认证&#xff0c;具有较高的价值和认可度&#xff0c;可以帮助持有人提高职业竞争力和工作效率。 Adobe公司提供了多种认证考…

CentOS7(三)MySQL8 Redis7 (单机)安装

文章目录 一、MySQL安装1、确认是否有老版本2、在线安装3、本地安装 二、启动MySQL三、MySQL常用配置1、密码修改2、配置远程登录3、开启防火墙 3306 端口4、 报错5、MySQL中Java写入时间少14小时 四、Redis 安装1、安装Redis依赖2、启动redis3、指定配置启动 & 后台运行4、…

手机端H5地图调起开发实战案例解析(百度高德腾讯地图调起、底部弹出层、提示安装地图导航APP)

文章目录 1.导航菜单配置构建导航菜单容器设置取消事件调起菜单样式表 2.地图调起事件导航到这里获取导航坐标百度坐标系 (BD-09) 与 火星坐标系 (GCJ-02)的转换 3.地图调起效果 地图调起功能&#xff0c;是地图URI API是为开发者提供直接调起地图产品&#xff08;手机客户端&a…

nextjs13临时笔记

动态路由 文件夹以中括号命名[id] -pages: --list: ---[id]: ----index.jsx(访问路径/list/1 即这种形式/list/:id) ---index.jsx(访问路径/list)[...params]gpt接口分析 初始化项目 npm install next react react-dom # or yarn add next react react-dom # or pnpm add n…

WPF教程(六)--依赖属性(2)--属性值优先级与继承

一、 依赖属性的优先级 由于WPF 允许我们可以在多个地方设置依赖属性的值&#xff0c;所以我们就必须要用一个标准来保证值的优先级别。比如下面的例子中&#xff0c;我们在三个地方设置了按钮的背景颜色&#xff0c;那么哪一个设置才会是最终的结果呢&#xff1f;是Black、Re…

[oeasy]python0136_接收输入_input函数_字符串_str

输入变量 回忆上次内容 上次研究了 一行赋值多个变量 a b 5a, b 7, 8 还研究了 标识符的惯用法 python使用的是 snake_case蛇形命名法用下划线 分隔开小写字母的 方法这样就可以 更合理地 命名变量了 变量变量 能变的量我可以 手工输入变量的值 吗&#xff1f;&#x1f9…

MongoDB 数据库数据导入 - 关于如何使用 csv 导入数据的命令方法、图形界面可视化导入方法

序言 兴趣使然&#xff0c;突发奇想&#xff0c;想到了就写&#xff0c;就当打发时间了。 一、使用 csv 导入数据的命令方法 csv文件路径问题&#xff0c;绝对路径和相对路径都可以 方法1 type 没有号&#xff0c;也是可以的&#xff0c;空格自动识别 将测试表.csv 文件导…

pikachu靶场-csrf

csrf 跨站请求伪造&#xff08;英语&#xff1a;Cross-site request forgery&#xff09;&#xff0c;也被称为 one-click attack 或者 session riding&#xff0c;通常缩写为 CSRF 或者 XSRF&#xff0c; 是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方…

【C++ 六】内存分区、引用

内存分区、引用 文章目录 内存分区、引用前言1 内存分区模型1.1 程序运行前1.2 程序运行后1.3 new 操作符 2 引用2.1 引用基本使用2.2 引用注意事项2.3 引用做函数参数2.4 引用做函数返回值2.5 引用本质2.6 常量引用 总结 前言 本文包含内存分区、引用基本使用、引用注意事项、…

记一次完整的rc.local中启动python脚本报psutil找不到问题解决

文章目录 1&#xff0c;问题1.1&#xff0c;rc.local1.2&#xff0c;watchdog.py 2&#xff0c;问题排查2.1&#xff0c;手动执行start.sh后功能正常2.2&#xff0c;开机启动后rc.local加载start.sh&#xff0c;然后start.sh启动python脚本报错2.3&#xff0c;怀疑是rc.local加…

SAP S/4HANA不是ERP了?

今天浏览了一下SAP官方帮助&#xff08;Help&#xff09;网站&#xff0c;有一个意外的发现&#xff0c;如上图&#xff1a;SAP S/4HANA和SAP ERP是分别显示的&#xff0c;这让我想起了前段时间一个朋友和我说&#xff1a;“S/4HANA现在都不叫ERP了&#xff0c;因为里面包括了超…

【C++初阶】C++入门(一):命名空间C++的输入输出缺省参数函数重载

​ ​&#x1f4dd;个人主页&#xff1a;Sherry的成长之路 &#x1f3e0;学习社区&#xff1a;Sherry的成长之路&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;数据结构 &#x1f3af;长路漫漫浩浩&#xff0c;万事皆有期待 文章目录 1.什么是C1.1 C的发…

最新Tuxera NTFS2023最新版Mac读写NTFS磁盘工具 更新详情介绍

Tuxera NTFS for Mac是一款Mac系统NTFS磁盘读写软件。在系统默认状态下&#xff0c;MacOSX只能实现对NTFS的读取功能&#xff0c;Tuxera NTFS可以帮助MacOS 系统的电脑顺利实现对NTFS分区的读/写功能。Tuxera NTFS 2023完美兼容最新版本的MacOS 11 Big Sur&#xff0c;在M1芯片…

Python统计学:如何理解样本统计量?

本期介绍样本统计量是怎么算的&#xff0c;并用Python来模拟随机抽样。用一个在鱼塘捞鱼的简单例子来理解样本均值的概念。 如何理解重复试验&#xff1f; 指能够在完全相同条件下进行多次的试验&#xff1b; 比如我们抛10枚硬币&#xff0c;用来计算正面出现的概率&#xff…

4.7 贝塞尔曲线

学习目标&#xff1a; 学习贝塞尔曲线可以遵循以下步骤&#xff1a; 1.了解基本概念和定义&#xff1a;学习贝塞尔曲线前需要了解贝塞尔曲线的基本概念和定义&#xff0c;如何定义一条贝塞尔曲线、控制点的概念以及贝塞尔曲线的几何性质等。 2.学习贝塞尔曲线的构造方法&…

Django搭建一个简易GPT网站

文章目录 环境安装创建主项目和应用程序在 settings.py 文件中注册应用程序在 views.py 文件中为应用程序创建视图配置应用程序的 URL创建和渲染模板KEY实现发送提示功能注意事项完整源码 环境安装 pip install django openai创建主项目和应用程序 处理完项目的环境后&#x…

第二个机器学习应用:乳腺癌数据集在决策树模型上的挖掘

目录 决策树优化与可视化 1 决策树分类 2 决策树可视化 3 显示树的特征重要性 特征重要性可视化 决策树回归 1 决策树回归 决策树优化与可视化 1 决策树分类 from sklearn.datasets import load_breast_cancer from sklearn.tree import DecisionTreeClassifier from sk…