第一章:项目全景与开发环境搭建
大家好,我是你们的嵌入式系统讲师。今天咱们正式开始《FreeRTOS实战项目:从设计到交付》的第一课。
说实话,我见过太多工程师学RTOS时卡在第一步——环境没搭好,源码移植失败,然后就放弃了。这很可惜。所以这一章,我会带着你一步步把地基打牢。
1.1 FreeRTOS是什么?为什么选它?
FreeRTOS,全称是Free Real-Time Operating System。说白了,它是一个轻量级的实时内核,专门给单片机用的。
你可能会问:「我裸机跑得挺好的,干嘛要上系统?」
嗯,这个问题我十年前也问过自己。当时我在做一个智能家居网关的原型,功能越来越多:Wi-Fi通信、传感器采集、LCD显示、按键扫描……裸机while(1)循环里塞了七八个任务,中断嵌套搞得我头皮发麻。后来上了FreeRTOS,世界清净了。
FreeRTOS的核心价值就三点:
- 任务调度:多个任务看起来「同时」运行,实际上CPU在快速切换
- 资源管理:队列、信号量、互斥锁,帮你搞定数据同步
- 低开销:内核最小可以裁剪到4KB ROM、1KB RAM
我个人习惯:选RTOS时先看生态。FreeRTOS的文档、社区、移植例程都是最全的。STM32官方SDK直接集成了FreeRTOS,省心。
1.2 项目需求分析:智能家居网关
我们这个课程要做的项目,是一个智能家居网关。它负责把家里的各种传感器、开关、家电连到云端,同时支持本地控制。
先看看需求清单:
| 功能模块 | 具体需求 | 优先级 |
|---|---|---|
| 传感器采集 | 温湿度、光照、人体红外 | 高 |
| 网络通信 | Wi-Fi连接、MQTT上报云端 | 高 |
| 本地显示 | OLED屏显示实时数据 | 中 |
| 本地控制 | 按键控制继电器、LED | 中 |
| 远程控制 | 手机APP下发指令 | 高 |
| 异常报警 | 温度超限、设备离线告警 | 低 |
你想想看,如果裸机实现这些功能,光任务调度就够你喝一壶的。传感器采集要定时,Wi-Fi通信可能阻塞,按键要防抖……每个模块的时序要求都不一样。
用FreeRTOS之后,每个功能独立成一个任务,各管各的。采集任务只管读传感器,通信任务只管发数据,互不干扰。
1.3 硬件平台选型:为什么是STM32?
硬件选型这件事,我踩过不少坑。曾经为了省几块钱选了一款小众MCU,结果开发工具链难用,社区没人,遇到问题连个问的人都没有。
所以这次我选STM32F407VET6,原因很简单:
- 性能够用:Cortex-M4内核,168MHz主频,512KB Flash,192KB RAM
- 外设丰富:3个SPI、3个I2C、6个USART、2个CAN
- 生态成熟:Keil、STM32CubeIDE、HAL库、LL库,随便选
- 价格合理:批量采购20元左右,性价比很高
避坑指南:我曾经在项目中期发现Flash不够用,被迫换芯片,重新画板子,浪费了两周。所以选型时建议留出30%的余量。
其他硬件清单:
- ESP8266/ESP32模块(Wi-Fi通信)
- DHT22温湿度传感器
- 0.96寸OLED屏(I2C接口)
- 继电器模块、LED、按键
- 5V/3.3V电源模块
1.4 开发工具链安装与配置
工欲善其事,必先利其器。这里我推荐两种IDE,你选一个就行。
方案一:Keil MDK-ARM
老牌工具,稳定可靠。我用了快十年了。
- 去ARM官网下载Keil MDK v5.38或更新版本
- 安装时勾选「Cortex-M4」器件支持包
- 安装STM32F4的DFP包(Device Family Pack)
- 破解(嗯,你懂的)
方案二:STM32CubeIDE
ST官方出品,免费,功能越来越强。
- 去ST官网下载STM32CubeIDE
- 安装时选择默认路径
- 首次启动会自动下载STM32F4的固件包
我个人建议:新手用STM32CubeIDE,省去破解的麻烦。老手用Keil,编译速度快,调试顺手。
1.5 FreeRTOS源码移植
好,重头戏来了。移植FreeRTOS其实没那么玄乎,说白了就是三步:
- 拿源码:从FreeRTOS官网或GitHub下载v10.4.6版本
- 挑文件:只复制需要的文件到工程目录
- 配接口:配置中断、时钟、堆栈
具体操作:
第一步:复制核心源码
从下载的FreeRTOS文件夹中,找到以下目录:
FreeRTOS/Source/
├── include/ // 头文件,全部复制
├── portable/ // 移植层,挑对应MCU的
│ └── RVDS/ARM_CM4F/ // Keil用的
│ └── GCC/ARM_CM4F/ // CubeIDE用的
├── tasks.c
├── queue.c
├── list.c
├── timers.c
├── event_groups.c
└── croutine.c // 协程,一般不用
第二步:配置FreeRTOSConfig.h
这个文件是FreeRTOS的灵魂。我直接给你一个模板:
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
/* 基础配置 */
#define configUSE_PREEMPTION 1 // 抢占式调度
#define configUSE_IDLE_HOOK 0 // 空闲钩子
#define configUSE_TICK_HOOK 0 // 时钟钩子
#define configCPU_CLOCK_HZ ( ( unsigned long ) 168000000 ) // 168MHz
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) // 1ms一个tick
#define configMAX_PRIORITIES ( 5 ) // 5个优先级
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 128 )
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 30 * 1024 ) ) // 30KB堆
#define configMAX_TASK_NAME_LEN ( 16 )
/* 启用功能 */
#define INCLUDE_vTaskDelay 1
#define INCLUDE_xTaskDelayUntil 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_xSemaphoreTake 1
#define INCLUDE_xQueueSend 1
/* 中断配置 */
#define configPRIO_BITS 4 // STM32使用4位优先级
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0xf
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
#endif /* FREERTOS_CONFIG_H */
注意:configCPU_CLOCK_HZ一定要和你的MCU实际主频一致。我见过有人写168MHz但实际跑72MHz,结果延时全乱了。
第三步:修改中断处理
在stm32f4xx_it.c中,找到PendSV_Handler和SysTick_Handler,改成:
// 在文件开头包含FreeRTOS头文件
#include "FreeRTOS.h"
#include "task.h"
// 修改PendSV中断
void PendSV_Handler(void)
{
vPortSVCHandler();
}
// 修改SysTick中断
void SysTick_Handler(void)
{
if(xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
{
xPortSysTickHandler();
}
}
第四步:验证移植是否成功
写一个最简单的测试代码:
#include "FreeRTOS.h"
#include "task.h"
void vTask1(void *pvParameters)
{
while(1)
{
// 任务代码
vTaskDelay(pdMS_TO_TICKS(1000)); // 延时1秒
}
}
int main(void)
{
// 硬件初始化
HAL_Init();
SystemClock_Config();
// 创建任务
xTaskCreate(vTask1, "Task1", 128, NULL, 1, NULL);
// 启动调度器
vTaskStartScheduler();
// 正常情况下不会执行到这里
while(1);
}
编译下载后,如果程序能跑起来,没有死机,说明移植成功了。
避坑指南:我曾经在移植时忘了改中断优先级分组,结果FreeRTOS的临界区保护失效,任务切换时数据被破坏。记得在SystemClock_Config()之后调用NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4)。
1.6 本章小结
这一章我们做了四件事:
- 理解了FreeRTOS的核心价值
- 明确了智能家居网关的需求
- 选定了STM32F407作为硬件平台
- 完成了开发环境搭建和FreeRTOS移植
下一章,我们会创建第一个任务,让LED闪烁起来。你会发现,原来多任务编程这么简单。
好,今天就到这里。有任何问题,欢迎在课程群里交流。
公众号:蓝海资料掘金营,微信deep3321