Problem compiling lvgl with custom micropython

Hi guys!
So I have passed the past days trying to compile a custom version of Micropython + lvgl
This one
So I am able to use in my project that already uses lvgl.

I have tried to compile it by myself by making changes to the necessary files with no success, then I tried the approach mentioned in ESP32 Micropython build errors... LOTS and ERROR lv_bindings/driver/generic/modlvindev.c. I successfully merged but got the same errors that I was having using the first method when trying to compile.

The errors are the following portnativeglue_error.txt (73.8 KB)

They happen when portnativeglue starts to be processed. Any idea of what is happening? Is my setup broken? Is it a code problem? Starting to be a bit desperate right now :weary:

I have setup esp-idf using the , anyone done that before?

Any help is highly appreciated! Thank you in advance.

Hi @Tiago_Almeida!
You can use lv_micropython as a reference.
You can compare it to upstream micropython to get an idea of what needs to be changed in a micropython fork to support lvgl.

Another option is to take lv_micropython as a base an merge to it the features that are missing for you (what are they, btw?)

1 Like

Hi @amirgon !
I have already tried the approaches you suggest I think, last try I cloned lv_micropython, then merged it with . In the end I got the errors reported in the txt.

I am trying to have OTA updates via MQTT using tls. And also MQTT communication with tls. For that I need the changes that are made in that repo ( (They are in the beggining of the README file . That is why I need that micropython version.

I will try once again and check if I am not missing anything.

Thank you for the help!

I suspect there is something wrong with portnativeglue on tve fork.
It defines some types that should be defined by system libraries. For example:

typedef int size_t;
typedef int int32_t;
typedef unsigned int uint32_t;

When integrating lvgl into Micropython, we add an include in mpconfigport.h to lv_gc.h. This is needed in order to integrate lvgl gc-roots into micropython’s MICROPY_PORT_ROOT_POINTERS.
However, it also means that mpconfigport.h now includes some headers that come from lvgl, such as lv_gc.h, lv_mem.h etc.
These headers assume the existence and uses standard types such as int16_t, size_t etc.
However, it looks like portnativeglue on tve fork both includes mpconfigport.h and re-defines these types and this is what causes the errors you see.

To solve this, either remove #include "mpconfigport.h" or include standard C library headers instead of these redefinitions in portnativeglue of tve fork.
Did you try writing to @tve about this?

I’m planning at some point to align lv_micropython to upstream Micropython.
If tve’s changes are integrated into Micropython upstream by the time I do that, or if you can already use an up to date Micropython instead of tve’s port, that could solve your problem.

1 Like

@Tiago_Almeida to pull in LVGL on top of my fork you need two things:

I created a tve-lvgl fork that compiles and boots, but I haven’t tested LVGL specifically, I need to wire-up a display first…

This is awesome!! Thank you so much @tve ! I will try it and will give feedback. I really really appreciate you taking the time for helping!
@amirgon Thank you so much too! I really appreciate your tips and calling out for tve !
Hands to work now!

So I cloned, as the lv_bindings submodule was not downloaded ( I guess the link used in the .gitmodules is deprecated.) I added it myself (used

This time a got a lot less errors but still got this:
errors.txt (4.3 KB)

Any idea of what to change to fix it?

I am using esp-idf v4.0.1 (see the exact hash in the ports/esp32/Makefile) and xtensa-esp32-elf-8.2.0
I believe it also works with esp-idf v3.2.3 and xtensa-esp32-elf-5.2.0/

1 Like

Heads-up that there is a problem still in keeping lv “running”. The timer in lvesp32 that schedules lv_task_handler isn’t working, and if it were it would run every millisecond, which I don’t think is practical. I’m looking into it: What calls for xpt2046?

Thank you @tve ! It worked.
It compiled but with this micropython version and lv_bindings I get
File “”, line 125, in init
RuntimeError: Not enough DMA-able memory to allocate display buffer

I had this problem before, I changed factor to 8 and it worked. My code was running fine. Now I have already tried a factor of 8 and 16 and I am still getting the error.

I guess this new version of lvgl is using more DMA_RAM ? I was still using version 6. Any clue @amirgon ?

It worked with fct=16 for me…

If you’re using this without SPIRAM we have to do a bit of work to reduce the amount of memory that MP allocates to itself so there’s something left in the esp-idf heap for LVGL and the networking stack… Probably use a 0.8 factor in the esp32 main.c…

1 Like

Yup, until now I was using the version without SPIRAM. I had this problem before Not enough DMA-able memory to allocate display buffer. But changing factor worked. Now it’s not working, even if I don’t use wifi etc.
Last case scenario I will use the M5stack fire (esp32 with SPIRAM) that I ordered for the case I got this problem again, but I would like to use the normal version if possible.
But since I don’t even have the mqboard yet I don’t how feasible it would be in the future to use everything just with the normal esp32.

About the problem with the lv_task_handler I haven’t got to that point yet and don’t really know the lvgl internals. But I am sure that somebody can help us. Maybe @amirgon or @kisvegabor if they have the time.

This is what I run (you would have to adjust the SPI pins):

import lvgl as lv

class Driver:
    def __init__(self):

    def init_esp32(self):
        import lvesp32

        # Import ILI9341 driver and initialized it
        from ili9341 import ili9341

        self.disp = ili9341(spihost=2, miso=19, mosi=23, clk=18, cs=12, dc=14,
                rst=13, power=-1, backlight=-1, mhz=10, factor=16, hybrid=True)

    def init(self):
        return self

def main():
    drv = Driver().init()

    scr = lv.obj()
    btn = lv.btn(scr)
    btn.align(lv.scr_act(), lv.ALIGN.CENTER, 0, 0)
    label = lv.label(btn)

if __name__ == "__main__":

I was setting the factor wrong :man_facepalming: nvm. With factor 16 your example runs fine. But when I try to add the network stack I get this… I haven’t change anything else yet.

W (2739) wifi: malloc buffer fail
E (2739) wifi: Expected to init 10 rx buffer, actual is 6
Traceback (most recent call last):
File “”, line 56, in
File “”, line 52, in main
RuntimeError: Wifi Unknown Error 0x0101

Btw when you say setting a 0.8 factor in the esp32 main.c do you mean setting
mp_task_heap = malloc(mp_task_heap_size); to mp_task_heap ==malloc(0.8*mp_task_heap_size); ? For future reference if needed.

Yup, except that’s all integer stuff, so no literal 0.8… You could also subtract 16KB or thereabouts.

1 Like

Tried, got the same wifi malloc buffer fail error.
Will try the SPIRAM version now.

@tve have you successfully flashed a version with PSRAM? On my m5stack fire (16mb flash + 520kbRAM + 4MB PSRAM) I am getting:
E (830) esp_image: Image length 2108848 doesn’t fit in partition length 2097152
E (830) boot: Factory app partition is not bootable
E (832) boot: No bootable app partitions in the partition table
Is this normal? I’ll try to compile using espidf v3 instead of v4. Anything else I can do?
Sorry for all the trouble!

Ouch. That says that the flash partition for the app is too small. So you need to modify partitions.csv to give it more space. That’s a pain.

Oh god. Why can’t one just be happy and have everything working at the first try! :roll_eyes: