FreeRTOS的低功耗Tickless模式与空闲函数

目录

1.了解低功耗Tickless模式

1.1 STM32F1 低功耗模式

1  睡眠(Sleep)模式

2  停止(Stop)模式

 3  待机(Standby)模式

1.2 Tickless 模式详解

1.2.1  如何降低功耗?

1.2.2 Tickless 具体实现

1、宏configUSE_TICKLESS_IDLE

 2、宏portSUPPRESS_TICKS_AND_SLEEP()

3、宏configPRE_SLEEP_PROCESSING ()和 configPOST_SLEEP_PROCESSING()

下面是函数实际的使用:

4、宏configEXPECTED_IDLE_TIME_BEFORE_SLEEP

2.FreeRTOS的空闲函数

2.1 空闲函数简介

2.2 空闲任务的创建

2.3 空闲任务函数

2.4 空闲任务钩子函数详解

2.4.1 钩子函数

2.4.2 空闲任务钩子函数

总结:


1.了解低功耗Tickless模式

      很多应用场合对于空耗的要求很严格,比如长期无人照看的数据采集仪器,可穿戴设备等。 其实很多 MCU 都有相应的低功耗模式,以此来降低设备运行时的功耗,进行裸机开发的时候就可以使用这些低功耗模式。但是现在我们要使用操作系统,因此操作系统对于低功耗的支持也显得尤为重要,这样硬件与软件相结合,可以进一步降低系统的功耗。这样开发也会方便很多,毕竟系统已经原生支持低功耗了,我们只需要按照系统的要求来做编写相应的应用层代码即可。FreeRTOS 提供了一个叫做 Tickless 的低功耗模式。

1.1 STM32F1 低功耗模式

      STM32 本身就支持低功耗模式,以本教程使用的 STM32F429 为例,共有三种低功耗模式:

 睡眠(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 域的所有时钟都会停止,PLLHSI  HSE RC 振荡器会被禁止,但是内部 SRAM 的数据会被保留。调压器可以工作在正常模式,也可配置为低功耗模式。如果有必要的话可以通过将 PWR_CR 寄存器的FPDS位置1来使 Flash 在停止模式的时候进入掉电状态,当 Flash 处于掉电状态的时候 MCU 从停止模式唤醒以后需要更多的启动延时。停止模式的进入和退出如表所示:

 3  待机(Standby)模式

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

     退出待机模式的话会导致 STM32F1  启,所以待机模式的唤醒延时也是最大的。实际应 用中要根据使用环境和要求选择合适的待机模式。关于 STM32  低功耗模式的详细介绍和使用 请参考 ST 

### FreeRTOS 实现低功耗模式配置方法 #### 1. 配置 `FreeRTOSConfig.h` 为了使能并配置 FreeRTOSTickless 模式,在 `FreeRTOSConfig.h` 文件中需设置特定宏定义。 - **使能启用 Tickless 模式** 定义 `configUSE_TICKLESS_IDLE` 宏为 1 来开启此功能。这允许系统在空闲时停止计数器中断,从而减少能耗[^1]。 ```c #define configUSE_TICKLESS_IDLE 1 ``` - **配置进入低功耗模式的时间** 设置 `configEXPECTED_IDLE_TIME_BEFORE_SLEEP` 宏来指定预计的空闲时间长度。如果预测到即将有一段时间不会有任何任务运行,则可以安全地进入更深的休眠状态。 ```c #define configEXPECTED_IDLE_TIME_BEFORE_SLEEP ( ticktype_t )50 / portTICK_PERIOD_MS; ``` #### 2. 进入 Tickless 模式的条件 当所有可执行的任务都处于阻塞或挂起状态下,并且满足预设的空闲周期阈值时,FreeRTOS 将准备进入低功耗模式。此时会调用钩子函数 `vApplicationTickHook()` 或者直接跳转至 `vPortSuppressTicksAndSleep()` 函数处理具体的节能操作。 #### 3. 执行低功耗的具体过程 ##### 3.1 使用 `vPortSuppressTicksAndSleep()` 该函数负责暂停滴答定时器(即关闭定期产生的硬件中断),并通过 WFI/WFE 指令让 CPU 进入等待事件/中断的状态,直到下一个外部触发唤醒为止[^4]。 ```c void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) { /* 关闭滴答中断 */ /* 调整电源管理模式 */ /* 发送CPU进入待机命令 */ } ``` ##### 3.2 自定义低功耗函数 `MySleep()` 对于某些应用场景可能需要更精细控制电源行为的情况,可以在项目里编写自己的睡眠逻辑作为替代方案: ```c static void prvSetupTimerForRunTimeStats(void); extern uint32_t ulLowPowerTickCount; void MySleep(TickType_t expected_idle_time) { /* 用户自定义前处理动作 */ /* 停止滴答中断源 */ prvStopTimer(); /* 计算预期休眠时长 */ ulLowPowerTickCount += expected_idle_time; /* ARM 架构下使用WFI指令 */ __asm volatile ("wfi"); /* 用户自定义后恢复动作 */ } /* 替换默认实现 */ #define vPortSuppressTicksAndSleep(x) MySleep((x)) ``` 上述代码展示了如何创建一个名为 `MySleep` 的新函数用于代替标准库中的 `vPortSuppressTicksAndSleep` 。这样做可以让开发者根据具体需求调整系统的响应方式和性能表现[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值