Chapter 2. API Reference
a task running on that specific core. Internal interrupt sources are still allocatable using esp_intr_alloc as normal, but
they cannot be shared and will always have a fixed interrupt level (namely, the one associated in hardware with the
peripheral).
External Peripheral Interrupts
in soc/soc.h as ETS_*_INTR_SOURCE.
Non-internal interrupt slots in both CPU cores are wired to an interrupt multiplexer, which can be used to route any
external interrupt source to any of these interrupt slots.
• Allocating an external interrupt will always allocate it on the core that does the allocation.
• Freeing an external interrupt must always happen on the same core it was allocated on.
• Disabling and enabling external interrupts from another core is allowed.
• Multiple external interrupt sources can share an interrupt slot by passing ESP_INTR_FLAG_SHARED as a
flag to esp_intr_alloc().
Care should be taken when calling esp_intr_alloc() from a task which is not pinned to a core. During task switching,
these tasks can migrate between cores. Therefore it is impossible to tell which CPU the interrupt is allocated on,
which makes it difficult to free the interrupt handle and may also cause debugging difficulties. It is advised to use
xTaskCreatePinnedToCore() with a specific CoreID argument to create tasks that will allocate interrupts. In the case
of internal interrupt sources, this is required.
IRAM-Safe Interrupt Handlers
The ESP_INTR_FLAG_IRAM flag registers an interrupt handler that always runs from IRAM (and reads all its data
from DRAM), and therefore does not need to be disabled during flash erase and write operations.
This is useful for interrupts which need a guaranteed minimum execution latency, as flash write and erase operations
can be slow (erases can take tens or hundreds of milliseconds to complete).
It can also be useful to keep an interrupt handler in IRAM if it is called very frequently, to avoid flash cache misses.
Refer to the
SPI flash API documentation
Multiple Handlers Sharing A Source
Several handlers can be assigned to a same source, given that all handlers are allocated using the
ESP_INTR_FLAG_SHARED flag. They'll be all allocated to the interrupt, which the source is attached to, and
called sequentially when the source is active. The handlers can be disabled and freed individually. The source is
attached to the interrupt (enabled), if one or more handlers are enabled, otherwise detached. A handler will never be
called when disabled, while its source may still be triggered if any one of its handler enabled.
Sources attached to non-shared interrupt do not support this feature.
Though the framework support this feature, you have to use it very carefully. There usually exist 2 ways to stop a
interrupt from being triggered: disable the source or mask peripheral interrupt status. IDF only handles the enabling
and disabling of the source itself, leaving status and mask bits to be handled by users. Status bits should always
be masked before the handler responsible for it is disabled, or the status should be handled in other enabled
interrupt properly. You may leave some status bits unhandled if you just disable one of all the handlers without
masking the status bits, which causes the interrupt to trigger infinitely resulting in a system crash.
API Reference
Header File
•
components/esp_hw_support/include/esp_intr_alloc.h
Espressif Systems
The remaining interrupt sources are from external peripherals. These are defined
for more details.
1001
Submit Document Feedback
Release v4.4
Need help?
Do you have a question about the ESP32-S2 and is the answer not in the manual?
Questions and answers