FreeRTOS基础篇(二)——移植FreeRTOS
FreeRTOS基础篇(一)——介绍
前言:
本篇文章介绍FreeRTOS的移植方法,以stm32f103举例。
1 下载源码
FreeRTOS 官网 支持中文,提供丰富的包括文档、教程和 API 参考等。
可以从官网下载源码或者从github仓库clone源码。FreeRTOS提供三种版本。
| 仓库 | 版本类型 | 更新策略 | 适用场景 | 是否适合生产环境 |
|---|---|---|---|---|
| FreeRTOS | 正式版(Mainline) | 频繁更新,加入新功能 | 需要最新功能的项目 | 是 |
| FreeRTOS-LTS | 长期支持版 | 只修复Bug,不新增功能 | 工业级稳定产品 | 是 |
| FreeRTOS-Labs | 实验性版本 | 不稳定,可能有新特性 | 评估、学习、Demo 开发 | 否 |
学习为目的建议使用正式版,能接触到最新的功能,工业开发则建议使用长期支持版。
开发项目建议选择长期支持版,功能更稳定。登陆官网可以看到 下载链接 ,但更推荐从github上获取 仓库 。
执行以下指令将仓库克隆到本地。
1 | git@github.com:FreeRTOS/FreeRTOS-LTS.git |
&esmp;clone仓库后还需要更新子仓库。
1 | git submodule update --init |
切换分支可以选择需要的稳定版本,比如我使用最新的长期稳定版 202406-LTS 。

2 freertos工程架构
以下以stm32(STM32F1 Cortex-M3)为例移植freertos,其他平台移植类似。
&emps; 先认识下 FreeRTOS-LTS 的目录结构,202406-LTS版本的目录结构如下(其他版本类似)。
1 | . |
AWS IoT 是亚马逊云科技提供的一个托管云平台,让互联设备(比如传感器、执行器、嵌入式设备)能够轻松、安全地与云应用程序和其他设备交互。它是物联网设备与AWS云之间的桥梁,本篇文章用不到,因此不介绍这部分的移植。主要关注 FreeRTOS 目录,里面是FreeRTOS-LTS的核心源码,目录结构如下。
1 | . |
FreeRTOS采用模块设计,模块化设计让开发者可以按需选择组件,特别适合资源受限的嵌入式设备,只链接实际需要的功能,最大化优化内存和性能。因此以上模块不需要全部移植,只需要移植自己需要的部分。
这里我们移植必须的 FreeRTOS-Kernel 部分,其他部分方法类似。继续熟悉FreeRTOS-Kernel的目录结构。
1 | . |
需要重点了解的内核核心架构如下。
| 文件类别 | 核心文件 | 功能描述 |
|---|---|---|
| 调度核心 | tasks.c, list.c | 任务调度和管理 |
| 通信机制 | queue.c, stream_buffer.c | 任务间数据传递 |
| 同步原语 | event_groups.c | 任务同步和事件管理 |
| 时间管理 | timers.c | 定时器和时间服务 |
| 内存管理 | portable/MemMang/ | 动态内存分配策略 |
| 硬件抽象 | portable/ | 处理器架构移植层 |
继续介绍 portable 的目录结构。
1 | . |
portable 目录是FreeRTOS可移植性的核心,包含了针对不同编译器和处理器架构的适配代码。总结为如下。
| 类别 | 目录/文件 | 功能描述 |
|---|---|---|
| 编译器支持 | GCC/, IAR/, Keil/, ARMClang/ | 不同编译器工具链的适配 |
| 内存管理 | MemMang/ | 5种动态内存分配策略实现 |
| 处理器架构 | ARMv8M/, Common/ | 特定CPU架构的移植代码 |
| 开发环境 | CCS/, MPLAB/, MSVC-MingW/ | 各厂商IDE的集成支持 |
| 其他编译器 | Rowley/, Tasking/, SDCC/等 | 小众或专用编译器支持 |
| 模板文件 | template/ | 新端口开发的参考模板 |
| 第三方 | ThirdParty/ | 第三方移植和维护的代码 |
portable的作用时移植层,主要作用有以下几点。
- 硬件抽象 : 将 FreeRTOS 内核与具体硬件隔离
- 编译器适配 : 处理不同编译器的汇编语法和调用约定
- 架构优化 : 针对特定处理器优化任务切换和中断处理
- 内存管理 : 提供可配置的内存分配方案
MemMang 提供了5种内存管理方法可供选择。
1 | └── MemMang/ # 内存管理方案 |
这种设计使得 FreeRTOS 可以轻松移植到任何支持C语言的微控制器上,只需实现对应的移植层即可。
3 移植FreeRTOS
假定你已经拥有一个基础的芯片平台工程,已经实现基础的编译和运行环境,在此基础上移植FreeRTOS。我以stm32f103裸机工程移植FreeRTOS为例说明移植方法。
3.1 内核移植
将FreeRTOS内核部分移植到本地工程,即将 FreeRTOS-LTS/FreeRTOS/FreeRTOS-Kernel 目录整个拷贝到自己的工程中,操作系统通常作为中间层(底层是微控制器,中间BSW,底层时ASW),我们在自己的工程创建目录 mw 意为Middleware。
FreeRTOS-Kernel 其实是一个独立的仓库,通过子仓库的方式关联到FreeRTOS-LTS仓库,如果自己完全不做修改,也可以作为自己项目的子仓库关联,如果自己有修改则应将原本的 .git , .github 目录删除,通过自己的git进行管理。建议不要改变FreeRTOS-Kernel下的目录结构,在原有的目录结构基础上保留需要使用的部分,删除不需要的目录和文件,这样方便升级FreeRTOS官方版本时的横向对比。如果芯片追求极致的代码量小,工程简化,并不需要追求随官方版本升级,可以只将需要的文件拷贝到自己工程中,做到最简化运行。应尽量避免去修改内核中源码,一旦修改,将来合入官方版本的修改时都需要考虑和自身修改的兼容性,官网的修改经过严格测试,带入自身的修改后理论上需要自己再做严格测试。
- 导入源文件
修改工程根目录的CMakeLists.txt,在 target_sources 中添加相关的源文件路径,主要是一些必要的内核文件。
1 | target_sources(${CMAKE_PROJECT_NAME} PRIVATE |
- 导入头文件
继续修改根目录CMakeLists.txt,添加对应的头文件路径。
1 | target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE |
- 配置FreeRTOSConfig.h
FreeRTOS的内核中含有examples,可以将其中的FreeRTOSConfig.h拷贝到自己的工程中作为初版配置使用,将 FreeRTOS-LTS/FreeRTOS/FreeRTOS-Kernel/examples/template_configuration/FreeRTOSConfig.h 拷贝到自己的工程,比如我将其拷贝到 cfg 目录下。在CMakeLists.txt的target_include_directories中添加该头文件路径(如果缺少路径)。
1 | {CMAKE_PROJECT_NAME} PRIVATE |
FreeRTOSConfig.h中的主要配置如下。
- configTICK_TYPE_WIDTH_IN_BITS
定义了系统节拍计数器的数据类型宽度,由于我使用的32不支持64位,因此需要将定义改为32位(默认是64位)。64位时节拍器技术之很大,几乎不用考虑溢出的问题。
1 |
- configKERNEL_INTERRUPT_PRIORITY
定义了最低优先级,比如我用的stm32f103系列使用4位优先级,范围为0~15,则定义为。
1 |
- configMAX_SYSCALL_INTERRUPT_PRIORITY
定义了系统调用的最大优先级,需要具体值要根据项目需求而定,这里暂时设置为1。
1 |
FreeRTOSConfig.h里有很多宏配置,这篇文章主要介绍移植的方法,后续在其他文章详细展开分析这些配置,这里不用太就接配置,我们先让移植程序跑起来即可。
- 创建Task测试
修改main.c文件,尝试使用FreeRTOS的任务调度,让程序运行起来。
1 |
|
由于FreeRTOS的port.c中定义了 SVC_Handler , PendSV_Handler , SysTick_Handler 三个函数的实现,这可能会芯片平台的定义重复,比如我使用的stm32f103芯片,在stm32f1xx_it.c中也定义了这三个函数的实现,这里我们选择使用FreeRTOS的定义,将stm32f1xx_it.c中实现的这三个函数注释调。
1 | // void SVC_Handler(void) |
同时在FreeRTOSConfig.h中添加以下定义。
1 |
编译、烧录、运行后可以看到成功运行到断点内,系统任务调度成功。








