RTT潘多拉开发板上实现电源管理

简介

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

在产品开发的起始阶段,首先考虑是尽快完成产品的功能开发。在产品功能逐步完善之后,就需要加入电源管理功能。为了适应IoT的这种需求,RT-Thread提供了电源管理框架。电源管理框架的理念是尽量透明,使得产品加入低功耗功能更加轻松。

本文的示例都是在潘多拉开发板下运行。
潘多拉开发板是RTT和正点原子联合推出的硬件平台,该平台上专门为IoT领域设计,并提供了丰富的例程和文档。

MCU通常提供了多种时钟源供用户选择。
例如潘多拉开发板上板载的STM32L475就可以选择LSI/MSI/HSI等内部时钟,还可以选择HSE/LSE等外部时钟。
MCU内通常也集成了PLL(Phase-lock loops),基于不同的时钟源,向MCU的其它模块提供更高频率的时钟。

为了支持低功耗功能,MCU里也会提供不同的休眠模式。
例如STM32L475里,可以分成SLEEP模式、STOP模式、STANDBY模式。

定时应用

在定时应用里,我们创建了一个周期性的软件定时器,定时器任务里周期性输出当前的OS Tick。
如果创建软件定时器成功之后,使用rt_pm_request(PM_SLEEP_MODE_DEEP)请求深度睡眠模式。

按键唤醒应用

在按键唤醒应用里,我们使用wakeup按键来唤醒处于休眠模式的MCU。
一般情况下,在MCU处于比较深度的休眠模式,只能通过特定的方式唤醒。

#include <board.h>
#include <rtthread.h>
#include <rtdevice.h>

#ifdef RT_USING_PM

#define WAKEUP_EVENT_BUTTON                 (1 << 0)
#define PIN_LED_R                           GET_PIN(E, 7)
#define WAKEUP_PIN                          GET_PIN(C, 13)
#define WAKEUP_APP_THREAD_STACK_SIZE        1024

static rt_event_t wakeup_event;

static void wakeup_callback(void *args)
{
    rt_event_send(wakeup_event, WAKEUP_EVENT_BUTTON);
}

static void wakeup_init(void)
{
    rt_pin_mode(WAKEUP_PIN, PIN_MODE_INPUT_PULLUP);
    rt_pin_attach_irq(WAKEUP_PIN, PIN_IRQ_MODE_FALLING, wakeup_callback, RT_NULL);
    rt_pin_irq_enable(WAKEUP_PIN, 1);
}

static void wakeup_app_entry(void *parameter)
{
    wakeup_init();
    rt_pm_request(PM_SLEEP_MODE_DEEP);

    while (1)
    {
        if (rt_event_recv(wakeup_event,
                          WAKEUP_EVENT_BUTTON,
                          RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR,
                          RT_WAITING_FOREVER, RT_NULL) == RT_EOK)
        {
            rt_pm_request(PM_SLEEP_MODE_NONE);

            rt_pin_mode(PIN_LED_R, PIN_MODE_OUTPUT);
            rt_pin_write(PIN_LED_R, 0);
            rt_thread_delay(rt_tick_from_millisecond(500));
            rt_pin_write(PIN_LED_R, 1);

            rt_pm_release(PM_SLEEP_MODE_NONE);
        }
    }
}

static int wakeup_app(void)
{
    rt_thread_t tid;

    wakeup_event = rt_event_create("wakup", RT_IPC_FLAG_PRIO);
    RT_ASSERT(wakeup_event != RT_NULL);

    tid = rt_thread_create("wakeup_app", wakeup_app_entry, RT_NULL,
                           WAKEUP_APP_THREAD_STACK_SIZE, RT_MAIN_THREAD_PRIORITY, 20);
    RT_ASSERT(tid != RT_NULL);

    rt_thread_startup(tid);

    return 0;
}
INIT_APP_EXPORT(wakeup_app);

#endif

线程里注册了按键中断回调函数,接着请求深度睡眠模式,当唤醒中断之后就会触发回调。回调函数里会发送时间。
线程在接收事件之后,完成LED闪烁功能后,再去释放None。

STM32L4的低功耗模式简介

STM32L476是ST公司推出的一款超低功耗的Cortex-M4内核的MCU,支持多个电源管理模式,其中最低功耗shutdown模式下,待机电流仅30nA。

ST公司把L476的电源管理分为很多种,但各个模式并非功耗逐级递减的特点,下面是各个模式之间的状态转换图:
在这里插入图片描述
仅管L476的低功耗模式很多,但本质上并不复杂,理解它的原理有助于我们移植驱动,同时更好的在产品中选择合适的模式。

最终决定STM32L476系统功耗的主要是三个因素:稳压器(voltage regulator)、CPU工作频率、芯片自身低功耗的处理,下面分别对三个因素进行阐述。

稳压器

L4使用两个嵌入式线性稳压器为所有数字电路、待机电路以及备份时钟域供电,分别是主稳压器(main regulator,MR)和低功耗稳压器(low power regulator,简称LPR)。

稳压器在复位后处于使能状态,根据应用模式,选择不同的稳压器对Vcore域供电。
其中,MR的输出电压可以由软件配置为不同的范围(Range1 和 Range2)。

在这里插入图片描述

CPU工作频率

通过降低CPU的主频达到降低功耗的目的:MR工作中Range1正常模式时,SYSCLK最高可以工作在80M;MR工作在Range 2时,SYSCLK最高不能超过26M。
低功耗运行模式和低功耗休眠模式,即Vcore域由LPR供电,SYSCLK必须小于2M。

芯片本身的低功耗处理

芯片本身定义了一系列的休眠模式,如Sleep、Stop、Standby和Shutdown,前面的四种模式功耗逐渐降低,实质是芯片内部通过关闭外设和时钟来实现。

移植具体实现

RTT低功耗管理系统从设计上分离运行模式和休眠模式,独立管理,运行模式用于变频和变电压,休眠调用芯片的休眠特性。
对于多数芯片和开发来说,可能并不需要考虑变频和变电压,仅需关注休眠模式

STM32 L4系列的芯片有运行模式和低功耗运行模式的概念,同时MR还有Range 2模式,可用于变频场景。

PM组件的底层功能都是通过struct rt_pm_ops结构体里的函数完成:

/**
 * low power mode operations
 */
struct rt_pm_ops
{
    void (*sleep)(struct rt_pm *pm, uint8_t mode);
    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);
};

移植休眠模式

移植休眠模式仅需关注sleep接口,根据PM用户手册相关介绍,首先将RTT的休眠模式和STM32的模式做一个转换:

  • NONE——Run:正常运行模式,不进行任何降功耗的措施
  • IDLE——Run:正常运行模式,可选择WFI(等待中断唤醒)和WFE(等待事件唤醒),此处暂不处理
  • LIGHT——Sleep:轻度睡眠模式,执行ST的Sleep模式
  • PM_SLEEP_MODE_DEEP——Stop2:深度睡眠模式,执行ST的Stop2模式
  • STANDBY——Standby:待机模式,执行ST的Standby模式
  • SHUTDOWN——Shutdown:停止模式,执行ST的Shutdown模式
#include <board.h>
#include <rtthread.h>
#include <rtdevice.h>

static void sleep(struct rt_pm *pm,uint8_t mode)
{
	
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++变量的作用域与存储类型

一 变量的作用域和存储类型 1 变量的作用域(Scope) 指在源程序中定义变量的位置及其能被读写访问的范围分为局部变量(Local Variable)和全局变量(Global Variable) 1&#xff09;局部变量(Local Variable) 在语句块内定义的变量 形参也是局部变量 特点&#xff1a; 生存期是…

web 基础之 HTTP 请求

web 基础 网上冲浪 就是在互联网(internet)上获取各种信息&#xff0c;进行工作&#xff0c;或者娱乐&#xff0c;他的英文表示surfing the Internet&#xff0c;因 “surfing”d的意思是冲浪&#xff0c;即成为网上冲浪&#xff0c;这是一种形象说法&#xff0c; 也是一个非…

交易复盘-20240507

仅用于记录当天的市场情况&#xff0c;用于统计交易策略的适用情况&#xff0c;以便程序回测 短线核心&#xff1a;不参与任何级别的调整&#xff0c;采用龙空龙模式 一支股票 10%的时候可以操作&#xff0c; 90%的时间适合空仓等待 蔚蓝生物 (5)|[9:25]|[36187万]|4.86 百合花…

SpringBootWeb入门

SpringBoot可以帮助我们快速的构建应用程序、简化开发、提高效率 创建SpringBoot工程&#xff0c;并勾选web开发相关依赖 定义HelloController类&#xff0c;添加方法&#xff0c;并添加注解 运行测试 创建SpringBoot工程(联网下载) 在File里面点击new Module 点击next 修…

Linux\_c输出

第一条Linux_c输出 初界面 : ls # 显示目录下的文件cd # 进入到某个目录 # 比如 我进入了Codels # 发现没有显示, 说明为文件下为空vim cpucdoe.c # 创建一个 .c的源码文件进入到了vim的编辑界面: i # 按i 就可以进行编辑 , 下面显示插入标识在编辑模式下, 可以通…

计算图:深度学习中的链式求导与反向传播引擎

在深度学习的世界中&#xff0c;计算图扮演着至关重要的角色。它不仅是数学计算的图形化表示&#xff0c;更是链式求导与反向传播算法的核心。本文将深入探讨计算图的基本概念、与链式求导的紧密关系及其在反向传播中的应用&#xff0c;旨在为读者提供一个全面而深入的理解。 计…

练习项目后端代码解析切面篇(Aspect)

前言 之前注解篇时我说&#xff0c;通常情况下一个自定义注解一般对应一个切面&#xff0c;虽然项目里的切面和注解个数相同&#xff0c;但是好像有一个名字看起来并不对应&#xff0c;无所谓&#xff0c;先看了再说。 ExceptionLogAspect切面 我在里面做了具体注释&#x…

使用Simulink Test进行单元测试

本文摘要&#xff1a;主要介绍如何利用Simulink Test工具箱&#xff0c;对模型进行单元测试。内容包括&#xff0c;如何创建Test Harness模型&#xff0c;如何自动生成excel格式的测试用例模板来创建测试用例&#xff0c;如何手动填写excel格式的测试用例模板来手动创建测试用例…

Golang Map类型

文章目录 Map介绍Map的定义方式Map的增删查改新增和修改Map元素查找Map元素删除Map元素遍历Map元素 Map元素排序Map切片 Map介绍 Map介绍 在Go中&#xff0c;map是哈希表的引用&#xff0c;是一种key-value数据结构。map类型写作map[K]V&#xff0c;其中K和V分别对应key和value…

系统维护启动盘 优启吧

优启吧-《优启时代系统维护盘》2025典藏版&#xff08;UD/ISO&#xff09;

亿发解密:数据中台管理系统,引领企业数字化转型的智能数据体系

在当今数字化时代&#xff0c;数据已成为企业发展的关键驱动力。为了更好地利用数据&#xff0c;提升业务水平&#xff0c;企业需要建立一套完备的数据管理体系&#xff0c;而数据中台便应运而生。 什么是数据中台 数据中台是集方法论、组织和工具于一体的智能大数据体系。它…

一起深度学习(AlexNet网络)

AlexNet神经网络 代码实现&#xff1a; 代码实现&#xff1a; import torch from torch import nn from d2l import torch as d2lnet nn.Sequential(# 采用了11*11的卷积核来捕捉对象&#xff0c;因为原始输入数据比较大#步幅为4 &#xff0c;可减少输出的高度核宽度。#输出通…

微搭低代码入门06分页查询

目录 1 创建自定义代码2 编写分页代码3 创建页面4 创建变量5 配置数据列表总结 我们在数据模型章节介绍了微搭后端服务编写的三种方式&#xff0c;包括Http请求、自定义代码、云函数。本篇我们详细讲解一下利用自定义代码开发分页查询的功能。 1 创建自定义代码 打开控制台&am…

Adaboost (BiLSTM-Adaboost ELM-Adaboost RF--Adaboost RVM-Adaboost SVM-Adaboost)

Adaboost Adaboost&#xff08;多输入单输出matlab&#xff09;代码获取戳此处代码获取戳此处 Adaboost是一种迭代式集成学习算法&#xff0c;全称为“Adaptive Boosting”&#xff0c;即自适应增强。该算法的核心思想是针对同一个训练集训练不同的分类器&#xff08;弱分类器&…

win10禁止自动更新的终极方法

添加注册表值 1.运行&#xff0c;输入regedit 2.打开注册表编辑器依次进入以下路径“计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings”。 3.在Settings项中&#xff0c;新建DWORD&#xff08;32位&#xff09;值(D)&#xff0c;重命名为以下命名“Fl…

《ESP8266通信指南》12-Lua 固件烧录

往期 《ESP8266通信指南》11-Lua开发环境配置-CSDN博客 《ESP8266通信指南》10-MQTT通信&#xff08;Arduino开发&#xff09;-CSDN博客 《ESP8266通信指南》9-TCP通信&#xff08;Arudino开发&#xff09;-CSDN博客 《ESP8266通信指南》8-连接WIFI&#xff08;Arduino开发…

【C语言】用数组和函数实现扫雷游戏

用数组和函数实现扫雷游戏 游戏界面&#xff1a; 代码如下&#xff1a; game.h #pragma once #include <stdio.h> #include <stdlib.h> #include <time.h> #define EASY_COUNT 10 #define ROW 9 #define COL 9 #define ROWS ROW2 #define COLS COL2 //初始…

PXE批量安装

系统装机的三种引导方式 u盘光盘网络装机 光盘&#xff1a; 1.类似于usb模式 2.刻录模式 系统安装过程 加载boot loader Boot Loader 是在操作系统内核运行之前运行的一段小程序。通过这段小程序&#xff0c;我们可以初始化硬件设备、建立内存空间的映射图&#xff0c;从…

jmeter分布式集群压测

目的&#xff1a;通过多台机器同时运行 性能压测 脚本&#xff0c;模拟更好的并发压力 简单点&#xff1a;就是一个人&#xff08;控制机&#xff09;做一个项目的时候&#xff0c;压力有点大&#xff0c;会导致结果不理想&#xff0c;这时候找几个人&#xff08;执行机&#x…

java10基础(this super关键字 重写 final关键字 多态 抽象类)

目录 一. this和super关键字 1. this关键字 2. super关键字 二. 重写 三. final关键字 四. 多态 五. 抽象类 1. 抽象方法 2. 抽象类 3. 面向抽象设计 一. this和super关键字 1. this关键字 this 当前对象的引用 this.属性 this.方法名() this() -- 调用构造函数 …