Android的电源管理
2013-09-25 15:07
232 查看
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_enterstatic 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的Linux内核的电源管理 -- 1.概述
- Android的电源管理
- android 电源管理,屏幕锁 ,小米2s点亮屏幕,解锁
- Android WiFi 电源管理
- Android 电源管理
- Android 电源管理 -- wakelock机制
- android中涉及wi-fi管理,internetManager网络管理,connectivityManager连接管理,PowerManager电源管理,vibrator震动管理等参数问题
- [转载]Android Power Management 电源管理
- android电源管理
- Android电源管理,低电量报警
- android电源管理
- android 电源管理
- Android平台开发-Power management-电源管理
- Android电源管理
- android 电源管理的网址
- Android电源管理-Healthd (2)
- Android电源管理
- 学习笔记 之 android 电源管理学习
- Android电源管理-休眠简要分析
- Android电源管理分析