https://github.com/azure-rtos/th ... ower/tx_low_power.c
看了下源码实现,跟楼主位的英文描述是一致的,threadx这里条件编译很多,所以用法也很多,滴答唤醒是最简单的用法。复杂点的是借助真正的低功耗定时器来计数溢出时间,时间到了唤醒。并更新给滴答(这个是标准用法,看下面源码有实现)。
这里有个问题要注意,M7内核芯片,像H7的滴答定时器中断是无法唤醒停机模式的,而F1和F4可以唤醒,这点在使用的时候要尤其注意。
[C] 纯文本查看 复制代码 VOID tx_low_power_enter(VOID)
{
TX_INTERRUPT_SAVE_AREA
#ifdef TX_LOW_POWER_TIMER_SETUP
ULONG tx_low_power_next_expiration; /* The next timer experation (units of ThreadX timer ticks). */
ULONG timers_active;
#endif
/* Disable interrupts while we prepare for low power mode. */
TX_DISABLE
/* TX_LOW_POWER_TIMER_SETUP is a macro to a routine that sets up a low power
clock. If such routine does not exist, we can skip the logic that computes
the next expiration time. */
#ifdef TX_LOW_POWER_TIMER_SETUP
/* At this point, we want to enter low power mode, since nothing
meaningful is going on in the system. However, in order to keep
the ThreadX timer services accurate, we must first determine the
next ThreadX timer expiration in terms of ticks. This is
accomplished via the tx_timer_get_next API. */
timers_active = tx_timer_get_next(&tx_low_power_next_expiration);
/* There are two possibilities:
1: A ThreadX timer is active. tx_timer_get_next returns TX_TRUE.
Program the hardware timer source such that the next timer
interrupt is equal to: tx_low_power_next_expiration*tick_frequency.
In most applications, the tick_frequency is 10ms, but this is
completely application specific in ThreadX, typically set up
in tx_low_level_initialize. Note that in this situation, a low
power clock must be used in order to wake up the CPU for the next timeout
event. Therefore an alternative clock must be programmed.
2: There are no ThreadX timers active. tx_timer_get_next returns TX_FALSE.
2.a: application may choose not to keep the ThreadX internal
tick count updated (define TX_LOW_POWER_TICKLESS), therefore no need
to set up a low power clock.
2.b: Application still needs to keep ThreadX tick up-to-date. In this case
a low power clock needs to be set up.
*/
#ifndef TX_LOW_POWER_TICKLESS
/* We still want to keep track of time in low power mode. */
if (timers_active == TX_FALSE)
{
/* Set the next expiration to 0xFFFFFFF, an indication that the timer sleeps for
maximum amount of time the HW supports.*/
tx_low_power_next_expiration = 0xFFFFFFFF;
timers_active = TX_TRUE;
}
#endif /* TX_LOW_POWER_TICKLESS */
if (timers_active == TX_TRUE)
{
/* A ThreadX timer is active or we simply want to keep track of time. */
TX_LOW_POWER_TIMER_SETUP(tx_low_power_next_expiration);
}
#endif /* TX_LOW_POWER_TIMER_SETUP */
/* Set the flag indicating that low power has been entered. This
flag is checked in tx_low_power_exit to determine if the logic
used to adjust the ThreadX time is required. */
tx_low_power_entered = TX_TRUE;
/* Re-enable interrupts before low power mode is entered. */
TX_RESTORE
/* User code to enter low power mode. This allows the application to power down
peripherals and put the processor in sleep mode.
*/
#ifdef TX_LOW_POWER_USER_ENTER
TX_LOW_POWER_USER_ENTER;
#endif
/* If the low power code returns, this routine returns to the tx_thread_schedule loop. */
} |