STM32 WFI выходит сразу после вызова - PullRequest
0 голосов
/ 19 сентября 2018

Я запускаю 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), он завершается немедленно.

Что я пропустил?

Ответы [ 2 ]

0 голосов
/ 14 мая 2019

Вы, вероятно, не остановили SysClk.Эти часы будут генерировать прерывание каждую миллисекунду и, следовательно, выходить из WFI.Попробуйте добавить:

   HAL_SuspendTick();
   // WFI 
   HAL_ResumeTick();
0 голосов
/ 20 сентября 2018

Проблема в том, что даже когда отладчик подключен к плате, он не будет работать.

Проблема была решена простым отключением отладчика STLink.Даже когда отладчик был подключен, но к отладчику не был подключен источник питания, он тоже не работал.

...