安卓休眠与唤醒流程

理解Android的休眠与唤醒流程,需要从应用层框架层 一直深入到内核驱动层。为了帮你直观地看清这个复杂的协作过程,下图展示了完整的架构与核心流程:
请求休眠/持有WakeLock ioctl/系统调用 中断/事件 广播/回调 Linux内核层 Wakeup Source
唤醒源跟踪 Suspend/Resume流程
及状态机 系统服务层 PowerManagerService
核心协调器 Native空间
JNI桥接 应用框架层 PowerManager 应用/WakeLock/Alarm

上图揭示了各层级的关键角色:应用层发起请求,PowerManagerService作为"总指挥",而内核层则负责硬件层面的最终执行。

🔍 核心流程详解与代码日志分析

下面我们结合你提供的日志片段,对休眠和唤醒这两个主要流程进行拆解。

1. 休眠流程:从应用到内核的层层关停

完整的休眠是一个由应用触发、最终由内核执行的"关停"过程:

  1. 应用层请求 :当需要休眠时(如超时、按电源键),会调用 PowerManager.goToSleep()。拥有系统权限的应用才能调用此方法。

  2. 框架层协调PowerManagerService 收到请求后,会先检查是否有唤醒锁 阻止休眠。这是关键检查点,可以参考一个早期但原理一致的代码逻辑:

    c 复制代码
    // kernel/power/wakelock.c (简化示例,说明机制)
    static long has_wake_lock_locked(int type) {
        struct wake_lock *lock;
        list_for_each_entry(lock, &active_wake_locks[type], link) {
            if (!(lock->flags & WAKE_LOCK_AUTO_EXPIRE)) {
                printk("lockname = %s,lockflag = 0x%x\n", lock->name, lock->flags);
                return -1; // 返回-1,表示有非自动释放的锁阻止休眠
            }
        }
        return 0; // 返回0,表示没有锁阻止,可以休眠
    }

    代码注释 :这个函数遍历活跃的唤醒锁列表。如果存在 WAKE_LOCK_AUTO_EXPIRE(非自动释放)类型的锁,系统就无法进入休眠。

  3. 内核层执行 :如果没有唤醒锁阻止,PowerManagerService 会通过 JNIsysfs 接口,向内核写入 memstandby 等状态,触发内核的全局休眠流程 。这包括:

    • 冻结用户进程 :日志中出现的 Freezing user space processes ... (elapsed 0.017 seconds) done. 就是这个阶段。
    • 挂起外围设备 :内核会依次调用各设备驱动的 suspend 回调函数。在你之前的日志中,[TP]ILITEK: ilitek_spi_suspendmtk-msdc ... suspend 就是触屏、存储等设备进入低功耗状态。
    • 系统核心挂起:最后,CPU进入特定的低功耗状态。
2. 唤醒流程:从硬件中断到应用响应

唤醒通常由硬件中断发起,是一个"启动"过程:

  1. 硬件中断 :唤醒源(如电源键、网络中断、RTC闹钟)产生硬件中断。你日志中的 Resume caused by IRQ 138, wlan0 明确指示了唤醒源头是Wi-Fi中断

  2. 内核响应与日志记录 :Linux内核的 wakeup_reason 基础设施会记录导致唤醒的中断号(IRQ)或唤醒源(wakeup_source) 。这就是你日志开头部分记录的由来。其核心实现逻辑简化如下:

    c 复制代码
    // drivers/base/power/wakeup.c (相关逻辑)
    void pm_system_irq_wakeup(unsigned int irq_number) {
        if (pm_wakeup_irq == 0) {
            log_irq_wakeup_reason(irq_number); // 记录唤醒原因
            pm_wakeup_irq = irq_number;
            pm_system_wakeup(); // 触发系统唤醒
        }
    }

    代码注释 :当中断触发唤醒时,pm_system_irq_wakeup 被调用。log_irq_wakeup_reason(irq_number) 会将这个中断号记录下来,最终可以通过 /sys/power/last_wakeup_reason 读取。

  3. 恢复系统与设备 :内核沿着休眠的逆序恢复:CPU核心 -> 系统总线 -> 设备驱动 (调用 resume 函数)-> 解冻进程

  4. 框架层与应用层通知PowerManagerService 被通知后,会更新系统状态,并发送 ACTION_SCREEN_ON 等广播。应用可以接收这些广播来执行恢复操作。

💎 总结与问题回顾

综上所述,Android的休眠唤醒是一个涉及软硬件多层级的状态机协作。其核心在于 PowerManagerService 作为中央协调器,基于唤醒锁 策略和硬件唤醒源事件,指挥内核完成状态切换。

回顾你最初日志中遇到的 "eMMC访问违例"问题 ,其根源正是在这个精密的协作流程中出现了时序竞争 :系统在休眠流程中已经开始挂起eMMC控制器(释放时钟/电源),但此时安全子系统(TEE)的RPMB操作仍在进行,导致非法访问。这通常需要在驱动或系统层面增加同步机制,确保关键操作在器件下电前完成。

如果你想进一步探讨,我们可以深入某个具体环节,例如:

  1. 唤醒锁的具体类型和应用场景(如保持CPU唤醒或屏幕唤醒)。
  2. Android Doze模式等更深度的电源优化策略。
  3. 如何利用 /sys/power/wakeup_sourcesdumpsys power 命令进行实际的功耗问题调试。

欢迎你提出更具体的方向。

相关推荐
二流小码农3 小时前
鸿蒙开发:个人开发者如何使用华为账号登录
android·ios·harmonyos
StarShip3 小时前
Android View框架概览
android·计算机图形学
愤怒的代码3 小时前
解析Android内存分析的指标
android·app
summerkissyou19873 小时前
android-hardware/interfaces/automotive和hardware/libhardware/include/hardware区别
android
Evan芙3 小时前
mysql二进制部署以及多实例部署
android·数据库·mysql
走在路上的菜鸟4 小时前
Android学Dart学习笔记第二十三节 类-扩展类型
android·笔记·学习·flutter
百***78754 小时前
【技术教程】3步极速接入GPT-5.1:零门槛体验多模态AI能力
android·java·人工智能·gpt·opencv
走在路上的菜鸟5 小时前
Android学Dart学习笔记第二十一节 类-点的简写
android·笔记·学习·flutter
QQ12958455045 小时前
ThingsBoard-修改Android APP应用程序名和描述
android·物联网·iot