Tickless 低功耗模式相关函数

FreeRTOS 的 Tickless 低功耗模式 是一种在系统空闲时暂停定时器中断(SysTick)的技术,允许微控制器(MCU)进入深度睡眠状态以降低功耗,直到下一个任务就绪或外部事件唤醒。此模式特别适用于电池供电的嵌入式设备。以下是 Tickless 模式的配置、核心 API 及实现原理的详细讲解。


Tickless 模式的核心原理

  1. 空闲时停用 SysTick
    当系统进入空闲状态且无任务需要运行时,FreeRTOS 关闭 SysTick 中断,并根据下一个任务的唤醒时间计算 MCU 可睡眠的时长。
  2. 动态唤醒
    使用低功耗定时器(如 RTC 或 LP Timer)在指定时间后唤醒 MCU,或依赖外部中断(如 GPIO、UART)提前唤醒。
  3. 时间补偿
    睡眠期间跳过 SysTick 中断,通过硬件定时器记录实际睡眠时间,并在唤醒后修正系统时间。

Tickless 模式的配置

FreeRTOSConfig.h 中启用并配置以下宏:

宏定义 说明
configUSE_TICKLESS_IDLE 设为 1 启用 Tickless 模式。
configEXPECTED_IDLE_TIME_BEFORE_SLEEP 定义进入低功耗的最小空闲时间(单位:Tick)。若空闲时间小于此值,不进入睡眠。默认为 2
configPRE_SLEEP_PROCESSING 用户自定义的预睡眠处理函数(关闭外设、降低时钟等)。
configPOST_SLEEP_PROCESSING 用户自定义的睡眠后恢复函数(恢复外设、时钟等)。

Tickless 模式的关键函数

1. 核心函数 portSUPPRESS_TICKS_AND_SLEEP()
  • 功能:由 FreeRTOS 内核调用,用于进入低功耗状态并计算睡眠时间。
  • 实现要求:需用户根据硬件平台实现此函数(通常位于 port.c 或独立驱动文件中)。
  • 函数原型
    void portSUPPRESS_TICKS_AND_SLEEP(TickType_t xExpectedIdleTime);
    
    • xExpectedIdleTime:预计的空闲时间(单位:Tick),即下一个任务的等待时间。
2. 预睡眠处理 configPRE_SLEEP_PROCESSING
  • 功能:在进入低功耗前关闭高功耗外设或调整系统时钟。
  • 示例
    void vPreSleepProcessing(uint32_t ulExpectedIdleTime) {
         
         
        // 关闭ADC、串口等外设
        HAL_ADC_Stop(&hadc);
        
### 实现原理 Tickless 模式是一种在嵌入式系统中降低功耗的机制,特别是在 FreeRTOS 等实时操作系统中。其核心思想是通过动态调整系统时钟中断(Tick 中断)的频率,使得在系统空闲时能够减少不必要的中断触发,从而延长 CPU 处于低功耗状态的时间。 在默认情况下,FreeRTOS 使用固定间隔的系统滴答(Tick)中断来管理任务调度,即使系统处于空闲状态,Tick 也会继续触发,导致 CPU 无法进入深度低功耗模式 [^2]。而在 Tickless 模式下,当系统检测到没有任务需要执行时,会暂时停止周期性的时钟中断,并根据预期的空闲时间调整下一次时钟中断的触发时刻。这样可以避免频繁唤醒 CPU,显著降低系统的平均功耗 [^1]。 具体来说,当系统进入空闲状态时,FreeRTOS 会调用 `portSUPPRESS_TICKS_AND_SLEEP()` 宏,该宏负责计算出下一个需要唤醒的时间点,并在此期间关闭或抑制时钟中断。当系统从低功耗模式中唤醒时,会重新启用时钟中断并更新 RTOS 的 tick 计数器,以确保任务调度的准确性 [^3]。 ### 配置方法 要在 FreeRTOS 中启用 Tickless 模式,需要进行以下配置步骤: 1. **定义宏 `configUSE_TICKLESS_IDLE`** 在 `FreeRTOSConfig.h` 文件中,将 `configUSE_TICKLESS_IDLE` 宏定义为 1 或 2: - 如果定义为 1,则表示启用了 Tickless Idle 功能,并且可以在具有 Tickless Idle 功能的接口中使用。 - 如果定义为 2,则除了启用功能外,还允许将 Tickless Idle 函数提供给任何 FreeRTOS 接口使用 [^3]。 2. **实现 `portSUPPRESS_TICKS_AND_SLEEP()` 宏** 该宏通常用于定义 Tickless Idle 函数的行为。它的原型如下: ```c void portSUPPRESS_TICKS_AND_SLEEP(TickType_t xExpectedIdleTime); ``` 此函数的主要作用是在系统进入低功耗模式之前,计算出下一个需要唤醒的时间点,并在此期间关闭或抑制时钟中断。同时,在系统从低功耗模式中唤醒后,重新启用时钟中断并更新 RTOS 的 tick 计数器 [^3]。 3. **处理退出低功耗模式后的事务** 在某些情况下,系统在退出低功耗模式后可能需要恢复一些外设的状态。为此,可以定义 `configPOST_SLEEP_PROCESSING(x)` 宏,用于指定在系统退出低功耗模式后需要执行的操作,例如重新开启之前关闭的外设时钟 [^5]。 4. **选择合适的低功耗模式** 根据具体的硬件平台和需求,可以选择不同的低功耗模式。例如,在 TencentOS-tiny 中,可以通过 `tos_tickless_wkup_alarm_install()` API 来安装一个唤醒报警器,以便在特定条件下唤醒系统 [^4]。 ### 示例代码 以下是一个简单的示例代码,展示了如何实现 `portSUPPRESS_TICKS_AND_SLEEP()` 宏: ```c void vPortSuppressTicksAndSleep(TickType_t xExpectedIdleTime) { // 计算下一个唤醒时间 uint64_t ullNextWakeTime = xExpectedIdleTime * portTICK_PERIOD_MS; // 关闭系统滴答定时器 SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; // 设置新的唤醒时间 SysTick->LOAD = ullNextWakeTime - 1; SysTick->VAL = 0; SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; // 进入低功耗模式 __WFI(); // 重新启用系统滴答定时器 SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; // 更新 RTOS 的 tick 计数器 vTaskStepTick(xExpectedIdleTime); } ``` 在这个示例中,首先关闭了系统滴答定时器,然后设置了新的唤醒时间,并进入了低功耗模式。当系统从低功耗模式中唤醒后,重新启用了系统滴答定时器,并更新了 RTOS 的 tick 计数器 [^3]。 ### 总结 通过上述配置和实现,可以有效地在 FreeRTOS 中启用 Tickless 模式,从而显著降低系统的平均功耗。这对于电池驱动设备、物联网(IoT)设备、低功耗传感器节点等应用场景尤为重要 [^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

九层指针

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值