在 ESP-IDF 的 ESP32 上开发时,如何打印错误并阻止进一步的控制台监视器垃圾邮件?

How to print error and stop further console monitor spam when developing on ESP32 in ESP-IDF?

提问人:mik13ST 提问时间:5/31/2023 最后编辑:mik13ST 更新时间:6/1/2023 访问量:261

问:

我正在使用 Eclipse 和 ESP-IDF 5.0.2 为 ESP32 C3 进行开发。 在此代码中,调用始终失败,因为 WiFi 未初始化。esp_wifi_set_config

#include <stdio.h>

#include "esp_wifi.h"

void app_main(void) {
    printf("hello\n");

    wifi_config_t wifi_details = {
        .sta = {
            .ssid = "wifissid",
            .password = "wifipwd",
        },
    };
    int err = esp_wifi_set_config(WIFI_IF_STA, &wifi_details);
    if (err != 0) {
        printf("WiFi set details failed: %s\n", esp_err_to_name(err));
        exit(1);
    }
}

但是,输出如下所示:

hello
WiFi set details failed: ESP_ERR_WIFI_NOT_INIT

abort() was called at PC 0x42003889 on core 0
0x42003889: syscall_not_implemented_aborts at C:/esp-idf/esp-idf-v5.0.2/components/newlib/syscalls.c:27

Core  0 register dump:
MEPC    : 0x4038084c  RA      : 0x403840d0  SP      : 0x3fc91300  GP      : 0x3fc8b600
0x4038084c: panic_abort at C:/esp-idf/esp-idf-v5.0.2/components/esp_system/panic.c:423

0x403840d0: __ubsan_include at C:/esp-idf/esp-idf-v5.0.2/components/esp_system/ubsan.c:313

TP      : 0x3fc8960c  T0      : 0x37363534  T1      : 0x7271706f  T2      : 0x33323130
S0/FP   : 0x00000004  S1      : 0x3fc91364  A0      : 0x3fc9132c  A1      : 0x3fc91362
A2      : 0x00000000  A3      : 0x3fc91359  A4      : 0x00000001  A5      : 0x3fc8e000
A6      : 0x7a797877  A7      : 0x76757473  S2      : 0x00000000  S3      : 0x00000000
S4      : 0x00000000  S5      : 0x00000000  S6      : 0x00000000  S7      : 0x00000000
S8      : 0x00000000  S9      : 0x00000000  S10     : 0x00000000  S11     : 0x00000000
T3      : 0x6e6d6c6b  T4      : 0x6a696867  T5      : 0x66656463  T6      : 0x62613938
MSTATUS : 0x00001881  MTVEC   : 0x40380001  MCAUSE  : 0x00000007  MTVAL   : 0x00000000
0x40380001: _vector_table at ??:?

MHARTID : 0x00000000

Stack memory:
3fc91300: 0x00000000 0x3fc8c60c 0x3fc91360 0x403894b8 0x00000000 0x3fc8c60c 0x3fc8edc0 0x3fc8b50c
0x403894b8: abort at C:/esp-idf/esp-idf-v5.0.2/components/newlib/abort.c:35 (discriminator 3)

3fc91320: 0x3fc91364 0x3fc8b528 0x3fc91360 0x726f6261 0x20292874 0x20736177 0x6c6c6163 0x61206465
3fc91340: 0x43502074 0x34783020 0x33303032 0x20393838 0x63206e6f 0x2065726f 0x00000030 0x42000000
3fc91360: 0x00000030 0x30303234 0x39383833 0x00000000 0x00000000 0x00000000 0x00000001 0x4200388c
0x4200388c: newlib_include_syscalls_impl at C:/esp-idf/esp-idf-v5.0.2/components/newlib/syscalls.c:161

3fc91380: 0x00000000 0x00000000 0x00000001 0x4200b43e 0x0000003a 0x3c0244e8 0x00000000 0x420063a6
0x4200b43e: _fclose_r at ??:?

0x420063a6: riscv_decode_offset_from_jal_instruction at C:/esp-idf/esp-idf-v5.0.2/components/riscv/instruction_decode.c:34

3fc913a0: 0x00000804 0x69666977 0x64697373 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
3fc913c0: 0x00000000 0x69666977 0x00647770 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
3fc913e0: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
3fc91400: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
3fc91420: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x42015232
0x42015232: main_task at C:/esp-idf/esp-idf-v5.0.2/components/freertos/FreeRTOS-Kernel/portable/port_common.c:132 (discriminator 2)

3fc91440: 0x00000000 0x00001388 0x00000001 0x00000000 0x00000000 0x00000000 0x00000000 0x40386544
0x40386544: vPortTaskWrapper at C:/esp-idf/esp-idf-v5.0.2/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c:131

3fc91460: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5
3fc91480: 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0x00000154 0x3fc913e0 0x3fc8e304 0x3fc8c328
3fc914a0: 0x3fc8c328 0x3fc91494 0x3fc8c320 0x00000018 0x13e9b397 0xd9d9b153 0x3fc91494 0x00000000
3fc914c0: 0x00000001 0x3fc90490 0x6e69616d 0x37f11b00 0x5db4bd0d 0x00b999a0 0x00000000 0x3fc91480
3fc914e0: 0x00000001 0x00000000 0x00000000 0x00000000 0x00000000 0x3fc8ecf0 0x3fc8ed58 0x3fc8edc0
3fc91500: 0x00000000 0x00000000 0x00000001 0x00000000 0x00000000 0x00000000 0x4200b818 0x00000000
0x4200b818: _cleanup_r at ??:?

3fc91520: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
3fc91540: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
3fc91560: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
3fc91580: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
3fc915a0: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
3fc915c0: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
3fc915e0: 0x00000000 0x3f000000 0x00000600 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5
3fc91600: 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5
3fc91620: 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5
3fc91640: 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5
3fc91660: 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5
3fc91680: 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5
3fc916a0: 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5
3fc916c0: 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5
3fc916e0: 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5

我希望输出是什么:

hello
WiFi set details failed: ESP_ERR_WIFI_NOT_INIT

如何禁用核心寄存器转储?我还有哪些其他选项只能在串行监视器中查看我的输出?

我试过了:

  • 在 sdkconfig/menuconfig 中将紧急处理程序设置为各种选项。
    • 仅停止行为不是一种选择。
    • 由于重新启动和 init,静默重新启动会导致更多输出。
    • 紧急模式下的 GDB 模式打印转储。
    • 无法在运行时使用 GDB 模式,可能是因为我将 UART0 用于其他用途(在实际代码中)。错误是uart: uart_driver_install(1559): UART used by GDB-stubs! Please disable GDB in menuconfig.
  • 进入深度睡眠状态是好的,但会断开 ESP32 与虚拟串口的连接,因此下次重启时必须使用按钮进入闪存模式。exit(1)
  • while(1) { printf("the error: ..."); }有效,但我看不到以前的程序输出。
  • sleep(100000)不会阻止其他 FreeRTOS 任务的打印。在它之前发出或之前似乎不起作用(在实际代码中)。vTaskEndScheduler()vTaskSuspendAll()
  • vTaskSuspendAll(); while(1) {};有效,但会触发看门狗计时器。不建议全局禁用 WDT。如果看门狗最终工作,那么在 while 循环中馈送它有点太复杂了。
C 错误处理 ESP32 FreeRTOS ESP-IDF

评论

2赞 stark 5/31/2023
为什么不修复导致未实现的系统调用的原因?
0赞 mik13ST 5/31/2023
这与一般的错误处理有关,与此特定错误无关。
2赞 stark 5/31/2023
对于太严重而无法继续的错误,打印包含修复信息的转储是适当的响应。为什么要有办法关闭它?
0赞 mik13ST 5/31/2023
作为初学者,我不知道如何阅读转储,错误消息是我通常解决问题所需要的。或者至少我想先看到错误,并且必须滚动整个转储很乏味。
0赞 mik13ST 6/1/2023
哦,没有实现。核心转储太大了,我从来没有费心阅读它。我应该早点注意到这一点。exit()

答:

2赞 Tarmo 5/31/2023 #1

“垃圾邮件”不是来自WiFi配置失败。它从调用到 - 嵌入式固件的主要功能没有退出:)exit(1);

通常,引起恐慌的错误不会受到错误处理,它们表示应立即修复的异常情况。在这种情况下,根本不支持 syscall,因此您无法调用它。exit();

至于详细输出,其中大部分是 ESP IDF 异常解码器在工作。微型本身只打印带有编码堆栈信息的几行。过滤串行输出的 python 脚本对其进行解码,并使用 elf 文件填充详细信息。有关如何禁用它的信息,请参阅 IDF Monitor 文档中的此部分。我不知道如何将此修复程序应用于 Eclipse 环境,但我个人希望在这种情况下查看完整的堆栈跟踪,以找出出了什么问题并尽快修复它。

评论

0赞 mik13ST 6/1/2023
我认为错误是由核心退出引起的,而不是由未实现引起的。感谢您指出这一点。至于 IDF 监视器解码,我仍然认为未解码的输出太冗长了。exit()
0赞 mik13ST 6/1/2023 #2

我后来决定:

void halt() {
    esp_task_wdt_deinit(); // Disable global WDT.
    vTaskSuspendAll(); // Suspend all other RTOS tasks.
    while (1) {} // Loop forever.
}

void main() {
    ...
    if (err != 0) {
        printf("WiFi set details failed: %s\n", esp_err_to_name(err));
        halt();
    }

优点:

  • 不会产生比消息本身更多的输出
  • 允许查看上一个输出
  • 不会断开 ESP 模块的连接
  • 不触发 WDT
  • 不需要全局禁用 WDT
  • 似乎可以从 RTOS 任务内部以及main()

缺点:

  • 没有一个电话