Merge branch 'doc/esp32p4_intr_alloc' into 'master'

docs(soc): add a few details in the `intr_alloc` documentation for the ESP32-P4

Closes IDF-8781

See merge request espressif/esp-idf!28249
pull/13090/head
Omar Chebib 2024-01-19 10:50:42 +08:00
commit 0d9d004d00
3 zmienionych plików z 29 dodań i 6 usunięć

Wyświetl plik

@ -109,7 +109,6 @@ api-reference/system/misc_system_api.rst
api-reference/system/inc/power_management_esp32p4.rst
api-reference/system/esp_https_ota.rst
api-reference/system/ulp-risc-v.rst
api-reference/system/intr_alloc.rst
api-reference/index.rst
api-reference/protocols/icmp_echo.rst
api-reference/protocols/esp_serial_slave_link.rst

Wyświetl plik

@ -22,6 +22,10 @@ Overview
The {IDF_TARGET_NAME} has one core, with 28 external asynchronous interrupts. Each interrupt's priority is independently programmable. In addition, there are also 4 core local interrupt sources (CLINT). See **{IDF_TARGET_NAME} Technical Reference Manual** [`PDF <{IDF_TARGET_TRM_EN_URL}#riscvcpu>`__] for more details.
.. only:: esp32p4
The {IDF_TARGET_NAME} has two cores, with 32 external asynchronous interrupts each. Each interrupt's priority is independently programmable. In addition, there are also 3 core local interrupt sources (CLINT) on each core. See **{IDF_TARGET_NAME} Technical Reference Manual** [`PDF <{IDF_TARGET_TRM_EN_URL}#riscvcpu>`__] for more details.
Because there are more interrupt sources than interrupts, sometimes it makes sense to share an interrupt in multiple drivers. The :cpp:func:`esp_intr_alloc` abstraction exists to hide all these implementation details.
A driver can allocate an interrupt for a certain peripheral by calling :cpp:func:`esp_intr_alloc` (or :cpp:func:`esp_intr_alloc_intrstatus`). It can use the flags passed to this function to specify the type, priority, and trigger method of the interrupt to allocate. The interrupt allocation code will then find an applicable interrupt, use the interrupt matrix to hook it up to the peripheral, and install the given interrupt handler and ISR to it.
@ -61,9 +65,18 @@ To illustrate why shard interrupts can only be level-triggered, take the scenari
External Peripheral Interrupts
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The remaining interrupt sources are from external peripherals. These are defined in ``soc/soc.h`` as ``ETS_*_INTR_SOURCE``.
The remaining interrupt sources are from external peripherals.
Non-internal interrupt slots in both CPU cores are wired to an interrupt matrix, which can be used to route any external interrupt source to any of these interrupt slots.
.. only:: esp32p4
Multicore considerations
------------------------
Despite providing internal interrupts, part of the RISC-V core, ESP-IDF only makes the use of the external interrupts, within the {IDF_TARGET_NAME} but outside the RISC-V cores themselves. Most {IDF_TARGET_NAME} peripherals are of this type.
External interrupt slots in both CPU cores are wired to an interrupt matrix, which can be used to route any external interrupt source, defined in ``soc/interrupts.h`` as ``ETS_*_INTR_SOURCE``, to any of these interrupt slots.
.. only:: SOC_HP_CPU_HAS_MULTIPLE_CORES
- 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.
@ -143,7 +156,7 @@ If you have confirmed that the application is indeed running out of interrupts,
.. list::
:SOC_HP_CPU_HAS_MULTIPLE_CORES: - On multi-core SoCs, try initializing some of the peripheral drivers from a task pinned to the second core. Interrupts are typically allocated on the same core where the peripheral driver initialization function runs. Therefore by running the initialization function on the second core, more interrupt inputs can be used.
:SOC_HP_CPU_HAS_MULTIPLE_CORES: - On multi-core targets, try initializing some of the peripheral drivers from a task pinned to the second core. Interrupts are typically allocated on the same core where the peripheral driver initialization function runs. Therefore by running the initialization function on the second core, more interrupt inputs can be used.
- Determine the interrupts which can tolerate higher latency, and allocate them using ``ESP_INTR_FLAG_SHARED`` flag (optionally ORed with ``ESP_INTR_FLAG_LOWMED``). Using this flag for two or more peripherals will let them use a single interrupt input, and therefore save interrupt inputs for other peripherals. See :ref:`intr-alloc-shared-interrupts` above.
:not SOC_CPU_HAS_FLEXIBLE_INTC: - Some peripheral driver may default to allocating interrupts with ``ESP_INTR_FLAG_LEVEL1`` flag, so priority 2 and 3 interrupts do not get used by default. If :cpp:func:`esp_intr_dump` shows that some priority 2 or 3 interrupts are available, try changing the interrupt allocation flags when initializing the driver to ``ESP_INTR_FLAG_LEVEL2`` or ``ESP_INTR_FLAG_LEVEL3``.
- Check if some of the peripheral drivers do not need to be used all the time, and initialize or deinitialize them on demand. This can reduce the number of simultaneously allocated interrupts.

Wyświetl plik

@ -22,6 +22,10 @@
{IDF_TARGET_NAME} 有一个核28 个外部异步中断。每个中断的优先级别都可独立地通过编程设置。此外,还有 4 个核心本地中断源 (CLINT)。详细信息请参见 **{IDF_TARGET_NAME} 技术参考手册** [`PDF <{IDF_TARGET_TRM_CN_URL}#riscvcpu>`__]。
.. only:: esp32p4
{IDF_TARGET_NAME} 有两个核,每个核有 32 个外部异步中断。每个中断的优先级别都可独立地通过编程设置。此外,每个核还有 3 个核心本地中断源 (CLINT)。详细信息请参见 **{IDF_TARGET_NAME} 技术参考手册** [`PDF <{IDF_TARGET_TRM_CN_URL}#riscvcpu>`__]。
由于中断源数量多于中断,有时多个驱动程序可以共用一个中断。:cpp:func:`esp_intr_alloc` 抽象隐藏了这些实现细节。
驱动程序可以通过调用 :cpp:func:`esp_intr_alloc`,或 :cpp:func:`esp_intr_alloc_intrstatus` 为某个外设分配中断。通过向此函数传递 flag可以指定中断类型、优先级和触发方式。然后中断分配代码会找到适用的中断使用中断矩阵将其连接到外设并为其安装给定的中断处理程序和 ISR。
@ -61,7 +65,14 @@
外部外设中断
^^^^^^^^^^^^^^^^^^^^
剩余的中断源来自外部外设,在 ``soc/soc.h`` 中定义为 ``ETS_*_INTR_SOURCE``
剩余的中断源来自外部外设,在 ``soc/interrupts.h`` 中定义为 ``ETS_*_INTR_SOURCE``
.. only:: esp32p4
多核问题
--------
.. only:: SOC_HP_CPU_HAS_MULTIPLE_CORES
两个 CPU 的非内部中断源槽都与中断矩阵相连,可以将任何外部中断源发送到这些中断槽中。
@ -143,7 +154,7 @@ CPU 中断在大多数 Espressif SoC 上都是有限的资源。因此,一个
.. list::
:SOC_HP_CPU_HAS_MULTIPLE_CORES: - 在多核 SoC 上,尝试通过固定在第二个核的任务来初始化某些外设驱动程序。中断通常分配在运行外设驱动程序初始化函数的同一个内核上,因此,通过在第二个内核上运行初始化函数,就可以使用更多的中断输入。
:SOC_HP_CPU_HAS_MULTIPLE_CORES: - 在多核目标上,尝试通过固定在第二个核的任务来初始化某些外设驱动程序。中断通常分配在运行外设驱动程序初始化函数的同一个内核上,因此,通过在第二个内核上运行初始化函数,就可以使用更多的中断输入。
- 找到可接受更高延迟的中断,并用 ``ESP_INTR_FLAG_SHARED`` flag (或与 ``ESP_INTR_FLAG_LOWMED`` 进行 OR 运算)分配这些中断。对两个或更多外设使用此 flag 能让它们使用单个中断输入,从而为其他外设节约中断输入。参见 :ref:`intr-alloc-shared-interrupts`
:not SOC_CPU_HAS_FLEXIBLE_INTC: - 一些外设驱动程序可能默认使用 ``ESP_INTR_FLAG_LEVEL1`` flag 来分配中断,因此默认情况下不会使用优先级为 2 或 3 的中断。如果 :cpp:func:`esp_intr_dump` 显示某些优先级为 2 或 3 的中断可用,尝试在初始化驱动程序时将中断分配 flag 改为 ``ESP_INTR_FLAG_LEVEL2`` 或 ``ESP_INTR_FLAG_LEVEL3``。
- 检查是否有些外设驱动程序不需要一直启用,并按需将其初始化或取消初始化。这样可以减少同时分配的中断数量。