4

我正在使用ESP32 DEVKIT 链接Adafruit VS1053 Codec + MicroSD Breakout - MP3/WAV/MIDI/OGG Play + Record - v4 链接来录制然后播放声音。我正在使用 Arduino IDE 进行编码。

我现在面临一个问题,模块使用硬件中断进行播放。但是当我尝试播放音轨时,ESP32 会一次又一次地重置。调试日志说:

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 Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU1)表示其中断 wdt。

我搜索了禁用中断 WDT 的方法,但没有帮助。中的文件esp_int_wdt.h提供 ~Documents\Arduino\hardware\espressif\esp32\tools\sdk\include\esp32了两个函数来启用两个或一个 CPU 的中断 WDT。没有禁用它的功能。

如何禁用 ESP32 中断 WDT?

4

3 回答 3

4
#include "soc/rtc_wdt.h"

rtc_wdt_protect_off();
rtc_wdt_disable();

或者在 menuconfig 中将其关闭。不过我同意其他海报,你不应该把它关掉,相反,你也可以用以下功能喂它:

rtc_wdt_feed();

我通常会创建一个优先级最低的 FreeRTOS 任务,它只是循环并以小于超时的延迟调用 feed 方法,从而为更高优先级的“业务逻辑”提供足够的时间来运行。例子:

在 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);

然后在您的任务中执行此操作:

while(true) {
    rtc_wdt_feed();
    vTaskDelay(pdMS_TO_TICKS(100));
}

这将为 FreeRTOS WDT 和 RTC WDT 提供数据,并在系统陷入循环或未在您的时间要求内处理时重置您的系统。您需要考虑超时时间以及为计时器提供的频率以使其适合您的系统。请记住 Wifi、PHY 和 BT 不是确定性的,因此如果您在时间上会有很多不可预测性依赖于来自“网络”的数据采集。

于 2019-09-26T11:53:18.390 回答
1

看门狗定时器在系统稳定性方面起着重要作用。

与其禁用看门狗定时器,不如尝试确保您不要停留loop()太久。您应该始终构建您的代码,以便您做最少的工作loop()并让它返回。当它返回支持您的 ESP32 应用程序的软件时,它会执行重要的内务管理任务,并重置看门狗定时器。

例如,你永远不应该写:

void loop() {
  while(1) {
    do_some_work();
  }
}

相反,您应该写:

void loop() {
  do_some_work();
}

如果您绝对需要做loop()比看门狗定时器允许的更多的工作,请确保您调用yield()delay()偶尔从您的代码中调用;这将使系统能够赶上它需要做的事情。yield()完成任何必要的家务工作后将立即返回;delay(milliseconds)milliseconds在完成任何必要的工作后返回。

所以与其写

void loop() {
  unsigned long start_time = millis();

  while(millis() - start_time < 10*1000) { }

  do_some_work();
}

这会导致看门狗定时器关闭,你想写

void loop() {
  delay(10*1000);

  do_some_work();
  start_time = millis();
}

甚至更好,如果您的循环可能满足多种需求:

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();
  }
}
于 2018-08-08T16:09:32.423 回答
1

我不知道如何使用 arduino 禁用看门狗,但我可以告诉你如何使用它来禁用esp-idfmake menuconfig

  1. 打开菜单配置:make menuconfig
  2. 进入component config
  3. 进入ESP32-specific
  4. 去掉星星interrupt watchdog

PS根据esp-idf docs void esp_int_wdt_init()用于初始化中断看门狗。IWDT在启用时调用此函数menuconfig。所以你可以尝试找到这个函数的调用并删除它;)

但是: 我建议您不要禁用看门狗。取而代之的是,尝试使用 FreeRTOS 任务在中断时执行大量代码。

我不确定如何在 arduino 平台上准确地做到这一点,但我可以知道我是如何使用 esp-idf 做到的

首先,创建带有签名的中断处理程序void f(void*)

void MyHandler(void* pData){
    /* Your code here */
    vTaskDelete(NULL); // delete current taks, must have
}

其次,在中断处理程序中,您必须使用xTaskCreateor创建新任务xTaskCreatePinnedToCore。例如,xTaskCreate(MyHandler, "int_handler", 256, NULL, 4, NULL);(查看api 参考

就是这样,现在您可以在中断上运行大代码。除此之外,我建议您不要创建太多任务。系统可能会挂起。

PS 如果您需要每秒处理大量的中断请求,请尝试使用FreeRTOS 队列

于 2018-08-08T18:22:01.023 回答