
1. 简介
本文STM32 为例, Crotex
系列属于 ARMv7
架构。
ARMv7-M
等待中断支持使用 (WFI
) 和等待事件 (WFE
) 指令是系统电源管理的一部分;
ARMv7-M
有三种电源模式 :运行、 三种睡眠,深度睡眠。
一般来说,对于基础 ARM
架构的 MCU
系统或电源复位后,CPU
处于运行状态 CPU
当不需要继续运行时,可以使用各种低功耗模式来节省功耗。 进入低功耗模式之后,等待一个外部事件将 CPU
唤醒。
用户可根据最低功耗、启动时间和可用唤醒源选择合适的低功耗模式。
STM32
有三种低功耗模式:
- 睡眠模式:
Crotex-M3/4
内核停止,所有外设包括Crotex-M3/4
核心外设,如NVIC
、系统滴答定时器Systick
等等还在运行。 - 停机模式: 所有时钟都停止了。 基于停机模式
Crotex-M3/4
深度睡眠模式和外设时钟控制。电压调节器可在正常或低功耗模式下运行。 此时在 1.8V 停止供电区域的所有时钟,禁止振荡器的功能,SRAM
在停机模式下,容都保留在停机模式下I/O
引脚在运行模式下保持状态。 - 待机模式: 1.8V 电源关闭(
Crotex-M3
)。 待机模式可以实现系统的最低功耗。该模式是Cortex-M3
深度睡眠时关闭电压调节器。整个睡眠模式。 1.8V 供电区域断电。PLL
、HSI
(High Speed Internal Clock Signal
) 和HSE
(High Speed External Clock Signal
) 振荡器也断电。SRAM 只有备份的寄存器和待机电路的寄存器和待机电路维持供电。
2. 睡眠模式
2.1 如何进入睡眠模式
通过执行 WFI
(等待中断) 或 WFE
(等待事件) 根据指令进入睡眠模式 Crotex-M3/4
系统控制寄存器 SLEEPONEXIT
睡眠模式可通过两种方案进入位值:
SLEEP-NOW
: 立即睡眠模式。 如果SLEEPONEXIT
清除位置,并当WFI
或者WFE
被执行时,MCU 会立即进入睡眠模式。SLEEP-ON-EXIT
: 退出时的睡眠模式。 如果SLEEPONEXIT
当系统退出最低优先级中断处理程序时,位置位置,MCU 立即进入睡眠模式。
我们通常在实际应用中使用它 WFI
指令进入睡眠模式,睡眠模式的进入机制是 SLEEP-NOW
。系统复位上电后 SLEEPONEXIT
位置被清除了,所以这个位置不需要专门设置。此外,在睡眠模式下,所有这些都是 I/O 口 它们在运行模式持它们的状态。
如果运行 FreeRTOS
系统后,不使用 tickless
如果是低功耗模式,我们可以 WFI
指令放在空闲任务中。 FreeRTOSConfig.h
中将宏 configUSE_IDLE_HOOK
修改为 1 ,并且重写 vApplicationIdleHook
函数。
// To Test Low power mode - Set configUSE_IDLE_HOOK as '1' in FreeRTOSConfig.h void vApplicationIdleHook( void ) { __WFI(); }
但是,如果我们运行的话 tickless
模式(在 FreeRTOSConfig.h
中将宏 configUSE_TICKLESS_IDLE
修改为 1 ),基本上不需要这种方法。
需要注意的是,在 FreeRTOSConfig.h
在中间,我们通常不会使用宏configUSE_IDLE_HOOK
和 configUSE_TICKLESS_IDLE
同时置位。具体原因我后面详细讲解。
2.2 如何退出睡眠模式?
因为我们使用指令 WFI
进入睡眠模式,任何嵌套向量中断控制器 NVIC
系统可以从睡眠模式中唤醒响应的外设。而且这种模式唤醒所需的时间最短,因为中断进出没有时间损失。
如果运行了 FreeRTOS
,主要是定期执行系统滴答定时器中断会唤醒系统冲向睡眠种,其他任何中断也可以从睡眠状态唤醒。
3. 停机模式
3.1 如何进入停机模式
在这种模式下,芯片通常会提供相应的 API
例如,供开发者使用 STM32 可直接调用固件库函数 PWR_Enter_STOPMode()
。 需要注意的是,大多数芯片需要在进入停机模式之前中断所有外部请求位(挂起寄存器)EXTI_PT
) 和 RTC
必须清除闹钟标志位,否则停机模式的进入过程将跳过,程序将继续运行。
3.2 如何退出停机模式?
我们通过 WFI 如果指令进入停机模式,则设置任何外部中断线 EXTI
并在中断模式 NVIC
该中断唤醒停机模式可用于中断相应的外部中断向量。例如,将按钮设置为中断触发。按下按钮时,系统可以从停机模式中唤醒。
需要注意的是,滴答定时器必须在停机模式下关闭,因为滴答定时器也可以中断 MCU
唤醒停机模式。 另一点是,当中断或唤醒事件导致退出停机模式时,可能涉及需要重新配置时钟。 STM32
上,退出停机模式时, HSI RC
振荡器将被选为系统时钟。此时,用户应根据需要重新配置时钟。 HSE
时钟需要重新配置和使能 HSE
和 PLL
.
4. 待机模式
4.1 如何进入待机模式
进入待机模式类似于进入停机模式,提供相应的服务 API
,比如我们熟知的 STM32
固件库函数可直接调用PWR_EnterSTANDBYMode
进入待机模式。
4.2 如何退出待机模式?
可采用外部复位( NRST
引脚)、IWDG
复位、WKUP
上升沿或引脚 RTC
闹钟事件的上升边缘。 除电源控制/状寄存器外,所有寄存器都被复位。
待机模式唤醒后的代码执行相当于复位后的执行。 电源控制/状态寄存器(PWR_CSR
)将指示内核处于待机状态。
5. 关于 WFI 和 WFE
WFI 和 WFE 也许每个人都应该经常遇到这两个指令。这里我简单提一下。
WFI(Wait for interrupt)
和 WFE(Wait for event)
是两个让 ARM
核进入 low-power standby
模式指令,由 ARM
架构定义,由 ARM core
实现。
WFI和WFE以 ARMv8-A
以将军为例 ARMv8-A PE
(Processing Element
, 处理单元)设置为 low-power standby state
。
但是 ARM
没有规定架构 low-power standby state
因此,具体形式可以由 ARM core
自行发。但根据 ARM
的建议,一般可以实现有 standby
, dirmant
, shutdown
等等。 但是有一个原则是不能造成内存一致性的问题。
以 Cortex-A57 ARM core
为例,它把 WFI
和 WFE
实现为“ put the core in a low-power state by disabling the clocks in the core while keeping the core powered up
”,即我们通常所说的 standby
模式,保持供电,关闭 clock
。
6. 降低功耗的其他方面
在考虑低功耗的时候,还需要注意以下几个部分:
- 关闭可以关闭的外设时钟
- 降低系统主频
- 关闭可以关闭的外设。比如串口、PWM 之类的。
- 主要 I/O 的状态,因为在睡眠模式下,所有的 I/O 引脚都保持他们在运行模式时的状态
- 如果 I/O 口带上拉,可以设置为高电平输出或者高阻态输入
- 如果 I/O 口带下拉,可以设置为低电平输出或者高阻态输入
- 主要和外设IC连接的 I/O 口状态。比如外接了温湿度传感器。
- 测试电流的时候,需要注意不要连接调试器以及评估班上是否有除了MCU之外的其他模块是否已经断开供电。
本文参考了 ARMv7-M Architecture Reference Manual Reference Manual.