From 9a6791b79d80055644bb7495234af1c309bea77f Mon Sep 17 00:00:00 2001 From: Omar Chebib Date: Wed, 3 Jan 2024 19:04:31 +0800 Subject: [PATCH] docs(soc): add a few details in the `intr_alloc` documentation for the ESP32-P4 --- docs/docs_not_updated/esp32p4.txt | 1 - docs/en/api-reference/system/intr_alloc.rst | 19 ++++++++++++++++--- .../zh_CN/api-reference/system/intr_alloc.rst | 15 +++++++++++++-- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/docs/docs_not_updated/esp32p4.txt b/docs/docs_not_updated/esp32p4.txt index 96acd4b10c..fbfcb4b309 100644 --- a/docs/docs_not_updated/esp32p4.txt +++ b/docs/docs_not_updated/esp32p4.txt @@ -111,7 +111,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 diff --git a/docs/en/api-reference/system/intr_alloc.rst b/docs/en/api-reference/system/intr_alloc.rst index 62329d945d..3d3275f3f6 100644 --- a/docs/en/api-reference/system/intr_alloc.rst +++ b/docs/en/api-reference/system/intr_alloc.rst @@ -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. diff --git a/docs/zh_CN/api-reference/system/intr_alloc.rst b/docs/zh_CN/api-reference/system/intr_alloc.rst index 1ac547249b..92d6e78421 100644 --- a/docs/zh_CN/api-reference/system/intr_alloc.rst +++ b/docs/zh_CN/api-reference/system/intr_alloc.rst @@ -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``。 - 检查是否有些外设驱动程序不需要一直启用,并按需将其初始化或取消初始化。这样可以减少同时分配的中断数量。