adafruit / circuitpython

CircuitPython - a Python implementation for teaching coding with microcontrollers
https://circuitpython.org
Other
4.11k stars 1.22k forks source link

HardFault/crash with 4th displayio.I2CDisplay and CIRCUITPY_DISPLAY_LIMIT=4 #6395

Open todbot opened 2 years ago

todbot commented 2 years ago

CircuitPython version

Adafruit CircuitPython 7.0.0-alpha.5-716-gd2d08fc94-dirty on 2022-05-13; Adafruit QT Py RP2040 with rp2040

Code/REPL

import time, gc
import board, busio, displayio

displayio.release_displays()

for i in range(5):
    print("waiting for USB", 5-i)
    time.sleep(1) # wait for USB to connect

i2cA = busio.I2C(scl=board.SCL, sda=board.SDA)
i2cB = busio.I2C(scl=board.SCL1, sda=board.SDA1)
#i2cB = busio.I2C(scl=board.TX, sda=board.RX) # alt on esp32s3, use any pins

print("Created I2C busses, creating display busses")

display_bus1 = displayio.I2CDisplay(i2cA, device_address=0x3C )
print(" created bus1", gc.mem_free())

display_bus2 = displayio.I2CDisplay(i2cA, device_address=0x3D )
print(" created bus2", gc.mem_free())

display_bus3 = displayio.I2CDisplay(i2cB, device_address=0x3C )
print(" created bus3", gc.mem_free())

display_bus4 = displayio.I2CDisplay(i2cB, device_address=0x3D )
print(" created bus4", gc.mem_free())

print("Created display busses, now creating displays")
# continue creating adafruit_displayio_ssd1306 displays, etc

Behavior

On adafruit_qtpy_rp2040, system simply hangs on creation of fourth display_bus:

Adafruit CircuitPython 7.0.0-alpha.5-716-gd2d08fc94-dirty on 2022-05-13; Adafruit QT Py RP2040 with rp2040
>>>
>>>
soft reboot

Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
waiting for USB 5
waiting for USB 4
waiting for USB 3
waiting for USB 2
waiting for USB 1
Created I2C busses, creating display busses
 created bus1 178512
 created bus2 178512
 created bus3 178464

On adafruit_qtpy_esp32s3, it actually triggers the HardFaultHandler:

[17:19:46.304] Waiting for tty device..
[17:19:48.321] Connected
waiting for USB 3
waiting for USB 2
waiting for USB 1
Created I2C busses, creating display busses
 created bus1 147392
 created bus2 147392
 created bus3 147344

[17:19:53.086] Disconnected
[17:19:54.099] Connected
Auto-reload is off.
Running in safe mode! Not running saved code.

You are in safe mode because:
CircuitPython core code crashed hard. Whoops!
Crash into the HardFault_Handler.
Please file an issue with the contents of your CIRCUITPY drive at
https://github.com/adafruit/circuitpython/issues

Description

When adding #define CIRCUITPY_DISPLAY_LIMIT (4) to mpconfigboard.h, recompiling, and using resulting UF2, CircuitPython crashes when trying to create a fourth displayio.I2CDisplay display bus. Tested on adafruit_qtpy_rp2040 and adafruit_qtpy_esp32s3.

Additional information

I've been poking around shared-module/displayio/__init__.c and I don't see anything obviously wrong. Perhaps the loop for (uint8_t j = i + 1; j < CIRCUITPY_DISPLAY_LIMIT; j++) { in reset_displays()? I don't understand it yet but it seems like it could make trouble. :)

tannewt commented 2 years ago

2+ displays really isn't supported so I'm not sure what could be the issue. The next step I'd take is to use a JLink on the RP2040 to determine the backtrace of where it hangs. On the S3 you could do a debug build and see what backtrace is output to the UART.

furbrain commented 1 year ago

I think this may be linked to #2204 - I would expect it to crash when you add a fourth display - I've put a PR in to fix this

dhalbert commented 1 year ago

Probably fixed by #7983. needs re-test.