Android JNI控制CPU工作频率

一,知识预讲

首先 需要先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支持的频率档位
root@NOBLEX:/sys # cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies
sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies
1300000 1235000 1170000 1040000 819000 598000 442000 299000
root@NOBLEX:/sys #
2、查看当前支持的governor(手机型号可能略有不同)
root@NOBLEX:/sys # cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors
sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors
ondemand userspace powersave interactive performance
performance表示不降频,
ondemand表示使用内核提供的功能,可以动态调节频率,
powersvae表示省电模式,通常是在最低频率下运行,
userspace表示用户模式,在此模式下允许其他用户程序调节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 <fcntl.h>
#include<sys/types.h>
#include<sys/stat.h>

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<stdio.h>
#include<globalvar.h>
#include <pthread.h>
#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");
    }
}




    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值