在工作过程中,遇到这样一个产品,它基于 Cortex-M7 内核的 STM32F769 芯片,同时使用了 FreeRTOS 实时操作系统。

由于该产品使用电池供电,因此有着低功耗的需求。

接下来,我将简单描述一下 STM32 与 FreeRTOS 各自的低功耗特性,以及在配合使用时如何去实现产品的低功耗。

    一、STM32F769 芯片的三种低功耗模式[1]

STM32F769 支持三种低功耗模式,它们分别是:SLEEP、STOP和STANDBY,其省电能力依次增强。

  • SLEEP

在 SLEEP 模式下,只有 Cortex-M7 内核停止了工作,而外设仍然在运行。

在进入 SLEEP 模式后,所有中断均可唤醒 MCU,从而退出 SLEEP 模式。

  • STOP

在 STOP 模式下,内核停止工作,并且所有的时钟(如 HCLK, PCLK1, PCLK2 等)也停止工作,即所有外设停止工作,这里有一点要特别注意,此时 SYSTICK 也会被停掉。当然,我们产品中的 RTC 还在继续运行,因为它的时钟源为外部的 32.768K 晶振。

在进入 STOP 模式后,只有外部中断(EXTI)才能唤醒 MCU(由于 RTC 中断挂在外部中断线上,所以 RTC 中断也能唤醒 MCU)。

  • STANDBY

在 STANDBY 模式下,内核、所有的时钟、以及后备 1.2V 电源全部停止工作。

从 STANDBY 模式中唤醒后,系统相当于执行了一次复位操作,程序会从头来过。

综上所述,很明显地,在STM32 提供的这三种低功耗模式中,我们只能使用其中的 SLEEP 和 STOP 这两种,STANDBY 不适用。

关于 STM32769 更详细的低功耗内容介绍,请查看 Reference Manual 的4.3节 – Low-power modes.

    二、FreeRTOS 的低功耗实现[2]

在启动任务调度器时,FreeRTOS 会创建一个 IDLE 任务,其任务优先级最低,当且仅当所有其它任务均被阻塞时,IDLE 任务才会获得 CPU 使用权。

因此,可以很容易想到在 IDLE 任务里去实现进入与退出 STM32F769 的低功耗模式,即在切入 IDLE 任务后,让 STM32 也进入低功耗模式,而在即将切换出 IDLE 任务之前,去唤醒 STM32。

另外,较新版本的 FreeRTOS 中,增加了 Tickless mode,更详细的介绍请查看参考文献[2].

    三、整个产品的低功耗实现

那么在 IDLE 任务里,要如何去确定当前 STM32 应该是进入 SLEEP 还是 STOP 模式呢?

考虑到 SLEEP 和 STOP 两者之间的差异,即 SLEEP 下任何中断均可唤醒 STM32,而在 STOP 下,只能通过外部中断去唤醒,所以,我们的产品采用了如下的机制:

在可确定的将来的一段时间内,如果程序员知道这期间会发生一个非外部中断,这时,就不能让 STM32 进入 STOP 模式。因为,一旦进入了 STOP,STM32 就只能响应外部中断,而不能对非外部中断(如串口、I2C 等外设中断)作出响应。

举个例子会更便于理解。假设这样一个场景 —— 通过中断去读取 I2C 数据。在程序员配置好 I2C 读取数据中断后,系统就处于等待 I2C 中断的状态。之后如果产生了 I2C 中断,就代表数据已经读取完毕,程序员接下来就可以去处理数据了。

接上面的,在配置好 I2C 读取数据中断后,如果此时 IDLE 任务得到执行,那么,这种情况下就不能让 STM32 进入 STOP 模式,而只能进入 SLEEP 模式。一旦产生了 I2C 中断,则 STM32 就会从 SLEEP 中被唤醒。而如果之前 STM32 进入了 STOP 模式,那么这个 I2C 中断就会被略掉了。

所以,在这个产品中,我们提供了两个接口,disable_enter_stop_mode 和 enable_enter_stop_mode,分别用来告知,当前不能进入 STOP 模式和当前可以进入 STOP 模式了。

整理一下,我们可以得到如下的流程图:

如果当前可以进入 STOP 模式,在真正进入 STOP 之前,还有一件事要做——配置 RTC 唤醒定时器,让其在某一时刻来唤醒 STM32。具体能在 STOP 模式下睡多长时间,由 FreeRTOS 中的 prvGetExpectedIdleTime 接口计算得出。

RTC 唤醒定时器配置完成后,即可通过调用 HAL_PWR_EnterSTOPMode 让 STM32 进入 STOP 模式了。如果此时没有任何中断处于 PENDING 状态,则 STM32 会立即进入 STOP 模式,如果此时有中断处于 PENDING 状态,则 STM32 不会进入 STOP 模式,代码会继续往下执行。

在 STM32 处于 STOP 模式期间,如果产生了任何外部中断(EXTI 中断),则 STM32 会被立马唤醒,不管 RTC 唤醒定时器有没有超时。如果期间一直没有外部中断,那么 STM32 会一直处于 STOP 模式,直到 RTC 唤醒定时器超时,从而将 STM32 唤醒。

另外,由于在 STOP 下,为 FreeRTOS 提供心跳时钟的 SYSTICK 也停止了工作,所以,在被唤醒之后,还需要将在 STOP 下流逝的时间告诉 FreeRTOS。

总之,降低整个产品功耗的基本思想,就是让 FreeRTOS 仅可能多的时间处于 IDLE 任务,让 STM32 尽可能多的时间处于 STOP 模式,最终达到尽可能多的降低功耗的目的。

过段时间有空了,再把相关的代码整理一下贴出来,以供参考。

参考文献:

[1] STM32F76xxx Reference Manual

[2] FreeRTOS Low Power Support – Tickless Idle Mode

STM32与FreeRTOS实现低功耗的更多相关文章

  1. stm32f10x基于freeRTOS的低功耗实现

    0. 写在前面 没有太多时间更新,可能偶尔有时间就更新一些. 因为突然有项目用到了stm32f10x系列并且是电池驱动的,所以需要对功耗进行优化,其他CM3核心系列应该也同样适用. 1. 背景 Stm ...

  2. STM32之FreeRTOS

    STM32之FreeRTOS http://www.freertos.org/index.html http://www.freertos.org/a00090.html#ST http://www. ...

  3. STM32移植FreeRTOS(1)

    "STM32F103VET6<_>FreeRTOS" 1.项目功能实现 1)LED灯定时闪烁 2)KEY按键检测 3)FreeRTOS任务创建 4)串口输出程序运行状态 ...

  4. STM32 使用 FreeRTOS过程记录

    资源:http://blog.csdn.net/zhzht19861011/article/category/6191478 资源:可以下载安富莱的STM32-V5开发版资料中的FreeRTOS教程, ...

  5. STM32——项目需求之低功耗的停机模式

    在说低功耗之前,先要明白一个东西,那就是stm32中的事件和中断. 事件是中断的触发源,开放了对应的中断屏蔽位,则事件可以触发相应的中断.在STM32中,中断与事件不是等价的,一个中断肯定对应一个事件 ...

  6. STM32运行FreeRTOS出现prvTaskExitError错误死机

    文件port.c prvTaskExitError();任务退出错误,一个可能在任务里面写了return,另一个可能任务切换退出问题,入栈和出栈的时候出了问题. static void prvTask ...

  7. STM32用FreeRTOS时任务优先级和中断优先级说明

    下面对 FreeRTOS 优先级相关的几个重要知识点进行下说明,这些知识点在以后的使用中务必要掌握牢固. FreeRTOS 中任务的最高优先级是通过 FreeRTOSConfig.h 文件中的 co ...

  8. FreeRTOS 低功耗之 tickless 模式

    以下转载自安富莱电子: http://forum.armfly.com/forum.php 本章节为大家讲解 FreeRTOS 本身支持的低功耗模式 tickless 实现方法,tickless 低功 ...

  9. FreeRTOS 低功耗之睡眠模式

    以下转载自安富莱电子: http://forum.armfly.com/forum.php 低功耗是 MCU 的一项重要的指标,比如某些可穿戴的设备,其携带的电量有限,如果整个电路消耗的电量特别大的话 ...

随机推荐

  1. Vue.js起手式+Vue小作品实战

    本文是小羊根据Vue.js文档进行解读的第一篇文章,主要内容涵盖Vue.js的基础部分的知识的,文章顺序基本按照官方文档的顺序,每个知识点现附上代码,然后根据代码给予个人的一些理解,最后还放上在线编辑 ...

  2. 关于IOS的唯一标识总结

    APPLE官方宣布在2013年5月后,使用 UUID的APP将不能通过审核,同时APPLE增加了广告标识符(IDFA)和IDFV. 1.有什么方法获取UUID? //CFUUID CFUUIDRef ...

  3. 使用Ajax异步加载页面时,怎样调试该页面的Js

    前言-本人不是干前端的,所以有的名词不专业 在前端中,有时候会遇到这样的框架,http://172.17.11.151:8060/frontend/backend.html#1.html (通过解析U ...

  4. 记一次【求n以内的素数个数】的优化记录

    最近在leetCode上刷提,还是满锻炼人的,为以后面试打基础吧.不多说下面开始. 问题:求[2,n]之间的素数的个数. 来源:leetCode OJ 提示: Let's start with a i ...

  5. EditText添加了ImageSpan后,在两者中间不能输入纯文本

    严格来说是连续插入两个ImageSpan之后,在其中间不能够输入纯文本内容. 最后发现问题出现在了SpannableString在设置ImageSpan的时候第四个参数flag的问题. spannab ...

  6. LeetCode Sum of Two Integers

    原题链接在这里:https://leetcode.com/problems/sum-of-two-integers/ 题目: Calculate the sum of two integers a a ...

  7. C++学习笔记 构造&析构 友元 new&delete

    构造&析构函数 构造函数 定义:与类同名,可以有参可以无参,主要功能用于在类的对象创建时定义初始化的状态,无返回值,也不能用void修饰,构造函数不能被直接调用,必须通过new运算符在创建对象 ...

  8. 《奥威Power-BI案例应用:带着漫画看报告》腾讯课程开课啦

    元旦小假期过去了,不管是每天只给自己两次下床机会的你,还是唱K看电影逛街样样都嗨的你,是时候重振旗鼓,重新上路了!毕竟为了不给国家的平均工资水平拖后腿,还是要努力工作的.话说2016年已经过去了,什么 ...

  9. 区间K 大数查询

      算法训练 区间k大数查询   时间限制:1.0s   内存限制:256.0MB 问题描述 给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个. 输入格式 第一行包含一个数n,表示序列 ...

  10. Android Activity 管理 (AppManager)(非原创)

    AppManager 类: /** * 应用程序Activity管理类:用于Activity管理和应用程序退出 *  */ public class AppManager {     private ...