YTM32的低功耗系统中有设计了多种工作模式,功耗从高到低,包括:正常工作模式(Active Mode)、休眠模式(Sleep Mode)、深度休眠模式(DeepSleep Mode)、待机模式(Standby Mode)和掉电模式(PowerDown Mode)。其中Active Mode、Sleep Mode和DeepSleep Mode是Arm处理器内核定义的通用功耗模式,分别对应着芯片系统正常工作、停用CPU时钟但不停用系统总线时钟,以及进一步停用系统总线时钟的三种情况。在有多组内部调压器(regulator)的MCU功耗管理系统中,在这三种常规的功耗模式下,在芯片内部通常仍设计使用同一个高压调压器(例如LDO25)供电,此时,在不同工作模式下,通过逐步停用芯片内部各功能区域的时钟,可以实现降低系统功耗。
YTM32在通用功耗模式之外,设计了Standby Mode,相对于Arm定义的DeepSleep Mode,StandBy Mode切换使用芯片内部的处于节能模式的低压调压器(LDO11)为部分片内模块供电,高压调压器处于不激活的节能模式,如此,可以进一步减少系统的功耗。此时,芯片内部只有能够使用低压调压器工作的模块还能存活,例如一些低速的时钟源(SIRC、SXOSC),以及可以使用这些时钟源的外设(LPTMR、SPI、I2C等)。
进一步在PowerDown模式中,彻底停用了高压调压器,仅保留处于节能模式下的低压调压器为部分模块供电,对应也停用了一些原本还可以在Standby模式下存活的外设,仅保留了少量外设,包括SIRC(选配)、SXOSC(选配)、LPTMR、RTC、ACMP等,以及将这些外设的触发事件作为唤醒源唤醒芯片系统的WKU模块。特别注意,在PowerDown模式中,Flash和大部分SRAM(除了一小块特殊保留供电的区域)都已经停电,CPU不能从Flash中读取程序,SRAM中保存的数据也已经丢失,此时,即使原地唤醒MCU,也已经不具备原地唤醒的条件。因此,相比于其他低功耗模式下唤醒从原地醒来继续接着干活,PowerDown模式唤醒后,将直接进入硬件复位流程,通过重新启动过程,重新建立程序的运行环境。
由于PowerDown模式不是原地唤醒,而是进入复位流程重新执行程序,这对开发者不是很友好,因此很多用户都尽量避免使用这种模式。但对于追求极限低功耗的应用场景,PowerDown模式极度省电的特性也能帮助开发者实现最优的低功耗方案。本文整理了使用要点,供开发者了解和利用好PowerDown模式。
另外,关于片内调压器的节能模式,在寄存器字段PCU_CTRL[FASTREC]的介绍中,提到了一些有意思的说法:
This bit controls the recovery time from Low Power Mode (LPM) to Performance Mode (FPM). At recovery from Low Power Mode all the capacitors from the secondary supplies have to re recharged. This high current demand, that might not be met by the supply driving primary domain. When selecting the fast recovery time, the curre echarging is approximately 3 times higher than for FASTREC=0.
这里是说,当芯片系统从低功耗模式中恢复时,需要为次级负载(也就是外设模块)的电容充电(对应于芯片RESET引脚和VDD引脚上的电容)。相对于常规的从低功耗模式下恢复的机制,有一种快速回复模式,如果启用了快速恢复的功能,则会(用更大的电流)加速这个充电的过程,此时在主电源域(VDD)上流过的电流是未启用快速恢复功能的将近3倍,这样的大电流对外部供电系统也提出了要求。
相对于其他低功耗工作模式可以通过任何外设的中断事件唤醒,在PowerDown模式下,Arm核的中断管理器NVIC都已经停用了,不能捕获中断事件。此时,必须使用具体芯片上专门设计的唤醒管理器WKU(概念类似于NXP产品中的LLWU),搜集触发信号,进一步唤醒MCU。需要特别注意的是,WKU模块仅能在PowerDown模式模式中时钟,WKU模块是不起作用的,
WKU模块(Wakeup Unit)可以捕获两种事件以唤醒PowerDown模式下的MCU:
其中,WKU监控最多32个(受限于32位的WKU_PFR寄存器的宽度)唤醒引脚(Wake-Up Pin)上的电平变化,用户可在每个独立的WKU_PCRn[WUPE]
寄存器字段中,为对应的唤醒引脚单独设置唤醒的事件,为上升沿、下降沿或者任一边沿。如图x所示。
当配置启用唤醒引脚捕获外部引脚上特定的边沿触发事件,就相当于是把这些外部引脚都变成了工作在PowerDown模式下的复位引脚,外部电路可以通过它们复位并唤醒MCU。
从图x中还可以看到,在WKU_PCR
寄存器唤醒引脚启用滤波器,以对外部输入的信号“消抖”。如果不启用滤波器,单纯监测外部电平变化产生唤醒请求,则MCU在PowerDown模式下也可以停用SIRC和SXOSC。但如果要启用过滤器,就必须启用对应的时钟源,因为过滤器是基于某一个时钟源进行连续采样和判别,从而实现“消抖”的功能。
这里提到的唤醒引脚,是WKU模块内部的信号,但在具体芯片上,WKU的唤醒引脚都是绑定到MCU的具体引脚上的,例如,在YTM32B1ME05的手册中,就有具体列出的引脚映射关系,如图x所示。
除了WKU管辖的32个普通的唤醒引脚,WKU还专门为RESET引脚设计了配置寄存器WKU_RPCR
,如图x所示。其中也包含了关于引脚上滤波器的配置字段。另外,可以选配将RESET作为WKU的唤醒源,但若启用,只能通过下降沿触发(同复位控制电平保持一致),而不像别的唤醒引脚可以灵活配置多种边沿模式。
WKU也能够捕获到芯片内部模块主动产生的触发信号,转变成唤醒事件。当然,前提是这些模块也能够在PowerDown模式下存活并工作。这些能够在PowerDown模式下存活并且能够产生触发信号给WKU的模块,在每个具体的MCU上都是专门定制的,以YTM32B1ME05为例,在WKU_MER
寄存器中,就设计了能够捕获到的内部模块的开关,如图x所示。
从寄存器字段WKU_MER[WUME]
中可以看到,WKU能够捕获到内部模块的触发信号有RTC_IRQ
、RTC_Seconds_IRQ
、LPTMR0_IRQ
,以及ACMP0_IRQ
。关于此处使用的IRQ信号,对应需要RTC、LPTMR及ACMP0也要启用中断的。但此时并不是说能执行这些外设模块的中断服务程序(Flash和SRAM都断电了,不能访问程序也不能访问栈),而是这些外设模块在原本设计的中断事件产生了原本要发给NVIC中断管理器的触发信号,被WKU捕获,用作了唤醒源而已。类似地,本节前文内容中提到的WKU_PCR
寄存器中,也要求当使用唤醒引脚时,也要在寄存器字段WKU_PCR[WUPIE]
中开启对应的中断开关,不为调用中断服务程序,仅用于产生触发信号作为唤醒源而已。
这样分析下来,中断向量表中的WKU_IRQn
也只是为了在通用的NVIC框架下管理WKU模块的中断信号而已,不见得真的能用上WKU_IRQHandler
,所以,有一些非常细致的开发者会关心WKU唤醒后,是先执行WKU_IRQHandler
中程序还是先执行复位流程。结论是,压根不建议使用WKU_IRQHander
,还是之前强调过的,PowerDown模式下,Flash和SRAM都断电了,不具备原地执行程序的条件。
在进入PowerDown模式之前,一定要预先配置好唤醒源。
在进入PowerDown模式之前,一定要预先配置好唤醒源,否则芯片睡下去之后,就叫不醒了。咳咳,好吧,直接断电重新上电(POR)或者硬复位也可以让芯片恢复到正常工作状态,等价于PowerDown模式的唤醒行为。但这种唤醒其实是人工唤醒,不是监测外部触发信号唤醒,在实际产品中是没有意义的。不会真的有人将外部唤醒信号连到RESET引脚上吧,万一程序正常运行的时候被外部的触发信号意外复位,岂不是飞来横祸。。。
配置唤醒源的操作,是可以在程序正常运行的模式下完成的。配置引脚或者配置片内外设作为唤醒源都可以。若配置片内外设作为唤醒源,例如LPTMR,需要预先将作为唤醒源的外设及依赖的时钟源、电源都配置成可以在PowerDown模式下存活的状态,如此后续系统的电源管理电源PMU切换至PowerDown模式时,不影响唤醒源继续工作。
PowerDown模式作为低功耗模式的扩展,也遵循使用WFI
指令进入休眠的操作。但进入休眠之前,还需要进行一些专门的配置,告诉PMU将要进入的低功耗模式是PowerDown模式,而不是别的低功耗模式。
在YTMicro SDK的power驱动模块中,有关于切换低功耗模式的API,POWER_SYS_SwitchToLowPowerMode()
,其中展现了进入PowerDown模式前需要准备的配置工作。
static void POWER_SYS_SwitchToLowPowerMode(const power_manager_user_config_t * const configPtr)
{
uint32_t systickCSR;
uint32_t cmuCtrl = SCU->CMU_CTRL;
/* Configure the hardware layer */
switch (configPtr->powerMode)
{
...
case POWER_MANAGER_POWERDOWN:
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
PCU->CTRL &= ~(PCU_CTRL_RPMEN_MASK | PCU_CTRL_STANDBYEN_MASK);
PCU->CTRL |= PCU_CTRL_RPMEN_MASK;
break;
...
}
/* Disable CMU before entering low power mode */
SCU->CMU_CTRL = 0;
SCU->CMUSTS = SCU->CMUSTS;
/* Disable systick before entering low power mode */
systickCSR = SysTick->CTRL;
SysTick->CTRL = 0x00;
if (configPtr->sleepOnExitValue)
{
SCB->SCR |= SCB_SCR_SLEEPONEXIT_Msk;
}
else
{
SCB->SCR &= ~(SCB_SCR_SLEEPONEXIT_Msk);
}
__asm("wfi\n");
/* Restore systick */
SysTick->CTRL = systickCSR;
/* Restore CMU control register */
SCU->CMU_CTRL = cmuCtrl;
}
首先,要在Arm核规范的系统控制块模块中的SCB_SCR
寄存器中,启用SCB_SCR_SLEEPDEEP_Msk
位,表示在Arm核看来,PowerDown模式也是同自身的DeepSleep模式处于同一个级别的低功耗模式。然后在YTM32自己的功耗管理单元PCU的寄存器PCU_CTRL
中,指定目标低功耗模式时DeepSleep而不是StandBy模式。RM手册中有PCU_CTRL[PCU_CTRL_RPMEN_MASK]
寄存器的描述,如图x所示。
在进入PowerDown模式后,整个芯片系统以一种“不正常”的工作方式运行,需要提前关闭一些监测芯片正常工作的外设模块,防止误报错,例如,监测时钟系统稳定与否的CMU(Clock Monitor Unit)模块,监测系统供电低压LVD(Low Voltage Detection)模块等。
YTM32微控制器片内集成的复位管理模块RCU(Reset Control Unit),也为唤醒复位后的程序提供了复位事件的标志位,见RCU_RSSR
寄存器,用来指示本次复位可是来自于从PowerDown模式下唤醒(使用RCU_RSSR[POR_LVD]
标志位)。这些标志位是Sticky的,为了确保他们能够正确地指示最近一次的复位事件,程序在每次复位判定复位原因后,都需要手动清零,为记录下次复位原因做准备。
在RCU_RSSR
寄存器中,还设计了一个LPACK
字段,用于指示当进入低功耗模式(包括DeepSleep、StandBy和PowerDown)失败超时产生的复位事件。如图x所示。
手册中对RCU_RSSR[LPACK]
字段的机制有进一步的说明:
The low power mode entry acknowledge timeout reset is generated if the MCU fails to enter low power
mode mode within 2^24 cycles of SIRC clock.
细心的读者会注意到,这里有个低功耗模式的应答和超时的概念。我试着演绎一下应答和超时的工作机制。当软件配置PCU进入低功耗模式后,PCU不是立刻粗暴地停用调压器,直接断开各外设模块的时钟供给,而是先给各外设模块发出断电的请求,各外设模块收到请求后,自行以安全的执行序列进入安全状态,准备休眠,并给PCU回复应答,可以断电了。PCU在收到所有外设模块的断电应答确认后,开始停用调压器,整个系统可以平稳切换至低功耗模式。但是,若因为某些原因(例如外设模块内部的状态机意外地执行到某个死锁的状态,或者任务负载过重来不及调度),导致外设模块在收到断电请求后,来不及在一个预留的事件段内切换到安全状态,更别说再回发断电应答了,那PCU不会那么智能地选择帮助外部模块诊断(各种稀奇古怪的)回复超时的原因,而是选择直接断电。此时的外设,像极了被宿管阿姨熄灯时,没准备好上床睡觉的各位同学。这种情况下断电,外设可能会被定格在不确定的情况下,产生额外的漏电,导致整个系统未能达到预期的低功耗性能指标。
RCU_RSSR[LPACK]
标志位就反馈了这样的一种情况,当重新唤醒复位后,交由软件判定,并对上个休眠周期中未能成功进入低功耗的原因进行诊断。
SCU模块中,配置SIRC时钟源的寄存器位SCU_SIRC_CTRL[SIRC_PD_ EN]
,可以选配在PowerDown模式下,SIRC是否可以继续存活。配置SXOSC(低速晶振,32.768kHz)时钟源的寄存器位SCU_SXOSC_CTRL[SXOSC_PD_ EN]
,可以选配在PowerDown模式下,SXOSC是否可以继续存活。
在DataSheet文档中,可以查阅到YTM32微控制器在PowerDown及其他低功耗模式下的性能指标,包括低功耗下的极限静态电流,以及唤醒时间等等。
PowerDown模式可以实现最低的功耗模式,在超低功耗模式下,通过WKU管理的多种唤醒源,通过复位(而不是原地)唤醒微控制器芯片。