前言
- RT-Thread PM框架主要用于PM(电源管理)、功耗调优(降低功耗),组件默认【关闭】,如果需要使用需要手动开启
- 部分用户对【功耗管理】并不专业,更不清楚如何使用RT-Thread PM框架管理产品的功耗
- 部分用户对【PM框架】使用存在【二义性】,理解片面,影响使用的体现,实际产品中很难应用起来
问题主线
- RT-Thread PM 框架的开启
- RT-Thread PM 框架的调试运行
- RT-Thread PM 框架的管理思想
- RT-Thread PM 框架的持续优化
PM框架文件
- 首先查看PM框架的实现文件的存放位置
- RT-Thread PM框架,目前在RT-Thread【标准版】中实现,Nano版中暂无法使用(后期会适配)
- PM 框架目前在BSP中适配了STM32L4平台,这个平台支持lptimer(低功耗定时器),可以使用PM框架的完整管理功能,但这不代表PM框架只适用于这个平台,其他的BSP平台稍做适配,依旧可以使用PM框架
- 本次【实例】在【NUCLEO-L476RG】开发板上实现PM框架的适配,开发板MCU:STM32L476RGT6
最小系统搭建
- 为了不影响默认RT-Thread源码架构,我把这个 【stm32l476-st-nucleo】单独重新复制出来做成独立的工程,用于PM框架功能验证。
- 注意只有STM32 BSP的project工程,没有STM32的libraries 与 RT-Thread 内核代码,无法使用。
- 把RT-Thread 内核代码与STM32 libraries 复制到新建的工程目录
- 自此基于【NUCLEO-L476RG】最小RT-Thread 标准版工程搭建完成
开启PM框架
- 通过RT-Thread ENV工具: menuconfig开启(如果不懂ENV、menuconfig操作,抓紧先去【磨刀】)
.config - RT-Thread Configuration
→ RT-Thread Components
→Device Drivers
→ [*] Using Power Management device drivers
- 配置menuconfig后,需要重新构建工程:
scons --target=mdk5
PM框架的调试
- PM框架并不是一个【纯软件】玩具,它的运行,离不开【平台MCU电源模式】【系统时钟配置】【外设开关】【引脚配置】等
- PM框架,通过适配后,可以真实的自动管理系统的【睡眠】【唤醒】【电源运行模式】
- PM框架的几个主要的msh 串口命令使用如下:
pm_release - release power management mode
pm_release_all - release power management mode count
pm_request - request power management mode
pm_module_releas - release module power mode
pm_module_releas - release power management mode count
pm_module_reques - request power management mode
pm_module_delay - module request delay sleep
pm_run - switch power management run mode
pm_dump - dump power management status
- 【答疑点一】开机后的【睡眠模式】,默认是 【PM_SLEEP_MODE_NONE】,如果开启PM框架后,发现系统无法【深睡眠】,注意这个问题。
- 通过pm_dump,可以明显的发现有个【模块】请求了【PM_SLEEP_MODE_NONE 0】这个模式。
- 为何PM框架,上来就请求一个【不睡眠】,还不自动释放?原因注意是开机后,此时用户没有请求,如果马上睡眠,系统可能无法正常的初始化。所以,开机时不睡眠的。
- 如果移除开机的【不睡眠】:用户在初始化完成后,手动调用:
rt_pm_module_release(PM_POWER_ID, PM_SLEEP_MODE_NONE);
- 【好像进入深睡眠了】,系统卡死,串口不能使用?是的,进入深睡眠,默认平台MCU如STM32,进入了STOP模式,串口外设已经不能使用了,
- 接下来讨论如何手动请求某个模式
- 开机后不请求模式,释放PM框架的【不睡眠】后,默认就进入了【DEEP模式】,还咋玩?
- 注意:
pm_request 1 请求了【IDLE】模式后,如果不释放,就会一直运行这个模式 - 【睡眠模式】有优先级的,有多个电源模式请求,运行【高功耗的】模式。
- 手动释放这个请求的模式:
pm_request 0 ,系统发现没有其他的请求,就默认进入深睡眠了 - 注意【引用计数】:多次请求,需要多次释放,如下:Idle 模式请求了 2次,需要释放2次,才能真正释放这个模式
- 也就是说,pm请求与释放,最好【成对出现】
msh >pm_dump
| Power Management Mode | Counter | Timer |
+-----------------------+---------+-------+
| None Mode | 0 | 0 |
| Idle Mode | 2 | 0 |
| LightSleep Mode | 0 | 0 |
| DeepSleep Mode | 0 | 1 |
| Standby Mode | 0 | 0 |
| Shutdown Mode | 0 | 0 |
+-----------------------+---------+-------+
pm current sleep mode: Idle Mode
pm current run mode: Normal Speed
| module | busy | start time | timeout |
+--------+------+------------+-----------+
+--------+------+------------+-----------+
rt_pm_request(PM_SLEEP_MODE_IDLE);
rt_pm_release(PM_SLEEP_MODE_IDLE);
rt_pm_release_all(PM_SLEEP_MODE_IDLE);
rt_pm_module_request(PM_I2C_ID, PM_SLEEP_MODE_IDLE);
rt_pm_module_release(PM_I2C_ID, PM_SLEEP_MODE_IDLE);
rt_pm_module_release_all(PM_I2C_ID, PM_SLEEP_MODE_IDLE);
/* 请求一个100ms的不睡眠 */
rt_pm_module_delay_sleep(PM_LCD_ID, 100);
小结
- RT-Thread PM框架的使用,需要实际上手的操作
- 本篇注意注重PM框架的环境的搭建、基础睡眠的操作。
|