休眠唤醒 standby 调试

更多内容可以加入Linux系统知识库套餐(教程+视频+答疑)

休眠唤醒(Power Management)是嵌入式驱动的常见痛点------板子睡死了、唤不醒、唤醒后外设不正常...本文从原理到调试工具,带你搞定 Linux standby 休眠唤醒调试。

一、Linux 休眠方式

Linux 支持多种休眠状态,从浅到深:

状态 说明 功耗 唤醒速度
freeze 冻结用户态 + 停止 I/O,CPU 还在运行 高 最快
standby 待机,CPU 断电,内存保持 中 快
mem Suspend to RAM,内存自刷新,CPU/外设断电 低 较快
disk Suspend to Disk,内存写入磁盘,完全断电 最低 最慢

嵌入式常用的是 mem(STR,Suspend to RAM),也就是我们常说的"待机"。

二、休眠唤醒流程

🌙 休眠过程:

复制代码
用户空间触发休眠 (echo mem > /sys/power/state)
    ↓
冻结用户态进程
    ↓
调用各设备驱动的 .suspend 回调
    ↓
关闭非唤醒中断
    ↓
CPU 进入低功耗状态
    ↓
内存自刷新,板子进入待机

☀️ 唤醒过程:

复制代码
唤醒源触发中断(按键/定时器/网络等)
    ↓
CPU 恢复运行
    ↓
调用各设备驱动的 .resume 回调
    ↓
恢复用户态进程
    ↓
系统恢复正常运行

三、驱动 PM 操作接口

驱动通过 dev_pm_ops 结构体实现休眠唤醒回调:

复制代码
static const struct dev_pm_ops my_dev_pm_ops = {
    .suspend = my_suspend,     // 休眠
    .resume  = my_resume,      // 唤醒
    .freeze  = my_freeze,      // 冻结
    .thaw    = my_thaw,        // 解冻
    .prepare = my_prepare,     // 休眠前准备
    .complete = my_complete,   // 唤醒后完成
};

static struct platform_driver my_driver = {
    .probe  = my_probe,
    .remove = my_remove,
    .driver = {
        .name = "my_device",
        .pm = &my_dev_pm_ops,  // 关联 PM 操作
    },
};

四、常用调试手段

🔧 1. no_console_suspend

休眠时控制台默认会关闭,导致你看不到休眠过程中的打印。在 bootargs 中添加:

复制代码
no_console_suspend

这样休眠过程中串口控制台保持开启,可以看到完整的休眠唤醒日志。

🔧 2. initcall_debug + no_console_suspend

更详细的设备休眠/唤醒调试信息:

复制代码
initcall_debug no_console_suspend ignore_loglevel

🔧 3. wakeup_sources 唤醒源

查看哪些设备可以唤醒系统,以及是谁唤醒了系统:

复制代码
# 查看所有唤醒源
cat /sys/kernel/debug/wakeup_sources

# 查看唤醒计数
cat /sys/power/wakeup_count

# 查看最后一次唤醒原因(平台相关)
cat /sys/kernel/debug/suspend_stats

🔧 4. wake_lock 唤醒锁

系统持有唤醒锁时不会进入休眠。调试"睡不下去"的问题:

复制代码
# 查看当前持有的唤醒锁
cat /sys/power/wake_lock
cat /sys/power/wake_unlock

# Android 系统常用
dumpsys power | grep WAKE_LOCK

五、休眠失败常见原因

问题 可能原因 排查方向
睡不下去 有唤醒锁未释放 查看 /sys/power/wake_lock
睡不下去 某个驱动 suspend 返回失败 开 no_console_suspend 看日志
睡死了 唤醒源未正确配置 检查唤醒源是否使能、极性是否正确
唤醒后外设异常 驱动 resume 有问题 检查寄存器是否恢复、时钟是否重新使能
自动唤醒 有干扰信号触发中断 查看 wakeup_sources 中的 event_count

六、autosleep 自动休眠

Android 等系统使用 autosleep 机制,没有唤醒锁时自动进入休眠:

复制代码
# 查看/设置自动休眠模式
cat /sys/power/autosleep
echo mem > /sys/power/autosleep

# 唤醒锁阻止休眠
echo my_wakelock > /sys/power/wake_lock
# 释放唤醒锁
echo my_wakelock > /sys/power/wake_unlock

七、调试步骤总结

第1步:确认能否正常休眠

复制代码
echo mem > /sys/power/state

第2步:如果睡不下去,开启调试日志

复制代码
# bootargs 添加
no_console_suspend initcall_debug ignore_loglevel

第3步:检查唤醒源

复制代码
cat /sys/kernel/debug/wakeup_sources

第4步:逐个驱动排查

复制代码
# 去掉驱动的 suspend/resume 函数,二分法定位问题
相关推荐
whyutianict_vv16 分钟前
零基础转 AI 运维:投入清单、技术路线与核对表
linux·运维·人工智能·ai
无言听风雨丶17 分钟前
systemd 与信号 / 僵尸进程:Linux 进程管理的底层逻辑与排错
linux·服务器·网络
DevOpenClub36 分钟前
高考一分一段 API:分数查位次、科类枚举与历史对照
linux·数据库·高考
小贾要学习1 小时前
【C++后端开发项目】Reactor 模型 / C++ 仿写 muduo HTTP 服务器:让底层网络库真正跑起网页
linux·服务器·c++·http·网络编程·muduo·reactor模型
Blockbuater_drug1 小时前
OpenMM分子动力学模拟02 安装:Linux:conda 一条命令装通 GPU 加速的分子模拟环境
linux·conda·cuda·gpu驱动·pythonpath·openmm安装
程序员JerrySUN1 小时前
PCIe Gen5 SSD 为什么读得快、写得慢?从存储原理到 Linux 性能实测
linux·服务器·网络
Android系统攻城狮1 小时前
Linux FFmpeg深度解析之avcodec_parameters_copy调用流程与实战(二十五)
linux·运维·服务器·ffmpeg·音视频·车载音频
ITKEY_2 小时前
emacs 文件管理Dired, the Directory Editor
linux·编辑器·emacs
源图客2 小时前
解决CentOS操作系统网络异常问题
linux·运维·centos
HideF12 小时前
Linux sudo
linux