总体的框架
wakeup events framework主要包括 wake lock, wakeup count, autosleep等机制系统在suspend过程中的时候,当wakeup事件产生的时候,不能进入suspend状态,wakeup event framework就是解决用户空间和内核空间的同步问题的,包含下面情况
1. 驱动处理过程中,不允许进入suspend
2. 后续需要处理的用户进程,不会获取到wakeup events
3. 正在后续处理的用户进程,处理过程中,系统不能进入suspend
总体框架如下:
wakeup events framework core就是linux关于wakeup event的核心框架,主要向驱动提供唤醒源注册,使能等接口。向上层提供上报,停止等接口,还有关于PM core的状态查询接口
sysfs文件
wake lock/unlock 提供给用户层面,可以阻止系统进入suspend的一个接口
wakeup count,用户上层用户查询wakeup event的一个接口
auto sleep就是设定系统没活动时,自动休眠的接口
关于wakeup source和wakeup event
1. 只有具有唤醒功能的设备才能作为wakeup source,具备唤醒功能的设备会被标识为唤醒能力,通过设备结构里面的can_wakeup标志标识,并且会在sysfs目录下有关于wakeup信息的文件存在
2. 具备唤醒功能的设备主要和 dev_pm_info结构有关
3. 一个wakeup source的设备,主要虚拟为结构体struct wakeup_source结构
View Code
关于wakeup event framework核心功能
1. __pm_stay_awake : wakeup source 切换为active状态的接口
2. __pm_relax: wakeup source 切换为disacTIve状态的接口
3. __pm_wakeup_event: 上边两个接口的结合体,引入了时间控制
对于驱动设备常用的接口:
View Code
wakeup count
主要用于解决system suspend 和system wakeup events之间的同步问题
wakeup count给上层提供了sysfs接口,给auto sleep提供了接口
实现的原理
1. 发生电源切换的实体先读取系统的wakeup count变量,并且告知wakeup events framework。
2. framework core保存这个变量到saved_count中
3. suspend过程中,有可能会发生wakeup events,所以某些时间点,会调用接口(pm_wakeup_pending),检查是否有wakeup需要处理
4. 如果有,代表读出来wakeup count 和saved_count不一样,这时需要终止suspend的过程
当调用类似 read(&cnt, “/sys/power/wakeup_count”); 的时候,系统最终会调用pm_get_wakeup_count
调用 write(cnt, “/sys/power/wakeup_count”)的时候,系统最终会调用 pm_save_wakeup_count
pm_get_wakeup_count的主要实现:
View Code
pm_save_wakeup_count的主要实现
View Code
前面的suspend过程中,最后阶段会调用suspend_enter函数:
View Code
里面调用的pm_wakeup_pending,主要是:
View Code
以上就是wakeup在用户层和suspend过程中的使用方式
wake_lock/wake_unlock
sysfs下的 /sys/power/wake_lock & /sys/power/wake_unlock
总体的框架
代码分析
wakeup_lock/wakeup_unlock的接口主要是下面的四个函数
View Code
其 中pm_show_wakelocks 表示
View Code
关于 pm_wake_lock 表示
View Code
关于pm_wake_unlock表示
View Code
wakelock的垃圾回收机制
主要考虑到wakeup events 建立,销毁,建立的过程太频繁,效率就会降低,所以引入了wakeuplock的垃圾回收机制
主要的原理是:
先保留一些非acTIve状态的wakelocks,等保留的wakelock的数量到达某一个定义的最大值时,则从尾部开始,依次取出wakelock,判断idle的时间,进行注销和释放memory资源
Auto Sleep
概念:
当系统没有了正在处理和新增的wakeup events时,就尝试suspend
总体的框架为:
1. sysfs关于autosleep的接口 /sys/power/autosleep
这个sysfs文件的读取 函数 autosleep_show:
View Code
2. 关于autosleep的初始化
关于 pm_autosleep_init
View Code
3. 设置 autosleep的状态
View Code
与之有关的函数pm_wakep_autosleep_enabled
View Code