Search code examples
esp32freertosesp-idf

How to get OUT of an ISR in freertos / esp-idf


I have an ISR that's fired from a button press. The handler looks like this...

void IRAM_ATTR buttonIsrHandler(void *arg) {
  xTaskResumeFromISR(buttonTaskHandle);
}

// `buttonTaskHandle` is set up as the handle for this task function...
void buttonTask(void *pvParameter) {
  while (1) {
    vTaskSuspend(NULL);
    // ... my task code goes here...
  }
}

When I'm in an ISR, I can't do certain things. For instance, calling ESP_LOGI() results in an error relating to disallowed memory access.

I was expecting those limitations to exist only within the buttonIsrHandler() function, but they also exist within buttonTask() given that I woke it up from an ISR.

How do I get out of an ISR so that I can do all my normal stuff? I could use something like a queue to do this, but that seems heavy weight. Is there an easier way? Would sending a task-notification from the ISR handler be any different? Any other suggestions?


Solution

  • As you can see in the documentation of xTaskResumeFromISR, such a use case is not recommended. Task notifications are designed and optimized for this exact use case. In your case, you'd want to use vTaskNotifyGiveFromISR.

    As for "leaving the ISR", FreeRTOS will not call your task function from the ISR context. xTaskResumeFromISR and other functions simply update the state of the task so that it can run when its turn comes.