一、系统睡眠状态
Linux内核支持四种系统睡眠状态即:mem、standby、freeze and disk
。
可通过文件/sys/power/state
进行读写访问,区别如下:
Label | ACPI State | 说明 | State | 功耗 | 唤醒 |
---|---|---|---|---|---|
freeze | Suspend-To-Idle | 冻结用户空间,将所有I/O设备进入低功耗状态,处理器进入空闲状态 | S0 | 最高 | 最快 |
standby | Power-On Suspend | 冻结用户空间,将所有I/O设备进入低功耗状态,关闭非引导CPU,暂停系统 | S1 | 较高 | 较快 |
mem | Suspend-to-RAM(STR) | 将系统和设备状态保存到内存(处在自刷新模式,已保留其内容),所有设备进入低功耗模式 | S2 | 较低 | 较慢 |
disk | Suspend-to-disk(STD) | 类似STR,将内存内容写入到磁盘, | S3 | 最低 | 最慢 |
二、睡眠状态说明
在RockPI 4A
单板Debian
系统Linux 4.4
内核中,查看电源状态,仅支持freeze和mem
两种。
root@linaro-alip:/sys/power# cat state
freeze mem
原因:
1、Platform
驱动只实现了mem
类型的suspend
2、只有在hibernation
可用时,才支持STD
1、psci
初始化流程
/**
* suspend_valid_only_mem - Generic memory-only valid callback.
*
* Platform drivers that implement mem suspend only and only need to check for
* that in their .valid() callback can use this instead of rolling their own
* .valid() callback.
*/
int suspend_valid_only_mem(suspend_state_t state)
{
return state == PM_SUSPEND_MEM;
}
static const struct platform_suspend_ops psci_suspend_ops = {
.valid = suspend_valid_only_mem, ## 判读有效状态,仅支持mem状态
...
};
static void __init psci_init_system_suspend(void)
{
int ret;
...
if (ret != PSCI_RET_NOT_SUPPORTED)
suspend_set_ops(&psci_suspend_ops); ### 设置global suspend method table
}
suspend_set_ops()
函数赋值数组pm_states
实现如下:
/**
* suspend_set_ops - Set the global suspend method table.
* @ops: Suspend operations to use.
*/
void suspend_set_ops(const struct platform_suspend_ops *ops)
{
suspend_state_t i;
int j = 0;
lock_system_sleep();
suspend_ops = ops;
for (i = PM_SUSPEND_MEM; i >= PM_SUSPEND_STANDBY; i--)
## 1、此处判断valid状态,只有mem满足
if (valid_state(i)) {
pm_states[i] = pm_labels[j++];
} else if (!relative_states) { ## 2、standby状态,置NULL
pm_states[i] = NULL;
j++;
}
pm_states[PM_SUSPEND_FREEZE] = pm_labels[j]; ## 3、freeze状态
unlock_system_sleep();
}
2、power state显示
/sys/power/state
文件显示的内容,通过state_show()
函数实现,该函数最终显示数组pm_states
的内容。
static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr,
char *buf)
{
char *s = buf;
#ifdef CONFIG_SUSPEND
suspend_state_t i;
for (i = PM_SUSPEND_MIN; i < PM_SUSPEND_MAX; i++)
if (pm_states[i])
s += sprintf(s,"%s ", pm_states[i]);
#endif
if (hibernation_available()) ### hibernation_available()为true,才支持STD
s += sprintf(s, "disk ");
if (s != buf)
/* convert the last space to a newline */
*(s-1) = '\n';
return (s - buf);
}
参考:
Documentation/power/states.txt
网友评论