This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How to avoid interrupt handling is not missed with sd_app_evt_wait()?

For example, I have the following code:

bool interruptFlag;

void interruptHanler(void)
{
   interruptFlag = true;
}

void main(void)
{
  while (true)
  {
    if (interruptFlag)
    { interruptFlag = false;
      processThings(); // process heavier things here
    }
    // CRITICAL POINT: what if interrupt occurs here?
    sd_app_evt_wait();
  }
}

What if the interrupt occurs after checking the flag, but just before entering sd_app_evt_wait()? Does the sd_app_evt_wait() then just block and the system eventually jams to wait for the next possible interrupt?

The question: If the above speculation is true, can I somehow disable interrupts in-between checking my software flag and entering the sd_app_evt_wait()? The code could then look something like:

sd_nvic_critical_region_enter(...);
while (interruptFlag) // loop again if interrupt occurs while processing previous
{  sd_nvic_critical_region_exit(...);
   interruptFlag = false;
   processThings();
   sd_nvic_critical_region_enter(...);
}
// Now we are inside critical region thus application interrupt cannot occur here.
sd_app_evt_wait(); // does this enable application interrupts automatically?

So, can I enter sd_app_evt_wait() while inside critical region?

Parents
  • Hi Jarmo,

    sd_app_evt_wait() calls wait in the sequence of __WFE() __SEV() __WFE()

    This way if the interrupt happened just before calling sd_app_evt_wait, then the above sequence will not sleep because
    __WFE() -> The internal event was set as an interrupt occured just before this , now the event is cleared and this _WFE does nothing, means it wont go to sleep

    __SEV()-> Set the event register explicitly

    __WFE-> since we set event register explicitly, this __WFE will also not do anything apart from clearing the event register.

    The above sequence will also work perfectly if no interrupt happened before calling sd_app_evt_wait
    __WFE()-> since no internal event is set, this will make chip go to sleep (system idle)

    __SEV -> executing this means the chip has woken up now or before in other context, we are setting internal event just to make sure

    __WFE -> clear the internal event and do nothing, so now we are awake and all events handled and cleared.

    sd_app_evt_wait also keeps track of application interrupts forwarded and acked by softdevice. So it avoids any race condition.

  • single WFI would have been enough to make sure that it makes the chip to sleep. But then there could be race conditions with WFI. WFE is not guarenteed to sleep because of its internal event set register. You can read more about the difference in this forum or ARM infocenter. It is well documented i think.

Reply Children
No Data
Related