1.2 了解FreeRTOS发行版
定义:FreeRTOS移植
可以用大约20种编译器来构建FreeRTOS,并且可以在30多种[1]处理器架构上运行FreeRTOS。将每种支持的编译器和处理器组合认为是一种独立的FreeRTOS移植。
构建FreeRTOS
可以认为FreeRTOS是一个库,该库为原本裸机运行的应用程序提供了多任务处理能力。
FreeRTOS以一组C源文件的形式提供。有些源文件对所有的移植是通用的,而有些则是特定的。将这些源文件作为工程的一部分来编译,以使FreeRTOS的API函数可以在应用程序中使用。为了方便使用,每种官方的FreeRTOS移植都提供了演示程序。该演示程序是已经预先配置为能够正确构建的源文件,并且包含正确的头文件。
尽管有些演示程序相较于其他程序更陈旧,但是演示程序应该“开箱即用”。自从演示程序发布以来,对构建工具的更改有时可能会导致问题出现。1.3节描述了演示程序。
FreeRTOSConfig.h
FreeRTOS由名为FreeRTOSConfig.h的头文件配置。
FreeRTOSConfig.h用来定制FreeRTOS在特定应用程序中的使用。例如,FreeRTOSConfig.h包含configUSE_PREEMPTION等常量,其设置定义了是使用协同式还是抢占式调度算法[2]。由于FreeRTOSConfig.h包含应用程序的特定定义,因此应该被放置于正在构建的应用程序的目录中,而不是放在包含FreeRTOS源代码的目录中。
每种FreeRTOS移植都会提供演示程序,而每个演示程序都包含FreeRTOSConfig.h文件,因此没有必要从头开始创建FreeRTOSConfig.h文件。
替代方法是,建议从为FreeRTOS移植提供的演示程序中使用的FreeRTOSConfig.h头文件开始,然后进行修改。
FreeRTOS官方发行版
FreeRTOS以一个单独压缩文件包的形式发布。该压缩文件包具有全部FreeRTOS移植的源代码,以及所有FreeRTOS演示程序的工程文件;还包含FreeRTOS+生态系统组件的选集,以及FreeRTOS+生态系统演示程序的选集。
不要被FreeRTOS发行版中的文件数量所吓到!任何应用程序都只需要很少的文件。
FreeRTOS发行版的顶层目录
FreeRTOS发行版的第一级和第二级目录如图1-1所示,图中对这些目录进行了描述。
图1-1 FreeRTOS发行版的第一级和第二级目录
该压缩文件包只含有一份FreeRTOS源文件;所有的FreeRTOS演示工程,以及所有的FreeRTOS+演示工程,都可以在FreeRTOS/Source目录下找到对应的FreeRTOS源文件,而且如果目录结构发生改变,则可能无法构建。
对全部移植通用的FreeRTOS源文件
FreeRTOS的核心源代码只包含在两个C文件中,这两个文件是全部FreeRTOS移植所通用的。这两个文件是tasks.c和list.c,直接位于FreeRTOS/Source目录下,除这两个文件外,还有一些源文件也位于同一目录下,如图1-2所示。
图1-2 FreeRTOS目录树中核心的FreeRTOS源文件
• queue.c
queue.c同时提供了队列和信号量服务,在本书后面会有介绍。queue.c几乎总是需要的。
• timers.c
timers.c提供了软件定时器功能,在本书后面会有介绍。只有在实际使用软件定时器的情况下,才需要在构建中包含该文件。
• event_groups.c
event_groups.c提供了事件组功能,在本书后面会有介绍。只有在实际使用事件组的情况下,才需要在构建中包含该文件。
• croutine.c
croutine.c实现了FreeRTOS的协同例程功能。只有在实际使用协同例程的情况下,才需要在构建中包含该文件。协同例程的目的是用于非常小的微控制器上,现在已经很少使用了,因此没有像FreeRTOS的其他功能那样进行相同程度的维护。协同例程在本书中没有介绍。
人们认识到,文件名可能会导致名称空间冲突,因为许多工程已经包含了具有相同名称的文件。然而,我们认为现在改变文件名会有问题,因为这样做将破坏与成千上万使用FreeRTOS的工程、自动化工具和IDE插件的兼容性。
与移植相关的FreeRTOS源文件
与FreeRTOS移植相关的源文件包含在FreeRTOS/Source/portable目录下。可移植目录是按层次排列的,首先是编译器,然后是处理器架构。FreeRTOS目录树中与移植相关的源文件如图1-3所示。
图1-3 FreeRTOS目录树中与移植相关的源文件
如果使用编译器compiler在架构为architecture的处理器上运行FreeRTOS,那么除核心的FreeRTOS源文件外,还必须构建位于FreeRTOS/Source/portable/[compiler]/[architecture]目录下的文件。
正如第2章“堆内存管理”所描述的那样,FreeRTOS也认为堆内存分配是可移植层的一部分。使用低于FreeRTOS V9.0.0版本的工程必须包含堆内存管理器。从FreeRTOS V9.0.0开始,只有在将FreeRTOSConfig.h中的configSUPPORT_DYNAMIC_ALLOCATION设置为1,或者configSUPPORT_DYNAMIC_ALLOCATION未被定义时,才需要堆内存管理器。
FreeRTOS提供了5种堆分配方案。这5种方案按heap_1~heap_5命名,分别由源文件heap_1.c~heap_5.c实现。堆分配方案的示例包含在FreeRTOS/Source/portable/MemMang目录下。如果已经将FreeRTOS配置为使用动态内存分配,那么就必须在工程中构建这5个源文件中的某一个,除非应用程序有别的替代实现方案。
包括路径
FreeRTOS需要在编译器的包含路径中包含3个目录。这3个目录如下所示。
(1)核心的FreeRTOS头文件的路径,通常为FreeRTOS/Source/include。
(2)与FreeRTOS移植相关的源文件的路径。如前面所介绍的,这个目录是FreeRTOS/Source/portable/[compiler]/[architecture]。
(3)FreeRTOSConfig.h头文件的路径。
头文件
使用FreeRTOS API函数的源文件必须包含FreeRTOS.h,后面的头文件包含用到的API函数的原型——tasks.h、queue.h、semphr.h、timers.h或event_groups.h。