FreeRTOS学习笔记3:系统配置文件+任务创建和删除的API函数介绍
1.系统配置文件
FreeRTOS系统配置文件的文件名为FreeRTOSConfig.h,它的作用是对FreeRTOS进行功能配置和裁剪,以及API函数的使能。
因为FreeRTOSConfig.h能对FreeRTOS功能配置和裁剪,以及API函数的使能,将使用不到API函数进行失能,能减少代码编译后的空间。所以FreeRTOSConfig.h这个文件很重要,所以后续有需要可以去官方的在线文档查看该文件里面每一个宏定义的说明:官方在线文档
1.1系统配置文件的分类
FreeRTOSConfig.h该文件里面相关宏大致可分为三类,分别是:
1.INCLUDE:配置FreeRTOS中可选的API函数,如下图所示:
2.config:完成FreeRTOS的功能配置和裁剪,如下图所示:
3.其他配置项:PendSV宏定义、SVC宏定义,如下图所示:
1.2浅识系统配置文件
在官方在线手册可以详细的看到FreeRTOSConfig.h该文件里面每一个宏定义的说明,并且正点原子所提供的例程中FreeRTOSConfig.h该文件里有每一个宏定义作用都有注释,所以就不一一列举出来,下面放出正点原子所提供的FreeRTOSConfig.h文件部分截屏只需稍微看一下了解即可,如下图所示:
刚开始接触系统配置文件FreeRTOSConfig.h肯定会很懵逼,现阶段只需浅浅的看一下即可后续才会用到和说明后才能了解。
2.任务创建和删除的API函数
任务的创建和删除本质就是调用FreeRTOS的API函数。
API函数 描述 xTaskCreate() 动态方式创建任务 xTaskCreateStatic() 静态方式创建任务 vTaskDelete() 删除任务 动态创建任务:任务的任务控制块以及任务的栈空间所需的内存,均有FreeRTOS从FreeRTOS管理的堆中分配。
静态创建任务:任务的任务控制块以及任务的栈空间所需的内存,需用户分配提供。
3.动态创建任务的API函数介绍
BaseType_t xTaskCreate ( TaskFunction_t pxTaskCode,//指向任务函数的指针 const char * const pcName, //任务名字,最大长度为configMAX_TASK_NAME_LEN const configSTACK_DEPTH_TYPE usStackDepth,//任务堆栈大小,单位为字,乘4后才是单位才是字节 void * const pvParameters,//传递给任务函数的参数 UBaseType_t uxPriority,//任务优先级,范围0-configMAX_PRIORITIES-1 TaskHandle_t * const pxCreatedTask //任务句柄,也就是任务控制块 )
动态创建任务的API函数xTaskCreate()它一个有六个参数,分别是:
1.pxTaskCode:类型是函数指针,它指向我们自己所写的任务函数
2.pcName:类型是char类型的指针,我们将自己所写的任务函数的名字传入即可,任务函数的名字最大是系统配置文件中configMAX_TASK_NAME_LEN来决定,如下图所示:
3.usStackDepth:任务堆栈的大小,类型是unsigned short,注意是以字为单位,如果想换算成字节需要乘4。
4.pvParameters:传递给任务函数的参数,类型是空指针,没有参数就传空进去。
5.uxPriority:任务的优先级,值越大,优先级越大,范围0-configMAX_PRIORITIES-1,也就是[0,31](用的是硬件方式)。
6.pxCreatedTask:任务句柄,也就是任务的任务控制块(学过操作系统的同学可以将它理解为PCB)。
当xTaskCreate()创建任务成功时返回pdPASS,失败返回errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY
创建任务失败可能是堆栈空间已经不够了,以及usStackDepth这个参数给的太大了,芯片空间根本不够。
3.1实现动态创建任务的流程
1.将系统配置文件里的宏configSUPPORT_DYNAMIC_ALLOCATION设置为1,该宏的作用是是否支持支持动态申请内存,设置为1支持,设置为0不支持。
2.定义函数入口参数。
3.编写任务函数,该任务的功能是点灯、在oled上显示字符等等。
4.调用xTaskCreate(),将参数一一传入,动态的方式创建任务完成
使用xTaskCreate()此函数创建的任务会立刻进入就绪态,由任务调度器调度运行。
3.2xTaskCreate()函数内部实现介绍
动态创建任务函数内部实现(了解)
1.申请堆栈内存,任务控制块内存
2.TCB结构体成员赋值(任务控制块结构体成员赋值)
学过操作系统的同学可以将TCB/任务控制块给理解为PCB,没有学习过操作系统的同学可以理解为是任务函数的身份证,FreeRTOS给任务函数发的身份证,FreeRTOS想要管理任务函数只需要使用任务控制块就能管理任务函数。
3.添加新任务到就绪列表中
3.3任务控制块/TCP结构体介绍
typedef struct tskTaskControlBlock { volatile StackType_t * pxTopOfStack; ListItem_t xStateListItem; ListItem_t xEventListItem; UBaseType_t uxPriority; StackType_t * pxStack; char pcTaskName[ configMAX_TASK_NAME_LEN ]; /* ............. */ }tskTCB;
1.pxTopOfStack:任务栈栈顶,必须为TCB的第一个成员,因为它跟任务的切换,任务的上下文保存,任务的恢复都息息相关。
2.xStateListItem:任务状态列表项,该任务处于什么状态保存在这里
3.xEventListItem:任务事件列表项,当任务处于什么事件就会用到
4.uxPriority:任务的优先级,保存任务的优先级,数值越大,优先级越大
5.pxStack:任务栈起始地址
6.pcTaskName:任务名字
此外任务控制块还有很多条件编译的成员,只需要了解基本部分即可
4.静态创建任务的API函数介绍
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 )
1.pxTaskCode:指向任务函数的指针
2.pcName:任务函数名
3.ulStackDepth:任务堆栈大小,单位字
4.pvParameters:任务函数参数
5.uxPriority:任务优先级
6.puxStackBuffer:任务堆栈,一般为数组,由用户分配
7.pxTaskBuffer:任务控制块指针,由用户分配
创建失败返回NULL,用户没有提供相应的内存,任务创建失败。
创建成功返回任务的句柄(任务控制块)
4.1实现静态创建任务的流程
1.需要将系统配置文件里的宏configSUPPORT_STATIC_ALLOCATION配置为1,该宏的作用是是否支持支持静态申请内存,配置为1支持,配置为0不支持。
2.定义空闲任务与定时器任务的任务堆栈及TCB/任务控制块,空闲任务是必须要有的,不能让STM32有空闲,定时器任务是可选的,如果将系统配置文件里的宏configUSE_TIMERS给配置1,就必须要实现定时器任务,该宏的作用是是否使能软件定时器。
3.实现两个接口函数,1.空闲任务内存赋值(必须),软件定时器内存赋值(系统配置文件里的宏configUSE_TIMERS如果配置为0可以不用实现)。
4.定义任务函数的入口参数。
5.编写任务函数。
6.调用xTaskCreateStatic() ,将参数一一传入,动态的方式创建任务完成。
和动态创建任务一样,使用xTaskCreateStatic()静态创建任务成功后会立刻进入就绪态,由任务调度器调度运行。
4.2xTaskCreateStatic()函数内部实现介绍
1.TCB/任务控制块结构体成员赋值
2.添加新任务到就绪列表中
5.任务删除函数介绍
void vTaskDelete( TaskHandle_t xTaskToDelete )
xTaskToDelete:待删除任务的任务句柄,当传入的参数为空(NULL),则代表删除任务自身
xTaskToDelete的功能是用于删除已被创建的任务,不管要删除的任务处于什么状态,调用该函数后都会被删除,被删除的任务将从就绪态任务列表,阻塞态任务列表,挂起态任务列表和事件列表中移除。
任务被删除后由FreeRTOS自身来释放系统分配的内存,如果删除的任务是该任务本身,会由空闲任务负责释放系统分配的内存,在任务删除前用户申请的内存由用户在任务删除前提前释放,否则会造成内存泄漏。
5.1删除任务的流程
1.需要将系统配置文件里的宏INCLUDE_vTaskDelete配置为1才能使用任务删除函数
2.调用任务删除函数,入口参数输入任务句柄/NULL
5.2xTaskToDelete内部实现大致介绍
1.获取所要删除任务的控制块
2.将被删除任务,移除所在列表(就绪,阻塞,挂起,事件等列表)
3.判断所需要删除的任务,如果是自身需要添加到等待删除列表,内存释放将在空闲任务进行,如删除的是其他任务,释放内存,任务数量自减。