1. 课程导论与硬件平台概览
各位同学好,欢迎来到这门实战课。我是你们的老朋友,一个在嵌入式低功耗领域摸爬滚打了十几年的工程师。
咱们这门课,说白了就是解决一个核心矛盾:既要马儿跑,又要马儿不吃草。在物联网终端、可穿戴设备、传感器节点这些场景里,电池就那么一小块,可功能却一个不能少——要采集数据、要处理算法、要无线通信。怎么办?
答案就藏在芯片的「睡眠」和「唤醒」里。今天这第一讲,我们先搭个知识框架,把STM32L4这颗芯片的低功耗家底摸清楚,再看看Cortex-M4内核怎么睡、怎么醒,最后聊聊RTOS选型那些事儿。
本章核心目标:建立「功耗-性能-唤醒延迟」三角权衡的直觉。学完这一章,你应该能回答:为什么选L4?WFI和WFE到底差在哪?FreeRTOS和RT-Thread在低功耗场景下谁更合适?
1.1 STM32L4系列低功耗特性总览
STM32L4系列,是ST主打的超低功耗MCU。我最早接触这个系列是在一个智能水表项目上,当时客户要求一颗CR2032电池撑三年,算下来平均电流得压到10µA以下。说实话,一开始我心里也没底,但L4的表现确实让我吃了一惊。
它的低功耗能力,主要来自这几个方面:
- 多级睡眠模式:从最低功耗的Standby(几十nA),到保留大部分SRAM的Stop 2(几个µA),再到快速唤醒的Sleep模式(几十µA),一共7种模式。你想想看,这就像给系统装了7个档位的变速箱,总能找到最省油的那一档。
- 灵活的时钟门控:每个外设的时钟都可以独立开关。我习惯在进入低功耗前,把不用的外设时钟全关了,就这一招,功耗能降30%以上。
- 丰富的唤醒源:这是咱们这门课的重头戏。RTC闹钟、外部中断、USART、LPUART、I2C、比较器、甚至ADC窗口比较器,都能把芯片从睡梦中叫醒。
- 智能的电源管理:内置的SMPS(开关电源)和LDO(低压差线性稳压器)可以动态切换,在高负载时用SMPS提高效率,在轻负载时用LDO降低纹波。
下面这张图,是我自己总结的L4低功耗架构,你一看就明白:
我的经验:别一上来就追求最低功耗的Standby模式。Standby虽然电流只有几十nA,但唤醒后系统要重新初始化,RAM数据全丢。很多项目其实用Stop 2模式就够了——保留SRAM,唤醒只要几个微秒,电流才1.5µA左右。性价比最高。
1.2 Cortex-M4内核的睡眠模式与WFI/WFE指令
聊完芯片级,咱们看看内核级。Cortex-M4提供了两种进入睡眠的指令:WFI(Wait For Interrupt)和WFE(Wait For Event)。
这两个指令,我刚开始学的时候也搞混过。后来在一个数据采集项目里,因为选错了指令,导致系统响应慢了半拍,才真正把它们吃透。
| 特性 | WFI (Wait For Interrupt) | WFE (Wait For Event) |
|---|---|---|
| 唤醒条件 | 必须产生中断(IRQ) | 中断 或 事件(Event)均可 |
| 事件寄存器 | 不涉及 | 使用事件寄存器,可软件置位 |
| 唤醒延迟 | 稍长(需完整中断响应) | 更短(事件响应更快) |
| 典型场景 | RTOS空闲任务、等待外设中断 | 自旋锁等待、多核同步 |
| 功耗 | 相同(都进入Sleep模式) | 相同 |
你可能会问:「那到底用哪个?」
我的建议是:在RTOS里,99%的情况用WFI。为什么?因为RTOS的任务切换依赖SysTick中断,而WFI正好能被中断唤醒。WFE更适合那种「等一个事件,但不想走完整中断流程」的场景——比如两个核之间用事件信号同步。
⚠️ 避坑指南:我曾经在一个项目里,用WFE代替WFI来实现空闲睡眠。结果发现,有时候WFE莫名其妙就醒了,查了半天才发现是某个外设产生了事件信号,触发了事件寄存器。从那以后,我养成了一个习惯:在RTOS里只用WFI,除非你非常清楚WFE的副作用。
另外,Cortex-M4还支持睡眠模式(Sleep Mode)和深度睡眠模式(Deep Sleep Mode)。区别在于:
- Sleep Mode:内核时钟停止,但外设时钟继续跑。唤醒最快(几个时钟周期),适合频繁进出睡眠的场景。
- Deep Sleep Mode:内核和外设时钟都停,甚至整个芯片进入Stop模式。唤醒慢(几十微秒),但功耗更低。
在STM32L4上,WFI/WFE指令配合SLEEPDEEP位,就能在这两种模式间切换。代码很简单:
// 进入 Sleep 模式(浅睡眠)
SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
__WFI();
// 进入 Deep Sleep 模式(深度睡眠)
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
__WFI();
关键点:进入Deep Sleep前,一定要先配置好PWR寄存器,选择具体的Stop模式(Stop 0/1/2)或Standby。否则芯片可能进入默认的Stop 0,功耗不是最优的。
1.3 主流RTOS在低功耗场景下的选型考量
好了,硬件和内核都聊完了。现在说说RTOS。市面上RTOS很多,但咱们做低功耗,主要看两个:FreeRTOS和RT-Thread。
我两个都用过,各有千秋。下面这张表,是我根据自己的项目经验整理的:
| 对比维度 | FreeRTOS | RT-Thread |
|---|---|---|
| 低功耗支持 | 内置 tickless idle 模式,自动进入睡眠 | 支持 PM 组件,可动态调整功耗模式 |
| 唤醒延迟 | 依赖 SysTick 补偿,延迟可控 | PM 组件可配置,更灵活 |
| 生态与文档 | 全球最广,资料多,但低功耗部分需自己调 | 中文社区活跃,PM 组件开箱即用 |
| 代码体积 | 极小(ROM 4-9KB) | 稍大(ROM 10-20KB,含组件) |
| 学习曲线 | 平缓,适合快速上手 | 稍陡,但功能更丰富 |
| 我的推荐场景 | 简单传感器节点、电池供电设备 | 复杂物联网终端、需要多组件协同 |
说说我的个人习惯吧:
- 如果项目简单——比如一个温度传感器,每隔10秒采集一次,用LoRa发出去。这种场景,我首选FreeRTOS。它的tickless idle模式,说白了就是在空闲时把SysTick停了,等下一个任务该执行时,用RTC闹钟唤醒。代码量少,功耗也低。
- 如果项目复杂——比如一个智能门锁,要处理指纹、蓝牙、键盘、电机驱动,还要考虑安全加密。这种场景,我建议用RT-Thread。它的PM组件可以动态调整CPU频率、电压、甚至外设时钟,比FreeRTOS的tickless idle灵活得多。
我的经验:选RTOS,别只看功能列表。我见过有人用FreeRTOS做复杂项目,结果为了调低功耗,自己写了一大堆PM代码,最后还不如直接用RT-Thread省事。反过来,也有人用RT-Thread做简单项目,结果组件太多,功耗反而下不去。记住:合适的才是最好的。
最后,我想强调一点:RTOS本身不决定功耗,决定功耗的是你怎么用它。同样的FreeRTOS,有人能做出1µA的待机电流,有人做出来100µA。差别在哪?就在唤醒源的配置、睡眠模式的选择、以及任务调度的设计上。这些,正是咱们这门课要讲的核心内容。