您的位置:首页 > 移动开发 > Android开发

android的电源管理

2012-09-20 19:23 176 查看
1.设备的电源管理struct dev_pm_ops

在struct bus_type,struct dev_type,struct class,struct devic_driver中包含有次结

构体

对于rumtime,会一次检查dev_type,class,bus_type,调用其中rumtime相关函数,一般是

最中调用到device_driver中的pm管理函数,从而进行硬件的runtime,device_driver一般

是device-specific的

如果struct device 中pm_domain 不为NULL,则优先调用其中的ops

2.__pm_runtime_set_status()设设备的状态,只有当设备disable和出错时才能改变其状



3.只有当设备的usage_count为0时,设备才能被suspend和idle

4.echo "mem" > /sys/power/state 屏幕变黑

echo "on" > /sys/power/state 屏幕变亮

5.内核中的early suspend 执行:

在suspend的时候先执行优先等级低的handler,在resume的时候则先执行等级高的

handler

6.汇总:

linux的电源管理有两种情况,system sleep PM ,和runtime PM,前者是针对系统中的所有

设备而runtime是针对某种设备,但最终的callback都在dev_pm_ops中定义,一个设备在系统

中用struct device 结构体表示,struct device中的dev_pm_ops的操作优先级是:

pm_domain->pm_ops,dev_type->pm_ops,class->pm_ops,bus->pm_ops。这些接口都是在系

统进入深度休眠是才会调用.

android在linux kernel的基础上增加了一种休眠,叫early suspend,进行浅度休眠,在手机

系统中,关闭LCD背光,TP等设备来降低功耗,通过向/sys/power/state中写“mem"就会进入浅

度休眠,写”on",则退出浅度休眠,android让设备也能够进入深度休眠,另外再增加了一种

wake_lock(醒锁)的机制,当系统中不存在wake_lock的持有者时,系统将进入深度休眠阶段,

此时就会调用device->pm_ops中的相关函数。

6.1 PM core init:

kernel/kernel/power/main.c

pm_init:

1.建立了一个pm_wq工作队列用于runtime时的电源管理

2.在/sys/目录下建立了一个power目录,用于用户空间的交互

3.在/sys/power目录建立属性文件,其中最重要的是state文件

其他有:

pm_async:设置设备进行suspend时是同步执行还是异步执行

wakeup_count:对系统中wakeup 事件进行统计

touch_event:功能暂不明确

//kernel/kernel/power/userwakelock.c中定义

wake_lock:从用户空间申请wake lock

wake_unlock:从用户空间释放wake lock

wakelock core init:

kernel/kernel/power/wakelock.c

wakelocks_init:

1.主要申请了deleted_wake,main_wake,unknown_wake,suspend_backoff_wake等SUSPEND类

型的wake_lock(wake_lock有两种类型,suspend和idle,前者防止设备进入休眠,或者防止设

备进入idle)

2.创建了suspend ,sync工作队列用于进行early suspend 和同步

3.以及创建/proc/wake_lock目录

6.2: early suspend 和late resume 分析

/kernel/kernel/power/earlysuspend.c

struct early_suspend {

struct list_head link;//链接到early_suspend_handlers

int level;//优先级,suspend是从小到大,resume是从大到小

void (*suspend)(struct early_suspend *h);//suspend callback

void (*resume)(struct early_suspend *h); //resume callback

};

在kernel中用early_suspend_handlers去维护驱动注册的early suspend

驱动调用register_early_suspend去注册用于suspend和resume的callback

在用户空间对/sys/power/state进行操作是会调用state_store函数

进而调用request_suspend_state函数进入early suspend流程,根据用户空间传递进来的

state(mem,on,standy)进行操作,对于suspend调用suspend_work_queue上的early_suspend

函数,对于resume调用late_resume函数去执行挂起或者恢复。在suspend以后会释放醒锁

main_wake_lock(wake_unlock(&main_wake_lock)),在resuem时wake_lock

(&main_wake_lock)

6.3:wake_lock的实现

android在linux的基础上增加了醒锁,当系统中没有醒锁时就会进入深度睡眠,只要系统中

还存在一个suspend类型的wake lock,那么整个系统就不能进入深度休眠(这设计....)

系统在初始化时注册了几个主要的系统wake lock。而驱动程序可以通过以下API注册醒锁

wake_lock_init()

wake_lock()

在wake_unlock时,如果系统中已经不存在suspend类型的锁,则会调用suspend_work上的

suspend函数进入深度休眠流程.

suspend->pm_suspend(休眠时,次函数不会返回,返回了说明已经resume完成了)最终

pm_suspend调用enter_state进入深度休眠。

enter_state主要调用的两个函数:

suspend_prepare()//休眠前的准备,冻结进程。

suspend_devices_and_enter()//进入休眠,会调用到系统中所有device的

suspend_prepare,suspend,suspend_noirq函数

系统中维护在四个链表,代表着电源管理的各个阶段

LIST_HEAD(dpm_list);//还没有进行suspend,设备运行正常

LIST_HEAD(dpm_prepared_list);//prepared 的所有设备

LIST_HEAD(dpm_suspended_list); //suspend的所有设备

LIST_HEAD(dpm_noirq_list); //noirq阶段

6.4 device与PM建立联系的过程

系统中的device是通过linux设备模型(device model),与电源管理建立联系的

在调用device_register()设备时分别调用了

device_initialize

device_add

在device_initialize中调用device_pm_init去初始化一个device的电源管理相关项

在device_add中调用device_pm_add把device添加到pm_list链表中,从而进行电源管理

6.5runtime 分析

/kernel/driver/base/power/runtime.c

runtime的callback也在pm_ops中,

主要涉及到rpm_suspend,rpm_resume,rpm_idle,定时器suspend_timer,和工作队列

pm_wq,pm_wq用于异步执行设备的suspend和resuem

API 使用:

首先要执行下面的两个函数,才能启动设备的runtime管理

pm_runtime_set_active(struct device *dev)

pm_runtime_enable(struct device *dev)

//如果设备的使用计数不为0,那么这个两个函数立即返回,同步执行

pm_runtime_idle(struct device)//使设备进入idle模式

pm_runtime_suspend(struct device)//是设备进入suspend模式

pm_runtime_resume(struct device) //立即使设备进入resume模式

int pm_request_idle(struct device )//异步进入idle模式

int pm_request_resume(struct device)//异步进入resuem模式

int pm_runtime_get(struct device)//异步进入resuem模式,且增加引用计数

int pm_runtime_get_sync(struct device)//同步进入resume模式,且增加引用计数
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: