参考:
02-STM32CubeIDE创建FreeRTOS工程_哔哩哔哩_bilibili
大D老师
概述
FreeRTOS (Free Real-Time Operating System)** 是一个开源的、小型的、专为微控制器设计的实时操作系统内核。它在资源受限的嵌入式系统中扮演着核心角色,提供任务调度、通信、同步和定时器等关键服务。
层级架构:
从上至下,由表及里:
- 应用:使用FreeRTOS实现具体逻辑:
- Task层:通过FreeRTOS创建任务:
- 系统初始化层:初始化系统时钟,外设,硬件,FreeRTOS内核等
- FreeRTOS内核层:调度和管理任务的核心层,负责任务调度、通信、同步和定时器等;
- 硬件抽象层(HAL):最内层,直接操作硬件;
- 硬件层:STM32芯片
核心定位
- 实时性:核心目标是提供*确定性*和*可靠性*的任务执行。保证高优先级的任务能在预定的时间内(或尽可能接近)响应事件并执行完毕。对于控制类应用(如电机控制、传感器读取)至关重要。
- 轻量级:设计极其精简,内核代码量小(通常几KB到十几KB),内存占用低(RAM 需求从几百字节到几KB不等)。这使得它非常适合资源极其有限的微控制器。
- 可移植性:内核绝大部分代码用标准的 C 语言编写,与处理器架构无关。通过提供针对不同处理器架构(ARM Cortex-M, RISC-V, PIC, AVR, MSP430, Xtensa 等)的*移植层*,可以轻松地移植到各种微控制器上。
- 开源免费:采用 MIT 许可证,允许在商业闭源产品中免费使用、修改和分发,无需支付版税,极大地降低了开发成本。
核心功能:
任务调度:
- 抢占式调度:核心机制。高优先级任务可以“抢占”(中断)正在运行的低优先级任务,立即获得 CPU 执行权,确保高优先级事件的及时响应。
- 时间片轮转调度: 在相同优先级的任务之间,可以配置为按时间片轮流执行,实现公平性。
- 协程: 提供了一种更轻量级的、协作式(非抢占)的任务模型(现在较少使用)。
任务间通信与同步:
- 队列:最主要的通信机制。任务之间、任务与中断服务程序之间可以通过队列安全地传递数据(消息或数据块)。支持阻塞和非阻塞操作。
- 信号量:用于资源访问控制(二进制信号量、计数信号量)和任务同步(通常用二进制信号量实现)。
- 互斥锁: 一种特殊的二进制信号量,具有*优先级继承*机制,用于解决优先级反转问题,保护共享资源。
- 事件组:允许任务等待或通知多个事件(标志位)的组合,提供更灵活的同步方式。
内存管理:
- FreeRTOS 本身不提供复杂的内存分配器,而是提供几个可选的、简单的堆管理方案(`heap_1` 到 `heap_5`),开发者也可以完全使用自己的内存分配策略。
- `heap_4` 和 `heap_5` 提供了碎片整理功能。
时间管理:
- 系统节拍器:依赖硬件定时器中断提供时间基准(Tick),用于任务延时、超时判断和调度决策。
- 软件定时器:提供创建周期性或一次性定时器的功能(由守护任务管理执行回调函数)。
- 中断管理:提供安全的机制让中断服务程序与任务进行通信(通常通过队列、信号量、任务通知)和唤醒阻塞的任务。定义了中断安全版本的 API(通常以 `FromISR` 结尾)。
优势:
- 极低的资源开销:对 RAM 和 ROM 的需求极小,适用于成本敏感、资源受限的 MCU。
- 卓越的实时性能: 抢占式调度确保了关键任务能及时响应。
- 高可移植性:广泛支持各种微控制器架构和开发工具链。
- 强大社区和生态系统:拥有庞大且活跃的开发者社区,丰富的文档、教程、示例和第三方组件支持。
- 免费且商业友好:MIT 许可证消除了商业化的障碍。
- 成熟稳定:经过多年发展和广泛应用(数十亿设备部署),非常成熟可靠。
- 模块化设计:核心精简,许多高级功能(如 TCP/IP 栈、文件系统、USB 协议栈)可通过附加组件实现,按需选用,避免资源浪费。
- 亚马逊维护: 自 2017 年起由亚马逊 AWS 收购并积极维护,确保了其持续发展和支持。
应用领域:
-
工业自动化与控制(PLC、传感器、执行器)
-
消费电子(家电、可穿戴设备、智能家居)
-
汽车电子(车身控制、信息娱乐辅助系统)
-
物联网设备与边缘节点
-
医疗设备(监护仪、便携设备)
-
网络设备(交换机、路由器模块)
-
测试测量设备
-
任何需要多任务管理、实时响应且运行在资源受限 MCU 上的嵌入式系统。
部署
以STM32cubeIDE为例,核心流程:创建工程 -> 图形化配置 -> 生成代码 -> 编写任务代码
S1:创建或打开 STM32CubeIDE 工程
S2:使用 CubeMX 配置 FreeRTOS
ioc 配置:
在 Project Explorer 中双击项目根目录下的 .ioc 文件,打开 CubeMX 图形界面。
启用 FreeRTOS:
在左侧的 Middleware and Software Packs 分类下,找到 FREERTOS。点击下拉箭头,选择 CMSIS_V2 (推荐使用此版本,兼容性更好,功能更丰富)。状态会变为 Enabled。(可选) 如果你看到的是 CMSIS_V1 或 Native,CMSIS_V2 通常是更好的选择。
配置 FreeRTOS 参数 (关键步骤):
-
切换到顶部的
Middleware and Software Packs选项卡 (或直接在.ioc视图中间区域找到 FreeRTOS 配置项)。 -
选择 FreeRTOS 接口,推荐选择
CMSIS_V2(功能更丰富,兼容性更好),点击下拉框 → 选择CMSIS_V2→ 状态变为Enabled -
展开
FREERTOS下的Configuration, -
Kernel Settings标签页:-
TICK_RATE_HZ:设置系统节拍频率 (Hz)。通常为 1000 (1ms) 或 100 (10ms)。更高的 Tick Rate 提供更精细的时间控制但增加 CPU 开销。 -
USE_PREEMPTION:确保勾选 (抢占式调度是核心)。 -
MAX_PRIORITIES:设置最大优先级数量 (通常 5-15 足够,太多浪费 RAM)。 -
MINIMAL_STACK_SIZE:设置最小任务栈大小 (单位:字,4字节/字)。务必根据任务需求增加! 默认值 (128 字 = 512 字节) 对简单任务可能够用,复杂任务或使用 printf 等函数需增大 (如 256-512 字或更大)。栈溢出是常见问题! -
TOTAL_HEAP_SIZE:非常重要! 设置 FreeRTOS 动态内存堆的总大小 (单位:字节)。所有任务栈、队列、信号量等动态创建对象都从这里分配。默认值 (3072 字节 = 3KB) 通常太小! 根据你计划创建的任务数和对象大小估算并增大 (例如 8192, 16384 甚至更大)。监控运行时的xPortGetFreeHeapSize()来调整。 -
MEMORY_ALLOCATION:选择内存分配方案:-
Dynamic:使用 FreeRTOS 自带的堆管理器 (heap_x.c)。heap_4.c(包含碎片合并) 是最常用推荐选项 (在Project Manager -> Code Generator中选择Copy only necessary library files后会自动包含)。 -
Static:用户自己提供内存块 (需要手动分配内存数组)。更复杂但确定性更高。
-
-
配置系统时钟 (SysTick 冲突):
-
-
FreeRTOS 默认使用 SysTick 定时器作为其时钟源 (
Timebase Source)。 -
转到
System Core > SYS配置。 -
确保
Timebase Source设置为除SysTick以外的选项 (如TIM1,TIM6等)。这是必须步骤,避免 FreeRTOS 和 HAL 库争用 SysTick。
-
-
配置中断优先级 (NVIC):
-
转到
System Core > NVIC。 -
找到与 FreeRTOS 相关的中断:
-
PendSV_IRQn:应设置为最低优先级 (如优先级 15)。 -
SVCall_IRQn:通常设置为最低优先级 (如优先级 15)。 -
SysTick_IRQn:FreeRTOS 使用,优先级应高于PendSV和SVC,但低于或等于你应用的最高优先级中断。一个常见的设置是比最低优先级高一点 (如优先级 14 或 15)。确保其抢占优先级低于你的关键硬件中断。
-
-
关键原则:确保 FreeRTOS 管理的中断 (
PendSV,SVC,SysTick) 的优先级低于或等于你应用中需要快速响应的硬件中断的优先级。避免 FreeRTOS 中断抢占关键硬件中断。
-
S3:生成代码
-
完成所有配置(FreeRTOS 和其他所需外设如 GPIO, UART, SPI 等)后。
-
点击 CubeMX 界面顶部的
GENERATE CODE按钮 (或按Alt+K)。 -
STM32CubeIDE 会自动:
-
根据你的配置生成 HAL 库初始化代码。
-
生成 FreeRTOS 配置文件
FreeRTOSConfig.h(位于Core/Inc),包含所有你在 CubeMX 中设置的宏定义。 -
生成 FreeRTOS 移植层代码 (位于
Middlewares/Third_Party/FreeRTOS/Source/portable/[Compiler]/[Architecture],如GCC/ARM_CM4F)。 -
生成你在
Tasks and Queues中定义的任务函数框架 (位于Core/Src/freertos.c和Core/Inc/freertos.h)。任务函数体是空的for(;;)循环或osDelay调用。 -
将 FreeRTOS 内核源文件 (
tasks.c,queue.c,list.c,timers.c,event_groups.c,heap_x.c等) 链接到你的项目 (通常位于Middlewares/Third_Party/FreeRTOS/Source)。
-
S4:编写任务代码
-
在
Project Explorer中,打开Core/Src/freertos.c文件。 -
找到你在 CubeMX 中创建的任务对应的函数 (如
void StartDefaultTask(void *argument)。 -
在此函数内编写你的任务逻辑:
-
任务通常包含一个无限循环 (
for(;;) {...}或while(1) {...})。 -
在循环内部,使用 FreeRTOS API 进行:
-
延时:
vTaskDelay(pdMS_TO_TICKS(100));// 延迟 100ms (推荐方式) -
挂起/恢复任务:
vTaskSuspend(),vTaskResume() -
任务间通信:
xQueueSend(),xQueueReceive(),xSemaphoreGive(),xSemaphoreTake(),xEventGroupSetBits(),xEventGroupWaitBits()等。 -
获取时间:
xTaskGetTickCount()
-
-
-
创建更多任务/对象:
-
除了在 CubeMX 中静态创建的任务,可以在
main()函数 (或某个任务中) 使用 FreeRTOS API 动态创建: xTaskCreate(MyTaskFunction, // 任务函数指针 "MyTaskName", // 任务名字符串 256, // 栈大小 (字) NULL, // 传递给任务的参数 tskIDLE_PRIORITY + 2, // 优先级 &xMyTaskHandle); // 任务句柄指针 (用于后续操作) -
同样可以动态创建队列、信号量等:
xQueueCreate(),xSemaphoreCreateBinary()等。
-
-
启动调度器:
-
在
Core/Src/main.c的main()函数中,HAL 初始化 (MX_xxx_Init()) 和 FreeRTOS 初始化 (MX_FREERTOS_Init()) 完成后,会调用osKernelStart()(这是 CMSIS-RTOS v2 封装的 API)。 -
osKernelStart()会启动 FreeRTOS 调度器,永不返回。 你的任务从此开始运行。
-
S5:编译、下载与调试
-
编译:点击工具栏上的锤子图标或
Project -> Build Project。 -
下载:连接开发板,点击工具栏上的绿色箭头图标或
Run -> Run。 -
调试:
-
使用 STM32CubeIDE 的内置调试器。
-
查看任务状态:在
Run -> Debug后,打开Window -> Show View -> Other...,在FreeRTOS分类下找到FreeRTOS Task List和FreeRTOS Queue List等视图。这些视图能实时显示任务状态(Running, Ready, Blocked, Suspended)、栈使用量、队列状态等,是调试利器! -
监视堆使用:在代码中调用
xPortGetFreeHeapSize()或uxTaskGetStackHighWaterMark()监控堆和栈的使用情况,防止溢出。
-
关键注意事项与提示:
-
栈大小 (
Stack Size) 和堆大小 (TOTAL_HEAP_SIZE): 这是新手最容易出错的地方。务必根据任务复杂度、函数调用深度(尤其是递归、局部大数组、调用库函数如printf)、队列/信号量数量等慷慨设置并实时监控。栈溢出或堆耗尽会导致极其难以调试的崩溃。 -
中断优先级 (
NVIC): 正确配置SysTick,PendSV,SVC的优先级至关重要,必须低于你的关键硬件中断优先级。 -
Timebase Source: 必须确保不是SysTick。 -
API 版本: 优先使用 CMSIS-RTOS v2 (
CMSIS_V2) 封装层。它提供了更现代、更统一的 API 接口。 -
延时: 在任务中务必使用 FreeRTOS 提供的延时函数 (
vTaskDelay,osDelay),而不是 HAL_Delay 或忙等待。这会让出 CPU 给其他任务。 -
共享资源保护: 在任务间或任务与中断间共享变量、外设等资源时,必须使用互斥量 (
osMutex...)、信号量或关中断等机制进行保护,防止竞态条件。 -
FreeRTOSConfig.h: 这个文件定义了所有核心配置。CubeMX 生成后,除非必要,不建议手动修改,最好通过 CubeMX 界面修改后重新生成。如需手动调整高级特性,请小心操作。
4357

被折叠的 条评论
为什么被折叠?



