android的电源管理

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模式,且增加引用计数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值