故障排除
本指南帮助您诊断和调试 ESPHome 设备问题,特别是崩溃和启动失败。无论您是遇到随机重启、看门狗超时,还是需要分析堆栈跟踪,本指南都会提供捕获和理解崩溃数据的分步说明。
NOTE
本指南假设您已安装 ESPHome 并基本熟悉命令行。有关安装说明,请参阅安装 ESPHome。
从崩溃中获取堆栈跟踪
Section titled “从崩溃中获取堆栈跟踪”自动崩溃报告(无需串口线)
Section titled “自动崩溃报告(无需串口线)”ESPHome 自动捕获崩溃回溯并在 ESP32、ESP8266 和 RP2040 上的软件重置(热重启)后保存。崩溃后,回溯会在启动时以及 esphome logs 通过 API 连接时记录。ESPHome CLI 和 ESPHome Device Builder 会自动使用上次本地编译的调试符号解码地址。
NOTE
在 ESP32 上,此功能需要 ESP-IDF 框架(默认)。在 ESP32 上使用 Arduino 框架时不可用。在 ESP8266 和 RP2040 上,崩溃报告始终启用。
WARNING
要获取解码后的堆栈跟踪,您必须使用 ESPHome CLI(esphome logs)或 ESPHome Device Builder 查看日志。通过其他工具(如通用串口监视器或 Home Assistant 日志查看器)查看日志将显示原始地址而不进行解码。ESPHome CLI 和 ESPHome Device Builder 使用上次本地编译的调试符号将崩溃地址解码为函数名、文件路径和行号。
要查看解码后的崩溃数据:
-
在本地编译并上传以确保您有匹配的调试符号:
Terminal window esphome compile your-device.yamlesphome upload your-device.yaml -
崩溃后使用 ESPHome CLI 或 ESPHome Device Builder 查看日志(无需 USB):
Terminal window esphome logs your-device.yaml上次启动的崩溃数据将自动显示:
[12:31:55][E][esp32.crash:221]: *** CRASH DETECTED ON PREVIOUS BOOT ***[12:31:55][E][esp32.crash:224]: Reason: Fault - StoreProhibited[12:31:55][E][esp32.crash:228]: PC: 0x4011AD40 (fault location)WARNING Decoded 0x4011AD40: setup()::{lambda()#1}::_FUN() at your-device.yaml:89[12:31:55][E][esp32.crash:242]: BT0: 0x4011AD3D (backtrace)WARNING Decoded 0x4011AD3D: setup()::{lambda()#1}::_FUN() at your-device.yaml:89[12:31:55][E][esp32.crash:242]: BT1: 0x4011AD95 (backtrace)WARNING Decoded 0x4011AD95: esphome::StatelessLambdaAction<>::play()[12:31:56][E][esp32.crash:242]: BT2: 0x4011AD77 (backtrace)WARNING Decoded 0x4011AD77: esphome::Action<>::play_complex()[12:31:56][E][esp32.crash:242]: BT3: 0x4011AE6D (backtrace)WARNING Decoded 0x4011AE6D: esphome::ActionList<>::play()[12:31:56][E][esp32.crash:242]: BT4: 0x400D6C7E (backtrace)WARNING Decoded 0x400D6C7E: esphome::button::Button::press()
NOTE
崩溃数据在软件重启后仍然存在,但断电后丢失。如果设备崩溃并在您连接之前断电重启,崩溃数据将丢失。
NOTE
原始(未解码的)崩溃数据也可以出现在 Home Assistant 日志查看器中,如果您在 ESPHome 设备的集成选项中启用了 Subscribe to logs from the device(订阅设备日志)。但是,Home Assistant 不会解码地址——您需要使用基于 Web 的堆栈跟踪解码器手动解码。建议使用 esphome logs,因为它会自动解码堆栈跟踪。
所有平台:串口控制台堆栈跟踪
Section titled “所有平台:串口控制台堆栈跟踪”当您需要完整的寄存器转储,或无法通过网络连接时,可以通过串口控制台捕获崩溃输出。这需要:
- 在本地编译固件(以匹配调试符号)
- 通过 USB 线连接设备以访问串口控制台
- 运行日志命令以捕获和解码崩溃
获取堆栈跟踪的步骤
Section titled “获取堆栈跟踪的步骤”-
在本地编译:在本地机器上构建配置以确保您有匹配的调试符号。
如果您使用 ESPHome Device Builder Web 界面:
- 点击设备旁边的溢出菜单(三个点)
- 选择 “Download YAML” 获取您的配置文件
- 保存到本地目录
然后使用命令行界面(有关完整详细信息,请参阅 CLI 指南):
Terminal window esphome compile your-device.yamlesphome upload your-device.yaml
NOTE
虽然您可以使用 OTA 进行上传,但下一步仍需要 USB 连接来捕获崩溃输出,因此通过 USB 上传通常更方便。
-
通过 USB 连接:使用 USB 线将设备连接到计算机。设备必须通过串口控制台(而非 WiFi/OTA)连接才能捕获崩溃输出。
-
监控日志:运行日志命令以监控设备输出:
Terminal window esphome logs your-device.yaml -
等待崩溃:当设备崩溃时,ESPHome 将自动检测并解码堆栈跟踪。您将看到类似以下的输出:
[08:17:06]E (5906) task_wdt: Task watchdog got triggered. The following tasks/users did not reset the watchdog in time:[08:17:06]E (5906) task_wdt: - loopTask (CPU 0)[08:17:06]E (5906) task_wdt: Tasks currently running:[08:17:06]E (5906) task_wdt: CPU 0: esp_timer[08:17:06]E (5906) task_wdt: CPU 1: IDLE1[08:17:06]E (5906) task_wdt: Aborting.[08:17:06]E (5906) task_wdt: Print CPU 0 (current core) backtrace[08:17:06]Backtrace: 0x4013d30e:0x3ffbac20 0x4013d383:0x3ffbac40 0x4014b23e:0x3ffbac70WARNING Found stack trace! Trying to decode itWARNING Decoded 0x4013d30e: touch_ll_is_measure_done at /Users/bdraco/.platformio/packages/framework-espidf/components/hal/esp32/include/hal/touch_sensor_ll.h:505(inlined by) _touch_pad_read at /Users/bdraco/.platformio/packages/framework-espidf/components/driver/touch_sensor/esp32/touch_sensor.c:365WARNING Decoded 0x4013d383: touch_pad_filter_cb at /Users/bdraco/.platformio/packages/framework-espidf/components/driver/touch_sensor/esp32/touch_sensor.c:108(inlined by) touch_pad_filter_cb at /Users/bdraco/.platformio/packages/framework-espidf/components/driver/touch_sensor/esp32/touch_sensor.c:98WARNING Decoded 0x4014b23e: timer_process_alarm at /Users/bdraco/.platformio/packages/framework-espidf/components/esp_timer/src/esp_timer.c:456(inlined by) timer_task at /Users/bdraco/.platformio/packages/framework-espidf/components/esp_timer/src/esp_timer.c:482解码后的堆栈跟踪显示:
- 发生崩溃的确切函数名和源文件
- 源代码中的行号
- 导致崩溃的调用堆栈
NOTE
重要提示:您必须在捕获崩溃之前在本地编译并上传固件。调试符号必须与正在运行的固件匹配,堆栈跟踪才能正确解码。
- 没有解码输出:确保在捕获崩溃之前在本地编译并上传了固件
- 无法连接:确保您使用的是 USB 数据线(不仅仅是充电线)和正确的串口
替代方案:基于 Web 的堆栈跟踪解码器
Section titled “替代方案:基于 Web 的堆栈跟踪解码器”如果您已经有堆栈跟踪但需要解码,可以使用 ESP Stack Trace Decoder 网页工具:
-
下载 .elf 文件:从 ESPHome Device Builder 中,点击设备卡片上的溢出菜单(三个点),选择 “Download .elf file”
NOTE
.elf 文件必须来自生成当前设备上正在运行的固件的同一次编译。如果您在刷写后重新编译了,调试符号将不匹配。
-
上传文件:
- 在 “ELF File” 下点击 “Choose File” 并选择您下载的 .elf 文件
- 将您的堆栈跟踪粘贴到文本区域
- 点击 “Decode Stack Trace”
-
查看结果:该工具将解码地址并显示函数名、文件路径和行号
NOTE
该工具完全在浏览器中运行——没有数据发送到任何服务器,确保您的固件和调试信息保持私密。
调整日志级别以进行调试
Section titled “调整日志级别以进行调试”在排查 ESPHome 设备问题时,提高日志级别可以提供有关内部情况的更详细信息。这对于诊断特定组件问题或理解组件之间的数据流特别有用。
设置全局日志级别
Section titled “设置全局日志级别”要提高全局日志的详细程度,请在日志记录器配置中调整 level:
logger: level: VERBOSE # 或 VERY_VERBOSE 以获得最大细节可用的日志级别从最不详细到最详细:
NONE- 不记录任何消息ERROR- 仅记录错误WARN- 警告及以上INFO- 信息性消息及以上DEBUG- 调试消息及以上(默认)VERBOSE- 详细的调试消息及以上VERY_VERBOSE- 所有内部消息,包括数据总线流量
WARNING
使用 VERY_VERBOSE 会显著降低设备速度,并可能因生成的日志消息量过大而导致连接问题。仅在短时间的调试会话中使用。
ESP-IDF 框架日志级别
Section titled “ESP-IDF 框架日志级别”在 ESP32 上使用 ESP-IDF 框架时,您还可以调整框架的内部日志级别,以从底层系统获取更详细的信息:
esp32: framework: type: esp-idf log_level: VERBOSE # 框架日志级别可用的 ESP-IDF 日志级别:NONE、ERROR(默认)、WARN、INFO、DEBUG、VERBOSE
组件特定日志级别
Section titled “组件特定日志级别”您还可以为特定组件配置日志级别,以减少噪音或从单个组件获取更多详细信息。请参阅日志记录器手册标签特定日志级别文档以获取详细信息和示例。
IMPORTANT
全局日志级别决定了哪些消息被编译到固件中。组件特定日志级别只能降低详细程度,不能超过全局级别。例如,如果全局级别是 INFO,将组件设置为 DEBUG 将无效。
“Took a long time for an operation” 警告
Section titled ““Took a long time for an operation” 警告”[W][component:511]: Component sensor.my_sensor took a long time for an operation (85 ms), max is 30 ms某个组件阻塞主循环的时间超过了预期的最大值。在阻塞期间,没有其他组件可以运行。严重情况可能触发看门狗重启或 Wi-Fi 断开。
此测量值是挂钟时间,而非 CPU 时间。在单核芯片(ESP32-C3、C2、H2)上,FreeRTOS 系统任务抢占主循环可能会触发或夸大此警告。有关更多详细信息,请参阅运行时统计挂钟时间文档。
如果您看到此警告,请在 GitHub issue #9517 上发表评论,附上日志输出和相关组件配置,以便修复该组件。
要收集更多详细信息,请启用运行时统计并查看 max 列:
runtime_stats: log_interval: 60s性能故障排除
Section titled “性能故障排除”如果您的设备遇到性能问题,例如:
- 响应时间慢
- 传感器读数丢失
- 连接问题
- 组件未按预期更新
运行时统计组件可以帮助识别哪些组件消耗了最多的处理时间或阻塞了事件循环。请参阅运行时统计文档获取详细的使用说明和示例,包括关于单核和双核芯片之间挂钟时间测量差异的重要说明。