【发布时间】:2015-11-12 02:56:25
【问题描述】:
我有一个在 Linux 上运行的 Qt 应用程序。
用户可以使用此应用程序将系统切换到内存睡眠。
切换到内存睡眠很简单,但在用户空间中捕获唤醒事件却不是。
我目前的解决方案是使用无限循环来捕获 mem 睡眠,这样当系统唤醒时,我的应用程序总是从可预测的点继续。
这是我的代码:
void MainWindow::memSleep()
{
int fd;
fd = ::open("/sys/power/state", O_RDWR);// see update 1)
QTime start=QTime::currentTime();
write(fd,"mem",3); // command that triggers mem sleep
while(1){
usleep(5000); // delay 5ms
const QTime &end=QTime::currentTime();// check system clock
if(start.msecsTo(end)>5*2){// if time gap is more than 10ms
break; // it means this thread was frozen for more
} // than 5ms, indicating a wake up after a sleep
start=end;
}
:: close(fd); // the end of this function marks a wake up event
}
我将此方法描述为对this question的评论,有人指出这不是一个好的解决方案,我同意。
问题:是否有可用于捕获唤醒事件的 C API?
更新:
1) 什么是内存睡眠?
https://www.kernel.org/doc/Documentation/power/states.txt
内核通常最多支持四种系统睡眠状态,尽管三种 其中一些依赖于平台支持代码来实现底层细节 每个州。
状态由可以读取或写入的字符串表示 /sys/power/state 文件。这些字符串可能是 "mem"、"standby"、"freeze" 和 "disk",最后一个总是代表休眠(Suspend-To-Disk)和 其余的含义取决于 relative_sleep_states 命令 行参数。
2) 我为什么要捕捉唤醒事件?
因为某些硬件需要在唤醒后重置。硬件输入设备在系统唤醒后会产生错误的输入事件,所以必须在睡眠前禁用(easy),唤醒后启用(this question)。
这应该/可以由内核中的驱动程序处理,我可以访问,或者在硬件中修复,我的团队可以做但没有时间去做。(为什么我,一个应用程序开发人员,需要在用户空间修复它)
3) 约束
这是嵌入式 linux,内核 2.6.37,arch:arm,march:omap2,distro:arago。它不像PC发行版那样方便添加软件包,它没有ACPI。而且内核 2.6.37 中的 mem sleep 支持一点也不成熟。
【问题讨论】:
-
什么是“内存睡眠”?让电脑休眠?在这种情况下,如果有任何代码被执行,要么是 sleep 命令失败,要么已经被唤醒(不需要检查)
-
@SJuan76 请看我的更新
-
不确定,但可以选择 grep-ing dmesg 或任何其他日志文件来指示已调用 resume。