esp_ipc: Update documentation and API descriptions
This commit updates the documentation and API descriptions of the esp_ipc and esp_ipc_isr features.
This commit is contained in:
committed by
Darian Leung
parent
460f3ad7b6
commit
209702d055
@@ -512,33 +512,27 @@ menu "IPC (Inter-Processor Call)"
|
||||
default 2048 if APPTRACE_ENABLE
|
||||
default 1024
|
||||
help
|
||||
Configure the IPC tasks stack size. One IPC task runs on each core
|
||||
(in dual core mode), and allows for cross-core function calls.
|
||||
|
||||
See IPC documentation for more details.
|
||||
|
||||
The default stack size should be enough for most common use cases.
|
||||
It can be shrunk if you are sure that you do not use any custom
|
||||
IPC functionality.
|
||||
Configure the IPC tasks stack size. An IPC task runs on each core (in dual core mode), and allows for
|
||||
cross-core function calls. See IPC documentation for more details. The default IPC stack size should be
|
||||
enough for most common simple use cases. However, users can increase/decrease the stack size to their
|
||||
needs.
|
||||
|
||||
config ESP_IPC_USES_CALLERS_PRIORITY
|
||||
bool "IPC runs at caller's priority"
|
||||
default y
|
||||
depends on !FREERTOS_UNICORE
|
||||
help
|
||||
If this option is not enabled then the IPC task will keep behavior
|
||||
same as prior to that of ESP-IDF v4.0, and hence IPC task will run
|
||||
at (configMAX_PRIORITIES - 1) priority.
|
||||
If this option is not enabled then the IPC task will keep behavior same as prior to that of ESP-IDF v4.0,
|
||||
hence IPC task will run at (configMAX_PRIORITIES - 1) priority.
|
||||
|
||||
config ESP_IPC_ISR_ENABLE
|
||||
bool
|
||||
default y if !FREERTOS_UNICORE
|
||||
help
|
||||
This feature serves a similar purpose to the IPC except that the callback function is run
|
||||
in the context of a level 4 interrupt (i.e., high priority/level interrupt). The IPC ISR
|
||||
feature is intended for low latency execution of simple functions written in assembly on
|
||||
another CPU. Due to being run in higher level interrupt context, the assembly functions
|
||||
should be written in a particular way (see esp_test_ipc_isr_asm() and the "High-Level Interrupts"
|
||||
chapter in hlinterrupts.rst for more details).
|
||||
The IPC ISR feature is similar to the IPC feature except that the callback function is executed in the
|
||||
context of a High Priority Interrupt. The IPC ISR feature is itended for low latency execution of simple
|
||||
callbacks written in assembly on another CPU. Due to being run in a High Priority Interrupt, the assembly
|
||||
callbacks must be written with particular restrictions (see "IPC" and "High-Level Interrupt" docs for more
|
||||
details).
|
||||
|
||||
endmenu # "IPC (Inter-Processor Call)
|
||||
|
||||
@@ -195,6 +195,6 @@ esp_err_t esp_ipc_start_gcov_from_isr(uint32_t cpu_id, esp_ipc_func_t func, void
|
||||
|
||||
return ret == pdTRUE ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
#endif
|
||||
#endif // CONFIG_APPTRACE_GCOV_ENABLE
|
||||
|
||||
#endif // not CONFIG_FREERTOS_UNICORE or CONFIG_APPTRACE_GCOV_ENABLE
|
||||
#endif // !defined(CONFIG_FREERTOS_UNICORE) || defined(CONFIG_APPTRACE_GCOV_ENABLE)
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef __ESP_IPC_H__
|
||||
#define __ESP_IPC_H__
|
||||
#pragma once
|
||||
|
||||
#include <esp_err.h>
|
||||
|
||||
@@ -15,30 +14,30 @@ extern "C" {
|
||||
|
||||
#if !defined(CONFIG_FREERTOS_UNICORE) || defined(CONFIG_APPTRACE_GCOV_ENABLE)
|
||||
|
||||
/** @cond */
|
||||
typedef void (*esp_ipc_func_t)(void* arg);
|
||||
/** @endcond */
|
||||
/*
|
||||
* Inter-processor call APIs
|
||||
*
|
||||
* FreeRTOS provides several APIs which can be used to communicate between
|
||||
* different tasks, including tasks running on different CPUs.
|
||||
* This module provides additional APIs to run some code on the other CPU.
|
||||
*
|
||||
* These APIs can only be used when FreeRTOS scheduler is running.
|
||||
* FreeRTOS provides several APIs which can be used to communicate between different tasks, including tasks running on
|
||||
* different CPUs. This module provides additional APIs to run some code on the other CPU. These APIs can only be used
|
||||
* when FreeRTOS scheduler is running.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Execute a function on the given CPU
|
||||
* @brief IPC Callback
|
||||
*
|
||||
* Run a given function on a particular CPU. The given function must accept a
|
||||
* void* argument and return void. The given function is run in the context of
|
||||
* the IPC task of the CPU specified by the cpu_id parameter. The calling task
|
||||
* will be blocked until the IPC task begins executing the given function. If
|
||||
* another IPC call is ongoing, the calling task will block until the other IPC
|
||||
* call completes. The stack size allocated for the IPC task can be configured
|
||||
* in the "Inter-Processor Call (IPC) task stack size" setting in menuconfig.
|
||||
* Increase this setting if the given function requires more stack than default.
|
||||
* A callback of this type should be provided as an argument when calling esp_ipc_call() or esp_ipc_call_blocking().
|
||||
*/
|
||||
typedef void (*esp_ipc_func_t)(void* arg);
|
||||
|
||||
/**
|
||||
* @brief Execute a callback on a given CPU
|
||||
*
|
||||
* Execute a given callback on a particular CPU. The callback must be of type "esp_ipc_func_t" and will be invoked in
|
||||
* the context of the target CPU's IPC task.
|
||||
*
|
||||
* - This function will block the target CPU's IPC task has begun execution of the callback
|
||||
* - If another IPC call is ongoing, this function will block until the ongoing IPC call completes
|
||||
* - The stack size of the IPC task can be configured via the CONFIG_ESP_IPC_TASK_STACK_SIZE option
|
||||
*
|
||||
* @note In single-core mode, returns ESP_ERR_INVALID_ARG for cpu_id 1.
|
||||
*
|
||||
@@ -55,17 +54,10 @@ esp_err_t esp_ipc_call(uint32_t cpu_id, esp_ipc_func_t func, void* arg);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Execute a function on the given CPU and blocks until it completes
|
||||
* @brief Execute a callback on a given CPU until and block until it completes
|
||||
*
|
||||
* Run a given function on a particular CPU. The given function must accept a
|
||||
* void* argument and return void. The given function is run in the context of
|
||||
* the IPC task of the CPU specified by the cpu_id parameter. The calling task
|
||||
* will be blocked until the IPC task completes execution of the given function.
|
||||
* If another IPC call is ongoing, the calling task will block until the other
|
||||
* IPC call completes. The stack size allocated for the IPC task can be
|
||||
* configured in the "Inter-Processor Call (IPC) task stack size" setting in
|
||||
* menuconfig. Increase this setting if the given function requires more stack
|
||||
* than default.
|
||||
* This function is identical to esp_ipc_call() except that this function will block until the execution of the callback
|
||||
* completes.
|
||||
*
|
||||
* @note In single-core mode, returns ESP_ERR_INVALID_ARG for cpu_id 1.
|
||||
*
|
||||
@@ -80,10 +72,8 @@ esp_err_t esp_ipc_call(uint32_t cpu_id, esp_ipc_func_t func, void* arg);
|
||||
*/
|
||||
esp_err_t esp_ipc_call_blocking(uint32_t cpu_id, esp_ipc_func_t func, void* arg);
|
||||
|
||||
#endif // not CONFIG_FREERTOS_UNICORE or CONFIG_APPTRACE_GCOV_ENABLE
|
||||
#endif // !defined(CONFIG_FREERTOS_UNICORE) || defined(CONFIG_APPTRACE_GCOV_ENABLE)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ESP_IPC_H__ */
|
||||
|
||||
@@ -14,31 +14,38 @@ extern "C" {
|
||||
|
||||
#ifdef CONFIG_ESP_IPC_ISR_ENABLE
|
||||
|
||||
/** @cond */
|
||||
/**
|
||||
* @brief IPC ISR Callback
|
||||
*
|
||||
* A callback of this type should be provided as an argument when calling esp_ipc_isr_asm_call() or
|
||||
* esp_ipc_isr_asm_call_blocking().
|
||||
*/
|
||||
typedef void (*esp_ipc_isr_func_t)(void* arg);
|
||||
/** @endcond */
|
||||
|
||||
/**
|
||||
* @brief Initialize inter-processor call module which based on #4 high-interrupt.
|
||||
* @brief Initialize the IPC ISR feature
|
||||
*
|
||||
* This function is called on CPU start and should not be called from the application.
|
||||
* This function initializes the IPC ISR feature and must be called before any other esp_ipc_isr...() functions.
|
||||
* The IPC ISR feature allows for callbacks (written in assembly) to be run on a particular CPU in the context of a
|
||||
* High Priority Interrupt.
|
||||
*
|
||||
* This function starts two tasks, one on each CPU. These tasks register
|
||||
* #4 High-interrupt and after that, the tasks are deleted.
|
||||
* The next API functions work with this functionality:
|
||||
* esp_ipc_isr_asm_call
|
||||
* esp_ipc_isr_asm_call_blocking
|
||||
* They allow to run an asm function on other CPU.
|
||||
* - This function will register a High Priority Interrupt on each CPU. The priority of the interrupts is dependent on
|
||||
* the CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL option.
|
||||
* - Callbacks written in assembly can then run in context of the registered High Priority Interrupts
|
||||
* - Callbacks can be executed by calling esp_ipc_isr_asm_call() or esp_ipc_isr_asm_call_blocking()
|
||||
*/
|
||||
void esp_ipc_isr_init(void);
|
||||
|
||||
/**
|
||||
* @brief Execute an asm function on the other CPU (uses the #4 high-priority interrupt)
|
||||
* @brief Execute an assembly callback on the other CPU
|
||||
*
|
||||
* @note In single-core mode, it is not available.
|
||||
* This function calls the #4 high-priority interrupt on the other CPU.
|
||||
* The given function is called in the context of the interrupt by CALLX0 command and
|
||||
* operates with registers a2, a3, a4.
|
||||
* Execute a given callback on the other CPU in the context of a High Priority Interrupt.
|
||||
*
|
||||
* - This function will busy-wait in a critical section until the other CPU has started execution of the callback
|
||||
* - The callback must be written in assembly, is invoked using a CALLX0 instruction, and has a2, a3, a4 as scratch
|
||||
* registers. See docs for more details
|
||||
*
|
||||
* @note This function is not available in single-core mode.
|
||||
*
|
||||
* @param[in] func Pointer to a function of type void func(void* arg) to be executed
|
||||
* @param[in] arg Arbitrary argument of type void* to be passed into the function
|
||||
@@ -46,11 +53,12 @@ void esp_ipc_isr_init(void);
|
||||
void esp_ipc_isr_asm_call(esp_ipc_isr_func_t func, void* arg);
|
||||
|
||||
/**
|
||||
* @brief Execute an asm function on the other CPU and blocks until it completes (uses the #4 high-priority interrupt)
|
||||
* @brief Execute an assembly callback on the other CPU and busy-wait until it completes
|
||||
*
|
||||
* @note In single-core mode, it is not available.
|
||||
* This function calls the #4 high-priority interrupt on the other CPU.
|
||||
* The given function is called in the context of the interrupt by CALLX0 command.
|
||||
* This function is identical to esp_ipc_isr_asm_call() except that this function will busy-wait until the execution of
|
||||
* the callback completes.
|
||||
*
|
||||
* @note This function is not available in single-core mode.
|
||||
*
|
||||
* @param[in] func Pointer to a function of type void func(void* arg) to be executed
|
||||
* @param[in] arg Arbitrary argument of type void* to be passed into the function
|
||||
@@ -58,51 +66,60 @@ void esp_ipc_isr_asm_call(esp_ipc_isr_func_t func, void* arg);
|
||||
void esp_ipc_isr_asm_call_blocking(esp_ipc_isr_func_t func, void* arg);
|
||||
|
||||
/**
|
||||
* @brief Stall the other CPU and the current CPU disables interrupts with level 3 and lower.
|
||||
* @brief Stall the other CPU
|
||||
*
|
||||
* @note In single-core mode, it is not available.
|
||||
* This function calls the #4 high-priority interrupt on the other CPU.
|
||||
* The esp_ipc_isr_finish_cmd() function is called on the other CPU in the context of the #4 high-priority interrupt.
|
||||
* The esp_ipc_isr_finish_cmd is called by CALLX0 command.
|
||||
* It is waiting for the end command. The command will be sent by esp_ipc_isr_release_other_cpu().
|
||||
* This function is used for DPORT workaround.
|
||||
* This function will stall the other CPU. The other CPU is stalled by busy-waiting in the context of a High Priority
|
||||
* Interrupt. The other CPU will not be resumed until esp_ipc_isr_release_other_cpu() is called.
|
||||
*
|
||||
* This function blocks other CPU until the release call esp_ipc_isr_release_other_cpu().
|
||||
* - This function is internally implemented using IPC ISR
|
||||
* - This function is used for DPORT workaround.
|
||||
* - If the stall feature is paused using esp_ipc_isr_stall_pause(), this function will have no effect
|
||||
*
|
||||
* This fucntion is used for the DPORT workaround: stall other cpu that this cpu is pending to access dport register start.
|
||||
* @note This function is not available in single-core mode.
|
||||
*/
|
||||
void esp_ipc_isr_stall_other_cpu(void);
|
||||
|
||||
/**
|
||||
* @brief Release the other CPU
|
||||
*
|
||||
* @note In single-core mode, it is not available.
|
||||
* This function will send the end command to release the stall other CPU.
|
||||
* This function is used for DPORT workaround: stall other cpu that this cpu is pending to access dport register end.
|
||||
* This function will release the other CPU that was previously stalled from calling esp_ipc_isr_stall_other_cpu()
|
||||
*
|
||||
* - This function is used for DPORT workaround.
|
||||
* - If the stall feature is paused using esp_ipc_isr_stall_pause(), this function will have no effect
|
||||
*
|
||||
* @note This function is not available in single-core mode.
|
||||
*/
|
||||
void esp_ipc_isr_release_other_cpu(void);
|
||||
|
||||
/**
|
||||
* @brief Pause stall the other CPU
|
||||
* @brief Puase the CPU stall feature
|
||||
*
|
||||
* This function will pause the CPU stall feature. Once paused, calls to esp_ipc_isr_stall_other_cpu() and
|
||||
* esp_ipc_isr_release_other_cpu() will have no effect. If a IPC ISR call is already in progress, this function will
|
||||
* busy-wait until the call completes before pausing the CPU stall feature.
|
||||
*/
|
||||
void esp_ipc_isr_stall_pause(void);
|
||||
|
||||
/**
|
||||
* @brief Abort stall the other CPU
|
||||
* @brief Abort a CPU stall
|
||||
*
|
||||
* This routine does not stop the stall routines in any way that is recoverable.
|
||||
* Please only call in case of panic().
|
||||
* Used in panic code: the enter_critical stuff may be messed up so we just stop everything without checking the mux.
|
||||
* This function will abort any stalling routine of the other CPU due to a pervious call to
|
||||
* esp_ipc_isr_stall_other_cpu(). This function aborts the stall in a non-recoverable manner, thus should only be called
|
||||
* in case of a panic().
|
||||
*
|
||||
* - This function is used in panic handling code
|
||||
*/
|
||||
void esp_ipc_isr_stall_abort(void);
|
||||
|
||||
/**
|
||||
* @brief Resume stall the other CPU
|
||||
* @brief Resume the CPU stall feature
|
||||
*
|
||||
* This function will resume the CPU stall feature that was previously paused by calling esp_ipc_isr_stall_pause(). Once
|
||||
* resumed, calls to esp_ipc_isr_stall_other_cpu() and esp_ipc_isr_release_other_cpu() will have effect again.
|
||||
*/
|
||||
void esp_ipc_isr_stall_resume(void);
|
||||
|
||||
#else // not CONFIG_ESP_IPC_ISR_ENABLE
|
||||
#else // CONFIG_ESP_IPC_ISR_ENABLE
|
||||
|
||||
#define esp_ipc_isr_stall_other_cpu()
|
||||
#define esp_ipc_isr_release_other_cpu()
|
||||
|
||||
@@ -160,6 +160,7 @@ void IRAM_ATTR esp_ipc_isr_stall_pause(void)
|
||||
|
||||
void IRAM_ATTR esp_ipc_isr_stall_abort(void)
|
||||
{
|
||||
//Note: We don't enter a critical section here as we are calling this from a panic.
|
||||
s_stall_state = STALL_STATE_IDLE;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
/* esp_ipc_isr_waiting_for_finish_cmd(void* finish_cmd)
|
||||
*
|
||||
* It should be called by the CALLX0 command from the handler of High-priority interrupt (4 lvl).
|
||||
* It should be called by the CALLX0 command from the handler of High-priority interrupt.
|
||||
* Only these registers [a2, a3, a4] can be used here.
|
||||
*/
|
||||
.section .iram1, "ax"
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
/* esp_test_ipc_isr_asm(void *arg)
|
||||
*
|
||||
* It should be called by the CALLX0 command from the handler of High-priority interrupt (4 lvl).
|
||||
* It should be called by the CALLX0 command from the handler of High-priority interrupt.
|
||||
* Only these registers [a2, a3, a4] can be used here.
|
||||
*/
|
||||
.section .iram1, "ax"
|
||||
|
||||
Reference in New Issue
Block a user