1、FreeRTOS基础知识点
1.1 FreeRTOS任务调度的方式
抢占式调度:主要是针对优先级不同的任务,优先级高的任务会抢占优先级低的任务
时间片调度:主要是针对优先级相同的任务,当多个任务的优先级相同时,任务调度器就会在时钟节拍到时切换任务。同等优先级任务轮流享有相同的CPU时间,叫时间片,在FreeRTOS中,一个时间片等于SysTick中断周期。
协程式调度:当前执行任务将一直运行,同时高优先级的任务不会抢占低优先级任务。
1.2 任务状态
运行态(正在执行的任务)
就绪态(能够被执行的任务,但未被执行)
堵塞态(处于延时或者等待外部事件发生的状态)
挂起态(类似暂停,需要解挂函数恢复)
调度器总是在所有处于就绪列表的任务中,选择具有最高优先级的任务执行。相同优先级的任务会连接在同一个就绪列表上
2、 FreeRTOS任务调度的方式
2.1 代码移植
D:\正点原子\【正点原子】探索者STM32F407开发板V3 资料盘(A盘)\6,软件资料\13,FreeRTOS学习资料\FreeRTOSv202112.00\FreeRTOS\Source
在该路径下
为操作系统的源文件,这里可以按需选择
3、FreeRTOS任务创建与删除
3.1 通过API函数创建任务和删除任务
这里主要涉及的函数为
xTASKCreat() 动态创建任务
xTASKCreatStatic 静态创建任务
xTaskDelete() 删除任务
这里在开始调用API函数时大家应该先了解一下的是在FreeRTOS中这些函数这样命名的原因何在
我在学习FreeRTOS的时候第一次看见每个函数名前面都有一个x或者u之类的前缀。并不知道什么意思。后来经过学习了解竟然是函数的返回值或者函数属性的含义,下面是FreeRTOS的函数命名规则和变量的命名规则。
从这里就可以看出创建任务的时候会返回对应的任务句柄
3.2 动态创建任务和静态创建任务的区别
动态
任务的任务控制块以及任务的栈空间所需的内存,均由 FreeRTOS 从 FreeRTOS 管理的堆中分配
BaseType_t xTaskCreate
( TaskFunction_t pxTaskCode, /* 指向任务函数的指针 */
const char * const pcName, /* 任务名字,最大长度
configMAX_TASK_NAME_LEN */
const configSTACK_DEPTH_TYPE usStackDepth, /* 任务堆栈大小,注意字为单位 */
void * const pvParameters, /* 传递给任务函数的参数 */
UBaseType_t uxPriority, /* 任务优先级,范围:0 ~ configMAX_PRIORITIES - 1 */
TaskHandle_t * const pxCreatedTask /* 任务句柄,就是任务的任务控制块 */
)
静态
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 /* 任务控制块指针,由用户分配 */
);
任务的任务控制块以及任务的栈空间所需的内存,需用户分配提供
任务结构块
typedef struct tskTaskControlBlock
{
volatile StackType_t * pxTopOfStack; /* 任务栈栈顶,必须为TCB的第一个成员 */
ListItem_t xStateListItem; /* 任务状态列表项 */
ListItem_t xEventListItem; /* 任务事件列表项 */
UBaseType_t uxPriority; /* 任务优先级,数值越大,优先级越大 */
StackType_t * pxStack; /* 任务栈起始地址 */
char pcTaskName[ configMAX_TASK_NAME_LEN ]; /* 任务名字 */
…
省略很多条件编译的成员
} tskTCB;
任务句柄与任务控制块之间的关系
每个任务控制块都有一个栈底指针和栈顶指针,从而实现任务控制块包含对应任务的所有信息,而任务句柄指向的是对应的任务控制块,所有最终可以使用任务句柄来对任务进行控制。