低功耗 Tickless 模式
低功耗 Tickless 模式简介
FreeRTOS 的低功耗 Tickless 模式是基于硬件层面的相应低功耗模式实现的,MCU 硬件层 面相关的低功耗模式请读者参考正点原子对应开发板开发指南中《低功耗实验》章节,本章主要介绍 FreeRTOS 的低功耗 Tickless 模式。
空闲任务中的低功耗 Tickless 处理
在整个系统的运行过程中, 其实大部分的时间是在执行空闲任务的,而空闲任务之所及叫做空闲任务,是因为空闲任务是 在系统中的所有其他都阻塞或被挂起时才运行的,因此可以在本该空闲任务执行的期间,让 MCU 进入相应的低功耗模式,接着在其他任务因被解除阻塞或其他原因,而准备运行的时候, 让 MCU 退出相应的低功耗模式,去执行相应的任务。在以上这一过程中,主要的难点在于, MCU 进入相应的低功耗模式后,如何判断有除空闲任务外的其他任务就绪,并退出相应的空闲 模式去执行就绪任务,也就是如何计算 MCU 进入相应低功耗模式的时间,而 FreeRTOS 的低功耗 Tickless 模式机制已经处理好了这个问题。
函数 portSUPPRESS_TICKS_AND_SLEEP()
此函数实际上是一个宏,该宏在portmacro.h文件中有定义,因为各种不同架构的不同MCU, 其进入低功耗模式的方式各有不同,因为 FreeRTOS 针对不同架构的不同 MCU,为用户提供了此宏,代码如下所示:
#ifndef portSUPPRESS_TICKS_AND_SLEEP
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) \
vPortSuppressTicksAndSleep( xExpectedIdleTime )
#endif
可 以 看 出 , 宏 portSUPPRESS_TICKS_AND_SLEEP() 默 认 是 被 定 义 成 函 数 vPortSuppressTickAndSleep(),此函数中有一段重要的代码,使得 CPU 进入睡眠模式,代码如下 所示:
__weak void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
{
/* 省略其他代码 */
/* 此宏用于执行进入相应低功耗模式之前的事务 */
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
/* 判断时长是否大于 0 */
if( xModifiableIdleTime > 0 )
{
__dsb( portSY_FULL_READ_WRITE );
/* 进入睡眠模式 */
__wfi();
__isb( portSY_FULL_READ_WRITE );
}
/* 此宏用于执行退出相应低功耗模式后的事务 */
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
/* 省略其他代码 */
}
从上面的代码中可以看出,调用了函数__wfi()使得 CPU 进入睡眠模式,且在 CPU 进入睡 眠 模 式 前 后 , 分 别 调 用 了 函 数 configPRE_SLEEP_RPOCESSING() 和 函 数 configPost_Sleep_ProCESSING()处理 CPU 进入睡眠模式之前和 CPU 退出睡眠模式之后要做的 事务,在这两个函数中,用户可以自行添加一些优化功耗的相关功能,例如管理 MCU 一些片 上外设的时钟、修改 MCU 的系统时钟或时钟源,使得 CPU 在进入睡眠模式后功耗达到最低, 在退出睡眠模式后又恢复功能。
低功耗 Tickless 模式相关配置项
在前面对 FreeRTOS 低功耗 Tickless 模式的简介中提到了 FreeRTOS 中针对该模式的几个配 置,如下表所示:
configUSE_TICKLESS_IDLE
此宏用于使能低功耗 Tickless 模式,当此宏定义为 1 时,系统会在进入空闲任务期间进入 相应的低功耗模式大于 configEXPECTED_IDLE_TIME_BEFORE_SLEEP 的时长。
configEXPECTED_IDLE_TIME_BEFORE_SLEEP
此宏用于定义系统进入相应低功耗模式的最短时长,如果系统在进入相应低功耗模式前, 计算出系统将进入相应低功耗的时长小于 configEXPECTED_IDLE_TIME_BEFORE_SLEEP 定 义的最小时长,则系统不进入相应的低功耗模式,要注意的是,此宏的值不能小于 2
configPRE_SLEEP_PROCESSING(x)
此宏用于定义一些需要在系统进入相应低功耗模式前执行的事务,例如可以在进入低功耗 模式前关闭一些 MCU 片上外设的时钟,以达到降低功耗的目的。
configPOSR_SLEEP_PROCESSING(x)
此宏用于定义一些需要在系统退出相应低功耗模式后执行的事务,例如开启在系统在进入 相应低功耗模式前关闭的 MCU 片上外设的时钟,以是系统能够正常运行。
使用低功耗模式时将configUSE_TICKLESS_IDLE置1,宏定义设定configPRE_SLEEP_PROCESSING(x)和configPOSR_SLEEP_PROCESSING(x)即可
Comments NOTHING