嵌入式软件的低功耗设计

2023年 7月 18日 44.8k 0

1 低功耗的意义

电子产品尤其是电池供电的都要求低功耗,究竟怎样才算低功耗?脱离应用场合的数值没有意义,低功耗是一种看情况而定、只可意会的标准。

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 工欲善其事,必先利其器

在实践低功耗系统设计前,必须要有一个有效的手段来检测或观察系统当前的工作模式,可直观知道系统什么时候工作,什么时候休眠,工作时长和休眠时长,高精度的电流表必不可少。

相关文章

JavaScript2024新功能:Object.groupBy、正则表达式v标志
PHP trim 函数对多字节字符的使用和限制
新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
为React 19做准备:WordPress 6.6用户指南
如何删除WordPress中的所有评论

发布评论