首页 > 解决方案 > STM32 WFI被调用后立即退出

问题描述

我运行 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我配置了无滴答空闲以使用我的 post 和 pre 钩子:

#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函数设置xExpectedIdleTime0通知WFI在 pre-hook 中显式调用:

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)它也会立即退出。

我错过了什么?

标签: stm32freertossleep-mode

解决方案


问题是即使调试器连接到板上它也无法工作。

只需断开 STLink 调试器即可解决该问题。即使连接了调试器但没有电源连接到调试器,它也不起作用。


推荐阅读