1、什么是任务
(1)在FreeRTOS中,任务就是一个函数,原型如下。
void ATaskFunction( void *pvParameters );
(2)注意点。
- 任务这个函数不能返回。
- 同一个函数,可以用来创建多个任务;换句话说,多个任务可以运行同一个函数。
- 函数内部,尽量使用局部变量:每个任务都有自己的栈,每个任务运行这个函数时,任务A的局部变量放在任务A的栈里、任务B的局部变量放在任务B的栈里。不同任务的局部变量,有自己的副本。
- 函数使用全局变量、静态变量的话。只有一个副本:多个任务使用的是同一个副本,要防止冲突。
(3)示例。
void ATaskFunction( void *pvParameters )
{
/* 对于不同的任务,局部变量放在任务的栈里,有各自的副本 */
int32_t lVariableExample = 0;
/* 任务函数通常实现为一个无限循环 */
while(1)
{
/* 任务的代码 */
}
/* 如果程序从循环中退出,一定要使用vTaskDelete删除自己
* NULL表示删除的是自己
*/
vTaskDelete( NULL );
/* 程序不会执行到这里, 如果执行到这里就出错了 */
}
2、任务创建与删除相关API函数
(1)可以参考官网,现在是中文了,阅读方便。FreeRTOS API categories
(2)FreeRTOS中用于创建和删除任务的API函数如下表所示:
函数 | 描述 |
xTaskCreate() | 动态方式创建任务 |
xTaskVreateStatic() | 静态方式创建任务 |
vTaskDelete() | 删除任务 |
3、动态方式创建任务
(1)创建任务时使用函数如下:
BaseType_t xTaskCreate(
TaskFunction_t pxTaskCode, // 函数指针,任务函数
const char * const pcName, // 任务的名字
const configSTACK_DEPTH_TYPE usStackDepth, // 栈大小,单位world,10表示40字节
void * const pvParameters, // 调用任务时传入的参数
UBaseType_t uxPriority, // 优先级
TaskHandle_t * const pxCreatedTask ) //任务句柄,以后使用它来操作这个任务
(2)参数说明
参数 | 描述 |
pvTaskCode | 函数指针,可以简单地认为任务就是一个C函数。 它稍微特殊一点:永远不退出,或者退出时要调用"vTaskDelete(NULL)" |
pcName | 任务的名字,FreeRTOS内部不使用它,仅仅起调试作用。 长度为:configMAX_TASK_NAME_LEN |
usStackDepth | 每个任务都有自己的栈,这里指定栈大小。 单位是word,比如传入100,表示栈大小为100 word,也就是400字节。 最大值为uint16_t的最大值。 怎么确定栈的大小,并不容易,很多时候是估计。 精确的办法是看反汇编码。 |
pvParameters | 调用pvTaskCode函数指针时用到:pvTaskCode(pvParameters) |
uxPriority | 优先级范围:0~(configMAX_PRIORITIES – 1) 数值越小优先级越低, 如果传入过大的值,xTaskCreate会把它调整为(configMAX_PRIORITIES – 1) |
pxCreatedTask | 用来保存xTaskCreate的输出结果:task handle。 以后如果想操作这个任务,比如修改它的优先级,就需要这个handle。 如果不想使用该handle,可以传入NULL。 |
返回值 | 成功:pdPASS; 失败:errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY(失败原因只有内存 不足) 注意:文档里都说失败时返回值是pdFAIL,这不对。 pdFAIL是0,errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY是-1。 |
4、静态方式创建任务
(1)静态方式创建任务函数原型如下:
TaskHandle_t xTaskCreateStatic(
TaskFunction_t pxTaskCode,
const char * const pcName,
const uint32_t ulStackDepth,
void * const pvParameters,
UBaseType_t uxPriority,
StackType_t * const puxStackBuffer,
StaticTask_t * const pxTaskBuffer );
(2)参数说明
参数 | 描述 |
pxTaskCode | 指向任务函数的指针 |
pcName | 任务的描述性名称 |
ulStackDepth | 任务堆栈大小,单位:字 |
pvParameters | 传递给任务函数的参数 |
uxPriority | 任务优先级 |
puxStackBuffer | 任务栈指针,内存由用户分配提供 |
pxTaskBuffer | 任务控制块指针,内存由用户分配提供 |
(3)返回值
返回值 | 描述 |
NULL | 用户没有提供相应的内存,任务创建失败 |
其他值 | 任务句柄,任务创建成功 |
5、删除任务
(1)删除任务时使用函数如下:
void vTaskDelete( TaskHandle_t xTaskToDelete );
(2)参数说明:
参数 | 描述 |
pvTaskCode | 任务句柄,使用xTaskCreate创建任务时可以得到一个句柄。 也可传入NULL,这表示删除自己。 |
(3)删除任务举例:
- 自杀: vTaskDelete(NULL)
- 被杀:别的任务执行 vTaskDelete(pvTaskCode) ,pvTaskCode是自己的句柄
- 杀人:执行 vTaskDelete(pvTaskCode) ,pvTaskCode是别的任务的句柄