ESP32在类构造函数中调用WiFi.begin触发RTCWDT_RTC_RESET重启问题
ESP32构造函数调用WiFi.begin触发看门狗复位的原因与解决办法
问题原因
- 全局对象
dm的构造函数会在setup()执行前运行,此时ESP32的系统核心初始化(包括WiFi驱动、RTOS任务调度机制等)还未完成。 WiFi.begin()内部包含大量耗时的硬件初始化和网络协商操作,而此时RTC看门狗已经启动,但系统还没有机会执行喂狗操作,最终触发看门狗复位(串口日志里的rst:0x10 (RTCWDT_RTC_RESET)就是直接证据)。
可行解决方案
方法1:拆分初始化逻辑到独立方法
修改类的设计,把WiFi初始化放到单独的init()方法里,在setup()中调用——此时系统已经完成初始化,调用WiFi.begin是安全的:
#include <WiFi.h> const char* WIFI_SSID = "ssid"; const char* WIFI_PASS = "password"; class dummyClass { public: dummyClass() { // 构造函数只做轻量初始化,不涉及硬件/网络操作 } void init() { WiFi.begin(WIFI_SSID, WIFI_PASS); } }; dummyClass dm; void setup() { Serial.begin(115200); while(!Serial); dm.init(); Serial.println("Setup function"); Serial.println(""); } void loop() { delay(10000); Serial.println("loop finished"); Serial.println(""); }
方法2:延迟对象实例化到setup中
如果不需要全局对象,把对象创建移到setup()里,此时系统初始化完成,构造函数里调用WiFi.begin不会触发看门狗:
#include <WiFi.h> const char* WIFI_SSID = "ssid"; const char* WIFI_PASS = "password"; class dummyClass { public: dummyClass() { WiFi.begin(WIFI_SSID, WIFI_PASS); } }; dummyClass* dm; void setup() { Serial.begin(115200); while(!Serial); dm = new dummyClass(); Serial.println("Setup function"); Serial.println(""); } void loop() { delay(10000); Serial.println("loop finished"); Serial.println(""); }
方法3:临时禁用看门狗(不推荐)
可以临时禁用看门狗避免复位,但会失去系统看门狗的故障保护能力,仅适合调试场景:
#include <WiFi.h> #include <esp_task_wdt.h> const char* WIFI_SSID = "ssid"; const char* WIFI_PASS = "password"; class dummyClass { public: dummyClass() { esp_task_wdt_init(0, false); // 禁用看门狗 WiFi.begin(WIFI_SSID, WIFI_PASS); esp_task_wdt_init(5, true); // 调试完成后建议重新启用 } }; dummyClass dm; void setup() { Serial.begin(115200); while(!Serial); Serial.println("Setup function"); Serial.println(""); } void loop() { delay(10000); Serial.println("loop finished"); Serial.println(""); }
内容的提问来源于stack exchange,提问作者Juan_David
相关产品推荐
相关产品推荐

