mirror of
https://github.com/apache/nuttx.git
synced 2026-09-28 15:54:57 +08:00
esp32s3/irq: Allow IRAM ISRs to run during SPI flash operation
This commit provides an interface to register ISRs that run from IRAM and keeps track of the non-IRAM interrupts. It enables, for instance, to avoid disabling all the interrupts during a SPI flash operation: IRAM-enabled ISRs are, then, able to run during these operations.
This commit is contained in:
committed by
Xiang Xiao
parent
86b118854e
commit
0ddb64555a
@@ -37,6 +37,16 @@
|
||||
|
||||
#define ESP32S3_INT_PRIO_DEF 1
|
||||
|
||||
/* CPU interrupt flags:
|
||||
* These flags can be used to specify which interrupt qualities the
|
||||
* code calling esp32s3_setup_irq needs.
|
||||
*/
|
||||
|
||||
#define ESP32S3_CPUINT_FLAG_LEVEL (1 << 0) /* Level-triggered interrupt */
|
||||
#define ESP32S3_CPUINT_FLAG_EDGE (1 << 1) /* Edge-triggered interrupt */
|
||||
#define ESP32S3_CPUINT_FLAG_SHARED (1 << 2) /* Interrupt can be shared between ISRs */
|
||||
#define ESP32S3_CPUINT_FLAG_IRAM (1 << 3) /* ISR can be called if cache is disabled */
|
||||
|
||||
/* Interrupt Matrix
|
||||
*
|
||||
* The Interrupt Matrix embedded in the ESP32-S3 independently allocates
|
||||
@@ -386,17 +396,13 @@
|
||||
* 26 can be mapped to peripheral interrupts:
|
||||
*
|
||||
* Level triggered peripherals (21 total):
|
||||
* 0-5, 8-9, 12-13, 17-18 - Priority 1
|
||||
* 19-21 - Priority 2
|
||||
* 23, 27 - Priority 3
|
||||
* 24-25 - Priority 4
|
||||
* 26, 31 - Priority 5
|
||||
* Edge triggered peripherals (4 total):
|
||||
* 10 - Priority 1
|
||||
* 22 - Priority 3
|
||||
* 28, 30 - Priority 4
|
||||
* 0-5, 8-10, 12-13, 17-18 - Priority 1
|
||||
* 19-21 - Priority 2
|
||||
* 22-23, 27 - Priority 3
|
||||
* 24-25, 28, 30 - Priority 4
|
||||
* 26, 31 - Priority 5
|
||||
* NMI (1 total):
|
||||
* 14 - NMI
|
||||
* 14 - NMI
|
||||
*
|
||||
* CPU peripheral interrupts can be a assigned to a CPU interrupt using the
|
||||
* PRO_*_MAP_REG or APP_*_MAP_REG. There are a pair of these registers for
|
||||
|
||||
@@ -734,6 +734,19 @@ menuconfig ESP32S3_WIFI_BT_COEXIST
|
||||
depends on ESP32S3_WIFI && ESP32S3_BLE
|
||||
select ESP32S3_WIFI_STA_DISCONNECT_PM
|
||||
|
||||
menu "Interrupt Configuration"
|
||||
|
||||
config ESP32S3_IRAM_ISR_DEBUG
|
||||
bool "Enable debugging of the IRAM-enabled interrupts"
|
||||
default n
|
||||
---help---
|
||||
This option enables keeping track of the IRAM-enabled interrupts by
|
||||
registering its execution when non-IRAM interrupts are disabled. It
|
||||
keeps track of the IRQ executed and register how many times since
|
||||
boot it was executed.
|
||||
|
||||
endmenu # Interrupt Configuration
|
||||
|
||||
menu "SPI RAM Configuration"
|
||||
depends on ESP32S3_SPIRAM
|
||||
|
||||
@@ -1605,6 +1618,17 @@ config ESP32S3_STORAGE_MTD_DEBUG
|
||||
If this option is enabled, Storage MTD driver read and write functions
|
||||
will output input parameters and return values (if applicable).
|
||||
|
||||
config ESP32S3_SPIFLASH_OP_TASK_STACKSIZE
|
||||
int "The SPI flash operation task stack size"
|
||||
default 768
|
||||
depends on SMP
|
||||
---help---
|
||||
When SMP is enabled, it is needed to create two tasks (one for each
|
||||
core) to be able to run IRAM-enabled interrupts. These tasks ensures
|
||||
that the core that isn't performing the SPI flash operation is able
|
||||
to disable non-IRAM interrupts and wait for the SPI flash operation
|
||||
to be finished.
|
||||
|
||||
endif # ESP32S3_SPIFLASH
|
||||
|
||||
endmenu # SPI Flash configuration
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -46,8 +46,8 @@ extern "C"
|
||||
|
||||
/* CPU interrupt types. */
|
||||
|
||||
#define ESP32S3_CPUINT_LEVEL 0
|
||||
#define ESP32S3_CPUINT_EDGE 1
|
||||
#define ESP32S3_CPUINT_LEVEL ESP32S3_CPUINT_FLAG_LEVEL
|
||||
#define ESP32S3_CPUINT_EDGE ESP32S3_CPUINT_FLAG_EDGE
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions Prototypes
|
||||
@@ -82,7 +82,9 @@ int esp32s3_cpuint_initialize(void);
|
||||
* periphid - The peripheral number from irq.h to be assigned to
|
||||
* a CPU interrupt.
|
||||
* priority - Interrupt's priority (1 - 5).
|
||||
* type - Interrupt's type (level or edge).
|
||||
* flags - An ORred mask of the ESP32S3_CPUINT_FLAG_* defines. These
|
||||
* restrict the choice of interrupts that this routine can
|
||||
* choose from.
|
||||
*
|
||||
* Returned Value:
|
||||
* The allocated CPU interrupt on success, a negated errno value on
|
||||
@@ -90,7 +92,7 @@ int esp32s3_cpuint_initialize(void);
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int esp32s3_setup_irq(int cpu, int periphid, int priority, int type);
|
||||
int esp32s3_setup_irq(int cpu, int periphid, int priority, int flags);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32s3_teardown_irq
|
||||
@@ -121,8 +123,8 @@ void esp32s3_teardown_irq(int cpu, int periphid, int cpuint);
|
||||
* This function returns the IRQ associated with a CPU interrupt
|
||||
*
|
||||
* Input Parameters:
|
||||
* cpu - The CPU to receive the interrupt 0=PRO CPU 1=APP CPU
|
||||
* cpuint - The CPU interrupt associated to the IRQ
|
||||
* cpu - The CPU core of the IRQ being queried
|
||||
* cpuint - The CPU interrupt associated to the IRQ
|
||||
*
|
||||
* Returned Value:
|
||||
* The IRQ associated with such CPU interrupt or CPUINT_UNASSIGNED if
|
||||
@@ -132,6 +134,126 @@ void esp32s3_teardown_irq(int cpu, int periphid, int cpuint);
|
||||
|
||||
int esp32s3_getirq(int cpu, int cpuint);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32s3_getcpuint_from_irq
|
||||
*
|
||||
* Description:
|
||||
* This function returns the CPU interrupt associated with an IRQ
|
||||
*
|
||||
* Input Parameters:
|
||||
* irq - The IRQ associated with a CPU interrupt
|
||||
* cpu - Pointer to store the CPU core of the CPU interrupt
|
||||
*
|
||||
* Returned Value:
|
||||
* The CPU interrupt associated with such IRQ or IRQ_UNMAPPED if
|
||||
* CPU interrupt is not mapped to an IRQ.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int esp32s3_getcpuint_from_irq(int irq, int *cpu);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32s3_irq_noniram_disable
|
||||
*
|
||||
* Description:
|
||||
* Disable interrupts that aren't specifically marked as running from IRAM
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void esp32s3_irq_noniram_disable(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32s3_irq_noniram_enable
|
||||
*
|
||||
* Description:
|
||||
* Re-enable interrupts disabled by esp32s3_irq_noniram_disable
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void esp32s3_irq_noniram_enable(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32s3_irq_noniram_status
|
||||
*
|
||||
* Description:
|
||||
* Get the current status of non-IRAM interrupts on a specific CPU core
|
||||
*
|
||||
* Input Parameters:
|
||||
* cpu - The CPU to check the non-IRAM interrupts state
|
||||
*
|
||||
* Returned Value:
|
||||
* true if non-IRAM interrupts are enabled, false otherwise.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
bool esp32s3_irq_noniram_status(int cpu);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32s3_irq_set_iram_isr
|
||||
*
|
||||
* Description:
|
||||
* Set the ISR associated to an IRQ as a IRAM-enabled ISR.
|
||||
*
|
||||
* Input Parameters:
|
||||
* irq - The associated IRQ to set
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success; A negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int esp32s3_irq_set_iram_isr(int irq);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32s3_irq_unset_iram_isr
|
||||
*
|
||||
* Description:
|
||||
* Set the ISR associated to an IRQ as a non-IRAM ISR.
|
||||
*
|
||||
* Input Parameters:
|
||||
* irq - The associated IRQ to set
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success; A negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int esp32s3_irq_unset_iram_isr(int irq);
|
||||
|
||||
#ifdef CONFIG_ESP32S3_IRAM_ISR_DEBUG
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32s3_get_iram_interrupt_records
|
||||
*
|
||||
* Description:
|
||||
* This function copies the vector that keeps track of the IRQs that ran
|
||||
* when non-IRAM interrupts were disabled.
|
||||
*
|
||||
* Input Parameters:
|
||||
*
|
||||
* irq_count - A previously allocated pointer to store the counter of the
|
||||
* interrupts that ran when non-IRAM interrupts were disabled.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void esp32s3_get_iram_interrupt_records(uint64_t *irq_count);
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -521,6 +521,19 @@ static inline bool IRAM_ATTR esp32s3_ptr_extram(const void *p)
|
||||
(intptr_t)p < SOC_EXTRAM_DATA_HIGH);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32s3_ptr_iram
|
||||
*
|
||||
* Description:
|
||||
* Check if the pointer is in IRAM
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline bool IRAM_ATTR esp32s3_ptr_iram(const void *p)
|
||||
{
|
||||
return ((intptr_t)p >= SOC_IRAM_LOW && (intptr_t)p < SOC_IRAM_HIGH);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32s3_ptr_exec
|
||||
*
|
||||
|
||||
@@ -76,24 +76,30 @@ SECTIONS
|
||||
|
||||
*(.iram1 .iram1.*)
|
||||
|
||||
*libarch.a:esp32s3_cpuindex.*(.literal .text .literal.* .text.*)
|
||||
*libarch.a:esp32s3_irq.*(.literal .text .literal.* .text.*)
|
||||
*libarch.a:esp32s3_spiflash.*(.literal .text .literal.* .text.*)
|
||||
*libarch.a:xtensa_assert.*(.literal .text .literal.* .text.*)
|
||||
*libarch.a:xtensa_cpuint.*(.literal .text .literal.* .text.*)
|
||||
*libarch.a:xtensa_cpupause.*(.literal .text .literal.* .text.*)
|
||||
*libarch.a:xtensa_irqdispatch.*(.literal .text .literal.* .text.*)
|
||||
*libarch.a:xtensa_modifyreg32.*(.literal .text .literal.* .text.*)
|
||||
*libarch.a:xtensa_testset.*(.literal .text .literal.* .text.*)
|
||||
*libarch.a:xtensa_modifyreg32.*(.literal.modifyreg32 .text.modifyreg32)
|
||||
|
||||
*libdrivers.a:syslog_flush.*(.literal .text .literal.* .text.*)
|
||||
|
||||
*libsched.a:assert.*(.literal .text .literal.* .text.*)
|
||||
*libsched.a:irq_csection.*(.literal .text .literal.* .text.*)
|
||||
*libsched.a:irq_dispatch.*(.literal .text .literal.* .text.*)
|
||||
*libsched.a:irq_spinlock.*(.literal .text .literal.* .text.*)
|
||||
*libsched.a:sched_note.*(.literal .text .literal.* .text.*)
|
||||
*libsched.a:sched_suspendscheduler.*(.literal .text .literal.* .text.*)
|
||||
*libsched.a:sched_thistask.*(.literal .text .literal.* .text.*)
|
||||
*libsched.a:spinlock.*(.literal .text .literal.* .text.*)
|
||||
|
||||
#ifdef CONFIG_ESP32S3_SPEED_UP_ISR
|
||||
*libarch.a:xtensa_irqdispatch.*(.literal.xtensa_irq_dispatch .text.xtensa_irq_dispatch)
|
||||
*libarch.a:xtensa_switchcontext.*(.literal.up_switch_context .text.up_switch_context)
|
||||
*libarch.a:xtensa_modifyreg32.*(.literal.modifyreg32 .text.modifyreg32)
|
||||
|
||||
*libarch.a:esp32s3_irq.*(.literal.xtensa_int_decode .text.xtensa_int_decode)
|
||||
*libarch.a:esp32s3_timerisr.*(.literal.systimer_isr .text.systimer_isr)
|
||||
*libarch.a:esp32s3_idle.*(.literal.up_idle .text.up_idle)
|
||||
*libarch.a:esp32s3_dma.*(.literal.esp32s3_dma_load .text.esp32s3_dma_load \
|
||||
@@ -195,6 +201,7 @@ SECTIONS
|
||||
*(.dram1 .dram1.*)
|
||||
|
||||
*libphy.a:(.rodata .rodata.*)
|
||||
*libarch.a:xtensa_context.*(.rodata .rodata.*)
|
||||
|
||||
_edata = ABSOLUTE(.);
|
||||
. = ALIGN(4);
|
||||
|
||||
Reference in New Issue
Block a user