mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Per-CPU interrupt handlers and args
This commit is contained in:
parent
fcba7e278d
commit
86d8f63005
@ -45,14 +45,9 @@ the ISR will cause it to switch _away_ from it. portYIELD_FROM_ISR will probably
|
||||
*/
|
||||
static void esp_crosscore_isr(void *arg) {
|
||||
uint32_t myReasonVal;
|
||||
#if 0
|
||||
//A pointer to the correct reason array item is passed to this ISR.
|
||||
volatile uint32_t *myReason=arg;
|
||||
#else
|
||||
//The previous line does not work yet, the interrupt code needs work to understand two separate interrupt and argument
|
||||
//tables... this is a valid but slightly less optimal replacement.
|
||||
volatile uint32_t *myReason=&reason[xPortGetCoreID()];
|
||||
#endif
|
||||
|
||||
//Clear the interrupt first.
|
||||
if (xPortGetCoreID()==0) {
|
||||
WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_0_REG, 0);
|
||||
|
@ -265,12 +265,6 @@
|
||||
#define INCLUDE_eTaskGetState 1
|
||||
#define configUSE_QUEUE_SETS 1
|
||||
|
||||
#if (!defined XT_INTEXC_HOOKS)
|
||||
#define configXT_INTEXC_HOOKS 1 /* Exception hooks used by certain tests */
|
||||
#if configUSE_TRACE_FACILITY_2
|
||||
#define configASSERT_2 1 /* Specific to Xtensa port */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define configXT_BOARD 1 /* Board mode */
|
||||
#define configXT_SIMULATOR 0
|
||||
|
@ -19,11 +19,6 @@ it would on a single-core system: the other core still will keep on
|
||||
executing all it's own. Use a mux, queue or semaphore to protect your
|
||||
structures instead.
|
||||
|
||||
- While each core has individual interrupts, the handlers are shared. This
|
||||
means that when you set a handler for an interrupt, it will get triggered if
|
||||
the interrupt is triggered on both CPU0 as well as on CPU1. This is something
|
||||
we may change in future FreeRTOS-esp32 releases.
|
||||
|
||||
- This FreeRTOS version has the task local storage backported from the 8.2.x
|
||||
versions. It, however, has an addition: you can also set a callback when you
|
||||
set the pointer. This callback will be called by the idle task, with the
|
||||
|
@ -30,7 +30,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#include <xtensa/config/core.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/xtensa_api.h"
|
||||
#include "freertos/portable.h"
|
||||
|
||||
#include "rom/ets_sys.h"
|
||||
|
||||
@ -39,7 +41,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
/* Handler table is in xtensa_intr_asm.S */
|
||||
// Todo: Make multicore - JD
|
||||
|
||||
extern xt_exc_handler _xt_exception_table[XCHAL_EXCCAUSE_NUM];
|
||||
extern xt_exc_handler _xt_exception_table[XCHAL_EXCCAUSE_NUM*portNUM_PROCESSORS];
|
||||
|
||||
|
||||
/*
|
||||
@ -66,6 +68,8 @@ xt_exc_handler xt_set_exception_handler(int n, xt_exc_handler f)
|
||||
if( n < 0 || n >= XCHAL_EXCCAUSE_NUM )
|
||||
return 0; /* invalid exception number */
|
||||
|
||||
/* Convert exception number to _xt_exception_table name */
|
||||
n = n * portNUM_PROCESSORS + xPortGetCoreID();
|
||||
old = _xt_exception_table[n];
|
||||
|
||||
if (f) {
|
||||
@ -89,7 +93,7 @@ typedef struct xt_handler_table_entry {
|
||||
void * arg;
|
||||
} xt_handler_table_entry;
|
||||
|
||||
extern xt_handler_table_entry _xt_interrupt_table[XCHAL_NUM_INTERRUPTS];
|
||||
extern xt_handler_table_entry _xt_interrupt_table[XCHAL_NUM_INTERRUPTS*portNUM_PROCESSORS];
|
||||
|
||||
|
||||
/*
|
||||
@ -118,6 +122,9 @@ xt_handler xt_set_interrupt_handler(int n, xt_handler f, void * arg)
|
||||
if( Xthal_intlevel[n] > XCHAL_EXCM_LEVEL )
|
||||
return 0; /* priority level too high to safely handle in C */
|
||||
|
||||
/* Convert exception number to _xt_exception_table name */
|
||||
n = n * portNUM_PROCESSORS + xPortGetCoreID();
|
||||
|
||||
entry = _xt_interrupt_table + n;
|
||||
old = entry->handler;
|
||||
|
||||
|
@ -30,6 +30,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#include <xtensa/config/core.h>
|
||||
|
||||
#include "xtensa_context.h"
|
||||
#include "FreeRTOSConfig.h"
|
||||
|
||||
#if XCHAL_HAVE_INTERRUPTS
|
||||
|
||||
@ -59,6 +60,15 @@ _xt_vpri_mask: .word 0xFFFFFFFF /* Virtual priority mask */
|
||||
Table of C-callable interrupt handlers for each interrupt. Note that not all
|
||||
slots can be filled, because interrupts at level > EXCM_LEVEL will not be
|
||||
dispatched to a C handler by default.
|
||||
|
||||
Stored as:
|
||||
int 0 cpu 0
|
||||
int 0 cpu 1
|
||||
...
|
||||
int 0 cpu n
|
||||
int 1 cpu 0
|
||||
int 1 cpu 1
|
||||
etc
|
||||
-------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@ -69,7 +79,7 @@ _xt_vpri_mask: .word 0xFFFFFFFF /* Virtual priority mask */
|
||||
_xt_interrupt_table:
|
||||
|
||||
.set i, 0
|
||||
.rept XCHAL_NUM_INTERRUPTS
|
||||
.rept XCHAL_NUM_INTERRUPTS*portNUM_PROCESSORS
|
||||
.word xt_unhandled_interrupt /* handler address */
|
||||
.word i /* handler arg (default: intnum) */
|
||||
.set i, i+1
|
||||
@ -85,6 +95,15 @@ _xt_interrupt_table:
|
||||
Table of C-callable exception handlers for each exception. Note that not all
|
||||
slots will be active, because some exceptions (e.g. coprocessor exceptions)
|
||||
are always handled by the OS and cannot be hooked by user handlers.
|
||||
|
||||
Stored as:
|
||||
exc 0 cpu 0
|
||||
exc 0 cpu 1
|
||||
...
|
||||
exc 0 cpu n
|
||||
exc 1 cpu 0
|
||||
exc 1 cpu 1
|
||||
etc
|
||||
-------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@ -93,7 +112,7 @@ _xt_interrupt_table:
|
||||
.align 4
|
||||
|
||||
_xt_exception_table:
|
||||
.rept XCHAL_EXCCAUSE_NUM
|
||||
.rept XCHAL_EXCCAUSE_NUM * portNUM_PROCESSORS
|
||||
.word xt_unhandled_exception /* handler address */
|
||||
.endr
|
||||
|
||||
|
@ -113,6 +113,27 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#define XIE_ARG 4
|
||||
#define XIE_SIZE 8
|
||||
|
||||
|
||||
/*
|
||||
Macro get_percpu_entry_for - convert a per-core ID into a multicore entry.
|
||||
Basically does reg=reg*portNUM_PROCESSORS+current_core_id
|
||||
Multiple versions here for multiple
|
||||
*/
|
||||
.macro get_percpu_entry_for reg scratch
|
||||
#if (portNUM_PROCESSORS == 1)
|
||||
/* No need to do anything */
|
||||
#elif (portNUM_PROCESSORS == 2)
|
||||
/* Optimized 2-core code. */
|
||||
getcoreid \scratch
|
||||
addx2 \reg,\reg,\scratch
|
||||
#else
|
||||
/* Generalized n-core code. Untested! */
|
||||
movi \scratch,portNUM_PROCESSORS
|
||||
mull \scratch,\reg,\scratch
|
||||
getcoreid \reg
|
||||
add \reg,\scratch,\reg
|
||||
#endif
|
||||
.endm
|
||||
/*
|
||||
--------------------------------------------------------------------------------
|
||||
Macro extract_msb - return the input with only the highest bit set.
|
||||
@ -229,6 +250,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
find_ms_setbit a3, a4, a3, 0 /* a3 = interrupt number */
|
||||
|
||||
get_percpu_entry_for a3, a12
|
||||
movi a4, _xt_interrupt_table
|
||||
addx8 a3, a3, a4 /* a3 = address of interrupt table entry */
|
||||
l32i a4, a3, XIE_HANDLER /* a4 = handler address */
|
||||
@ -395,6 +417,9 @@ panic_print_hex_ok:
|
||||
with index 0 containing the entry for user exceptions.
|
||||
Initialized with all 0s, meaning no handler is installed at each level.
|
||||
See comment in xtensa_rtos.h for more details.
|
||||
|
||||
*WARNING* This array is for all CPUs, that is, installing a hook for
|
||||
one CPU will install it for all others as well!
|
||||
--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@ -688,6 +713,7 @@ _xt_user_exc:
|
||||
|
||||
rsr a2, EXCCAUSE /* recover exc cause */
|
||||
movi a3, _xt_exception_table
|
||||
get_percpu_entry_for a3, a4
|
||||
addx4 a4, a2, a3 /* a4 = address of exception table entry */
|
||||
l32i a4, a4, 0 /* a4 = handler address */
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
|
Loading…
x
Reference in New Issue
Block a user