Calling portYIELD_FROM_ISR in the middle of some ISR

Citing from the book “Mastering the FreeRTOS Real Time Kernel - A Hands-On Tutorial Guide”

Most FreeRTOS ports allow portYIELD_FROM_ISR() to be called anywhere within an ISR. A few FreeRTOS ports (predominantly those for smaller architectures), only allow portYIELD_FROM_ISR() to be called at the very end of an ISR.

My questions are

  1. What does it mean that few ports allow portYIELD_FROM_ISR() to be called at the very end of an ISR ? Do they generate a run-time error?
  2. I use STM32H7, FreeRTOS 10.3. How I know whether my port supports portYIELD_FROM_ISR() to be called anywhere or not?
  3. What happens in the the ports that allow portYEILD_FROM_ISR to be called anywhere within an ISR ? I mean will the context switching be performed immediately upon portYEILD_FROM_ISR call even before the ISR end?
  4. Why there is this difference between different ports?

Thanks for any help!

One example for when it has to be at the end is the Pic24 port, where portYIELD_FROM_ISR() directly calls the scheduler at that point in the ISR (at least this was the behavior a few years ago when I used it). If you put it earlier, then the rest of the ISR won’t run until the task that was interrupted get run again.

For the ports where it can be anywhere, typically they schedule a bottom priority software interrupt that won’t actually get called until the ISR (and any nested ISRs) return.

Arm Cortex ports can call it from anywhere because they use the second method, but generally I try to always just use the ‘wasWoken’ flag from all the calls, and end the ISR with a conditional portYIELD_FROM_ISR() if that flag is set. That way I don’t need to worry about which type of port I am in.

1 Like

Thank you Richard for your prompt response and valuable answer!

As for this point -

For the ports where it can be anywhere, typically they schedule a bottom priority software interrupt that won’t actually get called until the ISR (and any nested ISRs) return.

Actually I didn’t understand clearly how this works , do you know where I can read about that with some more details?

Thank you!

In my opinion, the best definition would be the code and the Arm documentation. A portYIELD (or portYIELD_FROM_ISR) basically sets the PENDSV bit in the NVIC, and the scheduler is configure to be the ISR for the SV interrupt. This interrupt is set to be the at the lowest priority, so gets run when all the other interrupts are done.

1 Like