1 FreeRTOS 的特点
文章目录
1 FreeRTOS 的特点
- 支持抢占式调度,合作式调度和时间片调度。
SafeRTOS
作为FreeRTOS
的衍生品大大提高了 FreeRTOS 在代码完整性方面的信心。- 用于低功耗的
Tickless
模式。 - 支持
35
种系统架构。 FreeRTOS-MPU
支持M3/M4/M7
内核的MPU
(内存保护单元)。- 设计的简单易用,典型的内核使用大小在
4k-9k
。 - 移植非常简单,代码主要用
C
编写。 - 同时支持合作式和抢占式任务。
- 支持消息队列、二值信号量、计数信号量、递归信号量和互斥信号量,可用于任务与任务间的消息传递和同步,任务与中断间的消息传递和同步。
- 优先级继承方式的互斥信号量。
- 高效的软件定时器。
- 强大的跟踪执行函数。
- 堆栈溢出检查。
- 提供丰富的,配置好的工程例子。
- 提供论坛技术支持,有可选的商业支持和许可版本。
- 任务的数量不限。
- 任务优先级数量不限。
- 多个任务可以分配相同优先级,即支持时间片调度。
- 免费的开发工具。
- 免费的嵌入式软件源码。
- 免版权费。
2 高质量的管理机制
FreeRTOS
经过非常严格的高质量管理,不仅表现为规范的源码,还主要表现在以下几个方面:
- 在关键代码区和中断里面从不会执行像遍历列表这样的时间非确定性任务。
- 高效的软件定时器,不需要损耗额外的 CPU 时间,除非需要执行定时器任务。
- 任务间直接的消息传递,相对于通用的信号量、消息队列等方式,速度较快。
- 不需要定时的去查询阻塞或者挂起列表。
FreeRTOS
的队列使用模型(消息队列、互斥信号量、信号量等都是基于此队列模式设计的)使得它简单并且灵活。FreeRTOS
的队列是其它通信和同步机制的基础,这种代码复用方式可以有效地降低整体代码的大小,并且反过来有助于调试。
3 FreeRTOS 的命名规则
变量
uint32_t
定义的变量都加上前缀ul
(u
代表unsigned
无符号,l
代表long
长整型)。uint16_t
定义的变量都加上前缀us
(u
代表unsigned
无符号,s
代表short
短整型)。uint8_t
定义的变量都加上前缀uc
(u
代表unsigned
无符号,c
代表char
字符型)。stdint.h
文件中未定义的变量类型,在定义变量时需要加上前缀x
(例如BaseType_t
和TickType_t
定义的变量)。stdint.h
文件中未定义的无符号变量类型,在定义变量时要加上前缀u
(例如UBaseType_t
定义的变量要加上前缀ux
)。size_t
定义的变量也要加上前缀ux
。- 枚举变量会加上前缀
e
。 - 指针变量会加上前缀
p
(例如uint16_t
定义的指针变量会加上前缀pus
)。 - 根据
MISRA
代码规则,char
定义的变量只能用于ASCII
字符,前缀使用c
。 - 根据
MISRA
代码规则,char *
定义的指针变量只能用于ASCII
字符串,前缀使用pc
。
函数
- 加上了
static
声明的函数,定义时要加上前缀prv
(private
的缩写)。 - 带有返回值的函数,根据返回值的数据类型加上相应的前缀:
- 无返回值(
void
类型),函数前缀加字母v
。
- 无返回值(
- 根据文件名,文件中相应的函数定义时也将文件名加到函数命名中(例如
tasks.c
文件中的函数vTaskDelete
,task
是文件名的一部分)。
宏定义
- 根据宏定义所在的文件,文件中的宏定义声明时也将文件名加到宏定义中:
- 例如宏
configUSE_PREEMPTION
定义在文件FreeRTOSConfig.h
中,config
是文件名的一部分。 - 前缀小写,其余部分全部大写,并用下划线分隔。
- 例如宏
4 FreeRTOS 中数据类型
FreeRTOS
使用的数据类型主要分为 stdint.h
文件中定义的和自定义类型,自定义数据类型包括:
-
TickType_t
:- 如果使能宏定义
configUSE_16_BIT_TICKS
,则为 16 位无符号数;否则为 32 位无符号数。 - 32 位架构需禁止此宏(设置为
0
)。
- 如果使能宏定义
-
BaseType_t
:- 根据系统架构:32 位架构为 32 位有符号数,16 位架构为 16 位有符号数。
- 若定义为
char
类型,需确保其为有符号数(负返回值表示错误)。
-
UBaseType_t
:BaseType_t
的无符号版本。
-
StackType_t
:
6 位系统为 16 位变量,32 位系统为 32 位变量。
/* 数据类型重定义 */
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
#if( configUSE_16_BIT_TICKS == 1 )
typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff
#else
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
#endif
FreeRTOS 通用宏定义
宏 | 实际值 |
---|---|
pdTRUE | 1 |
pdFALSE | 0 |
pdPASS | 1 |
pdFAIL | 0 |
5 FreeRTOS 的排版和注释
- 缩进:
- Tab 制表符用于缩进,一次缩进 4 个字符空间。
- 注释:
- 源码主要采用
/* */
形式注释,不使用 C++ 双斜杠(//
)风格。
- 源码主要采用
6 FreeRTOS 和 OpenRTOS、SafeRTOS 的区别
- FreeRTOS 和 OpenRTOS:拥有相同源码,但 OpenRTOS 受商用授权保护。
- SafeRTOS:被安全专家重新设计,获得重要安全认证。