查看: 2837|回复: 0

FreeRTOS_DeepSleep例程中,睡眠前关闭了全局中断,为啥还能被低功耗定时器中断唤醒?

[复制链接]

2

主题

3

帖子

150

积分

中级工程师

Rank: 2

积分
150
发表于 2023-2-3 10:12:58 | 显示全部楼层 |阅读模式

最新0.43例程。vApplicationSleep函数中,如下代码,1处关闭了全局中断,2处睡眠,3处唤醒以后才能启用全局中断。
那么2处睡眠的时候,低功耗定时器或者RTC中断似乎都能正常唤醒MCU,关中断为什么不起作用?此处的关中断对哪些中断生效?

void vApplicationSleep ( TickType_t xExpectedIdleTime )
{
    unsigned long ulLowPowerTimeBeforeSleep, ulLowPowerTimeAfterSleep;
    eSleepModeStatus eSleepStatus;
    FL_LPTIM32_Enable(LPTIM32);
    /* Read the current time from a time source that will remain operational
    while the microcontroller is in a low power state. */
    ulLowPowerTimeBeforeSleep = ulGetExternalTime ();

    /* Stop the timer that is generating the tick interrupt. */
    prvStopTickInterruptTimer ();

    /* Enter a critical section that will not effect interrupts bringing the MCU
    out of sleep mode. */
    disable_interrupts ();    // 1

    /* Ensure it is still ok to enter the sleep mode. */
    eSleepStatus = eTaskConfirmSleepModeStatus ();

    if ( eSleepStatus == eAbortSleep )
    {
      /* A task has been moved out of the Blocked state since this macro was
      executed, or a context siwth is being held pending.  Do not enter a
      sleep state.  Restart the tick and exit the critical section. */
      prvStartTickInterruptTimer ();
      enable_interrupts ();
    }
    else
    {
      if ( eSleepStatus == eNoTasksWaitingTimeout )
      {
        /* It is not necessary to configure an interrupt to bring the
        microcontroller out of its low power state at a fixed time in the
        future. */
        prvSleep ();
      }
      else
      {

        /* Configure an interrupt to bring the microcontroller out of its low
        power state at the time the kernel next needs to execute.  The
        interrupt must be generated from a source that remains operational
        when the microcontroller is in a low power state. */
        vSetWakeTimeInterrupt ( xExpectedIdleTime - 1 );

        /* Enter the low power state. */
        prvSleep ();    // 2

        /* Determine how long the microcontroller was actually in a low power
        state for, which will be less than xExpectedIdleTime if the
        microcontroller was brought out of low power mode by an interrupt
        other than that configured by the vSetWakeTimeInterrupt() call.
        Note that the scheduler is suspended before
        portSUPPRESS_TICKS_AND_SLEEP() is called, and resumed when
        portSUPPRESS_TICKS_AND_SLEEP() returns.  Therefore no other tasks will
        execute until this function completes. */
        ulLowPowerTimeAfterSleep = ulGetExternalTime ();
        FL_LPTIM32_Disable(LPTIM32);
        /* Correct the kernels tick count to account for the time the
        microcontroller spent in its low power state. */
        vTaskStepTick ( ( ulLowPowerTimeAfterSleep - ulLowPowerTimeBeforeSleep ) );
      }

      /* Exit the critical section - it might be possible to do this immediately
      after the prvSleep() calls. */
      enable_interrupts ();  // 3

      /* Restart the timer that is generating the tick interrupt. */
      prvStartTickInterruptTimer ();
    }
}


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表