休眠唤醒 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 函数,二分法定位问题
相关推荐
Android系统攻城狮8 小时前
Linux Gstreamer深度解析之gst_audio_ring_buffer_delay调用流程与实战(七十二)
linux·运维·服务器·gstreamer音视频·音视频进阶
快乐的韭菜根根9 小时前
ubuntu 安装slurm并配置
linux·运维·ubuntu
倒头就睡的小比特11 小时前
Linux基础指令3
linux·服务器
梦帮科技11 小时前
Kali Linux Scapy 畸形报文构造学——深度解剖非法 TCP Flags 与反常序列号
linux·爬虫·神经网络·算法·数学建模·系统架构·模拟退火算法
半杯咖啡半行码12 小时前
Linux 驱动开发入门:内核模块编程基础
linux·服务器·网络
别动我齐刘海12 小时前
Linux 系统调试学习2
linux·运维·c++·人工智能·学习·机器学习·机器人
龙虾电话12 小时前
语音机器人打断不进去:VAD 双阈值迟滞里一个共用的 bool,和它引发的连锁误判
linux
honsor13 小时前
机房IP化改造首选:以太网温湿度传感器,PoE供电+Modbus TCP一网搞定
linux·运维·服务器
默|笙13 小时前
【Linux网络】_udp_socket(认识)
linux·网络·udp
程序员梅雨14 小时前
ZooKeeper面经总结
java·大数据·linux·分布式·后端·zookeeper·中间件