cancel
Showing results for 
Search instead for 
Did you mean: 

WFI Race Condition

rcummings
Associate II
Posted on August 11, 2010 at 17:37

WFI Race Condition

9 REPLIES 9
rcummings
Associate II
Posted on May 17, 2011 at 14:01

I thought about that as a possibility, but won't disabling interrupts prevent the WFI from waking the chip back up?

RonCK

John F.
Senior
Posted on May 17, 2011 at 14:01

Hi,

Disable interrupts before preparing to sleep? Re-enable them on wake-up?

rcummings
Associate II
Posted on May 17, 2011 at 14:01

OK,  I fixed it, though if anyone has a better idea how to do this, please let me know.

void WaitForCycleTime(void)

{

   while(stBaseTimer.bCycleTimeFlag == FALSE)

   {

      if((SysTick->VAL > 500) && (SysTick->VAL < (CLOCKS_PER_CYCLE-500)))

      {

         __WFI();

      }

   }

}

The if statement inside the while prevents it from going to sleep within a 250us window around the occurrence of SysTick.  This window ensures that the flag that gets set in the SysTick interrupt has time to be updated.

regards,

RonCK

rcummings
Associate II
Posted on May 17, 2011 at 14:01

So you got me thinking about the possibility of playing with interrupt enabling/disabling.  I tried this:

void WaitForCycleTime(void)

{

   while(stBaseTimer.bCycleTimeFlag == FALSE)

   {

      __enable_interrupt();

      __WFI();

      __disable_interrupt();

   }

   __enable_interrupt();

}

This should disable interrupts just during the evaluation of the while loop.  This reduced the occurrence rate but did not eliminate it.  On the scope there is 16us from the falling edge of the EXTI interrupt to the rising edge of the SysTick interrupt.  That's 64 processor clocks.  How is it taking that long to roll over?  John, I will think about the WFE possibilities.

regards,

RonCK

John F.
Senior
Posted on May 17, 2011 at 14:01

Yes. It's going to depend on the mode you enter and how you can arrange to exit it.

Please see section 4.3 in the RM0008 Reference manual Rev 11. For example, consider using WFE as described below.

Exiting Sleep mode

If the WFI instruction is used to enter Sleep mode, any peripheral interrupt acknowledged by

the nested vectored interrupt controller (NVIC) can wake up the device from Sleep mode.

If the WFE instruction is used to enter Sleep mode, the MCU exits Sleep mode as soon as

an event occurs. The wakeup event can be generated either by:

�? enabling an interrupt in the peripheral control register but not in the NVIC, and enabling

the SEVONPEND bit in the Cortex-M3 System Control register. When the MCU

resumes from WFE, the peripheral interrupt pending bit and the peripheral NVIC IRQ

channel pending bit (in the NVIC interrupt clear pending register) have to be cleared.

�? or configuring an external or internal EXTI line in event mode. When the CPU resumes

from WFE, it is not necessary to clear the peripheral interrupt pending bit or the NVIC

IRQ channel pending bit as the pending bit corresponding to the event line is not set.

This mode offers the lowest wakeup time as no time is wasted in interrupt entry/exit.

domen23
Associate II
Posted on May 17, 2011 at 14:01

Why can't you just disable EXTI?

rcummings
Associate II
Posted on May 17, 2011 at 14:01

In this app the EXTI interrupts are measuring the frequency of two external lines.  Those frequencies are critical to the app, so I can't disable them.  I can't effectively ignore them during a window either.

regards,

RonCK

joseph239955_st
Associate II
Posted on May 17, 2011 at 14:01

Hi Ron,

Please use WFE instead of WFI for this idle loop.

void WaitForCycleTime(void)

{

    while(stBaseTimer.bCycleTimeFlag == FALSE)

   {

       __WFE();

    }

}

And put __SEV(); in your SysTick handler.

If a event is detected (generated by SEV) then the WFE will not enter sleep.

Hope this helps.

Joseph

rcummings
Associate II
Posted on May 17, 2011 at 14:01

Joseph, Stuart, and John, 

   I was able to get this WFE swap working this morning.  It seems to be a fine answer, and is decidedly more elegant than what I had forced on Wednesday evening.

Best regards,

Ron