Arduino 如何禁用';中断看门狗&x27;在ESP32中还是增加ISR时间限制?
我正在使用ESP32 DEVKIT和Adafruit VS1053编解码器+MicroSD Breakout-MP3/WAV/MIDI/OGG Play+Record-v4来录制并播放声音。我使用ArduinoIDE进行编码 我现在面临一个问题,模块使用硬件中断进行播放。但当我试着播放音轨时,ESP32一次又一次地重置。调试日志显示:Arduino 如何禁用';中断看门狗&x27;在ESP32中还是增加ISR时间限制?,arduino,arduino-ide,adafruit,esp32,Arduino,Arduino Ide,Adafruit,Esp32,我正在使用ESP32 DEVKIT和Adafruit VS1053编解码器+MicroSD Breakout-MP3/WAV/MIDI/OGG Play+Record-v4来录制并播放声音。我使用ArduinoIDE进行编码 我现在面临一个问题,模块使用硬件中断进行播放。但当我试着播放音轨时,ESP32一次又一次地重置。调试日志显示: Guru Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU1) Core 1 re
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
行Guru冥想错误:Core 1 panic'ed(CPU 1上的中断wdt超时)
指示其中断wdt
我找到了禁用中断WDT的方法,但没有任何帮助。~Documents\Arduino\hardware\espressif\esp32\tools\sdk\include\esp32
中的文件esp\u int\u wdt.h
提供了两个函数,用于为两个或一个CPU启用中断wdt。没有禁用它的功能
如何禁用ESP32中断WDT?看门狗定时器对系统稳定性起着重要作用 与其禁用看门狗计时器,不如确保不要在
循环()中停留太长时间。您应该始终对代码进行结构化,以便在loop()
中尽可能少地工作,然后让它返回。当它返回支持您的ESP32应用程序的软件时,它将执行重要的内务管理任务,并重置看门狗计时器
例如,你不应该写:
void loop() {
while(1) {
do_some_work();
}
}
相反,你应该写:
void loop() {
do_some_work();
}
如果您必须在loop()
中完成比看门狗定时器允许的更多的工作,请确保偶尔从代码中调用yield()
或delay()
;这将允许系统赶上它需要做的事情yield()
将在完成任何必要的内务工作后立即返回<代码>延迟(毫秒)
将在完成任何需要的工作后返回毫秒
与其写,不如写
void loop() {
unsigned long start_time = millis();
while(millis() - start_time < 10*1000) { }
do_some_work();
}
或者更好,如果您的循环可以满足多种需求:
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();
}
}
我不知道如何使用arduino禁用看门狗,但我可以告诉您如何使用esp idf
及其make menuconfig
禁用它
打开菜单配置:makemenuconfig
输入组件配置
输入ESP32特定的
从中断看门狗中删除星号
根据void,esp\u int\u wdt\u init()
用于初始化中断看门狗。在menuconfig
中启用IWDT
时调用此函数。因此,您可以尝试查找此函数的调用并将其删除;)
但是:
我建议你不要禁用看门狗。相反,尝试使用FreeRTOS任务在中断时执行大量代码
我不知道如何在arduino平台上实现,但我可以告诉你我是如何使用esp idf实现的
首先,创建带有签名的中断处理程序void f(void*)
其次,在中断处理程序中,您必须使用xTaskCreate
或xtaskcreatedpinnedtocore
创建新任务。例如,xTaskCreate(MyHandler,“int_handler”,256,NULL,4,NULL)代码>(签出)
仅此而已,现在您可以在中断时运行大型代码。除此之外,我建议您不要创建太多的任务。系统可能会挂起
另外,如果您需要每秒处理成吨的interurpt请求,请尝试使用
或者在menuconfig中关闭它。不过,我同意其他海报,您不应该关闭它,相反,您还可以使用以下功能为其提供信息:
rtc_wdt_feed();
我通常创建一个优先级最低的FreeRTOS任务,该任务只循环并调用feed方法,延迟小于超时,这样就有足够的时间运行优先级较高的“业务逻辑”。例如:
在菜单配置或代码中将超时设置为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);
然后在任务中执行以下操作:
while(true) {
rtc_wdt_feed();
vTaskDelay(pdMS_TO_TICKS(100));
}
while(true) {
rtc_wdt_feed();
vTaskDelay(pdMS_TO_TICKS(100));
}
这将为FreeRTOS WDT和RTC WDT提供数据,并在系统陷入循环或未在您的时间要求内处理时重置系统。您需要处理超时以及为系统提供计时器的频率。请记住,Wifi、PHY和BT不是确定性的,因此如果您依赖来自“网络”的DAQ,则在计时方面会有很多不可预测性。我也遇到了类似的问题。虽然我没有解决方案,但我可以在Arduino+ESP32中确认,上面的答案似乎都不起作用或解决了这个问题。
特别是:
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);
tc_wdt_set_time(RTC_WDT_STAGE0, 250);`
然后在任务中执行以下操作:
while(true) {
rtc_wdt_feed();
vTaskDelay(pdMS_TO_TICKS(100));
}
while(true) {
rtc_wdt_feed();
vTaskDelay(pdMS_TO_TICKS(100));
}
虽然它编译得很好,但以一种非常可靠的方式,它似乎什么也没做
事实上,我可以触发WDT超时,这是完全可复制的,所以我认为WDT超时根本没有增加,或者WDT被馈送
我对loop()没有任何怀疑代码>(arduino特定任务)可能希望更改、禁用或以任何方式篡改看门狗。另外,yield()代码>和延迟(nnn)代码>似乎什么都不做,不管我把它们放在哪里,不管我放了多少这样的东西。恕我直言,你永远不应该告诉某人他们不应该做一些不常用的实践方法,甚至是在特定庄园执行任务的好主意。在庄园里执行一项任务有很多理由,而“产业界”认为这是个坏主意。FWIW:我讲的是近40年的编程经验。
while(true) {
rtc_wdt_feed();
vTaskDelay(pdMS_TO_TICKS(100));
}