电子产品尤其是电池供电的都要求低功耗,究竟怎样才算低功耗?脱离应用场合的数值没有意义,低功耗是一种看情况而定、只可意会的标准。
2 思路决定成败芯片数据手册写着低功耗,上面那些小的出奇的电流标准,只是用来摆设的一种无法工作的假死状态,工作功耗才是实实在在的。有时为了体现低功耗,还要在应用中设计所谓的低功耗模式,当系统确认没有任务时就休眠。于是乎,低功耗这种“既要马儿跑,又要马儿不吃草”的逻辑,就成为降低正常工作模式下系统功耗的常规选择。
从硬件角度来说,找到所有可能消耗电流的回路,确定哪些是可以通过软件控制的方式来优化,哪些是不可避免的,并给软件开发人员提供所有IO口状态对功耗影响的关系,用简单的表格说明一下高电平或低电平会怎样,悬浮会怎样。前期配置驱动软件,验证工作时最小电流满足标准,基本可确认硬件正常。剩下的就是软件开发人员的发挥空间,而基于软件的降功耗策略,正是本文所要讨论的重点。
3 驱动软件设计3.1 端口配置首先确认复位后引脚的默认状态,该状态下是否漏电,是否会开启某些时钟源,是否内部上拉或下拉,软件再结合硬件或外围做相应配置。例如AD通道禁止内部上拉,普通GPIO设为输出低或者高避免漏电,悬空引脚避免中断输入模式。
固定连接控制的,可以推挽输出控制外设,或者外部带上拉时选开漏;特殊引脚如UART一般配置模式即可,硬件自动控制对应电平;间歇性工作如ADC,作为输入转换完成后,可以再设为输出或关闭AD。
有些外设是可以插拔的,如UART正常空闲时收发都是高,如外设关机或者移除,仍保持高电平则存在漏电,这种情况下需将引脚设为输出低。重点关注工作中一种状态,工作结束或异常时要及时切换状态,避免漏电或者电平不匹配。
如果外设支持中断尽量配置开启,而不是定时轮询通信。
3.2 电源管理芯片内部往往划分不同的电源域,硬件外设也分不同单元的供电,暂时不使用的部分,可以立刻关闭电源域、时钟域。在硬件成本允许或者功耗要求严苛的情况下,外设尽量独立供电,这样在非使用状态下软件控制断电。需要注意关闭电源域后,某些端口可能需要重新配置避免漏电,如上节所提到关闭外设的供电后,外设的UART端口变为低,主控的UART端口就不能继续维持高电平了。
3.3 系统时钟在正常的工作模式下,频率越高功耗越高,完成同样工作的时间越短,也可更快进入休眠。如果单片机主要做控制,没有复杂运算,降频能实现需求就往更低的频率切换。如果有大量数学计算,可以空间换时间,或者先高频运行,尽快完成算法,运行结束后动态切换到低频。
同等时钟下,供电电压低功耗也低;定时采样、屏幕刷新也可在满足需求的情况下尽量低频处理。
3.4 待机底电流查阅数据手册或者SDK官方文档,确定符合需求的、可被唤醒的最低功耗休眠模式,编写一个测试用例,关闭所有可能耗电的外设,进入休眠的状态,验证极限情况下的功耗。
可能还需要硬件排除电路板上无法优化的固有功耗,比如电压转换等固定消耗电流的部分,单纯看主芯片的工作电流,是否达到数据手册上对应模式下的理论值。如果不满足就需要继续关闭一些复位后自动开启的功能,比如时钟使能等;或者硬件工程师配合拆除可疑器件加快排查。这第一步非常关键,直接决定后期整机功耗能达到的最佳效果,同时在配置过程中,非常细微的认识到哪些外设和配置影响功耗,如何影响,有多大的影响。
3.5 休眠与唤醒休眠后有的是降频工作,有的是假死(软件未运行,内存可恢复;有的不能恢复,唤醒类似重启效果),或者直接关机(RTC关机闹钟唤醒),不同的硬件方案和软件需求,休眠模式的表现不同。单片机开发,确认其所有的休眠模式,以及对应休眠模式下哪些时钟源工作或休眠,结合具体应用的需求,明确系统对唤醒源以及唤醒模式的需求,由此便确定了系统的基础休眠模式。
注意有些芯片在休眠模式下仅少数端口维持唤醒的状态,只有特殊引脚才能唤醒,这需要硬件设计前考虑。
3.6 功耗评估降低功耗是软件和硬件协同工作才能解决的问题。比如AD采样时候的分压电阻,如果直接接了地,那会一直消耗电流;增加分压电阻足够大,表面上静态电流小,但因为AD内阻分流,最终结果就存在较大偏差。如果通过一个IO口来控制其接地的方式,只在需要采样的时候接地,采样完成后悬浮或者拉高,就可以将静态损耗降到最低,虽然成本加了不少,但实实在在的省电了。具体是否采用,主要是看功耗的标准,如果略微可以接受持续的静态损耗,就没必要增加硬件成本。
系统实现最低功耗,有时需要在外设性能、硬件成本和功耗之间做妥协,CPU是否可以降频,硬件外设是否支持中断唤醒等,这些都会影响最终的待机功耗,降低功耗是硬件和软件配合的结果,软件配置驱动,硬件逐个确认电流是否在期望之内,这理论值定义就看原厂资料或者经验了,以及与产品定义的待机时长妥协解决。
4 业务软件设计低功耗从硬件上能够解决一部分,但单纯依靠硬件肯定是不行的,需要软件的密切配合,才能达到最好的效果。以上是从硬件驱动层面的,一般情况下都比较关注,但实际上软件业务层的灵活性高,发掘低功耗的效果比硬件低功耗本身的效果更加显著,通俗地讲,底层硬件辛辛苦苦地优化设计节省的效果,远远不如软件设计得好的表现。
从软件的业务逻辑、产品需求方面的设计,在功耗方面更有意想不到的效果,软件功耗优化简单总结就是“能睡就睡”。
4.1 任务周期化一个嵌入式产品包括很多子功能、子任务,一个应用是对若干服务的调用实现的。这里服务可以是硬件服务,比如AD电压采样、UART串口通讯,也可以是软件服务,比如TCP/IP网络通信等。简单的功能如CRC校验,纯软件实现,函数运行立即获得结果,对功耗无所谓影响;复杂的功能,尽量使用任务的方式来实现,并不是特指操作系统的task或者thread,可以理解为一个流程,即一个子功能运行的完整过程。一件事有始有终就可以根据需要循环反复,周期运行的任务,明确运行的起止时间点,区分运行与非运行状态就能更好的优化,比如减少运行持续时间或者其中大电流的时间段,在功耗方面效果比较明显。
4.2 休眠自理与协调将整个嵌入式软件系统分成了很多周期性工作的小任务,它们可能是交错的或者毫无关系并行的。从本质上说,每个小任务只需关注自身的起止时间点。系统的功耗管理就是为每个任务的功耗进行管理,整体在一个有效的协调方式下才能做到功耗最小。基于任务的功耗管理实际上分成两个部分,微观角度单任务自身的功耗管理,和宏观角度多任务的休眠协调。
从微观角度来看,一个任务能独立完成自己的功能,任务中所有的步骤都是确定的,都是“自己说了算的”,对外界来说是“黑盒子”,对低功耗的要求,不外乎以下几种情形:
(1)、任务执行的过程中不允许休眠,因此任务的开头和结尾处要设置标志,告知协调系统,“只要我不同意,就不允许系统休眠”。 (2)、任务执行的过程中,某些阶段允许休眠,某些阶段不允许休眠;任务的执行过程中,不同阶段允许不同的休眠等级。 (3)、任务执行的过程中,不在乎是否休眠。
三类任务同时存在于系统中,第一类任务是相当霸道的,只要它在执行,根本不允许休眠;第二类任务既完成了任务,又兼顾了休眠;第三类任务基本上可当做空气无视。系统任务设计时应尽可能编写后两类任务,避免或者尝试拆分第一类任务。
从宏观角度来看,任意时刻可能有多个任务同时在执行,每个任务对休眠的需求都是不同的。如果要设立一个协调机制,该怎么办呢?每个任务按最低需求,随时来休眠协调机构签到投票,表明自身当前能够容忍的最低功耗对应的休眠等级,休眠协调机构的仲裁者定时或轮询检查所有任务的投票结果,找到最小的休眠等级,类似水桶的最矮一环作为“共识”,然后进入相应的休眠等级。
如果有人投了“不休眠”的票,仲裁就只能放弃休眠。所以,每一个任务都应该是一个负责的任务,都应该根据自己的不同步骤及时的更新自己对休眠的容忍度,从而保证投票能够达成有意义的结果。
这种机制实现也很容易,比如
uint16_t sleep_enable = 0xFFFF; //0xFFFF表示可以进入休眠
uint16_t sleep_enable=0xFFFF,表示系统可以进入休眠,每个任务独立的操作相应的一位,禁止休眠时清0,允许休眠则置1。休眠协调机制即定时查询sleep_enable是否为0xFFFF,可以在main轮询或RTOS的待机任务查询,进行休眠的进出。
任务的划分合理,尽量允许休眠,通过这种协商机制可以解决“能睡就睡”的问题。
4.3 任务等待合并设备运行中必然存在定时唤醒的任务,多个定时任务随机的在任意时刻唤醒工作,导致频繁退出休眠。这种情况下,在最大允许延迟的情况下,多个任务可以在一次唤醒全部执行。比如去超市买菜,肯定是一次把当天需要的菜都买了,而不是每餐前都去买,一天到晚跑超市。在4G物联网产品应用,比如设备每3分钟需要向服务器发送一个TCP/IP心跳包,同时传感器每10秒采集一个数据也需要上报服务器,可以实现为数据缓存,等到3分钟的定时器溢出上报时,将采集的多组传感器数据组合一并上报,减少无线网络模块唤醒的次数。
4.4 及时止损因为环境或外设组合不同,可能在某些时间段无法实现需求,或者结合当前信息大概率无法实现,或者硬件部分故障,软件监测到这种异常后,需要及时止损,减少不必要的消耗。例如GNSS卫星定位,其属性就是必须在开阔区域才能定位,如果设备开启GNSS但发现信号很差,可初步判断当前位置可能在室内,即使继续工作也不能定位,可以立刻关闭GNSS节省电量;当然产品在需求层面需要考虑不定位的其他操作。或者通信中确认外设不存在或者损坏,就没必要继续供电定时交互,进行异常报警即可。
4.5 需求层面在需求定义时,充分考虑某个任务或外设工作的起止要求,避免长时间进行无效工作。例如可以根据加速度传感器判断设备是否处于运动状态在开启监控,或者通过红外或声控判断有人接近才开启工作。这种都是通过产品定义,在需求层面组合,满足要求才唤醒工作,不满足则及时停止进入休眠,当然也可能增加硬件成本。部分设备也可以考虑使用场地增加太阳能充电板,开源节流。
5 工欲善其事,必先利其器在实践低功耗系统设计前,必须要有一个有效的手段来检测或观察系统当前的工作模式,可直观知道系统什么时候工作,什么时候休眠,工作时长和休眠时长,高精度的电流表必不可少,如果可以记录电流-时间曲线更佳,针对电流曲线有针对性的优化软件流程或时间参数。