1. 休眠&唤醒
休眠状态指的是一种系统低功耗运行状态。在此状态下,各种支持休眠模式的外围设备也都全部进入休眠模式,CPU 挂起,所有用户态应用程序和内核态进程全部被冻结,内存处于自刷新模式。系统处于休眠状态会屏蔽所有除唤醒之外的所有命令,直到系统被某种原因唤醒才会解除此种状态。
// cat /sys/power/state【freeze: 可快速恢复,mem: 长时间省电】:支持哪些挂起模式,不是当前状态
// echo freeze/mem > /sys/power/state:触发休眠,命令敲完后,串口卡住没反应了(在/sys/power/autosleep【CONFIG_PM_AUTOSLEEP:自动休眠唤醒】是 off 状态才行)
// kernel/power/suspend.c: int pm_suspend(suspend_state_t state)
// autosleep 也是调用这行函数
{
error = enter_state(state);
// 进入 suspend 状态,具体的状态根据 state 值而定,如果执行成功的话,一直到系统退出 suspend 的状态后此函数才退出
}
// 如果外设没有实现 dev_pm_ops,那么外设对于休眠唤醒没有任何动作
struct dev_pm_ops {
int (*suspend)(struct device *dev); // 休眠,下电,与下面成对出现
int (*resume)(struct device *dev); // 唤醒,上电
...
int (*runtime_suspend)(struct device *dev); // 单设备:并不是要求设备一定要进入低功耗状态,而是要求设备在 suspend 后,不再处理数据,不再和 CPUs、RAM 进行任何的交互,直到设备的 runtime_resume 被调用
int (*runtime_resume)(struct device *dev);
};
如整机休眠时调用下面外设的.suspend。
如下查看哪个驱动模块当前有活跃锁,导致整机休眠不下去。自动休眠唤醒 suspend 控制器发现如果 /sys/kernel/debug/wakeup_sources 中 active_since 一列都为 0 即没有持锁(即没有唤醒)就休眠。
如下 __pm_relax 用来释放先前通过 __pm_stay_awake 增加的唤醒请求即 active_since 一列。
如按触屏和播放视频都不能休眠。
/* 有时候进程在读设备时,发现设备数据还没准备好,没办法正常读取设备。或在写设备时,发现设备缓冲区满,没办法正常写设备。进程在操作设备时,如果条件不满足,就让它进入休眠等待,直到条件满足,就可唤醒进程进行后面操作。
初始化:DECLARE_WAIT_QUEUE_HEAD() // 初始化等待队列头,宏的静态方式 或 wait_queue_head_t wq; // 动态方式 init_waitqueue_head(&wq);
休眠:wait_event() // 不可被打断,死等,直到满足条件为止
wait_event_interruptible() // 可使用信号打断它,常用
唤醒:wake_up() // 对应 wait_event()
wake_up_interruptible() // 对应上面可中断方式休眠的进程 wait_event_interruptible()
*/
#include
DECLARE_WAIT_QUEUE_HEAD(wq);
{
printk(KERN_INFO , hc_dev);
wait_event_interruptible(wq, hc_dev->c != );
}
{
printk(KERN_INFO , current->comm);
wake_up(&wq);
wake_up_interruptible(&wq);
count;
}


