osThreadNew创建新任务。
当使用这个函数创建新任务时,该函数会返回一个osThreadId_t类型的值。
实际上该函数是调用xTaskCreate或xTaskCreateStatic来创建任务的,前者会返回BaseType_t类型并通过指针返回句柄,后者会返回TaskHandle_t类型。
不论是那种方式,最终任务句柄都会被osThreadNew返回。
xTaskGetCurrentTaskHandle获取当前任务句柄。
使用场景:
- 创建任务是未保存该任务句柄;
- 多个任务都会调用某一函数,函数内部需要知道到底是哪个任务调用的;
- 多任务通信,需要告诉对方自己的句柄。
xTaskGetIdleTaskHandle获取空闲任务句柄。
可以通过统计空闲任务运行时间来得到实际 CPU 利用率。
最开始这个函数是默认不编译的,并且不能在 cubemx 里设置。
如果你需要这个任务,请在
FreeRTOSConfig.h里自己添加宏定义:
xTaskGetHandle工具任务名称获取任务句柄,同样默认不编译,但可以通过 cubemx 启用。
通过任务名称字符串查询任务句柄,当两个任务具有相同的名称时,返回结果不确定。
注意,该函数查询所需的时间可能会很长,不建议频繁使用。
uxTaskPriorityGet通过句柄返回对应任务的优先级,UBaseType_t类型。
当传递 null 时,返回当前正在运行的任务的优先级。
除此之外,它还有用于中断函数里的版本uxTaskPriorityGetFromISR,传入 null 时,会返回被当前中断打断的任务优先级。
这主要是为了系统的绝对稳定和兼容不同架构的处理机制:
uxTaskPriorityGet() 使用的是 taskENTER_CRITICAL()。它假设你目前处于任务态(Thread Mode),直接去操作 CPU 的中断屏蔽寄存器。uxTaskPriorityGetFromISR() 使用的是 portSET_INTERRUPT_MASK_FROM_ISR()。由于你已经处于中断态(Handler Mode),甚至可能处于中断嵌套中,这个函数会非常小心地保存当前的中断屏蔽状态,读取完数据后,再原封不动地恢复回去。如果你在中断里调用了普通的 uxTaskPriorityGet,它的临界区操作可能会错误地完全打开中断,破坏中断嵌套的优先级逻辑,直接导致 ARM 处理器触发 HardFault(硬错误)死机。
vTaskPrioritySet通过句柄设置任务的优先级。
句柄传递为 null 时,设置当前任务的优先级。
当传入 CMSIS2 里定义的枚举型时,需要强转为UBaseType_t。
vTaskGetInfo获取单个任务信息。
void vTaskGetInfo( TaskHandle_t xTask,
TaskStatus_t *pxTaskStatus,
BaseType_t xGetFreeStackSpace,
eTaskState eState );xTask (目标任务句柄): 想查询的那个任务的句柄。如果传入 NULL,查询当前正在运行的任务(。pxTaskStatus (状态结构体指针): 需要提前定义一个 TaskStatus_t 类型的变量,把它的地址传进去。函数会将任务信息返回到该地址。xGetFreeStackSpace (是否计算剩余栈空间):pdTRUE:系统会去计算该任务的历史最小剩余栈空间(High Water Mark)。注意:计算栈空间需要遍历未使用的栈内存,比较耗时。pdFALSE:跳过计算,结构体里的栈剩余字段将被设为 0。如果为了追求极速执行,建议传这个。eState (任务当前状态):eBlocked, eSuspended 等),可以直接传进去,这样能省去系统自己去查找状态的时间。eInvalid,FreeRTOS 的调度器会自动去各个状态的链表里寻找到它的真实状态。函数执行完毕后,你可以从传入的结构体中读取到以下数据:
xHandle: 任务句柄。pcTaskName: 任务名称(字符串指针)。xTaskNumber: 任务的唯一编号(创建时的序号)。eCurrentState: 当前状态(如就绪、阻塞、挂起等枚举值)。uxCurrentPriority: 当前的真实优先级(如果任务使用了互斥锁并发生了优先级继承,这个值可能会高于它的初始优先级)。uxBasePriority: 任务创建时的初始基准优先级。ulRunTimeCounter: 任务总共占用 CPU 的运行时间(前提是开启了运行时间统计宏)。usStackHighWaterMark: 栈区历史最低剩余容量(注意:单位是“字 (Word)”,在 32 位系统上 1 个字 = 4 字节)。pcTaskGetName通过句柄获取任务名称字符串。
uxTaskGetStackHighWaterMark通过句柄获取栈区历史最低剩余容量(栈高水位值)。
除此之外,还有uxTaskGetStackHighWaterMark2,用于更好的兼容不同位的单片机。在 32 位控制器上,两者表现完全一致。
eTaskGetState通过句柄获取任务状态,返回eTaskState型。
uxTaskGetNumberOfTasks返回当前任务总数,包括就绪、阻塞、运行、挂起和虽然删除但仍未释放的任务。
vTaskList以字符串表格的形式展示所有任务情况。默认不编译。
需要传入一个足够大的字符串数组,且 freertos 不会检查数组大小。
该函数使用 sprintf 函数,会使编译后的固件大小明显增大,最好仅在调试中使用。
uxTaskGetSystemState获取系统内所有任务的状态,并返回到参数指定的数组里。函数返回值表示成功填入数组的数据的数量
UBaseType_t uxTaskGetSystemState(
TaskStatus_t * const pxTaskStatusArray,
const UBaseType_t uxArraySize,
uint32_t * const pulTotalRunTime
);pxTaskStatusArray (任务状态数组指针)TaskStatus_t 类型的数组,然后把这个数组的首地址传给它。FreeRTOS 会把扫描到的所有任务的详细状态信息(如任务名字、当前状态、优先级、剩余堆栈等)逐一填入这个数组中。uxArraySize (数组容量)uxTaskGetNumberOfTasks() 获取当前系统真实存在的任务总数,并据此来设定数组大小。如果传入的 uxArraySize 小于当前系统中实际存在的任务总数,函数为了防止内存越界,会直接放弃操作,返回 0,并且不会向数组中写入任何有效数据。pulTotalRunTime (系统总运行时间指针)ulRunTimeCounter(该任务独立的运行时间)一起使用,通过简单的除法就可以计算出每个任务占据 CPU 时间的百分比。如果你不需要计算 CPU 占用率,或者没有开启运行时间统计宏,可以直接给这个参数传入 NULL,FreeRTOS 就会安全地忽略它。vTaskGetRunTimeStats以文字表格的形式返回每个任务的运行时间。
该函数会在调用时禁用所有中断,因此尽量不要在正常运行时调用它。
xTaskGetSchedulerState获取调度器状态的函数。
taskSCHEDULER_NOT_STARTED (未启动):main() 函数里进行了一堆外设初始化(比如初始化 GPIO、I2C),创建了几个任务,但还没有调用 vTaskStartScheduler()(或者 CMSIS-RTOS 封装的 osKernelStart())之前。taskSCHEDULER_RUNNING (正在运行):taskSCHEDULER_SUSPENDED (已挂起):vTaskSuspendAll() 强行“冻结”了。在这个状态下,哪怕有更高优先级的任务就绪了,也不会发生上下文切换,直到调用 xTaskResumeAll() 为止。(注:挂起调度器不会关闭硬件中断,但中断里不能要求切换任务)。