如何在 Android Framework层面控制高通(Qualcomm)芯片的 CPU 和 GPU。
参考:https://blog.csdn.net/YoungHong1992/article/details/117047839?utm_source%20=%20uc_fansmsg
作为一名 Framework 开发者,您拥有系统级的权限,可以直接与底层硬件接口交互。但这通常不被推荐,因为现代 Android 系统有更优雅、更安全的功耗和性能管理机制。我将从底层原理到推荐的框架层方法,逐一为您介绍。
重要前提:理解核心概念
- Sysfs 虚拟文件系统: 这是 Linux 内核提供的一种机制,允许用户空间代码(如 Android 框架)通过读写虚拟文件来与内核驱动和硬件设备交互。这是控制 CPU 和 GPU 频率最直接的底层方法。
- Governor (调速器): 这是一个内核模块,用于决定如何根据系统负载动态调整 CPU/GPU 的频率。常见的 Governor 包括
performance
(维持最高频率)、powersave
(维持最低频率)、schedutil
(由 CPU 调度器决定)、ondemand
(负载高时升频,低时降频)等。 - HAL (硬件抽象层): 在
sysfs
之上,Android 定义了标准的 HAL 接口,例如Power HAL
。厂商(如高通)会实现这些 HAL,提供标准化的 API 给上层框架调用。这是比直接操作sysfs
更推荐的方式。 - 系统服务 (System Service): 例如
PowerManagerService
,它会与Power HAL
通信。您的框架代码应该尽可能通过这些现有的服务来间接实现目标。
CPU 频率与模式控制
1. 获取 CPU 信息 (通过 sysfs
)
您可以通过读取特定的 sysfs
节点来获取 CPU 的实时状态。这需要适当的权限,但作为框架开发者通常不成问题。
-
路径: CPU 的信息通常位于
/sys/devices/system/cpu/cpu[N]/cpufreq/
,其中[N]
是 CPU核心的编号。 -
关键文件节点:
scaling_cur_freq
: 读取此文件可获取该核心的当前频率(单位:KHz)。scaling_governor
: 读取此文件可获取当前使用的调速器。scaling_available_governors
: 读取此文件可获取所有可用的调速器列表。scaling_available_frequencies
: 读取此文件可获取该核心所有支持的频率点列表。cpuinfo_min_freq
/cpuinfo_max_freq
: 该核心硬件支持的最低/最高频率。scaling_min_freq
/scaling_max_freq
: 当前调速器允许使用的最低/最高频率。
示例 (Java/Kotlin 代码读取)
private String readFile(String path) {// 实现文件读取逻辑...// 注意处理权限和异常
}// 获取0号核心的当前频率
String currentFreq = readFile("/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq");// 获取当前调速器
String currentGovernor = readFile("/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor");
2. 设置 CPU 模式与频率 (不推荐直接操作)
警告: 直接写入 sysfs
会绕过系统整体的功耗管理策略,可能导致设备过热、耗电异常或不稳定。正确的做法是调用更高层的接口。但了解其原理很重要。
-
设置 Governor (工作模式): 这是最常用且相对安全的操作。
- 命令:
echo performance > /sys/devices/system/cpu/cpu[N]/cpufreq/scaling_governor
- 效果: 将指定核心锁定在高性能模式,频率会维持在
scaling_max_freq
附近。同理可以设置为powersave
等其他模式。
- 命令:
-
设置频率范围:
- 命令:
echo 2200000 > /sys/devices/system/cpu/cpu[N]/cpufreq/scaling_max_freq
- 效果: 限制调速器能使用的最高频率。
- 命令:
-
直接设置频率 (需要
userspace
governor):echo userspace > /sys/devices/system/cpu/cpu[N]/cpufreq/scaling_governor
echo 1800000 > /sys/devices/system/cpu/cpu[N]/cpufreq/scaling_setspeed
- 效果: 将核心频率精确地设定为某个值。
GPU 频率与模式控制
GPU 的 sysfs
接口不像 CPU 那样标准化,路径和文件名可能因高通芯片型号和内核版本而异。
1. 获取 GPU 信息 (通过 sysfs
)
-
常见路径:
/sys/class/kgsl/kgsl-3d0/
(Adreno GPU 的通用路径)/sys/class/devfreq/soc:qcom,gpubw/
(GPU 总线带宽)
-
关键文件节点:
gpuclk
或cur_freq
: 读取此文件获取当前 GPU 频率(单位:Hz)。gpu_busy_mhz
: 读取此文件可以查看 GPU 的使用率和时钟。available_frequencies
: 所有支持的频率点列表。governor
或power_policy
: 当前使用的调速器或电源策略。max_freq
/min_freq
: 限制频率范围。
2. 设置 GPU 模式与频率 (同样不推荐直接操作)
-
设置 Governor:
- 命令:
echo performance > /sys/class/kgsl/kgsl-3d0/governor
- 效果: 将 GPU 锁定在高性能模式。
- 命令:
-
设置频率范围:
- 命令:
echo 180000000 > /sys/class/kgsl/kgsl-3d0/min_freq
- 命令:
echo 850000000 > /sys/class/kgsl/kgsl-3d0/max_freq
- 效果: 将 GPU 的工作频率限制在指定的最小和最大值之间。
- 命令:
正确的 Framework 开发方式
作为框架开发者,您的职责是实现或使用更高层、更抽象的接口,而不是直接读写文件。
-
使用 Power HAL 和 Performance HAL
您的代码应该与PowerManagerService
或类似的性能管理服务交互。这些服务会通过 AIDL/HIDL 调用到厂商实现的Power.hal
或Perf.hal
。HAL 的实现者(高通或手机厂商的系统团队)会负责将标准化的请求(例如 “PERFORMANCE_BOOST”)转换为对底层sysfs
的具体操作。- 您的工作:
- 如果您需要添加一种新的性能模式(例如“超级游戏模式”),您可能需要在 Framework 中定义新的 API,然后在
PowerManagerService
中添加逻辑。 - 这个逻辑会调用到 HAL 的一个新接口,或者使用现有的
powerHint
接口并传递自定义的 hint。 - 例如,Android 提供了
PerformanceHintManager
,APP 可以用它向系统发送性能请求。 您的框架代码需要实现处理这些 hint 的后端逻辑,最终通过 HAL 作用于硬件。
- 如果您需要添加一种新的性能模式(例如“超级游戏模式”),您可能需要在 Framework 中定义新的 API,然后在
- 您的工作:
-
与厂商的专有服务交互
高通平台通常有一个名为perfd
(Performance Daemon) 的用户态守护进程,它统一管理所有性能相关的sysfs
节点。 系统服务通常不是直接写sysfs
,而是通过 Socket 或其他 IPC 方式与perfd
通信。- 您的工作:
- 研究您所在公司的平台上层服务是如何与
perfd
或其他性能守护进程通信的。 - 您需要做的很可能是调用一个现有的内部 API(例如
VendorPowerManager.setPerformanceMode(MODE_GAME)
),而不是自己去实现一整套sysfs
的读写逻辑。
- 研究您所在公司的平台上层服务是如何与
- 您的工作:
-
使用
PerformanceHintManager
(AOSP 推荐方向)
这是 Android 11 及以后版本中引入的标准化 API,旨在让应用能够向系统提供性能提示,而系统则根据这些提示和当前状态智能地调整 CPU/GPU 等资源。- 您的工作:
- 在框架层,您需要确保当
PerformanceHintManager
收到 hint 时,PowerManagerService
和Perf HAL
能够正确地解读它,并执行相应的频率/模式调整。 - 这包括确保高通的
Perf HAL
实现能够将 AOSP 定义的 hint(如ADPF_GPU_CAPACITY_TARGET
)映射到实际的 GPU 频率控制上。
- 在框架层,您需要确保当
- 您的工作:
总结与建议
操作 | 底层 Sysfs 方法 (了解原理) | 推荐的 Framework 方法 (您的工作重点) |
---|---|---|
获取频率 | 读取 /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq 和 /sys/class/kgsl/kgsl-3d0/gpuclk | 封装一个内部 Debug API 或服务,该服务来读取 sysfs ,但不用于业务逻辑。 |
设置模式/频率 | 写入 scaling_governor 、scaling_max_freq 等文件 | 不要直接写入! 应该通过您司已有的性能管理服务(如 GameTurboService )、PowerManagerService 或 PerformanceHintManager 的后端逻辑,调用到厂商实现的 HAL 接口,由 HAL 或 perfd 进程来安全地完成底层操作。 |
请使用高层、标准化的接口来控制硬件。这不仅能保证应用的性能和功耗表现符合预期,还能避免因直接操作底层文件而引入的各种不稳定风险。