找回密码
 立即注册
首页 业界区 安全 低功耗设计参考

低功耗设计参考

俏襟选 昨天 21:13
前言

低功耗设计(Low Power Design)是指在系统的软硬件架构、芯片选择、外围电路、供电管理、工作模式等方面做出合理设计,以降低设备的能耗、延长电池寿命或减少发热。
低功耗设计可带来好处如下:
        续航增加,可以提升用户体验,提高产品竞争力;
        充电次数减少,可以延长电池寿命;
        降低发热,提高稳定性,并可以延长产品使用寿命。

而低功耗设计难度并不在技术本身,而在:
        软硬件配合难,要 MCU、外设、电源管理、电路板设计、固件策略全链路协同;
        取舍难,功能强则功耗高,响应快则功耗高,处理快则功耗高,难两全;
        状态管理难,系统状态多(运行/待机/休眠/唤醒),工作状态多(高性能/一般性能/低性能),处理不好容易死机、异常唤醒;
        细节排查难,细如某个IO配置错误,时钟源未关闭,执行的先后时序差异就会造成功耗异常;
        功耗测试难,需要各种专业仪器(电源分析仪、示波器)配合才能精准定位问题源;
        调试难,每次调试都需要进入 Sleep/Wake 再观测功耗,流程复杂、验证周期长、甚至复现概率低;
        解耦难,有的问题是各模块耦合产生,增加了问题定位分析难度;

可见低功耗设计是一项繁琐、枯燥但十分重要的工作,且跟踪周期贯穿了整个产品生命,需要开发者保持耐心、细心。
本文会从设计整体流程、测试建议、设计参考、调试方法这几个方面入手,帮助初学者入门,笔者水平有限,如有错漏或者有其他建议,欢迎指出,感谢!
wjh_hugh@163.com
设计整体流程

首先需要先回答一个问题:功耗要多低才算低功耗呢?对于耳机uA级别算低,对于手机mA级别就算低,不同产品不同场景下的定义都是不同的,所以我们需要先设定一个目标,由目标来制定标准,由标准来框定设计。
总体设计流程如下:
1.png

例如,产品定义会影响ID,ID会决定尺寸,尺寸会决定电池容量,最后在供应商提供的范围内根据成本选定了300mAh的容量,产品需求出货待机续航大于180天,那计算可得300mAh/(24h180)=69uA,又因为出货时电量不能满电(长时间满电状态会影响电池寿命),一般按50~80%电量出货,再算得69uA80%=56uA,即可标定待机功耗须小于56uA,此为该场景的功耗要求上限(注意因为会有多种功耗场景,最后应取最小功耗上限值,此处简化例子,以该场景下的就是最小上限值)。
此值就需要纳入到主芯片等器件选型的考虑因素中,比如在同样deep-sleep模式下,主芯片A典型功耗为30uA,而主芯片B典型功耗为1uA,那在功耗方面,芯片B更具优势。硬件估算低功耗模式总的工作电路功耗=主芯片功耗+LDO(1uA)+电源管理芯片(8uA),此时不管是选择芯片A还是B都能满足产品的功耗需求,那此时主芯片选型就可以着重考虑其他因素。假如还有颗主芯片C典型功耗达50uA,显然不满足需求,正常情况下会被排除掉,但如果产品某个需求只有芯片C可满足,不得不选用芯片C,那这个时候可能就需要调整id、砍功能、更换其他器件甚至是更改产品定义。
最终电路所有主要器件定型后就可以确定产品的功耗基线,制定测试标准,编写测试用例。
注意,我们还需要使用原始SDK与最小系统开发板实测一遍功耗,因为数据手册中数据下的工作状态不一定与产品实际应用的工作状态一致,而且不同芯片平台的测试环境,测试参数也不一定一致。
在实际过程中,由于电路器件精度、测试仪器精度、环境温度、软件工作负载的影响,测试数据会和理论值存在偏差,一般偏差在±10%以内,会认为是在正常范围内,当然还是要根据应用场景、测试手法和项目要求视具体情况而定。
以上流程的主要工作量并不在软件这边,当产品需求明确和硬件器件定型后,软件便可以开始需求拆解,然后进行具体的软件设计。这里推荐使用状态机法(FSM),将系统的运行状态拆分为几个典型状态,通过事件驱动触发状态跳转,然后在不同状态下启用/关闭不同模块,以达到功耗管理的目的。假如以某果耳机为例,状态机图可以如下:
2.png

测试建议


  • 定标准,统一验收测试的场景手法
    功耗测试的影响因素众多,以耳机播歌为例,影响因素有环境温度、音频EQ参数、播歌音量、音频格式、手机型号和品牌,播歌歌曲、天线信号质量、外壳装配、手机距离、信号干扰、多点功能是否打开、BLE是否打开,蓝牙参数是否一致(发射功率、广播间隔、广播时长),测试时要尽量保持一致性,前期的测试标准也要先明确好,避免影响验收。测试环境的搭建会相对比较麻烦,但切勿随意,不然测试结果也是无效数据,作无用功。
  • 定期大版本监测
    因为功耗测试需要借助测试仪器,相比与功能测试会多一定的工作量,如果要求过于频繁地监测那既不现实也没这个必要,反之一直不测试,直到临近生产前才测一遍同样是不可取的。平衡工作量和风险,建议在这两种节点都需监测一下功耗数据:一个是软件大版本发布,另一个是硬件电路板变动。
  • 灵活小版本监测
    上述的大版本监测属于定期监测,但有的时候项目周期长,大版本间跨度比较大,中间可能有大量的代码提交,如果还只是死板地定期监测,一旦出现功耗异常,其排查难度会增加。所以还需要灵活手段补充,每个周版本我们需要对每笔代码提交有个初步判断,是否对功耗有所影响,觉得有那就应当安排相关场景下的功耗测试。以下几个判断点以供参考:
            是否与驱动相关
            有无增减模块功能
            主频是否变更
            系统负载是否加大(比如某个任务执行很频繁)
            有无模式状态切换
            是否影响输出功能

  • 保留版本金机
    软硬件版本都会不断迭代,如果某个版本突然出现功耗异常,那其他版本的金机就能提供对比,具有很高的参考价值,所以保留版本金机会是一个不错的习惯。
  • 异常场景测试
    除了正常场景的测试用例,开发者还需进行需求拆解后设计异常场景下的测试用例。
    // to do.如果您有好用的异常场景测试用例设计方法论,请联系笔者。
  • 埋点测试
    不同于其他功能,低功耗问题不易察觉。开发者可以设计一些检测功耗状态的日志用于调试、排查功耗异常。比如可以记录进入/退出低功耗的条件/原因、时间戳,这样就可以分析出总的续航时间、睡眠比例、睡眠时长、进入/退出低功耗是否正常。
    注:低功耗状态一般不会开串口,可以保存在RAM中,唤醒后统一上报;低功耗状态的systick不一定会保持运行,但一般会有RTC或者LP Timer进行周期喂狗,这样也可以代替计算时长。
设计参考

低功耗设计是一个系统性的设计优化过程,但总的来说,低功耗设计可以从两个纬度去考虑:
        功能->线程->器件->外设->内核
        板级->芯片->外设->内核

分别从软硬件层面,由外到内的收缩聚拢;
0.        设计原则
        余量设计。这不仅是低功耗设计,还是提高产品可靠性的重要设计原则。参数设计上要预留出一定的空间,状态切换能慢不快,功耗数据能低不高,富裕空间能多不少, 操作频率能低不高。
        自主原则。尽量不依赖自动的、默认的操作和设置,尽量每一步的控制都是可掌控的、可预见的。
        异常处理原则。程序总会遇到意料之外的输入、状态或者故障,我们需要及时检测并妥善处理。当然,这对于开发者,尤其新手来说是总是难以考虑周全的,对此建议是起码养成对函数的返回值进行处理的习惯(至少log输出返回值),同样的编写被调用函数也应尽量考虑是否需要提供返回值给调用者。


  • 建立基本的功耗模型
    //to do
  • 熟悉外部芯片的工作模式及其功耗
    对器件的熟悉程序很大程度上会影响到问题定位速度和功耗设计思路。
    例1:正常整机功耗约20uA,有某个样机功耗异常,约120uA,如若已知充电管理芯片在boost打开状态下典型功耗110uA,便那可快速联系到可能是进低功耗前boost关闭失败导致的,加快问题的定位分析。
    例2:某传感器有不同工作模式,其low-power mode和high-performance mode的功耗差约200uA,假如一直保持高性能的状态,产品可能无法达到续航要求,故程序需要做工作模式切换来进行功耗优化。
  • 各线程对各自资源负责
    当系统决定进低功耗时,需先通知各线程,各线程对使用的资源进行关闭和反初始化,该过程不应有依赖或阻塞。建议先关闭异步资源,如定时器;注意资源的关闭不要遗漏,如定时器不要忘记关闭。而功耗管理线程只对通用资源管理,如时钟、电源轨等。
    例1:某线程进低功耗前忘记关闭定时器A,虽然不会被定时唤醒,但若系统的定时器打开了补偿模式,那经过长时间后,系统唤醒后,由于systick值累积,会大量触发定时器回调,导致系统崩溃死机。
  • 对进入低功耗模式的条件进行分级,增加容错设计
    系统进入低功耗模式需要先满足各种条件,比如不能在充电状态、需满电状态等,你需要对各种条件进行分级,区分必须必要条件和非必要条件,例如非充电状态就是必要条件,因为充电状态由外部供电(假设电源管理芯片有路径管理)长时间不进入低功耗模式不会影响产品续航。而满电状态是一个非必要条件,例如产品电量太低了,如果继续高功耗运行可能会使得电池过放从而影响电池寿命。
  • 对外部芯片的操作和进入低功耗之间建议保持适当的时间间隔
    对外部芯片操作可能会产生中断,而由于内部工作状态的切换或者电路的充放电需要一定时间,中断信号可能是延迟产生的,如果操作完立刻进入低功耗,那可能又会马上被延迟产生的中断信号唤醒。
    例1:为了降低功耗,进低功耗前需要关闭某传感器的部分功能,这可能会使得内部状态发生变化,但这变化与内部电路的放电时间挂钩,所以会延迟产生一个中断信号,然后立刻重新唤醒主芯片;
  • 显式设置所有芯片引脚
    注意是所有,有的芯片由于封装不同有点引脚没有引出来,也必须进行设置;注意还是所有,除了主芯片,外部芯片的引脚设置也应当是确定的;
    例1:原厂基于成本或封装原因,芯片内部部分引脚没有封装出来,如果没有对这些GPIO进行配置,内部的GPIO会出现漏电,导致功耗出现浮动。
  • 芯片引脚的模式设置
    一般情况下低功耗模式下优先设置模拟输入>输出低>高阻;
    但是注意避免外部电路冲突,比如外部是上拉电路,那就不适宜设置输出低,会形成电位差产生漏电流。
    而裸漏在整机外部的引脚也不适合设置成输出,容易漏电导致加快腐蚀;
    避免使用浮空模式,当为浮空输入时,表面上电路上没有回路,实际上IO电平是有可能会出现反复抖动,短暂的电位差也会导致漏电;
  • 考虑使用场景,关闭不必要模块,节省功耗
    不是所有外设在所有场景都需要保持常开的,同时注意关闭外设模块后须同步关闭外设时钟,不然该外设仍会产生功耗。
  • 中断使能与中断唤醒使能
    中断使能是用来控制中断是否响应,影响是否进入执行中断服务函数,而中断唤醒使能是控制唤醒源能否可唤醒MCU,这是两个独立的开关功能。那如果只关闭中断唤醒而不关闭中断使能可以吗?理论上可以,但还是强烈建议同时关闭。中断是不可控的,假如在唤醒时刚好触发执行了中断服务,可能与开发者预期不符。
  • 区分不同程度的功耗模式
    避免芯片选型时的数据参考错误,功耗对比要在同一等级的功耗模式下比较。常用的有sleep、deepsleep、standby模式,确认不同模式还能工作的外设;明确需求是否需要保持RAM,选择的低功耗模式下芯片是否全部RAM都可保持,是否还需要什么外设继续工作,选择的中断源是否还能保持工作,该中断源是否还能作唤醒源。
  • 显式切换时钟
    有的芯片进入低功耗会自动切换外部时钟到内部时钟,唤醒后再自动从内部时钟切换到外部时钟,无需我们主动编程切换,但建议时钟切换还是由开发者进行主动显式切换,同时如果对唤醒时间要求不严格的话建议增加适当的延时来增加系统的稳定性。
    例1:晶振的起振需要一定的时间,倘若电源不稳定或者阻抗不匹配,会需要更长的起振时间,在时钟未稳定情况下执行程序会跑飞或者死机。
  • 看门狗喂狗
    在产品中看门狗是必不可少的功能,但是看门狗基本一旦打开就无法关闭,进入低功耗后如果没有及时喂狗就会触发复位。所以系统需要定时(建议50%~80%的看门狗超时时间)唤醒去喂狗,为了保持低功耗,可使用RTC或者LP Timer。芯片选型时也应考虑是否有提供此类外设,同时也要验证打开RTC或者LP Timer后功耗是否还能满足需求。
  • 深究故障根因
    在调试阶段,我们经常可以遇到单例的功耗异常样机,最后分析系器件损坏的问题。比如二极管击穿,此时不能更换器件后就结束分析,硬件需要检查是否是因为电路的余量设计不足使得器件容易损坏。甚者还会遇到芯片内部损坏的情况,开发者须深究损坏的根因,是否是坏片流出,后续可增加什么措施避免该类坏片继续流出。
调试方法

三分写七分调,debug是最漫长耗时的过程,特别是前期设计不足的话下更会遗留更多的问题。但是如果掌握了常用的方法论,那调试起来将会事半功倍。
注:下述提及的模块既可以是软件模块,也可以是硬件模块。
0.        调试原则
        保护现场。现场是十分重要的分析素材,特别是低概率和单例问题,一旦现场被破坏就很容易丢失分析方向。但是大部分情况下为了验证分析思路又不得不破坏现场,此时我们一定要慎重地逐步破坏:环境破坏->状态破坏->软复位->硬复位->板级系统掉电->烧录代码->硬件破坏,破坏之前应尽可能地分析全面,或者保留现场数据,比如重新烧录代码之前,先download芯片的flash数据。
        软硬结合。功耗问题与硬件息息相关,需积极和硬件配合排查,同时也敢于寻求硬件的帮助。


  • 确认现场
    首先,确认软件版本和硬件版本是否有问题;
    其次,确认概率:单例问题,少例问题,普遍问题?概率问题,必现问题?手法相关还是场景相关?回答这几个问题,就可以先初步推测出大概率会是软件问题还是硬件问题,提供大方向验证思路;
    接着确认复现手法,大如用什么设备,什么用例,小如步骤顺序、速度、力度,都有可能是复现的影响因素;
    最后要信任测试员,测试结果无效,那指导责任在于开发者,开发者就需要去纠正测试员的测试手法。同时保持对测试员所表述内容的怀疑,因为他们表述是带主观的,可能存在偏差,不可尽信。
  • 对齐复现手法
    复现手法、设备尽量1比1复刻,必要时连测试员都可以用同一个。总之就是要重视测试手法,但是正如上述提到过不可尽信测试员表述,所以有时候适当地调整测试手法反而能复现到。
  • 场景联系法
    主要用于明确复现场景的问题。由复现场景推测相关模块,比如充过电后休眠功耗会异常,反之不会,那可以推测与充电管理模块相关。然后就可以针对相关模块进行重点排查和代码review。
  • 版本回退法
    遇到必现或者稳定复现的问题,可以尝试回退版本复测,排查是否是代码提交引入的问题,甚至可以回退到SDK版本,看是否是原始SDK就自带的问题。这种方法虽然麻烦但有效,可以很好地帮助我们定位到那些看起来毫不相干的问题代码提交。
  • 交叉验证法
    又称ABA验证,主要用于分析单例或者少例问题,将一个正常样机和异常样机交换某个模块,然后通过查看异常跟随方向就能定位问题出在哪里。比如将一个功耗异常样机A的主芯片和正常样机B的交换,结果样机A功耗回归正常,样机B功耗却异常,这就可以定位到是主芯片有问题。同样的,新样机的版本回退加上旧样机的版本升级,也是一种交叉验证。
  • 解耦排除法
    主要可用于必现或者稳定复现但是不确定哪个模块有异常的问题,通过屏蔽或者移除某个模块,查看功耗是否回归正常,如果正常了,那就说明该模块有问题。比如某功耗异常样机,拆除触控芯片或者屏蔽了触控相关代码后回归正常,那说明触控芯片或者触控代码有问题。
  • 波形分析法
    主要用于有功耗波形可分析的问题,通过分析波形特征来帮助定位。比如某样机功耗偏高,分析出正常时的波形可分为三个阶段,正常情况三个阶段功耗依次降低,但是功耗异常时却没有第三阶段波形,功耗一直维持与第二阶段一致,所以可以定位问题出在这两个阶段的状态切换过程。
附录A-常用概念

注意:不同平台定义可能有些许不同,此处仅帮助学习理解,具体问题应当具体分析。
以下几种功耗模式(Power Modes)的功耗依次降低:
升压模式(Boost Mode):提升输出电压或者工作频率的模式;
运行模式(Active Mode):正常运行,内核、外设全开;
睡眠模式(Sleep Mode):内核停止、外设可用,即使睡眠也可快速响应中断;
深睡模式(Deep Sleep Mode):内核和大部分外设停用,只可由部分外设(如RTC)唤醒,此模式RAM仍保持;
待机模式(Standby Mode):几乎全关(包括RAM和寄存器),仅保留最少模块,唤醒需要更长时间;
掉电模式(Shutdown Mode):所有模块掉电,只能由复位类时间启动;
船运模式(Ship Mode):该模式一般用于出厂运输或者仓库存放,和掉电模式很相似,都是最深的功耗模式,但船运模式一般是用于说明板级的功耗模式,不单是主芯片的,而是整个产品硬件板。
唤醒延迟(Wakeup Latency):从低功耗模式唤醒到正常运行所需时间,睡眠越深延迟越大。
时钟(Clock):时钟如同“心脏”,频率越高,能耗越高。
时钟树(Clock Tree):系统中时钟信号从主时钟源(如晶振)逐级分配到各个子模块或外设的结构,可以单独调节和开关子模块或外设的时钟,在低功耗设计中非常关键。
电源轨(Power Rail):特定电压等级的供电网络,可以为多个器件/模块同时提供不同的电压,以满足不同器件/模块的电压要求。
LDO(线性稳压器):用于输出一个稳定电压,常用于小电流应用。
DC-DC(Buck/Boost):电压转换器,降压或者升压,常用于大电流应用。
标称电压(Nominal Voltage):电池在正常工作期间的平均电压值,注意不是最大值或最小值。一般无用例要求的话测功耗就会选用标称电压。
保护电压(OVP/UVP):当电池电压高于或低于某个阈值时,为了保护电池安全和寿命,系统会触发“过压保护”或“欠压保护”,停止充放电操作。为了避免过放,关机(休眠)电压一定要高于欠压保护电压且预留一定的阈值。

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册