赞
踩
Android的休眠唤醒主要基于wake_lock机制,只要系统中存在任一有效的wake_lock,系统就不能进入深度休眠,但可以进行设备的浅度休眠操作。wake_lock一般在关闭lcd、tp但系统仍然需要正常运行的情况下使用,比如听歌、传输很大的文件等。
wake lock - wakelock在android的电源管理系统中扮演一个核心的角色,wakelock是一种锁的机制, 只要有task拿着这个锁, 系统就无法进入休眠, 可以被用户态进程和内核线程获得。这个锁可以是有超时的或者是没有超时的, 超时的锁会在时间过去以后自动解锁。如果没有锁了或者超时了, 内核就会启动标准linux的那套休眠机制机制来进入休眠。
a.相关文件:
kernel/kernel/power/wakelock.c
kernel/include/linux/wakelock.h
enum { WAKE_LOCK_SUSPEND, // 阻止进入深度休眠模式 WAKE_LOCK_IDLE, // 阻止进入空闲模式 WAKE_LOCK_TYPE_COUNT }; struct wake_lock { #ifdef CONFIG_HAS_WAKELOCK struct list_head link; // 链表节点 int flags; // 标志 const char *name; // 名称 unsigned long expires; // 超时时间 #ifdef CONFIG_WAKELOCK_STAT struct { int count; // 使用计数 int expire_count; // 超时计数 int wakeup_count; // 唤醒计数 ktime_t total_time; // 锁使用时间 ktime_t prevent_suspend_time; // 锁阻止休眠的时间 ktime_t max_time; // 锁使用时间最长的一次 ktime_t last_time; // 锁上次操作时间 } stat; #endif #endif };
可以看到wake_lock按功能分为休眠锁和空闲锁两种类型,用于阻止系统进入深度休眠模式或者空闲模式。
b.wake_lock对外提供的操作接口:
void wake_lock_init(struct wake_lock *lock, int type, const char *name); //用于初始化一个新锁,type参数指定了锁的类型
void wake_lock_destroy(struct wake_lock *lock); //注销一个锁
void wake_lock(struct wake_lock *lock); //激活锁(永久锁)
void wake_lock_timeout(struct wake_lock *lock, long timeout); //激活锁(超时锁)
void wake_unlock(struct wake_lock *lock); //解锁(无效锁)
int wake_lock_active(struct wake_lock *lock); //判断锁当前是否有效,如果有效则返回非0值
long has_wake_lock(int type); //判断系统中是否还存在有效的type型锁,如果存在超时锁则返回最长的一个锁的超时时间,如果存在永久锁则返回-1,如果系统中不存在有效锁则返回0
案例:展讯平台深睡后tp中断唤不醒CPU,导致如手势、tp模拟距离传感功能休眠后唤不醒的bug,这时就可以在驱动中加入休眠锁来阻止CPU深睡。
#include <linux/wakelock.h>
struct wake_lock ps_wakelock;//定义锁
//probe中添加:
wake_lock_init(&ps_wakelock, WAKE_LOCK_SUSPEND, "elan-touchscreen");//初始化锁
//suspend中:
wake_lock(&ps_wakelock); //激活锁(上锁)
//resume中:
wake_unlock(&ps_wakelock); //解锁
//remove中:
wake_lock_destroy(&ps_wakelock); //销毁锁
注:也可在pin-map里面修改中断脚gpio的模式为eic模式使中断可以唤醒CPU:
{REG_PIN_EXTINT0, BIT_PIN_SLP_AP|BIT_PIN_NULL|BITS_PIN_DS(1)|BITS_PIN_AF(3)|BIT_PIN_WPU|BIT_PIN_SLP_WPU|BIT_PIN_SLP_IE},//CTP_INT
参考:
http://blog.csdn.net/qq_20678703/article/details/52189274
另见使用enable_irq_wake的方法(待验证):
enable_irq():用于使能中断,只在系统正常运行状态下产生的IRQ会上报。
enable_irq_wake():用于使能中断,不仅在系统正常运行状态下产生的IRQ会上报,同时在系统休眠的情况下产生的IRQ会上报。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。