文章目录
- 前言
- 二、FreeRTOS简介
- 三、FreeRTOS源码结构
-
- 1.关于各个c文件的主要用途:
- 2.四种内存分配方式比较:
- 3.优先级:
- 4.任务状态:
- 5.通信方式:
- 6.临界区
- 7.调度锁
- 四、官方教程与例程
前言
在介绍FreeRTOS之前,需要先引入一个概念:什么是实时操作系统?
实时指的是任务(Task)必须在给定的时间内完成,比如汽车安全气囊必须要在30ms内完全打开,保障司机和乘客的人身安全。因此,实时操作系统就是为了保障这些实时任务能在规定的时间内完成而设计的一个对任务进行调度和管理的多任务系统。
目前比较流行的实时操作系统有uCOS,RT-Thread,FreeRTOS,RTX5等,腾讯也开源了面向物联网的实时操作系统TencentOS tiny,华为也发布了鸿蒙LiteOS。
与实时操作系统相对的是裸机系统,裸机系统就是在main函数中的while大循环中依次处理各个模块的任务,这种程序运行方式也叫轮询系统;如果加上中断处理函数,又被称为前后台系统,中断处理是前台,主循环是后台。
在嵌入式领域中,嵌入式实时操作系统(RTOS)可以更合理、更有效地利用CPU的资源,简化应用软件的设计,缩短系统开发时间,从而更好地保证系统的实时性和可靠性。
二、FreeRTOS简介
FreeRTOS是一个开源的、轻量级的实时操作系统,功能强大:任务管理,时间管理,信号量,消极队列,内存管理,软件定时器,协程等,可移植、裁剪,能够在小RAM的单片机上运行,因此近年来市场占有率在迅速上升。
其主要特点:
- 使用免费!
- 系统简单小巧、文件数量少、通常情况下内核占用4~9k字节空间
- 抢占式内核
- 代码主要由C编写,可移植性高,已实现在30多种架构的芯片上移植
- 任务与任务,任务与中断间的通信方式包括:信号量、消息队列、事件标志组、任务通知
- 具有优先级继承特性的互斥信号令,避免优先级反转问题
- 高效的软件定时器
三、FreeRTOS源码结构
官网下载的压缩包包含FreeRTOS和FreeRTOS-Plus文件夹,后者是一些补充文件,初学者用不到,可以先忽略。在FreeRTOS文件夹中主要关注source文件夹,这里是FreeRTOS的全部源码,包括6个c文件和include文件夹下的多个h文件。另外,在portable文件夹下,是针对不同硬件平台的接口。
1.关于各个c文件的主要用途:
-portable
- port.c : 针对不同硬件平台的接口
- heap_4.c : 内存管理相关
-core
- croutine.c : 协程相关
- event_groups.c : 事件标志组相关
- list.c : 列表,FreeRTOS的一种基础数据结构(双向链表)
- queue.c : 消息队列相关
- tasks.c : 任务创建、挂起、恢复、调度相关
- timers.c : 软件定时器相关
-include:相关头文件
-FreeRTOSConfig.h:功能裁剪与配置相关
其中FreeRTOSConfig.h可以在Demo文件夹中根据使用的硬件平台选择复制,然后根据需要进行修改。如果Demo文件中没有相关硬件平台的例程,可以找硬件厂商询问,或者随意拷贝一个,根据硬件资源进行修改与配置。
2.四种内存分配方式比较:
分配方式 |
优点 |
缺点 |
heap1 |
分配简单,时间确定 |
只分配,不回收 |
heap2 |
动态分配,最佳匹配 |
产生碎片,时间不定 |
heap3 |
调用标准库动态分配 |
速度慢,时间不定 |
heap4 |
相邻空闲内存可合并 |
合并效率低 |
注:通常使用heap4分配方式,具体的分配方式和原理以后搞清楚了再单独写。
3.优先级:
FreeRTOS中优先级数字越大,优先级越高,0是最低优先级,可在FreeRTOSConfig.h中通过设置configMAX_priorities来配置最高优先级。
通常来讲,优先级高的就绪态任务优先执行,同优先级的任务按时间片轮询方式“同时”执行。可在FreeRTOSConfig.h中通过设置configUSE_TIME_SLICING来配置是否开启时间片。
4.任务状态:
任务分4种状态:
挂起态:当任务被vTaskSuspend()函数禁止运行的时候处于此状态
就绪态:当任务没有被阻塞或者挂起等待运行的时候处于此状态
运行态:当任务被内核调度执行的时候处于此状态
阻塞态:当任务等待某个事件或信号的时候处于此状态
注:空闲任务一直处于就绪态。
5.通信方式:
信号量:用于任务间的同步,一个任务以阻塞方式等待另一个任务释放信号量。
互斥量:用于任务间共享资源的互斥访问,使用前获取锁,使用后释放锁。
事件标记组:用于任务间的同步,相比信号量,事件标记组可以等待多个事件的发生。
消息队列:有限长度的队列,可传递大小固定的数据。
消息缓冲区:基于消息队列实现,可传递不同大小的数据
6.临界区
代码的临界段也称为临界区,一旦这部分代码开始执行,则不允许任何中断打断。为确保临界段代码的执行不被中断,在进入临界段之前须关中断,而临界段代码执行完毕后,要立即开中断。
注:为了保障系统的实时性,临界区的执行时间越短越好!
7.调度锁
调度锁就是 RTOS 提供的调度器开关函数,如果某个任务调用了调度锁开关函数,处于调度锁开和调度锁关之间的代码在执行期间是不会被高优先级的任务抢占的,即任务调度被禁止。
注:调度锁只是禁止了任务调度,并没有关闭任何中断,中断还是正常执行的。
四、官方教程与例程
这个是官网的在线文档,有教程和相关API的使用例程。官方文档
这个是官网源码的下载地址。源码下载