Я запускаю FreeRTOS и настраиваю тиканье на холостом ходу.Я хочу перевести микросхему STM32L432KC в режим STOP2
, но проблема в том, что инструкция WFI
завершается немедленно.
Я хочу разбудить микросхему, используя прерывание RTC WAKEUP
.
RTC инициализируется следующим образом:
/* Disable RTC registers write protection */
LL_RTC_DisableWriteProtection(RTC);
// Disable wake up timer to modify it.
LL_RTC_WAKEUP_Disable(RTC);
// Wait until the registers could get changed.
while(!LL_RTC_IsActiveFlag_WUTW(RTC))
;
/* Setting the Wakeup time to 60 s */
LL_RTC_WAKEUP_SetAutoReload(RTC, 60 - 1);
// CKSPRE has 1Hz frequency.
LL_RTC_WAKEUP_SetClock(RTC, LL_RTC_WAKEUPCLOCK_CKSPRE);
/* Enable RTC registers write protection */
LL_RTC_EnableWriteProtection(RTC);
LL_EXTI_EnableRisingTrig_0_31(LL_EXTI_LINE_20);
LL_EXTI_EnableIT_0_31(LL_EXTI_LINE_20);
Я пропустил исходный код инициализации, сгенерированный CubeMX.
В FreeRTOSConfig.h
Я настроил режим без галочки для использования своего сообщения и предварительных хуков:
#define configUSE_TICKLESS_IDLE 1
// You must manually convert milliseconds to ticks because pdMS_TO_TICKS won't work here.
#define configEXPECTED_IDLE_TIME_BEFORE_SLEEP 7
extern void pre_sleep(long unsigned int *expected_idle_time);
#define configPRE_SLEEP_PROCESSING(xExpectedIdleTime) pre_sleep(xExpectedIdleTime)
extern void post_sleep(long unsigned int *expected_idle_time);
#define configPOST_SLEEP_PROCESSING(xExpectedIdleTime) post_sleep(xExpectedIdleTime)
pre_sleep
функция устанавливает xExpectedIdleTime
в 0
, чтобы сообщить, что WFI
явно вызывается в предварительном хуке:
void pre_sleep(long unsigned int *expected_idle_time)
{
*expected_idle_time = 0;
enter_sleep_mode(LL_PWR_MODE_STOP2);
}
void post_sleep(long unsigned int *expected_idle_time) { }
Функция, которая входит в спящий режим:
void enter_sleep_mode(uint32_t low_power_mode)
/* ######## ENABLE WUT #################################################*/
/* Disable RTC registers write protection */
LL_RTC_DisableWriteProtection(RTC);
/* Enable wake up counter and wake up interrupt */
/* Note: Periodic wakeup interrupt should be enabled to exit the device
from low-power modes.*/
LL_RTC_WAKEUP_Enable(RTC);
LL_RTC_EnableIT_WUT(RTC);
LL_RTC_ClearFlag_WUT(RTC);
/* Enable RTC registers write protection */
LL_RTC_EnableWriteProtection(RTC);
/* ######## ENTER IN SLEEP MODE ######################################*/
/** Request to enter a sleep mode.
* Following procedure describe in STM32L4xx Reference Manual
* See PWR part, section Low-power modes.
*/
/* Reset Internal Wake up flag */
LL_RTC_ClearFlag_WUT(RTC);
/* Check that PWR Internal Wake-up is enabled */
if (LL_PWR_IsEnabledInternWU() == 0)
{
/* Need to enable the Internal Wake-up line */
LL_PWR_EnableInternWU();
}
/* Set the sleep mode */
LL_PWR_SetPowerMode(low_power_mode);
/* Set SLEEPDEEP bit of Cortex System Control Register */
LL_LPM_EnableDeepSleep();
/* This option is used to ensure that store operations are completed */
#if defined ( __CC_ARM)
__force_stores();
#endif
/* Request Wait For Interrupt */
__WFI();
}
Обработчик WAKEUP
:
void RTC_WKUP_IRQHandler(void)
{
if(LL_RTC_IsActiveFlag_WUT(RTC))
{
LL_RTC_ClearFlag_WUT(RTC);
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_20);
xTaskNotifyFromISR(wakeup_task_handle);
}
else
{
NVIC_DisableIRQ(RTC_WKUP_IRQn);
}
}
Я проверил NVIC на наличие ожидающих прерываний и увидел, что все регистры ICPR
и ISPR
установлены в ноль.
WFI
также завершается по запросу Debug Entry, но даже когда я не выполняю отладку (я использую STLinkV2), он завершается немедленно.
Что я пропустил?