打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
ESP32 官方文档(五)严重错误

严重错误

概述

在某些情况下,程序的执行,没有按照定义的方式持续执行.在 ESP-IDF 中,这些情况包括:

  • CPU 异常:Illegal Instruction, Load/Store Alignment Error, Load/Store Prohibited error, Double Exception.(非法指令,加载/存储对齐错误,加载/存储禁止错误,双重异常)
  • 系统级别检查和安全措施:
    • Interrupt watchdog timeout 中断看门狗超时
    • Task watchdog timeout 任务监视程序超时(如果设置了 CONFIG_TASK_WDT_PANIC,则仅 fatal)
    • Cache access error 缓存访问错误
    • Brownout detection event 掉电检测事件
    • Stack overflow 堆栈溢出
    • Stack smashing protection check 堆栈粉碎保护检查
    • Heap integrity check 堆完整性检查
  • Failed assertions 断言失败,通过 assert ,configASSERT 和类似的宏.

本指南介绍了 ESP-IDF 中用于处理这些错误的过程,并提供了有关错误故障排除的建议.

Panic 处理

概述中列出的每个错误原因都将由 Panic 处理程序处理.

Panic 处理程序将首先将错误原因打印到控制台. 对于 CPU 异常,消息类似于:

Guru Meditation Error: Core 0 panic'ed (IllegalInstruction). Exception was unhandled.

对于某些系统级别检查(中断监视程序,缓存访问错误),该消息将类似于:

Guru Meditation Error: Core 0 panic'ed (Cache disabled but cached memory region accessed)

在所有情况下,错误原因将打印在括号中. 有关可能的错误原因列表,请参阅 Guru Meditation Errors.

可以使用 CONFIG_ESP32_PANIC 配置选项设置 Panic 处理程序的后续行为. 可用选项包括:

  • 打印寄存器并重新启动(CONFIG_ESP32_PANIC_PRINT_REBOOT) - 默认选项.
    这将在异常点打印寄存器值,打印回溯,然后重新启动芯片.

  • 打印寄存器并暂停(CONFIG_ESP32_PANIC_PRINT_HALT)
    与上述选项类似,但暂停而不是重新启动. 重启程序需要外部重置.

  • 无提示重启(CONFIG_ESP32_PANIC_SILENT_REBOOT)
    不要打印寄存器或回溯,立即重启芯片.

  • 调用 GDB 存根(CONFIG_ESP32_PANIC_GDBSTUB)
    启动 GDB 服务器,它可以通过控制台 UART 端口与 GDB 通信. 有关详细信息,请参阅 GDB 存根.

Panic 处理程序的行为受另外两个配置选项的影响.

  • 如果启用了 CONFIG_ESP32_DEBUG_OCDAWARE (这是默认设置),则 Panic 处理程序将检测 JTAG 调试器是否已连接. 如果是,则执行将暂停,控制权将传递给调试器. 在这种情况下,寄存器和回溯不会转储到控制台,并且不使用 GDBStub/Core Dump 功能.
  • 如果启用了核心转储功能(CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASHCONFIG_ESP32_ENABLE_COREDUMP_TO_UART 选项),则系统状态(任务堆栈和寄存器)将被转储到 Flash 或 UART,以供以后分析.

下图说明了 Panic 处理程序的行为:

寄存器转储和回溯

除非启用了 CONFIG_ESP32_PANIC_SILENT_REBOOT 选项,否则 Panic 处理程序会将一些 CPU 寄存器和回溯打印到控制台:

Core 0 register dump:PC      : 0x400e14ed  PS      : 0x00060030  A0      : 0x800d0805  A1      : 0x3ffb5030A2      : 0x00000000  A3      : 0x00000001  A4      : 0x00000001  A5      : 0x3ffb50dcA6      : 0x00000000  A7      : 0x00000001  A8      : 0x00000000  A9      : 0x3ffb5000A10     : 0x00000000  A11     : 0x3ffb2bac  A12     : 0x40082d1c  A13     : 0x06ff1ff8A14     : 0x3ffb7078  A15     : 0x00000000  SAR     : 0x00000014  EXCCAUSE: 0x0000001dEXCVADDR: 0x00000000  LBEG    : 0x4000c46c  LEND    : 0x4000c477  LCOUNT  : 0xffffffffBacktrace: 0x400e14ed:0x3ffb5030 0x400d0802:0x3ffb5050

打印的寄存器值是异常帧中的寄存器值,即 CPU 异常或其他严重错误发生时的值.

如果由于 abort() 调用而执行了 Panic 处理程序,则不会打印寄存器转储.

在某些情况下,例如中断看门狗超时, Panic 处理程序可能会打印额外的 CPU 寄存器 (EPC1-EPC4) 以及在另一个 CPU 上运行的代码的寄存器/回溯.

Backtrace 行包含 PC:SP 对,其中 PC 是程序计数器,SP 是堆栈指针,用于当前任务的每个堆栈帧. 如果在 ISR 内发生严重错误,则回溯可能包括来自被中断的任务和来自 ISR 的 PC:SP 对.

如果使用 IDF Monitor,程序计数器值将转换为代码位置(函数名称,文件名和行号),输出将与其他行进行注释:

Core 0 register dump:PC      : 0x400e14ed  PS      : 0x00060030  A0      : 0x800d0805  A1      : 0x3ffb50300x400e14ed: app_main at /Users/user/esp/example/main/main.cpp:36A2      : 0x00000000  A3      : 0x00000001  A4      : 0x00000001  A5      : 0x3ffb50dcA6      : 0x00000000  A7      : 0x00000001  A8      : 0x00000000  A9      : 0x3ffb5000A10     : 0x00000000  A11     : 0x3ffb2bac  A12     : 0x40082d1c  A13     : 0x06ff1ff80x40082d1c: _calloc_r at /Users/user/esp/esp-idf/components/newlib/syscalls.c:51A14     : 0x3ffb7078  A15     : 0x00000000  SAR     : 0x00000014  EXCCAUSE: 0x0000001dEXCVADDR: 0x00000000  LBEG    : 0x4000c46c  LEND    : 0x4000c477  LCOUNT  : 0xffffffffBacktrace: 0x400e14ed:0x3ffb5030 0x400d0802:0x3ffb50500x400e14ed: app_main at /Users/user/esp/example/main/main.cpp:360x400d0802: main_task at /Users/user/esp/esp-idf/components/esp32/cpu_start.c:470

要查找发生严重错误的位置,请查看“Backtrace”的下一行. 严重错误位置是顶行,后续行显示调用堆栈.

GDB 存根

如果启用了 CONFIG_ESP32_PANIC_GDBSTUB 选项,则发生严重错误时, Panic 处理程序不会重置芯片. 相反,它将启动 GDB 远程协议服务器,通常称为 GDB Stub. 发生这种情况时,可以指示主机上运行的 GDB 实例连接到 ESP32 UART 端口.

如果使用 IDF Monitor,则在 UART 上检测到 GDB Stub 提示时会自动启动 GDB. 输出看起来像这样:

Entering gdb stub now.$T0b#e6GNU gdb (crosstool-NG crosstool-ng-1.22.0-80-gff1f415) 7.10Copyright (C) 2015 Free Software Foundation, Inc.License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>This is free software: you are free to change and redistribute it.There is NO WARRANTY, to the extent permitted by law.  Type "show copying"and "show warranty" for details.This GDB was configured as "--host=x86_64-build_apple-darwin16.3.0 --target=xtensa-esp32-elf".Type "show configuration" for configuration details.For bug reporting instructions, please see:<http://www.gnu.org/software/gdb/bugs/>.Find the GDB manual and other documentation resources online at:<http://www.gnu.org/software/gdb/documentation/>.For help, type "help".Type "apropos word" to search for commands related to "word"...Reading symbols from /Users/user/esp/example/build/example.elf...done.Remote debugging using /dev/cu.usbserial-313010x400e1b41 in app_main ()    at /Users/user/esp/example/main/main.cpp:3636      *((int*) 0) = 0;(gdb)

GDB 提示可用于检查 CPU 寄存器,本地和静态变量以及内存中的任意位置. 无法设置断点,更改 PC 或继续执行. 要重置程序,请退出 GDB 并执行外部重置:IDF Monitor 中的 Ctrl-T Ctrl-R,或使用开发板上的外部重置按钮.

Guru Meditation 错误

本节解释了不同错误原因的含义,打印在 Guru Meditation Error:Core panic'ed message 之后的括号中.

有关“Guru Meditation”的历史渊源,请参阅 Wikipedia 文章.

IllegalInstruction (非法指令)

该 CPU 异常表示执行的指令不是有效指令. 此错误的最常见原因有:

  • FreeRTOS 任务功能已经返回. 在 FreeRTOS 中,如果任务函数需要终止,它应该调用 vTaskDelete() 函数并删除它自己,而不是返回.
  • 无法从 SPI Flash 加载下一条指令. 这种情况通常发生在:
    • 应用程序已将 SPI Flash 引脚重新配置为其他功能(GPIO,UART 等). 有关 SPI Flash 引脚的详细信息,请参阅硬件设计指南和芯片或模块的数据表.
    • 某些外部设备意外连接到 SPI Flash 引脚,干扰了 ESP32 和 SPI Flash 之间的通信.

InstrFetchProhibited (禁止指令加载)

此 CPU 异常表示 CPU 无法加载指令,因为指令的地址不属于指令 RAM 或 ROM 中的有效区域.

通常这意味着尝试调用函数指针,该指针不指向有效代码. PC (程序计数器)寄存器可用作指示器:它将为零或将包含垃圾值(不是 0x4xxxxxxx).

LoadProhibited,StoreProhibited(禁止加载,禁止存储)

当应用程序尝试读取或写入无效的内存位置时,会发生此 CPU 异常. 写入/读取的地址可在寄存器转储中的 EXCVADDR 寄存器中找到. 如果此地址为零,则通常表示应用程序尝试取消引用 NULL 指针. 如果此地址接近于零,则通常意味着应用程序尝试访问结构的成员,但指向该结构的指针为 NULL. 如果该地址是别的(垃圾值,不在 0x3fxxxxxx - 0x6xxxxxxx 范围内),则可能意味着用于访问数据的指针未初始化或已损坏.

IntegerDivideByZero(除以 0)

应用程序尝试将整数除以零.

LoadStoreAlignment(对齐方式不对)

应用程序尝试读取或写入内存位置,并且地址对齐与加载/存储大小不匹配. 例如,32 位加载只能从 4 字节对齐的地址完成,而 16 位加载只能从 2 字节的对齐地址完成.

LoadStoreError(加载/存储错误)

应用程序尝试从仅支持 32 位加载/存储的内存区域进行 8 位或 16 位加载/存储. 例如,取消引用指向内存存储器的 char * 指针将导致这样的错误.

Unhandled debug exception(堆栈错误)

通常会出现以下消息:

Debug exception reason: Stack canary watchpoint triggered (task_name)

此错误表示应用程序已写入 task_name 任务堆栈的末尾. 请注意,并非每个堆栈溢出都可以保证触发此错误. 任务可能会在堆栈 canary 位置之外写入堆栈,在这种情况下,不会触发观察点.

Interrupt wdt timeout on CPU0 / CPU1(看门狗超时)

表示发生了中断看门狗超时. 有关详细信息,请参阅看门狗.

Cache disabled but cached memory region accessed(Cache 禁止)

在某些情况下,ESP-IDF 将暂时禁止通过高速缓存访问外部 SPI Flash 和 SPI RAM. 例如,spi_flash API 用于读取/写入/擦除/mmap SPI Flash 区域. 在这些情况下,任务被挂起,并且未注册 ESP_INTR_FLAG_IRAM 的中断处理程序被禁用. 确保使用此标志注册的任何中断处理程序都具有 IRAM/DRAM 中的所有代码和数据. 有关更多详细信息,请参阅 SPI Flash API 文档.

其他严重错误

Brownout(欠压)

ESP32 有一个内置的掉电检测器,默认启用. 如果电源电压低于安全水平,掉电检测器可以触发系统复位. 可以使用 CONFIG_BROWNOUT_DETCONFIG_BROWNOUT_DET_LVL_SEL 选项配置掉电检测器. 当掉电检测器触发时,将打印以下消息:

Brownout detector was triggered

打印消息后,芯片将复位.

请注意,如果电源电压快速下降,则控制台上只能看到部分消息.

Corrupt Heap

ESP-IDF 堆实现包含许多堆结构的运行时检查. 可以在 menuconfig 中启用其他检查(“Heap Stisoning”). 如果其中一项检查失败,将打印类似于以下内容的消息:

CORRUPT HEAP: Bad tail at 0x3ffe270a. Expected 0xbaad5678 got 0xbaac5678assertion "head != NULL" failed: file "/Users/user/esp/esp-idf/components/heap/multi_heap_poisoning.c", line 201, function: multi_heap_freeabort() was called at PC 0x400dca43 on core 0

有关详细信息,请参阅堆内存调试文档.

Stack Smashing

可以使用 CONFIG_STACK_CHECK_MODE 选项在 ESP-IDF 中启用 Stack Smashing 保护(基于 GCC -fstack-protector * 标志). 如果检测到 Stack Smashing,将打印类似于以下内容的消息:

Stack smashing protect failure!abort() was called at PC 0x400d2138 on core 0Backtrace: 0x4008e6c0:0x3ffc1780 0x4008e8b7:0x3ffc17a0 0x400d2138:0x3ffc17c0 0x400e79d5:0x3ffc17e0 0x400e79a7:0x3ffc1840 0x400e79df:0x3ffc18a0 0x400e2235:0x3ffc18c0 0x400e1916:0x3ffc18f0 0x400e19cd:0x3ffc1910 0x400e1a11:0x3ffc1930 0x400e1bb2:0x3ffc1950 0x400d2c44:0x3ffc1a800

回溯应该指向 Stack Smashing 发生的函数. 检查功能代码以获得对本地阵列的无限制访问.

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Linux 2.6 对新型 CPU 快速系统调用的支持
《深入理解Linux内核3rd》学习笔记——进程切换(下):switch
关于PHP程序员解决问题的能力(转)
逆向教程
移动平台调试利器:GikDbg | 神乎
C++引用的本质
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服