图片人是铁饭是钢,一顿不吃饿得慌”,对于嵌入式设备而言,没有电一切都白瞎,特别是带电池的终端嵌入式设备,对电能的管理尤其重要,也是我们调试设备的一个重点。可以说有省电需求的设备都需要关注调试软硬件中的电源管理,省下来一度电,或者多运行一会那可是实打实的钱啊,干这个直接就能转化成money,所以电源管理工程师在工作中岗位多,很重要,调试嵌入式设备都需要。 本文作为开篇,但是开篇即巅峰(非现学现卖,实属老司机),从电源管理基础知识Linux电源管理、SoC中电源管理,甚至从设计SoC 芯片的角度,带你进入电源管理的星辰大海。 先分享一些网上比较好的成系列的文章:

1. 电源状态介绍

图片 进行电源管理的原则就是不能“占着茅坑不拉屎”,或者“用力过猛”。我们做一件事情的时候,生手往往使用蛮力,一会就累趴下了,老油条又不用力,光占着位置不出活,我们需要的是愿意干活的熟练工,不该用力的时候不用力,该用力的时候用大力,这样才能上工时间长,效益高。就像上面图中的电源状态名字,该偷懒的时候就偷懒磨洋工(Power Save),该甩开膀子加油干的时候就不保留(Power on),该小睡(Standly)或者大睡(Sleep)就去睡觉。 嵌入式设备运行的时候也是同样的道理,CPU等各种元器件并不是每时每刻都有活干,比如我们的手机,打游戏(超级大活)的时候就费电,网络视频电话(大活)也费电,看个电子书(小活)能省电一点,关闭屏幕放口袋(没活眯一会)里面就更省电了。图片 各种电源状态也是可以相互转化的,比如掏出手机,按键解锁就从节能模式到正常模式了,或者手机长时间不用就自动进入休眠模式了。上图作为一个例子,在我们自己设计的系统里面可以定义电源模式编写转换方式。这里的电源模式有两种类型一种是系统电源状态,例如系统关机、重启休眠等,一种是每个外设的电源状态,例如网口、WiFi、I2C控制器等的关闭打开休眠等。

2. Linux 电源管理的组成

图片Linux内核电源管理的整体架构组成,大体可以归纳为如下几类:

  1. CPU在运行时根据系统负载进行动态电压和频率变换的CPUFreq
  2. CPU在系统空闲时根据空闲的情况进行低功耗模式的CPUIdle
  3. 多核系统下CPU的热插拔支持。
  4. 系统和设备针对延迟的特别需求而提出申请的PM QoS,它会作用于CPUIdle的具体策略。
  5. 设备驱动针对系统挂起到RAM/硬盘的一系列入口函数。
  6. SoC进入挂起状态、SDRAM自刷新的入口。
  7. 设备的运行时动态电源管理,根据使用情况动态开关设备。
  8. 底层的时钟、稳压器、频率/电压表(OPP模块完成)支撑,各驱动子系统都可能用到。

    先扯点别的,上面的图是从宋宝华《Linux设备驱动开发详解》这个书里面截取的,但是这个书真是不适合入门,可以说是写给懂的人看的,作为一个已经懂的人的索引词典还可以。所以懂的人看到图和解释就觉得还可以,总结的很好,对于初学者一脸懵逼。初学者推荐正点原子的视频和资料:http://www.openedv.com/docs/boards/arm-linux/zdyz-i.mx6ull.html 下面就Linux电源管理相关的一些名词解释,你也可以用ChatGPT来寻找解释,很多时候是我们不知道搜什么,就是你不知道你自己不知道,这里告诉你搜什么。最近百度的文言一心放开了:https://yiyan.baidu.com/,我直接上图,懒得自己写了:
    图片图片图片图片
    Linux电源管理框架 图片 对于Linux中的电源管理框架,首先就是分层抽象,可以看到有三层:

  9. API Layer,用于向用户空间提供接口,屏蔽底层内核和硬件具体的实现细节,这样方便上层软件的开发和维护。例如关机和重启的接口形式是系统调用,Hibernate和Suspend的接口形式是sysfs

  10. PM Core,是尽可能的抽象公共逻辑,并在Framework内实现,以提高重用性、减少开发量,位于kernel/power/目录下,主要处理和硬件无关的核心逻辑。
  11. PM Driver,分为两个部分,一是体系结构无关的Driver,提供Driver框架(Framework),向下层提供一系列的回调函数(callback function),下层软件可能面对差别较大的现实,但只要填充这些回调函数,即可完成所有逻辑,减小了开发的难度。另一部分是具体的体系结构相关的Driver,这也是电源管理驱动开发需要涉及到的内容(图中红色边框的模块)。

    Linux中电源管理有关的源码分别位于:

kernel/power/ 
*drivers/power/
drivers/base/power/*
drivers/cpuidle/*
drivers/cpufreq/*
drivers/devfreq/*
include/linux/power_supply.h
include/linux/cpuidle.h
include/linux/cpufreq.h
include/linux/cpu_pm.h
include/linux/device.h
include/linux/pm.h
include/linux/pm domain.h
include/linux/pm runtime.h
include/linux/pm wakeup.h
include/linux/suspend.h
Documentation/power/*.txt

3. ARM SoC中PCSA与SCP

图片 只从Linux角度研究电源管理还远远不够,特别是在ARM的异构多核SoC中,例如手机和汽车的复杂系统中。系统中有多个OS,Linux只是其中一个OS,而且电源管理相关的控制都是系统非常重要的,必须放安全世界,可惜的是Linux是非安全世界,所以需要Linux-》PSCI-》SMC-》ATF(BL31)-》SCMI-》MailBox-》SCP-》CRU/PMIC/PPU等。关于ARM权限的分析,可以参考之前的文章:ARM ATF入门-安全固件软件介绍和代码运行图片 对于ARM的一手资料,必须去ARM官网上搜索下载最重要的资料就是官网文档,例如PCSA的资料:https://developer.arm.com/search#q=Power_Control_System_Architecture 关于PCSA之前的文章:ARM SCP入门-简介和代码下载编译 中有详细的描述,这里不再说明了,放一张图:图片

4. SoC设计中的电源管理

图片 在CMOS电路中功耗可以分为静态功耗动态功耗

  • 静态功耗又叫做泄漏功耗,是指电路处于等待或不激活状态时泄漏电流所产生的功耗,跟硬件相关,系统都不运行了软件就不用关系了。
  • 动态功耗就是在系统运行时的功耗,直接看公式:

图片 式中C 代表负载电容的容值,V 是工作电压,A 是当前频率下电路的平均翻转率,f 为工作频率,IShort 和ILeakage 分别为短路电流和漏电流。从公式中可知,C、V 、A、f 决定了整个CMOS 电路的功耗:CMOS芯片的能量消耗正比于电压的平方和时钟频率。对于硬件器件的功耗控制技术,在软硬件上万变不离其宗,基本就是通过控制电压频率进行的。 对于电压的提供,引入电压域电源域的概念,梳理出来相同电压需求的器件可以加入一个电压域。梳理出来一个功能模块的电压供应放到一块是一个电源域。可以使用PMIC进行供电。另外引入电源轨的概念, 涉及到上下电的顺序,因为功能硬件可能有依赖,需要设计先后顺序。
对于频率和复位,可以使用PLL产生clock,用CRU对器件的频率复位进行管理。需要设计PLL对应的时钟树,复位也需要设计某个复位信号的作用范围。复位还牵扯watchdog的软硬件喂狗失败导致的复位。
图片 对于电源域的控制,可以使用一个独立的MCU运行SCP固件,上面放PPU对电压和频率一块控制,如上图。另一种方案:也可以使用一个PMU硬件对电源域进行管理,PMU的控制可以放到BL31的安全世界。PMU和SCP的区别就是SCP是一个OS有独立的软硬件可以有决策能力,PMU只是一个硬件执行者,一般依附于A核Linux软件进行决策。 还有一个clock gating的概念,就是把clock频率降为0,但是电压还有,从而来降低功耗,这个可以在CRU或者PPU中,某些器件不使用需要关闭降低功耗的时候不下电,只进行clock gating。


后记:

本篇虽然是开篇,但是尽量把遇到的一些电源管理知识都**涵盖**进去了,其中涉及的**软硬件** **技术非常多**,但是好在不像内核中进程、内存、文件系统等模块那么难理解。**蜗窝科技**的电源管理写了**43篇**,是他的博客最多的分类了,可见其很庞杂,借用蜗窝的一句话:“**慢下来,享受技术**”,我也写的很慢,但是尽量保持写出来的都是自己**精心打磨**的干货,而且纯公益分享,大家放心关注转发。  

“啥都懂一点,啥都不精通,

干啥都能干,干啥啥不是,

专业入门劝退,堪称程序员杂家”。

后续会继续更新,纯干货分析,欢迎分享给朋友,欢迎评论交流!

results matching ""

    No results matching ""