feat(ipc_isr): adds IPC ISR safe API for other CPU stall API

This commit is contained in:
Konstantin Kondrashov
2026-05-29 08:26:06 +03:00
parent a2d6680477
commit 672736304c
10 changed files with 499 additions and 64 deletions

View File

@@ -97,6 +97,11 @@ IPC 功能提供了下列 API以在高优先级中断的上下文中执行回
- :cpp:func:`esp_ipc_isr_call` 能够在目标内核上触发一个 IPC 调用。在目标内核 **开始** 执行回调前,此函数将一直处于忙等待。
- :cpp:func:`esp_ipc_isr_call_blocking` 能够在目标内核上触发一个 IPC 调用。在目标内核 **完成** 回调执行前,此函数将一直处于忙等待。
这些函数会中断另一 CPU并在高优先级中断的上下文中执行回调。常见用法有两种
- 对于不会进入与另一 CPU 共享的临界区的简单回调,可以直接调用 :cpp:func:`esp_ipc_isr_call`:cpp:func:`esp_ipc_isr_call_blocking`
- 如果调用 CPU 可能进入另一 CPU 使用的临界区,或者需要在另一 CPU 保持停止时执行多个回调,则应先使用 :cpp:func:`esp_ipc_isr_stall_other_cpu`:cpp:func:`esp_ipc_isr_stall_other_cpu_safe` 暂停另一 CPU。然后使用 :cpp:func:`esp_ipc_isr_call`:cpp:func:`esp_ipc_isr_call_blocking` 执行回调。操作完成后,使用 :cpp:func:`esp_ipc_isr_release_other_cpu` 释放另一 CPU。
.. only:: CONFIG_IDF_TARGET_ARCH_XTENSA
以下示例代码用汇编语言编写了一个高优先级中断 IPC 回调,该回调的作用为读取目标内核的周期计数:
@@ -117,10 +122,23 @@ IPC 功能提供了下列 API以在高优先级中断的上下文中执行回
s32i a3, a2, 0
ret
如果不会因为共享临界区而发生死锁,可以直接调用该回调:
.. code-block:: c
unit32_t cycle_count;
esp_ipc_isr_call_blocking(esp_test_ipc_isr_get_cycle_count_other_cpu, (void *)cycle_count);
uint32_t cycle_count;
esp_ipc_isr_call_blocking(esp_test_ipc_isr_get_cycle_count_other_cpu, (void *)&cycle_count);
或者,也可以在进行一次或多次 IPC 调用之前,安全地暂停另一 CPU
.. code-block:: c
while (esp_ipc_isr_stall_other_cpu_safe() != ESP_OK) {
// 在生产代码中,可按需添加超时或 yield以避免无限循环。
}
uint32_t cycle_count;
esp_ipc_isr_call_blocking(esp_test_ipc_isr_get_cycle_count_other_cpu, (void *)&cycle_count);
esp_ipc_isr_release_other_cpu();
.. note::
@@ -144,6 +162,7 @@ IPC 功能提供了下列 API以在高优先级中断的上下文中执行回
:CONFIG_IDF_TARGET_ARCH_RISCV: - :cpp:func:`esp_ipc_isr_stall_other_cpu`:暂停目标内核。调用内核禁用 3 级及以下级别的中断,而目标内核将在所有中断被禁用的情况下进入忙等待。在调用 :cpp:func:`esp_ipc_isr_release_other_cpu` 前,目标内核会保持忙等待。
:CONFIG_IDF_TARGET_ARCH_XTENSA: - :cpp:func:`esp_ipc_isr_stall_other_cpu`:暂停目标内核。调用内核禁用 3 级及以下级别的中断,而目标内核将在 5 级及以下的中断被禁用的情况下进入忙等待。在调用 :cpp:func:`esp_ipc_isr_release_other_cpu` 前,目标内核会保持忙等待。
- :cpp:func:`esp_ipc_isr_stall_other_cpu_safe`:仅当另一内核不在临界区或 ISR 上下文中时,才尝试暂停该内核。如果另一内核处于此类状态,则认为暂停不安全,会释放该内核并返回错误。
- :cpp:func:`esp_ipc_isr_release_other_cpu`:恢复目标内核。
应用示例