Trying to build esp8266 lv_micropython image

Hello guys, I was trying to build an esp8266 image from lv_micropython
and I got this error :neutral_face:
after running the command make from ports/esp8266:
can you help me, please? :pray:

Use make V=1 or set BUILD_VERBOSE in your environment to increase build verbosity.
CC ../../lib/lv_bindings/lvgl/src/lv_core/lv_obj.c
In file included from ../../lib/lv_bindings/lvgl/src/lv_core/lv_obj.c:26:0:
../../lib/lv_bindings/lvgl/src/lv_core/lv_obj.c: In function 'lv_init':
../../py/mpstate.h:260:40: error: 'mp_state_vm_t' has no member named '_lv_disp_ll'
 #define MP_STATE_VM(x) (mp_state_ctx.vm.x)
                                        ^
./mpconfigport.h:200:23: note: in expansion of macro 'MP_STATE_VM'
 #define MP_STATE_PORT MP_STATE_VM
                       ^
../../lib/lv_bindings/lvgl/src/lv_core/../../../lv_conf.h:95:25: note: in expansion of macro 'MP_STATE_PORT'
 #  define LV_GC_ROOT(x) MP_STATE_PORT(x)
                         ^
../../lib/lv_bindings/lvgl/src/lv_core/lv_obj.c:107:17: note: in expansion of macro 'LV_GC_ROOT'
     lv_ll_init(&LV_GC_ROOT(_lv_disp_ll), sizeof(lv_disp_t));
                 ^
../../py/mpstate.h:260:40: error: 'mp_state_vm_t' has no member named '_lv_indev_ll'
 #define MP_STATE_VM(x) (mp_state_ctx.vm.x)
                                        ^
./mpconfigport.h:200:23: note: in expansion of macro 'MP_STATE_VM'
 #define MP_STATE_PORT MP_STATE_VM
                       ^
../../lib/lv_bindings/lvgl/src/lv_core/../../../lv_conf.h:95:25: note: in expansion of macro 'MP_STATE_PORT'
 #  define LV_GC_ROOT(x) MP_STATE_PORT(x)
                         ^
../../lib/lv_bindings/lvgl/src/lv_core/lv_obj.c:108:17: note: in expansion of macro 'LV_GC_ROOT'
     lv_ll_init(&LV_GC_ROOT(_lv_indev_ll), sizeof(lv_indev_t));
                 ^
In file included from ../../lib/lv_bindings/lvgl/src/lv_core/lv_obj.h:28:0,
                 from ../../lib/lv_bindings/lvgl/src/lv_core/lv_obj.c:9:
../../lib/lv_bindings/lvgl/src/lv_core/lv_obj.c: In function 'lv_obj_get_disp':
../../py/mpstate.h:260:40: error: 'mp_state_vm_t' has no member named '_lv_disp_ll'
 #define MP_STATE_VM(x) (mp_state_ctx.vm.x)
                                        ^
../../lib/lv_bindings/lvgl/src/lv_core/../lv_misc/lv_ll.h:152:53: note: in definition of macro 'LV_LL_READ'
 #define LV_LL_READ(list, i) for(i = lv_ll_get_head(&list); i != NULL; i = lv_ll_get_next(&list, i))
                                                     ^
./mpconfigport.h:200:23: note: in expansion of macro 'MP_STATE_VM'
 #define MP_STATE_PORT MP_STATE_VM
                       ^
../../lib/lv_bindings/lvgl/src/lv_core/../../../lv_conf.h:95:25: note: in expansion of macro 'MP_STATE_PORT'
 #  define LV_GC_ROOT(x) MP_STATE_PORT(x)
                         ^
../../lib/lv_bindings/lvgl/src/lv_core/lv_obj.c:1506:16: note: in expansion of macro 'LV_GC_ROOT'
     LV_LL_READ(LV_GC_ROOT(_lv_disp_ll), d)
                ^
../../py/mpstate.h:260:40: error: 'mp_state_vm_t' has no member named '_lv_disp_ll'
 #define MP_STATE_VM(x) (mp_state_ctx.vm.x)
                                        ^
../../lib/lv_bindings/lvgl/src/lv_core/../lv_misc/lv_ll.h:152:91: note: in definition of macro 'LV_LL_READ'
 #define LV_LL_READ(list, i) for(i = lv_ll_get_head(&list); i != NULL; i = lv_ll_get_next(&list, i))
                                                                                           ^
./mpconfigport.h:200:23: note: in expansion of macro 'MP_STATE_VM'
 #define MP_STATE_PORT MP_STATE_VM
                       ^
../../lib/lv_bindings/lvgl/src/lv_core/../../../lv_conf.h:95:25: note: in expansion of macro 'MP_STATE_PORT'
 #  define LV_GC_ROOT(x) MP_STATE_PORT(x)
                         ^
../../lib/lv_bindings/lvgl/src/lv_core/lv_obj.c:1506:16: note: in expansion of macro 'LV_GC_ROOT'
     LV_LL_READ(LV_GC_ROOT(_lv_disp_ll), d)
                ^
make: *** [build/lib/lv_bindings/lvgl/src/lv_core/lv_obj.o] Error 1

Hi @th3happybit!

I’m happy to hear your are interested in lv_micropython! I’ll try to help you out.

Currently tested lv_micropython ports are ESP32, unix, javascript and stm32 (to some extent).
You are the first one to try it on ESP8266! But don’t worry, it should be quite simple to support the ESP8266 port.

As an example, let’s examine ESP32 port of lv_micropython code vs. upstream micropython.

The following files changed:

  • ports/esp32/.gitignore
  • ports/esp32/Makefile
  • ports/esp32/boards/sdkconfig.spiram
  • ports/esp32/mpconfigport.h
  • ports/esp32/partitions.csv

The interesting changes are on Makefile and mpconfigport.h, have a look at the changes on these files.

  • Makefile: You probably don’t need the “esp-idf generated module”, it’s not required for lvgl, so you can ignore ESPIDFMOD_* stuff.
    You do need to add some sources to LIB_SRC_C. These are your Display and Input drivers. On ESP32, for example, modILI9341.c is the driver for ILI9341 display.

  • mpconfigport.h: This is where you register your drivers as Micropython modules. The other important piece is related to gc - You need to add LitttlevGL root pointers to Micropython Garbage Collector roots (by adding it to MICROPY_PORT_ROOT_POINTERS).

Please give it a try and let me know how it goes.

If all goes well and working for you - we will be happy to add it to lv_micropython, so send us a PR!

1 Like

Hey @amirgon, I tried what you said and I’m facing a problem when I make the firmware image it’s overflowing the dram0_0_seg, dram0_0_seg, iram1_0_seg, and irom0_0_seg, and I found a way to solve it by editing the size of every segment but I need to calculate the exact amount of size I need to add so I can make the image without a problems, so do you have any idea of how to do that?

The error:

LINK build/firmware.elf
xtensa-lx106-elf-ld: build/firmware.elf section `.irom0.text' will not fit in region `irom0_0_seg'
xtensa-lx106-elf-ld: build/firmware.elf section `.text' will not fit in region `iram1_0_seg'
xtensa-lx106-elf-ld: address 0x400029a0 of build/firmware.elf section `.bss' is not within region `dram0_0_seg'
xtensa-lx106-elf-ld: address 0x400029a0 of build/firmware.elf section `.bss' is not within region `dram0_0_seg'
xtensa-lx106-elf-ld: region `iram1_0_seg' overflowed by 322716 bytes
xtensa-lx106-elf-ld: region `irom0_0_seg' overflowed by 109328 bytes
make: *** [build/firmware.elf] Error 1

the file we should edit to change the segments size:

ubuntu@ip-172-31-41-185:~/lv_micropython/ports/esp8266$ cat esp8266.ld
/* GNU linker script for ESP8266 */

MEMORY
{
dport0_0_seg : org = 0x3ff00000, len = 0x10
dram0_0_seg : org = 0x3ffe8000, len = 0x14000
iram1_0_seg : org = 0x40100000, len = 0x8000
irom0_0_seg : org = 0x40209000, len = 0x8f000
}

/* define common sections and symbols */
INCLUDE esp8266_common.ld

You can use xtensa-lx106-elf-size to extract section sizes from your elf files, and edit the linker script accordingly.

But first of all, does ESP8266 have enough RAM/ROM to accomodate Micropython+lvgl?
If you sum up the iram and irom segments, does it fit?

If not, or if it’s marginal, I would suggest configuring both Micropython and LittlevGL to build only what you really need.

By default, lots of stuff are built and linked into your firmware image.
For example, lvgl built-in fonts, all lvgl objects, styles, animation etc.
Have a look at lv_conf.h and disable all the features you don’t really need.
On Micropython you can edit mpconfigport.h and disable many micropython features you don’t need.

If you sum it up, it should fit into the total available ram/rom. Then you can try changing section sizes in the linker script if you need to.

1 Like
CC build/lvgl_gui/lvgl.pp.o
In file included from /home/haanhua/esp/ESP8266_RTOS_SDK/components/lvgl_gui/pycparser/utils/fake_libc_include/stdint.h:2:0,
                 from /home/haanhua/esp/ESP8266_RTOS_SDK/components/lvgl_gui/lvgl/src/lv_misc/../../../lv_conf.h:16,
                 from /home/haanhua/esp/ESP8266_RTOS_SDK/components/lvgl_gui/lvgl/src/lv_misc/lv_log.h:19,
                 from /home/haanhua/esp/ESP8266_RTOS_SDK/components/lvgl_gui/lvgl/lvgl.h:19:
/home/haanhua/esp/ESP8266_RTOS_SDK/components/lvgl_gui/pycparser/utils/fake_libc_include/_fake_typedefs.h:5:13: error: conflicting types for '__builtin_va_list'
cc1: note: previous declaration of '__builtin_va_list' was here
In file included from /home/haanhua/esp/ESP8266_RTOS_SDK/components/lvgl_gui/lvgl/src/lv_hal/lv_hal_disp.h:22:0,
                 from /home/haanhua/esp/ESP8266_RTOS_SDK/components/lvgl_gui/lvgl/src/lv_hal/lv_hal.h:16,
                 from /home/haanhua/esp/ESP8266_RTOS_SDK/components/lvgl_gui/lvgl/lvgl.h:24:
/home/haanhua/esp/ESP8266_RTOS_SDK/components/lvgl_gui/lvgl/src/lv_hal/../lv_misc/lv_area.h: In function 'lv_area_copy':
/home/haanhua/esp/ESP8266_RTOS_SDK/components/lvgl_gui/lvgl/src/lv_hal/../lv_misc/lv_area.h:75:5: error: implicit declaration of function 'memcpy' [-Werror=implicit-function-declaration]
     memcpy(dest, src, sizeof(lv_area_t));
     ^
/home/haanhua/esp/ESP8266_RTOS_SDK/components/lvgl_gui/lvgl/src/lv_hal/../lv_misc/lv_area.h:75:5: warning: incompatible implicit declaration of built-in function 'memcpy'
/home/haanhua/esp/ESP8266_RTOS_SDK/components/lvgl_gui/lvgl/src/lv_hal/../lv_misc/lv_area.h:75:5: note: include '<string.h>' or provide a declaration of 'memcpy'
cc1: some warnings being treated as errors
/home/haanhua/esp/ESP8266_RTOS_SDK/make/component_wrapper.mk:285: recipe for target 'lvgl.pp.o' failed
make[1]: *** [lvgl.pp.o] Error 1
/home/haanhua/esp/ESP8266_RTOS_SDK/make/project.mk:517: recipe for target 'component-lvgl_gui-build' failed
make: *** [component-lvgl_gui-build] Error 2

Can anyone tell me what’s going on here?

Hi @hanhua,
What are you trying to build?
From the log you sent, this doesn’t look like lv_micropython project. Did you port it to your project? Or did you change lv_micropython? Could you share your changes?

I ported micropython and lvgl to ESP8266_RTOS_SDK3.2 and it worked fine (my code was messy), but it so when I bound lvgl to micropython.

             ^~~~

lv_mpy.c: In function ‘mp_lv_obj_t_attr’:
lv_mpy.c:4191:64: error: lvalue required as unary ‘&’ operand
#define mp_read_byref_lv_style_t(field) mp_read_ptr_lv_style_t(&field)
^
lv_mpy.c:4397:45: note: in expansion of macro ‘mp_read_byref_lv_style_t’
case MP_QSTR_style_p: dest[0] = mp_read_byref_lv_style_t((void*)data->style_p); break; // converting from lv_style_t;
^~~~~~~~~~~~~~~~~~~~~~~~
lv_mpy.c:4433:17: error: cannot convert to a pointer type
case MP_QSTR_style_p: data->style_p = (void*)mp_write_lv_style_t(dest[1]); break; // converting to lv_style_t;
^~~~
lv_mpy.c: In function ‘mp_lv_obj_del’:
lv_mpy.c:4371:39: error: incompatible types when initializing type ‘lv_obj_t * {aka struct _lv_obj_t *}’ using type ‘lv_obj_t {aka struct _lv_obj_t}’
#define mp_write_lv_obj_t(struct_obj) *mp_write_ptr_lv_obj_t(struct_obj)
^
lv_mpy.c:4497:21: note: in expansion of macro ‘mp_write_lv_obj_t’
lv_obj_t *obj = mp_write_lv_obj_t(mp_args[0]);

I suggest using a public medium where other people can participate and collaborate, and not a private email.
This is an open source public project - our goal is to encourage many people to participate.

Could you upload your project to GitHub?
From your logs, it seems that your problems are related to the Makefile, include paths, directory structure, possibly the tool-chain you are using, etc.

Instead of creating your own project, why don’t you try forking lv_micropython and implementing the missing pieces for ESP8266?
I think @th3happybit already did that and got to the point where it all builds, but he had some issue with section sizes.

@th3happybit - Could you share your code (a link to github) and show us how far you got?

@amirgon
In China, GitHub uploads are very slow…

I use ESP8266_RTOS_SDK because it has 72K of free memory…

I’ll try to upload it.