我有一个在Linux上运行的Qt应用程序。
用户可以使用此应用程序将系统切换为mem sleep。
切换到mem sleep很简单,但是捕获用户空间中的唤醒事件并非易事。
我当前的解决方案是使用无限循环来捕获内存 sleep ,以便在系统唤醒时,我的应用程序始终从可预测的点继续运行。
这是我的代码:
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)什么是内存 sleep ?
2)为什么我要 catch 唤醒事件?
因为唤醒后需要重置某些硬件。硬件输入设备在系统唤醒后会生成错误的输入事件,因此必须在 sleep 之前将其禁用(容易),并在唤醒后启用(此问题)。
这应该/可以由内核中的驱动程序来处理,我可以访问该内核中的驱动程序,也可以由硬件中的驱动程序来解决,我的团队可以这样做,但没有时间这样做。(为什么我是应用程序开发人员,所以需要修复在用户空间中)
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(),该文件在检测到恢复时会返回一个字节。该程序只需要打开设备并停留在读取单个字符的线程上即可。只要读取成功,系统就会恢复。
更重要的是,如果您的应用程序正在处理的设备具有设备驱动程序,则应更新驱动程序以对恢复做出适当的 react 。
关于c++ - 如何知道系统是否刚刚从内存 sleep 中醒来?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32084819/