前言
2020,重新学习一遍FreeRTOS收益良多,比前两年学习时更能体会FreeRTOS代码的优缺点。
FreeRTOS 于 2018 年被亚马逊收购, 改名为 AWS FreeRTOS,版本号升级为 V10。V10 版本相比于 V9 就是加入了一
些物联网相关的组件,内核基本不变。 亚马逊收购 FreeRTOS 也是为了进军眼下炒的火热的物联网和人工智能。
下载以往版本的可从托管网址: https://sourceforge.net/projects/freertos/files/FreeRTOS/
一、FreeRTOS重点内容
- 链表基本操作。(FreeRTOS基本是围绕链表操作搭建而成)
- 裁剪系统在FreeRTOSConfig.h中开关宏定义
二、编程风格
在 FreeRTOS 中, 使用的数据类型虽然都是标准 C 里面的数据类型,但是针对不同的处理器,对标准 C 的数据类型又进行了重定义。这些数据类型重定义在 portmacro.h 这个头文件中。
2.1 变量名
FreeRTOS文件定义变量会将变量类型当作前缀放在变量名上。常见类型前缀有:
2.2 函数名
采用“返回值类型+所在文件名+自定义”,如:vSemaphoreCreateBinary()函数的返回值为 void 型, 在 semphr.h 这个文件中定义。注:私有函数前缀“prv”
2.3 宏命名
格式:小写前缀(该宏所在头文件定义)+大写命名
特殊通用宏:
三、任务管理
3.1 任务切换
注:任务之所以是独立互不干扰的,主要是因为每个任务都分配了独立的栈空间。
- 调度器:从就绪列表找出优先级最高的任务执行。启动时,会将PendSV(触发任务切换)和SysTicks的中断优先级设为最低。
- 在Cortex-M 系列芯片中,有三个内核中断屏蔽寄存器组:
- SVC_Handler:启动第一个任务;
- PendSVHandler:任务切换
- TCB_t数据结构关系到任务的建立、使用,需重点了解。因为,任务切换主要切换任务块。
3.2 临界段的保护
关于中断保护嵌套,即利用中断返回值,实现逐级恢复退出;
3.3 阻塞延时
阻塞延时是利用Systick定时器计时。任务进入阻塞延时,是从就绪链表退出,进入延时链表,同时取消其在优先级的位置。
3.4 支持优先级
在 FreeRTOS 中,数字优先级越小,逻辑优先级也越小,这与RT-Thread 和 μC/OS 刚好相反。
优先级有两种方式:
1.通用方式:不限优先级,uxTopReadyPriority 是一个在 task.c 中定义的静态变量, 用于表示创建的任务的最高
优先级,
2.前导零的指令CLZ:Cprtex-M有指令,更高效,但优先级限制在32位
3.5 支持时间片
所谓时间片就是同一个优先级下可以有多个任务,每个任务轮流地享有相同的 CPU 时间, 享有 CPU 的
时间我们叫时间片。(每个优先级下还有链表挂着任务)
3.6 任务状态
共有四种状态:就绪态、阻塞态、运行态、挂起态(vTaskSuspend())
四、任务通信
4.1 消息队列
- 读取消息为空,任务会被阻塞
- 支持超时机制
- 任务与任务之间、任务与中断之间
4.2 信号量
用于任务之间同步或临界资源的互斥访问,有阻塞任务功能。
- 二值信号量:偏向同步功能
- 互斥信号量:偏向用于临界资源访问,有优先级继承机制
- 计数信号量:有资源限制访问
代码位于semphr.h,基于Queue,主要函数接口:
1、创建信号量
xSemaphoreCreateBinary()
xSemaphoreCreateCounting ()
2、删除信号量
vSemaphoreDelete()
3、信号量释放
xSemaphoreGive()(任务)
xSemaphoreGiveFromISR()(中断)
4、信号量获取函数
xSemaphoreTake()(任务)
xSemaphoreTakeFromISR()(中断)
4.3 事件(EventBits_t):类似全局标志位变量,但有保护功能
一个任务可以等待多个事件的发生:可以是任意一个事件发生时唤醒任务进行事件处理;也可以是几个事件都发生后才唤醒任务进行事件处理。同样,也可以是多个任务同步多个事件。
事件只与任务相关联,事件相互独立,一个 32 位的事件集合(EventBits_t 类型的变量, 实际可用与表示事件的只有 24 位),用于标识该任务发生的事件类型,其中每一位表示一种事件类型(0 表示该事件类型未发生、 1 表示该事件类型已经发生),一共 24 种事件类型。
4.4 任务通知
- 效率比信号、事件快
- 只能有一个任务接收通知消息
五、软件定时器
- 与硬件定时器类似,触发回调函数同中断服务函数,需快进快出不能阻塞。
- 可以单次,也可以周期模式
六、内存管理
见《FreeRTOS学习笔记NO2》