1.任务函数
/*
FreeRTOS 的任务可认为是一系列独立任务的集合。每个任务在自己的环境中运行。在任何时刻,只有一个任务得到运行,FreeRTOS 调度器决定运行哪个任务。调度器会不断的启动、停止每一个任务,宏观看上去所有的任务都在同时在执行。作为任务,不需要对调度器的活动有所了解,在任务切入切出时保存上下文环境(寄存器值、堆栈内容)是调度器主要的职责。为了实现这点,每个 FreeRTOS 任务都需要有自己的栈空间。
FreeRTOS 中的任务是抢占式调度机制,高优先级的任务可打断低优先级任务,低优先级任务必须在高优先级任务阻塞或结束后才能得到调度。同时 FreeRTOS 也支持时间片轮转调度方式,只不过时间片的调度是不允许抢占任务的 CPU 使用权。
任务通常会运行在一个死循环中,也不会退出,如果一个任务不再需要,可以调用FreeRTOS 中的任务删除 API 函数接口显式地将其删除。
任务状态迁移
FreeRTOS 系统中的每一个任务都有多种运行状态
(1):创建任务→就绪态(Ready):任务创建完成后进入就绪态,表明任务已准备就绪,随时可以运行,只等待调度器进行调度。
(2):就绪态→运行态(Running):发生任务切换时,就绪列表中最高优先级的任务被执行,从而进入运行态。
(3):运行态→就绪态:有更高优先级任务创建或者恢复后,会发生任务调度,此刻就绪列表中最高优先级任务变为运行态,那么原先运行的任务由运行态变为就绪态,依然在就绪列表中,等待最高优先级的任务运行完毕继续运行原来的任务(此处可以看做是 CPU 使用权被更高优先级的任务抢占了)。
(4):运行态→阻塞态(Blocked):正在运行的任务发生阻塞(挂起、延时、读信号量等待)时,该任务会从就绪列表中删除,任务状态由运行态变成阻塞态,然后发生任务切换,运行就绪列表中当前最高优先级任务。
(5):阻塞态→就绪态:阻塞的任务被恢复后(任务恢复、延时时间超时、读信号量超时或读到信号量等),此时被恢复的任务会被加入就绪列表,从而由阻塞态变成就绪态;如果此时被恢复任务的优先级高于正在运行任务的优先级,则会发生任务切换,将该任务将再次转换任务状态,由就绪态变成运行态。
(6) (7) (8):就绪态、阻塞态、运行态→挂起态(Suspended):任务可以通过调用 vTaskSuspend() API 函数都可以将处于任何状态的任务挂起,被挂起的任务得不到CPU 的使用权,也不会参与调度,除非它从挂起态中解除。
(9):挂起态→就绪态:把 一 个 挂 起 状态 的 任 务 恢复的 唯 一 途 径 就 是调 用 vTaskResume() 或 vTaskResumeFromISR() API 函数,如果此时被恢复任务的优先级高于正在运行任务的优先级,则会发生任务切换,将该任务将再次转换任务状态,由就绪态变成运行态。
*/
1.1声明任务句柄
/*头文件*/
#include "task.h"
TaskHandle_t app_task1_handle=NULL;//要声明任务句柄
1.2创建任务
//任务原型
//参数一:任务函数名
//参数二:任务的名字测试用 同任务函数名一样即可
//参数三:分配给任务函数的堆栈大小
//参数四:传递给任务函数的参数 没有可为NULL
//参数五:任务优先级0~configMAX_PRIORITIES-1 优先级越小优先级越高
//参数六:任务句柄
BaseType_t xTaskCreate(TaskFunction_t pxTaskCode,
const char * const pcName,
const uint16_t usStackDepth,
void * const pvParameters,
UBaseType_t uxPriority,
TaskHandle_t * const pxCreatedTask)
/* 创建任务1
app_task1,任务函数
"app_task1",任务的名字
512,分配给任务1的内存(栈)大小,单位为字
7,优先级为7,数值不能超过(configMAX_PRIORITIES -1)
app_task1_handle任务句柄
*/
xReturn=xTaskCreate(app_task1,"app_task1",512,&app_task1_arg,7,&app_task1_handle);
/*返回值
1. pdTRUE
表明任务创建成功。
2. errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY
由于内存堆空间不足,FreeRTOS 无法分配足够的空间来保存任务
*/
1.3创建任务函数
//任务函数
void app_task1(void *pvParameters)//void类型 参数为void *
{
//必须死循环 while(1)或for(;;)
while(1)
{
/* 延时1000ms */
vTaskDelay(1000);//使用RTOS延时释放cpu权限让别的任务调用
printf("[app_task1] running ...\r\n");
}
}
1.4开启任务调度
/* 开启任务调度 */
vTaskStartScheduler();
1.5删除任务
//删除任务 例如初始化任务函数
vTaskDelete(Start_Task_Handle);