mirror of
https://github.com/espressif/esp-idf.git
synced 2025-09-30 19:19:21 +00:00
feat(esp_system): Support IPC_ISR for ESP32P4
This commit is contained in:
@@ -530,19 +530,19 @@ menu "ESP System Settings"
|
||||
prompt "Interrupt level to use for Interrupt Watchdog and other system checks"
|
||||
default ESP_SYSTEM_CHECK_INT_LEVEL_4
|
||||
help
|
||||
Interrupt level to use for Interrupt Watchdog and other system checks.
|
||||
Interrupt level to use for Interrupt Watchdog, IPC_ISR and other system checks.
|
||||
|
||||
config ESP_SYSTEM_CHECK_INT_LEVEL_5
|
||||
bool "Level 5 interrupt"
|
||||
depends on IDF_TARGET_ESP32
|
||||
help
|
||||
Using level 5 interrupt for Interrupt Watchdog and other system checks.
|
||||
Using level 5 interrupt for Interrupt Watchdog, IPC_ISR and other system checks.
|
||||
|
||||
config ESP_SYSTEM_CHECK_INT_LEVEL_4
|
||||
bool "Level 4 interrupt"
|
||||
depends on !BTDM_CTRL_HLI
|
||||
help
|
||||
Using level 4 interrupt for Interrupt Watchdog and other system checks.
|
||||
Using level 4 interrupt for Interrupt Watchdog, IPC_ISR and other system checks.
|
||||
endchoice
|
||||
|
||||
# Insert chip-specific system config
|
||||
@@ -595,11 +595,10 @@ menu "IPC (Inter-Processor Call)"
|
||||
|
||||
config ESP_IPC_ISR_ENABLE
|
||||
bool
|
||||
default n if IDF_TARGET_ESP32P4 # TODO: IDF-7769
|
||||
default y if !FREERTOS_UNICORE
|
||||
help
|
||||
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
|
||||
context of a High Priority Interrupt. The IPC ISR feature is intended 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).
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -17,31 +17,44 @@ extern "C" {
|
||||
/**
|
||||
* @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().
|
||||
* The callback must be written:
|
||||
* - in assembly for XTENSA chips (such as ESP32, ESP32S3).
|
||||
* - in C or assembly for RISCV chips (such as ESP32P4).
|
||||
*
|
||||
* A callback of this type should be provided as an argument when calling esp_ipc_isr_call() or
|
||||
* esp_ipc_isr_call_blocking().
|
||||
*/
|
||||
typedef void (*esp_ipc_isr_func_t)(void* arg);
|
||||
|
||||
/**
|
||||
* @brief Execute an assembly callback on the other CPU
|
||||
* @brief Execute an ISR callback on the other CPU
|
||||
*
|
||||
* 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
|
||||
* - The callback must be written:
|
||||
* - in assembly for XTENSA chips (such as ESP32, ESP32S3).
|
||||
* The function is invoked using a CALLX0 instruction and can use only a2, a3, a4 registers.
|
||||
* See :doc:`IPC in Interrupt Context </api-reference/system/ipc>` doc for more details.
|
||||
* - in C or assembly for RISCV chips (such as ESP32P4).
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
void esp_ipc_isr_asm_call(esp_ipc_isr_func_t func, void* arg);
|
||||
void esp_ipc_isr_call(esp_ipc_isr_func_t func, void* arg) ;
|
||||
|
||||
/**
|
||||
* @brief Execute an assembly callback on the other CPU and busy-wait until it completes
|
||||
* @brief Execute an ISR callback on the other CPU
|
||||
* See esp_ipc_isr_call().
|
||||
*/
|
||||
#define esp_ipc_isr_asm_call(func, arg) esp_ipc_isr_call(func, arg)
|
||||
|
||||
/**
|
||||
* @brief Execute an ISR callback on the other CPU and busy-wait until it completes
|
||||
*
|
||||
* This function is identical to esp_ipc_isr_asm_call() except that this function will busy-wait until the execution of
|
||||
* This function is identical to esp_ipc_isr_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.
|
||||
@@ -49,7 +62,13 @@ void esp_ipc_isr_asm_call(esp_ipc_isr_func_t func, void* arg);
|
||||
* @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
|
||||
*/
|
||||
void esp_ipc_isr_asm_call_blocking(esp_ipc_isr_func_t func, void* arg);
|
||||
void esp_ipc_isr_call_blocking(esp_ipc_isr_func_t func, void* arg);
|
||||
|
||||
/**
|
||||
* @brief Execute an ISR callback on the other CPU and busy-wait until it completes
|
||||
* See esp_ipc_isr_call_blocking().
|
||||
*/
|
||||
#define esp_ipc_isr_asm_call_blocking(func, arg) esp_ipc_isr_call_blocking(func, arg)
|
||||
|
||||
/**
|
||||
* @brief Stall the other CPU
|
||||
|
@@ -26,7 +26,7 @@ extern "C" {
|
||||
* - This function will register a High Priority Interrupt for a CPU where it is called. 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()
|
||||
* - Callbacks can be executed by calling esp_ipc_isr_call() or esp_ipc_isr_call_blocking()
|
||||
*/
|
||||
void esp_ipc_isr_init(void);
|
||||
|
||||
|
@@ -17,11 +17,16 @@ if(CONFIG_ESP_CONSOLE_USB_CDC)
|
||||
endif()
|
||||
|
||||
if(CONFIG_ESP_IPC_ISR_ENABLE)
|
||||
if(CONFIG_IDF_TARGET_ARCH_XTENSA)
|
||||
list(APPEND srcs "arch/xtensa/esp_ipc_isr.c"
|
||||
"arch/xtensa/esp_ipc_isr_handler.S"
|
||||
"arch/xtensa/esp_ipc_isr_routines.S")
|
||||
endif()
|
||||
list(APPEND srcs "esp_ipc_isr.c")
|
||||
if(CONFIG_IDF_TARGET_ARCH_XTENSA)
|
||||
list(APPEND srcs "arch/xtensa/esp_ipc_isr_port.c"
|
||||
"arch/xtensa/esp_ipc_isr_handler.S"
|
||||
"arch/xtensa/esp_ipc_isr_routines.S")
|
||||
elseif(CONFIG_IDF_TARGET_ARCH_RISCV)
|
||||
list(APPEND srcs "arch/riscv/esp_ipc_isr_port.c"
|
||||
"arch/riscv/esp_ipc_isr_handler.S"
|
||||
"arch/riscv/esp_ipc_isr_routines.c")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CONFIG_IDF_TARGET_ARCH_XTENSA)
|
||||
|
78
components/esp_system/port/arch/riscv/esp_ipc_isr_handler.S
Normal file
78
components/esp_system/port/arch/riscv/esp_ipc_isr_handler.S
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "soc/hp_system_reg.h"
|
||||
|
||||
/* IPC_ISR handler */
|
||||
.equ SAVE_REGS, 16 /* count of saving regs: a0 - a7, t0 - t6, ra */
|
||||
.equ CONTEXT_SIZE, (SAVE_REGS * 4)
|
||||
.section .iram1,"ax"
|
||||
.global esp_ipc_isr_handler
|
||||
.type esp_ipc_isr_handler,@function
|
||||
esp_ipc_isr_handler:
|
||||
|
||||
/* save a0 - a7, t0 - t6, ra */
|
||||
addi sp, sp, -(CONTEXT_SIZE)
|
||||
sw a0, 0(sp)
|
||||
sw a1, 4(sp)
|
||||
sw a2, 8(sp)
|
||||
sw a3, 12(sp)
|
||||
sw a4, 16(sp)
|
||||
sw a5, 20(sp)
|
||||
sw a6, 24(sp)
|
||||
sw a7, 28(sp)
|
||||
sw t0, 32(sp)
|
||||
sw t1, 36(sp)
|
||||
sw t2, 40(sp)
|
||||
sw t3, 44(sp)
|
||||
sw t4, 48(sp)
|
||||
sw t5, 52(sp)
|
||||
sw t6, 56(sp)
|
||||
sw ra, 60(sp)
|
||||
|
||||
/* MIE is cleared, so nested interrupts are disabled */
|
||||
|
||||
/* Reset isr interrupt flags */
|
||||
li a1, HP_SYSTEM_CPU_INT_FROM_CPU_2_REG
|
||||
csrr a0, mhartid # Get CORE_ID
|
||||
beqz a0, 1f
|
||||
li a1, HP_SYSTEM_CPU_INT_FROM_CPU_3_REG
|
||||
1:
|
||||
sw zero, (a1)
|
||||
|
||||
/* Set the start flag */
|
||||
la a0, esp_ipc_isr_start_fl
|
||||
sw a0, 0(a0)
|
||||
|
||||
/* Call the esp_ipc_func(void* esp_ipc_func_arg) */
|
||||
lw a1, (esp_ipc_func)
|
||||
lw a0, (esp_ipc_func_arg)
|
||||
jalr a1
|
||||
|
||||
/* Set the end flag */
|
||||
la a0, esp_ipc_isr_end_fl
|
||||
sw a0, 0(a0)
|
||||
|
||||
/* Restore a0 - a7, t0 - t6, ra */
|
||||
lw a0, 0(sp)
|
||||
lw a1, 4(sp)
|
||||
lw a2, 8(sp)
|
||||
lw a3, 12(sp)
|
||||
lw a4, 16(sp)
|
||||
lw a5, 20(sp)
|
||||
lw a6, 24(sp)
|
||||
lw a7, 28(sp)
|
||||
lw t0, 32(sp)
|
||||
lw t1, 36(sp)
|
||||
lw t2, 40(sp)
|
||||
lw t3, 44(sp)
|
||||
lw t4, 48(sp)
|
||||
lw t5, 52(sp)
|
||||
lw t6, 56(sp)
|
||||
lw ra, 60(sp)
|
||||
addi sp, sp, (CONTEXT_SIZE)
|
||||
|
||||
mret
|
48
components/esp_system/port/arch/riscv/esp_ipc_isr_port.c
Normal file
48
components/esp_system/port/arch/riscv/esp_ipc_isr_port.c
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "soc/soc.h"
|
||||
#include "soc/interrupts.h"
|
||||
#include "soc/hp_system_reg.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "riscv/interrupt.h"
|
||||
#include "esp_rom_sys.h"
|
||||
#include "esp_cpu.h"
|
||||
#include "esp_attr.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
|
||||
void esp_ipc_isr_port_init(const int cpuid)
|
||||
{
|
||||
uint32_t intr_source = ETS_FROM_CPU_INTR2_SOURCE + cpuid; // ETS_FROM_CPU_INTR2_SOURCE and ETS_FROM_CPU_INTR3_SOURCE
|
||||
|
||||
esp_intr_disable_source(ETS_IPC_ISR_INUM);
|
||||
|
||||
esp_rom_route_intr_matrix(cpuid, intr_source, ETS_IPC_ISR_INUM);
|
||||
|
||||
esp_cpu_intr_set_type(ETS_IPC_ISR_INUM, INTR_TYPE_LEVEL);
|
||||
|
||||
#if CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5
|
||||
esp_cpu_intr_set_priority(ETS_IPC_ISR_INUM, 5);
|
||||
#elif CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4
|
||||
esp_cpu_intr_set_priority(ETS_IPC_ISR_INUM, 4);
|
||||
#else
|
||||
#error "CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL is not defined!"
|
||||
#endif
|
||||
|
||||
esp_intr_enable_source(ETS_IPC_ISR_INUM);
|
||||
}
|
||||
|
||||
IRAM_ATTR void esp_ipc_isr_port_int_trigger(const int cpuid)
|
||||
{
|
||||
if (cpuid == 0) {
|
||||
// it runs an interrupt on cpu0
|
||||
REG_WRITE(HP_SYSTEM_CPU_INT_FROM_CPU_2_REG, HP_SYSTEM_CPU_INT_FROM_CPU_2);
|
||||
} else {
|
||||
// it runs an interrupt on cpu1
|
||||
REG_WRITE(HP_SYSTEM_CPU_INT_FROM_CPU_3_REG, HP_SYSTEM_CPU_INT_FROM_CPU_3);
|
||||
}
|
||||
}
|
12
components/esp_system/port/arch/riscv/esp_ipc_isr_routines.c
Normal file
12
components/esp_system/port/arch/riscv/esp_ipc_isr_routines.c
Normal file
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "stdint.h"
|
||||
|
||||
void esp_ipc_isr_waiting_for_finish_cmd(void* ipc_isr_finish_cmd)
|
||||
{
|
||||
while (*(volatile uint32_t*)ipc_isr_finish_cmd == 0) { };
|
||||
}
|
36
components/esp_system/port/arch/xtensa/esp_ipc_isr_port.c
Normal file
36
components/esp_system/port/arch/xtensa/esp_ipc_isr_port.c
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "soc/soc.h"
|
||||
#include "soc/interrupts.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32
|
||||
#include "soc/system_reg.h"
|
||||
#endif
|
||||
#include "esp_rom_sys.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "esp_attr.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
|
||||
void esp_ipc_isr_port_init(const int cpuid)
|
||||
{
|
||||
uint32_t intr_source = ETS_FROM_CPU_INTR2_SOURCE + cpuid; // ETS_FROM_CPU_INTR2_SOURCE and ETS_FROM_CPU_INTR3_SOURCE
|
||||
ESP_INTR_DISABLE(ETS_IPC_ISR_INUM);
|
||||
esp_rom_route_intr_matrix(cpuid, intr_source, ETS_IPC_ISR_INUM);
|
||||
ESP_INTR_ENABLE(ETS_IPC_ISR_INUM);
|
||||
}
|
||||
|
||||
IRAM_ATTR void esp_ipc_isr_port_int_trigger(const int cpuid)
|
||||
{
|
||||
if (cpuid == 0) {
|
||||
// it runs an interrupt on cpu0
|
||||
DPORT_REG_WRITE(SYSTEM_CPU_INTR_FROM_CPU_2_REG, SYSTEM_CPU_INTR_FROM_CPU_2);
|
||||
} else {
|
||||
// it runs an interrupt on cpu1
|
||||
DPORT_REG_WRITE(SYSTEM_CPU_INTR_FROM_CPU_3_REG, SYSTEM_CPU_INTR_FROM_CPU_3);
|
||||
}
|
||||
}
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -10,19 +10,12 @@
|
||||
#include <assert.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_attr.h"
|
||||
#include "soc/soc.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32
|
||||
#include "soc/periph_defs.h"
|
||||
#include "soc/system_reg.h"
|
||||
#endif
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/portmacro.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "esp_private/esp_ipc_isr.h"
|
||||
#include "esp_private/esp_ipc_isr_port.h"
|
||||
#include "esp_ipc_isr.h"
|
||||
#include "xtensa/core-macros.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
static portMUX_TYPE s_ipc_isr_mux = portMUX_INITIALIZER_UNLOCKED;
|
||||
@@ -61,10 +54,7 @@ static void esp_ipc_isr_call_and_wait(esp_ipc_isr_func_t func, void* arg, esp_ip
|
||||
void esp_ipc_isr_init(void)
|
||||
{
|
||||
const uint32_t cpuid = xPortGetCoreID();
|
||||
uint32_t intr_source = ETS_FROM_CPU_INTR2_SOURCE + cpuid; // ETS_FROM_CPU_INTR2_SOURCE and ETS_FROM_CPU_INTR3_SOURCE
|
||||
ESP_INTR_DISABLE(ETS_IPC_ISR_INUM);
|
||||
esp_rom_route_intr_matrix(cpuid, intr_source, ETS_IPC_ISR_INUM);
|
||||
ESP_INTR_ENABLE(ETS_IPC_ISR_INUM);
|
||||
esp_ipc_isr_port_init(cpuid);
|
||||
|
||||
if (cpuid != 0) {
|
||||
s_stall_state = STALL_STATE_RUNNING;
|
||||
@@ -76,14 +66,14 @@ void esp_ipc_isr_init(void)
|
||||
|
||||
/* Public API functions */
|
||||
|
||||
void IRAM_ATTR esp_ipc_isr_asm_call(esp_ipc_isr_func_t func, void* arg)
|
||||
void IRAM_ATTR esp_ipc_isr_call(esp_ipc_isr_func_t func, void* arg)
|
||||
{
|
||||
IPC_ISR_ENTER_CRITICAL();
|
||||
esp_ipc_isr_call_and_wait(func, arg, IPC_ISR_WAIT_FOR_START);
|
||||
IPC_ISR_EXIT_CRITICAL();
|
||||
}
|
||||
|
||||
void IRAM_ATTR esp_ipc_isr_asm_call_blocking(esp_ipc_isr_func_t func, void* arg)
|
||||
void IRAM_ATTR esp_ipc_isr_call_blocking(esp_ipc_isr_func_t func, void* arg)
|
||||
{
|
||||
IPC_ISR_ENTER_CRITICAL();
|
||||
esp_ipc_isr_call_and_wait(func, arg, IPC_ISR_WAIT_FOR_END);
|
||||
@@ -201,14 +191,8 @@ static void IRAM_ATTR esp_ipc_isr_call_and_wait(esp_ipc_isr_func_t func, void* a
|
||||
esp_ipc_isr_start_fl = 0;
|
||||
esp_ipc_isr_end_fl = 0;
|
||||
|
||||
if (cpu_id == 0) {
|
||||
// it runs an interrupt on cpu1
|
||||
DPORT_REG_WRITE(SYSTEM_CPU_INTR_FROM_CPU_3_REG, SYSTEM_CPU_INTR_FROM_CPU_3);
|
||||
} else {
|
||||
// it runs an interrupt on cpu0
|
||||
DPORT_REG_WRITE(SYSTEM_CPU_INTR_FROM_CPU_2_REG, SYSTEM_CPU_INTR_FROM_CPU_2);
|
||||
}
|
||||
|
||||
// Trigger an interrupt on the opposite core.
|
||||
esp_ipc_isr_port_int_trigger(!cpu_id);
|
||||
// IPC_ISR handler will be called and `...isr_start` and `...isr_end` will be updated there
|
||||
|
||||
if (wait_for == IPC_ISR_WAIT_FOR_START) {
|
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ESP_IPC_ISR_ENABLE
|
||||
|
||||
/**
|
||||
* @brief Initialize the IPC ISR interrupt for a specific CPU.
|
||||
*
|
||||
* This function initializes the IPC ISR (Inter-Processor Communication Interrupt)
|
||||
* for a specific CPU core. It configures the interrupt source and enables the
|
||||
* IPC ISR interrupt for the specified CPU.
|
||||
*
|
||||
* @param[in] cpuid The ID of the CPU core to initialize IPC ISR for.
|
||||
*/
|
||||
void esp_ipc_isr_port_init(const int cpuid);
|
||||
|
||||
/**
|
||||
* @brief Trigger an interrupt on a specific CPU core.
|
||||
*
|
||||
* @param[in] cpuid The ID of the CPU core to trigger the interrupt on (0 or 1).
|
||||
*/
|
||||
void esp_ipc_isr_port_int_trigger(const int cpuid);
|
||||
|
||||
#endif // CONFIG_ESP_IPC_ISR_ENABLE
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@@ -16,7 +16,12 @@ set(SRC "test_app_main.c"
|
||||
"test_task_wdt.c")
|
||||
|
||||
if(CONFIG_ESP_IPC_ISR_ENABLE)
|
||||
list(APPEND SRC "test_ipc_isr.c" "test_ipc_isr.S")
|
||||
list(APPEND SRC "test_ipc_isr.c")
|
||||
if(CONFIG_IDF_TARGET_ARCH_XTENSA)
|
||||
list(APPEND SRC "port/arch/xtensa/test_ipc_isr.S")
|
||||
elseif(CONFIG_IDF_TARGET_ARCH_RISCV)
|
||||
list(APPEND SRC "port/arch/riscv/test_ipc_isr.c")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS ${SRC}
|
||||
|
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#if CONFIG_ESP_IPC_ISR_ENABLE
|
||||
|
||||
void esp_test_ipc_isr_callback(void *arg) {
|
||||
uint32_t value = 0xa5a5;
|
||||
*(volatile uint32_t*)arg = value;
|
||||
}
|
||||
|
||||
void esp_test_ipc_isr_get_other_core_id(void *arg) {
|
||||
uint32_t core_id;
|
||||
__asm volatile("csrr %0, mhartid" : "=r"(core_id));
|
||||
*(volatile uint32_t*)arg = core_id;
|
||||
}
|
||||
|
||||
void esp_test_ipc_isr_get_cycle_count_other_cpu(void *arg) {
|
||||
uint32_t cycle_count;
|
||||
__asm volatile("rdcycle %0;" : "=r"(cycle_count));
|
||||
*(volatile uint32_t*)arg = cycle_count;
|
||||
}
|
||||
|
||||
#endif // CONFIG_ESP_IPC_ISR_ENABLE
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -13,18 +13,18 @@
|
||||
#include <xtensa/config/system.h>
|
||||
#include <xtensa/hal.h>
|
||||
|
||||
/* esp_test_ipc_isr_asm(void *arg)
|
||||
/* esp_test_ipc_isr_callback(void *arg)
|
||||
*
|
||||
* 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"
|
||||
.align 4
|
||||
.global esp_test_ipc_isr_asm
|
||||
.type esp_test_ipc_isr_asm, @function
|
||||
.global esp_test_ipc_isr_callback
|
||||
.type esp_test_ipc_isr_callback, @function
|
||||
// Args:
|
||||
// a2 - void* arg
|
||||
esp_test_ipc_isr_asm:
|
||||
esp_test_ipc_isr_callback:
|
||||
movi a3, 0xa5a5
|
||||
s32i a3, a2, 0
|
||||
ret
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -17,12 +17,18 @@
|
||||
|
||||
#ifdef CONFIG_ESP_IPC_ISR_ENABLE
|
||||
|
||||
void esp_test_ipc_isr_asm(void* arg);
|
||||
#if CONFIG_IDF_TARGET_ARCH_RISCV
|
||||
#define STORE_ERROR "Store access fault"
|
||||
#else
|
||||
#define STORE_ERROR "StoreProhibited"
|
||||
#endif
|
||||
|
||||
void esp_test_ipc_isr_callback(void* arg);
|
||||
|
||||
TEST_CASE("Test ipc_isr blocking IPC function calls a ASM function", "[ipc]")
|
||||
{
|
||||
int val = 0x5a5a;
|
||||
esp_ipc_isr_asm_call_blocking(esp_test_ipc_isr_asm, &val);
|
||||
esp_ipc_isr_call_blocking(esp_test_ipc_isr_callback, &val);
|
||||
TEST_ASSERT_EQUAL_HEX(val, 0xa5a5);
|
||||
}
|
||||
|
||||
@@ -32,13 +38,13 @@ void esp_test_ipc_isr_get_other_core_id(void* arg);
|
||||
TEST_CASE("Test ipc_isr blocking IPC function calls get_other_core_id", "[ipc]")
|
||||
{
|
||||
int val = 0x5a5a;
|
||||
esp_ipc_isr_asm_call_blocking(esp_test_ipc_isr_get_other_core_id, &val);
|
||||
esp_ipc_isr_call_blocking(esp_test_ipc_isr_get_other_core_id, &val);
|
||||
TEST_ASSERT_EQUAL_HEX(val, 1);
|
||||
}
|
||||
|
||||
static void do_esp_ipc_isr_asm_call_blocking(void)
|
||||
static void do_esp_ipc_isr_call_blocking(void)
|
||||
{
|
||||
esp_ipc_isr_asm_call_blocking(esp_test_ipc_isr_asm, NULL);
|
||||
esp_ipc_isr_call_blocking(esp_test_ipc_isr_callback, NULL);
|
||||
}
|
||||
|
||||
static void check_reset_reason_panic(void)
|
||||
@@ -46,8 +52,8 @@ static void check_reset_reason_panic(void)
|
||||
TEST_ASSERT_EQUAL(ESP_RST_PANIC, esp_reset_reason());
|
||||
}
|
||||
|
||||
TEST_CASE_MULTIPLE_STAGES("Test ipc_isr exception in asm func leads to StoreProhibited not to Unhandled debug exception", "[ipc][reset=StoreProhibited,SW_CPU_RESET]",
|
||||
do_esp_ipc_isr_asm_call_blocking,
|
||||
TEST_CASE_MULTIPLE_STAGES("Test ipc_isr exception in asm func leads to StoreProhibited not to Unhandled debug exception", "[ipc][reset="STORE_ERROR",SW_CPU_RESET]",
|
||||
do_esp_ipc_isr_call_blocking,
|
||||
check_reset_reason_panic)
|
||||
|
||||
void esp_test_ipc_isr_get_cycle_count_other_cpu(void* arg);
|
||||
@@ -55,7 +61,7 @@ void esp_test_ipc_isr_get_cycle_count_other_cpu(void* arg);
|
||||
TEST_CASE("Test ipc_isr blocking IPC function calls get_cycle_count_other_cpu", "[ipc]")
|
||||
{
|
||||
int val = 0x5a5a;
|
||||
esp_ipc_isr_asm_call_blocking(esp_test_ipc_isr_get_cycle_count_other_cpu, &val);
|
||||
esp_ipc_isr_call_blocking(esp_test_ipc_isr_get_cycle_count_other_cpu, &val);
|
||||
esp_rom_printf("CCOUNT CPU0 = %d\n", esp_cpu_get_cycle_count());
|
||||
esp_rom_printf("CCOUNT CPU1 = %d\n", val);
|
||||
}
|
||||
@@ -70,12 +76,12 @@ static void task_asm(void *arg)
|
||||
printf("task_asm\n");
|
||||
while (s_stop == false) {
|
||||
val = 0x5a5a;
|
||||
esp_ipc_isr_asm_call_blocking(esp_test_ipc_isr_asm, &val);
|
||||
esp_ipc_isr_call_blocking(esp_test_ipc_isr_callback, &val);
|
||||
TEST_ASSERT_EQUAL_HEX(val, 0xa5a5);
|
||||
++counter;
|
||||
}
|
||||
printf("task_asm counter = %d\n", counter);
|
||||
TEST_ASSERT_GREATER_THAN(10000, counter);
|
||||
TEST_ASSERT_GREATER_THAN(1000, counter);
|
||||
xSemaphoreGive(*sema);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
Reference in New Issue
Block a user