设为首页 加入收藏

TOP

Power Management(五)
2014-11-23 21:37:42 来源: 作者: 【 】 浏览:63
Tags:Power Management
ror = suspend_ops->enter(state); events_check_enabled = false; } syscore_resume(); } arch_suspend_enable_irqs(); BUG_ON(irqs_disabled()); Enable_cpus: enable_nonboot_cpus(); Platform_wake: if (suspend_ops->wake) suspend_ops->wake(); dpm_resume_start(PMSG_RESUME); Platform_finish: if (suspend_ops->finish) suspend_ops->finish(); return error; }



当我们进入suspend 的时候,我们最后会调用到suspend_ops->enter 函数里面,当执行到这个函数的时候,我们进入了要求的suspend 状态,只有当唤醒的时候才会返回。关于suspend_ops->enter 函数的实现,我们在讲解suspend_ops的时候里面有赋值(msm_pm_enter)。

其实我目前还没有明白为何进入msm_pm_enter 函数为何就停止在哪里?
设置CPU 的寄存器,让整个CPU 进入睡眠,进入睡眠之后,执行的code 就停止执行了, 就停止在那里了,当我们按下power button 的时候,CPU 又起来来,code 又继续执行了,所以就走下面的resume 流程。
power button 是硬件设计好了的wake source 源,硬件设计好了的。



当返回的时候,我们就会调用resume设备的 函数。

Resume_devices:
suspend_test_start();
dpm_resume_end(PMSG_RESUME);
suspend_test_finish(resume devices);
resume_console();

其实resume 的过程就和suspend 的流程差不多,也是从设备的链表里面遍历设备,最后调用设备的resume 函数。
因为下面执行的是goto 语句,所以依次就会执行:


syscore_resume();
}

arch_suspend_enable_irqs(); //打开中断
BUG_ON(irqs_disabled());

Enable_cpus:
enable_nonboot_cpus();//启动非启动CPU


Platform_wake:
if (suspend_ops->wake)
suspend_ops->wake();

dpm_resume_start(PMSG_RESUME);//Execute noirq and early device callbacks.

Platform_finish:
if (suspend_ops->finish)
就是整个resume 设备的流程。

5.wake_lock机制
基本原理如下:当启动一个应用程序的时候,它都可以申请一个wake_lock唤醒锁,每当申请成功之后都会在内核中注册一下(通知 系统内核,现在已经有锁被申请),当应用程序在某种情况下释放wake_lock的时候,会注销之前所申请的wake_lock。特别要注意的是:只要是系统中有一个wake_lock的时候,系统此时都不能进行睡眠。
下面将讲解上层获得wake_lock 的整个过程。
frameworks/base/services/java/com/android/server/power/PowerManagerService.java
        public void acquire() {
            synchronized (this) {
                mReferenceCount += 1;
                if (mReferenceCount == 1) {
                    if (DEBUG_SPEW) {
                        Slog.d(TAG, Acquiring suspend blocker  + mName + .);
                    }
                    nativeAcquireSuspendBlocker(mName);
                }
            }
        }


会调用nativeAcquireSuspendBlocker 这个 函数的实现是放在jni 里面的:
frameworks/base/services/jni/com_android_server_power_PowerManagerService.cpp

static void nativeAcquireSuspendBlocker(JNIEnv *env, jclass clazz, jstring nameStr) {
ScopedUtfChars name(env, nameStr);
acquire_wake_lock(PARTIAL_WAKE_LOCK, name.c_str());
}

最后调用acquire_wake_lock 进行申请wake_lock
enum {
PARTIAL_WAKE_LOCK = 1, // the cpu stays on, but the screen is off
FULL_WAKE_LOCK = 2 // the screen is also on
};
通过注释也可以看出这两种wake_lock 的区别。
我们继续trace code :
acquire_wake_lock的实现:
hardware/libhardware_legacy/power/power.c

int
acquire_wake_lock(int lock, const char* id)
{
initialize_fds();//获得我们设备结点的设备描述符号,并将我们获得的设备描述符号放到g_fds 这个数组里面。或者 /sys/power/wake_lock,/sys/power/wake_unlock,这两个设备结点的设备描述符号。

// ALOGI(acquire_wake_lock lock=%d id='%s' , lock, id);

if (g_error) return g_error;

int fd;

if (lock == PARTIAL_WAKE_LOCK) {
fd = g_fds[ACQUIRE_PARTIAL_WAKE_LOCK];//获得wake_lock 的设备节点的设备描述符
}
else {
return EINVAL;
}

return write(fd, id, strlen(id));//我们获得对应的设备描述符后,我们直接操作描述符。

}
write(fd, id, strlen(id) 会调用到wake_lock 里面的store 函数。在下面的小章节会讲解到wakelock.c 这个文件。
5.1.wake_lock_store
当我们使用到wake_lock 设备节点的时候,最终调用到wake_lock_store 函数。
static ssize_t wake_lock_store(struct kobject *kobj,
struct kobj_attribute *attr,
const char *buf, size_t n)
{
int error = pm_wake_lock(buf);
return error error : n;
}
pm_wake_lock函数的实现如下
首页 上一页 2 3 4 5 下一页 尾页 5/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇C语言 十进制转换成二进制转换方.. 下一篇数组nice to see you again

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: