xTaskCreate()
BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,
const char * const pcName,
const uint16_t usStackDepth,
void * const pvParameters,
UBaseType_t uxPriority,
TaskHandle_t * const pxCreatedTask )
创建任务
- 运行的结果看似两个任务同时执行,但实际上是调度器快速地将两个任务不间断地在运行态和非运行态间进行切换,因此,两个任务看似同时都得到了执行,这也是操作系统的基本功能之一
任务的状态
“阻塞态”(blocked)
任务正在等待某个事件:
定时事件——这类事件可以是延迟到期或是绝对时间到点。例如,某个任务延迟10ms进入阻塞态。
同步事件——等待其他任务或中断的事件。比如,某个任务可以进入阻塞态以等待队列中有数据到来。
任务可以在进入阻塞态以等待同步事件的同时指定一个等待时限,这样可以有效地实现阻塞态下同时等待两种类型的事件。比如说,某个任务可以等待队列中有数据到来,时限为10ms,若10ms内有数据到来或10ms后没有数据到来,任务都将退出阻塞态
“就绪态”(ready)
具备运行条件,等待调度器调度
vTaskDelay()
void vTaskDelay( const TickType_t xTicksToDelay )
//指定任务在调用函数到切出阻塞态整个过程包含多少个心跳周期
- 任务保持在阻塞态的时间量由vTaskDelay()的入口参数指定,但任务离开阻塞态的时刻实际上是相对于vTaskDelay()被调用那一刻的。
vTaskDelayUntil()
void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime,
const TickType_t xTimeIncrement )
//指定任务离开阻塞态进入就绪态那一刻的精确心跳计数值
- 本例在优先级1上创建2个任务。这两个任务没有调用任何可能导致它们进入阻塞态的API函数,只是不停地打印输出字符串。因此这两个任务要么处于就绪态,要么处于运行态。具有这种性质的任务称为“持续处理”任务
- 第三个任务创建在优先级2上,高于另外两个任务的优先级。这个任务调用vTaskDelayUntil()周期性地打印输出字符串,在每两次打印之间让自己处于阻塞态
空闲任务回调函数
void vApplicationIdleHook( void )
- 空闲任务是一个非常短小的循环,总是处于就绪态。空闲任务拥有最低优先级,以保证具有更高优先级的应用任务能够进入运行态
- 当所有的任务都处于非运行状态,调度器会自动创建一个空闲任务
- 通常空闲任务回调函数被用于:
执行低优先级,后台或需要不停处理的功能代码。
系统性能统计,通过测量空闲任务占用的处理时间计算系统的处理时间裕量。
降低功耗,使得在没有任何应用功能需要处理的时候,系统自动进入低功耗模式。 - 空闲任务回调函数必须遵从以下规则:
绝不能阻塞或挂起。空闲任务只会在其他任务都不运行时才会被执行。以任何方式阻塞空闲任务都可能导致没有任务能够进入运行态。
如果应用程序用到了vTaskDelete()函数,则空闲回调函数必须能够尽快返回。因为在任务被删除后,空闲任务负责回收内核资源。如果空闲任务一直运行在回调函数中,则无法进行回收工作。
vTaskPrioritySet()
void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority )
//用于在调度器启动后改变任何任务的优先级
uxTaskPriorityGet
UBaseType_t uxTaskPriorityGet( TaskHandle_t xTask )
//用于查询一个任务的优先级
vTaskDelete()
void vTaskDelete( TaskHandle_t xTaskToDelete )