基于android5.1休眠唤醒流程

1.用户态睡眠流程

framework/base/services/core/java/com/android/server/power/PowerManagerService.java

updatePowerStateLocked()-> updateSuspendBlockerLocked()->setHalAutoSuspendModeLocked()->nativeSetAutoSuspend();

调用此接口陷入jni调用:

framework/base/services/core/jni/com_android_server_power_PowerManagerService.cpp

nativeSetAutoSuspend()->autosuspend_enable();

直接调用掉libautosuspend中的配置函数

system/core/libsuspend/autosuspend.c

autosuspend_enable()中通过回调autosuspend_ops->enable();调用到autosuspend_earlysuspend_enable()中,在此函数中执行write系统调用。

将mem的字符串通过sys虚拟文件系统,写入/sys/power/state引起kernel中的休眠流程。

2.kernel中的休眠流程:

/kernel/kernel/power/main.c

state_store()通过decode_state()函数确认当前的睡眠状态,调用pm_suspend();引起睡眠;

调用到enter_state()

static int enter_state(suspend_state_t state)
{
    int error;
    if (!valid_state(state))
        return -ENODEV;

    if (!mutex_trylock(&pm_mutex))
        return -EBUSY;

    if (state == PM_SUSPEND_FREEZE)
        freeze_begin();

    printk(KERN_INFO "PM: Syncing filesystems ... ");
    sys_sync();
    printk("done.\n");

    pr_debug("PM: Preparing system for %s sleep\n", pm_states[state]);
    error = suspend_prepare(state);
    if (error)
        goto Unlock;

    if (suspend_test(TEST_FREEZER))
        goto Finish;

    pr_debug("PM: Entering %s sleep\n", pm_states[state]);
    pm_restrict_gfp_mask();
    error = suspend_devices_and_enter(state);
    pm_restore_gfp_mask();

 Finish:
    pr_debug("PM: Finishing wakeup.\n");
    suspend_finish();
 Unlock:
    mutex_unlock(&pm_mutex);
    return error;
}

个人感觉比较重要的是suspend_prepare()和suspend_devices_and_enter()

static int suspend_prepare(suspend_state_t state)
{
    int error;

    if (need_suspend_ops(state) && (!suspend_ops || !suspend_ops->enter))
        return -EPERM;

    pm_prepare_console();

    error = pm_notifier_call_chain(PM_SUSPEND_PREPARE);//通过内核通知链通知所有期望的得到SUSPEND_PREPARE消息模块
    if (error)
        goto Finish;

    error = suspend_freeze_processes();//冻结进程,首先usr进程,然后kernel workqueue
    if (!error)
        return 0;

    suspend_stats.failed_freeze++;
    dpm_save_failed_step(SUSPEND_FREEZE);
 Finish:
    pm_notifier_call_chain(PM_POST_SUSPEND);
    pm_restore_console();
    return error;
}

对于int suspend_devices_and_enter(suspend_state_t state)
{
    int error;
    bool wakeup = false;

    if (need_suspend_ops(state) && !suspend_ops)
        return -ENOSYS;

    trace_machine_suspend(state);
    if (need_suspend_ops(state) && suspend_ops->begin) {
        error = suspend_ops->begin(state);
        if (error)
            goto Close;
    }
    suspend_console();
    ftrace_stop();
    suspend_test_start();
    error = dpm_suspend_start(PMSG_SUSPEND); //通过此函数调用到device_suspend();引起各个设备注册suspend函数被调用
    if (error) {
        printk(KERN_ERR "PM: Some devices failed to suspend\n");
        goto Recover_platform;
    }
    suspend_test_finish("suspend devices");
    if (suspend_test(TEST_DEVICES))
        goto Recover_platform;

    do {
        error = suspend_enter(state, &wakeup);//系统从此函数真正进入休眠。
    } while (!error && !wakeup && need_suspend_ops(state)
        && suspend_ops->suspend_again && suspend_ops->suspend_again());

 Resume_devices:
    suspend_test_start();
    dpm_resume_end(PMSG_RESUME);
    suspend_test_finish("resume devices");
    ftrace_start();
    resume_console();
 Close:
    if (need_suspend_ops(state) && suspend_ops->end)
        suspend_ops->end();
    trace_machine_suspend(PWR_EVENT_EXIT);
    return error;

 Recover_platform:
    if (need_suspend_ops(state) && suspend_ops->recover)
        suspend_ops->recover();
    goto Resume_devices;
}


static int suspend_enter(suspend_state_t state, bool *wakeup)
{
    int error;

    if (need_suspend_ops(state) && suspend_ops->prepare) {
        error = suspend_ops->prepare();
        if (error)
            goto Platform_finish;
    }

    error = dpm_suspend_end(PMSG_SUSPEND);
    if (error) {
        printk(KERN_ERR "PM: Some devices failed to power down\n");
        goto Platform_finish;
    }

    if (need_suspend_ops(state) && suspend_ops->prepare_late) {
        error = suspend_ops->prepare_late();
        if (error)
            goto Platform_wake;
    }

    if (suspend_test(TEST_PLATFORM))
        goto Platform_wake;

    /*
     * PM_SUSPEND_FREEZE equals
     * frozen processes + suspended devices + idle processors.
     * Thus we should invoke freeze_enter() soon after
     * all the devices are suspended.
     */
    if (state == PM_SUSPEND_FREEZE) {
        freeze_enter();
        goto Platform_wake;
    }

    error = disable_nonboot_cpus();
    if (error || suspend_test(TEST_CPUS))
        goto Enable_cpus;

    arch_suspend_disable_irqs();
    BUG_ON(!irqs_disabled());

    error = syscore_suspend(); //使真正的内核进入休眠。
    if (!error) {
        *wakeup = pm_wakeup_pending();
        if (!(suspend_test(TEST_CORE) || *wakeup)) {
            error = suspend_ops->enter(state);
            events_check_enabled = false;
        }
        syscore_resume(); //当有中断打破当前的睡眠状态,将引起系统的唤醒,首先是core唤醒,后续返回到int suspend_devices_and_enter(suspend_state_t state)

                                              //继续执行唤醒流程


    }

    arch_suspend_enable_irqs();
    BUG_ON(irqs_disabled());

 Enable_cpus:
    enable_nonboot_cpus();

 Platform_wake:
    if (need_suspend_ops(state) && suspend_ops->wake)
        suspend_ops->wake();

    dpm_resume_start(PMSG_RESUME);

 Platform_finish:
    if (need_suspend_ops(state) && suspend_ops->finish)
        suspend_ops->finish();

    return error;
}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值