1.应用层操作

PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE); 

   PowerManager.WakeLock wl =pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "My Tag"); 

   wl.acquire(); //在释放之前,屏幕一直亮着(有可能会变暗,但是还可以看到屏幕内容) 

   wl.release();

 

<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.DEVICE_POWER"/>




2.kernel中的文件

  在文件系统中有一个虚拟的文件:/sys/power/state

  向该文件写入字符串“mem”,则启动进入休眠的过程。

  向该文件写入字符串“on”,则手机退出休眠状态。

  state_store向文件写入字符串.

 

/kernel/kernel/power/earlysuspend.c //通用

/kernel/kernel/power/suspend.c //通用

/kernel/drivers/power/rk30_factory_adc_battery.c 电源的驱动实现, 与遥控驱动实现(remotectl)如出一辙.

/kernel/arch/arm/mach-rk30/board-rk30-box.c // 板级支持

int rk29_standby_led_suspend(void)

{

int i;

     //printk("\n+++yangchao+++func%s+++\n",__FUNCTION__);

#if 0

     int ret = 0;

     rk30_mux_api_set(STANDBY_MUX_NAME,STANDBY_MUX_MODE);

     ret =gpio_request(STANDBY_LED_GPIO, NULL);

     if (ret != 0) {

         printk("func %s,line %d: request gpio fail\n", __FUNCTION__, __LINE__);    

                gpio_free(STANDBY_LED_GPIO);

     }

     gpio_direction_output(STANDBY_LED_GPIO,0);

  #endif

  for (i=0; i<10; i++){

     gpio_set_value(STANDBY_LED_GPIO,i%2);

     msleep(100);

  }

     gpio_set_value(STANDBY_LED_GPIO,0);

     return 0;
}

3.kernel中几个文件之间的关系

3.1 从电池供电驱动入手, /kernel/drivers/power/rk30_adc_battery.c

rk30_adc_battery_data其中有中断号irq

#defineBATT_MAX_VOL_VALUE   8284 //满电时的电池电压   

#defineBATT_ZERO_VOL_VALUE  6800 //关机时的电池电压


#define BATT_NOMAL_VOL_VALUE  7600              


gpio_direction_output(pdata->charge_set_pin,pdata->charge_set_level);

 

rk30_adc_battery_platform_data.charge_set_pin充电级别设置


rk30_adc_battery_platform_data.dc_det_pin 充电级别寄存器

rk30_adc_battery_platform_data.charge_ok_pin 充电完成寄存器

什么关系? GPIO要研究一下. jiffies. INIT_WORK


jiffies为系统启动后的ticks. 除以时钟晶振频率即为秒数.

INIT_WORK是将中断处理函数加入工作队列, 实现对需要长时间处理的中断的延时调度.

3.2 电池供电驱动初始化函数:

rk30_adc_battery_probe

注意两个结构体:

rk30_adc_battery_data  *data

rk30_adc_battery_platform_data*pdata

在probe函数中, 为data分配空间. 然后把data赋值给全局变量gBatteryData.

并且data->pdata= data; 表示platform_data也被关联进入了全局的gBatteryData. 所以gBatteryData是一个非常重要的变量.

A.  rk30_adc_battery_io_init

这个函数初始化的是platform_data. 其中做的事情有:

初始化charge_set_pin, 这是充电控制引脚, 设置级别.

初始化dc_det_pin, 直流充电检测引脚.

初始化charge_ok_pin, 充电完成引脚.

初始化batt_low_pin, 低电量引脚.

以上四个引脚, 全部是GPIOPullUp.

B.  清空电压采样数组data->adc_samples

C.  注册电池状态回调函数

adc_register(0, rk30_adc_battery_callback, NULL);

此函数非常简单, 只是gBatteryData->adc_val= result;

问题: adc_val是电量多少的标识???

D.  供电方式注册. 包括USB供电, 电池供电, 直流供电

power_supply_register

直接会注册一个供电方式rk30_battery_supply.

从power_supply_register的内容来看, 可以注册多个供电方式. 主要任务是初始化power_supply结构体.

E.  wake_lock_init

F.  初始化data->wq, 电源工作队列

G.  rk30_adc_battery_timer_work

初始化定时器, 定时进行电量采样, 检查电量

H.  rk30_adc_battery_check

开机检查电池电量, 如果不够且有低电压保护功能, 则直接关机.

I.  将低电量中断信号的处理函数对应到lowerpower_work

rk30_adc_battery_lowerpower_delaywork对低电量时的处理

 

注册低电量中断响应函数

rk30_adc_battery_low_wakeup, 在这个函数中,实际上是将前面的函数加入工作队列gBatteryData->wq中.

3.3 电源系统管理核心/kernel/kernel/power/suspend.c

suspend.c是电源管理的核心模块. 其中有对几种模式的定义, 包括

const char *const pm_states[PM_SUSPEND_MAX] = {

#ifdef CONFIG_EARLYSUSPEND

   [PM_SUSPEND_ON]      = "on",

#endif

   [PM_SUSPEND_STANDBY] = "standby",

   [PM_SUSPEND_MEM]  = "mem",

};

以及基本不常用的hibernation模式(将所有数据写入disk, 然后关机).

 

核心变量struct platform_suspend_ops suspend_ops

A.  pm_suspend/enter_state 进入待机状态

总括性函数

B.  suspend_prepare待机之前的准备

在所有的待机被执行之前都会执行这一段代码, 主要是通知其他应用程序, 分配一个console, 以及停止其他进程.

C.  suspend_enter 待机完成之后执行这个函数

suspend_test(TEST_PLATFORM)

disable_nonboot_cpus

suspend_test(TEST_CPUS)

arch_suspend_disable_irqs

D.  suspend_devices_and_enter进入待机状态

3.4 待机在驱动层的实现/kernel/arch/arm/mach-rk30/pm.c

    rk30_pm_enter

static int__init rk30_pm_init(void)

    suspend_set_ops(&rk30_pm_ops);

 

static structplatform_suspend_ops rk30_pm_ops = {

   .enter     =rk30_pm_enter,

   .valid     =suspend_valid_only_mem,

   .prepare   =rk30_pm_prepare,

   .finish       =rk30_pm_finish,

};




suspend_valid_only_mem该函数表明只有mem的待机是被支持的, 即实现上电源管理只有两种状态, 一种是开机, 一种是mem的待机模式. 而suspend.c中定义的standby,hibernation并不支持.

rk30_pm_prepare,rk30_pm_finish只是对disable_hlt, enable_hlt的处理.

核心即是驱动层的rk30_pm_enter. 该函数主要是对GPIO的一些操作. 估计这些操作主要是对外部设备, 或者一些电量使用设备的判断操作.

 

3.5 state_store电源状态调用函数

该函数是写入待机状态, 主要调用了两个函数:

request_suspend_state

和enter_state

后者前面已经提及, 这里看一下request_suspend_state

if (state == PM_SUSPEND_ON ||valid_state(state)) {

          error = 0;

          request_suspend_state(state);

       },




如果是请求待机, 则将early_suspend_work加入suspend_work_queue.

如果是开机, 则首先wake_lock(&main_wake_lock)禁止待机, 然后将late_resume_work加入suspend_work_queue.

suspend_work_queue是在wakelock.c中定义的任务队列:

suspend_work_queue= create_singlethread_workqueue("suspend");

3.6 待机过程的函数调用流程图

 

android 电源管理 后台运行 安卓高级电源管理_android 电源管理 后台运行