前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Linux 电源管理子系统

Linux 电源管理子系统

作者头像
刘盼
发布2022-10-08 14:44:23
2.8K0
发布2022-10-08 14:44:23
举报
文章被收录于专栏:人人都是极客人人都是极客

Linux 在消费电子领域的应用已经相当普遍,而对于消费电子产品而言,省电是一个重要的议题。

Linux 电源管理非常复杂,牵扯到系统级的待机、频率电压变换、系统空闲时的处理以及每个设备驱动对系统待机的支持和每个设备的运行时(Runtime)电源管理,可以说它和系统中的每个设备驱动都息息相关。

对于消费电子产品来说,电源管理相当重要。因此,这部分工作往往在开发周期中占据相当大的比重,下图呈现了 Linux 内核电源管理的整体架构。大体可以归纳为如下几类:

1)CPU 在运行时根据系统负载进行动态电压和频率变换的 CPUFreq。

2)CPU 在系统空闲时根据空闲的情况进行低功耗模式的 CPUIdle。

3)多核系统下 CPU 的热插拔支持。

4)系统和设备针对延迟的特别需求而提出申请的 PM QoS,它会作用于 CPUIdle 的具体策略。

5)设备驱动针对系统挂起到 RAM/硬盘 的一系列入口函数。

6)SoC 进入挂起状态、SDRAM 自刷新的入口。

7)设备的运行时动态电源管理,根据使用情况动态开关设备。

8)底层的时钟、稳压器、频率/电压表(OPP模块完成)支撑,各驱动子系统都可能用到。

1、CPUFreq 驱动

CPUFreq 子系统位于 drivers/cpufreq 目录下,负责进行运行过程中 CPU 频率和电压的动态调整,即 DVFS(Dynamic Voltage Frequency Scaling,动态电压频率调整)。运行时进行 CPU 电压和频率调整的原因是:CMOS 电路中的功耗与电压的平方成正比、与频率成正比,因此降低电压和频率可降低功耗。

CPUFreq 的核心层位于 drivers/cpufreq/cpufreq.c 下,它为各个 SoC 的 CPUFreq 驱动的实现提供了一套统一的接口,并实现了一套 notifier 机制,可以在 CPUFreq 的策略和频率改变的时候向其他模块发出通知。

2、CPUFreq 的策略

SoC CPUFreq 驱动只是设定了 CPU 的频率参数,以及提供了设置频率的途径,但是它并不会管 CPU 自身究竟应该运行在哪种频率上。究竟频率依据的是哪种标准,进行何种变化,而这些完全由 CPUFreq 的策略(policy)决定,这些策略如表所示。

Android 系统中,则增加了 1 个交互策略,该策略适合于对延迟敏感的 UI 交互任务,当有 UI 交互任务的时候,该策略会更加激进并及时地调整 CPU 频率。

总而言之,系统的状态以及 CPUFreq 的策略共同决定了 CPU 频率跳变的目标,CPUFreq 核心层并将目标频率传递给底层具体 SoC 的 CPUFreq驱动,该驱动修改硬件,完成频率的变换,如图所示。

用户空间一般可通过/sys/devices/system/cpu/cpux/cpufreq 节点来设置 CPUFreq。譬如,我们要设置 CPUFreq 到 700MHz,采用 userspace 策略,则运行如下命令:

代码语言:javascript
复制
# echo userspace > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
# echo 700000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed
3、CPUFreq 的性能测试和调优

Linux 3.1 以后的内核已经将 cpupower-utils 工具集放入内核的tools/power/cpupower 目录中,该工具集当中的 cpufreq-bench 工具可以帮助工程师分析采用 CPUFreq 后对系统性能的影响。

cpufreq-bench 工具的工作原理是模拟系统运行时候的“空闲→忙→空闲→忙”场景,从而触发系统的动态频率变化,然后在使用 ondemand、conservative、interactive 等策略的情况下,计算在做与 performance 高频模式下同样的运算完成任务的时间比例。

交叉编译该工具后,可放入目标电路板文件系统的 /usr/sbin/ 等目录下,运行该工具:

代码语言:javascript
复制
# cpufreq-bench -l 50000 -s 100000 -x 50000 -y 100000 -g ondemand -r 5 -n 5 -v

会输出一系列的结果,我们提取其中的 Round n 这样的行,它表明了-g ondemand选项中设定的 ondemand 策略相对于 performance 策略的性能比例,假设值为:

代码语言:javascript
复制
Round 1 - 39.74%
Round 2 - 36.35%
Round 3 - 47.91%
Round 4 - 54.22%
Round 5 - 58.64%

这显然不太理想,我们在同样的平台下采用Android的交互策略,得到新的测试结果:

代码语言:javascript
复制
Round 1 - 72.95%
Round 2 - 87.20%
Round 3 - 91.21%
Round 4 - 94.10%
Round 5 - 94.93%

一般的目标是在采用CPUFreq动态调整频率和电压后,性能应该为performance这个高性能策略下的90%左右,这样才比较理想。

4、CPUIdle 驱动

目前的 ARM SoC 大多支持几个不同的 Idle 级别,CPUIdle 驱动子系统存在的目的就是对这些Idle状态进行管理,并根据系统的运行情况进入不同的Idle级别。具体 SoC 的底层 CPUIdle 驱动实现则提供一个类似于 CPUFreq 驱动频率表的 Idle 级别表,并实现各种不同 Idle 状态的进入和退出流程。

对于 Intel 系列笔记本计算机而言,支持 ACPI(Advanced Configuration and Power Interface,高级配置和电源接口),一般有 4 个不同的 C 状态 (其中C0为操作状态,C1是Halt状态,C2是Stop-Clock状态,C3是Sleep状态),如表所示。

5、PowerTop

PowerTop 是一款开源的用于进行电量消耗分析和电源管理诊断的工具,其主页位于 Intel 开源技术中心的 https://01.org/powertop/,维护者是Arjan van de Ven和Kristen Accardi。PowerTop可分析系统中软件的功耗,以便找到功耗大户,也可显示系统中不同的C状态(与CPUIdle驱动对应)和P状态(与CPUFreq驱动对应)的时间比例,并采用了基于TAB的界面风格,如图所示。

6、Regulator 驱动

Regulator是Linux系统中电源管理的基础设施之一,用于稳压电源的管理,是各种驱动子系统中设置电压的标准接口。前面介绍的CPUFreq驱动就经常使用它来设定电压。

而Regulator则可以管理系统中的供电单元,即稳压器(Low Dropout Regulator,LDO,即低压差线性稳压器),并提供获取和设置这些供电单元电压的接口。一般在ARM电路板上,各个稳压器和设备会形成一个Regulator树形结构,如图所示。

Linux的Regulator子系统提供如下API以用于注册/注销一个稳压器:

代码语言:javascript
复制
structregulator_dev * regulator_register(conststructregulator_desc
*regulator_desc, conststructregulator_config *config);
voidregulator_unregister(structregulator_dev *rdev);
7、OPP

现今的SoC一般包含很多集成组件,在系统运行过程中,并不需要所有的模块都运行于最高频率和最高性能。在SoC内,某些domain可以运行在较低的频率和电压下,而其他domain可以运行在较高的频率和电压下,某个domain所支持的<频率,电压>对的集合被称为Operating Performance Point,缩写为OPP。

代码语言:javascript
复制
int opp_add(struct device *dev, unsigned long freq, unsigned long u_volt);

目前,TI OMAP CPUFreq 驱动的底层就使用了OPP 这种机制来获取CPU所支持的频率和电压列表。在开机的过程中,TI OMAP4芯片会注册针对CPU设备的OPP表(代码位于arch/arm/mach-omap2/中)

8、PM QoS

Linux内核的PM QoS系统针对内核和应用程序提供了一套接口,通过这个接口,用户可以设定自身对性能的期望。一类是系统级的需求,通过cpu_dma_latency、network_latency和network_throughput这些参数来设定;另一类是单个设备可以根据自身的性能需求发起per-device的PM QoS请求。

9、CPU 热插拔

Linux CPU 热插拔的功能已经存在相当长的时间了,Linux 3.8之后的内核里一个小小的改进就是CPU0也可以热插拔。

一般来讲,在用户空间可以通过/sys/devices/system/cpu/cpun/online节点来操作一个CPU的在线和离线:

代码语言:javascript
复制
# echo 0>/sys/devices/system/cpu/cpu3/online
CPU 3 is now offline
# echo 1 >/sys/devices/system/cpu/cpu3/online

通过 echo 0 >/sys/devices/system/cpu/cpu3/online 关闭 CPU3 的时候,CPU3 上的进程都会被迁移到其他的CPU上,以保证这个拔除CPU3的过程中,系统仍然能正常运行。一旦通过echo 1 >/sys/devices/system/cpu/cpu3/online再次开 启CPU3,CPU3又可以参与系统的负载均衡,分担系统中的任务。

在嵌入式系统中,CPU 热插拔可以作为一种省电的方式,在系统负载小的时候,动态关闭CPU,在系统负载增大的时候,再开启之前离线的CPU。目前各个芯片公司可能会根据自身SoC的特点,对内核进行调整,来实现运行时“热插拔”。

10、挂起到 RAM

Linux支持STANDBY、挂起到RAM、挂起到硬盘等形式的待机,如图所示。

一般的嵌入式产品仅仅只实现了挂起到RAM(也简称为s2ram,或常简称为STR),即将系统的状态保存于内存中,并将SDRAM置于自刷新状态,待用户按键等操作后再重新恢复系统。少数嵌入式Linux系统会实现挂起到硬盘(简称STD),它与挂起到RAM的不同是s2ram并不关机,STD则把系统的状态保持于磁盘,然后关闭整个系统。

Linux下,这些行为通常是由用户空间触发的,通过向/sys/power/state写入mem可开始挂起到RAM的流程。当然,许多Linux产品会有一个按键,一按就进入挂起到RAM。

这通常是由于与这个按键对应的输入设备驱动汇报了一个和电源相关的input_event,用户空间的电源管理daemon进程收到这个事件后,再触发s2ram的。当然,内核也有一个INPUT_APMPOWER驱动,位于drivers/input/apm-power.c下,它可以在内核级别侦听EV_PWR类事件,并通过apm_queue_event(APM_USER_SUSPEND)自动引发s2ram。

11、运行时的 PM

dev_pm_ops 结构体中,有3个以 runtime 开头的成员函数:runtime_suspend()、runtime_resume()和runtime_idle(),它们辅助设备完成运行时的电源管理:

运行时 PM 与前文描述的系统级挂起到 RAM 时候的PM不太一样,它是针对单个设备,指系统在非睡眠状态的情况下,某个设备在空闲时可以进入运行时挂起状态,而在不是空闲时执行运行时恢复使得设备进入正常工作状态,如此,这个设备在运行时会省电。Linux运行时PM最早是在Linux2.6.32内核中被合并的。

总结

Linux内核的PM框架涉及众多组件,弄清楚这些组件之间的依赖关系,在合适的着眼点上进行优化,采用正确的方法进行PM的编程,对改善代码的质量、辅助功耗和性能测试都有极大的好处。

另外,在实际工程中,尤其是在消费电子的领域,可能有超过半数的bug都属于电源管理。这个时候,电源管理的很多工作就是在搞定鲁棒性和健壮性,可以说,在很多时候,这就是个体力活,需要工程师有足够的耐性。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-10-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 人人都是极客 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、CPUFreq 驱动
  • 2、CPUFreq 的策略
  • 3、CPUFreq 的性能测试和调优
  • 4、CPUIdle 驱动
  • 5、PowerTop
  • 6、Regulator 驱动
  • 7、OPP
  • 8、PM QoS
  • 9、CPU 热插拔
  • 10、挂起到 RAM
  • 11、运行时的 PM
  • 总结
相关产品与服务
负载均衡
负载均衡(Cloud Load Balancer,CLB)提供安全快捷的流量分发服务,访问流量经由 CLB 可以自动分配到云中的多台后端服务器上,扩展系统的服务能力并消除单点故障。负载均衡支持亿级连接和千万级并发,可轻松应对大流量访问,满足业务需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档