电源管理休眠流程梳理

1.Linux 描述的电源状态
S3 aka STR( to ram),挂起到内存,简称待机 。计算机将目前的运行状态等数据存放在内存,关闭硬盘、外设等设备,进入等待状态 。此时内存仍然需要电力维持其数据,但整机耗电很少 。恢复时计算机从内存读出数据,回到挂起前的状态,恢复速度较快 。对DDR的耗电情况进行优化是S3性能的关键,大多数手持设备都是用S3待机 。
S4 aka STD( to disk),挂起到硬盘,简称休眠 。把运行状态等数据存放在硬盘上某个文件或者某个特定的区域,关闭硬盘、外设等设备,进入关机状态 。此时计算机完全关闭,不耗电 。恢复时计算机从休眠文件/分区中读出数据,回到休眠前的状态,恢复速度较慢 。
二. 给u-boot添加命令
u-boot全速运行,耗电83ma
u-boot :耗电33ma ==>外设备没有完全关闭,比如声卡、网卡
进入休眠模式的方法:
/* 1. 配置GPIO: 比如想维持LED亮或灭, 用于唤醒CPU的引脚要设为中断功能 /
/ 2. 设置屏蔽所有中断: 在sleep模式下,这些引脚只是用于唤醒系统,当CPU正常运行时可以重新设置让这些引脚用于中断功能 /
/ 3. 配置唤醒源 /
/ 4. 设置[13:12]=11b, 使得USB模块进入休眠 /
/ 5. 在[4:3]保存某值, 它们可以在系统被唤醒时使用 /
/ 6. 设置 [1:0] 使能数据总线的上拉电阻 /
/ 7. 清除 .ENVID 以停止LCD /
/ 8. 读这2个寄存器:and , 以便填充TLB
* 如果不使用MMU的话,这个目的可以忽略
/ 9. 设置 [22]=1b,让SDRAM进入self- mode /
/ 10. 等待SDRAM成功进入self- mode /
/ 11.设置 [19:17]=111b以保护SDRAM信号(SCLK0,SCLK1 and SCKE) /
/ 12. 设置的SLEEP位让系统进入sleep mode */
在进入str之前,1.先要填充TLB,将页表复制到TLB中,防止SDRAM进入自刷新模式,虚拟地址不能通过页表找到物理地址 。
2.将SDRAM的部分指令到中,以便在SDRAM自刷新到sleep期间cpu能够正常运行 。3.让SDRAM进入self- mode 4.设置的SLEEP位让系统进入sleep mode

电源管理休眠流程梳理

文章插图
SDRAM的自刷新
下面图片对Linux &过程做了一个概述,读者可以顺着这个流程阅读内核源代码 。具体的说明,可以参考后面的代码分析 。
在用户空间执行如下操作:
echo "freeze" > /sys/power/stateecho "standby" > /sys/power/stateecho "mem" > /sys/power/state
会通过sysfs触发的执行,那么echo会底层的哪些动作呢?
先看看有一个
(state)的源码如下:
//位于\kernel\power\power.h#define power_attr(_name) \static struct kobj_attribute _name##_attr = { \.attr = {\.name = __stringify(_name), \.mode = 0644,\},\.show = _name##_show,\.store = _name##_store,\}===========================//将power_attr(state)代入,可知定义可一个结构体static struct kobj_attribute state_attr = { \.attr = {\.name = __stringify(_name), \.mode = 0644,\},\.show = state_show,\.store = state_store,\}
接着发现在结构体中
static struct attribute * g[] = {&state_attr.attr,//这了取到state_attr#ifdef CONFIG_PM_TRACE&pm_trace_attr.attr,&pm_trace_dev_match_attr.attr,#endif#ifdef CONFIG_PM_SLEEP&pm_async_attr.attr,&wakeup_count_attr.attr,#ifdef CONFIG_PM_AUTOSLEEP&autosleep_attr.attr,#endif#ifdef CONFIG_PM_WAKELOCKS&wake_lock_attr.attr,&wake_unlock_attr.attr,#endif#ifdef CONFIG_PM_DEBUG&pm_test_attr.attr,#endif#ifdef CONFIG_PM_SLEEP_DEBUG&pm_print_times_attr.attr,#endif#endif#ifdef CONFIG_FREEZER&pm_freeze_timeout_attr.attr,#endifNULL,};static struct attribute_group attr_group = {//attr_group中可以拿到attribute.attrs = g,};