Skip to content

Fatal crash on sta.scan() in UIFlow2 v2.4.4 on Tab5 (MEPC: 0x4ff13582) #94

@Runaque

Description

@Runaque

Bug Report: Fatal crash on sta.scan() in UIFlow2 v2.4.4 on Tab5

Summary

Calling sta.scan() on the Tab5 causes a fatal Guru Meditation Error (Load access fault)
every time, crashing and rebooting the device. The crash is 100% reproducible and occurs
on the first WiFi scan attempt regardless of code structure.

Device Information

  • Board: M5Stack Tab5
  • SoC: ESP32-P4 + ESP32-C6 (via SDIO)
  • UIFlow2 Version: v2.4.4
  • MicroPython Version: v1.27.0-dirty (2026-04-22)
  • IDF Version: v5.5.1-dirty
  • OS: Windows 11

Steps to Reproduce

  1. Flash UIFlow2 v2.4.4 to Tab5 via M5Burner
  2. Open UIFlow2 web IDE, connect via USB
  3. Paste and run the following minimal reproduction:
import network
import utime

sta = network.WLAN(network.STA_IF)
sta.active(True)
utime.sleep_ms(500)
print("Scanning...")
results = sta.scan()   # <-- CRASHES HERE
print("Found:", len(results))
  1. Device immediately crashes with Guru Meditation Error

Expected Behaviour

sta.scan() should return a list of nearby WiFi networks.

Actual Behaviour

Device crashes with a fatal Load access fault at the same instruction address every time:

Guru Meditation Error: Core 1 panic'ed (Load access fault). Exception was unhandled.

MEPC    : 0x4ff13582   (always identical)
S10     : 0x00000022   (ETIMEDOUT = 34)
S11     : 0x4ff4a4c0   (always identical)
MTVAL   : 0x0000004c

Additional Observations

Crash is always identical

The crash registers are byte-for-byte identical across every run:

  • MEPC: 0x4ff13582 — same instruction every time
  • S10: 0x00000022 — errno 34 (ETIMEDOUT)
  • S11: 0x4ff4a4c0 — same buffer address every time

This indicates a null pointer dereference in the esp-hosted SDIO transport layer
when the ESP32-C6 WiFi coprocessor times out during scan initialization.

WiFi credentials make no difference

Tested both with and without WiFi credentials configured in M5Burner:

  • With credentials: MQTT client also crashes alongside the scan
  • Without credentials: Same crash, same address, no MQTT involvement

SDIO bus conflict suspected

The Tab5 uses SDIO to communicate with both:

  • The ESP32-C6 WiFi/BLE coprocessor
  • The SD card slot

The crash signature matches a known SDIO transport timeout in the
esp-hosted component (esp_wifi_remote / SDIO transport layer).

Related community findings

  • Arduino WiFi on Tab5 also requires special WiFi.setPins() due to non-standard
    SDIO pin mapping (reported in arduino-esp32 issue #11404)
  • Community vanilla MicroPython builds for Tab5 work around this by using a
    different board definition

Crash Dump (representative sample)

MPY version : v1.27.0-dirty on 2026-04-22
IDF version : v5.5.1-dirty
Machine     : M5STACK Tab5 with ESP32P4

Guru Meditation Error: Core  1 panic'ed (Load access fault). Exception was unhandled.

MEPC    : 0x4ff13582  RA      : 0x4ff12970  SP      : 0x4ff2ee10
S0/FP   : 0x0000abab  S1      : 0x0000004c  A0      : 0x0000004c
S10     : 0x00000022  S11     : 0x4ff4a4c0
MCAUSE  : 0x00000005  MTVAL   : 0x0000004c

Crash is Uncatchable from Python

The crash occurs below the MicroPython VM and bypasses Python exception handling entirely.
No try/except block can catch or recover from it. The device hard-crashes and reboots.

UI is Irrelevant

The crash reproduces in a completely minimal non-LVGL environment (see minimal
reproducer above). It has been tested with and without LVGL, with simple scripts,
complex applications, different scan intervals, and different architectural patterns.
None of these variables affect the crash. The UI layer is not the cause.

Root Cause Analysis

MTVAL: 0x0000004c suggests NULL + offset dereference

MTVAL: 0x0000004c (decimal 76) strongly suggests the crash is:

NULL pointer + offset 0x4c = 0x0000004c

Meaning the transport context/session pointer became NULL after a timeout,
and the driver then dereferenced session->field at offset 0x4c without
validating the pointer. This is a classic embedded driver bug in timeout
error-handling paths.

Probable crash sequence

network.WLAN(STA_IF)
  ↓
esp-hosted transport init
  ↓
scan command issued to ESP32-C6 via SDIO
  ↓
SDIO response timeout (S10 = 0x22 = ETIMEDOUT)
  ↓
transport state invalidated / session pointer set to NULL
  ↓
driver dereferences session->field @ offset +0x4c
  ↓
Load access fault at 0x4ff13582
  ↓
Guru Meditation Error / reboot

Possible race condition

This may also be a race condition between SDIO host readiness and
esp-hosted scan command dispatch
— timing-sensitive SDIO init races
are extremely common in hosted WiFi architectures.

Additional Diagnostic Tests Performed

WiFi credentials: no effect

  • With credentials configured: crashes + MQTT client errors alongside
  • Without credentials: identical crash, no MQTT involvement
  • Confirms: not a connection state issue

Code architecture: no effect

Tested with minimal scripts, complex applications, different LVGL patterns,
different scan intervals (6s, 10s, 15s), sta.active() checks before scan,
gc.collect() calls, delayed first scan — all crash identically.

Workaround

None available at Python level. The crash occurs inside the C-level
esp-hosted SDIO transport layer and cannot be caught or prevented from MicroPython.

Request

Please investigate the esp_wifi_remote / SDIO transport initialization in the
Tab5 UIFlow2 firmware. Specifically:

  1. The timeout error-handling path at 0x4ff13582 does not appear to validate
    the transport context pointer before dereferencing it at offset +0x4c
  2. There may be a race condition between SDIO host initialization and the
    first scan command dispatch to the ESP32-C6 coprocessor
  3. sta.scan() is a core networking API — if it hard-crashes the device,
    the WiFi transport layer is fundamentally broken for this firmware/device combination

A fix in a future UIFlow2 firmware update for Tab5 would be greatly appreciated.

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions