8000 Update README.md · wired8/lv_binding_micropython@403b1a5 · GitHub
[go: up one dir, main page]

Skip to content

Commit 403b1a5

Browse files
authored
Update README.md
1 parent d343eb9 commit 403b1a5

File tree

1 file changed

+57
-22
lines changed

1 file changed

+57
-22
lines changed

README.md

Lines changed: 57 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,47 +9,50 @@ Please fork [lv_micropython](https://github.com/lvgl/lv_micropython) for a quick
99

1010
---
1111

12-
See also [Micropython + LittlevGL](https://blog.lvgl.io/2019-02-20/micropython-bindings) blog post. (LittlevGL is the previous name of LVGL.)
13-
For advanced features, see [Pure Micropython Display Driver](https://blog.lvgl.io/2019-08-05/micropython-pure-display-driver) blog post.
12+
See also [Micropython + LittlevGL](https://blog.lvgl.io/2019-02-20/micropython-bindings) blog post. (LittlevGL is the previous name of LVGL.)
13+
For advanced features, see [Pure Micropython Display Driver](https://blog.lvgl.io/2019-08-05/micropython-pure-display-driver) blog post.
1414
For questions and discussions - please use the forum: https://forum.lvgl.io/c/micropython
1515

1616
## Micropython
1717

18-
Micropython Binding for LVGL provides an automatically generated Micropython module with classes and functions that allow the user access much of the lvgl library.
19-
The module is generated automatically by the script [`gen_mpy.py`](https://github.com/lvgl/lv_binding_micropython/blob/master/micropython/gen_mpy.py).
20-
This script reads, preprocesses and parses lvgl header files, and generates a C file `lv_mpy.c` which defines the Micropython module (API) for accessing lvgl from Micropython.
21-
Micopython's build script (Makefile) should run `gen_mpy.py` automatically to generate and compile `lv_mpy.c`.
18+
Micropython Binding for LVGL provides an automatically generated Micropython module with classes and functions that allow the user access much of the LVGL library.
19+
The module is generated automatically by the script [`gen_mpy.py`](https://github.com/lvgl/lv_binding_micropython/blob/master/gen/gen_mpy.py).
20+
This script reads, preprocesses and parses LVGL header files, and generates a C file `lv_mpy.c` which defines the Micropython module (API) for accessing LVGL from Micropython.
21+
Micopython's build script (Makefile or CMake) should run `gen_mpy.py` automatically to generate and compile `lv_mpy.c`.
2222

23-
- If you would like to see an example of how a generated `lv_mpy.c` looks like, have a look at [`v_mpy_example.c`](https://raw.githubusercontent.com/lvgl/lv_binding_micropython/master/gen/lv_mpy_example.c). Note that its only exported (non static) symbol is `mp_module_lvgl` which should be registered in Micropython as a module.
24-
- An example project that builds Micropython + lvgl + lvgl-bindings: [`lv_mpy`](https://github.com/lvgl/lv_mpy)
23+
- If you would like to see an example of how a generated `lv_mpy.c` looks like, have a look at [`lv_mpy_example.c`](https://raw.githubusercontent.com/lvgl/lv_binding_micropython/master/gen/lv_mpy_example.c). Note that its only exported (non static) symbol is `mp_module_lvgl` which should be registered in Micropython as a module.
24+
- lv_binding_micropython is usually used as a git submodule of [lv_micropython](https://github.com/lvgl/lv_micropython) which builds Micropython + LVGL + lvgl-bindings, but can also be used on other forks of Micropython.
2525

26-
It's worth noting that the Mircopython Bindings module (`lv_mpy.c`) is dependant on lvgl configuration. lvgl is configured by `lv_conf.h` where different objects and features could be enabled or disabled. lvgl bindings are generated only for the enabled objects and features. Changing `lv_conf.h` requires re running `gen_mpy.py`, therfore it's useful to run it automatically in the build script.
26+
It's worth noting that the Mircopython Bindings module (`lv_mpy.c`) is dependant on LVGL configuration.
27+
LVGL is configured by `lv_conf.h` where different objects and features could be enabled or disabled. LVGL bindings are generated only for the enabled objects and features. Changing `lv_conf.h` requires re running `gen_mpy.py`, therfore it's useful to run it automatically in the build script, as done by lv_micropython.
2728

2829
### Memory Management
2930

30-
When lvgl is built as a Micropython library, it is configured to allocate memory using Micropython memory allocation functions and take advantage of Micropython *Garbage Collection* ("gc").
31-
This means that structs allocated for lvgl use don't need to be deallocated explicitly, gc takes care of that.
32-
For this to work correctly, lvgl is configured to use gc and to use Micropython's memory allocation functions, and also register all lvgl "root" global variables to Micropython's gc.
31+
When LVGL is built as a Micropython library, it is configured to allocate memory using Micropython memory allocation functions and take advantage of Micropython *Garbage Collection* ("gc").
32+
This means that structs allocated for LVGL use don't need to be deallocated explicitly, gc takes care of that.
33+
For this to work correctly, LVGL is configured to use gc and to use Micropython's memory allocation functions, and also register all LVGL "root" global variables to Micropython's gc.
3334

3435
From the user's perspective, structs can be created and will be collected by gc when they are no longer referenced.
35-
However, lvgl screen objects (`lv.obj` with no parent) are automatically assigned to default display, therefor not collected by gc even when no longer explicitly referenced.
36-
When you want to free a screen and all its decendants so gc could collect their memory, make sure you call `screen.delete()` when you no longer need it.
36+
However, LVGL screen objects (`lv.obj` with no parent) are automatically assigned to default display, therefor not collected by gc even when no longer explicitly referenced.
37+
When you want to free a screen and all its decendants so gc could collect their memory, make sure you call `screen.delete()` when you no longer need it.
38+
39+
Make sure you keep a reference to your display driver and input driver to prevent them from being collected.
3740

3841
### Concurrency
3942

40-
This implementation of Micropython Bindings to lvgl assumes that Micropython and lvgl are running **on a single thread** and **on the same thread** (or alternatively, running without multithreading at all).
43+
This implementation of Micropython Bindings to LVGL assumes that Micropython and LVGL are running **on a single thread** and **on the same thread** (or alternatively, running without multithreading at all).
4144
No synchronization means (locks, mutexes) are taken.
42-
However, asynchronous calls to lvgl still take place periodically for screen refresh and other lvgl tasks such as animation.
45+
However, asynchronous calls to LVGL still take place periodically for screen refresh and other LVGL tasks such as animation.
4346

4447
This is achieved by using the internal Micropython scheduler (that must be enabled), by calling `mp_sched_schedule`.
45-
`mp_sched_schedule` is called when screen needs to be refreshed. lvgl expects the function `lv_task_handler` to be called periodically (see [lvgl/README.md#porting](https://github.com/lvgl/lvgl/blob/6718decbb7b561b68e450203b83dff60ce3d802c/README.md#porting)). This is ususally handled in the display device driver.
46-
Here is [an example](https://github.com/lvgl/lv_binding_micropython/blob/77b0c9f2678b6fbd0950fbf27380052246841082/driver/SDL/modSDL.c#L23) of calling `lv_task_handler` with `mp_sched_schedule` for refreshing lvgl. [`mp_lv_task_handler`](https://github.com/lvgl/lv_binding_micropython/blob/77b0c9f2678b6fbd0950fbf27380052246841082/driver/SDL/modSDL.c#L7) is scheduled to run on the same thread Micropython is running, and it calls both `lv_task_handler` for lvgl task handling and `monitor_sdl_refr_core` for refreshing the display and handling mouse events.
48+
`mp_sched_schedule` is called when screen needs to be refreshed. LVGL expects the function `lv_task_handler` to be called periodically (see [lvgl/README.md#porting](https://github.com/lvgl/lvgl/blob/6718decbb7b561b68e450203b83dff60ce3d802c/README.md#porting)). This is ususally handled in the display device driver.
49+
Here is [an example](https://github.com/lvgl/lv_binding_micropython/blob/77b0c9f2678b6fbd0950fbf27380052246841082/driver/SDL/modSDL.c#L23) of calling `lv_task_handler` with `mp_sched_schedule` for refreshing LVGL. [`mp_lv_task_handler`](https://github.com/lvgl/lv_binding_micropython/blob/77b0c9f2678b6fbd0950fbf27380052246841082/driver/SDL/modSDL.c#L7) is scheduled to run on the same thread Micropython is running, and it calls both `lv_task_handler` for LVGL task handling and `monitor_sdl_refr_core` for refreshing the display and handling mouse events.
4750

4851
With REPL (interactive console), when waiting for the user input, asynchronous events can also happen. In [this example](https://github.com/lvgl/lv_mpy/blob/bc635700e4186f39763e5edee73660fbe1a27cd4/ports/unix/unix_mphal.c#L176) we just call `mp_handle_pending` periodically when waiting for a keypress. `mp_handle_pending` takes care of dispatching asynchronous events registered with `mp_sched_schedule`.
4952

5053
### Structs Classes and globals
5154

52-
The lvgl binding script parses lvgl headers and provides API to access lvgl **classes** (such as `btn`) and **structs** (such as `color_t`). All structs and classes are available under lvgl micropython module.
55+
The LVGL binding script parses LVGL headers and provides API to access LVGL **classes** (such as `btn`) and **structs** (such as `color_t`). All structs and classes are available under lvgl micropython module.
5356

5457
lvgl Class contains:
5558
- functions (such as `set_x`)
@@ -109,10 +112,36 @@ The `user_data` field **must not be used directly by the user**, since it is use
109112

110113
### Display and Input Drivers
111114

112-
LVGL can be configured to use different displays and different input devices. More information is available on [LVGL documentation](https://docs.lvgl.io/#Porting).
115+
LVGL can be configured to use different displays and different input devices. More information is available on [LVGL documentation](https://docs.lvgl.io/master/porting/display.html).
113116
Registering a driver is essentially calling a registeration function (for example `disp_drv_register`) and passing a function pointer as a parameter (actually a struct that contains function pointers). The function pointer is used to access the actual display / input device.
114-
When using LVGL with Micropython, it makes more sense to **implement the display and input driver in C**. However, **the device registration is perfomed in the Micropython script** to make it easy for the user to select and replace drivers without building the project and changing C files.
115-
Technically, the driver can be written in either C or in pure Micropython using callbacks.
117+
118+
When implementing a display or input LVGL driver with Micropython, there are 3 option:
119+
- Implement a Pure Python driver. It the easiest way to implement a driver, but may perform poorly
120+
- Implement a Pure C driver.
121+
- Implemnent a Hybrid driver where the critical parts (such as the `flush` function) are in C, and the non-critical part (such as initializing the display) are implemented in Python.
122+
123+
An example of Pure/Hybrid driver is the [ili9XXX.py](https://github.com/lvgl/lv_binding_micropython/blob/master/driver/esp32/ili9XXX.py).
124+
125+
The driver registration should eventually be perfomed in the Micropython script, either in the driver code itself in case of the pure/hybrid driver or in user code in case of C driver (for example, in the case of the SDL driver). Registering the driver on Python and not in C is important to make it easy for the user to select and replace drivers without building the project and changing C files.
126+
127+
When creating a display or input LVGL driver, make sure you let the user **configure all parameters on runtime**, such as SPI pins, frequency, etc.
128+
Eventually the user would want to build the firmware once and use the same driver in different configuration without re-building the C project.
129+
This is different from standard LVGL C drivers where you usually use macros to configure parameters and require the user to re-build when any configurations changes.
130+
131+
Example:
132+
133+
```python
134+
135+
# Initialize ILI9341 display
136+
137+
from ili9XXX import ili9341
138+
self.disp = ili9341(dc=32, cs=33, power=-1, backlight=-1)
139+
140+
# Register xpt2046 touch driver
141+
142+
from xpt2046 import xpt2046
143+
self.touch = xpt2046()
144+
```
116145

117146
Example:
118147

@@ -166,6 +195,12 @@ Driver code is under `/driver` directory.
166195
Drivers can also be implemented in pure Micropython, by providing callbacks (`disp_drv.flush_cb`, `indev_drv.read_cb` etc.)
167196
Currently the supported ILI9341, FT6X36 and XPT2046 are pure micropython drivers
168197

198+
### The Event Loop
199+
200+
LVGL requires an Event Loop to re-draw the screen, handle user input etc.
201+
The default Event Loop is implement in [lv_utils.py](https://github.com/lvgl/lv_binding_micropython/blob/master/lib/lv_utils.py) which uses Micropython Timer to schedule calls to LVGL.
202+
It also supports running the Event Loop in [uasyncio](https://docs.micropython.org/en/latest/library/uasyncio.html) if needed.
203+
169204
### Adding Micropython Bindings to a project
170205

171206
An example project of "Micropython + lvgl + Bindings" is [`lv_mpy`](https://github.com/lvgl/lv_mpy).

0 commit comments

Comments
 (0)
0