从设备驱动的角度看电源管理

【Android休眠】之kernel电源管理 关于kernel的电源管理部分,有一位首席PM专家的博客写得相当好,为方便故,分享一下。 阅读详情
1. 前言

相信工作稍微久一点的linux驱动工程师都深有体会:

在旧时光里,实现某一个设备的电源管理功能,是非常简单的一件事情。大多数设备都被抽象为platform设备,driver只需要提供suspend/resume/shutdown等回调函数,并注册到kernel即可。kernel会在系统电源状态切换的过程中,调用driver提供的回调函数,切换设备的电源状态。

但是在新时代中,设备电源管理有关的操作,被统一封装在struct dev_pm_ops结构中了。该结构包含20多个回调函数,再加上复杂的电源管理机制(常规的suspend/resume、runtime PM等等),使设备驱动的电源管理工作不再那么单纯,工程师(如蜗蜗自己)的思路也不再特别清晰。

因此本文希望能以单一设备的电源管理为出发点,结合kernel的电源管理机制,介绍怎样在设备驱动中添加电源管理功能,并分析设备电源状态切换和系统电源状态切换的关系。

另外,我们在电源管理系列文章中,介绍了很多的电源管理机制,如generic PM、wakeup event framework、wakelock、autosleep、runtime PM、PM domain、等等,本文也算是对它们的梳理和总结。

2. 功能描述

设备的电源状态切换,和系统电源状态切换基本保持一致(runtime PM除外),切换的场景如下:

1)系统reboot的过程,包括halt、power off、restart等(可参考“Linux电源管理(3)_Generic PM之Reboot过程”),要求设备进入shutdown状态,以避免意外产生。

2)系统suspend/resume的过程(可参考“Linux电源管理(6)_Generic PM之Suspend功能”),要求设备也同步suspend/resume。

3)系统hibernate及恢复的过程,要求设备在suspend/resume的基础上,增加poweroff的动作。

4)runtime PM过程(可参考“Linux电源管理(11)_Runtime PM之功能描述”),要求设备在引用计数为0时suspend甚至power off,并在引用计数大于0时power on以及resume。

旧有的电源管理框架中,通过bus、class、device_driver等结构体中的shutdown、suspend、resume三个回调函数,就可以实现上面处runtime PM之外的所有功能。但是在新框架中,特别是引入struct dev_pm_ops结构之后,其中的suspend/resume就不再推荐使用了。

不过,对有些设备来说,例如platform device,如果电源管理需求不是很复杂,driver工程师仍然可以使用旧的方法实现,kernel会自动帮忙转换为新的方式。但是,如果有更多需求,就不得不面对struct dev_pm_ops了。下面将会详细说明。

3. 数据结构回顾

正式开始之前,我们先回顾一下设备电源管理有关的数据结构。它们大多都在之前的文章中介绍过了,本文放在一起,权当一个总结。

3.1 .shutdown回调函数以及使用方法

由于reboot过程是相对独立和稳定的,且该过程依赖于设备的.shutdown回调函数,这里把它独立出来,单独描述,后面就不再涉及了。

.shutdown回调函数存在于两个数据结构中:struct device_driver和struct bus_type,在系统reboot的过程中被调用,负责关闭设备。设备驱动可以根据需要,实现其中的一个。我们以一个普通的platform设备为例,介绍这个过程。

1)定义一个platform_driver,并实现其.shutdown回调,然后调用platform_driver_register将它注册到kernel中

 1: static void foo_shutdown(struct platform_device *pdev)
 2: {
         
 3: ...
 4: } 
 5: static platform_driver foo_pdrv = 
 6: {
         
 7: .shutdown = foo_shutdown,
 8: ...
 9: };

2)platform_driver_register时,会把struct device_driver变量的shutdown函数,替换为platform设备特有的shutdown函数(platform_drv_shutdown),并调用driver_register将device_driver注册到kernel

 1: int __platform_driver_register(struct platform_driver *drv,
 2: struct module *owner)
 3: {
         
 4: …
 5:  
 6: if (drv->shutdown)
 7: drv->driver.shutdown = platform_drv_shutdown; 
 8:  
 9: return driver_register(&drv->driver);
 10: }

3)系统reboot的过程中,会调用每个设备的shutdown函数。对这里的foo_pdrv而言,会先调用platform_drv_shutdown,它继续调用foo_shutdown。

3.2 legacy的不再使用的.suspend/.resume

旧的suspend/resume操作,主要依赖struct device_driver、struct class、struct bus_type等结构中的suspend和resume回调函数,其使用方式和上面的.shutdown几乎完全一样。以platform设备为例,只需多定义两个函数即可,如下:

 1: static int foo_suspend(struct platform_device *pdev, pm_message_t state)
 2: {
         
 3: ...
 4: }
 5:  
 6: static int foo_resume(struct platform_device *pdev)
 7: {
         
 8: ...
 9: }
 10:  
 11: static void foo_shutdown(struct platform_device *pdev)
 12: {
         
 13: ...
 14: }
 15:  
 16: static platform_driver foo_pdrv = {
         
 17: .suspend = foo_suspend,
 18: .resume = foo_resume,
 19: .shutdown = foo_shutdown,
 20: ...
 21: };

在较新的kernel中,已经不再建议使用这些回调函数了,但对platform设备来说,如果场景比较简单,可以照旧使用上面的实现方法,platform.c会自动帮忙转换为struct dev_pm_ops回调,具体请参考后面描述。

3.3 struct dev_pm_ops结构

struct dev_pm_ops是设备电源管理的核心数据结构,用于封装和设备电源管理有关的所有操作。

 1: struct dev_pm_ops {
         
 2: int (*prepare)(struct device *dev);
 3: void (*complete)(struct device *dev);
 4: int (*suspend)(struct device *dev);
 5: int (*resume)(struct device *dev);
 6: int (*freeze)(struct device *dev);
 7: int (*thaw)(struct device *dev);
 8: int (*poweroff)(struct device *dev);
 9: int (*restore)(struct device *dev);
 10: int (*suspend_late)(struct device *dev);
 11: int (*resume_early)(struct device *dev);
 12: int (*freeze_late)(struct device *dev);
 13: int (*thaw_early)(struct device *dev);
 14: int (*poweroff_late)(struct device *dev);
 15: int (*restore_early)(struct device *dev);
 16: int (*suspend_noirq)(struct device *dev);
 17: int (*resume_noirq)(struct device *dev);
 18: int (*freeze_noirq)(struct device *dev);
 19: int (*thaw_noirq)(struct device *dev);
 20: int (*poweroff_noirq)(struct device *dev);
 21: int (*restore_noirq)(struct device *dev);
 22: int (*runtime_suspend)(struct device *dev);
 23: int (*runtime_resume)(struct device *dev);
 24: int (*runtime_idle)(struct device *dev);
 25: };

该结构基本上是个大杀器了,该有的东西都有,主要分为几类:

传统suspend的常规路径,prepare/complete、suspend/resume、freeze/thaw、poweroff、restore;

传统suspend的特殊路径,early/late、noirq;

runtime PM,suspend/resume/idle。

各类driver需要做的事情很单纯,实现这些回调函数,并保存在合适的位置,我们接着往下看。

3.4 struct dev_pm_ops的位置

 1: struct device {
         
 2: ...
 3: struct dev_pm_domain *pm_domain;
 4: const struct device_type *type;
 5: struct class *class;
 6: struct bus_type *bus;
 7: struct device_driver *driver; 
 8: ...
 9: };
 10:  
 11:  
 12:  
 13: struct dev_pm_domain {
         
 14: struct dev_pm_ops ops; 
 15: ...
 16: };
 17:  
 18: struct device_type {
         
 19: ...
 20: const struct dev_pm_ops *pm;
 21: };
 22:  
 23: struct class {
         
 24: ...
 25: const struct dev_pm_ops *pm;
 26: ...
 27: };
 28:  
 29: struct bus_type {
         
 30: ...
 31: const struct dev_pm_ops *pm;
 32: ...
 33: };
 34:  
 35: struct device_driver {
         
 36: ...
 37: const struct dev_pm_ops *pm;
 38: ...
 39: };

可谓是狡兔多窟,struct dev_pm_ops存在于struct device、struct device_type、struct class、struct bus_type、struct device_driver等所有和设备模型有关的实体中。

由之前的文章可知,kernel在电源管理的过程中,会按照如下优先级调用dev_pm_ops中的回调函数,以命令设备实现相应的状态切换:

dev->pm_domain->ops、dev->type->pm、dev->class->pm、dev->bus->pm、dev->driver->pm。

因此,设备driver需要做的事情也很单纯,实现这些回调函数,并保存在合适的位置。但这么多位置,到底怎么实现呢?我们接着分析。

4. struct dev_pm_ops的实现

由之前的描述可知,系统在电源状态切换时,会按照一定的优先顺序,调用设备的pm ops。所谓的优先顺序,是指:只要存在优先级高的ops(如dev->pm_domain->ops),则调用该ops,否则继续查找下一个优先级。因此,设备驱动可以根据该设备的实际情况,在指定层次上,实现dev pm ops,以达到电源管理的目的。

dev pm ops可以存在于pm domain、device type、class、bus、device driver任何一个地方,本章以pm domain、bus和device driver三个典型场景为例,介绍设备电源管理的实现思路。

注1:为了方便,我会以struct dev_pm_ops中的.suspend函数为例,其它类似。

4.1 pm domain

当一个设备属于某个pm domain时(具体可参考“Linux PM domain framework(1)_概述和使用流程”),系统suspend的过程中,会直接调用pm_domain->ops.suspend。而由pm_genpd_init可知,pm_domain->ops.suspend由pm_genpd_suspend实现:

genpd->domain.ops.suspend = pm_genpd_suspend;

该接口的实现为:

 1: static int pm_genpd_suspend(struct device *dev)
 2: {
         
 3: struct generic_pm_domain *genpd;
 4:  
 5: dev_dbg(dev, "%s()\n", __func__);
 6:  
 7: genpd = dev_to_genpd(dev);
 8: if (IS_ERR(genpd))
 9: return -EINVAL;
 10:  
 11: return genpd->suspend_power_off ? 0 : pm_generic_suspend(dev);
 12: }

最终会调用pm_generic_suspend,由“Linux电源管理(4)_Power Management Interface”的描述可知,该接口最终会调用该设备驱动的suspend接口(如果有的话),即:dev->driver->pm->suspend。

看来是空欢喜一场,本以为pm domain帮忙做了,设备驱动就可以偷一点懒,谁知道绕来绕去,又把球踢给了设备驱动!让我们思考一下其中的原因:

1)suspend时,设备的动作到底是什么,只有设备驱动最清楚,所以,把事情交给driver做,是合理的。

2)那么,为什么要经过pm domain这一层呢?直接调用driver的suspend不就可以了吗?因为需要在suspend前,由pm domain做一些处理,例如判断该设备是否已经掉电(如果掉电了,就不能再suspend了,否则可能有非预期的结果),等等。

4.2 dev->bus->pm

来看另一个例子,如果该设备所在的bus提供了dev_pm_ops呢?开始之前,我们再强调一下这个事实:suspend时,设备的动作到底是什么,只有设备驱动最清楚,所以,把事情交给driver做,是合理的。所以相信大家猜到了,就算bus有suspend回调,最终还是要绕到设备驱动的suspend接口上。

我们以platform bus为例,原因是这个bus很简单,而且我们平时需要面对的大多数设备都是platform设备。

在drivers/base/platform.c中,platform bus是这样定义的:

 1: struct bus_type platform_bus_type = {
         
 2: .name = "platform",
 3: .dev_groups = platform_dev_groups,
 4: .match = platform_match,
 5: .uevent = platform_uevent,
 6: .pm = &platform_dev_pm_ops,
 7: };

接着看一下platform_dev_pm_ops:

 1: static const struct dev_pm_ops platform_dev_pm_ops = {
         
 2: .runtime_suspend = pm_generic_runtime_suspend,
 3: .runtime_resume = pm_generic_runtime_resume,
 4: USE_PLATFORM_PM_SLEEP_OPS
 5: };

哦,有runtime PM相关的两个回调,有一个宏定义:USE_PLATFORM_PM_SLEEP_OPS,该宏定义指定了dev_pm_ops的suspend回调为platform_pm_suspend(其它的类似)。该接口的实现如下:

 1: int platform_pm_suspend(struct device *dev)
 2: {
         
 3: struct device_driver *drv = dev->driver;
 4: int ret = 0;
 5:  
 6: if (!drv)
 7: return 0;
 8:  
 9: if (drv->pm) {
         
 10: if (drv->pm->suspend)
 11: ret = drv->pm->suspend(dev);
 12: } else {
         
 13: ret = platform_legacy_suspend(dev, PMSG_SUSPEND);
 14: }
 15:  
 16: return ret;
 17: }

原来如此,如果该设备的驱动提供了dev_pm_ops指针,调用相应的suspend接口。否则,调用legacy的接口(即pdrv->suspend)。再对比3.1,3.2小节的描述,是不是豁然开朗了?

另外,由于platform bus是一个虚拟的bus,不需要其它的动作。对于一些物理bus,可以在bus的suspend接口中,实现bus有关的suspend操作。这就是设备模型的魅力所在。

4.3 dev->driver->pm

无论怎样,如果一个设备需要在suspend时有一些动作,就一定要在设备驱动中实现suspend,那样怎么实现呢?定义一个struct dev_pm_ops变量,并实现设备所需的回调函数,在driver注册之前,保存在driver->pm指针中即可。

那有什么变化?大多数的设备是platform设备,我们也可以用旧的方式(3.1,3.2小节),实现platform driver的suspend/resume。但是,在新时代,不建议这样做了,注意platform_legacy_suspend中的legacy字样哦,遗产、遗留下来的,只是为了兼容。如果我们新写driver,就用新的方式好了。

5. 设备电源状态的切换过程

本来还想梳理一下系统电源切换的过程中,driver是怎么处理的。但经过上面的分析,传统的suspend/resume已经很明确了,无非是按照pm_domain—>device driver或者class—>device driver或者bus—>device driver的顺序,调用相应的回调函数。而runtime PM,还是放到runtime PM的分析文章里比较好。所以本文就结束好了。

32、Linux内核电源管理:从基础到实践 本文深入探讨了Linux内核的电源管理机制,涵盖运行时恢复规则、电源域的概念、系统挂起与恢复流程、设备驱动的电源管理实现以及唤醒源的工作原理。通过详细的步骤解析和代码示例,帮助开发者理解和应用Linux电源管理的核心技术,优化系统功耗与性能。 阅读详情

相关推荐

32、Linux内核电源管理全解析

本文深入解析了Linux内核的电源管理机制,涵盖电源管理基础规则、电源域(Genpd)概念、系统挂起与恢复序列、系统睡眠功能的实现方式,以及如何将设备配置为系统唤醒源。内容还涉及关键数据结构如 `struct dev_pm_ops` 和 `struct wakeup_source` 的使用,以及相关回调函数、宏和驱动示例,帮助开发者理解和应用Linux电源管理的核心原理与实践方法。

sat99的博客 99

Linux电源管理(14)_从设备驱动的角度看电源管理

相信工作稍微久一点的linux驱动工程师都深有体会:在旧时光里,实现某一个设备的电源管理功能,是非常简单的一件事情。大多数设备都被抽象为platform设备,driver只需要提供suspend/resume/shutdown等回调函数,并注册到kernel即可。kernel会在系统电源状态切换的过程中,调用driver提供的回调函数,切换设备的电源状态。但是在新时代中,设备电源管理有关的操作,被统一封装在struct dev_pm_ops结构中了。

苏法迪的专栏 1122

32、Linux内核电源管理详解

本文详细解析了Linux内核中的电源管理机制,涵盖运行时恢复规则、电源域概念、系统挂起与恢复流程、系统睡眠功能的实现,以及设备如何成为系统唤醒源。通过深入分析唤醒源的状态转换、定时器的作用及在不同应用场景下的电源管理策略,为开发者提供了电源管理性能优化与调试的实用方法。内容适用于希望深入了解Linux电源管理机制、优化系统功耗的嵌入式及系统开发人员。

egg99的博客 140

Linux电源管理(12)_从设备驱动的角度看电源管理

相信工作稍微久一点的linux驱动工程师都深有体会:在旧时光里,实现某一个设备的电源管理功能,是非常简单的一件事情。大多数设备都被抽象为platform设备,driver只需要提供suspend/resume/shutdown等回调函数,并注册到kernel即可。kernel会在系统电源状态切换的过程中,调用driver提供的回调函数,切换设备的电源状态。但是在新时代中,设备电源管理有关的操作,被统一封装在struct dev_pm_ops结构中了。

weixin_41028159的博客 703

31、Linux系统电源管理与唤醒机制详解

本文深入解析了Linux系统的电源管理与唤醒机制,涵盖电源域概念、系统挂起与恢复的完整流程、设备睡眠功能的实现方法,以及如何将设备配置为系统唤醒源。通过详细分析struct dev_pm_ops回调机制、wakeup_source结构体和实际驱动代码示例,帮助开发者理解底层PM核心工作原理。文章还提供了唤醒事件处理流程图、优化建议及常见问题解决方案,全面指导Linux平台下的低功耗设计与调试。

alice7model的博客 125

展会客流统计的客流统计系统,WiFi客流每时每客

一般展会的举行时间都在3-7天之间,展会作为市场部门一项重要工作,一直以来没有一项有效的工具能够提供数据支持。 展会最重要的是通过活动和产品来吸引参展者的参观,如何统计展会期间的客流量呢?如何通过将数据转化成为活动数据的支撑呢? 目前成熟的解决方案有,视频客流统计、WiFi客流统计、红外线客流统计等方式。由于展会通常的时间都比较短,视频、红外线客流统计采购及安装价格都比较高,需

isentech的博客 3994

Linux功耗管理(25_Linux电源管理(14)_从设备驱动的角度看电源管理)

1. 前言 相信工作稍微久一点的linux驱动工程师都深有体会: 在旧时光里,实现某一个设备的电源管理功能,是非常简单的一件事情。大多数设备都被抽象为platform设备,driver只需要提供suspend/resume/shutdown等回调函数,并注册到kernel即可。kernel会在系统电源状态切换的过程中,调用driver提供的回调函数,切换设备的电源状态。 但是在新

芋圆_钰源 2204

Vivado 2018.3 安装步骤及 license 获取

本文的主要内容是介绍 Vivado 2018.3 版本的安装步骤及其 license 的获取与加载。

西岸贤 4万+

设备驱动开发:接口稳定比代码炫技更重要

设备驱动开发的重点,不只是把寄存器配对,而是提供稳定接口、清晰错误语义和可诊断状态。接口稳定,比代码炫技更重要。

jiang_style的博客 6013

从仿真到真机:如何将XTDrone的VINS-Fusion+RTABMap建图方案部署到真实无人机上?

本文详细介绍了如何将XTDrone的VINS-Fusion+RTABMap建图方案从仿真环境迁移到真实无人机上。内容涵盖硬件选型、传感器配置、VINS-Fusion调优、RTABMap性能优化以及系统集成等关键步骤,特别针对三维稠密重建在真实环境中的挑战提供了实用解决方案。

weixin_29056781的博客 241

DIY压电陶瓷传感器信号放大:从拆解到JFET电路实战(附示波器实测数据)

本文详细介绍了如何利用废旧设备拆解的压电陶瓷片,结合JFET(结型场效应管)高输入阻抗特性,DIY搭建高灵敏度振动传感器放大电路。从元件拆解、参数实测到JFET共源极放大器实战搭建与调试,提供了完整的步骤、示波器实测数据及优化方案,帮助电子爱好者实现低功耗振动检测应用。

weixin_29195615的博客 386

Linux电源管理2

Linux电源管理2(基于Linux6.6)---Generic PM介绍

ListQ的博客 1214

k8s集群部署私有镜像仓库

本文介绍了在Kubernetes集群中部署私有镜像仓库的完整方案。使用registry:2镜像创建Deployment,通过NodePort(30500)暴露服务,并采用hostPath(/data/registry)实现数据持久化。部署过程包括节点标记、YAML配置、资源创建及验证步骤,同时提供了Docker和Containerd两种环境下的详细使用方法,包括配置不信任私有仓库、镜像推送/拉取操作指南。该方案特别适合开发测试环境,为团队提供便捷的本地镜像管理能力。

weixin_42728286的博客 893

Linux - 电源管理

引用 【原创】Linux Suspend流程分析 Linux 进程中 Stop, Park, Freeze Linux Signal Linux电源管理(6)_Generic PM之Suspend功能 Linux电源管理(13)_Driver的电源管理 Linux电源管理(11)_Runtime PM之功能描述 【原创】Linux PSCI框架 Linux电源管理(13)_Driver的电源管理 系统休眠(System Suspend)和设备中断处理 一. Linux电源管理的组成

vertor11的博客 612

【python基础】一文掌握 Jupyter Notebook 的使用(超级详细!)

是一个非营利组织,致力于为多种编程语言的交互式计算开发开源软件、开放标准和服务。Jupyter 于 2014 年由 Fernando Pérez 从IPython衍生出来,支持几十种编程语言的执行环境。Jupyter 项目主要开发并支持(.ipynb 文件格式)、JupyterHub和JupyterLab等交互式计算产品。

数据知道的博客 1万+

OpenClaw更新后变傻了?一分钟教你快速恢复(OpenClaw更新版本后降智、缺少权限问题的解决方案)

OpenClaw 版本更新后出现降智问题,AI不再执行具体任务。本文详细分析问题原因,提供最简便的解决方案✅

XiaoqiangClub的博客 3880

Linux运行时IO设备电源管理框架---PM

1. 介绍 对I/O设备的运行时电源管理(运行时PM)的支持,是在电源管理的核心(PM core)下借助于以下方式实现的:   电源管理工作队列pm_wq,总线类型(bus types)和设备驱动(devicedrivers)可以把自己的PM相关的工作项(workitems)置于其上。我们强烈建议,pm_wq用于对所有运行时PM相关的工作项进行排队,因为这使得他们能够与全系统的电

u013403237的专栏 1326

9.9华为OD机试真题 新系统 - 受限任务分配 (Java/Py/C/C++/Js/Go)

华为OD机试真题 新系统【受限任务分配】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试真题 【受限任务分配】多语言题解。

qq_45776114的博客 724

Android电源管理子系统-软件架构

1)在嵌入式领域中,电源管理是可以说是无处不在,并且遍布整个系统,核心思想动态调配功耗资源,让设备在性能和续航之间取得最佳平衡,从而提供最流畅、持久的用户体验;2)产品场景电池产品考虑得更多-续航是个非常重要的特性;非电池场景相对而言 没那么严格 - 满足能耗法律法规即可;3)站在不同的角度看电源管理从用户功能来看:息屏、STR、非STR从设备角度来看:CPU电源管理、音频子系统的电源管理、WIFI/BT低功耗、各类硬件都基本会有电源管理从BOOT/PM角度来看:开关机、重启。

STCNXPARM的博客 620

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

深入剖析linux内核和设备驱动,深入剖析Linux内核与设备驱动

本书从需求的角度出发,以层次分析的方法探究Linux内核以及驱动的各部分框架和实现。另外以TI的嵌入式芯片为例,对内核各部分功能特别是电源管理功能进行代码级别的分析。整体以需求是什么,如何实现相应需求来进行分析,更易于对系统的把握和理解。本书将软件和硬件结合起来分析了嵌入式处理以及Linux内核实现中的各种技术,特别是对电源管理技术进行了全面细致的分析和介绍。本书可以作为本科和研究生操作系统的参考...

weixin_39657125的博客 211

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

《Linux 设备驱动开发详解:基于最新的 Linux 4.0 内核》 第 1 章 Linux 设备驱动概述及开发环境搭建

本文介绍了Linux设备驱动的基本概念、功能及其在系统架构中的关键作用。主要内容包括: 设备驱动作为硬件与操作系统之间的接口层,实现了硬件无关性,为上层提供统一访问接口; 无操作系统时的裸机驱动开发模式,通过STM32 GPIO和UART驱动案例展示了直接寄存器操作方式; 对比了裸机驱动的特点(简单直接)与局限性(缺乏资源管理、无法并发访问等),为后续Linux驱动开发奠定基础。 (98字)

qq_40843427的博客 571

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

四极管:WinCE 电源管理概述(九)

四、设备电源管理指南 电源管理器对设备功耗、性能及响应时间没有严格的限制。然后,从用户的角度看D0和D1的状态下是可操作的。而更高的电源状态药比这两个状态消耗更少的电源。 这个简单的指南只是为了是OEM厂商能共容易的定义有意义的电源状态,而不知道每个设备的详细功耗要求。 1、设备电源自管理 一些设备自行管理其电源的过程是比较复杂的,驱动程序设计人员通常希望在设备处于休止状态时减少耗电量。降

杨琦(四极管) 1366

Linux运行时I/O设备的电源管理框架【转】

转自:https://www.cnblogs.com/coryxie/archive/2013/03/01/2951243.html 本文介绍Linux运行时I/O设备的电源管理框架。属于Linux内核文档的翻译。 原文:http://www.kernel.org/doc/Documentation/power/runtime_pm.txt 翻译:CoryXie <wenxue.xie...

weixin_34292287的博客 122
上一篇: Linux memcg lru lock提升锁性能
下一篇: 高通camx ThreadManager
OS技术解密
博客等级 码龄16年 3760粉丝 189原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值