Notify and Resume from ISR

I need to both notify one task and wake up another from an ISR.

Here’s how my code looks:

void interrupt()
{
  BaseType_t task_a_awoken = pdFALSE;
  xTaskNotifyFromISR(task_a_handle, 0, eNoAction, &task_a_awoken);

  BaseType_t task_b_awoken = xTaskResumeFromISR(task_b_handle);
  
  portYIELD_FROM_ISR(task_a_awoken or task_b_awoken);
}

Buuut, it doesn’t seem to work. A notification goes through, but the task is never awoken. I’m obviously doing it wrong, but:

  • Why exactly?
  • How is it supposed to be done?

Resuming a task from an interrupt is rarely a safe thing to do because of race conditions. See https://www.freertos.org/taskresumefromisr.html

Other than that there doesn’t seem to be an issue with how the notification is being sent. How are you determining the task is never woken?

One thought is ‘or’ is generally not the right C syntax unless you have defined something special or include a special header. The normal C syntax would be (task_a_awoken || task_b_awoken)

Note, as Richard Barry says, the big risk is that if this interrupt occurs before the task suspends itself, the resume gets lost. Better to have that task wait for a notification like the first one (or wait on a semaphore).

It was actually my bad, the code does work as intended. Sorry everyone.

I’m actually ok losing an interrupt in case the task hasn’t been suspended yet, but thanks for the heads-up.

‘or’ is C++ syntax, which is what I’m using.

Hi,

C++ allows the use of names instead of symbols for the boolean operators, as shown here: and, or, not. One can also use the type bool as primitive type as well, instead of the Bool macro found in <stdbool.c>.

Yes, C++ effectively auto includes iso646.h for you, but then the interrupt function will normally need to be declared as extern “C”.

I personally avoid the ‘or’ keyword as you need to remember the difference between it and bitor, and the symbol seems cleaner to me.