Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork8.2k
ESP32 debugging
An overview of how to debug and/or report issues in the MicroPython ESP32 port.
If your board crashed with a "Guru Meditation Error" you've encountered a fatalerror. MicroPython will print a collection of data that might be relevant todetermining the cause, and then reset the board.
These errors may indicate a bug in MicroPython. But it might also be caused bya bug in your code, especially if you're building and/or customizing your ownversion of MicroPython. The instructions below may help to determine the whatis going wrong.
If you believe the crash is due to a bug in MicroPython, please considerreporting it. To do first determine if you can reproduce the issue and writedown the steps for doing so. Then copy all output leading up to the error untiland including the 'Rebooting...' message and file a bug reporthere.
In order to debug issues on the ESP32 port, you need two things:
- A working ESP-IDF build environment.
- To set up the ESP-IDF, follow the instructions inthe ESP32 port READMEsectionfor setting up the build environment.
- The ELF file for the exact build of MicroPython that you're using.
- If you're building MicroPython yourself, the ELF file will be located in thebuild directory (
ports/esp32/build-BOARDNAME
) alongside the flashablebinary itself. - If you downloaded MicroPython from the official website, you can find thecorresponding ELF file available as a separate download link next to theflashable binary link itself.
- If you're building MicroPython yourself, the ELF file will be located in thebuild directory (
There are a number of different variants of the ESP32 supported, and theyrequire slightly different toolchains which support their specific chiparchitectures. In all the examples below replace$TOOLCHAIN
with theappropriate toolchain for the chip variant you are using:
# ESP32TOOLCHAIN=xtensa-esp32-elf# ESP32-S2TOOLCHAIN=xtensa-esp32s2-elf# ESP32-S3TOOLCHAIN=xtensa-esp32s3-elf# ESP32-C2, ESP32-C3, ESP32-C6, ESP32-H2TOOLCHAIN=riscv32-esp-elf
When MicroPython on the ESP32 crashes, it will print out a backtrace as a listof pointers, as can be seen in this example crash:
MicroPython v1.22.2 on 2024-02-22; Generic ESP32 module with ESP32Type "help()" for more information.>>> from network import PPP>>> from io import BytesIO>>> ppp = PPP(BytesIO(0))>>> ppp.active(True)True>>> ppp.connect()Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.Core 1 register dump:PC : 0x400db62b PS : 0x00060c30 A0 : 0x800db9c7 A1 : 0x3ffbb830A2 : 0x3ffd0220 A3 : 0x00000040 A4 : 0x00000001 A5 : 0xb33fffffA6 : 0x00000000 A7 : 0x00060823 A8 : 0x800db62b A9 : 0x3ffbb810A10 : 0x00000000 A11 : 0x3ffbd634 A12 : 0x3ffdeba4 A13 : 0x3ffdf1a4A14 : 0x3ffdebcc A15 : 0x00000001 SAR : 0x00000020 EXCCAUSE: 0x0000001cEXCVADDR: 0x00000008 LBEG : 0x4000c2e0 LEND : 0x4000c2f6 LCOUNT : 0x00000000Backtrace: 0x400db628:0x3ffbb830 0x400db9c4:0x3ffbb850 0x400e819e:0x3ffbb870 0x40113d22:0x3ffbb890 0x401f7bdd:0x3ffbb8b0 0x400fd081:0x3ffbb8e0 0x4016fca8:0x3ffbb910 0x4016fe25:0x3ffbb930 0x401fa741:0x3ffbb960 0x40178d97:0x3ffbb980 0x40178df1:0x3ffbb9b0 0x40176f72:0x3ffbb9d0 0x4016f795:0x3ffbb9f0 0x4016fb97:0x3ffbba10 0x4016f5e5:0x3ffbba30 0x4016fa80:0x3ffbba50 0x401611a0:0x3ffbba70ELF file SHA256: 51aa7525e37c5ea9Rebooting...
Note the SHA256 hash of the ELF file is printed, which you can use to check thatyou have the correct ELF file:
sha256sum ESP32_GENERIC-20240222-v1.22.2.elf
This will print the SHA256 hash of the ELF file:
51aa7525e37c5ea9e35a4aa7d994ccd3897917063110d0885347c0eb8faf473b ESP32_GENERIC-20240222-v1.22.2.elf
Having determine the correct ELF file, we can now convert the backtrace from thelist of pointers into a more human-readable form useaddr2line
:
$TOOLCHAIN-addr2line -pfiaC -e path/to/micropython.elf [backtrace]
For the example crash given above this would become:
xtensa-esp32-elf-addr2line -pfiaC -e ESP32_GENERIC-20240222-v1.22.2.elf 0x400db628:0x3ffbb830 0x400db9c4:0x3ffbb850 0x400e819e:0x3ffbb870 0x40113d22:0x3ffbb890 0x401f7bdd:0x3ffbb8b0 0x400fd081:0x3ffbb8e0 0x4016fca8:0x3ffbb910 0x4016fe25:0x3ffbb930 0x401fa741:0x3ffbb960 0x40178d97:0x3ffbb980 0x40178df1:0x3ffbb9b0 0x40176f72:0x3ffbb9d0 0x4016f795:0x3ffbb9f0 0x4016fb97:0x3ffbba10 0x4016f5e5:0x3ffbba30 0x4016fa80:0x3ffbba50 0x401611a0:0x3ffbba70
And it will give the following output:
0x400db628: gc_realloc at /home/micropython/micropython-autobuild/py/gc.c:10360x400db9c4: m_realloc at /home/micropython/micropython-autobuild/py/malloc.c:1410x400e819e: vstr_ensure_extra at /home/micropython/micropython-autobuild/py/vstr.c:115 (inlined by) vstr_add_len at /home/micropython/micropython-autobuild/py/vstr.c:1260x40113d22: stringio_write at /home/micropython/micropython-autobuild/py/objstringio.c:980x401f7bdd: mp_stream_rw at /home/micropython/micropython-autobuild/py/stream.c:600x400fd081: ppp_output_callback at /home/micropython/micropython-autobuild/ports/esp32/network_ppp.c:1040x4016fca8: pppos_output_last at /home/micropython/esp-idf-v5.0/components/lwip/lwip/src/netif/ppp/pppos.c:8780x4016fe25: pppos_write at /home/micropython/esp-idf-v5.0/components/lwip/lwip/src/netif/ppp/pppos.c:2410x401fa741: ppp_write at /home/micropython/esp-idf-v5.0/components/lwip/lwip/src/netif/ppp/ppp.c:9960x40178d97: fsm_sconfreq at /home/micropython/esp-idf-v5.0/components/lwip/lwip/src/netif/ppp/fsm.c:7570x40178df1: fsm_lowerup at /home/micropython/esp-idf-v5.0/components/lwip/lwip/src/netif/ppp/fsm.c:102 (inlined by) fsm_lowerup at /home/micropython/esp-idf-v5.0/components/lwip/lwip/src/netif/ppp/fsm.c:910x40176f72: lcp_lowerup at /home/micropython/esp-idf-v5.0/components/lwip/lwip/src/netif/ppp/lcp.c:4750x4016f795: ppp_start at /home/micropython/esp-idf-v5.0/components/lwip/lwip/src/netif/ppp/ppp.c:7500x4016fb97: pppos_connect at /home/micropython/esp-idf-v5.0/components/lwip/lwip/src/netif/ppp/pppos.c:3400x4016f5e5: ppp_do_connect at /home/micropython/esp-idf-v5.0/components/lwip/lwip/src/netif/ppp/ppp.c:464 (inlined by) ppp_connect at /home/micropython/esp-idf-v5.0/components/lwip/lwip/src/netif/ppp/ppp.c:2850x4016fa80: pppapi_do_ppp_connect at /home/micropython/esp-idf-v5.0/components/lwip/lwip/src/netif/ppp/pppapi.c:2770x401611a0: tcpip_thread_handle_msg at /home/micropython/esp-idf-v5.0/components/lwip/lwip/src/api/tcpip.c:166 (inlined by) tcpip_thread at /home/micropython/esp-idf-v5.0/components/lwip/lwip/src/api/tcpip.c:148
To interactively debug MicroPython itself on the ESP32 you need a JTAG debuggerattached to the chip. The easiest way to set do this is by making use of thebuilt-in USB JTAG support available on the S3/C3/C6/H2 variants, or using aboard that includes JTAG support. For more information on setting up and usingJTAG please referencethe ESP-IDF documentation on JTAGdebugging.
For example to debug a board using the built-in USB JTAG of an ESP32-S3:
openocd -f board/esp32s3-builtin.cfg&$TOOLCHAIN-gdb -x gdbinit path/to/micropython.elf
This is using the followinggdbinit
file:
set pagination offtarget remote :3333set remote hardware-watchpoint-limit2monitor reset haltmaintenance flush register-cachethbreak app_maincontinue