处理器电源管理(以Cortex-M3为例)

睡眠与深睡眠度

不同于以往的处理器,CM3 对电源管理的重视,已经上升到处理器内核的水平上。它提供了若两种睡眠模式。在睡眠时,可以停止系统时钟,但可以让 FCLK 继续走,以允许处理器能被 SysTick异常唤醒。这两种睡眠模式依次为:

睡眠:由 CM3 处理器的 SLEEPING 信号指示

深度睡眠:由 CM3 处理器的 SLEEPDEEP 信号指示

为了判定当前使用的是哪一种睡眠模式,以及其它睡眠时的上下文,需要检视在 NVIC 的系统控制寄存器,如下表(系统控制寄存器(地址:0xE000_ED10))所示。要注意,CM3 的这两条信号线是给芯片设计者看的,需要芯片设计者配合它们作一系列的处理,因此不同的芯片,响应这两种睡眠模式的方式也是不同的。粗线条的实现可能把它们两个等同处理也说不定。

处理器电源管理(以Cortex-M3为例)_第1张图片

通过执行 WFI/WFE 指令,请求 CM3 进入睡眠模式,它们在 CM3 中的地位就类似于某些处理器的”sleep/slp”指令。WFI 表示 Wait-For-Interrupt,而 WFE 表示 Wait-For-Event。那么什么可以算是 event 呢?新来的中断、早先被悬起的中断,或者是通过 RXEV 信号表示的一个外部事件信号脉冲,都属于 event。在处理内部,对事件有一个锁存器,因此过去发生的事件可以用来唤醒将来才执行到的 WFE。流程如下图所示。

处理器电源管理(以Cortex-M3为例)_第2张图片

当处理器进入睡眠模式时,单片机作如何反应,还取决于芯片的设计。最典型的作法就是把一些外设的时钟停掉以降低功耗。当然,芯片还可以做得更有力,切断一部分功能模块的电源,甚至切断整个芯片的电源并且停止所有的时钟。这是把事情做绝了,只能通过复位来唤醒。为此,芯片厂商可以在单片机上提供一个引脚,并根据它的电平变化来产生此复位信号。另外,芯片厂商还可以在设计时加入少量的 SRAM 作为后备存储区,该区电力供应不被切断(如 STM32)。

特殊功能寄存器 PRIMASK 与 FAULTMASK

PRIMASK 用于除能在 NMI 和硬 fault 之外的所有异常,它有效地把当前优先级改为 0(可编程优先级中的最高优先级)。该寄存器可以通过 MRS 和 MSR 以下例方式访问:

1. 关中断

MOV  R0,       #1

MSR  PRIMASK,  R0

2. 开中断

MOV  R0,       #0

MSR  PRIMASK,  R0

此外,还可以通过CPS指令快速完成上述功能:

CPSID  i ;关中断

CPSIE  i ;开中断

FAULTMASK更绝,它把当前优先级改为-1。这么一来,连硬fault都被掩蔽了。使用方案与PRIMASK的相似。但要注意的是,FAULTMASK会在异常退出时自动清零。

掩蔽寄存器虽然能一手遮天,却都动不了NMI,因为NMI是用在最危急的情况下的。

BASEPRI 寄存器

有些情况下,可能只想禁止优先级低于某特定等级的中断,此时,就可以使用BASEPRI寄存器。要实现这个目的,只需简单地j将所需的屏蔽优先级写入BASEPRI寄存器。例如,要屏蔽优先级小于等于0x60的所有异常,则可以将这个数值写入BASEPRI:

__set_BASEPRI(0x60); //禁止优先级在0x60-0xFF间的中断。

若使用汇编:

MOV   R0,       #0x60

MSR   BASEPRI,  R0

WFI/WFE唤醒行为

当从 WFI 唤醒时,要根据异常系统的游戏规则来决定是否唤醒。只有当该中断的优先级比当前优先级要高(如果是在服务例程中使用 WFI),并且比 BASEPRI 掩蔽的高时,才唤醒处理器并执行ISR。但如果 PRIMASK 置位,则依然唤醒处理器,然而 ISR 却不执行了。

WFE 则有点区别,不管优先级和掩蔽情况如何,只要 SETONPEND 置位,它就会不错过任何一个事件,在发生事件时一定把处理器唤醒。至于是否执行 ISR,则与 WFI 的规则相同。

CM3 处理器唤醒的具体规则如下表所示(带“+”的表示执行此动作)。但要注意:这是假设中断的优先级比当前优先级要高的。

处理器电源管理(以Cortex-M3为例)_第3张图片

处理器电源管理(以Cortex-M3为例)_第4张图片

你可能感兴趣的:(ARM,CORTEX-M底层技术,cortex,电源管理,pmu)