当前位置: 首页 > backend >正文

32-低功耗与钩子函数

一、概述

        FreeRTOS 的低功耗 Tickless 模式是基于硬件层面的相应低功耗模式实现的,本章主要介绍 FreeRTOS 的低功耗 Tickless 模式,在整个系统的运行过程中,其实大部分的时间是在执行空闲任务的,而空闲任务之所及叫做空闲任务,是因为空闲任务是在系统中的所有其他都阻塞或被挂起时才运行的,因此可以在本该空闲任务执行的期间,让MCU 进入相应的低功耗模式,接着在其他任务因被解除阻塞或其他原因,而准备运行的时候,让 MCU 退出相应的低功耗模式,去执行相应的任务。在以上这一过程中,主要的难点在于,MCU 进入相应的低功耗模式后,如何判断有除空闲任务外的其他任务就绪,并退出相应的空闲模式去执行就绪任务,也就是如何计算 MCU 进入相应低功耗模式的时间,而 FreeRTOS 的低功耗 Tickless 模式机制已经处理好了这个问题。

二、FreeRTOS 低功耗 Tickless 模式相关配置项

在前面对 FreeRTOS 低功耗 Tickless 模式的简介中提到了 FreeRTOS 中针对该模式的几个配置,如下表所示:

1. configUSE_TICKLESS_IDLE

此宏用于使能低功耗 Tickless 模式,当此宏定义为 1 时,系统会在进入空闲任务期间进入

相应的低功耗模式大于 configEXPECTED_IDLE_TIME_BEFORE_SLEEP 的时长。

2. configEXPECTED_IDLE_TIME_BEFORE_SLEEP

此宏用于定义系统进入相应低功耗模式的最短时长,如果系统在进入相应低功耗模式前,

计算出系统将进入相应低功耗的时长小于 configEXPECTED_IDLE_TIME_BEFORE_SLEEP 定

义的最小时长,则系统不进入相应的低功耗模式,要注意的是,此宏的值不能小于 2(这里不能小于2个时钟节拍)。

3. configPRE_SLEEP_PROCESSING(x)--进入低功耗要做的事情

此宏用于定义一些需要在系统进入相应低功耗模式前执行的事务,例如可以在进入低功耗

模式前关闭一些 MCU 片上外设的时钟,以达到降低功耗的目的。

4. configPOSR_SLEEP_PROCESSING(x)--退出低功耗要做的事情

此宏用于定义一些需要在系统退出相应低功耗模式后执行的事务,例如开启在系统在进入

相应低功耗模式前关闭的 MCU 片上外设的时钟,以是系统能够正常运行。

需要在FreeRTOSconfig.h定义


//添加进入低功耗处理与退出低功能处理函数
extern void PRE_SLEEP_PROCESSING(void);
extern void POST_SLEEP_PROCESSING(void);
#define configPRE_SLEEP_PROCESSING( x )       PRE_SLEEP_PROCESSING()
#define configPOST_SLEEP_PROCESSING( x )      POST_SLEEP_PROCESSING()

三、配置

下面这两个上面已经配置了,可以再次检查一下

在FreeRTOS.h配置如下

#ifndef configEXPECTED_IDLE_TIME_BEFORE_SLEEP#define configEXPECTED_IDLE_TIME_BEFORE_SLEEP 2 //值不能小于2
#endif#if configEXPECTED_IDLE_TIME_BEFORE_SLEEP < 2#error configEXPECTED_IDLE_TIME_BEFORE_SLEEP must not be less than 2
#endif#ifndef configUSE_TICKLESS_IDLE#define configUSE_TICKLESS_IDLE 1  //使能
#endif

在FreeRTOSConfig.h配置如下

/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
standard names. */
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler
//添加进入低功耗处理与退出低功能处理函数
extern void PRE_SLEEP_PROCESSING(void);
extern void POST_SLEEP_PROCESSING(void);
#define configPRE_SLEEP_PROCESSING( x )         PRE_SLEEP_PROCESSING()
#define configPOST_SLEEP_PROCESSING( x )        POST_SLEEP_PROCESSING()#endif /* FREERTOS_CONFIG_H */

主函数主要部分的低功耗代码

/* 进入低功耗前所需要执行的操作 */
void PRE_SLEEP_PROCESSING(void)
{/* 关闭部分外设时钟,仅作演示 */RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, DISABLE);RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, DISABLE);RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, DISABLE);RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, DISABLE);RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, DISABLE);RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, DISABLE);RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, DISABLE);
}
/* 退出低功耗后所需要执行的操作 */
void POST_SLEEP_PROCESSING(void)
{/* 重新打开部分外设时钟,仅作演示 */RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);
}

三,钩子函数(回调函数)

1. configUSE_IDLE_HOOK

此宏用于使能使用空闲任务钩子函数,当宏 configUSE_IDLE_HOOK 设置为 1 时,使能使

用空闲任务钩子函数,用户需自定义相关钩子函数;当宏 configUSE_IDLE_HOOK 设置为 0 时,

则不使能使用空闲任务钩子函数。

2. configUSE_TICK_HOOK

此宏用于使能使用系统时钟节拍中断钩子函数,当宏 configUSE_TICK_HOOK 设置为 1 时

使 能 使 用 系 统 时 钟 节 拍 中 断 钩 子 函 数 , 用 户 需 自 定 义 相 关 钩 子 函 数 ; 当 宏

configUSE_TICK_HOOK 设置为 0 时,则不使能使用系统时钟节拍中断钩子函数。

3. configCHECK_FOR_STACK_OVERFLOW

此宏用于使能栈溢出检测,当宏 configCHECK_FOR_STACK_OVERFLOW 设置为 1 时

使用栈溢出检测方法一;当宏 configCHECK_FOR_STACK_OVERFLOW 设置为 2 时,栈溢出

检测方法二;当宏 configCHECK_FOR_STACK_OVERFLOW 设置为 0 时,不使能栈溢出检测。

4. configUSE_MALLOC_FAILED_HOOK

此 宏 用 于 使 能 使 用 动 态 内 存 分 配 失 败 钩 子 函 数 , 当 宏

configUSE_MALLOC_FAILED_HOOK 设置为 1 时,使能使用动态内存分配失败钩子函数,用

户需自定义相关钩子函数;当宏 configUSE_MALLOC_FAILED_HOOK 设置为 0 时,则不使能

使用动态内存分配失败钩子函数。

5. configUSE_DAEMON_TASK_STARTUP_HOOK

此 宏 用 于 使 能 使 用 定 时 器 服 务 任 务 首 次 执 行 前 的 钩 子 函 数 , 当 宏

configUSE_DEAMON_TASK_STARTUP_HOOK 设置为 1 时,使能使用定时器服务任务首次执

行前的钩子函数,此时用户需定义定时器服务任务首次执行的相关钩子函数;当宏

configUSE_DEAMON_TASK_STARTUP_HOOK 设置为 0 时,则不使能使用定时器服务任务首

次执行前的钩子函数。

源码例子:

https://download.csdn.net/download/m0_63622771/90897135

http://www.xdnf.cn/news/8855.html

相关文章:

  • 人工智能数学基础实验(四):最大似然估计的-AI 模型训练与参数优化
  • 电路图识图基础知识-回路编号及代号(四)
  • 微信小程序常用方法
  • QListWidgetItem的函数介绍
  • Leetcode刷题 | Day67_图论12_Floyd算法 / A*算法
  • Kafka Consumer工作流程
  • 大数据治理:大数据环境下协同办公系统的数据串联与深度分析
  • python打卡训练营打卡记录day36
  • Windows系统部署Redis
  • Spring Cloud项目登录认证从JWT切换到Redis + UUID Token方案
  • 阿里千问系列:Qwen3技术报告解读(上)
  • 力扣第451场周赛
  • Linux基本指令篇 —— cd指令
  • 练习实践--deepseek的使用环境搭建回顾--火山方舟
  • (每日一道算法题)实现 pow(x, n) 的快速幂解法
  • 本地处理 + GPU 加速 模糊视频秒变 4K/8K 修复视频老旧素材
  • 前端协同文档实现思路
  • LLaMA-Factory 微调模型与训练数据量对应关系
  • 【每日一题 | 2025年5.19 ~ 5.25】动态规划相关题
  • 篇章一 数据结构——前置知识(一)
  • Java 类加载机制详解
  • 【SCL编程案例】1-16整数的随机排列
  • leetcode hot100刷题日记——第一周没做好的题目总结
  • C#拾遗补漏之 Dictionary 详解
  • 【从0到1搞懂大模型】chatGPT 中的对齐优化(RLHF)讲解与实战(9)
  • uniapp报错mongo_cell_decision_not_found
  • Python年快乐!祝福语大全。
  • 从零开始:Python语言进阶之迭代器
  • JVM——JNI 的运行机制
  • Python模型优化技巧