Maintainer wanted

Hi guys,

@amirgon just let me know that he can’t continue the maintenance of the the MicroPython biding due to other engagements.

So we are looking for a new maintainer for the MicroPython binding. In the practice it’d mainly mean discussing how to handle the upcoming changes of LVGL in the MicroPython binding and also updating the binding accordingly. Amir said that he will be available for discussions but can’t participate in the development. So we are not alone :slight_smile:

I wonder if someone from the community is interested in continuing the amazing work of Amir.

I aslo would like to say big thank you to Amir for the great work so far! It really made a big difference! :clap: :100:

2 Likes

For what it’s worth, the MicroPython community are very keen to expand LVGL support and there are some key members that would be willing to support anyone that took on this role!

I’d also like to extend that thanks to @amirgon for all his efforts. :smiling_face:

2 Likes

Thank you, Matt!

What do you think, would it be possible to add the binding into the upstream MicroPython library as a submodule?

@kisvegabor I’ve started work making lvgl work as an external C module on standard / upstream micropython here: Integration as external c module with unmodified micropython. by andrewleech · Pull Request #242 · lvgl/lv_binding_micropython · GitHub

This was done before v1.20 was released and requires updating (time pending) to work again, and also needed esp32 support fixed (I couldn’t figure out IDF issues here, don’t know how to solve).

Once that was done in theory lvgl could be submitted as a library for upstream micropython, with a couple of board profiles configured to use it the inclusion could be compelling.

If lvgl could be integrated into the existing framebuf subsystem I think this would be much smoother to roll out to more boards with existing graphics drivers, I haven’t figured out how likely / possible this would be.

If we manage to have someone maintaining the project, I would like to collaborate by setting up a continuous integration system with a variety of hardware.
I´ve accumulated a big trove of different MCUs and displays over the years.
I could help with:

  • selecting the most relevant combinations of hardware
  • physically build them into a testing plaform
  • integrate with github C.I.
  • publish binaries for each tested combinations

then maintain this test platform by integrating new displays or MCUs.

1 Like

All these sound amazing!

Next week a new employee will join to SquareLine LLC (it’s our drag and drop UI editor), and as SquareLine also uses the MicroPython binding under the hood, one of the responsibilities of him will be to maintain the binding.

Once he is on boarded I’ll show him your comments here and we can figure out how to proceed.

1 Like

After they get settled, I’d be happy having a call with the new hire if that’ll help? I can talk about the MicroPython side - though I’m less familiar with details around LVGL.

I suspect @andrewleech would be open to this too (Andrew and I work together).

Fantastic, thank you! I’ll let you know when we are settled. I think we will need a few weeks for that.

I have spent a great deal of time learning pycparser and how it works. I would be able to help out with the code generator end of things if help is needed. As @kisvegabor knows I also wrote the document build system and there are portions of that build system that might help with code generation for the MicroPython binding.

If memory serves the biggest issue is how QSTR is handled currently in MicroPython. Because of the very large API that LVGL has there is a significant impact on performance because of the QSTR’s. I believe there was a pull request made to MicroPython that mostly corrects the problem but it never got merged. I have not check on it for a while and that may have changed. But unless that code gets added to MicroPython the binding is not going to be able to be dded as a submodule.

We have this PR in LVGL which can fully change how we handle bindings: feat(obj): add unified obj property set/get API by XuNeo · Pull Request #4579 · lvgl/lvgl · GitHub

With this the huge widget API can be managed in much smarter and elegant way.

I am not understanding what the purpose of that PR is.

Th issue with QSTR in MicroPython is due to how the python interpreter works. Everything in Python is an object and an object has to have a mechanism built into it to identify attributes, methods, functions, etc… The mechanism used to do this on the interpreter side is what is called a dictionary or __dict__. Any function, method, class, attribute that has a cross to the underlying C code needs to have a pointer/mapping of a name to the C function. This is where the QSTR comes in.

Because of the sheer number of mappings that would need to exist for LVGL the mechanism that has been built into MicroPython that handles these lookups causes a serious performance problem. That is because of the sheer number of mappings that have to exist for LVGL.

Now that the current system is done this way but imagine a flat file where each line is a name to function mapping and every single time some something gets accessed that flat file needs to be iterated over to locate what is needed. Now think about how slow that would make things if you have 10000 entries in that flat file. This issue was addressed in a PR made to MicroPython that never got merged. I believe this to be the single largest reason as to why the current way the binding is handled is so that the code can be added to address the problems due to the fix not being merged upstream.

I have not looked into this in some time and it may be no longer relevant

I don’t know the details of QSTR-s, so I’m not sure if it really helps. My gut feeling was that if we have a single function to replace hundreds of functions, somehow it can hep to make the binding smaller as well. But we will see later.

Are you thinking enumerations to identify the attribute to get or set??

Only issue there is you still have to have the QSTR for the enumeration name. So it really isn’t going to make a difference. The API wouldn’t really be smaller either. Instead of using functions they are being replaced with some other marker to identify what is being done.

I’m very glad to hear someone is going to get paid to maintain the bindings. @amirgon, thank you very much for your fantastic work!

In making lv_binding_micropython compile into unmodified Micropython as a USER_C_MODULE, it looks like @andrewleech’s work is a great place to start. I don’t think he forked lv_bindings_micropython, so you have to go to the cmodules folder on his lvgl_mpy_example repository and find lv_binding_micropython, which is GitHub - lvgl/lv_binding_micropython at f4df5db0f7705a1f54f186aecf2868b1110c2cf9. One of the things he did was move LVGL out of micropython/extmod/extmod.mk, which is obviously a modification to Micropython, to a new file micropython.mk in the lv_bindings root. gen_mpy.py runs from there rather than from a file modified in Micropython. I’m not sure why he created new board definition folders instead of passing USER_C_MODULES as a command-line parameter to make, but it looks like it would be easy to do that, too.

Another issue moving forward with lv_bindings_micropython is the way display and touch drivers are handled. For instance, for the ESP32 port, Micropython moved to using ESP-IDF v5.x, while the drivers in lv_binding_micropython are written for v4.x. Due to that mismatch, the only way I can get lv_micropython (the fork, not the binding) to compile for an esp32-s3 is by removing any lines in the build files that require esp-idf. Rather than porting the old drivers to the new framework, I recommend moving away from including drivers in the binding, and instead use drivers that are are also themselves Micropython modules. For example, lcd_binding_micropython compiles as a USER_C_MODULE, so it could be compiled in simply using another command-line parameter to make. I understand lcd_binding_micropython doesn’t provide an lv.disp_t object, but it seems creating a wrapper in python to provide an lv.disp would be trivial, and if not, forking the repository and modifying the C code may be the answer. Also, since the goal is to have the binding function as a USER_C_MODULE, compiling it into Circuitpython may become an option. (Side note: Circuitpython compatibilty would be huge!) Circuitpython’s DisplayIO could provide the drivers, again possibly with a wrapper either in python or C. (Adafruit is currently putting a lot of time and effort into display hardware and drivers, including the recently released ESP32-S3 based Qualia board.) I know nothing about Arduino, but the drivers in TFT_eSPI may be useful, possibly as a fork if they won’t work as is.

I may be oversimplifying things. I understand there are huge speed advantages to using DMA and keeping display rendering completely in C, but the suggestions above would at least let us use new hardware, even if display performance was slow, until LVGL specific drivers that load as USER_C_MODULES could be written. As it is now, as far as I know, you can’t even compile lv_micropython for an ESP32-S3 without modifying the bindings.

Hi @bdbarnett,

Thank you for joining! :slightly_smiling_face:

Our new colleague started to familiarize himself with MicroPython. We still need some time to make something useful but we are on the right track now!

FYI, in v9 (to be released by the end of 2023) we add drivers right into LVGL. See here. Now we have mainly high end drivers (SDL, Linux frame buffer, etc) but we will add display controller drivers with a simple interface to peripheries too. TFT_eSPI is already there as well. And once they are in LVGL, binding will be generated for them as well.

This is possible to do using the viper code emitter. The drivers were originally made before that was available so any reordering of the frame buffer that needed to be done was done in C code because of the speed it gave. Most of the drivers should be able to be easily made to run using only python code.

I have used the code generator script to add the LCD components that is built into ESPIDF. It does require some tweaks to be made to the generation script but nothing too crazy to get it running.

I recommend using the LCD component in the ESPIDF instead of writing to pin registers using viper code. I do not however recommend using the 3rd party components for the display drivers due to them needing to be added at compile time instead of runtime.

The current state of the display drivers in MicroPython could use an overhaul so the code for irrelevant drivers doesn’t get loaded and also to come up with a common API for all of the drivers. This should not be too difficult to do. I did at one point in time locate a driver set for the STM boards and I have seen a few drivers for RPI. These can be used as a guide.

I know that there was talk of writing display drivers in C and while they could technically be used the idea behind MicroPython is runtime support for devices, not compile time. So IDK if that would work if specific displays have to be picked at compile time. Where as with MicroPython the display driver that gets used is chosen at runtime. It is not that hard to write drivers for MicroPython for the ESP32. IDK how hard it would be to expose the needed C functions for RPI and for STM or any of the other boards that MicroPython supports.

It would be a nice thing to be able to select the display and also the MCU and be able to have the proper code added when using SquareLine Studio or when using the online javascript port that is used for the examples.

Just a heads-up that improving QSTR performance is on the agenda - see:

This PR is assigned to the next MicroPython release (v1.22) so it’s high on the list to be resolved. Note that 10758 replaces @amirgon’s 6896.

1 Like

Thanks @matt.trentini, that’s great news!

@kdschlosser Thanks for the information. I realized after I posted my last post on this topic that I was hijacking the thread. Will you and anyone else interested in display drivers please see this post: Micropython Display Drivers? Thank you!

1 Like

Hey,

We have a PR for testing the MicroPython binding in LVGL. We are not experts on MicroPython so it would amazing if could take look and tell if we shall test something else too, or should do something differently.

In the end the the MicroPython examples will be moved to lv_binding_micropython from lvgl and we will run only these tests in the CI of LVGL.

I see the push in feat/multi-instance. Is this what you need tested? I can download, compile and test tonight. What does “multi-instance” refer to?