用户空间接口是什么

描述

/sys/power/state

state 是 sysfs 中一个文件,为 Generic PM
的核心接口,在“kernel/power/main.c”中实现,用于将系统置于指定的 Power State。

读取该文件,返回当前系统支持的 Power State,形式为字符串。在内核中,有两种类型的 Power
State,一种是 Hibernate
相关的,名称为“disk”,除“disk”之外,内核在"/kernel/power/suspend.c"中通过数组的形式定义了另外 3 个
state,如下:

const char *const pm_states[PM_SUSPEND_MAX] = {
    [PM_SUSPEND_FREEZE]     = "freeze",
    [PM_SUSPEND_STANDBY]    = "standby",
    [PM_SUSPEND_MEM]        = "mem",
};

这些 Power State 的解释如下:

  1. freeze:不涉及具体的
    Hardware 或 Driver,只是冻结所有的进程,包括用户空间进程及内核线程
  2. standby
  3. mem,即通常所讲的 Sleep
    功能,STR,Suspend to RAM。
  4. disk,即
    Hibernate 功能,STD,Suspend to Disk。

写入特定的 Power State 字符串,将会把系统置为该模式。

/sys/power/wakeup_count

该接口只和 Sleep 功能有关,因此由“CONFIG_PM_SLEEP”宏定义控制。它的存在,是为了解决
Sleep 和 Wakeup 之间的同步问题。

系统睡眠后,可以通过保留的 Wakeup source 唤醒系统。而在 CPU 体系中,唤醒系统就是唤醒
CPU,而唤醒 CPU 的唯一途径,就是 Wakeup source 产生中断(内核称作 Wakeup event)。而内核要保证在多种状态下,Sleep/Wakeup
的行为都能正常,如下:

▆ 系统处于 sleep 状态时,产生了 Wakeup event。此时应该直接唤醒系统。这没有问题。

▆ 系统在进入 sleep 的过程中,产生了
Wakeup event。此时应该放弃进入 sleep。

这一点就不那么容易做到了。例如,当 Wakeup event
发生在“/sys/power/state”被写之后、内核执行 freeze 操作之前。此时用户空间程序依旧可以处理 Wakeup
event,或者只是部分处理。而内核却以为该 Event 已经被处理,因此并不会放弃此次 sleep 动作。

这就会造成,Wakeup event 发生后,用户空间程序已经后悔了,不想睡了,但最终还是睡下去了。直到下一个
Wakeup event 到来。

为了解决上面的问题,内核提供 wakeup_count 机制,配合“/sys/power/state”,以实现
Sleep 过程中的同步。该机制的操作行为如下:

▆ wakeup_count 是内核用来保存当前
wakeup event 发生的计数。

▆ 用户空间程序在写入
state 切换状态之前,应先读取 wakeup_count 并把获得的 count 写回给 wakeup_count。

▆ 内核会比对写回的 count 和当前的 count 是否一致,如果不一致,说明在读取/写回操作之间,产生了新的的
wakeup event,内核就会返回错误。

▆ 用户空间程序检测到写入错误之后,不能继续后的动作,需要处理响应的 event 并伺机再次读取/写回
wakeup_count。

▆ 如果内核比对一致,会记录 write wakeup_count 成功时的 event 快照,后面继续
suspend 动作时,会检查是否和快照相符,如果不符,会终止 suspend。

▆ 用户空间程序检测到写入正确后,可以继续对 state 的写入,以便发起一次状态切换。而此时是安全的。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分