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.

Reply
  • 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.

Children
Related