首先 需要先adb shell进入手机cd /sys/devices/system/cpu 到cpu 目录下
使用ls查看当前目录下的文件,有:
cpuinfo_cur_freq:当前cpu正在运行的工作频率
cpuinfo_max_freq:该文件指定了处理器能够运行的最高工作频率 (单位: 千赫兹)
cpuinfo_min_freq :该文件指定了处理器能够运行的最低工作频率 (单位: 千赫兹)
cpuinfo_transition_latency:该文件定义了处理器在两个不同频率之间切换时所需要的时间 (单位: 纳秒)
scaling_available_frequencies:所有支持的主频率列表 (单位: 千赫兹)
scaling_available_governors:该文件显示当前内核中支持的所有cpufreq governor类型
scaling_cur_freq:被governor和cpufreq核决定的当前CPU工作频率。该频率是内核认为该CPU当前运行的主频率
scaling_driver:该文件显示该CPU正在使用何种cpufreq driver
scaling_governor:通过echo命令,能够改变当前处理器的governor类型
scaling_max_freq:显示当前policy的上下限 (单位: 千赫兹)需要注意的是,当改变cpu policy时,需要首先设置
scaling_max_freq, 然后才是scaling_min_freq
scaling_setspeed:如果用户选择了“userspace” governor, 那么可以设置cpu工作主频率到某一个指定值。
只需要这个值在scaling_min_freq 和 scaling_max_freq之间即可 。
1、查看当前CPU支持的频率档位
3、查看当前选择的governor
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
interactive
4、查看系统支持多少核数
root@NOBLEX:/ # cat sys/devices/system/cpu/present
1,控制cpu频率实际上就是改变它当前的工作模式,使其工作在对应频率上, cpu默认不受系统之外控制,所以我们先要使我们能够有权限写入值到scaling_governor,来改变工作模式,找到源码中init.rc文件,添加
chown system system /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
chmod 0644 /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
2,本人从事指纹工作,所以以指纹为例,其他举一反三,源码中找到fingerprintd.te文件.添加
allow fingerprintd sysfs_devices_system_cpu:file rw_file_perms;
allow fingerprintd shell_exec:file { read open execute_no_trans execute };
allow fingerprintd system_file:file {execute_no_trans};
3,JNI 部分,指纹库中添加控制cpu的操作,直接上代码:
/*************************************************************************
File Name: cpu_mode_status_control.h
Author: f
Created Time: Tue 13 Mar 2018 10:17:26 AM CST
************************************************************************/
#include
#include
#include
void start_cpu_status_control_process(void);
void stop_cpu_status_control_process(void);
void set_cpu_mode_flag(int flag);
/*************************************************************************
File Name: cpu_mode_status_control.c
Author: f
Created Time: Tue 13 Mar 2018 10:04:28 AM CST
************************************************************************/
#include
#include
#include
#include "cpu_mode_status_control.h"
//char const * CPUPATH = "/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor";
//char const * CPUPATH = "/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq";
char const * CPUPATH = "/sys/devices/system/cpu/cpufreq/policy0/scaling_governor";
char cpu_mode[32];
char cpu_current_mode[][32]={"performance", "interactive", "schedplus"};
static int s_pthread_exit = 0;
static pthread_t s_pthread_t;
static long take_time;
struct timespec cpu_set_time, cpu_restore_time;
static int authen_detect_flag = 0;
static int is_interactive = 0;
void set_cpu_mode_flag(int flag){
LOGD("set cpu mode flag = %d", flag);
authen_detect_flag = flag;
}
static void sysfs_write(const char *path, const int state)
{
char buffer[32];
int len=0;
int fd = open(path, O_RDWR,S_IRWXO|S_IRWXG|S_IRWXU);
if (fd < 0) {
strerror_r(errno, buffer, sizeof(buffer));
LOGE("Error opening %s: %s\n", path, buffer);
return;
}
read(fd, buffer, sizeof(buffer));
buffer[strlen(buffer)-1]=0; //去除结束符
if(state == 0 && strcmp(buffer, cpu_current_mode[0])==0){
LOGD("cpu already performance");
return;
}
if(state == 1 && (strcmp(buffer, cpu_current_mode[1])==0 || strcmp(buffer, cpu_current_mode[2])==0)){
LOGD("cpu already interactive");
return;
}
//获得初始cpu默认模式
if(strlen(cpu_mode) == 0 && strcmp(buffer, cpu_current_mode[0]) != 0){
strcpy(cpu_mode, buffer);
}
if(state ==0 && strcmp(buffer, cpu_current_mode[2])==0 || strcmp(buffer, cpu_current_mode[1])==0){
LOGD("write performance");
len = write(fd, "performance", sizeof("performance"));
}else{
LOGD("write interactive");
len = write(fd, cpu_mode, sizeof(cpu_mode));
}
if (len < 0) {
strerror_r(errno, buffer, sizeof(buffer));
LOGE("Error writing to %s: %s\n", path, buffer);
}
close(fd);
}
static void *cpu_status_control(void *p){
LOGD("start");
while(!s_pthread_exit){
//LOGD("while cpu status control");
if(authen_detect_flag){
sysfs_write(CPUPATH, 0);
authen_detect_flag = 0;
is_interactive = 1;
clock_gettime(CLOCK_BOOTTIME, &cpu_restore_time);
cpu_set_time.tv_sec = cpu_restore_time.tv_sec;
cpu_set_time.tv_nsec = cpu_restore_time.tv_nsec;
}
clock_gettime(CLOCK_BOOTTIME, &cpu_restore_time);
take_time = (cpu_restore_time.tv_sec - cpu_set_time.tv_sec) * 1000 + (cpu_restore_time.tv_nsec - cpu_set_time.tv_nsec)/1000000;
if(take_time > 5000 && is_interactive){
LOGD("take time = %ld", take_time);
is_interactive = 0;
sysfs_write(CPUPATH, 1);
}
usleep(300);
}
}
/**
* 开启cpu 设置线程
*/
void start_cpu_status_control_process(void){
s_pthread_exit = 0;
pthread_create(&s_pthread_t, NULL, cpu_status_control, NULL);
}
/**
* 退出cpu 设置线程
*/
void stop_cpu_status_control_process(void){
int ret;
s_pthread_exit = 1;
ret = pthread_kill(s_pthread_t, 0);
if(ret == ESRCH){
LOGD("pthread not found\n");
}else if(ret == EINVAL){
LOGD("send an illegal signal\n");
}else{
LOGD("pthread still alive\n");
}
}