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

gab6jxml  于 2023-06-05  发布在  其他
关注(0)|答案(2)|浏览(248)

我正在使用Eclipse和ESP-IDF 5.0.2为ESP 32 C3开发。在这段代码中,esp_wifi_set_config调用总是失败,因为WiFi没有初始化。

#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中的各种选项。
  • 只能暂停的行为不是一种选择。
  • 静默重新启动会导致更多的输出,因为重新启动和初始化。
  • GDB模式在紧急情况下打印转储。
  • 运行时的GDB模式无法使用,可能是因为我正在使用UART 0进行其他操作(在真实的代码中)。错误为uart: uart_driver_install(1559): UART used by GDB-stubs! Please disable GDB in menuconfig.
  • 进入深度睡眠而不是exit(1)是好的,但将ESP 32与虚拟串行端口断开,因此必须使用按钮在下次重新启动时进入闪存模式。
  • while(1) { printf("the error: ..."); }工作,但我看不到以前的程序输出。
  • sleep(100000)不会停止其他FreeRTOS任务的打印。在它看起来不起作用之前发出vTaskEndScheduler()vTaskSuspendAll()(在真实的代码中)。
  • vTaskSuspendAll(); while(1) {};工作,但触发看门狗定时器。不建议全局禁用WDT。在while循环中为看门狗提供数据,如果它最终能够工作,则有点太复杂了。
htrmnn0y

htrmnn0y1#

“垃圾邮件”不是来自WiFi配置失败。它来自对exit(1);的调用-嵌入式固件的主函数没有退出:)
通常,引发死机的错误不受错误处理的影响,它们表示应立即修复的异常情况。在这种情况下,不支持syscall exit();,因此无法调用它。
至于详细的输出,大部分是ESPIDF异常解码器在工作。micro本身只打印带有编码堆栈信息的几行。过滤串行输出的python脚本将其解码并使用elf文件填充详细信息。有关如何禁用IDF监视器的信息,请参阅IDF监视器文档中的本节。我不知道如何将此修复应用于Eclipse环境,但我个人希望在这种情况下看到完整的堆栈跟踪,以找出错误所在并尽快修复。

smdncfj3

smdncfj32#

后来我决定这样做:

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()中工作

缺点:

  • 没有一个电话

相关问题