RT-Thread电源管理组件

电源管理组件

嵌入式系统低功耗管理的目的在于满足用户对性能需求的前提下,尽可能降低系统能耗以延长设备待机时间。
高性能与有限的电池能量在嵌入式系统中矛盾最为突出,硬件低功耗设计与软件低功耗管理的联合应用成为解决矛盾的有效手段。

现在的各种MCU都或多或少的在低功耗方面提供了管理接口。比如对主控时钟频率的调整、工作电压的改变、总线频率的调整甚至关闭,外围设备工作时钟的关闭等。
有了硬件上的支持,合理的软件设计就成为节能的关键,一般可以把低功耗管理分为三个类别:

  • 处理器电源管理主要实现方式:对CPU频率的动态管理,以及系统空闲时对工作模式的调整。
  • 设备电源管理主要实现方式:关闭个别闲置设备。
  • 系统平台电源管理主要实现方式:针对特定系统平台的非常见设备具体定制。

随着物联网 (IoT) 的兴起,产品对功耗的需求越来越强烈。作为数据采集的传感器节点通常需要在电池供电时长期工作,而作为联网的SOC也需要有快速的响应功能和较低的功耗。

在产品开发的起始阶段,首先考虑是尽快完成产品的功能开发。在产品功能逐步完善之后,就需要加入电源管理(Power Menagement,以下简称PM)功能。
RTT提供了电源管理组件。电源管理组件的理念是尽量透明,使得产品加入低功耗功能更加轻松。

PM组件介绍

RTT的PM组件采用分层设计思想,分离架构和芯片相关的部分,提取公共部分作为核心。在上层提供通用的接口同时,也让底层驱动对组件的适配变得更加简单。

在这里插入图片描述

主要特点

  • 基于模式来管理功耗,空闲时动态调整工作模式,支持多个等级的休眠。
  • 对应用透明,组件在底层自动完成电源管理。
  • 支持运行模式下动态变频,根据模式自动更新设备的频率配置,确保在不同的运行模式都可以正常工作。
  • 支持设备电源管理,根据模式自动管理设备的挂起和恢复,确保在不同的休眠模式下可以正确的挂起和恢复。
  • 支持可选的休眠时间补偿,让依赖OS Tick的应用可以透明使用。
  • 向上层提供设备接口,如果打开了devfs组件,那么也可以通过文件系统接口访问。

工作原理

低功耗的本质是系统空闲时CPU停止工作,中断或事件唤醒后继续工作。
在RTOS中,通常包含一个IDLE任务,该任务的优先级最低且一直保持就绪状态,当高优先级任务未就绪时,OS执行IDLE任务。
一般地,未进行低功耗处理时,CPU在IDLE任务中循环执行空指令。RTT的电源管理组件在IDLE任务中,通过对CPU、时钟和设备等进行管理,从而有效降低系统的功耗。

在这里插入图片描述
在上图所示,当高优先级任务运行结束或挂起时,系统将进入IDLE任务中。

当IDLE任务执行后,它将判断系统是否可以进入到休眠状态(以节省功耗)。如果可以进入休眠,将根据芯片情况关闭部分硬件模块,OS Tick也非常有可能进入暂停状态。
此时电源管理框架会根据系统定时器情况,计算出下一个超时时间点,并设置低功耗定时器,让设备能够在这个时刻点唤醒,并进行后续的工作。
当系统被(低功耗定时器或其它唤醒中断源)唤醒后,系统也需要知道睡眠时间长度是多少,并对OS Tick进行补偿,让系统的OS tick值调整为一个正确的值。

设计架构

在RTT PM组件中,外设或应用通过投票机制对所需的功耗模式进行投票,当系统空闲时,根据投票数决策出合适的功耗模式,调用抽象接口,控制芯片进入低功耗状态,从而降低系统功耗。
当未进行任何投票时,会以默认模式进入(通常为空闲模式)。

与应用不同,某些外设可能在进入低功耗状态时执行特定操作,退出低功耗时采取恢复措施,此时可以通过注册PM设备来实现。
通过注册PM设备,在进入低功耗之前,会触发注册设备的suspend回调,开发者可以在回调里执行自己的操作;类似地,从低功耗状态退出时,也会触发resume回调。
在这里插入图片描述

低功耗状态和模式

RTT PM组件将系统划分为两种状态:运行状态(RUN)和休眠状态(SLEEP)。

  • 运行状态控制CPU的频率,适用于变频场景;
  • 休眠状态根据SOC特性实现休眠CPU,以降低功耗。

两种状态分别使用不同的API接口,独立控制。

休眠状态

休眠状态也就是通常意义上的低功耗状态,通过关闭外设,执行SOC电源管理接口,降低系统功耗。
休眠状态又分为六个模式,呈现金字塔的形式。
随着模式增加,功耗逐渐递减的特点。

  • PM_SLEEP_MODE_NONE:0——系统处于活跃状态,未采取任何的降低功耗
  • PM_SLEEP_MODE_IDLE:1——空闲模式,该模式在系统空闲时停止CPU和部分时钟,任何事件或中断均可以唤醒
  • PM_SLEEP_MODE_LIGHT:2——轻度睡眠模式,CPU停止,多数时钟和外设停止,唤醒后需要进行时间补偿
  • PM_SLEEP_MODE_DEEP:3——CPU停止,仅少数低功耗外设工作,可被特殊中断唤醒
  • PM_SLEEP_MODE_STANDBY:4——待机模式,CPU停止,设备上下文丢失(可保存至特殊外设),唤醒后通常复位
  • PM_SLEEP_MODE_SHUTDOMN:5——关闭模式,比Standby模式功耗更低,上下文通常不可恢复,唤醒后复位

因各家芯片差异,功耗管理的实现也不尽相同,上述的描述仅给出一些推荐的场景,并非一定需要实现所有。开发者可根据自身情况选择其中的几种进行实现,但是需要遵循级别越高,功耗越低的原则!

运行状态

运行状态通常用于改变CPU的运行频率,独立于休眠模式。

运行状态通常用于改变 CPU 的运行频率,独立于休眠模式。当前运行状态划分了四个等级:高速、正常、中速、低速,如下:

在这里插入图片描述

模式的请求和释放

在PM组件里,上层应用可以通过请求和释放休眠模式主动参与功耗管理
应用可以根据场景请求不同的休眠模式,并在处理完毕后释放,只要有任意一个应用或设备请求高等级的功耗模式,就不会切换到比它更低的模式。
因此,休眠模式的请求和释放的操作通常成对出现,可用于对某个阶段进行保护,如外设的 DMA 传输过程。

对模式变化敏感的设备

在PM组件里,切换到新的运行模式可能会导致CPU频率发生变化;如果外设和CPU共用一部分时钟,那外设的时钟就会受到影响;在进入新的休眠模式,大部分时钟源会停止,如果外设不支持休眠的冻结功能,那么从休眠唤醒的时候,外设的时钟就需要重新配置外设。
所以PM组件里支持了PM模式敏感的PM设备。使得设备在切换到新的运行模式或新的休眠模式都能正常的工作。该功能需要底层驱动实现相关的接口并注册为对陌生变化敏感的设备。

调用流程

在这里插入图片描述
首先应用设置进出休眠状态的回调函数,然后调用rt_pm_request请求休眠模式,触发休眠操作;PM组件在系统空闲时检查休眠模式技术,根据投票数给出推荐的模式;接着PM组件调用notify通知应用,告知即将进入休眠模式;然后对注册的PM设备执行挂起操作,返回OK后执行SOC实现的休眠模式,系统进入休眠状态(如果使能时间补偿,休眠之前会启动低功耗定时器)。
此时CPU停止工作,等待事件或中断唤醒。当系统被唤醒后,由于全局中断为关闭状态,系统继续从该处执行,获取睡眠时间补偿系统的心跳,依次唤醒设备,通知应用从休眠模式退出。
如此一个周期执行完毕,退出,等待系统下次空闲。

API

请求休眠

void rt_pm_request(uint8_t sleep_mode);
enum
{/* sleep modes */PM_SLEEP_MODE_NONE = 0,    /* 活跃状态 */PM_SLEEP_MODE_IDLE,        /* 空闲模式(默认) */PM_SLEEP_MODE_LIGHT,       /* 轻度睡眠模式 */PM_SLEEP_MODE_DEEP,        /* 深度睡眠模式 */PM_SLEEP_MODE_STANDBY,     /* 待机模式 */PM_SLEEP_MODE_SHUTDOWN,    /* 关断模式 */PM_SLEEP_MODE_MAX,
};

使用说明

设置低功耗等级
如果系统需要进入指定等级的低功耗,可通过调用rt_pm_request实现。
如进入深度睡眠模式:

rt_pm_request(PM_SLEEP_MODE_DEEP);

如果程序的其它地方请求了更高的功耗模式,如Light Mode或者Idle Mode,则需要释放相应的模式后,深度睡眠模式才能被进入。

保护某个阶段或者过程
特殊情况下,比如某个阶段并不允许系统进入更低的功耗模式,此时可以通过rt_pm_request和rt_pm_release对该过程进行保护。
如I2C读取数据期间,不允许进入深度睡眠模式(可能会导致外设停止工作),因此可以做如下处理:

/*请求轻度睡眠模式(I2C外设该模式下正常工作)*/
rt_pm_request(PM_SLEEP_MODE_LIGHT);/*读取数据过程*//*释放该模式*/
rt_pm_release(RM_SLEEP_MODE_LIGHT);

改变CPU运行频率
降低运行频率能有效减少系统的功耗,通过rt_pm_run_enter接口改变CPU的运行频率。
一般地,降频率意味着CPU性能降低、处理速度减慢,可能会导致任务的执行时间增长,需要合理进行权衡。

/* 进入中等速度运行模式 */
rt_pm_run_enter(PM_RUN_MODE_MEDIUM_SPEED);

移植说明

低功耗管理是一项十分细致的任务,开发者在移植时,还需熟悉板卡的外围电路,进入低功耗状态时逐一处理,避免出现外围电路漏电拉升整体功耗的情况。

RTT PM组件对各部分进行抽象,提供不同的ops接口供开发者适配。

struct rt_pm_ops
{/* sleep 接口用于适配芯片相关的低功耗特性 */void (*sleep)(struct rt_pm *pm, uint8_t mode);/* run 接口用于运行模式的变频和变电压 */void (*run)(struct rt_pm *pm, uint8_t mode);/* 以下三个接口用于心跳停止后启动低功耗定时器以补偿心跳 */void (*timer_start)(struct rt_pm *pm, rt_uint32_t timeout);void (*timer_stop)(struct rt_pm *pm);rt_tick_t (*timer_get_tick)(struct rt_pm *pm);
};
struct rt_device_pm_ops
{/* 进入休眠模式之前挂起外设,返回非 0 表示外设未就绪,不能进入 */int (*suspend)(const struct rt_device *device, uint8_t mode);/* 从休眠模式退出后恢复外设 */void (*resume)(const struct rt_device *device, uint8_t mode);/* 运行状态下模式改变通知外设处理 */int (*frequency_change)(const struct rt_device *device, uint8_t mode);
};
/* 注册一个 PM 设备 */
void rt_pm_device_register(struct rt_device *device, const struct rt_device_pm_ops *ops);

芯片自身的功耗特性

void (*sleep)(struct rt_pm*pm, uint8_t mode);

各个芯片对低功耗模式的定义和管理不同,PM组件将芯片相关的特征抽象为sleep接口。该接口适配芯片相关的低功耗管理,当要进入不同的休眠模式时,一些硬件相关的配置,保存等相关处理。

休眠的时间补偿

void (*timer_start)(struct rt_pm *pm, rt_uint32_t timeout);
void (*timer_stop)(struct rt_pm *pm);
rt_tick_t (*timer_get_tick)(struct rt_pm *pm);

在某些休眠模式下(Light Sleep或Deep Sleep),内核心跳定时器可能会被停止,此时需要对启动一个定时器对休眠的时间进行计量,唤醒后对心跳补偿。时间补偿的定时器必须在该模式下仍能够正常工作,并唤醒系统,否则没有意义!

  • timer_start:启动功耗定时器,入参为最近的下次任务就绪时间;
  • timer_get_tick:获取系统被唤醒的睡眠时间;
  • timer_stop:用于系统唤醒后停止低功耗定时器。

休眠模式的时间补偿需要在初始化阶段通过设置timer_mask的对应模式的bit控制开启。
例如需要开启Deep Sleep模式下的时间补偿,在实现timer相关的ops接口后,初始化时设置相应的bit:

rt_uint8_t timer_mask = 0;timer_mask = 1UL << PM_SLEEP_MODE_DEEP;rt_system_pm_init(&_ops, timer_mask, RT_NULL);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/2152.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

排序算法之桶排序

目录 一、简介二、代码实现三、应用场景 一、简介 算法平均时间复杂度最好时间复杂度最坏时间复杂度空间复杂度排序方式稳定性桶排序O(nk )O(nk)O(n^2)O(nk)Out-place稳定 稳定&#xff1a;如果A原本在B前面&#xff0c;而AB&#xff0c;排序之后A仍然在B的前面&#xff1b; 不…

Kotlin语法快速入门--条件控制和循环语句(2)

Kotlin语法入门–条件控制和循环语句&#xff08;2&#xff09; 文章目录 Kotlin语法入门--条件控制和循环语句&#xff08;2&#xff09;二、条件控制和循环语句1、if...else2、when2.1、常规用法2.2、特殊用法--并列&#xff1a;2.3、特殊用法--类型判断&#xff1a;2.4、特殊…

C语言进阶课程学习记录-第48课 - 函数设计原则

C语言进阶课程学习记录 - 函数设计原则 本文学习自狄泰软件学院 唐佐林老师的 C语言进阶课程&#xff0c;图片全部来源于课程PPT&#xff0c;仅用于个人学习记录

无人驾驶 自动驾驶汽车 环境感知 精准定位 决策与规划 控制与执行 高精地图与车联网V2X 深度神经网络学习 深度强化学习 Apollo

无人驾驶 百度apollo课程 1-5 百度apollo课程 6-8 七月在线 无人驾驶系列知识入门到提高 当今,自动驾驶技术已经成为整个汽车产业的最新发展方向。应用自动驾驶技术可以全面提升汽车驾驶的安全性、舒适性,满足更高层次的市场需求等。自动驾驶技术得益于人工智能技术的应用…

端口被占用的解决方案汇总

端口被占用的解决方案汇总 【一】windows系统端口被占用【二】Linux系统端口被占用【三】Linux的ps命令查找&#xff08;1&#xff09;ps命令常用的方式有三种&#xff08;2&#xff09;ps -ef |grep 8080 【一】windows系统端口被占用 &#xff08;1&#xff09;键盘上按住Wi…

【LeetCode刷题记录】21. 合并两个有序链表

21 合并两个有序链表 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4] 示例 2&#xff1a; 输入&#xff1a;l1 [], l2 …

# MySQL中的并发控制,读写锁,和锁的粒度

MySQL中的并发控制&#xff0c;读写锁&#xff0c;和锁的粒度 并发控制的概述 在数据库系统中&#xff0c;并发控制是一种用于确保当多个用户同时访问数据库时&#xff0c;系统能够提供数据的一致性和隔离性的机制。MySQL支持多种并发控制技术&#xff0c;其中包括锁机制、多…

调试 WebSocket API 技巧分享

WebSocket 是一种在单个 TCP 连接上实现全双工通信的先进 API 技术。与传统的 HTTP 请求相比&#xff0c;WebSocket 提供了更低的延迟和更高的通信效率&#xff0c;使其成为在线游戏、实时聊天等应用的理想选择。 开始使用 Apifox 的 WebSocket 功能 首先&#xff0c;在项目界…

node和go的列表转树形, 执行速度测试对比

保证数据一致性&#xff0c;先生成4000条json数据到本地&#xff0c;然后分别读取文本执行处理 node代码 node是用midway框架 forNum1:number 0forNum2:number 0//执行测试async index(){// 生成菜单列表// const menuList await this.generateMenuList([], 4000);const men…

双周总结#008 - AIGC

本周参与了公司同事对 AIGC 的分享会&#xff0c;分享了 AIGC 在实际项目中的实践经验&#xff0c;以及如何进行 AIGC 的落地。内容分几项内容&#xff1a; 什么是 AIGCAIGC 能做什么AIGC 工具 以年终总结为例&#xff0c;分享了哪些过程应用了 AIGC&#xff0c;以及 AIGC 落地…

QA测试开发工程师面试题满分问答19: url请求到响应整个过程,涉及到什么技术细节

概述 当你点击鼠标发起一个请求&#xff0c;直到页面显示响应数据&#xff0c;整个过程可以详细展开为以下步骤&#xff1a; 用户点击鼠标&#xff1a;用户在浏览器中点击某个链接或按钮&#xff0c;触发请求的发起。 URL 解析&#xff1a;浏览器解析点击的链接中的 URL&…

在线音乐播放网站项目测试(selenium+Junit5)

在做完在线音乐播放网站项目之后&#xff0c;需要对项目的功能、接口进行测试&#xff0c;利用测试的工具&#xff1a;selenium以及Java的单元测试工具Junit进行测试&#xff0c;下面式测试的思维导图&#xff0c;列出该项目需要测试的所有测试用例&#xff1a; 测试结果&#…

下列程序定义了NxN的二维数组,并在主函数中自动赋值。请编写函数fun(int a[][N],int n),该函数的功能是:使数组右上半三角元素中的值乘以m。

本文收录于专栏:算法之翼 https://blog.csdn.net/weixin_52908342/category_10943144.html 订阅后本专栏全部文章可见。 本文含有题目的题干、解题思路、解题思路、解题代码、代码解析。本文分别包含C语言、C++、Java、Python四种语言的解法完整代码和详细的解析。 题干 下列…

【QML】State组件

State(状态)组件是一组来自默认配置的批处理更改。所有项都有一个默认状态&#xff0c;该状态定义对象和属性值的默认配置。可以通过将State项添加到states属性来定义新的状态&#xff0c;以允许项在不同的配置之间切换。 State组件的基本用法如下&#xff1a; Window {id: …

【ARM Trace32(劳特巴赫) 使用介绍 12.1 -- Trace32 读写 64位地址】

请阅读【Trace32 ARM 专栏导读】 文章目录 Trace32 读写 64位地址读 64 位地址写64位地址Trace32 读写 64位地址 在使用TRACE32进行调试时,有时需要读取或操作64位的地址,特别是在处理64位的处理器或操作系统时。以下是如何在TRACE32中读取64位地址的一般方法。 读 64 位地…

MySQL行级锁——技术深度+1

引言 本文是对MySQL行级锁的学习&#xff0c;MySQL一直停留在会用的阶段&#xff0c;需要弄清楚锁和事务的原理并DEBUG查看。 PS:本文涉及到的表结构均可从https://github.com/WeiXiao-Hyy/blog中获取&#xff0c;欢迎Star&#xff01; MySQL行级锁 行级锁&#xff08;Row-…

js连接抖音打印组件实现打印

js连接抖音打印组件实现打印小票 安装抖音打印组件 抖音打印组件文档&#xff1a; https://bytedance.larkoffice.com/docs/doccn2vbOOdd3KWrCd6Z93nIlvg 跟着文档案例一步步配基本上没问题&#xff0c; 打印的时候需要设置下打印机名称 export class DouyinPrint {construct…

怎么理解算力?1000P算力是什么概念?

算力&#xff0c;指计算机系统在单位时间内能够完成的计算任务量&#xff0c;它涵盖了CPU、GPU、TPU等硬件&#xff0c;每秒能处理的数据量&#xff0c;通常以“P”&#xff08;PetaFLOPS&#xff0c;即千万亿次浮点运算每秒&#xff09;为单位来衡量&#xff0c;是评估计算机性…

PDF被加密无法打印的解决办法

思路很清晰&#xff1a;先解密→再打印 分享四个工具&#xff0c;可以轻松解密PDF&#xff1a; ⭐i love pdf I LOVE PDF是一款免费的PDF网站&#xff0c;界面设计简洁&#xff0c;首页没有广告&#xff0c;但每个功能的操作界面是有广告的&#xff0c;不会影响使用。 部分功…

大数据开发详解

点击下载《大数据开发详解》 1. 前言 随着信息化时代的快速发展&#xff0c;大数据已经成为了企业和组织不可或缺的重要资源。大数据开发则是指通过一系列技术手段&#xff0c;对海量数据进行收集、存储、处理、分析和挖掘&#xff0c;以实现数据的价值化利用。大数据开发涉及…