——————————————
FreeRTOS 笔记
一、FreeRTOS入门
数据类型
- 在FreeRTOS中,int型从不使用,只使用short和long型。在Cortex-M内核的MCU中,short为16位,long为32位。
- FreeRTOS中详细的数据类型重定义在portmarco.h中实现
- 在编程时,如果用户没有明确规定char的符号类型编译器会默认指定有符号或无符号的一种,所以在freertos中,需要明确指明。在keil中,默认char是无符号的,但是也可以配置成为有符号的。具体实现过程如下:
- Free RTOS中,定义变量时常常把变量 的类型当作前缀加在变量上,目的是让用户一看到变量名就知道是什么类型的,比如char会在前面加一个c,unsigned char会加一个前缀uc等等。
- 函数名前面通常也会加前缀,私有函数会加prv;根据返回值加,比如vTaskPrioritySet()返回值为void,在task.c中定义。
二、裸机系统和多任务系统
1.裸机系统
- 裸机系统通常分成轮询系统和前后台系统
轮询系统
- 轮询系统即在裸机编程时,先初始化好相关的硬件,然后让主程序在一个死循环里不断循环,顺序地处理各种事件
- 轮询系统通常只适用于仅需要顺序执行代码切不需要外部事件(按键检测等)来驱动就能完成的事件。
1 | int main() |
- 上述为轮询系统的伪代码。举个例子来说明外部事件对上述系统的影响:假如按键检测在Task3中进行,而此时程序运行到Task1且在Task1中需要运行很长时间,以至于松开按键时还没有执行到Task3,那么Task3就会丢失运行一次
前后台系统
- 相比于轮询系统,前后台系统是在轮询的基础上加上了中断。外部事件的响应在中断中进行,事件的处理还是回到轮询系统中进行,中断被称为前台,而无限循环被称为后台。
1 | int flag1=0; |
- 上述是前后台系统的伪代码。前后台系统确保了事件不会丢失,再加上中断具有可嵌套的功能,大大提高了程序的实时响应能力。而缺点也很明显,在大规模的模块使用中,可能会造成中断执行太长,造成多层的中断嵌套,最终可能导致中断栈空间爆掉。 更重要的是:不是所有的中断都是紧急的重要的,很可能各个要处理的模块优先级要大于不紧急的中断处理。这样造成的后果是不但各个Task间不能相互通讯,而且实时模块完全得不到处理,在一个中大型软件项目中,采用此类方法可以说是一种管理的灾难。
2.多任务系统
- 相比于前后台系统,多任务系统的事件响应也是在中断中进行的,但事件的处理是在任务中进行的。任务与中断一样,也有优先级,优先级高的任务会被优先执行。相比于前后台系统,多任务系统的实时性又被提高了。
1 | int flag1=0; |
- 上述是多任务系统的伪代码。
三、数据结构——列表与列表项
列表就是所说的链表,列表项就是节点
链表最大的作用是通过节点把离散的数据链接起来,组成一个表。为了顺利插入节点,会人为规定一个根节点root_node。
链表和数组的区别,链表是通过节点将离散的数据链接成一个表,可以通过节点的删除和插入来实现对数据的 存取,链表是一个圈,没有头尾之分,为了方便才人为规定的根节点;而数组是通过开辟一个连续的内存来存放数据,数组有起始和结束地址。
实在不会放弃了,等之后看看视频学习一下
四、任务的定义与任务切换
什么是任务
- 在裸机系统中,系统的主体是main函数中执行的无限循环;在多任务系统中,根据功能的不同,把整个系统分成一个个独立的且无法返回的函数,这样的函数就被称为任务
1
2
3
4
5
6
7
8void task(void)
{
for( ; ; )
{
/*任务主体代码*/
}
}- 上述便是任务的伪代码
创建任务
在裸机系统中,全局变量在子函数调用、中断发生时,局部变量在子函数调用时,中断发生时回调函数返回值的地址这些统统会放在栈中。
栈是单片机RAM中的一段连续的内存空间
多任务系统中,每个任务都是独立互不干扰的,所以需要给他们分配单独的栈空间,这个栈空间通常是一个预先定义好的全局数组,也可以是动态分配的一段内存空间,它们都存在于RAM中。
Free RTOS推荐的最小的任务栈是128字,即512字节
有多少任务就需要定义多少个栈空间
任务控制块(TCB:TaskControlBlock).相当于任务的身份证,有关任务的信息都会在里面被定义
1
2
3
4
5
6
7
8typedef struct tskTaskControlBlock
{
volatile StackType_t *pxTopOfStack; /*栈顶*/
ListItem_t xStateListItem; /*任务节点*/
StackType_t *pxStack; /*任务栈起始地址*/
char pcTaskName[configMAX_TASK_NAME_LEN];/*任务名称*/
}tskTCB;
typedef tskTCB TCB_t- 任务控制块类型声明
—————————————— 持续更新······ ——————————————