1. 低功耗概述

总体来说,Cortex-M0处理器包含以下低功耗特性:

  • 两个架构相关的休眠模式:普通休眠和深度休眠。

  • 两个指令用于进入休眠模式:WFE(等待事件)和WFI(等待中断)。这两个指令都可用于普通休眠和深度休眠。

  • 退出休眠特性(从异常退出):使得中断驱动的应用程序可以尽可能地处于休眠模式。

  • 可选的唤醒中断控制器(WIC):应用这种特性,处理器处于深度休眠时,其时钟完全关闭。

2. 休眠模式

Cortex-M0具有两种休眠模式:

  • 普通休眠

  • 深度休眠

一般来说,可以通过以下方法来降低休眠时的功耗:

  • 停止部分或所有的时钟信号;

  • 降低微控制器某些部分的时钟频率;

  • 降低微控制器各部分的电压;

  • 关掉微控制器某些部分电源;

可以通过下面三种方法进入休眠模

  • 执行WFE指令

  • 执行WFI指令

  • 利用退出休眠特性

进入普通休眠模式还是深度休眠模式,由SLEEPDEEP控制位决定。该位位于系统控制块(SCB)区域中的系统控制寄存器(SCR),寄存器中还包括了Cortex-M0的低功耗特性的控制位。使用CMSIS操作,可使用寄存器 “SCB->SCR”来访问。关于SCB的介绍,参考章节 1.7 系统异常控制寄存器

系统控制寄存器系统控制寄存器.png

使用CMSIS,可以按照 “SCB -> SCR” 的方式来访问系统控制寄存器。例如:

SCB -> SCR |= 1<<2;  // 使能深度休眠特性

不同休眠模式以及不同休眠操作产生多种组合,如下:

休眠操作多种组合休眠操作多种组合.png

3. 等待事件(WFE)和等待中断(WFI)

Cortex-M0处理器进入休眠模式,可以使用两条指令:WFE 和 WFI。WFE可以被中断请求以及事件唤醒,而WFI则只能被中断请求和调试请求唤醒。

WFE+WFI特性WFE+WFI特性.png

使用CMSIS,对应的内置函数,如下:

WFE+WFI_内在函数WFE+WFI_内在函数.png

3.1 等待事件(WFE)

当使用WFE进入休眠以后,可以通过以下的中断或事件来唤醒:

  • 新挂起的中断(仅当系统控制寄存器中的SEVONPEND置位时有效);

  • 外部事件请求;

  • 调试事件;

Cortex-M0处理器内部有一个事件寄存器,并且只有一位有效。处理器在运行中并且有事件发生时,寄存器置1,并且该信息将保存到处理器执行WFE指令。可以通过以下任何事件来置位事件寄存器:

  • 产生了需要服务的中断请求;

  • 异常进入和异常退出;

  • 不管中断是否允许,有新的挂起中断(仅当系统控制寄存器中的SEVONPEND置位时有效);

  • 发送事件(SEV)指令执行;

  • 调试事件。

在处理器唤醒后发生的多个事件会被当成一个事件。

WFE操作流程WFE操作流程.png

如上图,当处于WFE状态的处理器被事件寄存器中存储的事件唤醒后,寄存器就会被清零。

如果在执行WFE指令时,事件寄存器已经置位,则事件寄存器会被清零,WFE指令也会马上结束,并且处理器不会进入休眠。

如果执行WFE指令时事件寄存器没有置位,则处理器会进入休眠,下一个事件将唤醒处理器,并且事件寄存器会保存清零状态。

WFE唤醒流程WFE唤醒流程.png

如上图,在轮询循环中,WFE可以用于降低功耗。例如,若外设能够产生适用于WFE的事件,则处理器就可以在外设的任务完成后唤醒。由于处理器可以被不同的事件唤醒,所有处理器被唤醒后,也应该检查任务是否已经完成。

如果SCR中的SEVONPEND置位,任何挂起的中断都会产生事件并且唤醒处理器。如果执行WFE时中断已经处于挂起状态,则同一中断的新的请求不会产生事件,并且处理器也不会被唤醒。

3.2 等待中断(WFI)

WFI指令可以被以下方式唤醒:调试请求,或比当前优先级高的中断请求。

WFI唤醒流程WFI唤醒流程.png

WFI操作还有一个特殊用途,也就是在WFI休眠期间,如果PRIMASK屏蔽了某中断该中断的优先级大于当前优先级,那么该中断仍然可以唤醒处理器,只有在PRIMASK清除之前,处理器不会执行该中断处理。

有了这种特性,就可以关闭微控制器的某些部分(如外设总线时钟),而唤醒后执行中断服务程序之前再将它们打开。

3.3 唤醒条件

当处理器利用退出休眠(sleep-on-exit)特性或者执行WFI指令进入休眠之后,就会停止指令执行,并且当发生了中断请求(更高优先级)并且需要处理时,处理器就会唤醒。

如果处理器在异常处理中进入了休眠,并且新产生的中断的优先级与当前相等或者更低,那么处理器将不会被唤醒,并且保持在挂起状态。

处理器也可以通过复位或者调试器的暂停请求唤醒。

在执行WFE指令时,处理器的动作取决于事件锁存的当前状态:

  • 如果事件锁存置位,那么WFE指令完成,它将会被清零,并且处理器不会进入休眠;

  • 如果事件锁存清零,那么处理器会在事件发生前保持在休眠状态;

此处的事件,指以下任何一个:

  • 待处理的中断请求;

  • 进入或退出中断处理;

  • 暂停调试请求;

  • 片上硬件的外部信号(设备相关)

  • SEVONPEND置位并且产生了新的挂起中断;

  • 执行SEV(发送事件)指令;

处理器内的事件锁存可以保持过去发生的事件的状态,以前的事件也可以将处理器从WFE指令唤醒。因此,WFE一般用于空循环或者轮询循环,它能够让处理器进入休眠是不确定的。

WFE和WFI指令的唤醒条件,如下:

WFE+WFI唤醒特性比对WFE+WFI唤醒特性比对.png

WFI和WFE唤醒条件比对,如下:

WFI_WFE区别对比WFI_WFE区别对比.png

这里有个问题,为什么在PRIMASK置位时,处理器不能执行中断服务程序却可以被唤醒?

休眠时PRIMASK置位休眠时PRIMASK置位.png

如上,根据这种特性,处理器可以在执行中断服务程序前进行系统管理任务(例如,恢复外设的时钟)。

4. 退出休眠(sleep-on-exit)特性

退出休眠(sleep-on-exit)是Cortex-M0处理器低功耗特性之一,当其被使能时,如果处理器从异常处理器中退出时没有其他异常等待执行,则自动进入等待中断的休眠模式。

退出休眠特性非常适合中断驱动的应用程序。当该特性使能时,只要完成了异常处理并且返回了线程模式,处理器就会进入休眠模式,而从一个异常处理返回到另外一个异常处理则不会引发处理器休眠(即嵌套中断)。利用退出休眠特性,处理器可以尽可能多处于休眠模式。

退出休眠特性实例退出休眠特性实例.png

处理器的运行情况如下:

处理器退出休眠处理器退出休眠.png

退出休眠特性通过以下两点来降低系统功耗:

  • 中断驱动的应用无需执行线程中不必要的程序;

  • 减少了两次中断之间不必要的压栈和出栈操作;

退出休眠特性由系统控制寄存器中的 SLEEPONEXIT位控制,在中断驱动程序中对该位的置位一般为初始化操作的最后一步完成。否则,如果在初始化期间产生中断,则处理器可能此时就是进入休眠。

使用CMSIS,可以按照 “SCB -> SCR” 的方式来访问系统控制寄存器。例如:

SCB -> SCR |= 0x02;  // 强系统控制寄存器的SLEEPONEXIT置位
while(1)
{ 
    __WFI();   // 执行WFI并进入休眠
}

实际应用中,低功耗模式一览(以STM32F051xx为例),如下:

STM32F051xx系列有三种低功耗模式:

  • 睡眠模式 (Sleep mode) (CPU 时钟关闭 , 所有外设包括内核外设如 NVIC, SysTick, 等仍在 运行 )  

  • 停止模式 (Stop mode) ( 所有时钟都停止 )  

  • 待机模式 (Standby mode) (1.8V 供电域断电 )  

模式进入唤醒对 1.8V 区域 时钟的影响对 VDD 区域 时钟的影响电压调节器
睡眠  (SLEEP-NOW 或SLEEP-ON-EXIT)WFI任一中断CPU时钟关闭,对其它时钟及ADC时钟无影响
WFE唤醒事件
停机 (Stop)PDDS和LPDS 位+ SLEEPDEEP 位+ WFI 或 WFE任一外部中断(在EXTI寄存器中设置)指定通信口接收事件(CEC,USART, I2C)关闭所有1.8V区域时钟HSI和HSE振荡器关闭开启或处于低功耗模式(依据(电源控制寄存器PWR_CR的设置)
待机(Standby)PDDS位+SLEEPDEEP位+WFI或WFE唤醒引脚上升沿,RTC 闹钟,NRST脚的外部复位,IWDG复位
注意:本站所有文章除特别说明外,均为原创,转载请务必以超链接方式并注明作者出处。 标签:ARM,Cortex-M0,Cortex-M0低功耗