Linux的电源管理架构
- 格式:docx
- 大小:30.71 KB
- 文档页数:16
Linux下PowerManagement开发总结本⽂作为⼀个提纲挈领的介绍性⽂档,后⾯会以此展开,逐渐丰富。
1. 前⾔在《》中介绍了PM开发的⼀般流程,重点是好的模型、简单有效的接⼝参数、可量化的测试环境以及可独性强的输出。
内核中功耗开发⽆论是新模型开发还是已有模型的调优,都需要了解现有的框架,遵循已有框架,简单有效的修改。
这就需要了解《》,关于Linux省电,从开机-->运⾏-->suspend-->关机这四种状态,开机/关机不太受关注,但是⾜够快也是省电的⼀种。
在进⼊细节之前,了解⼀下Linux中PM框架()有助于下⾯学习。
suspend()是⼀种深层次的省电,运⾏态情况下省电就⼋仙过海各显神通了。
如果将电流曲线以timeline形式画出,功耗就是曲线覆盖的阴影⾯积了。
⼀个任务来看,⾯积越⼩越好,当然时间也要满⾜需求。
suspend是系统级省电,涉及到各外设、Memory、CPU等等各种设备,总之是尽量关闭。
只保留不能断电部分⽤于唤醒系统,以及系统恢复,⽐如外设唤醒中断、RAM Retention等。
suspend本⾝也有不同种类,mem/standby/hibernation。
⼤部分使⽤的还是mem,即suspend to ram。
此时内核处于冻结状态(),系统tick停⽌,只有中断将其从睡眠唤醒才会去处理任务。
在系统运⾏过程中省电,则要复杂多变多了。
对于CPU在⼯作是根据负载动态调频调压(),没有⼯作处理的时候进⼊IDLE(),更进⼀步在多核情况下CPU都可以被热插拔();对于各种其他外设可以根据是否被使⽤⽽动态关闭()。
当然这些调节都要保证性能的输出()。
在系统运⾏过程中,⾼温可能导致设别损坏,因此根据温度来分配功耗也是⼀门必要⼿段()。
当然省电也离不开⼀些基础功能⽐如时钟控制()、供电开关()、电源域划分(),以及内核和应⽤都会⽤到的睡眠锁、唤醒源、唤醒事件都可以归到唤醒事件框架中()。
ACPI in Linux ── 传闻与事实Len BrownIntel Open Source Technology Centerlen.brown@Translated by Albcamus <albcamus@>概要:主流的Linux发型版从几年前就开始提供ACPI支持了,但直到今天,Linux社区中还存在着很多对ACPI的误解。
本文给出并澄清了关于ACPI in Linux的几个最主要的传闻。
1, 传闻: 在我的笔记本、PC机、服务器上,打开ACPI支持没有什么好处当用户不再以传统模式引导,而以ACPI模式引导,他们注意到的第一件事就是,电源按钮也被软件控制了。
在传统模式下,当按下电源按钮从而切断电源时,对计算机来说这是个物理的状态改变(断电);而在ACPI模式下,按下电源按钮会给OS发送中断,从而使OS能安全关机。
实际上,电源、休眠,和笔记本上盖合拢, 这些事件都被ACPI标准化了, OS可以把它们映射到自己的处理例程上。
除了把电源按钮的按下事件标准化之外, OS怎样用软件方式切断电源, 也被ACPI标准化了。
所以,由软件引发的关机,在Linux系统关闭之后,还可以切断电源;而在传统模式下,必须在Linux关闭后手工按电源按钮断电。
当在ACPI模式运行时, 用户会注意到电池的寿命延长了。
在今天的笔记本上,要想延长电池寿命, 一个重要的手段就是电源管理。
当处理器空闲,Linux内核的IDLE循环例程,将利用ACPI的 「CPU空闲的电源状态(CPU idle power states)」(C-states)来省电。
当处理器部分空闲,Linux的cpufreq子系统,将利用ACPI的「CPU的性能状态(performance states)」(P-states),降低CPU的电压和频率,以达到省电目的。
ACPI和传统模式的其他区别,可能受到用户所在的平台(译按,platform,可能专指BIOS实现)和GUI界面的影响,这些区别包括:电池低容量警报,发热控制(thermal control),以及调用suspend-to-dis k或suspend-to-R A M的能力等等。
arm,linux,电源管理解决方案篇一:ARM+Linux开发平台搭建详细步骤1、安装VMWare虚拟机(创建一台虚拟的电脑)并设置(1)用默认的步骤安装,并输入注册号(2)打开VMWare,点击文件-新建虚拟机接下去几步选择默认不停的点击“下一步”直到最后点击“完成”就行了2、在VMWare上定制安装Linux系统在虚拟机的CD中选择挂载硬盘上的Linux iso镜像文件点击开启此虚拟机,出现这个界面时,把鼠标点进虚拟机界面,选择第一项,并回车这里选择Skip这里选择忽略所有数据篇二:基于arm的智能家居系统方案基于ARM的智能家居系统设计方案1. 系统综述智能家居(Smart Home)是以住宅为平台,利用综合布线技术、网络通信技术、安全防范技术、自动控制技术、音视频技术将家居生活有关的设施集成,构建高效的住宅设施与家庭日程事务管理系统,以提升家居安全性、便利性、舒适性、艺术性,并实现环保节能的居住环境。
衡量一个智能家居系统的成功与否,并非仅仅取决于智能化系统的多少、系统的先进性或集成度,而是取决于系统的设计和配置是否经济合理并且系统能否成功运行,系统的使用、管理和维护是否方便,系统或产品的技术是否成熟适用,换句话说,就是如何以最少的投入、最简便的实现途径来换取最大的功效,实现便捷高质量的生活。
智能家居通常包括以下子系统:访问/控制系统通过电脑、手持终端等设备了解家中状况,对设备进行控制。
门禁系统门禁系统主要包括以下功能,室外监控功能:当门口有异响自动提示,能在家中或远程看到外面情况;拍照存档功能:当家中没人且有人按动门铃,便自动拍照存储,方面房屋主人查询;可视对讲功能:有客来访,可自由通话,并能看到外面情况,并能控制门锁的打开关闭;远程开锁功能:可以通过Internet 网,在任何地方开启家里的门锁。
视频监控系统视频监控的基本功能主要有:远程监控:可以进行实时本地和远程网络监控;远程控制:可以实现远程对设备的各种控制,可以对图像质量,分辨率,图像缩放进行操作,可以对云台的移动方向进行控制;视频存储:能够将视频数据本地存储,能够在任何时候对这些数据进行回放;移动侦测:布防后能够发现移动的物体并报警。
linux驱动程序之电源管理之Run-time PM 详解(4)linux驱动程序之电源管理之Run-time PM 详解(4)Run-time PM.每个device或者bus都会向run-time PM core注册3个callbackstruct dev_pm_ops {...int (*runtime_suspend)(struct device *dev);int (*runtime_resume)(struct device *dev);int (*runtime_idle)(struct device *dev);...};每个device或者bus都会有2个计数器,一个是device的usage counter,一个是device的active状态的children个数。
当这个device的两个counter都减少为0的时候。
run-time PM core就会去调用runtime_idle函数,但是这里的idle函数可不是当前device的idle函数。
代码如下:if (dev->bus && dev->bus->pm&& dev->bus->pm->runtime_idle) {spin_unlock_irq(&dev->power.lock);dev->bus->pm->runtime_idle(dev);spin_lock_irq(&dev->power.lock);} else if (dev->type && dev->type->pm && dev->type->pm->runtime_idle) { spin_unlock_irq(&dev->power.lock);dev->type->pm->runtime_idle(dev);spin_lock_irq(&dev->power.lock);} else if (dev->class && dev->class->pm && dev->class->pm->runtime_idle) { spin_unlock_irq(&dev->power.lock);dev->class->pm->runtime_idle(dev);spin_lock_irq(&dev->power.lock);}按照dev->bus, dev->type, dev->class的顺序去调用。
Linux的电源管理架构Linux的源代码里,大部分都属于设备驱动程序的代码,因此,大多数电源管理(PM)的代码也是存在于驱动程序当中。
很多驱动程序可能只做了少量的工作,另外一些,例如使用电池供电的硬件平台(移动电话等)则会在电源管理上做了大量的工作。
这份文档对驱动程序如何与系统的电源管理部分交互做了一个大概的描述,尤其是关联到驱动程序核心中的模型和接口的共享,建议从事驱动程序相关领域的人通过本文档可以了解相关的背景知识。
设备电源管理的两种模型===================================驱动程序可以使用其中一种模型来使设备进入低功耗状态:1. 系统睡眠模型:驱动程序作为一部分,跟随系统级别的低功耗状态,就像”suspend”(也叫做”suspend-to-RAM”),或者对于有硬盘的系统,可以进入”hibernation”(也叫做”suspend-to-disk”)。
这种情况下,驱动程序,总线,设备类驱动一起,通过各种特定于设备的suspend和resume 方法,清晰地关闭硬件设备和各个软件子系统,然后在数据不被丢失的情况下重新激活硬件设备。
有些驱动程序可以管理硬件的唤醒事件,这些事件可以让系统离开低功耗状态。
这一特性可以通过相应的/sys/devices/…/power /wakeup文件来开启和关闭(对于Ethernet驱动程序,ethtool通过ioctl接口达到同样的目的);使能该功能可能会导致额外的功耗,但他让整个系统有更多的机会进入低功耗状态。
2. Runtime 电源管理模型:这种模型允许设备在系统运行阶段进入低功耗状态,原则上,他可以独立于其他的电源管理活动。
不过,通常设备之间不能单独进行控制(例如,父设备不能进入suspend,除非他的所有子设备已经进入suspend状态)。
此外,依据不同的总线类型,可能必须做出一些特别的操作来达到目的。
如果设备在系统运行阶段进入了低功耗状态,在系统级别的电源状态迁移时(suspend或hibernation)就必须做出特别的处理。
正因为这个原因,不仅仅设备驱动程序本身,相应的子系统(bus type,device type,device class)驱动程序和电源管理核心也会被卷入到rumtime电源管理的工作中来。
比如当系统睡眠时,以上的各模块必须互相合作来实现各种多样的suspend和resume方法,以便让硬件进入低功耗状态,唤醒后继续提供服务而不丢失数据。
对于低功耗状态的定义,我们没有太多可以说的,因为他们通常特定于系统,甚至特定于某个设备。
如果在系统运行状态,足够多的设备进入了低功耗状态,这时的效果其实和进入了系统级别的低功耗状态非常相像。
这样一些驱动程序可以利用rumtime电源管理让系统进入一种类似深度省电的状态。
大多数进入suspend状态的设备会停止所有的I/O操作:不会有DMA或者IRQ请求(需要唤醒系统的除外),不会有数据的读写,不再接受上层驱动的请求。
这对于不同的总线和平台会有不同的要求。
关于硬件唤醒事件的一些例子:由RTC发起的闹钟,网络数据包的到达,键盘或者鼠标的活动,媒体的插入或移除(PCMCIA,MMC/SD,USB,等等)。
进入系统睡眠状态的接口=================================================== 内核为各个子系统(bus type,device type, device class)和驱动程序提供了相应的编程接口,以便它们参与它们所关心的设备的电源管理。
这些接口覆盖了系统级别的睡眠和runtime级别的管理。
设备电源管理操作=================================================== 子系统和驱动程序的设备电源管理操作,都定义在dev_pm_ops结构中:1 2 3 4 5 6 7 8 9101112 struct dev_pm_ops {int(*prepare)(struct device *dev); void(*complete)(struct device *dev); int(*suspend)(struct device *dev); int(*resume)(struct device *dev);int(*freeze)(struct device *dev);13141516171819202122232425262728293031323334353637int(*thaw)(struct device *dev);int(*poweroff)(struct device *dev);int(*restore)(struct device *dev);int(*suspend_noirq)(struct device *dev); int(*resume_noirq)(struct device *dev);int(*freeze_noirq)(struct device *dev);int(*thaw_noirq)(struct device *dev);int(*poweroff_noirq)(struct device *dev); int(*restore_noirq)(struct device *dev); int(*runtime_suspend)(struct device *dev); int(*runtime_resume)(struct device *dev); int(*runtime_idle)(struct device *dev); };这个结构在include/linux/pm.h中定义,它们的作用将会在接下来进行描述。
现在,我们只要记住,最后三个方法是专门用于rumtime pm的,其他的则用于系统级别的电源状态迁移。
某些子系统中,依然存在所谓“过时的”或“传统的”电源管理操作接口,这种方式不会使用到dev_pm_ops结构,而且只适用于系统级别的电源管理方法,这边文章里将不会对它进行说明,如果要了解的话请直接查看内核的源代码。
子系统级别(Subsystem-Level)方法————————————————设备进入suspend和resume的关键方法在bus_type结构、device_type结构和class 结构的pm成员中,他是一个dev_pm_ops结构的指针。
多数情况下,这些都是那些具体总线的体系结构(例如PCI或USB或某个设备类别和设备类)的维护者们来关注的部分。
总线驱动会适当地实现这些方法以供硬件和驱动程序使用它们;因为PCI和USB有不同的工作方式。
只有少数人会编写subsystem-level的驱动程序;大多数的设备驱动程序是建立在各种特定总线架构的代码之上。
有关这些调用,稍后会进行更详尽的描述;它们将会顺着父子形式的设备模型树,一个设备一个设备地被调用。
/sys/devices/…/power/wakeup files————————————————-设备模型中的所有设备都有两个标志来控制唤醒事件(可使得设备或系统退出低功耗状态)。
设两个标志位由总线或者设备驱动用device_set_wakeup_capable()和device_set_wakeup_enable()来初始化,它们在include/linux/pm_wakeup.h中定义。
“can_wakeup”标志表示设备(或驱动)物理上支持唤醒事件,device_set_wakeup_capable()函数会影响该标志。
”should_wakeup”标志控制设备是否应该尝试启用他的唤醒机制。
device_set_wakeup_enable()会影响该标志。
大部分的驱动程序不会主动修改它们的值。
大多数设备的should_wakeup的初始值都被设为false,也有例外,比如电源键、键盘和由ethtool设置了wake-on-LAN功能的网卡。
设备是否有能力发出唤醒事件是一个硬件的问题,内核只是负责持续地跟踪这些事件的发生。
另外一方面,一个有唤醒能力的设备是否应该发起唤醒事件则是一个策略问题,它是由用户空间通过sysfs的属性文件(power/wakeup)进行管理的。
用户空间可以写入”enabled”,或”disabled”来设置或清除shoule_wakeup标志,相应地,读取该文件时,如果can_wakeup标志是true则返回对应的字符串,如果can_wakeup是false,则返回一个空字符串,以此来表明设备不支持唤醒事件。
(需要注意的是,尽管返回空字符串,该文件的写入依然会影响should_wakeup标志)只有当这两个标志都为true时,device_may_wakeup()函数才会返回true。
当系统迁移到睡眠状态时,驱动程序应该在让设备进入低功耗状态前通过这一函数检查,确定是否启用唤醒机制。
不过,在rumtime电源管理模式下,不管设备和驱动程序是否都支持,也不管should_wakeup标志是否设置,唤醒事件都会被使能。
/sys/devices/…/power/control files————————————————设备模型中的每个设备都有一个标志位来控制它是否属于runtime电源管理模式。
这个叫runtime_auto的标志由bus type(或其他子系统)用pm_rumtime_allow()或者是pm_rumtime_forbid()来初始化。
默认值是允许rumtimepm的。
用户空间可以通过向设备的sysfs文件power/control写入”on”或者”auto”来修改该标志位。
写入”auto”相当于调用了pm_rumtime_allow(),允许设备由驱动程序进行rumtimepm。
写入”on”相当于调用pm_rumtime_forbid(),标志位被清除,设备将会从低功耗状态返回全功率状态,并且阻止设备进行runtime电源管理。
用户空间也可以读取该文件来检查runtime_auto的当前值。
设备的runtime_auto标志不会影响系统级别电源状态的迁移。
特别注意的是,尽管runtime_auto标志被清除,当系统级别的电源状态迁移到睡眠状态时,设备也会被带入低功耗状态。
关于runtime电源管理架构的更多信息,请参看Documentation/power/runtime_pm.txt。
调用驱动程序进入或退出系统睡眠状态==================================当系统进入睡眠状态,系统会要求设备驱动程序让设备进入兼容于目标系统的一种状态来挂起(suspend)设备。