init Files

This commit is contained in:
2024-12-09 19:47:18 +01:00
parent b55a8cd2bc
commit 528e862838
3471 changed files with 1105029 additions and 0 deletions

View File

@@ -0,0 +1,504 @@
Output API as JSON data
=======================
We have written a script that will read the header files in LVGL and outputs a
more friendly JSON format for the API. This is done so that bindings that generate
code automatically will have an easy way to collect the needed information without
having to reinvent the wheel. The JSON data format has already made libraries for
reading the format for just about every programming language out there.
The script in order to run does have some requirements.
- Python >= 3.10
- Pycparser >= 2.21: Python Library for reading the preprocessor ouotput from the C compiler
- PyMSVC >= 0.4.0: Python library is using MSVC Compiler
- C compiler, gcc for Linux, clang for OSX and MSVC for Windows
- Doxygen: used to read the docstrings from the header files.
There are several options when running the script. They are as follows
- `--output-path`: output directory for JSON file. If one is not supplied
then it will be output stdout
- `--lvgl-config`: path to lv_conf.h (including file name), if this is not
set then a config file will be generated that has most common things turned on
- `--develop`: leaves the temporary folder in place.
to use the script
.. code:: shell
python /scripts/gen_json/gen_json.py --output-path=json/output/directory --lvgl-config=path/to/lv_conf.h
or if you want to run a subprocess from inside of a generation script and read the output from stdout
.. code:: shell
python /scripts/gen_json/gen_json.py --lvgl-config=path/to/lv_conf.h
The JSON data is broken apart into a couple of main categories.
- enums
- functions
- function_pointers
- structures
- unions
- variables
- typedefs
- forward_decls
- macros
Those categories are the element names undert the root of the JSON data.
The value for each categry is an array of JSON elements. There is a bit of
nesting with the elements in the arrays and I have created "json_types" that
will allow you to identify exactly what you are dealing with.
The different "json_types" are as follows:
- ``"array"``: The array type is used to identify arrays.
Available JSON fields:
- ``"dim"``: number of items in the array
- ``"quals"``: array of qualifiers, IE "const"
- ``"type"``: This may or may not be available.
- ``"name"``: the name of the data type
- ``"field"``: This type is used to describe fields in structures and unions.
It is used in the ``"fields"`` array of the ``"struct"`` and ``"union"`` JSON types.
Available JSON fields:
- ``"name"``: The name of the field.
- ``"type"``: This contains the type information for the field. Check the
``"json_type"`` to know what type you are dealing with.
- ``"bitsize"``: The number of bits the field has or ``null``
if there is no bit size defined
- ``"docstring"``: you should know what this is.
- ``"arg"``: Used to describe an argument/parameter in a function or a function pointer.
Available JSON fields:
- ``"name"``: The name of the argument/parameter.
- ``"type"``: This contains the type information for the field. Check the
``"json_type"`` to know what type you are dealing with.
- ``"docstring"``: you should know what this is.
- ``"quals"``: array of qualifiers, IE "const"
- ``"forward_decl"``: Describes a forward declaration.There are structures in
LVGL that are considered to be private and that is what these desccribe.
Available JSON fields:
- ``"name"``: The name of the formard declaration.
- ``"type"``: This contains the type information for the field. Check the
``"json_type"`` to know what type you are dealing with.
- ``"docstring"``: you should know what this is.
- ``"quals"``: array of qualifiers, IE "const"
- ``"function_pointer"``: Describes a function pointer. These are used when
registering callback functions in LVGL.
Available JSON fields:
- ``"name"``: The name of the function pointer.
- ``"type"``: This contains the return type information for the function pointer.
- ``"docstring"``: you should know what this is.
- ``"args"``: array of ``"arg"`` objects. This describes the fuction arguments/parameters.
- ``"quals"``: array of qualifiers, IE "const"
- ``"variable"``: Describes a global variable.
Available JSON fields:
- ``"name"``: The name of the variable.
- ``"type"``: This contains the type information for the field. Check the
``"json_type"`` to know what type you are dealing with.
- ``"docstring"``: you should know what this is.
- ``"quals"``: array of qualifiers, IE "const"
- ``"storage"``: array of storage classifiers, IE "extern"
- ``"special_type"``: Currently only used to describe an ellipsis argument
for a function.
Available JSON fields:
- ``"name"``: will always be "ellipsis".
- ``"primitive_type"``: This is a base type. There or no other types beneith this.
This tells you that the type is a basic or primitive C type.
IE: struct, union, int, unsigned int, etc...
Available JSON fields:
- ``"name"``: The name of the primitive type.
- ``"enum"``: Describes a grouping of enumeration items/members.
Available JSON fields:
- ``"name"``: The name of the enumeration group/type.
- ``"type"``: This contains the type information for the enumeration group.
This is always going to be an "int" type. Make sure you do not use this
type as the type for the members of this enumeration group. Check the
enumeration members type to get the correct type.
- ``"docstring"``: you should know what this is.
- ``"members"``: array of ``"enum_member"`` objects
- ``"enum_member"``: Describes an enumeration item/member. Only found under
the ``"members"`` field of an ``"enum"`` JSON type
Available JSON fields:
- ``"name"``: The name of the enumeration.
- ``"type"``: This contains the type information for the enum member.
This gets a bit tricky because the type specified in here is not always
going to be an "int". It will usually point to an lvgl type and the type
of the lvgl type can be found in the ``"typedefs"`` section.
- ``"docstring"``: you should know what this is.
- ``"value"``: the enumeration member/item's value
- ``"lvgl_type"``: This is a base type. There or no other types beneith this.
This tells you that the type is an LVGL data type.
Available JSON fields:
- ``"name"``: The name of the type.
- ``"quals"``: array of qualifiers, IE "const
- ``"struct"``: Describes a structure
Available JSON fields:
- ``"name"``: The name of the structure.
- ``"type"``: This contains the primitive type information for the structure.
- ``"docstring"``: you should know what this is.
- ``"fields"``: array of ``"field"`` elements.
- ``"quals"``: array of qualifiers, IE "const"
- ``"union"``: Describes a union
Available JSON fields:
- ``"name"``: The name of the union.
- ``"type"``: This contains the primitive type information for the union.
- ``"docstring"``: you should know what this is.
- ``"fields"``: array of ``"field"`` elements.
- ``"quals"``: array of qualifiers, IE "const"
- ``"macro"``: describes a macro. There is limited information that can be
collected about macros and in most cases a binding will need to have these
statically added to a binding. It is more for collecting the docstrings than
anything else.
Available JSON fields:
- ``"name"``: The name of the macro.
- ``"docstring"``: you should know what this is.
- ``"ret_type"``: return type from a function. This is only going to be seen in the ``"type"``
element of a ``"function"`` type.
Available JSON fields:
- ``"type"``: This contains the type information for the field. Check the
``"json_type"`` to know what type you are dealing with.
- ``"docstring"``: you should know what this is.
- ``"function"``: Describes a function.
Available JSON fields:
- ``"name"``: The name of the function.
- ``"type"``: This contains the type information for the return value.
- ``"docstring"``: you should know what this is.
- ``"args"``: array of ``"arg"`` json types. This describes the fuction arguments/parameters.
- ``"stdlib_type"``: This is a base type, meaning that there are no more
type levels beneith this. This tells us that the type is from the C stdlib.
Available JSON fields:
- ``"name"``: The name of the type.
- ``"quals"``: array of qualifiers, IE "const
- ``"unknown_type"``: This should not be seen. If it is then there needs to be
an adjustment made to the script. Please open an issue and let us know if you see this type.
Available JSON fields:
- ``"name"``: The name of the type.
- ``"quals"``: array of qualifiers, IE "const
- ``"pointer"``: This is a wrapper object to let you know that the type you
are dealing with is a pointer
Available JSON fields:
- ``"type"``: This contains the type information for the pointer. Check the
``"json_type"`` to know what type you are dealing with.
- ``"quals"``: array of qualifiers, IE "const", may or may not be available.
- ``"typedef"``: type definitions. I will explain more on this below.
Available JSON fields:
- ``"name"``: The name of the typedef.
- ``"type"``: This contains the type information for the field. Check the
``"json_type"`` to know what type you are dealing with.
- ``"docstring"``: you should know what this is.
- ``"quals"``: array of qualifiers, IE "const"
Here is an example of what the output will look like.
.. code:: json
{
"enums":[
{
"name":"_lv_result_t",
"type":{
"name":"int",
"json_type":"primitive_type"
},
"json_type":"enum",
"docstring":"LVGL error codes. ",
"members":[
{
"name":"LV_RESULT_INVALID",
"type":{
"name":"_lv_result_t",
"json_type":"lvgl_type"
},
"json_type":"enum_member",
"docstring":"",
"value":"0x0"
},
{
"name":"LV_RESULT_OK",
"type":{
"name":"_lv_result_t",
"json_type":"lvgl_type"
},
"json_type":"enum_member",
"docstring":"",
"value":"0x1"
}
]
}
],
"functions":[
{
"name":"lv_version_info",
"type":{
"type":{
"type":{
"name":"char",
"json_type":"primitive_type",
"quals":[
"const"
]
},
"json_type":"pointer",
"quals":[]
},
"json_type":"ret_type",
"docstring":""
},
"json_type":"function",
"docstring":"",
"args":[
{
"name":null,
"type":{
"name":"void",
"json_type":"primitive_type",
"quals":[]
},
"json_type":"arg",
"docstring":"",
"quals":[]
}
]
}
],
"function_pointers":[
{
"name":"lv_tlsf_walker",
"type":{
"type":{
"name":"void",
"json_type":"primitive_type",
"quals":[]
},
"json_type":"ret_type",
"docstring":""
},
"json_type":"function_pointer",
"docstring":"",
"args":[
{
"name":"ptr",
"type":{
"type":{
"name":"void",
"json_type":"primitive_type",
"quals":[]
},
"json_type":"pointer",
"quals":[]
},
"json_type":"arg",
"docstring":""
},
{
"name":"size",
"type":{
"name":"size_t",
"json_type":"stdlib_type",
"quals":[]
},
"json_type":"arg",
"docstring":""
},
{
"name":"used",
"type":{
"name":"int",
"json_type":"primitive_type",
"quals":[]
},
"json_type":"arg",
"docstring":""
},
{
"name":"user",
"type":{
"type":{
"name":"void",
"json_type":"primitive_type",
"quals":[]
},
"json_type":"pointer",
"quals":[]
},
"json_type":"arg",
"docstring":""
}
],
"quals":[]
}
],
"structures":[
{
"name":"_lv_gradient_cache_t",
"type":{
"name":"struct",
"json_type":"primitive_type"
},
"json_type":"struct",
"docstring":null,
"fields":[
{
"name":"color_map",
"type":{
"type":{
"name":"lv_color_t",
"json_type":"lvgl_type",
"quals":[]
},
"json_type":"pointer",
"quals":[]
},
"json_type":"field",
"bitsize":null,
"docstring":""
},
{
"name":"opa_map",
"type":{
"type":{
"name":"lv_opa_t",
"json_type":"lvgl_type",
"quals":[]
},
"json_type":"pointer",
"quals":[]
},
"json_type":"field",
"bitsize":null,
"docstring":""
},
{
"name":"size",
"type":{
"name":"uint32_t",
"json_type":"stdlib_type",
"quals":[]
},
"json_type":"field",
"bitsize":null,
"docstring":""
}
]
}
],
"unions":[],
"variables":[
{
"name":"lv_global",
"type":{
"name":"lv_global_t",
"json_type":"lvgl_type",
"quals":[]
},
"json_type":"variable",
"docstring":"",
"quals":[],
"storage":[
"extern"
]
}
],
"typedefs":[
{
"name":"lv_pool_t",
"type":{
"type":{
"name":"void",
"json_type":"primitive_type",
"quals":[]
},
"json_type":"pointer"
},
"json_type":"typedef",
"docstring":"",
"quals":[]
}
],
"forward_decls":[
{
"name":"lv_fragment_managed_states_t",
"type":{
"name":"struct",
"json_type":"primitive_type"
},
"json_type":"forward_decl",
"docstring":"",
"quals":[]
}
],
"macros":[
{
"name":"ZERO_MEM_SENTINEL",
"json_type":"macro",
"docstring":""
}
]
}

View File

@@ -0,0 +1,5 @@
===
Cpp
===
In progress: https://github.com/lvgl/lv_binding_cpp

View File

@@ -0,0 +1,13 @@
========
Bindings
========
.. toctree::
:maxdepth: 2
micropython
cpp
pikascript
javascript
api_json

View File

@@ -0,0 +1,133 @@
==========
JavaScript
==========
With `lv_binding_js <https://github.com/lvgl/lv_binding_js>`__ you can
write lvgl with JavaScript.
It uses React's virtual DOM concept to manipulate lvgl UI components,
providing a familiar React-like experience to users.
**Code**
**Code Running on Real Device**
Table of Contents
-----------------
- `Features <#features>`__
- `Demo <#demo>`__
- `Building <#building>`__
- `Components <#components>`__
- `Font <#font>`__
- `Animation <#animation>`__
- `Style <#style>`__
- `JSAPI <#jsapi>`__
- `Thanks <#thanks>`__
Features
--------
- Support all lvgl built-in components
- Fully support lvgl flex and grid style
- support most lvgl style, just write like html5 css
- support dynamic load image
- Fully support lvgl animation
Demo
----
See the
`demo <https://github.com/lvgl/lv_binding_js/tree/master/demo>`__ folder
Building
--------
The following are developer notes on how to build lvgljs on your native
platform. They are not complete guides, but include notes on the
necessary libraries, compile flags, etc.
lvgljs
~~~~~~
- `ubuntu build Notes for sdl
simulator <https://github.com/lvgl/lv_binding_js/blob/master/doc/build/build-ubuntu-arm.md>`__
- `macos x86 build Notes for sdl
simulator <https://github.com/lvgl/lv_binding_js/blob/master/doc/build/build-macos-x86-simulator.md>`__
- `ubuntu build Notes for platform
arm <https://github.com/lvgl/lv_binding_js/blob/master/doc/build/build-ubuntu-x86-simulator.md>`__
JS Bundle
~~~~~~~~~
- `JS Bundle build
Notes <https://github.com/lvgl/lv_binding_js/blob/master/doc/build/js-bundle.md>`__
Components
----------
- `View <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/View.md>`__
- `Image <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Image.md>`__
- `Button <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Button.md>`__
- `Text <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Text.md>`__
- `Input <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Input.md>`__
- `Textarea <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Textarea.md>`__
- `Switch <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Switch.md>`__
- `Checkbox <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Checkbox.md>`__
- `Dropdownlist <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Dropdownlist.md>`__
- `ProgressBar <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/ProgressBar.md>`__
- `Line <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Line.md>`__
- `Roller <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Roller.md>`__
- `Keyboard <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Keyboard.md>`__
- `Calendar <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Calendar.md>`__
- `Chart <https://github.com/lvgl/lv_binding_js/blob/master/doc/component/Chart.md>`__
Font
----
`Builtin-Symbol <https://github.com/lvgl/lv_binding_js/blob/master/doc/Symbol/symbol.md>`__
Animation
---------
`Animation <https://github.com/lvgl/lv_binding_js/blob/master/doc/animate/animate.md>`__
Style
-----
.. include::https://github.com/lvgl/lv_binding_js/blob/master/doc/style/position-size-layout.md
- `position-size-layout <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/position-size-layout.md>`__
- `boxing-model <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/boxing-model.md>`__
- `color <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/color.md>`__
- `flex <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/flex.md>`__
- `grid <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/grid.md>`__
- `font <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/font.md>`__
- `opacity <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/opacity.md>`__
- `display <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/display.md>`__
- `background <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/background.md>`__
- `scroll <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/scroll.md>`__
- `shadow <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/shadow.md>`__
- `recolor <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/recolor.md>`__
- `line <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/line.md>`__
- `transition <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/transition.md>`__
- `transform <https://github.com/lvgl/lv_binding_js/blob/master/doc/style/transform.md>`__
JSAPI
-----
- `network <https://github.com/lvgl/lv_binding_js/blob/master/doc/jsapi/network.md>`__
- `filesystem <https://github.com/lvgl/lv_binding_js/blob/master/doc/jsapi/fs.md>`__
- `dimension <https://github.com/lvgl/lv_binding_js/blob/master/doc/jsapi/dimension.md>`__
Thanks
------
lvgljs depends on following excellent work
`lvgl <https://github.com/lvgl/lvgl>`__: Create beautiful UIs for any
MCU, MPU and display type `QuickJS <https://bellard.org/quickjs/>`__:
JavaScript engine `libuv <https://github.com/libuv/libuv>`__: platform
abstraction layer `curl <https://github.com/curl/curl>`__: HTTP client
`txiki.js <https://github.com/saghul/txiki.js>`__: Tiny JavaScript
runtime

View File

@@ -0,0 +1,294 @@
.. _micropython:
===========
MicroPython
===========
What is MicroPython?
--------------------
`MicroPython <http://micropython.org/>`__ is Python for
microcontrollers. Using MicroPython, you can write Python3 code and run
it even on a bare metal architecture with limited resources.
Highlights of MicroPython
~~~~~~~~~~~~~~~~~~~~~~~~~
- **Compact**: Fits and runs within just 256k of code space and 16k of RAM. No OS is needed, although you
can also run it with an OS, if you want.
- **Compatible**: Strives to be as compatible as possible with normal Python (known as CPython).
- **Versatile**: Supports many architectures (x86, x86-64, ARM, ARM Thumb, Xtensa).
- **Interactive**: No need for the compile-flash-boot cycle. With the REPL (interactive prompt) you can type
commands and execute them immediately, run scripts, etc.
- **Popular**: Many platforms are supported. The user base is growing bigger. Notable forks:
- `MicroPython <https://github.com/micropython/micropython>`__
- `CircuitPython <https://github.com/adafruit/circuitpython>`__
- `MicroPython_ESP32_psRAM_LoBo <https://github.com/loboris/MicroPython_ESP32_psRAM_LoBo>`__
- **Embedded Oriented**: Comes with modules specifically for embedded systems, such as the
`machine module <https://docs.micropython.org/en/latest/library/machine.html#classes>`__
for accessing low-level hardware (I/O pins, ADC, UART, SPI, I2C, RTC, Timers etc.)
--------------
Why MicroPython + LVGL?
-----------------------
MicroPython `does not have a good native high-level GUI library <https://forum.micropython.org/viewtopic.php?f=18&t=5543>`__.
LVGL is an `Object-Oriented Component Based <https://blog.lvgl.io/2018-12-13/extend-lvgl-objects>`__
high-level GUI library, which seems to be a natural candidate to map into a higher level language, such as Python.
LVGL is implemented in C and its APIs are in C.
Here are some advantages of using LVGL in MicroPython:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Develop GUI in Python, a very popular high level language. Use paradigms such as Object-Oriented Programming.
- Usually, GUI development requires multiple iterations to get things right. With C, each iteration consists of
**``Change code`` > ``Build`` > ``Flash`` > ``Run``**. In MicroPython it's just
**``Change code`` > ``Run``** ! You can even run commands interactively using the
`REPL <https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop>`__ (the interactive prompt)
MicroPython + LVGL could be used for:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Fast prototyping GUI.
- Shortening the cycle of changing and fine-tuning the GUI.
- Modelling the GUI in a more abstract way by defining reusable composite objects, taking advantage of Python's language features
such as Inheritance, Closures, List Comprehension, Generators, Exception Handling, Arbitrary Precision Integers and others.
- Make LVGL accessible to a larger audience. No need to know C to create a nice GUI on an embedded system. This goes well with
`CircuitPython vision <https://learn.adafruit.com/welcome-to-circuitpython/what-is-circuitpython>`__.
CircuitPython was designed with education in mind, to make it easier for new or inexperienced users to get started with
embedded development.
- Creating tools to work with LVGL at a higher level (e.g. drag-and-drop designer).
--------------
So what does it look like?
--------------------------
It's very much like the C API, but Object-Oriented for LVGL components.
Let's dive right into an example!
A simple example
~~~~~~~~~~~~~~~~
.. code:: python
# Initialize
import display_driver
import lvgl as lv
# Create a button with a label
scr = lv.obj()
btn = lv.button(scr)
btn.align(lv.ALIGN.CENTER, 0, 0)
label = lv.label(btn)
label.set_text('Hello World!')
lv.screen_load(scr)
How can I use it?
-----------------
Online Simulator
~~~~~~~~~~~~~~~~
If you want to experiment with LVGL + MicroPython without downloading
anything - you can use our online simulator! It's a fully functional
LVGL + MicroPython that runs entirely in the browser and allows you to
edit a python script and run it.
`Click here to experiment on the online simulator <https://sim.lvgl.io/>`__
Many `LVGL examples <https://docs.lvgl.io/master/examples.html>`__ are available also for MicroPython. Just click the link!
PC Simulator
~~~~~~~~~~~~
MicroPython is ported to many platforms. One notable port is "unix", which allows you to build and run MicroPython
(+LVGL) on a Linux machine. (On a Windows machine you might need Virtual Box or WSL or MinGW or Cygwin etc.)
`Click here to know more information about building and running the unix port <https://github.com/lvgl/lv_micropython>`__
Embedded Platforms
~~~~~~~~~~~~~~~~~~
In the end, the goal is to run it all on an embedded platform. Both MicroPython and LVGL can be used on many embedded
architectures. `lv_micropython <https://github.com/lvgl/lv_micropython>`__ is a fork of MicroPython+LVGL and currently
supports Linux, ESP32, STM32 and RP2. It can be ported to any other platform supported by MicroPython.
- You would also need display and input drivers. You can either use one of the existing drivers provided with lv_micropython,
or you can create your own input/display drivers for your specific hardware.
- Drivers can be implemented either in C as a MicroPython module, or in pure Python!
lv_micropython already contains these drivers:
- Display drivers:
- SDL on Linux
- X11 on Linux
- ESP32 specific:
- ILI9341
- ILI9488
- GC9A01
- ST7789
- ST7735
- Generic (pure Python):
- ILI9341
- ST7789
- ST7735
- Input drivers:
- SDL
- X11
- XPT2046
- FT6X36
- ESP32 ADC with resistive touch
Where can I find more information?
----------------------------------
- ``lv_micropython`` `README <https://github.com/lvgl/lv_micropython>`__
- ``lv_binding_micropython`` `README <https://github.com/lvgl/lv_binding_micropython>`__
- The `LVGL micropython forum <https://forum.lvgl.io/c/micropython>`__ (Feel free to ask anything!)
- At MicroPython: `docs <http://docs.micropython.org/en/latest/>`__ and `forum <https://forum.micropython.org/>`__
- `Blog Post <https://blog.lvgl.io/2019-02-20/micropython-bindings>`__, a little outdated.
The MicroPython Binding is auto generated!
------------------------------------------
- LVGL is a git submodule inside `lv_micropython <https://github.com/lvgl/lv_micropython>`__
(LVGL is a git submodule of `lv_binding_micropython <https://github.com/lvgl/lv_binding_micropython>`__
which is itself a submodule of `lv_micropython <https://github.com/lvgl/lv_micropython>`__).
- When building lv_micropython, the public LVGL C API is scanned and MicroPython API is auto-generated. That means that
lv_micropython provides LVGL API for **any** LVGL version, and generally does not require code changes as LVGL evolves.
LVGL C API Coding Conventions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
For a summary of coding conventions to follow see the :ref:`coding-style`.
.. _memory_management:
Memory Management
~~~~~~~~~~~~~~~~~
| When LVGL runs in MicroPython, all dynamic memory allocations (:cpp:func:`lv_malloc`) are handled by MicroPython's memory
manager which is `garbage-collected <https://en.wikipedia.org/wiki/Garbage_collection_(computer_science)>`__ (GC).
| To prevent GC from collecting memory prematurely, all dynamic allocated RAM must be reachable by GC.
| GC is aware of most allocations, except from pointers on the `Data Segment <https://en.wikipedia.org/wiki/Data_segment>`__:
- Pointers which are global variables
- Pointers which are static global variables
- Pointers which are static local variables
Such pointers need to be defined in a special way to make them reachable by GC
Identify The Problem
^^^^^^^^^^^^^^^^^^^^
Problem happens when an allocated memory's pointer (return value of :cpp:func:`lv_malloc`) is stored only in either **global**,
**static global** or **static local** pointer variable and not as part of a previously allocated ``struct`` or other variable.
Solve The Problem
^^^^^^^^^^^^^^^^^
- Replace the global/static local var with :cpp:expr:`(LV_GLOBAL_DEFAULT()->_var)`
- Include ``lv_global.h`` on files that use ``LV_GLOBAL_DEFAULT``
- Add ``_var`` to ``lv_global_t`` on ``lv_global.h``
Example
^^^^^^^
More Information
^^^^^^^^^^^^^^^^
- `In the README <https://github.com/lvgl/lv_binding_micropython#memory-management>`__
- `In the Blog <https://blog.lvgl.io/2019-02-20/micropython-bindings#i-need-to-allocate-a-littlevgl-struct-such-as-style-color-etc-how-can-i-do-that-how-do-i-allocatedeallocate-memory-for-it>`__
.. _callbacks:
Callbacks
~~~~~~~~~
In C a callback is just a function pointer. But in MicroPython we need to register a *MicroPython callable object* for each
callback. Therefore in the MicroPython binding we need to register both a function pointer and a MicroPython object for every callback.
Therefore we defined a **callback convention** for the LVGL C API that expects lvgl headers to be defined in a certain
way. Callbacks that are declared according to the convention would allow the binding to register a MicroPython object
next to the function pointer when registering a callback, and access that object when the callback is called.
- The basic idea is that we have ``void * user_data`` field that is used automatically by the MicroPython Binding
to save the *MicroPython callable object* for a callback. This field must be provided when registering the function
pointer, and provided to the callback function itself.
- Although called "user_data", the user is not expected to read/write that field. Instead, the MicroPython glue code uses
``user_data`` to automatically keep track of the MicroPython callable object. The glue code updates it when the callback
is registered, and uses it when the callback is called in order to invoke a call to the original callable object.
There are a few options for defining a callback in LVGL C API:
- Option 1: ``user_data`` in a struct
- There's a struct that contains a field called ``void * user_data``
- A pointer to that struct is provided as the **first** argument of a callback registration function
- A pointer to that struct is provided as the **first** argument of the callback itself
- Option 2: ``user_data`` as a function argument
- A parameter called ``void * user_data`` is provided to the registration function as the **last** argument
- The callback itself receives ``void *`` as the **last** argument
- Option 3: both callback and ``user_data`` are struct fields
- The API exposes a struct with both function pointer member and ``user_data`` member
- The function pointer member receives the same struct as its **first** argument
In practice it's also possible to mix these options, for example provide a struct pointer when registering a callback
(option 1) and provide ``user_data`` argument when calling the callback (options 2),
**as long as the same ``user_data`` that was registered is passed to the callback when it's called**.
Examples
^^^^^^^^
- :cpp:type:`lv_anim_t` contains ``user_data`` field. :cpp:func:`lv_anim_set_path_cb`
registers `path_cb` callback. Both ``lv_anim_set_path_cb`` and :cpp:type:`lv_anim_path_cb_t`
receive :cpp:type:`lv_anim_t` as their first argument
- ``path_cb`` field can also be assigned directly in the Python code because it's a member
of :cpp:type:`lv_anim_t` which contains ``user_data`` field, and :cpp:type:`lv_anim_path_cb_t`
receive :cpp:type:`lv_anim_t` as its first argument.
- :cpp:func:`lv_imgfont_create` registers ``path_cb`` and receives ``user_data`` as the last
argument. The callback :cpp:type:`lv_imgfont_get_path_cb_t` also receives the ``user_data`` as the last argument.
.. _more-information-1:
More Information
^^^^^^^^^^^^^^^^
- In the `Blog <https://blog.lvgl.io/2019-08-05/micropython-pure-display-driver#using-callbacks>`__
and in the `README <https://github.com/lvgl/lv_binding_micropython#callbacks>`__
- `[v6.0] Callback conventions #1036 <https://github.com/lvgl/lvgl/issues/1036>`__
- Various discussions: `here <https://github.com/lvgl/lvgl/pull/3294#issuecomment-1184895335>`__
and `here <https://github.com/lvgl/lvgl/issues/1763#issuecomment-762247629>`__
and`here <https://github.com/lvgl/lvgl/issues/316#issuecomment-467221587>`__

View File

@@ -0,0 +1,203 @@
PikaScript
==========
What is PikaScript ?
--------------------
`PikaScript <https://github.com/pikasTech/pikascript>`__ is a Python
interpreter designed specifically for microcontrollers, and it supports
a subset of the common Python3 syntax.
It's lighter, requiring only 32k of code space and 4k of RAM, which
means it can run on stm32f103c8 (blue-pill) or even stm32g030c8, on the
other hand, you can leave valuable space for more material or larger
buffer areas.
It is simpler, out of the box, runs with no porting and configuration at
all, does not depend on OS or file system, has good support for popular
IDEs for Windows platforms like Keil, IAR, RT-Thread-Studio, and of
course, supports linux-gcc development platforms.
It's smarter, with a unique C module mechanism that allows you to
generate bindings automatically by simply writing the API for the C
module in Python, and you don't need to deal with the headache of
writing any macros or global tables manually. On the other hand, all C
modules have sophisticated smart hints, even hinting at the types of
your arguments .
--------------
Why PikaScript + LVGL ?
-----------------------
PikaScript now supports the main features of LVGL8, and these APIs are
fully compatible with MicroPython!
This means that you can continue to use already written code from
MicroPython, and then use less code space and RAM.
Enjoy detailed code hints down to the parameter type for a better
programming experience
Use a more convenient IDE, such as vs-based simulation projects
So how does it look like?
-------------------------
Here are some examples of lvgl that PikaScript can already run, they are
mainly from the lvgl documentation examples
LV_ARC
~~~~~~
.. code:: python
import pika_lvgl as lv
import PikaStdLib
mem = PikaStdLib.MemChecker()
# Create an Arc
arc = lv.arc(lv.screen_active())
arc.set_end_angle(200)
arc.set_size(150, 150)
arc.center()
print('mem used max: %0.2f kB' % (mem.getMax()))
print('mem used now: %0.2f kB' % (mem.getNow()))
LV_BAR
~~~~~~
.. code:: python
import pika_lvgl as lv
import PikaStdLib
mem = PikaStdLib.MemChecker()
bar1 = lv.bar(lv.screen_active())
bar1.set_size(200, 20)
bar1.center()
bar1.set_value(70, lv.ANIM.OFF)
print('mem used max: %0.2f kB' % (mem.getMax()))
print('mem used now: %0.2f kB' % (mem.getNow()))
LV_BTN
~~~~~~
.. code:: python
import pika_lvgl as lv
import PikaStdLib
mem = PikaStdLib.MemChecker()
def event_cb_1(evt):
print('in evt1')
print('mem used now: %0.2f kB' % (mem.getNow()))
def event_cb_2(evt):
print('in evt2')
print('mem used now: %0.2f kB' % (mem.getNow()))
btn1 = lv.btn(lv.screen_active())
btn1.align(lv.ALIGN.TOP_MID, 0, 10)
btn2 = lv.btn(lv.screen_active())
btn2.align(lv.ALIGN.TOP_MID, 0, 50)
btn1.add_event_cb(event_cb_1, lv.EVENT.CLICKED, 0)
btn2.add_event_cb(event_cb_2, lv.EVENT.CLICKED, 0)
print('mem used max: %0.2f kB' % (mem.getMax()))
print('mem used now: %0.2f kB' % (mem.getNow()))
LV_CHECKBOX
~~~~~~~~~~~
.. code:: python
import pika_lvgl as lv
import PikaStdLib
mem = PikaStdLib.MemChecker()
cb = lv.checkbox(lv.screen_active())
cb.set_text("Apple")
cb.align(lv.ALIGN.TOP_LEFT, 0 ,0)
cb = lv.checkbox(lv.screen_active())
cb.set_text("Banana")
cb.add_state(lv.STATE.CHECKED)
cb.align(lv.ALIGN.TOP_LEFT, 0 ,30)
cb = lv.checkbox(lv.screen_active())
cb.set_text("Lemon")
cb.add_state(lv.STATE.DISABLED)
cb.align(lv.ALIGN.TOP_LEFT, 0 ,60)
cb = lv.checkbox(lv.screen_active())
cb.add_state(lv.STATE.CHECKED | lv.STATE.DISABLED)
cb.set_text("Melon")
cb.align(lv.ALIGN.TOP_LEFT, 0 ,90)
print('mem used max: %0.2f kB' % (mem.getMax()))
print('mem used now: %0.2f kB' % (mem.getNow()))
--------------
How does it work?
-----------------
PikaScript has a unique C module smart binding tool
Just write the Python interface in pika_lvgl.pyi (.pyi is the python
interface file)
.. code:: python
# pika_lvgl.pyi
class arc(lv_obj):
def set_end_angle(self, angle: int): ...
def set_bg_angles(self, start: int, end: int): ...
def set_angles(self, start: int, end: int): ...
Then PikaScript's pre-compiler can automatically bind the following C
functions, simply by naming the functions in the module_class_method
format, without any additional work, and all binding and registration is
done automatically.
.. code:: c
/* pika_lvgl_arc.c */
void pika_lvgl_arc_set_end_angle(PikaObj* self, int angle) {
lv_obj_t* lv_obj = obj_getPtr(self, "lv_obj");
lv_arc_set_end_angle(lv_obj, angle);
}
void pika_lvgl_arc_set_bg_angles(PikaObj *self, int start, int end){
lv_obj_t* lv_obj = obj_getPtr(self, "lv_obj");
lv_arc_set_bg_angles(lv_obj, start, end);
}
void pika_lvgl_arc_set_angles(PikaObj *self, int start, int end){
lv_obj_t* lv_obj = obj_getPtr(self, "lv_obj");
lv_arc_set_angles(lv_obj, start, end);
}
To use the module, just ``import pika_lvgl`` and the precompiler will
automatically scan main.py and bind the ``pika_lvgl`` module
::
$ ./rust-msc-latest-win10.exe
(pikascript) packages installed:
pikascript-core==v1.10.0
PikaStdLib==v1.10.0
PikaStdDevice==v1.10.0
(pikascript) pika compiler:
scanning main.py...
binding pika_lvgl.pyi...
The precompiler is written in Rust, runs on windows and linux, and is
completely open source.
In addition to binding C modules, the precompiler compiles Python
scripts to bytecode in the PC, reducing the size of the script and
increasing its speed.
--------------
How can I use it?
-----------------
The simulation repo on vs is available on
https://github.com/pikasTech/lv_pikascript