STM32 WFI被调用后立即退出

时间:2018-09-19 10:11:40

标签: stm32 freertos sleep-mode

我运行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函数将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是否有任何待处理的中断,并且发现ICPRISPR寄存器都设置为零。

WFI也会在Debug Entry请求中退出,但是即使我不调试(我使用STLinkV2),它也会立即退出。

我错过了什么?

2 个答案:

答案 0 :(得分:0)

问题在于,即使将调试器连接到板上也无法正常工作。

只需断开STLink调试器即可解决此问题。即使连接了调试器但没有电源连接到调试器,它也无法正常工作。

答案 1 :(得分:0)

您可能没有停止SysClk。该时钟将每毫秒产生一次中断,因此会中断WFI。 尝试添加:

let dogs = [ 
{name: 'Beatrice', breed: 'Lurcher', owner: 'Tom'}, 
{name: 'Max', breed: 'Pug', owner: 'Izzi'}, 
{name: 'Poppy', breed: 'Pug', owner: 'Anat'} ];

function getPugOwners(dogs) { 
  return dogs.filter(dog => dog.breed=='Pug').map(dog => dog.owner);
}

console.log(getPugOwners(dogs));