文章目录
- 芯片的低功耗
- 1.1 低功耗的测量数据
- 1.2 低功耗的系统特性
- 1.3 低功耗的系统需求
- 1.3.1 Cortex-M3和Cortex-M4处理器的低功耗特点
- 1.4 低功耗系统特性
- 1.4.1 休眠模式
- 1.4.2 系统控制寄存器(SCR)
- 1.4.3 进入休眠模式的指令
- 1.4.4 唤醒条件
- 1.4.5 休眠扩展/唤醒延迟
- 1.4.6 唤醒中断控制器(WIC)
- 1.4.7 状态保持功率门(SRPG)
- 1.4.8 事件通信接口
- 1.4.8.1 外设与处理器之间通信
- 1.4.8.2 多处理器之间通信
- 1.4.8.3 信号量和互斥体
- 1.4.9 退出时的休眠特性
- 1.5低功耗指令的用法
-
- 开发低功耗应用的注意点
芯片的低功耗
1.1 低功耗的测量数据
Cortex-M微控制器的一个主要优势在于能耗效率和低功耗特性。能耗效率一般有一定的能量可以完成的工作来衡量,可以为DMIPS/uW或CoreMark/uW等形式,不过,低功耗的测量只会注重动态电流和休眠电流,其中动态电流的单位为uA/MHz, 休眠电流则为uA(时钟停止)。
1.2 低功耗的系统特性
目前,许多Cortex-M微控制器都具有许多可以提高电池寿命的系统特性。例如:
- 多种运行模式和休眠模式
- 超低功耗的实时时钟(RTC)、看门狗和掉电检测(BOD)
- 在处理器处于休眠模式时仍可以运行的只能外设
- 灵活的时钟系统控制特性,设计中不活跃的部分可被关闭
1.3 低功耗的系统需求
低功耗系统在设计时需要考虑的需求如下:
不同的嵌入式系统需要考虑的低功耗需求也是不同的,比如,对于一些电池供电的产品,能耗效率是最为关键的因素,但是对于一些追求实时特性的工控应用来说,唤醒等待时间会更为关键。中断驱动系统的工作流程如下:
若数据处理请求为周期性的,且每次的持续时间都相同,在无须考虑数据处理等待时间的情况下,可以再尽可能低的时钟频率下运行以降低功耗。
1.3.1 Cortex-M3和Cortex-M4处理器的低功耗特点
- 低功耗设计:这两种处理器的硅片面积更小,且具有多种低功耗的优化。
- 高性能:微控制器可以运行在较低的时钟频率下,或者更快的完成处理任务以便可以在休眠模式中多待些时间。
- 高代码密度:对于同一个应用任务,可以使用具有较小Flash存储器的微控制器以降低功耗和成本。
1.4 低功耗系统特性
1.4.1 休眠模式
Cortex-M处理器支持两种休眠模式:休眠和深度休眠。有些情况下,深度休眠模式可利用状态保持功率门(SRPG)等高级芯片设计技术进一步降低功耗。休眠期间发生的情况取决于芯片的设计,多数情况下,可以停止部分时钟信号以降低功耗。不过芯片也可以设计为部分关掉。有些情况下,还可以将芯片全部掉电,将处于这种掉电模式下的系统唤醒的唯一方法为系统复位。不同模式的功耗对比如下:
1.4.2 系统控制寄存器(SCR)
SCR => System Control Register(0xE000ED10),利用这个寄存器可以选择进入什么睡眠模式,也可以选择是不是要发送事件。具体如下:
1.4.3 进入休眠模式的指令
处理器提供了两个用于进入休眠模式的指令:WFI和WFE。具体的用法如下:
WFE可由事件唤醒,其中包括事件输入信号脉冲(在处理器中名为RXEV)及之前产生的事件。在处理器内部,之前产生的事件会体现在只有一位的事件寄存器中,该事件寄存器可由下列情况置位:
- 异常进入和退出
- 在使能SEV-ON-PEND特性后,当中断挂起状态由0变为1时,事件寄存器会置位
- 片上硬件的外部事件信号(RXEV)
- SEV(发送事件)指令的执行
- 调试事件(如暂停请求)
与WFI休眠类似,在WFE休眠期间,若中断的优先级高于当前等级,该中断可以将处理器唤醒,不管其优先级是否被BASEPRI屏蔽掉,或者SEV-ON-PEND如何设置。
1.4.4 唤醒条件
多数情况下,中断(包括NMI和Systick定时中断)可以将Cortex-M3或M4从休眠模式中唤醒。不过,有些睡眠模式可能会关掉NVIC或外设的时钟信号,但是具体还是根据芯片而异,可能有的中断时无法唤醒MCU的,只有特定中断才能唤醒。WFI的具体唤醒条件如下:
WFE的唤醒和WFI稍有不同,其中一个SEV-ON-PEND的bit位对其影响很大,如果这个bit位置位,无论什么中断产生并被挂起,都会唤醒处在WFE的MCU。具体唤醒条件如下:
注:当SEV-ON-PEND置位,只会在挂起位从0变到1的上升沿才会产生唤醒事件唤醒WFE,如果新产生的中断挂起位已经置位,那么就不会产生唤醒事件了。
1.4.5 休眠扩展/唤醒延迟
对于一些MCU,有些低功耗模式可能会通过某种手段极大地降低功耗,如减小对SRAM的供电(SRAM分区供电)并关掉Flash存储器的供电。有些情况下,中断请求产生后,硬件电路需要时间来恢复,因此中断实际执行的时间会被延迟。Cortex-M3/M4处理器提供了一组握手信号,利用这些信号,只有在其他部分准备好以后,处理器才会被唤醒。==该特性仅对芯片设计者可见,对软件则不可见。==使用该特性时候,会发觉中断等待时间变长了。
1.4.6 唤醒中断控制器(WIC)
WIC => Wakeup Interrupt Controller。系统进入深度睡眠期间,当处理器的所有时钟信号都被关闭后,NVIC无法检测到新产生的中断请求。为了解决这个问题,Cortex-M3版本r2p0之后引入了一个WIC的硬件单元,这个WIC是没有可编程寄存器的。芯片设计者可以配置WIC的中断检测逻辑,以支持异步操作。WIC一端连着电源管理单元PMU,一端连着NVIC,中断屏蔽信息在刚进入深度睡眠模式前由NVIC发送到WIC中,当产生中断时,WIC检测到该请求并通知PMU恢复时钟,然后处理器唤醒并通知PMU恢复时钟,一切准备就绪再去处理中断。
1.4.7 状态保持功率门(SRPG)
SRPG => State Remain Power Gate。此高级技术可以极大地降低芯片的漏电流。在SRPG中,寄存器(在IC术语中通常被称为触发器)中状态保持单元是独立供电的,进入深度睡眠的时候,状态保持单元不掉电。具体的逻辑电路如下:
SRPG虽然可以保存掉电前的状态,但是深度睡眠的时候仍然无法检测中断,因此还是需要WIC。对于SRPG设计,由于处理器的状态得到了保留,它可以从程序暂停的地方继续执行,这样就不会每次上电都由代码来恢复寄存器。
WIC只会用在深度睡眠模式(此时系统控制寄存器中的SLEEPDEEP置位)。普通的休眠模式不会使能WIC操作,也不应该触发SRPG掉电操作。
另外还有一点需要注意,当使用调试器链接系统时,调试器可能会禁止一些低功耗操作。例如,微控制器可能会被设计为,当连接调试器时,时钟会在深度睡眠模式继续运行,这样即使应用代码试图使用深度睡眠模式,调试器也可以检测系统状态。
1.4.8 事件通信接口
WFE指令可由Cortex-M处理器中一个名为RXEV(接收事件)输入信号唤醒。处理器中还有一个名为TXEV(发送事件)的输出信号,当执行SEV(发送事件)指令时,TXEV会输出一个周期的脉冲信号,此时RXEV就检测到输出信号,就会唤醒处于WFE的处理器。事件通信接口的目的就是,在特定事件发生前,处理器处于休眠状态,此时可以节省功耗,事件通信接口具有多种用法。
1.4.8.1 外设与处理器之间通信
对于具有DMA的单处理器设计,处理器会利用DMA控制器进行存储器复制操作以提高性能。如果处理器用轮询来检测DMA是否完成,就会浪费能量且由于部分带宽被处理器占用而降低了性能。如果DMA操作完成之后,能够发送一个事件,这样在等待DMA结果的时候就可以用WFE进行休眠,从而节省功耗。当然,也可以将DMA输出的DMA_Done信号连接到NVIC,并利用中断机制来唤醒处理器。具体的代码如下:
setup_DMA_memcpy(src, dest, length);
while((get_DMA_status() & DMA_DONE_MASK) == 0)
{
WFE();
}
1.4.8.2 多处理器之间通信
多处理器间的通信同样可以基于事件机制,如果处理器A为了确定处理器B的任务处理是否结束,需要查询共用存储空间中的用一个变量,处理器A可能要等待较长的时间,而且这样还会浪费能量。如果A和B之间用事件机制来通信,那么就可在在等待的过程中进入WFE,这样就会减少功耗。
注:这种任务同步无法保证系统中的多处理器开始任务执行时的精确同步。
1.4.8.3 信号量和互斥体
事件通信接口的另一个用途就是信号量和互斥体,如果信号量机制未使用事件通信特性,处理器可能会轮询检测锁定变量是否空闲,使用了事件接口就可用WFE来等。
void get_lock_with_WFE(volatile int *Lock_Variable)
{
int status;
do
{
while(_LDREXW(&Lock_Variable) != 0)
{
_WFE();
}
status = _STREXW(1, &Lock_Variable);
}while(status != 0);
_DMB();
return;
}
void free_lock(volatile int * Lock_Variable)
{
_DMB();
Lock_Variable = 0;
_SEV();
return;
}
对于具有嵌入式OS的系统,信号量操作可能会有很大不同, 这是因为在OS等待一个信号量时,它可能会将当前任务暂停并转而执行其他任务。
1.4.9 退出时的休眠特性
这个特性主要用在中断驱动的应用中,使能了这个特性,就会减少压栈和出栈。==这个特性应该在初始化阶段结束时使能,否则若在初始化阶段产生了中断事件且退出时休眠特性已使能,则处理器会在初始化阶段还没有完全完成时进入休眠。
1.5低功耗指令的用法
1.5.1 WFI的用法
WFI一般就只会用在中断驱动的应用中,如果中断事件的时序不可控,就无法确定是否能唤醒处理器了,具体参照P211页WFI的用法。
1.5.2 WFE的用法
WFE指令长用于空循环,其中包括RTOS设计中的空循环。下面是WFE的使用示例:
volatile int timer0irq_flag;
timer0irq_flag = 0;
set_timer();
NVIC_EnableIRQ(Timer0_IRQn);
while(timer0irq_flag == 0)
{
_WFE();
};
Toggle_LDE();
- 第一种情况:Timer0在进入WFE之后才会来。由于之前的中断等等的事件,事件标志位已经置位,如果timer中断还没来,第一次走while循序会进入WFE,但是不会睡眠,而只会把事件标志位清掉,第二次循环进入的时候才会进入睡眠。
- 第二种情况:Timer0在进入while循环前已经被触发了,此时软件标志位timer0irq_flag = 1,因此不会进入while循环,不会进入WFE。
- 第三种情况:Timer0在while循环比较之后在WFE之前来了,此时内部事件寄存器已经被置位,这一次执行WFE是清除事件标志位,然后又去while判断,此时软件标志位已经是1了,因此就不会再进入循环了,直接点亮LED灯。
==注意:对于Cortex-M3的r0p0~r2p0版本,处理器自身的缺陷会影响运行时内部事件寄存器的设置。要解决这个问题,可以在中断处理中插入一个SEV指令,这样中断就可以正确地设置中断寄存器了。
_SEV();
_WFE();
_WFE();
若需要SEVONPEND特性,也应该使用WFE指令
开发低功耗应用的注意点
-
- 选择合适的微控制器:除了考虑电器特性,考虑项目所需要的存储器大小也是很必要的,如果实际使用的位控制器的flash或sram比所需要的大,那么存储器就会带来更多的功耗。
-
- 运行合适的时钟频率:多数应用并不需要很高的时钟频率,因此可以通过降低时钟频率来降低系统的功耗。有时,可能需要衡量一下应该让系统运行得快些然后进入休眠,还是运行慢些以降低动态功耗。
-
- 选择合适的时钟源:有些微控制器提供了等多个时钟源,他们的频率和精确性存在差异。在实际应用中,由于外部石英晶振可能会带来比较大的功耗,因此使用可以降低功耗的内部时钟源可能会更好。
-
- 关闭未使用的时钟信号:许多现代微控制器都允许关闭未使用外设的时钟,或者多数情况是,在使用前再将时钟信号打开。
-
- 利用时钟系统特性:有些MCU为系统的不同部分提供了各种时钟分频器,可以利用他们降低外设或外设总线等的速度。
-
- 供电设计:一个良好的电源设计是提高能耗效率的另一个关键因素。
-
- 在SRAM中运行程序:如果SRAM够大可以在SRAM中运行整个程序,这样就可以关掉flash,减少功耗。但是SRAM价格昂贵,因此一般SRAM很难放的下整个程序,这个中情况可以将程序中常用的部分复制到SRAM,而且只在执行程序中剩余部分时打开flash存储器。
-
- 使用正确地I/O端口配置:有些MCU具有可配置的I/O,可以利用降低I/O的驱动电荷和转换速率来降低I/O接口逻辑的功耗。
-
- 休眠期间关掉Flash存储器:若要使用的休眠模式不支持自动关闭flash存储器,且SRAM不足以保存整个应用,那么可以只复制休眠进入和休眠退出的函数到SRAM中,这样,flash存储器可在休眠期间被手动关闭,休眠进入和退出的函数就在SRAM中跑起。具体的流程如下图:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)