注:在使用大多数功能时,FreeRTOS都要将对应的宏置为1,具体的需要查看FreeRTOS官方文档。
任务相关的API函数非常多,本章总结以下几个任务函数,如果需要详细了解所有函数,建议查看FreeRTOS官网。
API函数的使用步骤:
1.将对应宏置为 1
2.定义函数的入口参数
3.编写任务函数
API函数基础
获取任务优先级
1.uxTaskPriorityGet():
UBaseType_t uxTaskPriorityGet(const TaskHandle_t xTask);
参数:
- xTask:待获取优先级的任务
该函数由整数类型返回值,返回值表示任务的优先级数值
设置任务优先级
1.vTaskPrioritySet():
void vTaskPrioritySet(TaskHandle_t xTask,UBaseType_t uxNewPriority);
参数:
- xTask:待设置优先级的任务
- uxNewPriority:待设置的优先级数值
获取任务数量
1.uxTaskGetNumberOfTasks():
UBaseType_t uxTaskGetNumberOfTasks(void);
参数:
- 无输入参数
返回值为整数,表示总任务数量 。
获取所有任务的状态信息
1.uxTaskGetSystemState():
UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray,
const UBaseType_t uxArraySize,
configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime );
参数:
- pxTaskStatusArray:接收信息变量数组的首地址,指向的是结构体TaskStatus_t的首地址
- uxArraySize:接收信息变量数组的大小
- pulTotalRunTime:系统总运行时间
返回值是一个整数,表示的是信息的任务数量。
在使用该函数时,我们需要通过 malloc()函数去申请一个内存,内存的类型为 TaskStatus_t* ,申请如下,
这个函数表示申请的是内部内存SRAMIN,申请的大小和任务数量相关。
TaskStatus_t类型结构体如下,
typedef struct xTASK_STATUS
{
TaskHandle_t xHandle; /* 任务句柄 */
const char * pcTaskName; /* 任务名 */
UBaseType_t xTaskNumber; /* 任务编号 */
eTaskState eCurrentState; /* 任务状态 */
UBaseType_t uxCurrentPriority; /* 任务优先级 */
UBaseType_t uxBasePriority; /* 任务原始优先级 */
configRUN_TIME_COUNTER_TYPE ulRunTimeCounter; /* 任务被分配的运行时间 */
StackType_t * pxStackBase; /* 任务栈的基地址 */
configSTACK_DEPTH_TYPE usStackHighWaterMark; /* 任务栈历史剩余最小值 */
} TaskStatus_t;
获取指定任务信息
2.vTaskGetInfo():
void vTaskGetInfo( TaskHandle_t xTask,
TaskStatus_t * pxTaskStatus,
BaseType_t xGetFreeStackSpace,
eTaskState eState );
参数:
- xTask:想要获取信息的任务的任务句柄
- pxTaskStatus:接收信息变量数组的首地址,指向的是结构体TaskStatus_t的首地址
- xGetFreeStackSpace:任务栈历史剩余最小值,需要获取输入pdTURE
- eStata:获取任务状态,比如就绪态,运行态等
状态表如下,运行态则表示0,往后依次加
获取历史剩余最小堆栈
2.uxTaskGetStackHighWaterMark():
UBaseType_t uxTaskGetStackHighWaterMark(TaskHandle_t xTask);
参数:
- xTask:想要获取信息的任务的任务句柄
返回值为整数,表示任务历史剩余最小堆栈的大小
获取系统任务信息(表格)
2.vTaskList():
void vTaskList(char * pcWriteBuffer);
参数:
- pcWriteBuffer:接收任务信息的缓存指针
在使用该函数时,我们要创建一个数组,用来存储相关的任务信息即可,打印结果示例如下,
每一个参数表示如下,
- Name:任务名字,创建时自己分配
- State:任务状态,状态表在上面可见
- Priority:任务优先级
- Stack:任务的历史最小堆栈剩余大小
- Num:任务编号,这个编号是唯一的,多个任务用同一个任务名时,这个用来区分
获取任务运行时间
2.vTaskGetRunTimeStats():
vvoid vTaskGetRunTimeStats(char * pcWriteBuffer);
参数:
- pcWriteBuffer:接收任务运行时间和状态等信息的缓存指针
运行结果示例,
每一个参数表示如下,
- Task:任务名字,创建时自己分配
- Abs Time:任务实际运行总时间(绝对时间)
- %Time:占总处理时间的百分比
这个函数的使用需要一定步骤,如下,
- 将宏 configGENERATE_RUN_TIME_STATS 置1
- 将宏 configUSE_STATS_FORMATTING_FUNCTIONS置1
- 将宏 configSUPPORT_DYNAMIC_ALLOCATION置1
- 在将上述宏置1以后,还需要实现2个宏定义
- portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()用来实现时基定时器的初始化,这个时基定时器的精度需要高于系统节拍精度的10-100倍
- portGET_RUN_TIME_COUNTER_VALUE()返回当前时间,获取时基单元的计数值
备注:这两个宏对应两个函数,这两个函数需要我们自己编写 。
时间管理(延时函数)
延时函数包括两种,相对延时和绝对延时。
相对延时:表示每次延时都是从执行函数vTaskDelay()开始,直到延时指定时间结束
绝对延时:表示将整个任务的运行周期看出一个整体,适用于需要按照一定频率运行的任务
绝对延时示意图
延时函数解析
函数prvAddCurrentTaskToDelayedList解析
上述的解析,大家可以对照源码解析分析,总体来说还是很简单的。