0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

RT-Thread低功耗的适配和应用

RTThread物联网操作系统 来源:RTThread物联网操作系统 作者:RTThread物联网操作 2022-08-03 10:29 次阅读

近期 RT-Thread 工程师完成了基于瑞萨CPK-RA2L1 开发板的BSP适配,支持了GPIO、UARTI2C、SPI、ADCDAC、PWM、CAN、on-chip Flash、Watchdog、RTC等外设驱动,并在瑞萨工程师支持下完成电源组件(低功耗LPM)适配,经实际测量,芯片在Software Standby阶段可达到的最低平均电流约为0.696uA,本篇笔记记录低功耗的适配和应用。

af36e894-1250-11ed-ba43-dac502259ad0.png

可通过以下链接查看RA MCU BSP:

https://github.com/RT-Thread/rt-thread/tree/master/bsp/renesas

瑞萨 RA 系列 MCU 开发板的 BSP 制作教程

https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/tutorial/make-bsp/renesas-ra/RA%E7%B3%BB%E5%88%97BSP%E5%88%B6%E4%BD%9C%E6%95%99%E7%A8%8B

在开始介绍低功耗前,先了解一下 RA2L1 MCU 产品群关键特性

  • 48MHz Arm Cortex-M23 CPU内核

  • 支持1.6V-5.5V宽范围工作电压

  • 超低功耗,提供64μA/MHz工作电流和250nA软件待机电流,快速唤醒时间小于5µs

  • 采用瑞萨110nm低功耗工艺,用于运行和睡眠/待机模式,并且专门为电池驱动应用设计了特殊掉电模式

  • 灵活的供电模式可实现更低的平均功耗,以满足多种应用需求

  • 集成了新一代创新型电容式触摸感应单元,无需外部元器件,降低BOM成本

  • 通过高精度(1.0%)高速振荡器温度传感器和多种供电接口端口等片上外围功能降低系统成本

  • 后台运行的数据闪存,支持一百万次擦除/编程循环

  • 采用LQFP封装,产品涵盖48引脚至100引脚封装

低功耗基础

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

af5780a4-1250-11ed-ba43-dac502259ad0.png

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

PM组件

PM组件是RT-Thread系统中针对电源管理而设计的基础功能组件, 组件采用分层设计思想,分离架构和芯片相关的部分,提取公共部分作为核心。支持多种运行模式和休眠模式的管理切换,以及低功耗定时器的管理。

PM 组件有以下特点:

  • PM 组件是基于模式来管理功耗

  • PM 组件可以根据模式自动更新设备的频率配置,确保在不同的运行模式都可以正常工作

  • PM 组件可以根据模式自动管理设备的挂起和恢复,确保在不同的休眠模式下可以正确的挂起和恢复

  • PM 组件支持可选的休眠时间补偿,让依赖 OS Tick 的应用可以透明使用

  • PM 组件向上层提供设备接口,如果使用了设备文件系统组件,那么也可以用文件系统接口来访问

PM组件支持的休眠模式有

af701812-1250-11ed-ba43-dac502259ad0.png

RA系列LPM功能

RA2 MCU支持的LPM类型有:

  • Sleep mode

  • Software Standby mode

  • Snooze mode

af9b87f4-1250-11ed-ba43-dac502259ad0.png

低功耗模式转换和触发源如图所示:

afd444b8-1250-11ed-ba43-dac502259ad0.png

不同模式间的切换如图所示,从图中也可以看出三种模式的功耗关系是Sleep>Snooze>Standby。

RA2芯片的休眠模式对应PM组件的模式关系:

afeffaa0-1250-11ed-ba43-dac502259ad0.png

配置LPM功能

要使用RA2系列芯片的LPM功能,需要进入bsp enesas a2l1-cpk目录。

  • 在menuconfig中使能LPM驱动,并勾选要开启的休眠模式,然后保存配置,生成MDK5工程。

afff65a8-1250-11ed-ba43-dac502259ad0.png

  • 打开PM组件和驱动后,需要增加idle的线程栈大小,可改为1024。

    b015a8ea-1250-11ed-ba43-dac502259ad0.png

  • 打开生成的MDK5工程project.uvprojx,然后打开FSP配置工具添加LPM相关配置。下图是需要添加的stack,包括三种LPM模式的配置以及低功耗定时器AGT1。

b0268ee4-1250-11ed-ba43-dac502259ad0.png

  • 创建LPM如下图所示新建r_lpm,需要根据使用的模式进行配置且不同模式要创建不同的r_lpm。下面将分别介绍三种不同模式的配置,创建步骤就不再赘述。

b047ac0a-1250-11ed-ba43-dac502259ad0.png

Sleep mode休眠模式

创建出r_lpm后需要修改Name和Low Power Mode这两个配置项。Name需要改为g_lpm_sleep,因为在驱动文件中已经定义了sleep模式对应的stack名称。Low Power Mode选择Sleep mode即可。

b0719010-1250-11ed-ba43-dac502259ad0.png

Standby mode软件待机模式

Name需要改为g_lpm_sw_standby。Low Power Mode选择Software Standby mode即可。

另外在此模式下还需要配置唤醒MCU的中断源,因为会使用到AGT1做为低功耗定时器所以AGT1的中断需要勾选。如果在应用中还需要其他中断源在此模式下唤醒MCU,则勾选对应选项即可。

b0966a3e-1250-11ed-ba43-dac502259ad0.png

Snooze mode小睡模式

Name需要改为g_lpm_sw_standby_with_snooze。Low Power Mode选择Snooze mode即可。

另外在此模式下同样要配置唤醒MCU的中断源,因为会使用到AGT1做为低功耗定时器所以AGT1的中断需要勾选。如果在应用中还需要其他中断源在此模式下唤醒MCU,则勾选对应选项即可。

b0b436a4-1250-11ed-ba43-dac502259ad0.png

AGT1低功耗定时器

在驱动中使用了MCU的AGT1做为PM组件的低功耗定时器,用于在休眠状态下的系统时钟补偿。

b0d11742-1250-11ed-ba43-dac502259ad0.png

完成上述配置步骤就已经把LPM低功耗模式的相关配置做完了。然后再根据应用要实现的功能配置其他外设。

低功耗DEMO

上文介绍了在RT-Thread的RA2L1上怎么配置LPM的不同模式,接下来就用一个小DEMO来验证下MCU在各种模式下的工作情况。

低功耗DEMO要实现的功能是,在CPK-RA2L1开发板上用S1按钮切换不同的低功耗模式,并在msh中打印出模式切换的提示信息。要实现这个功能需要在刚才的基础上添加一个低功耗的唤醒源。

添加配置

  • 创建IRQ中断,IRQ中断选择通道3,详细配置如下。

    b0ef415e-1250-11ed-ba43-dac502259ad0.png

    b1039686-1250-11ed-ba43-dac502259ad0.png

b12c1188-1250-11ed-ba43-dac502259ad0.png

  • 在刚才的Snooze和Standby模式的配置里添加IRQ3的唤醒源

    b147c8c4-1250-11ed-ba43-dac502259ad0.png

    b1683d16-1250-11ed-ba43-dac502259ad0.png

    b17a32aa-1250-11ed-ba43-dac502259ad0.png

  • 然后保存并生成配置代码。

添加测试代码

#include 
#ifdef BSP_USING_LPM#include #include #include 
#define WAKEUP_APP_THREAD_STACK_SIZE        512#define WAKEUP_APP__THREAD_PRIORITY         RT_THREAD_PRIORITY_MAX / 3#define WAKEUP_EVENT_BUTTON                 (1 << 0)
static rt_event_t wakeup_event;
#define USER_INPUT  "P004"#define LED2_PIN    "P501" /* Onboard LED pins */
void rt_lptimer_init(rt_lptimer_t  timer,                   const char *name,                   void (*timeout)(void *parameter),                   void       *parameter,                   rt_tick_t   time,                   rt_uint8_t  flag);
rt_err_t rt_lptimer_detach(rt_lptimer_t timer);rt_err_t rt_lptimer_start(rt_lptimer_t timer);rt_err_t rt_lptimer_stop(rt_lptimer_t timer);
rt_err_t rt_lptimer_control(rt_lptimer_t timer, int cmd, void *arg);
static struct rt_lptimer lptimer; 
static void timeout_cb(void *parameter){    rt_interrupt_enter();    rt_kprintf("
 lptimer callback 
");    rt_interrupt_leave();}
static void lptimer_init(void){    rt_lptimer_init(&lptimer,                    "lpm",                    timeout_cb,                    (void*)&wakeup_event,                    1000,                    RT_TIMER_FLAG_PERIODIC);}
static void lptimer_stop(void){    rt_lptimer_stop(&lptimer);}
static void lptimer_start(void){    rt_lptimer_start(&lptimer);}
static void led_app(void){    static uint8_t key_status = 0x00;    rt_uint32_t led2_pin = rt_pin_get(LED2_PIN);
    rt_pin_write(led2_pin, PIN_HIGH);    switch(key_status%4)    {    case 0:/* IDLE */    lptimer_stop();        rt_pm_release(PM_SLEEP_MODE_NONE);        rt_kprintf("	request:IDLE
");        rt_pm_request(PM_SLEEP_MODE_IDLE);        break;    case 1:/* DEEP */    lptimer_stop();    lptimer_start();        rt_pm_release(PM_SLEEP_MODE_IDLE);        rt_kprintf("	request:DEEP
");        rt_pm_request(PM_SLEEP_MODE_DEEP);        break;    case 2:/* STANDBY */    lptimer_stop();    lptimer_start();        rt_pm_release(PM_SLEEP_MODE_DEEP);        rt_kprintf("	request:STANDBY
");        rt_pm_request(PM_SLEEP_MODE_STANDBY);        break;    case 3:/* NONE */    lptimer_stop();        rt_pm_release(PM_SLEEP_MODE_STANDBY);        rt_kprintf("	request:NONE
");        rt_pm_request(PM_SLEEP_MODE_NONE);        break;    default:        break;    }
    key_status++;    rt_pin_write(led2_pin, PIN_LOW);}
static void wakeup_callback(void* p){    rt_event_send(wakeup_event, WAKEUP_EVENT_BUTTON);}
void wakeup_sample(void){    /* init */    rt_uint32_t pin = rt_pin_get(USER_INPUT);    rt_kprintf("
 pin number : 0x%04X 
", pin);    rt_err_t err = rt_pin_attach_irq(pin, PIN_IRQ_MODE_RISING, wakeup_callback, RT_NULL);    if (RT_EOK != err)    {        rt_kprintf("
 attach irq failed. 
");    }    err = rt_pin_irq_enable(pin, PIN_IRQ_ENABLE);    if (RT_EOK != err)    {        rt_kprintf("
 enable irq failed. 
");    }}
static void wakeup_init(void){    wakeup_event = rt_event_create("wakup", RT_IPC_FLAG_FIFO);    RT_ASSERT(wakeup_event != RT_NULL);    wakeup_sample();}
static void pm_mode_init(void){    rt_pm_release_all(RT_PM_DEFAULT_SLEEP_MODE);    rt_pm_request(PM_SLEEP_MODE_NONE);}
void pm_test_entry(void* para){    /* 唤醒回调函数初始化 */  wakeup_init();
    /* 电源管理初始化 */    pm_mode_init();
  lptimer_init();
    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)        {            led_app();        }    }}
int pm_test(void){
    rt_thread_t tid = rt_thread_create(            "pmtest",pm_test_entry,RT_NULL,512,10,10);    if(tid)        rt_thread_startup(tid);
    return 0;}MSH_CMD_EXPORT(pm_test, pm_test);// INIT_APP_EXPORT(pm_test);#endif

将DEMO代码加入到工程中,可以直接添加到hal_entry.c或新建一个源文件。

测试验证

然后编译下载。开发板连接串口工具,输入pm_test命令启动测试DEMO。

按下S1按钮切换工作模式,在DEEP、STANDBY模式下会启动低功耗定时器,当定时唤醒后会打印出回调接口的提示信息。

b19b43a0-1250-11ed-ba43-dac502259ad0.png

经测试:

1)串口通中输入“pm_test”,观测到电流在8.6mA5.8mA之间变化。

2)按下S1后,串口通中打印信息为“requestIDLE”,此时电流约为2.2mA

3)再次按下S1后,串口通中打印信息为“requestDEEP”,此时电流约为1593uA,并间隔产生lptimer中断。

4)再次按下S1后,串口通中打印信息为“requestSTANDBY”,此时电流约为2.4uA,并间隔产生lptimer中断。

5)再次按下S1后,串口通中打印信息为“requestNONE”,恢复为(1)的电流值,然后可循环执行此流程。

审核编辑:汤梓红
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • mcu
    mcu
    +关注

    关注

    146

    文章

    16984

    浏览量

    350276
  • 瑞萨
    +关注

    关注

    34

    文章

    22290

    浏览量

    86051
  • RT-Thread
    +关注

    关注

    31

    文章

    1272

    浏览量

    39913

原文标题:基于瑞萨 RA2L1 MCU 的RT-Thread 低功耗应用笔记

文章出处:【微信号:RTThread,微信公众号:RTThread物联网操作系统】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    RT-Thread记录(二、RT-Thread内核启动流程)

    在前面我们RT-Thread Studio工程基础之上讲一讲RT-Thread内核启动流程.
    的头像 发表于 06-20 00:30 4960次阅读
    <b class='flag-5'>RT-Thread</b>记录(二、<b class='flag-5'>RT-Thread</b>内核启动流程)

    RT-Thread编程指南

    RT-Thread编程指南——RT-Thread开发组(2015-03-31)。RT-Thread做为国内有较大影响力的开源实时操作系统,本文是RT-Thread实时操作系统的编程指南
    发表于 11-26 16:06 0次下载

    RT-Thread用户手册

    RT-Thread用户手册——本书是RT-Thread的编程手册,用于指导在RT-Thread实时操作系统环境下如何进行编 程。
    发表于 11-26 16:16 0次下载

    STM32超低功耗之移植 RT-Thread PM 组件原理分析

    一, 认识 PM 组件在上一篇的文章中,介绍了如何移植 RT-Thread PM 组件,PM 组件的作用是通过 RTOS 来统一的管理,超低功耗是一个细致的工作,所以在使用的时候必须要知道 PM
    发表于 12-31 18:59 2次下载
    STM32超<b class='flag-5'>低功耗</b>之移植 <b class='flag-5'>RT-Thread</b> PM 组件原理分析

    RT-Thread全球技术大会:萤石研发团队使用RT-Thread的技术挑战

    RT-Thread全球技术大会:研发团队使用RT-Thread的技术挑战         审核编辑:彭静
    的头像 发表于 05-27 11:36 1280次阅读
    <b class='flag-5'>RT-Thread</b>全球技术大会:萤石研发团队使用<b class='flag-5'>RT-Thread</b>的技术挑战

    RT-Thread全球技术大会:Kconfig在RT-Thread中的工作机制

    RT-Thread全球技术大会:Kconfig在RT-Thread中的工作机制               审核编辑:彭静
    的头像 发表于 05-27 14:49 1498次阅读
    <b class='flag-5'>RT-Thread</b>全球技术大会:Kconfig在<b class='flag-5'>RT-Thread</b>中的工作机制

    RT-Thread全球技术大会:关于瑞萨RA2L1-CPK低功耗CPU演示

    RT-Thread全球技术大会:关于瑞萨RA2L1-CPK低功耗CPU演示           审核编辑:彭静  
    的头像 发表于 05-27 15:23 1354次阅读
    <b class='flag-5'>RT-Thread</b>全球技术大会:关于瑞萨RA2L1-CPK<b class='flag-5'>低功耗</b>CPU演示

    RT-Thread全球技术大会:在RT-Thread上编写测试用例

    RT-Thread全球技术大会:在RT-Thread上编写测试用例           审核编辑:彭静
    的头像 发表于 05-27 16:28 1450次阅读
    <b class='flag-5'>RT-Thread</b>全球技术大会:在<b class='flag-5'>RT-Thread</b>上编写测试用例

    RT-Thread全球技术大会:RT-Thread测试用例集合案例

    RT-Thread全球技术大会:RT-Thread测试用例集合案例           审核编辑:彭静
    的头像 发表于 05-27 16:34 2056次阅读
    <b class='flag-5'>RT-Thread</b>全球技术大会:<b class='flag-5'>RT-Thread</b>测试用例集合案例

    RT-Thread学习笔记 RT-Thread的架构概述

    RT-Thread 简介 作为一名 RTOS 的初学者,也许你对 RT-Thread 还比较陌生。然而,随着你的深入接触,你会逐渐发现 RT-Thread 的魅力和它相较于其他同类型 RTOS
    的头像 发表于 07-09 11:27 4480次阅读
    <b class='flag-5'>RT-Thread</b>学习笔记 <b class='flag-5'>RT-Thread</b>的架构概述

    RT-Thread文档_RT-Thread 简介

    RT-Thread文档_RT-Thread 简介
    发表于 02-22 18:22 5次下载
    <b class='flag-5'>RT-Thread</b>文档_<b class='flag-5'>RT-Thread</b> 简介

    RT-Thread文档_RT-Thread 潘多拉 STM32L475 上手指南

    RT-Thread文档_RT-Thread 潘多拉 STM32L475 上手指南
    发表于 02-22 18:23 9次下载
    <b class='flag-5'>RT-Thread</b>文档_<b class='flag-5'>RT-Thread</b> 潘多拉 STM32L475 上手指南

    RT-Thread文档_RT-Thread SMP 介绍与移植

    RT-Thread文档_RT-Thread SMP 介绍与移植
    发表于 02-22 18:31 9次下载
    <b class='flag-5'>RT-Thread</b>文档_<b class='flag-5'>RT-Thread</b> SMP 介绍与移植

    基于RT-Thread Studio学习

    前期准备:从官网下载 RT-Thread Studio,弄个账号登陆,开启rt-thread学习之旅。
    的头像 发表于 05-15 11:00 3820次阅读
    基于<b class='flag-5'>RT-Thread</b> Studio学习

    RT-Thread v5.0.2 发布

    RT-Thread 代码仓库地址: ●  https://github.com/RT-Thread/rt-thread RT-Thread 5.0.2 版本发布日志详情: ●  htt
    的头像 发表于 10-10 18:45 1393次阅读
    <b class='flag-5'>RT-Thread</b> v5.0.2 发布