adafruit / Adafruit_Learning_System_Guides

Programs and scripts to display "inline" in Adafruit Learning System guides

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

DVI_Hello_World - Out of Memory

mikeysklar opened this issue · comments

The stock example code for the RP2040 DVI - CircuitPython dvi-demo or DVI_Hello_World is running out of memory. Adjusting the color_depth to 1 which also requires boosting the resolution still results in an out of memory although the code gets another dozen lines further.

Forum user @Gregg28 pointed this out.

I reproduced this errors a Feather RP2040 DVI CP9.0.0-b2:

errors on stock example:

Adafruit CircuitPython 9.0.0-beta.2 on 2024-02-20; Adafruit Feather RP2040 DVI with rp2040
>>>
soft reboot

Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
Traceback (most recent call last):
  File "code.py", line 33, in <module>
MemoryError: memory allocation failed, allocating 88332 bytes

Code done running.

Adjusting resolution and color depth errors:

MemoryError: memory allocation failed, allocating 76800 bytes

Code done running.

Press any key to enter the REPL. Use CTRL-D to reload.
soft reboot

Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
Traceback (most recent call last):
  File "code.py", line 45, in <module>
MemoryError: memory allocation failed, allocating 96000 bytes

I've got my Feather DVI out and will attempt to recreate this and dig a bit further into it today.

commented

also testing- had 8.2.10 running and haven't run into any problems (let it run for about 45 minutes). running 9 beta2, i ran into the memory allocation issue on first run, hit ctrl+d and it started running:

Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
Traceback (most recent call last):
  File "code.py", line 33, in <module>
MemoryError: memory allocation failed, allocating 88332 bytes

Code done running.

Press any key to enter the REPL. Use CTRL-D to reload.
soft reboot

Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:

did a hard reset and same behavior, first run failed with memory error, ctrl+d had it run successfully. going to add a try/except and see if that can bypass the issue

commented

adding:

# check for DVI Feather
if 'CKP' in dir(board):
    try:
        fb = picodvi.Framebuffer(320, 240,
            clk_dp=board.CKP, clk_dn=board.CKN,
            red_dp=board.D0P, red_dn=board.D0N,
            green_dp=board.D1P, green_dn=board.D1N,
            blue_dp=board.D2P, blue_dn=board.D2N,
            color_depth=8)
    except MemoryError as e:
        print("Error:\n", str(e))
        time.sleep(5)
        supervisor.reload()
        
# otherwise assume Pico
else:
    try:
        fb = picodvi.Framebuffer(320, 240,
            clk_dp=board.GP12, clk_dn=board.GP13,
            red_dp=board.GP10, red_dn=board.GP11,
            green_dp=board.GP8, green_dn=board.GP9,
            blue_dp=board.GP6, blue_dn=board.GP7,
            color_depth=8)
    except MemoryError as e:
        print("Error:\n", str(e))
        time.sleep(5)
        supervisor.reload()

seems to get around it. i'll do a PR and @FoamyGuy assuming this should be an issue on CP?

@BlitzCityDIY oh, that is very odd. Yeah, lets make an issue on the core repo for it that.

The fact that it runs out of memory before it has done hardly anything seems weird to me, as does the behavior changing when you run it a second time via either ctrl-c / d or with supervisor.reload() like you added. I would have expected the circuitpython VM to be in the same state as the 1st time. The difference does suggest a potential issue in the core for this device I think.

Ahhhh I think I maybe understand what is going on here.

I think maybe this code doesn't need to (and probably shouldn't) initialize the picodvi framebuffer because that is done inside the core in the board init: https://github.com/adafruit/circuitpython/blob/main/ports/raspberrypi/boards/adafruit_feather_rp2040_dvi/board.c#L34.

The device doesn't have enough RAM to initialize two instances of the display buffer. Since the core board init is automatically initializing one it's consuming some RAM when it does so.

Then code.py begins, calls release_displays() which I guess must not release 100% of the RAM that was used and initializes the display frame buffer for what would be the 2nd time but it fails with the Memory error.

Since code.py called displayio.release_displays() and since that keeps in effect across the soft reboots it means that when the code.py launches after the soft reboot there is no display initialized so code.py initializing it for the "1st" time and it succeeds.

This device does have board.DISPLAY which looks to get initialized in the board init and I think it should work if the code.py just starts using that without initializing it. I'll give this a try now.

commented

ohhh interesting! that makes sense

I've found this issue with the new memory allocator in CP and have made a PR to fix it. Next time, please file a core issue before changing the example code because it could just be a CP bug.