Linux电源管理介绍-1

Categories Linux电源管理
Linux电源管理介绍-1

前言

为了节省功耗,需要让系统在不需要工作的时候尽可能的休眠(甚至断电)。同时,为了不影响到系统功能的正常运作,又必须保证休眠不能打断正在进行的重要事务,且能在适时还原回来。因此,一个高效运行的Low Power框架必不可少。 Linux电源管理介绍-1 本文以Linux 4.4内核为基础,介绍Linux的Low Power框架。

架构

Linux的电源管理架构如下图。首先内核态导出了一些sysfs节点,用来给用户空间态作电源管理控制:
  1. /sys/power/autosleep : 主要用于控制是否开启内核自动休眠,之后会有章节介绍
  2. /sys/power/state:直接控制进入休眠(有多种state,后边会看到)
  3. /sys/power/wake_lock&wake_unlock:拿Wake lock和释放Wake lock,用于避免正在处理重要事务时系统进入休眠
                                                      +-----------+
                                                      |应 用 程 序|
             +------------------+                     +-----+-----+
             |电 源 管 理 程 序  +---------+                 |
             +-----+------------+         |                 |
                   |                      |                 |
                   |                      |                 |
用 户 空 间 态      v                      v                 v
            /sys/power/autosleep   /sys/power/state  /sys/power/wake_lock&wake_unlock
+------------------+----------------------+-----------------+---------------------------
                   |                      |                 |
内 核 态           |                      |                 |
                   v                      v                 v 
             +-----+----------------------+-----------------+---+
             |                   sysfs                          |
             +--------------------------------------------------+
           kernel/power/main.c                              |
               +                                            |
   +--------------------------------------------------------|-------------------------+
   |           |                                            v        电 源 管 理 框 架 |
   |           |                   +--------------------------------+                 |
   |           v                   |                                |                 |
   |  +----------+                 | Wakeup Source                  |                 |
   |  |autosleep | <---------------+                                |                 |
   |  +----------+                 +----------------------------^---+                 |
   |kernel/power/autosleep.c                                    |                     |
   |        |                                             +-----+-----------+         |
   |        |                                             |                 |         |
   |        |-------------------------------------------->|  驱 动 程 序     |         |
   |        v                                             |                 |         |
   |  +-----+--------+                                    +-----------------+         |
   |  | 平 台 相 关   |                                                                |
   |  | 睡 眠 代 码   |                                                                |
   |  +--------------+                                                                |
   |                                                                                  |
   +----------------------------------------------------------------------------------+
   
内核态是实现电源管理的核心代码,主要分为如下几大功能模块:
  1. 提供用户空间态操作的SYSFS节点操作
  2. 记录系统中拿睡眠锁的Wake Source
  3. 内核自动休眠例程Autosleep
  4. 平台相关睡眠(及唤醒)代码
  5. 各个硬件驱动程序:
    1. 注册硬件相关的睡眠及唤醒代码,保证经过一次断电恢复后的硬件仍能正常工作。
    2. 根据应用需要,拿Wake Lock和释放Wake Lock,保证硬件驱动可以正常工作。

数据和变量

在对电源管理的系统流程进行介绍之前,先对电源管理的一些必要的数据结构和关键变量进行分析。

wakeup_source/wakeup_sources

wakeup_source名字具有一定迷惑性,乍一看像是触发系统从睡眠中唤醒的唤醒源,实则不然。这个结构体是用来描述所有“阻挡”系统进入休眠的对象,即向电源管理模块拿wakelock用的。而wakeup_sources则是记录系统中所有wakeup_source的链表。
struct wakeup_source {
	const char 		*name;            //名称
	struct list_head	entry;             //挂入wakeup_sources链表的表头
	spinlock_t		lock;              //自旋锁保护该wakeup_source内容的修改
	struct wake_irq		*wakeirq;
	struct timer_list	timer;             //wakeup source相关的定时器
	unsigned long		timer_expires;  //超时时间,也就是wake_lock_timeout()里面的时间参数,超时后会执行deactivate函数
	ktime_t total_time;                  //该wakeup source被激活的总时间
	ktime_t max_time;                  
	ktime_t last_time;                  //该wakeup source上次被访问的时间
	ktime_t start_prevent_time;           //上次因wakeup source导致系统无法休眠的时间
	ktime_t prevent_sleep_time;          //’阻止系统休眠的时长
	unsigned long		event_count;   //产生事件数
	unsigned long		active_count;   //激活次数
	unsigned long		relax_count;    //释放次数
	unsigned long		expire_count;   //Wakeup source的超时次数
	unsigned long		wakeup_count;  //该source阻止系统休眠的次数
	bool			active:1;               //是否激活状态
	bool			autosleep_enabled:1;    //系统是否开启autosleep
};

suspend_state_t

描述系统休眠几种不同状态,按照睡眠从浅入深分别是:
  1. On:未休眠
  2. Freeze:轻量级的休眠状态。
  3. Standby:中等休眠状态,CPU没有挂起(Memory和CPU带电)
  4. Mem:深度休眠,系统及设备状态挂起到Memory(Memory仍然带电),CPU不再工作(少数外围设备工作)。
typedefint __bitwise suspend_state_t;

#define PM_SUSPEND_ON         ((__force suspend_state_t) 0)

#define PM_SUSPEND_FREEZE   ((__force suspend_state_t) 1)

#define PM_SUSPEND_STANDBY      ((__force suspend_state_t) 2)

#define PM_SUSPEND_MEM             ((__force suspend_state_t) 3)

#define PM_SUSPEND_MIN        PM_SUSPEND_FREEZE

#define PM_SUSPEND_MAX              ((__force suspend_state_t) 4)

combined_event_count

用于记录系统中已注册的wakeup事件数量和正在生效的wakeup事件数量。这两个变量需要一起更新的,所以用combined_event_count一个变量来记录。高16 bit存放正在生效的wakeup事件数量,低16bit存放wakeup事件总数量。

后续章节预告

Autosleep及power状态设置流程 Autosleep代码分析 Wakelock拿锁与释放锁流程分析

猜你喜歡

Linux虚拟文件系统(3)– VFS系统调用之Mount... 前言 前2章分别介绍了VFS的基本数据结构和初始化流程。本章介绍VFS文件系统的使用。文件系统使用大多是从应用层系统调用开始的,下表是对文件系统系统调用的一个整理。 MOUNT 文件系统可以使用的前提是系统挂载(Mount)成功。初始化过程中,Linux会预先挂载一些支撑系统运行的特殊文件系统,...
Linux中断(1) 前言 之前LINUX中断学习笔记(1)和LINUX中断学习笔记(2)介绍了Linux中断的一些基础知识,但是不够深入。最近公司所在团队逐渐在往内核进一步深入,仅有前边文章的浅显知识已不足以覆盖工作的需求,也无法和部门同事做深入的技术讨论。本文是在工作之余,进行代码的研究和资料的查找,希望可以...
Linux虚拟文件系统(1) VFS简介 说明:本系列文章均以Linux 4.4为原型进行分析 Linux将系统中很多资源都抽象成文件,如Socket、设备节点、以及内存。可以如此做,归功于Linux操作系统的虚拟文件系统(VFS)。 有了VFS,无论底层文件系统格式是FAT、ext格式甚至是内存,(一般情况下)上层应用无论...
Linux內存初始化过程(ZZ) Linux内存管理是个庞大的课题,让多少工程师本文为之困惑。本文为对Linux内存初始化解释的比较清楚的一篇文章,转载自Link,欢迎交流 前言 一直以来,我都非常着迷于两种电影拍摄手法:一种是慢镜头,将每一个细节全方位的展现给观众。另外一种就是快镜头,多半是反应一个时代的变迁,从...
Linux中断学习笔记(1) 什么是中断 CPU获取外设状态变化有两种方式: Polling:不断跟外设询问它的状态 当外设状态变化后主动通知CPU CPU要负责处理系统中各种各样的业务,如果频繁地轮询外设状态,必然会对整个系统的吞吐量产生影响,影响操作系统的正常运作。 中断便是外设通知CPU其状态变化...

版权声明:本站文章除非特别声明,均为L&H原创。允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。

本文链接:Linux电源管理介绍-1 @ L&H site


留个言吧大佬

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据