ISR / Task Synchronization on ESP32

Hi all. I’m just starting to work with FreeRTOS. Reading through “Mastering the FreeRTOS™ Real Time Kernel”. The good news is that almost all of the topics are familiar from my college days. The not so good news is that college was a LONG time ago.

The FreeRTOS port I’m working with is v8.2.0 for the ESP32 processor as implemented in the Arduino ESP32 core.

Anyway, on the topic of synchronizing an ISR to a Task (Section 6.4), the guide contains the following code for the ISR (comments removed for brevity):

static uint32_t ulExampleInterruptHandler( void ) {
  BaseType_t xHigherPriorityTaskWoken;

  xHigherPriorityTaskWoken = pdFALSE;
  xSemaphoreGiveFromISR( xBinarySemaphore, &xHigherPriorityTaskWoken );
  portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}

My question is about the xSemaphoreGiveFromISR( xBinarySemaphore, &xHigherPriorityTaskWoken ) and portYIELD_FROM_ISR( xHigherPriorityTaskWoken ) macros.

It looks like this port’s implementation of the xSemaphoreGiveFromISR macro does indeed take two arguments – a SemaphoreHandle_t and a BaseType_t *.

However, its implementation of the portYIELD_FROM_ISR macro doesn’t take any arguments. In fact, it resolves to a call to _frxt_setup_switch(). The source code for this function is not included with the Arduino ESP32 core.

It seems pretty important that you should request a context switch when returning from the ISR if giving the token results in a higher-priority task (than the one that was interrupted) becoming ready to run.

So, is perhaps this context switch check is performed “automatically” by this particular port?

Thanks.

Espressif provided that port themselves so I’m not familiar with it, but some older ports did not take a parameter to portYIELD_FROM_ISR(), meaning the application writer had to test the value of xHigherPriorityTaskWoken themselves, such as:

if( xHigherPriorityTaskWoken != pdFLASE )
{
    portYIELD_FROM_ISR();
}

Macros that take a parameter work in exactly the same way, but the test of xHigherPriorityTaskWoken is performed inside the macro.

Is it possible the Espressif port wants you to test xHigherPriorityTaskWoken before calling portYIELD_FROM_ISR()? Are there any examples you can use as a reference? Otherwise you could ask Espressif directly.

Thanks for the reply. So, you’re saying that perhaps for this port the call should only be made to portYIELD_FROM_ISR() if xHigherPriorityTaskWoken is true? Otherwise just let the ISR function return normally?

Looking at other examples I see code like this:

static IRAM_ATTR void rsa_complete_isr(void *arg)
{
    BaseType_t higher_woken;
    DPORT_REG_WRITE(RSA_INTERRUPT_REG, 1);
    xSemaphoreGiveFromISR(op_complete_sem, &higher_woken);
    if (higher_woken) {
        portYIELD_FROM_ISR();
    }
}

so it looks like that is the case.