mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
components/doc: Update doc about high-level interrupt
some bugfix.
This commit is contained in:
parent
57eeb4d953
commit
006a10b050
@ -417,7 +417,7 @@ config BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD
|
|||||||
may cause adv packets lost more.
|
may cause adv packets lost more.
|
||||||
|
|
||||||
config BTDM_CTRL_HLI
|
config BTDM_CTRL_HLI
|
||||||
bool "High level interrut"
|
bool "High level interrupt"
|
||||||
depends on BT_ENABLED
|
depends on BT_ENABLED
|
||||||
default y
|
default y
|
||||||
help
|
help
|
||||||
|
@ -569,6 +569,7 @@ static xt_handler set_isr_hlevel_wrapper(int mask, xt_handler f, void *arg)
|
|||||||
static void IRAM_ATTR interrupt_hlevel_disable(void)
|
static void IRAM_ATTR interrupt_hlevel_disable(void)
|
||||||
{
|
{
|
||||||
assert(xPortGetCoreID() == CONFIG_BTDM_CTRL_PINNED_TO_CORE);
|
assert(xPortGetCoreID() == CONFIG_BTDM_CTRL_PINNED_TO_CORE);
|
||||||
|
assert(hli_cb.nested != ~0);
|
||||||
uint32_t status = hli_intr_disable();
|
uint32_t status = hli_intr_disable();
|
||||||
if (hli_cb.nested++ == 0) {
|
if (hli_cb.nested++ == 0) {
|
||||||
hli_cb.status = status;
|
hli_cb.status = status;
|
||||||
@ -947,7 +948,7 @@ static int32_t queue_recv_hlevel_wrapper(void *queue, void *item, uint32_t block
|
|||||||
if (block_time_ms == OSI_FUNCS_TIME_BLOCKING) {
|
if (block_time_ms == OSI_FUNCS_TIME_BLOCKING) {
|
||||||
ret = xQueueReceive(((hli_queue_handle_t)queue)->downstream, item, portMAX_DELAY);
|
ret = xQueueReceive(((hli_queue_handle_t)queue)->downstream, item, portMAX_DELAY);
|
||||||
} else {
|
} else {
|
||||||
ret =xQueueReceive(((hli_queue_handle_t)queue)->downstream, item, block_time_ms / portTICK_PERIOD_MS);
|
ret = xQueueReceive(((hli_queue_handle_t)queue)->downstream, item, block_time_ms / portTICK_PERIOD_MS);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (int32_t)ret;
|
return (int32_t)ret;
|
||||||
|
@ -1,5 +1,17 @@
|
|||||||
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
|
// Copyright 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||||
// All rights reserved.
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
@ -47,7 +59,6 @@ static void IRAM_ATTR customer_swisr_handle(customer_swisr_t *cus_swisr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static DRAM_ATTR hli_handler_info_t s_hli_handlers[HLI_MAX_HANDLERS];
|
static DRAM_ATTR hli_handler_info_t s_hli_handlers[HLI_MAX_HANDLERS];
|
||||||
// static const char* TAG = "hli_queue";
|
|
||||||
|
|
||||||
esp_err_t hli_intr_register(intr_handler_t handler, void* arg, uint32_t intr_reg, uint32_t intr_mask)
|
esp_err_t hli_intr_register(intr_handler_t handler, void* arg, uint32_t intr_reg, uint32_t intr_mask)
|
||||||
{
|
{
|
||||||
@ -91,14 +102,13 @@ void IRAM_ATTR hli_c_handler(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!handled) {
|
if (!handled) {
|
||||||
// esp_rom_printf(DRAM_STR("hli_c_handler: no handler found!\n"));
|
/* no handler found, it is OK in this case. */
|
||||||
// abort();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t IRAM_ATTR hli_intr_disable(void)
|
uint32_t IRAM_ATTR hli_intr_disable(void)
|
||||||
{
|
{
|
||||||
// disable level 4 and below
|
/* disable level 4 and below */
|
||||||
return XTOS_SET_INTLEVEL(XCHAL_DEBUGLEVEL - 2);
|
return XTOS_SET_INTLEVEL(XCHAL_DEBUGLEVEL - 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,7 +125,7 @@ void IRAM_ATTR hli_intr_restore(uint32_t state)
|
|||||||
#define HLI_QUEUE_FLAG_CUSTOMER BIT(1)
|
#define HLI_QUEUE_FLAG_CUSTOMER BIT(1)
|
||||||
|
|
||||||
static DRAM_ATTR struct hli_queue_t *s_meta_queue_ptr = NULL;
|
static DRAM_ATTR struct hli_queue_t *s_meta_queue_ptr = NULL;
|
||||||
intr_handle_t ret_handle;
|
static intr_handle_t ret_handle;
|
||||||
|
|
||||||
static inline char* IRAM_ATTR wrap_ptr(hli_queue_handle_t queue, char *ptr)
|
static inline char* IRAM_ATTR wrap_ptr(hli_queue_handle_t queue, char *ptr)
|
||||||
{
|
{
|
||||||
@ -150,7 +160,7 @@ static void IRAM_ATTR queue_isr_handler(void* arg)
|
|||||||
res = xQueueSendFromISR(queue->downstream, scratch, &do_yield);
|
res = xQueueSendFromISR(queue->downstream, scratch, &do_yield);
|
||||||
}
|
}
|
||||||
if (res == pdFAIL) {
|
if (res == pdFAIL) {
|
||||||
// ESP_EARLY_LOGE(TAG, "Failed to send to %s %p", (queue->flags & HLI_QUEUE_FLAG_SEMAPHORE) == 0 ? "queue" : "semaphore", queue->downstream);
|
/* Failed to send to downstream queue, it is OK in this case. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -222,7 +232,7 @@ hli_queue_handle_t hli_queue_create(size_t nelem, size_t elem_size, QueueHandle_
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
size_t buf_size = buf_elem * elem_size;
|
size_t buf_size = buf_elem * elem_size;
|
||||||
hli_queue_handle_t res = (hli_queue_handle_t) heap_caps_malloc(sizeof(*res) + buf_size,
|
hli_queue_handle_t res = (hli_queue_handle_t) heap_caps_malloc(sizeof(struct hli_queue_t) + buf_size,
|
||||||
MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
|
MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
|
||||||
if (res == NULL) {
|
if (res == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1,12 +1,20 @@
|
|||||||
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
|
// Copyright 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||||
// All rights reserved.
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "esp_err.h"
|
#include "esp_err.h"
|
||||||
#include "esp_intr_alloc.h"
|
#include "esp_intr_alloc.h"
|
||||||
@ -14,6 +22,10 @@ extern "C" {
|
|||||||
#include "freertos/queue.h"
|
#include "freertos/queue.h"
|
||||||
#include "freertos/semphr.h"
|
#include "freertos/semphr.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
#if CONFIG_BTDM_CTRL_HLI
|
#if CONFIG_BTDM_CTRL_HLI
|
||||||
|
|
||||||
/*** Queues ***/
|
/*** Queues ***/
|
||||||
|
@ -1,5 +1,17 @@
|
|||||||
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
|
// Copyright 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||||
// All rights reserved.
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
|
||||||
#include <xtensa/coreasm.h>
|
#include <xtensa/coreasm.h>
|
||||||
#include <xtensa/corebits.h>
|
#include <xtensa/corebits.h>
|
||||||
@ -21,13 +33,13 @@
|
|||||||
* - WINDOWBASE, WINDOWSTART — only WINDOWSTART is truly needed
|
* - WINDOWBASE, WINDOWSTART — only WINDOWSTART is truly needed
|
||||||
* - SAR, LBEG, LEND, LCOUNT — since the C code might use these
|
* - SAR, LBEG, LEND, LCOUNT — since the C code might use these
|
||||||
* - EPC1 — since the C code might cause window overflow exceptions
|
* - EPC1 — since the C code might cause window overflow exceptions
|
||||||
* This is not laid out a standard exception frame structure
|
* This is not laid out as standard exception frame structure
|
||||||
* for simplicity of the save/restore code.
|
* for simplicity of the save/restore code.
|
||||||
*/
|
*/
|
||||||
#define REG_FILE_SIZE (64 * 4)
|
#define REG_FILE_SIZE (64 * 4)
|
||||||
#define SPECREG_OFFSET REG_FILE_SIZE
|
#define SPECREG_OFFSET REG_FILE_SIZE
|
||||||
#define SPECREG_SIZE (7 * 4)
|
#define SPECREG_SIZE (7 * 4)
|
||||||
#define REG_SAVE_AREA_SIZE (SPECREG_OFFSET * SPECREG_SIZE)
|
#define REG_SAVE_AREA_SIZE (SPECREG_OFFSET + SPECREG_SIZE)
|
||||||
|
|
||||||
.data
|
.data
|
||||||
_l4_intr_stack:
|
_l4_intr_stack:
|
||||||
@ -46,7 +58,7 @@ xt_highint4:
|
|||||||
/*
|
/*
|
||||||
Here, Timer2 is used to count a little time(50us).
|
Here, Timer2 is used to count a little time(50us).
|
||||||
The subsequent dram0 write operation is blocked due to live lock, which will
|
The subsequent dram0 write operation is blocked due to live lock, which will
|
||||||
cause timer2 to timeout and trigger a l5 interrupt.
|
cause timer2 to timeout and trigger a level 5 interrupt.
|
||||||
*/
|
*/
|
||||||
rsr.ccount a0
|
rsr.ccount a0
|
||||||
addmi a0, a0, (CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ*50)
|
addmi a0, a0, (CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ*50)
|
||||||
@ -57,12 +69,13 @@ xt_highint4:
|
|||||||
extui a0, a0, 16, 1
|
extui a0, a0, 16, 1
|
||||||
bnez a0, 1f
|
bnez a0, 1f
|
||||||
movi a0, 0
|
movi a0, 0
|
||||||
xsr a0, INTENABLE // disable all interrupts
|
xsr a0, INTENABLE /* disable all interrupts */
|
||||||
|
/* And a0 with (1 << 16) for Timer 2 interrupt mask */
|
||||||
addmi a0, a0, (1<<14)
|
addmi a0, a0, (1<<14)
|
||||||
addmi a0, a0, (1<<14)
|
addmi a0, a0, (1<<14)
|
||||||
addmi a0, a0, (1<<14)
|
addmi a0, a0, (1<<14)
|
||||||
addmi a0, a0, (1<<14)
|
addmi a0, a0, (1<<14)
|
||||||
wsr a0, INTENABLE
|
wsr a0, INTENABLE /* Enable Timer 2 */
|
||||||
1:
|
1:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -93,14 +106,14 @@ xt_highint4:
|
|||||||
|
|
||||||
#if CONFIG_ESP32_ECO3_CACHE_LOCK_FIX
|
#if CONFIG_ESP32_ECO3_CACHE_LOCK_FIX
|
||||||
movi a0, 0
|
movi a0, 0
|
||||||
xsr a0, INTENABLE // disable all interrupts
|
xsr a0, INTENABLE /* disable all interrupts */
|
||||||
movi a2, ~(1<<16)
|
movi a2, ~(1<<16)
|
||||||
and a0, a2, a0
|
and a0, a2, a0
|
||||||
wsr a0, INTENABLE
|
wsr a0, INTENABLE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* disable exception mode, window overflow */
|
/* disable exception mode, window overflow */
|
||||||
movi a0, PS_INTLEVEL(5) | PS_EXCM /*TOCHECK*/
|
movi a0, PS_INTLEVEL(5) | PS_EXCM
|
||||||
wsr a0, PS
|
wsr a0, PS
|
||||||
rsync
|
rsync
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "soc/dport_reg.h"
|
#include "soc/dport_reg.h"
|
||||||
|
|
||||||
#ifndef CONFIG_FREERTOS_UNICORE
|
#ifndef CONFIG_FREERTOS_UNICORE
|
||||||
|
#ifndef CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5
|
||||||
|
|
||||||
#define L5_INTR_STACK_SIZE 12
|
#define L5_INTR_STACK_SIZE 12
|
||||||
#define L5_INTR_A2_OFFSET 0
|
#define L5_INTR_A2_OFFSET 0
|
||||||
@ -77,6 +78,8 @@ xt_highint5:
|
|||||||
|
|
||||||
.global ld_include_test_dport_xt_highint5
|
.global ld_include_test_dport_xt_highint5
|
||||||
ld_include_test_dport_xt_highint5:
|
ld_include_test_dport_xt_highint5:
|
||||||
|
|
||||||
|
#endif // CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5
|
||||||
#endif // CONFIG_FREERTOS_UNICORE
|
#endif // CONFIG_FREERTOS_UNICORE
|
||||||
|
|
||||||
#endif // CONFIG_IDF_TARGET_ESP32
|
#endif // CONFIG_IDF_TARGET_ESP32
|
||||||
|
@ -15,14 +15,30 @@
|
|||||||
|
|
||||||
/* High-priority interrupt - IPC_ISR handler */
|
/* High-priority interrupt - IPC_ISR handler */
|
||||||
|
|
||||||
#define L5_INTR_STACK_SIZE 16
|
#if CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5
|
||||||
#define L5_INTR_A0_OFFSET 0
|
#define LX_INTR_STACK_SIZE 16
|
||||||
#define L5_INTR_A2_OFFSET 4
|
#define LX_INTR_A0_OFFSET 0
|
||||||
#define L5_INTR_A3_OFFSET 8
|
#define LX_INTR_A2_OFFSET 4
|
||||||
#define L5_INTR_A4_OFFSET 12
|
#define LX_INTR_A3_OFFSET 8
|
||||||
|
#define LX_INTR_A4_OFFSET 12
|
||||||
|
#define EXCSAVE_X EXCSAVE_5
|
||||||
|
#define RFI_X 5
|
||||||
|
|
||||||
|
#elif CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4
|
||||||
|
|
||||||
|
#define LX_INTR_STACK_SIZE 16
|
||||||
|
#define LX_INTR_A0_OFFSET 0
|
||||||
|
#define LX_INTR_A2_OFFSET 4
|
||||||
|
#define LX_INTR_A3_OFFSET 8
|
||||||
|
#define LX_INTR_A4_OFFSET 12
|
||||||
|
#define EXCSAVE_X EXCSAVE_4
|
||||||
|
#define RFI_X 4
|
||||||
|
|
||||||
|
#endif /* CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 */
|
||||||
|
|
||||||
.data
|
.data
|
||||||
_l5_intr_stack:
|
_lx_intr_stack:
|
||||||
.space L5_INTR_STACK_SIZE
|
.space LX_INTR_STACK_SIZE
|
||||||
.section .iram1,"ax"
|
.section .iram1,"ax"
|
||||||
.global esp_ipc_isr_handler
|
.global esp_ipc_isr_handler
|
||||||
.type esp_ipc_isr_handler,@function
|
.type esp_ipc_isr_handler,@function
|
||||||
@ -30,17 +46,17 @@ _l5_intr_stack:
|
|||||||
esp_ipc_isr_handler:
|
esp_ipc_isr_handler:
|
||||||
/* Allocate exception frame and save minimal context. */
|
/* Allocate exception frame and save minimal context. */
|
||||||
/* Because the interrupt cause code has protection that only
|
/* Because the interrupt cause code has protection that only
|
||||||
allows one cpu to enter in the IPC_ISR section of the L4
|
allows one cpu to enter in the IPC_ISR section of the LX
|
||||||
interrupt at one time, there's no need to have two
|
interrupt at one time, there's no need to have two
|
||||||
_l5_intr_stack for each cpu */
|
_lx_intr_stack for each cpu */
|
||||||
|
|
||||||
/* Save A0, A2, A3, A4 so we can use those registers further*/
|
/* Save A0, A2, A3, A4 so we can use those registers further*/
|
||||||
movi a0, _l5_intr_stack
|
movi a0, _lx_intr_stack
|
||||||
s32i a2, a0, L5_INTR_A2_OFFSET
|
s32i a2, a0, LX_INTR_A2_OFFSET
|
||||||
s32i a3, a0, L5_INTR_A3_OFFSET
|
s32i a3, a0, LX_INTR_A3_OFFSET
|
||||||
s32i a4, a0, L5_INTR_A4_OFFSET
|
s32i a4, a0, LX_INTR_A4_OFFSET
|
||||||
rsr a2, EXCSAVE_5
|
rsr a2, EXCSAVE_X
|
||||||
s32i a2, a0, L5_INTR_A0_OFFSET
|
s32i a2, a0, LX_INTR_A0_OFFSET
|
||||||
|
|
||||||
/* disable nested iterrupts */
|
/* disable nested iterrupts */
|
||||||
/* PS.EXCM is changed from 1 to 0 . It allows using usually exception handler instead of the Double exception handler. */
|
/* PS.EXCM is changed from 1 to 0 . It allows using usually exception handler instead of the Double exception handler. */
|
||||||
@ -53,9 +69,14 @@ esp_ipc_isr_handler:
|
|||||||
/*
|
/*
|
||||||
* Reset isr interrupt flags
|
* Reset isr interrupt flags
|
||||||
*/
|
*/
|
||||||
|
#if CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5
|
||||||
|
/* This int is level-triggered and doesn't need clearing.
|
||||||
|
Do nothing here and clear int status by peripheral register later.*/
|
||||||
|
#elif CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4
|
||||||
/* This int is edge-triggered and needs clearing. */
|
/* This int is edge-triggered and needs clearing. */
|
||||||
movi a3, (1 << ETS_IPC_ISR_INUM)
|
movi a3, (1 << ETS_IPC_ISR_INUM)
|
||||||
wsr a3, INTCLEAR
|
wsr a3, INTCLEAR
|
||||||
|
#endif /* CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 */
|
||||||
|
|
||||||
/* get CORE_ID */
|
/* get CORE_ID */
|
||||||
getcoreid a3
|
getcoreid a3
|
||||||
@ -85,16 +106,16 @@ esp_ipc_isr_handler:
|
|||||||
callx0 a0
|
callx0 a0
|
||||||
|
|
||||||
/* Done. Restore registers and return. */
|
/* Done. Restore registers and return. */
|
||||||
movi a0, _l5_intr_stack
|
movi a0, _lx_intr_stack
|
||||||
l32i a2, a0, L5_INTR_A2_OFFSET
|
l32i a2, a0, LX_INTR_A2_OFFSET
|
||||||
l32i a3, a0, L5_INTR_A3_OFFSET
|
l32i a3, a0, LX_INTR_A3_OFFSET
|
||||||
l32i a4, a0, L5_INTR_A4_OFFSET
|
l32i a4, a0, LX_INTR_A4_OFFSET
|
||||||
|
|
||||||
/* set the end flag */
|
/* set the end flag */
|
||||||
movi a0, esp_ipc_isr_end_fl
|
movi a0, esp_ipc_isr_end_fl
|
||||||
s32i a0, a0, 0
|
s32i a0, a0, 0
|
||||||
|
|
||||||
/* restore a0 */
|
/* restore a0 */
|
||||||
rsr a0, EXCSAVE_5
|
rsr a0, EXCSAVE_X
|
||||||
/* restores PS from EPS[5] and jumps to the address in EPC[5] */
|
/* restores PS from EPS[X] and jumps to the address in EPC[X] */
|
||||||
rfi 5
|
rfi RFI_X
|
||||||
|
@ -464,12 +464,13 @@ menu "ESP System Settings"
|
|||||||
|
|
||||||
choice ESP_SYSTEM_CHECK_INT_LEVEL
|
choice ESP_SYSTEM_CHECK_INT_LEVEL
|
||||||
prompt "Interrupt level to use for Interrupt Watchdog and other system checks"
|
prompt "Interrupt level to use for Interrupt Watchdog and other system checks"
|
||||||
default ESP_SYSTEM_CHECK_INT_LEVEL_5
|
default ESP_SYSTEM_CHECK_INT_LEVEL_4
|
||||||
help
|
help
|
||||||
Interrupt level to use for Interrupt Watchdog and other system checks.
|
Interrupt level to use for Interrupt Watchdog and other system checks.
|
||||||
|
|
||||||
config ESP_SYSTEM_CHECK_INT_LEVEL_5
|
config ESP_SYSTEM_CHECK_INT_LEVEL_5
|
||||||
bool "Level 5 interrupt"
|
bool "Level 5 interrupt"
|
||||||
|
depends on IDF_TARGET_ESP32
|
||||||
help
|
help
|
||||||
Using level 5 interrupt for Interrupt Watchdog and other system checks.
|
Using level 5 interrupt for Interrupt Watchdog and other system checks.
|
||||||
|
|
||||||
|
@ -76,6 +76,7 @@ Interrupt , a high-priority interrupt, is used for several things:
|
|||||||
#define TIMG1_WDT_STG0_HOLD_OFFSET TIMG1_REG_OFFSET(TIMG_WDTCONFIG2_REG(1))
|
#define TIMG1_WDT_STG0_HOLD_OFFSET TIMG1_REG_OFFSET(TIMG_WDTCONFIG2_REG(1))
|
||||||
#define TIMG1_WDT_STG1_HOLD_OFFSET TIMG1_REG_OFFSET(TIMG_WDTCONFIG3_REG(1))
|
#define TIMG1_WDT_STG1_HOLD_OFFSET TIMG1_REG_OFFSET(TIMG_WDTCONFIG3_REG(1))
|
||||||
#define TIMG1_WDT_FEED_OFFSET TIMG1_REG_OFFSET(TIMG_WDTFEED_REG(1))
|
#define TIMG1_WDT_FEED_OFFSET TIMG1_REG_OFFSET(TIMG_WDTFEED_REG(1))
|
||||||
|
#define UART0_DATA_REG (0x3FF40078)
|
||||||
|
|
||||||
.macro wdt_clr_intr_status dev
|
.macro wdt_clr_intr_status dev
|
||||||
movi a2, \dev
|
movi a2, \dev
|
||||||
@ -120,24 +121,24 @@ Interrupt , a high-priority interrupt, is used for several things:
|
|||||||
.macro get_int_status_tg1wdt reg
|
.macro get_int_status_tg1wdt reg
|
||||||
rsr \reg, INTERRUPT
|
rsr \reg, INTERRUPT
|
||||||
extui \reg, \reg, ETS_T1_WDT_CACHEERR_INUM, 1
|
extui \reg, \reg, ETS_T1_WDT_CACHEERR_INUM, 1
|
||||||
beqz \reg, 99f // not ETS_T1_WDT_INUM or ETS_CACHEERR_INUM
|
beqz \reg, 99f /* not ETS_T1_WDT_INUM or ETS_CACHEERR_INUM */
|
||||||
|
|
||||||
getcoreid \reg
|
getcoreid \reg
|
||||||
bnez \reg, 98f
|
bnez \reg, 98f
|
||||||
// core 0
|
/* core 0 */
|
||||||
movi \reg, 0x3FF40078
|
movi \reg, UART0_DATA_REG
|
||||||
l32i \reg, \reg, 0 // Workaround for DPORT read error, for silicon revision 0~2 (ECO V0 ~ ECO V2).
|
l32i \reg, \reg, 0 /* Workaround for DPORT read error, for silicon revision 0~2 (ECO V0 ~ ECO V2). */
|
||||||
movi \reg, DPORT_PRO_INTR_STATUS_0_REG
|
movi \reg, DPORT_PRO_INTR_STATUS_0_REG
|
||||||
l32i \reg, \reg, 0
|
l32i \reg, \reg, 0
|
||||||
extui \reg, \reg, 20, 1 // ETS_TG1_WDT_LEVEL_INTR_SOURCE
|
extui \reg, \reg, ETS_TG1_WDT_LEVEL_INTR_SOURCE, 1
|
||||||
j 99f
|
j 99f
|
||||||
|
|
||||||
98: // core 1
|
98: /* core 1 */
|
||||||
movi \reg, 0x3FF40078
|
movi \reg, UART0_DATA_REG
|
||||||
l32i \reg, \reg, 0 // Workaround for DPORT read error, for silicon revision 0~2 (ECO V0 ~ ECO V2).
|
l32i \reg, \reg, 0 /* Workaround for DPORT read error, for silicon revision 0~2 (ECO V0 ~ ECO V2). */
|
||||||
movi \reg, DPORT_APP_INTR_STATUS_0_REG
|
movi \reg, DPORT_APP_INTR_STATUS_0_REG
|
||||||
l32i \reg, \reg, 0
|
l32i \reg, \reg, 0
|
||||||
extui \reg, \reg, 20, 1 // ETS_TG1_WDT_LEVEL_INTR_SOURCE
|
extui \reg, \reg, ETS_TG1_WDT_LEVEL_INTR_SOURCE, 1
|
||||||
99:
|
99:
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
@ -171,12 +172,14 @@ xt_highintx:
|
|||||||
/* See if we're here for the IPC_ISR interrupt */
|
/* See if we're here for the IPC_ISR interrupt */
|
||||||
rsr a0, INTERRUPT
|
rsr a0, INTERRUPT
|
||||||
extui a0, a0, ETS_IPC_ISR_INUM, 1
|
extui a0, a0, ETS_IPC_ISR_INUM, 1
|
||||||
bnez a0, esp_ipc_isr_handler
|
beqz a0, 1f
|
||||||
#endif // not CONFIG_FREERTOS_UNICORE
|
j esp_ipc_isr_handler
|
||||||
|
1:
|
||||||
|
#endif /* not CONFIG_FREERTOS_UNICORE */
|
||||||
|
|
||||||
|
|
||||||
// ETS_T1_WDT_INUM
|
|
||||||
#if CONFIG_ESP32_ECO3_CACHE_LOCK_FIX && CONFIG_ESP_INT_WDT
|
#if CONFIG_ESP32_ECO3_CACHE_LOCK_FIX && CONFIG_ESP_INT_WDT
|
||||||
|
|
||||||
|
#if CONFIG_BTDM_CTRL_HLI
|
||||||
/* Timer 2 interrupt */
|
/* Timer 2 interrupt */
|
||||||
rsr a0, INTENABLE
|
rsr a0, INTENABLE
|
||||||
extui a0, a0, 16, 1
|
extui a0, a0, 16, 1
|
||||||
@ -185,6 +188,9 @@ xt_highintx:
|
|||||||
extui a0, a0, 16, 1
|
extui a0, a0, 16, 1
|
||||||
bnez a0, .handle_multicore_debug_int
|
bnez a0, .handle_multicore_debug_int
|
||||||
1:
|
1:
|
||||||
|
#endif /* CONFIG_BTDM_CTRL_HLI */
|
||||||
|
|
||||||
|
/* ETS_T1_WDT_INUM */
|
||||||
#if CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5
|
#if CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5
|
||||||
get_int_status_tg1wdt a0
|
get_int_status_tg1wdt a0
|
||||||
#elif CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4
|
#elif CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4
|
||||||
@ -204,7 +210,7 @@ xt_highintx:
|
|||||||
rsr a5, depc /* restore a5 */
|
rsr a5, depc /* restore a5 */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
1: //ETS_CACHEERR_INUM or ETS_T1_WDT_INUM
|
1: /* ETS_CACHEERR_INUM or ETS_T1_WDT_INUM */
|
||||||
/* Allocate exception frame and save minimal context. */
|
/* Allocate exception frame and save minimal context. */
|
||||||
mov a0, sp
|
mov a0, sp
|
||||||
addi sp, sp, -XT_STK_FRMSZ
|
addi sp, sp, -XT_STK_FRMSZ
|
||||||
@ -276,7 +282,7 @@ xt_highintx:
|
|||||||
movi a0, PS_INTLEVEL(5) | PS_UM | PS_WOE
|
movi a0, PS_INTLEVEL(5) | PS_UM | PS_WOE
|
||||||
wsr a0, PS
|
wsr a0, PS
|
||||||
|
|
||||||
//Call panic handler
|
/* Call panic handler */
|
||||||
mov a6,sp
|
mov a6,sp
|
||||||
call4 panicHandler
|
call4 panicHandler
|
||||||
|
|
||||||
@ -294,6 +300,7 @@ xt_highintx:
|
|||||||
|
|
||||||
|
|
||||||
#if CONFIG_ESP32_ECO3_CACHE_LOCK_FIX && CONFIG_ESP_INT_WDT
|
#if CONFIG_ESP32_ECO3_CACHE_LOCK_FIX && CONFIG_ESP_INT_WDT
|
||||||
|
#if CONFIG_BTDM_CTRL_HLI
|
||||||
#define APB_ITCTRL (0x3f00)
|
#define APB_ITCTRL (0x3f00)
|
||||||
#define APB_DCRSET (0x200c)
|
#define APB_DCRSET (0x200c)
|
||||||
|
|
||||||
@ -326,7 +333,7 @@ xt_highintx:
|
|||||||
nop
|
nop
|
||||||
.endr
|
.endr
|
||||||
|
|
||||||
/* Enable Normally Mode */
|
/* Enable Normal Mode */
|
||||||
movi a2, ERI_ADDR(APB_ITCTRL)
|
movi a2, ERI_ADDR(APB_ITCTRL)
|
||||||
rer a0, a2
|
rer a0, a2
|
||||||
movi a2, ~0x1
|
movi a2, ~0x1
|
||||||
@ -336,8 +343,9 @@ xt_highintx:
|
|||||||
|
|
||||||
rsr a2, depc
|
rsr a2, depc
|
||||||
|
|
||||||
rsr a0, EXCSAVE_X /* restore a0 */
|
rsr a0, EXCSAVE_5 /* restore a0 */
|
||||||
rfi 5
|
rfi 5
|
||||||
|
#endif /* CONFIG_BTDM_CTRL_HLI */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
@ -63,10 +63,21 @@ _xt_debugexception:
|
|||||||
.align 4
|
.align 4
|
||||||
_xt_debug_di_exc:
|
_xt_debug_di_exc:
|
||||||
|
|
||||||
/* After testing,
|
/*
|
||||||
In 80 MHz, it will task 5us to loop 45 times;
|
The delay time can be calculated by the following formula:
|
||||||
In 160 MHz, it will task 5us to loop 90 times;
|
T = ceil(0.25 + max(t1, t2)) us
|
||||||
In 240 MHz, it will task 5us to loop 135 times;*/
|
|
||||||
|
t1 = 80 / f1, t2 = (1 + 14/N) * 20 / f2
|
||||||
|
|
||||||
|
f1: PSRAM access frequency, unit: MHz.
|
||||||
|
f2: Flash access frequency, unit: MHz.
|
||||||
|
|
||||||
|
When flash is slow/fast read, N = 1.
|
||||||
|
When flash is DOUT/DIO read, N = 2.
|
||||||
|
When flash is QOUT/QIO read, N = 4.
|
||||||
|
|
||||||
|
And after testing, when CPU frequency is 240 MHz, it will take 1us to loop 27 times.
|
||||||
|
*/
|
||||||
#if defined(CONFIG_ESPTOOLPY_FLASHMODE_QIO) || defined(CONFIG_ESPTOOLPY_FLASHMODE_QOUT)
|
#if defined(CONFIG_ESPTOOLPY_FLASHMODE_QIO) || defined(CONFIG_ESPTOOLPY_FLASHMODE_QOUT)
|
||||||
|
|
||||||
# if defined(CONFIG_ESPTOOLPY_FLASHFREQ_80M) && defined(CONFIG_SPIRAM_SPEED_80M)
|
# if defined(CONFIG_ESPTOOLPY_FLASHFREQ_80M) && defined(CONFIG_SPIRAM_SPEED_80M)
|
||||||
@ -99,7 +110,7 @@ _xt_debug_di_exc:
|
|||||||
movi a0, 243
|
movi a0, 243
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
1: addi a0, a0, -1
|
1: addi a0, a0, -1 /* delay_us(N) */
|
||||||
.rept 4
|
.rept 4
|
||||||
nop
|
nop
|
||||||
.endr
|
.endr
|
||||||
|
@ -371,7 +371,7 @@
|
|||||||
* 13 1 extern level
|
* 13 1 extern level
|
||||||
* 14 7 nmi Reserved Reserved
|
* 14 7 nmi Reserved Reserved
|
||||||
* 15 3 timer FreeRTOS Tick(L3) FreeRTOS Tick(L3)
|
* 15 3 timer FreeRTOS Tick(L3) FreeRTOS Tick(L3)
|
||||||
* 16 5 timer
|
* 16 5 timer Reserved Reserved
|
||||||
* 17 1 extern level
|
* 17 1 extern level
|
||||||
* 18 1 extern level
|
* 18 1 extern level
|
||||||
* 19 2 extern level
|
* 19 2 extern level
|
||||||
@ -403,15 +403,6 @@
|
|||||||
#define ETS_CACHEERR_INUM ETS_MEMACCESS_ERR_INUM
|
#define ETS_CACHEERR_INUM ETS_MEMACCESS_ERR_INUM
|
||||||
#define ETS_IPC_ISR_INUM 31
|
#define ETS_IPC_ISR_INUM 31
|
||||||
|
|
||||||
//CPU0 Interrupt number used in ROM, should be cancelled in SDK
|
|
||||||
#define ETS_SLC_INUM 1
|
|
||||||
#define ETS_UART0_INUM 5
|
|
||||||
#define ETS_UART1_INUM 5
|
|
||||||
//Other interrupt number should be managed by the user
|
|
||||||
|
|
||||||
//Invalid interrupt for number interrupt matrix
|
|
||||||
#define ETS_INVALID_INUM 6
|
|
||||||
|
|
||||||
#elif CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4
|
#elif CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4
|
||||||
|
|
||||||
//interrupt cpu using table, Please see the core-isa.h
|
//interrupt cpu using table, Please see the core-isa.h
|
||||||
@ -464,6 +455,8 @@
|
|||||||
#define ETS_CACHEERR_INUM ETS_MEMACCESS_ERR_INUM
|
#define ETS_CACHEERR_INUM ETS_MEMACCESS_ERR_INUM
|
||||||
#define ETS_IPC_ISR_INUM 28
|
#define ETS_IPC_ISR_INUM 28
|
||||||
|
|
||||||
|
#endif /* CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 */
|
||||||
|
|
||||||
//CPU0 Interrupt number used in ROM, should be cancelled in SDK
|
//CPU0 Interrupt number used in ROM, should be cancelled in SDK
|
||||||
#define ETS_SLC_INUM 1
|
#define ETS_SLC_INUM 1
|
||||||
#define ETS_UART0_INUM 5
|
#define ETS_UART0_INUM 5
|
||||||
@ -472,4 +465,3 @@
|
|||||||
|
|
||||||
//Invalid interrupt for number interrupt matrix
|
//Invalid interrupt for number interrupt matrix
|
||||||
#define ETS_INVALID_INUM 6
|
#define ETS_INVALID_INUM 6
|
||||||
#endif /* CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 */
|
|
@ -9,16 +9,39 @@ The Xtensa architecture has support for 32 interrupts, divided over 8 levels, pl
|
|||||||
Interrupt Levels
|
Interrupt Levels
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
===== ================= ====================================================
|
.. only:: esp32
|
||||||
Level Symbol Remark
|
|
||||||
===== ================= ====================================================
|
===== ================= ====================================================
|
||||||
1 N/A Exception and level 0 interrupts. Handled by ESP-IDF
|
Level Symbol Remark
|
||||||
2-3 N/A Medium level interrupts. Handled by ESP-IDF
|
===== ================= ====================================================
|
||||||
4 xt_highint4 Normally used by ESP-IDF debug logic
|
1 N/A Exception and level 0 interrupts. Handled by ESP-IDF
|
||||||
5 xt_highint5 Free to use
|
2-3 N/A Medium level interrupts. Handled by ESP-IDF
|
||||||
NMI xt_nmi Free to use
|
4 xt_highint4 Free to use :ref:`(See 1) <hlinterrupts-pin-notes>`
|
||||||
dbg xt_debugexception Debug exception. Called on e.g. a BREAK instruction.
|
5 xt_highint5 Normally used by ESP-IDF debug logic :ref:`(See 1) <hlinterrupts-pin-notes>`
|
||||||
===== ================= ====================================================
|
NMI xt_nmi Free to use
|
||||||
|
dbg xt_debugexception Debug exception. Called on e.g. a BREAK instruction. :ref:`(See 2) <hlinterrupts-pin-notes>`
|
||||||
|
===== ================= ====================================================
|
||||||
|
|
||||||
|
|
||||||
|
.. _hlinterrupts-pin-notes:
|
||||||
|
|
||||||
|
The following notes give more information about the items in the tables above.
|
||||||
|
|
||||||
|
1. ESP-IDF debug logic can be configured to run on `xt_highint4` or `xt_highint5` in :ref:`CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL`. Bluetooth's interrupt can be configured to run on level 4 by enabling :ref:`CONFIG_BTDM_CTRL_HLI`. If :ref:`CONFIG_BTDM_CTRL_HLI` is enabled, ESP-IDF debug logic must be running on level 5 interrupt.
|
||||||
|
2. If :ref:`CONFIG_BTDM_CTRL_HLI` is enabled, `xt_debugexception` is used to fix `live lock issue <https://www.espressif.com/sites/default/files/documentation/eco_and_workarounds_for_bugs_in_esp32_en.pdf>`_ in ESP32 ECO3.
|
||||||
|
|
||||||
|
.. only:: not esp32
|
||||||
|
|
||||||
|
===== ================= ====================================================
|
||||||
|
Level Symbol Remark
|
||||||
|
===== ================= ====================================================
|
||||||
|
1 N/A Exception and level 0 interrupts. Handled by ESP-IDF
|
||||||
|
2-3 N/A Medium level interrupts. Handled by ESP-IDF
|
||||||
|
4 xt_highint4 Normally used by ESP-IDF debug logic
|
||||||
|
5 xt_highint5 Free to use
|
||||||
|
NMI xt_nmi Free to use
|
||||||
|
dbg xt_debugexception Debug exception. Called on e.g. a BREAK instruction.
|
||||||
|
===== ================= ====================================================
|
||||||
|
|
||||||
Using these symbols is done by creating an assembly file (suffix .S) and defining the named symbols, like this::
|
Using these symbols is done by creating an assembly file (suffix .S) and defining the named symbols, like this::
|
||||||
|
|
||||||
@ -41,6 +64,10 @@ Notes
|
|||||||
(The panic handler interrupt does call normal C code, but this is OK because there is no intention of returning to the normal code
|
(The panic handler interrupt does call normal C code, but this is OK because there is no intention of returning to the normal code
|
||||||
flow afterwards.)
|
flow afterwards.)
|
||||||
|
|
||||||
|
.. only:: esp32
|
||||||
|
|
||||||
|
And if :ref:`CONFIG_BTDM_CTRL_HLI` is enabled, it does call normal C code in high-level interrupt, but this is OK becase we add some protection for it.
|
||||||
|
|
||||||
- Make sure your assembly code gets linked in. If the interrupt handler symbol is the only symbol the rest of the code uses from this
|
- Make sure your assembly code gets linked in. If the interrupt handler symbol is the only symbol the rest of the code uses from this
|
||||||
file, the linker will take the default ISR instead and not link the assembly file into the final project. To get around this, in the
|
file, the linker will take the default ISR instead and not link the assembly file into the final project. To get around this, in the
|
||||||
assembly file, define a symbol, like this::
|
assembly file, define a symbol, like this::
|
||||||
|
Loading…
x
Reference in New Issue
Block a user