FreeRTOS学习之路,以STM32F103C8T6为实验MCU(2-10:低功耗 Tickless 模式)

学习之路主要为FreeRTOS操作系统在STM32F103(STM32F103C8T6)上的运用,采用的是标准库编程的方式,使用的IDE为KEIL5。

注意!!!本学习之路可以通过购买STM32最小系统板以及部分配件的方式进行学习,也可以通过Proteus仿真的方式进行学习。

后续文章会同时发表在个人博客(jason1016.club)、CSDN;

视频会发布在bilibili(UID:399951374)

STM32F1 低功耗模式

proteus仿真无法实现

STM32 本身就支持低功耗模式,STM32F1共有三种低功耗模式:

● 睡眠(Sleep)模式。

● 停止(Stop)模式。

● 待机(Standby)模式。

1、睡眠(Sleep)模式

● 进入睡眠模式

进入睡眠模式有两种指令:WFI(等待中断)和WFE(等待事件)。根据 Cortex-M 内核的SCR(系统控制)寄存器可以选择使用立即休眠还是退出时休眠,当 SCR 寄存器的 SLEEPONEXIT(bit1)位为 0 的时候使用立即休眠,当为 1 的时候使用退出时休眠。关于立即休眠和退出时休眠的详细内容请参考《权威指南》“第 9 章 低功耗和系统控制特性”章节。

CMSIS(Cortex 微控制器软件接口标准)提供了两个函数来操作指令 WFI 和 WFE,我们可以直接使用这两个函数:__WFI 和__WFE。FreeRTOS 系统会使用 WFI 指令进入休眠模式。

● 退出休眠模式

如果使用 WFI 指令进入休眠模式的话那么任意一个中断都会将 MCU 从休眠模式中唤醒,如果使用 WFE 指令进入休眠模式的话那么当有事件发生的话就会退出休眠模式,比如配置一个 EXIT 线作为事件。

当 STM32F103 处于休眠模式的时候 Cortex-M3 内核停止运行,但是其他外设运行正常,比如 NVIC、SRAM 等。休眠模式的功耗比其他两个高,但是休眠模式没有唤醒延时,应用程序可以立即运行

2、停止(Stop)模式

停止模式基于 Cortex-M3 的深度休眠模式与外设时钟门控,在此模式下 1.2V 域的所有时钟都会停止,PLL、HSI 和 HSE RC 振荡器会被禁止,但是内部 SRAM 的数据会被保留。调压器可以工作在正常模式,也可配置为低功耗模式。如果有必要的话可以通过将 PWR_CR 寄存器的FPDS 位置 1 来使 Flash 在停止模式的时候进入掉电状态,当 Flash 处于掉电状态的时候 MCU从停止模式唤醒以后需要更多的启动延时。

3、待机(Standby)模式

相比于前面两种低功耗模式,待机模式的功耗最低。待机模式是基于 Cortex-M3 的深度睡眠模式的,其中调压器被禁止。1.2V 域断电,PLL、HSI 振荡器和 HSE 振荡器也被关闭。除了备份区域和待机电路相关的寄存器外,SRAM 和其他寄存器的内容都将丢失。

退出待机模式的话会导致 STM32F1 重启,所以待机模式的唤醒延时也是最大的。实际应用中要根据使用环境和要求选择合适的待机模式。

二、Tickless 模式

1、模式原理

一般的简单应用中处理器大量的时间都在处理空闲任务,所以我们就可以考虑当处理器处理空闲任务的时候就进入低功耗模式,当需要处理应用层代码的时候就将处理器从低功耗模式唤醒。FreeRTOS 就是通过在处理器处理空闲任务的时候将处理器设置为低功耗模式来降低能耗。一般会在空闲任务的钩子函数中执行低功耗相关处理,比如设置处理器进入低功耗模式、关闭其他外设时钟、降低系统主频等等。

我们知道 FreeRTOS 的系统时钟是由滴答定时器中断来提供的,系统时钟频率越高,那么滴答定时器中断频率也就越高。18.1 小节讲过,中断是可以将 STM32F03 从睡眠模式中唤醒,周期性的滴答定时器中断就会导致 STM32F103 周期性的进入和退出睡眠模式。因此,如果滴答定时器中断频率太高的话会导致大量的能量和时间消耗在进出睡眠模式中,这样导致的结果就是低功耗模式的作用被大大的削弱。

为此,FreeRTOS 特地提供了一个解决方法——Tickless 模式,当处理器进入空闲任务周期以后就关闭系统节拍中断(滴答定时器中断),只有当其他中断发生或者其他任务需要处理的时候处理器才会被从低功耗模式中唤醒

为此我们将面临两个问题:

问题一:关闭系统节拍中断会导致系统节拍计数器停止,系统时钟就会停止。

FreeRTOS 的系统时钟是依赖于系统节拍中断(滴答定时器中断)的,如果关闭了系统节拍中断的话就会导致系统时钟停止运行,这是绝对不允许的!该如何解决这个问题呢?我们可以记录下系统节拍中断的关闭时间,当系统节拍中断再次开启运行的时候补上这段时间就行了。这时候我们就需要另外一个定时器来记录这段该补上的时间,如果使用专用的低功耗处理器的话基本上都会有一个低功耗定时器,比如 STM32L4 系列(L 系列是 ST 的低功耗处理器)就有一个叫做 LPTIM(低功耗定时器)的定时器。STM32F103 没有这种定时器那么就接着使用滴答定时器来完成这个功能,具体实现方法后面会讲解。

问题二:如何保证下一个要运行的任务能被准确的唤醒?

即使处理器进入了低功耗模式,但是我的中断和应用层任务也要保证及时的响应和处理。中断自然不用说,本身就可以将处理器从低功耗模式中唤醒。但是应用层任务就不行了,它无法将处理器从低功耗模式唤醒,无法唤醒就无法运行!这个问题看来很棘手,既然应用层任务无法将处理器从低功耗模式唤醒,那么我们就借助其他的力量来完成这个功能。如果处理器在进入低功耗模式之前能够获取到还有多长时间运行下一个任务那么问题就迎刃而解了,我们只需要开一个定时器,定时器的定时周期设置为这个时间值就行了,定时时间到了以后产生定时中断,处理器不就从低功耗模式唤醒了。这里似乎又引出了一个新的问题,那就是如何知道还有多长时间执行下一个任务?这个时间也就是低功耗模式的执行时间,值得庆辛的是 FreeRTOS已经帮我们完成了这个工作。

2、Tickless具体实现

//宏定义:(在FreeRTOSconfig.h中设置)
#define configUSE_TICKLESS_IDLE 1 //1 启用低功耗 tickless 模式
/*当此宏为0时表示不使用Tickless为1时表示使用系统自带的低功耗模式(Sleep模式+滴答定时器计时)为2时表示自定义实现Tickless功能*//***************************************************************************************************************/
/*                                FreeRTOS与低功耗管理相关配置                                                    */
/***************************************************************************************************************/
extern void PreSleepProcessing(uint32_t ulExpectedIdleTime);
extern void PostSleepProcessing(uint32_t ulExpectedIdleTime);#define configPRE_SLEEP_PROCESSING                   PreSleepProcessing        //进入低功耗模式前要做的处理
#define configPOST_SLEEP_PROCESSING                   PostSleepProcessing        //退出低功耗模式后要做的处理

//进入低功耗模式前需要处理的事情
//ulExpectedIdleTime:低功耗模式运行时间
void PreSleepProcessing(uint32_t ulExpectedIdleTime)
{//关闭某些低功耗模式下不使用的外设时钟,此处只是演示性代码RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,DISABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,DISABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,DISABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,DISABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF,DISABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG,DISABLE);
}
//退出低功耗模式以后需要处理的事情
//ulExpectedIdleTime:低功耗模式运行时间
void PostSleepProcessing(uint32_t ulExpectedIdleTime)
{//退出低功耗模式以后打开那些被关闭的外设时钟,此处只是演示性代码RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG,ENABLE); 
}

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

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

相关文章

因为计算机中丢失MSVCP140.dll,无法启动此程序运行软件的解决方法

msvcp140.dll重新安装五个解决方法与msvcp140.dll文件的作用和丢失对电脑的影响介绍 正文: 在计算机使用过程中,我们经常会遇到一些错误提示,其中最常见的就是“缺少xxx.dll文件”。而msvcp140.dll就是其中之一。那么,msvcp140.…

(三)Pytorch快速搭建卷积神经网络模型实现手写数字识别(代码+详细注解)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言Q1:卷积网络和传统网络的区别Q2:卷积神经网络的架构Q3:卷积神经网络中的参数共享,也是比传统网络的优势所在4、 具体的实现代码网络搭建…

Linux Nmap命令解析(Nmap指令)(功能:主机发现、ping扫描、arp扫描、端口扫描、服务版本检测、操作系统识别等)

文章目录 Linux Nmap 命令解析简介Nmap 的核心功能主机发现端口扫描服务版本检测OS 指纹识别(操作系统指纹识别)脚本扫描 安装 NmapNmap 命令结构Nmap 命令文档英文中文 主机发现Ping 扫描ARP 扫描关于nmap -PR(ARP Ping Scan)和n…

CentOS7.9虚拟机EDA环境,支持模拟集成电路、数字集成电路、数模混合设计全流程,包含工艺库

目录 前言一、配置准备工作1.1 网盘文件说明1.2 EDA工具介绍 二、虚拟机运行2.1 虚拟机工具启动2.2 软件配置使用2.3 Module工具切换环境变量和软件版本 获取方法附录:部分EDA工具运行效果图 前言 搭建了CentOS7.9虚拟机环境,工具包括但不限于&#xff…

json处理由fastjson换jackjson

fastjson没有jackjson稳定,所以换成jackjson来处理对象转json和json转对象问题。 首先下载jackjson包,三个都要引用 然后修改实现类 package JRT.Core.Util;import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.ja…

安防视频监控汇聚EasyNVR视频集中存储平台级联上级时下级未回复原因是什么?该如何解决?

安防监控系统EasyNVR视频云存储平台可实现设备接入、实时直播、录像、检索与回放、视频云存储、视频分发等视频能力服务,可覆盖全终端平台(pc、手机、平板等终端),在智慧工厂、智慧工地、智慧社区、智慧校园等场景中有大量落地应用…

unity3d地图、地面跟着NPC跑

清除烘焙后,再 将地图、地面的设置为非静态。只设置NPC的寻路路面为静态,再烘焙

VS2010配置opencv2.4.10

1.下载opencv2.4.10,百度网盘链接如下: 链接:https://pan.baidu.com/s/1UdoQJbRUEB_G2urT703xYQ 提取码:7lbd 2.运行opencv-2.4.10.exe,将文件提取到一个自定义目录里: 3.添加系统环境变量 在“系统变量…

持续集成交付CICD:GitLab Webhook触发Jenkins流水线

目录 一、实验 1.Jenkins远程下载GiaLab仓库代码 2.curl远程触发Jenkins流水线 3.GitLab Webhook触发Jenkins流水线 二、问题 1.GitLab配置Webhook时报错 一、实验 1.Jenkins远程下载GiaLab仓库代码 (1) Jenkins添加选项参数 (2)添加字符参数 (3)查看构建参数情况 (4)添…

C++ 背包理论基础01 + 滚动数组

背包问题的重中之重是01背包 01背包 有n件物品和一个最多能背重量为w 的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大。 每一件物品其实只有两个状态,取或者不…

桥接设计模式

package com.jmj.pattern.bridge;/*** 视频文件(实现化角色)*/ public interface VideoFile {void decode(String fileName); }package com.jmj.pattern.bridge;public class RmvFile implements VideoFile{Overridepublic void decode(String fileName) {System.out.println(&…

语文老师怎么和家长沟通

作为一位语文老师,深知教育不单单是传授知识,更是引导学生发展潜能,培养品格。而在这个过程中,与家长建立良好的沟通关系是至关重要的。 建立信任关系 与家长沟通的第一步是建立信任关系。作为老师,需要展现出专业、热…

堆排序(详解)

在上篇文章中,我们说利用堆的插入和删除也可以排序数据,但排序的只是堆里面的数组;同时每次排序数据都要单独写一个堆的实现,很不方便,这次就来着重讲讲如何使用堆排序。 1.建堆 给了你数据,要利用堆对数据…

开发定制化抖音票务小程序的技术解析

通过定制化抖音票务小程序,可以为用户提供更加个性化的活动体验,同时也为企业和品牌提供了更多的营销机会。 一、小程序开发框架的选择 在开发定制化抖音票务小程序之前,选择合适的小程序开发框架至关重要。目前,主流的小程序框…

Unity之ARFoundation如何实现BodyTracking人体跟踪

前言 ARBodyTracking,就是指通过手机AR扫描并精确的捕获人物的肢体部位的技术。如下图所示 这项技术目前是有苹果的ARKit提供,苹果的body tracking 功能需要使用配备 TrueDepth 摄像头的设备,配备 A12 仿生芯片、运行 iOS 13 或更高版本的设备,比如 iPhone X 及更新机型。…

【开源】基于JAVA的城市桥梁道路管理系统

项目编号: S 025 ,文末获取源码。 \color{red}{项目编号:S025,文末获取源码。} 项目编号:S025,文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统展示四、核心代码4.1 查询城市桥…

SpringBoot RestTemplate 的使用

一、简介 RestTemplate 在JDK HttpURLConnection、Apache HttpComponents、OkHttp等基础上&#xff0c;封装了更高级别的API&#xff0c;默认依赖JDK HttpURLConnection&#xff0c;连接方式默认长连接。 二、使用 2.1、引入依赖 <dependency><groupId>org.spri…

1-2-3图片的排列

目录 1.展示效果 2.基础方法源码展示 ①div部分展示 ②css部分展示 3.接口方法源码展示 scoped使用 1.展示效果 2.基础方法源码展示 ①div部分展示 <view class"container"> <view class"cover"> <im…

独家精品!git action发布electron成功的关键

首先来说git action真心是个坑爹货&#xff0c;使用起来太费劲了&#xff0c;各种报错一大堆。 再加上electron这个更坑爹的东西&#xff0c;二者合璧要把你累死一层皮。 昨天经过反复测试&#xff0c;通过无数次的失败&#xff0c;查找&#xff0c;试验&#xff0c;再失败&a…

在Linux中对Docker中的服务设置自启动

先在Linux中安装docker&#xff0c;然后对docker中的服务设置自启动。 安装docker 第一步&#xff0c;卸载旧版本docker。 若系统中已安装旧版本docker&#xff0c;则需要卸载旧版本docker以及与旧版本docker相关的依赖项。 命令&#xff1a;yum -y remove docker docker-c…