In some cases, we need to quickly get the state of the other CPU (for example, in the core dump, in the GDB stub, in some unit tests, in the dport workaround, etc.), and usually it can be implemented as a fairly simple function and can be written in assembler.
For these purposes, the IPC API has special functions :cpp:func:`esp_ipc_isr_asm_call` and :cpp:func:`esp_ipc_isr_asm_call_blocking`.
The `esp_ipc_isr_asm...(asm_func, arg)` functions trigger the High-priority interrupt (4 level) on the other CPU. The given assembler function (asm_func) will run on the other CPU in the context of the interrupt. This assembler function will be called by the CALLX0 command therefore it must be written in assembler.
:cpp:func:`esp_ipc_isr_asm_call` - triggers the Hi-priority interrupt on a particular core to execute a given function. The CPU which called this function will be blocked until the other CPU begins execution of the given function.
:cpp:func:`esp_ipc_isr_asm_call_blocking` is similar but will block the calling CPU until the other CPU has completed the execution of the given function.
:cpp:func:`esp_ipc_isr_stall_other_cpu` stalls the other CPU and the calling CPU disables interrupts with level 3 and lower. To finish stalling the other CPU call :cpp:func:`esp_ipc_isr_release_other_cpu`. The stalled CPU disables interrupts with level 5 and lower.
Functions executed by Hi-priority IPC must be functions of type `void func(void *arg)`. Examples of a assembler function see in :idf_file:`components/esp_ipc/src/esp_ipc_isr/esp_ipc_isr_routines.S`, :idf_file:`components/esp_ipc/test/test_ipc_isr.S` and below. In the asm function, you can use only a few registers as they were saved in the interrupt handler before calling this function, their use is safe. The registers:`a2` as `void *arg`, a3 and a4 are free for use.
Some feature:
- The asm function should be placed in the IRAM memory and aligned on a memory address multiple of 4.
- As the asm function is run in the context of the High-priority interrupt, a C function can no be called because the windows spill is disabled.
- Use only a2, a3 and a4 registers in the asm function (to workaround it see esp_complex_asm_func).
- A CPU, that called these APIs `esp_ipc_isr_asm...(asm_func, arg)`, disables interrupts with level 3 and lower.
- A CPU, where the asm function is executed, disables interrupts with level 5 and lower.
- You do not need to take care about handling of the Hi-priority interrupt.
This number of registers available for use is sufficient for most simple cases. But if you need to run a more complex asm function, you can pass as an argument a pointer to a structure that can accept additional registers to a buffer to make them free to use. Remember to restore them before returning See the :example:`system/ipc/ipc_isr`.