二 android 休眠唤醒机制分析 — early_suspend

是休眠流程的第一阶段即浅度休眠,不会受到的阻止,一般用于关闭lcd、tp等设备为运行的应用节约电能 。的会根据用户的操作情况调整电源状态,如果需要休眠则会调用到HAL层的()接口,在()中会向/sys/power/state节点写入"mem"值让驱动层开始进入休眠流程 。
一、休眠唤醒机制及其用户空间接口
Linux系统支持如下休眠唤醒等级
[cpp] view plain copyprint ?
*[]={#PEND[]="on",#endif[]="",[]="mem",};
const char *const pm_states[PM_SUSPEND_MAX] = {#ifdef CONFIG_EARLYSUSPEND[PM_SUSPEND_ON]= "on",#endif[PM_SUSPEND_STANDBY] = "standby",[PM_SUSPEND_MEM] = "mem",};
但在中一般只支持"on"和"mem",其中"on"为唤醒设备,"mem"为休眠设备 。/sys/power/state节点的读写操作如下:
[cpp] view plain copyprint ?
how(*kobj,*attr,char*buf){char*s=buf;#nti;for(i=0;.level=;nd(&ts->);
ts->earlysuspend.suspend = sitronix_i2c_suspend_early;ts->earlysuspend.resume = sitronix_i2c_resume_late;ts->earlysuspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN;register_early_suspend(&ts->earlysuspend);
设置好和接口,定义优先等级,然后注册结构即可 。
2、初始化信息
我们看一下需要用到的一些数据:
[cpp] view plain copyprint ?
();(rs);//初始化浅度休眠链表//声明3个工作队列用于同步、浅度休眠和唤醒sync(*work);end(*work);e(*work);(,);(,);(,);K();enum{=0x1,//当前正在请求浅度休眠=0x2,//浅度休眠完成=|,};;
static DEFINE_MUTEX(early_suspend_lock);static LIST_HEAD(early_suspend_handlers);// 初始化浅度休眠链表// 声明3个工作队列用于同步、浅度休眠和唤醒static void early_sys_sync(struct work_struct *work);static void early_suspend(struct work_struct *work);static void late_resume(struct work_struct *work);static DECLARE_WORK(early_sys_sync_work,early_sys_sync);static DECLARE_WORK(early_suspend_work, early_suspend);static DECLARE_WORK(late_resume_work, late_resume);static DEFINE_SPINLOCK(state_lock);enum {SUSPEND_REQUESTED = 0x1,// 当前正在请求浅度休眠SUSPENDED = 0x2,// 浅度休眠完成SUSPEND_REQUESTED_AND_SUSPENDED = SUSPEND_REQUESTED | SUSPENDED,};static int state;

二  android 休眠唤醒机制分析 — early_suspend

文章插图
初始化了一个链表rs用于管理,还定义读写链表用到的互斥体;另外还声明了3个工作队列,分别用于缓存同步、浅度休眠和唤醒;还声明了操作的3个状态 。
3、nd 和pend
【二android 休眠唤醒机制分析 — early_suspend】[cpp] view plain copyprint ?
(*){*pos;(&);//遍历浅度休眠链表(pos,&rs){*e;e=(pos,,link);//判断当前节点的优先等级是否大于的优先等级//以此决定在链表中的顺序if(e->level>->level)break;}//将加入当前节点之前,优先等级越低越靠前(&->link,pos);if((state&)&&->)->();(&);}(nd);
void register_early_suspend(struct early_suspend *handler){struct list_head *pos;mutex_lock(&early_suspend_lock);// 遍历浅度休眠链表list_for_each(pos, &early_suspend_handlers) {struct early_suspend *e;e = list_entry(pos, struct early_suspend, link);// 判断当前节点的优先等级是否大于handler的优先等级// 以此决定handler在链表中的顺序if (e->level > handler->level)break;}// 将handler加入当前节点之前,优先等级越低越靠前list_add_tail(&handler->link, pos);if ((state & SUSPENDED) && handler->suspend)handler->suspend(handler);mutex_unlock(&early_suspend_lock);}EXPORT_SYMBOL(register_early_suspend);
注册的流程比较简单,首先遍历链表,依次比较每个节点的优先等级,如果遇到优先等级比新节点优先等级高则跳出,然后将新节点加入优先等级较高的节点前面,这样就确保了链表是优先等级低在前高在后的顺序;在将节点加入链表后查看当前状态是否为浅度休眠完成状态,如果是则执行的函数 。