Lvgl and network error with micropython on ESP32 in v7, ok in v6

Description

LVGL and network error occurs when running micorpython on ESP32 and using lvgl V7. Works in V6.

What MCU/Processor/Board and compiler are you using?

esp32 wroom 32

What do you experience?

When using lv_micropython ili9341 driver and network together an error occurs. Both ili9341 and network work on their own. This error occurs with lvgl.v7 but not with lvgl.v6.

The error appears to be due to a buffer allocation fail.

What do you expect?

No error.

Code to reproduce

import network
import lvgl as lv

lv.init()

from ili9341 import ili9341
disp = ili9341(rot=ili9341.MADCTL_MY, miso=16, mosi=17, clk=18, cs=19, dc=5, rst=21, mhz=80)

wlan = network.WLAN(network.STA_IF) # create station interface
wlan.active(True)       # activate the interface
scan = wlan.scan()             # scan for access points
print(scan)

And error message:

ILI9341 initialization completed
Enable backlight
Single buffer
I (3020) wifi:wifi driver task: 3ffdf800, prio:23, stack:3584, core=0
I (6171) wifi:wifi firmware version: 44aa95c
I (6171) wifi:config NVS flash: enabled
I (6171) wifi:config nano formating: disabled
I (6181) wifi:Init dynamic tx buffer num: 32
I (6181) wifi:Init data frame dynamic rx buffer num: 32
I (6181) wifi:Init management frame dynamic rx buffer num: 32
I (6191) wifi:Init management short buffer num: 32
I (6191) wifi:Init static rx buffer size: 1600
E (6201) wifi:malloc buffer fail
I (6201) wifi:Init static rx buffer num: 8
I (6201) wifi:Init dynamic rx buffer num: 32
E (6211) wifi:Expected to init 10 rx buffer, actual is 8
I (6211) wifi:Deinit lldesc rx mblock:0
I (6221) wifi:Deinit lldesc rx mblock:0
I (6221) wifi:Deinit lldesc rx mblock:0
I (6221) wifi:Deinit lldesc rx mblock:0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "t2.py", line 8, in <module>
RuntimeError: Wifi Unknown Error 0x0101

Commenting out ili9341 initialisation:

import network
import lvgl as lv

lv.init()

from ili9341 import ili9341
# disp = ili9341(rot=ili9341.MADCTL_MY, miso=16, mosi=17, clk=18, cs=19, dc=5, rst=21, mhz=80)

wlan = network.WLAN(network.STA_IF) # create station interface
wlan.active(True)       # activate the interface
scan = wlan.scan()             # scan for access points
print(scan)

produces no RuntimeError

I (1930) wifi:wifi driver task: 3ffd5f08, prio:23, stack:3584, core=0
I (3991) wifi:wifi firmware version: 44aa95c
I (3991) wifi:config NVS flash: enabled
I (3991) wifi:config nano formating: disabled
I (4001) wifi:Init dynamic tx buffer num: 32
I (4001) wifi:Init data frame dynamic rx buffer num: 32
I (4001) wifi:Init management frame dynamic rx buffer num: 32
I (4011) wifi:Init management short buffer num: 32
I (4011) wifi:Init static rx buffer size: 1600
I (4021) wifi:Init static rx buffer num: 10
I (4021) wifi:Init dynamic rx buffer num: 32
I (4121) wifi:mode : sta (80:7d:3a:ba:0f:6c)
[(b'spy ...

Screenshot and/or video

Hi @sornen

If memory allocation is the problem, you can try a few things:

  • Try to initialize network first, and only then initialize ili9341 (and see if now you get memory allocation error from ili9341)
  • Reduce the RAM needed for networking (I’m not sure about the details, probably some LWIP configuration macros)
  • Reduce the RAM consumed by ili9341 driver buffers: set higher values to factor argument of ili9341 (default is 4, you can try 8 or 16).
  • Try your code on ESP32 with SPI RAM such as wrover.
  • Reduce the RAM consumed by lvgl itself (@kisvegabor, @embeddedt - could you suggest what to change in lv_conf.h to reduce lvgl RAM alllocated on lv_init() ?)

This may be related:

Hi @amirgon
Thanks for your suggestions.

  • Running gc.mem_free before network.WLAN shows 98848 bytes of unallocated heap RAM.
  • With initializing network first I get the “Not enough DMA-able memory to allocate display buffer” error
  • Setting factor=8 on the ili9341 worked, but only if the nework.WLAN initialisation was before the ili9341.
  • I do not have a wrover ESP32 atm.
  • I notice in the ili9341 initialisation that the buf allocation from the heap use 38400 bytes each with factor=4. So with double_buffer=True this is near 76800, which is probably the reason for the memory allocation fail. I’ll play around with factors and double_buffer and see if this works out satisfactorily.

Edit: now found this discussion about dma able memory

As the above discussion the heap is not necessarily dma-able, which is what I am finding as both the network and ili9341 initialisation is hardly consuming any of the heap as shown by gc.mem_alloc().