[英]How to disable 'interrupt watchdog' in ESP32 OR increase ISR time limit?
I am using ESP32 DEVKIT link and Adafruit VS1053 Codec + MicroSD Breakout - MP3/WAV/MIDI/OGG Play + Record - v4 link to record and then play the sound.我正在使用ESP32 DEVKIT 链接和Adafruit VS1053 Codec + MicroSD Breakout - MP3/WAV/MIDI/OGG Play + Record - v4链接来录制然后播放声音。 I am using Arduino IDE for coding.我正在使用 Arduino IDE 进行编码。
I am facing an issue right now that the module uses hardware interrupt for playing purposes.我现在面临一个问题,该模块使用硬件中断进行播放。 But ESP32 is resetting again and again when I try to play a sound track.但是当我尝试播放音轨时,ESP32 会一次又一次地重置。 The debug log says:调试日志说:
Guru Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU1)
Core 1 register dump:
PC : 0x400d1280 PS : 0x00060834 A0 : 0x800d128f A1 : 0x3ffc0bb0
A2 : 0x3ffc241c A3 : 0x3ffb1f20 A4 : 0x800d1779 A5 : 0x3ffb1f00
A6 : 0x3ffc241c A7 : 0x3f400f9c A8 : 0x800d1280 A9 : 0x3ffc0b90
A10 : 0x0000002b A11 : 0x3f401067 A12 : 0x800d1691 A13 : 0x3ffb1ed0
A14 : 0x3ffc241c A15 : 0x00000000 SAR : 0x0000001f EXCCAUSE: 0x00000006
EXCVADDR: 0x00000000 LBEG : 0x400014fd LEND : 0x4000150d LCOUNT : 0xffffffff
Core 1 was running in ISR context:
EPC1 : 0x400d4123 EPC2 : 0x00000000 EPC3 : 0x00000000 EPC4 : 0x400d1280
Backtrace: 0x400d1280:0x3ffc0bb0 0x400d128c:0x3ffc0bd0 0x40080e21:0x3ffc0bf0 0x400817d5:0x3ffc0c10 0x400d3ae5:0x00000000
Core 0 register dump:
PC : 0x400ee86e PS : 0x00060934 A0 : 0x8008656c A1 : 0x3ffc7910
A2 : 0x00000008 A3 : 0x00000000 A4 : 0x00000001 A5 : 0x3ffc7f4c
A6 : 0x00000000 A7 : 0x00000001 A8 : 0x3ffc3404 A9 : 0x3ffc33e8
A10 : 0x00000000 A11 : 0x00000001 A12 : 0x00000000 A13 : 0x00000001
A14 : 0x00060b20 A15 : 0x00000000 SAR : 0x00000000 EXCCAUSE: 0x00000006
EXCVADDR: 0x00000000 LBEG : 0x00000000 LEND : 0x00000000 LCOUNT : 0x00000000
Backtrace: 0x400ee86e:0x3ffc7910 0x40086569:0x3ffc7930
Rebooting...
ets Jun 8 2016 00:22:57
rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:952
load:0x40078000,len:6084
load:0x40080000,len:7936
entry 0x40080310
Adafruit VS1053 Simple Test
VS1053 found
The line Guru Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU1)
indicates that its interrupt wdt.行Guru Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU1)
表示它的中断 wdt。
I searched ways to disable interrupt WDT but no help.我搜索了禁用中断 WDT 的方法,但没有帮助。 The file esp_int_wdt.h
in ~Documents\\Arduino\\hardware\\espressif\\esp32\\tools\\sdk\\include\\esp32
provides two functions for enabling interrupt WDT for both or one CPU.文件esp_int_wdt.h
在~Documents\\Arduino\\hardware\\espressif\\esp32\\tools\\sdk\\include\\esp32
用于使中断WDT两个或一个CPU提供两个功能。 There is no function to disable it.没有禁用它的功能。
How to disable ESP32 interrupt WDT?如何禁用 ESP32 中断 WDT?
#include "soc/rtc_wdt.h"
rtc_wdt_protect_off();
rtc_wdt_disable();
Or turn it off in menuconfig.或者在 menuconfig 中关闭它。 I agree with other posters though, you should not turn it off, instead, you can also feed it with the following function:我同意其他海报,但你不应该关闭它,相反,你也可以使用以下功能提供它:
rtc_wdt_feed();
I usually create a lowest priority FreeRTOS task that just loops and calls the feed method with a delay less then the timeout, giving enough time for higher priority "business logic" to run.我通常会创建一个优先级最低的 FreeRTOS 任务,该任务只是循环并以小于超时的延迟调用 feed 方法,从而为更高优先级的“业务逻辑”提供足够的时间来运行。 Example:例子:
Set timeout to 250 ms in menuconfig or in code:在 menuconfig 或代码中将超时设置为 250 毫秒:
rtc_wdt_set_length_of_reset_signal(RTC_WDT_SYS_RESET_SIG, RTC_WDT_LENGTH_3_2us);
rtc_wdt_set_stage(RTC_WDT_STAGE0, RTC_WDT_STAGE_ACTION_RESET_SYSTEM);
rtc_wdt_set_time(RTC_WDT_STAGE0, 250);
Then do this in your task:然后在您的任务中执行此操作:
while(true) {
rtc_wdt_feed();
vTaskDelay(pdMS_TO_TICKS(100));
}
This will feed both the FreeRTOS WDT and the RTC WDT and reset your system if it gets stuck in a loop or doesn't processes within your time requirements.这将同时提供 FreeRTOS WDT 和 RTC WDT,并在系统陷入循环或未在您的时间要求内处理时重置您的系统。 You'll need to play with the timeout and how often you feed the timer to get it right for your system.Keep in mind the Wifi, PHY, and BT are not deterministic so you'll have a lot of unpredictability in timing if you are dependent on DAQ from from "the net".您需要调整超时时间以及为计时器提供的频率以使其适合您的系统。请记住,Wifi、PHY 和 BT 不是确定性的,因此如果您在时间上有很多不可预测性依赖于来自“网络”的 DAQ。
The watchdog timer plays an important role in system stability.看门狗定时器对系统稳定性起着重要作用。
Rather than disabling the watchdog timer, try to make sure that you don't stay in loop()
for too long.与其禁用看门狗定时器,不如尝试确保您不会在loop()
停留太久。 You should always structure your code so that you do the least work you can in loop()
and let it return.您应该始终构建您的代码,以便您在loop()
做最少的工作并让它返回。 When it returns the software that supports your ESP32 application gets to do important housekeeping tasks, and reset the watchdog timer.当它返回时,支持您的 ESP32 应用程序的软件可以执行重要的内务管理任务,并重置看门狗定时器。
For instance, you should never write:例如,你永远不应该写:
void loop() {
while(1) {
do_some_work();
}
}
and instead you should write:而你应该写:
void loop() {
do_some_work();
}
If you absolutely have to do more work in loop()
than the watchdog timer allows for, make sure you call yield()
or delay()
occasionally from your code;如果你绝对需要在loop()
比看门狗定时器允许的更多的工作,确保你偶尔从你的代码中调用yield()
或delay()
; this will allow the system to catch up on things it needs to do.这将使系统能够赶上它需要做的事情。 yield()
will return immediately after doing any needed housekeeping work; yield()
将在完成任何需要的内务工作后立即返回; delay(milliseconds)
will return milliseconds
later after doing any needed work. delay(milliseconds)
将在完成任何需要的工作后返回milliseconds
。
So rather than write所以而不是写
void loop() {
unsigned long start_time = millis();
while(millis() - start_time < 10*1000) { }
do_some_work();
}
which would cause the watchdog timer to go off, you'd want to write这会导致看门狗定时器关闭,你想写
void loop() {
delay(10*1000);
do_some_work();
start_time = millis();
}
or even better, if your loop may be servicing multiple needs:甚至更好,如果您的循环可能满足多种需求:
void loop() {
static unsigned long start_time1 = millis();
static unsigned long start_time2 = millis();
if(millis() - start_time >= 10*1000) {
do_some_work1();
start_time1 = millis();
}
if(millis() - start_time >= 20*1000) {
do_some_work2();
start_time2 = millis();
}
}
I don't know how to disable watchdog using arduino, but I can tell you how to disable it using esp-idf
and its make menuconfig
我不知道如何使用 arduino 禁用看门狗,但我可以告诉您如何使用esp-idf
及其make menuconfig
禁用它
make menuconfig
打开 menuconfig: make menuconfig
component config
输入component config
ESP32-specific
进入ESP32-specific
interrupt watchdog
从interrupt watchdog
删除星号PS According to esp-idf docs void esp_int_wdt_init()
is used to init interrupt watchdog. PS 根据esp-idf docs void esp_int_wdt_init()
用于初始化中断看门狗。 This function is called when IWDT
enabled in menuconfig
.在menuconfig
启用IWDT
时调用此函数。 So you can try to find call of this function and remove it ;)所以你可以尝试找到这个函数的调用并删除它;)
BUT: I advise you to not disable watchdog.但是:我建议您不要禁用看门狗。 Instead of this, try to use FreeRTOS tasks to execute large amount of code on interrupt.相反,尝试使用 FreeRTOS 任务在中断时执行大量代码。
Im not sure how to do it exactly in arduino platform, but I can tell how I did it using esp-idf我不知道如何在 arduino 平台上完全做到这一点,但我可以告诉我我是如何使用 esp-idf 做到的
First, create interrupt handler with signature void f(void*)
首先,创建签名为void f(void*)
中断处理程序
void MyHandler(void* pData){
/* Your code here */
vTaskDelete(NULL); // delete current taks, must have
}
Second, in interrupt handler you have to create new task, using xTaskCreate
or xTaskCreatePinnedToCore
.其次,在中断处理程序中,您必须使用xTaskCreate
或xTaskCreatePinnedToCore
创建新任务。 For example, xTaskCreate(MyHandler, "int_handler", 256, NULL, 4, NULL);
例如, xTaskCreate(MyHandler, "int_handler", 256, NULL, 4, NULL);
(Check out api reference ) (查看api 参考)
That's all, now you can run big code on your interrupt.就是这样,现在您可以在中断上运行大代码。 In addition to this, I advise you to not create too many tasks.除此之外,我建议您不要创建太多任务。 System may hang.系统可能挂起。
PS If you need to handle tonns of interurpt requests per second, try to use FreeRTOS queues PS 如果您需要每秒处理大量的中断请求,请尝试使用FreeRTOS 队列
I am using ESP32 DEVKIT link and Adafruit VS1053 Codec + MicroSD Breakout - MP3/WAV/MIDI/OGG Play + Record - v4 link to record and then play the sound.我正在使用ESP32 DEVKIT 链接和Adafruit VS1053编解码器+ MicroSD Breakout-MP3 / WAV / MIDI / OGG播放+录制-v4链接来录制然后播放声音。 I am using Arduino IDE for coding.我正在使用Arduino IDE进行编码。
I am facing an issue right now that the module uses hardware interrupt for playing purposes.我现在面临一个问题,该模块出于播放目的使用硬件中断。 But ESP32 is resetting again and again when I try to play a sound track.但是当我尝试播放音轨时,ESP32会一次又一次地重置。 The debug log says:调试日志中显示:
Guru Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU1)
Core 1 register dump:
PC : 0x400d1280 PS : 0x00060834 A0 : 0x800d128f A1 : 0x3ffc0bb0
A2 : 0x3ffc241c A3 : 0x3ffb1f20 A4 : 0x800d1779 A5 : 0x3ffb1f00
A6 : 0x3ffc241c A7 : 0x3f400f9c A8 : 0x800d1280 A9 : 0x3ffc0b90
A10 : 0x0000002b A11 : 0x3f401067 A12 : 0x800d1691 A13 : 0x3ffb1ed0
A14 : 0x3ffc241c A15 : 0x00000000 SAR : 0x0000001f EXCCAUSE: 0x00000006
EXCVADDR: 0x00000000 LBEG : 0x400014fd LEND : 0x4000150d LCOUNT : 0xffffffff
Core 1 was running in ISR context:
EPC1 : 0x400d4123 EPC2 : 0x00000000 EPC3 : 0x00000000 EPC4 : 0x400d1280
Backtrace: 0x400d1280:0x3ffc0bb0 0x400d128c:0x3ffc0bd0 0x40080e21:0x3ffc0bf0 0x400817d5:0x3ffc0c10 0x400d3ae5:0x00000000
Core 0 register dump:
PC : 0x400ee86e PS : 0x00060934 A0 : 0x8008656c A1 : 0x3ffc7910
A2 : 0x00000008 A3 : 0x00000000 A4 : 0x00000001 A5 : 0x3ffc7f4c
A6 : 0x00000000 A7 : 0x00000001 A8 : 0x3ffc3404 A9 : 0x3ffc33e8
A10 : 0x00000000 A11 : 0x00000001 A12 : 0x00000000 A13 : 0x00000001
A14 : 0x00060b20 A15 : 0x00000000 SAR : 0x00000000 EXCCAUSE: 0x00000006
EXCVADDR: 0x00000000 LBEG : 0x00000000 LEND : 0x00000000 LCOUNT : 0x00000000
Backtrace: 0x400ee86e:0x3ffc7910 0x40086569:0x3ffc7930
Rebooting...
ets Jun 8 2016 00:22:57
rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:952
load:0x40078000,len:6084
load:0x40080000,len:7936
entry 0x40080310
Adafruit VS1053 Simple Test
VS1053 found
The line Guru Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU1)
indicates that its interrupt wdt.行Guru Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU1)
表明它的中断wdt。
I searched ways to disable interrupt WDT but no help.我搜索了禁用中断WDT的方法,但没有帮助。 The file esp_int_wdt.h
in ~Documents\\Arduino\\hardware\\espressif\\esp32\\tools\\sdk\\include\\esp32
provides two functions for enabling interrupt WDT for both or one CPU. esp_int_wdt.h
~Documents\\Arduino\\hardware\\espressif\\esp32\\tools\\sdk\\include\\esp32
提供了两个功能,用于为两个或一个CPU启用中断WDT。 There is no function to disable it.没有禁用它的功能。
How to disable ESP32 interrupt WDT?如何禁用ESP32中断WDT?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.