第十三章Android内核驱动——电源管理13.1 基本原理
Android 中定义了几种低功耗状态:earlysuspend,suspend,hibernation。
●earlysuspend是一种低功耗的状态,某些设备可以选择进入某种功耗较低的状态,比如
LCD可以降低亮度或灭掉;
●suspend是指除电源管理以外的其他外围模块以及cpu均不工作,只有内存保持自刷新的
状态;
●hibernation是指所有内存镜像都被写入磁盘中,然后系统关机,恢复后系统将能恢复到
“关机”之前的状态。
13.2 电源管理机制的实现
电源管理机制的源代码主要在kernel/power/文件夹下面。
main.c文件是整个框架的入口。用户可以通过读写sys文件/sys/power/state实现控制系统进入低功耗状态。用户对于/sys/power/state的读写会调用到main.c中的state_store(,用户可以写入const char * const pm_states[] 中定义的字符串,比如“on”,“mem”,“standby”,“disk”。
state_store(首先判断用户写入的是否是“disk”字符串,如果是则调用hibernate(函数命令系统进入hibernation状态。如果是其他字符串则调用request_suspend_state((如果未定义CONFIG_EARLYSUSPEND或者调用enter_state((如果未定义CONFIG_EARLYSUSPEND。
request_suspend_state(函数是android相对标准linux改动的地方,它实现在earlysuspend.c 中。在标准linux内核中,用户通过sysfs 写入“mem”和“standby”时,会直接调用enter_state(进入suspend模式,但在android中则会调用request_suspend_state(函数进入early suspend 状态。request_suspend_state(函数代码如下:
可见实际工作的是early_suspend和late_resume这两个函数。Android提供了register_early_suspend和unregister_early_suspend两个函数供驱动调用,分别完成设备earlysuspend的注册和注销。系统将所有注册支持early_suspend的设备驱动对应的handler 挂在一个称为early_suspend_handler的链表上。函数early_suspend和late_resume完成的事情很简单,就是遍历这个链表,依次调用每个设备注册的handler,late_resume是唤醒处于
register_early_suspend函数完成的功能就是把驱动提供的earlysuspend handler挂到early_suspend_handler链表上。unregister_early_suspend则相反,从链表上摘下handler。
fbearlysuspend.c和consoleearlysuspend.c这两个文件实现了针对lcd framebuffer的earlysuspend支持和console的earlysuspend支持。实际上这两个文件就是利用上面earlysuspend.c提供的接口注册了针对framebuffer和console的early suspend handler,并提供相应的handler函数。
Hibernate.c文件实现hibernation低功耗状态,是最彻底的低功耗模式,它把所有内存镜像都写入磁盘中,然后系统关机。该文件还在sysfs文件系统中创建了多个entry,分别是/sys/power/disk,/sys/power/resume和/sys/power/image_size,这样用户可以直接通过sysfs 来控制系统进出hibernation状态。这块代码跟标准Linux内核没有什么区别。
Android改动较大的另一处是增加了wakelock机制。实现在wakelock.c和userwakelock.c中。wakelock可以阻止处于正常运行(active或者空闲(idle状态的系统进入睡眠等低功耗状态。直到所持有的wakelock全部被释放,系统才能进入睡眠等低功耗的状态。
wakelock有加锁和解锁两种状态,加锁的方式有两种,一种是永久的锁住,这样的锁除非显示的放开,是不会解锁的。第二种是超时锁,这种锁会锁定系统一段时间,如果这个时间过去了,这个锁会自动解除。
锁有两种类型:
●WAKE_LOCK_SUSPEND:这种锁会防止系统进入睡眠,这种锁可以具有
WAKE_L