我有一个在Linux上运行的Qt应用程序.
用户可以使用此应用程序将系统切换到mem sleep.
切换到mem睡眠是微不足道的,但是在用户空间中捕获唤醒事件则不然.
我目前的解决方案是使用无限循环来捕获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
}
Run Code Online (Sandbox Code Playgroud)
我将此方法描述为对此问题的评论,并指出这不是一个好的解决方案,我同意.
问题:是否有可用于捕获唤醒事件的C API?
更新:
1)mem睡眠是什么?
https://www.kernel.org/doc/Documentation/power/states.txt
内核通常支持最多四个系统睡眠状态,尽管其中三个依赖于平台支持代码来实现每个状态的低级细节.
状态由可以读取或写入/ sys/power/state文件的字符串表示 .这些字符串可能是"mem","standby","freeze"和"disk",其中最后一个字符串始终表示休眠(Suspend-To-Disk),其余字符串的含义取决于relative_sleep_states命令行参数.
2)为什么我要赶上唤醒事件?
因为某些硬件需要在唤醒后重置.系统唤醒后,硬件输入设备会产生错误的输入事件,因此必须在睡眠前(简单)禁用,并在唤醒后启用(此问题).
这应该/可以由内核中的驱动程序处理,我可以访问或修复硬件,我的团队可以做但是没有时间去做.(为什么我,一个应用程序开发人员,需要修复它在用户空间)
3)约束
这是嵌入式linux,内核2.6.37,arch:arm,march:omap2,distro:arago.它不像PC发行版那样方便添加包,也没有ACPI.内核2.6.37中的mem sleep支持还不成熟.
PCI 设备的 Linux 设备驱动程序可以选择处理挂起和恢复,大概是内核在系统挂起之前和从挂起恢复之后分别调用的。PCI 入口点位于struct pci_driver.
您可以编写并安装一个简单的设备驱动程序,该驱动程序除了检测恢复操作并向任何感兴趣的进程提供指示之外,什么也不做。最简单的可能是支持文件read() ,只要检测到恢复,该文件就会返回单个字节。该程序只需要打开设备并让线程卡住读取单个字符。每当读取成功时,系统就会恢复。
更重要的是,如果您的应用程序正在处理的设备具有设备驱动程序,则应更新驱动程序以对resume做出适当的反应。