diff options
author | Ayke van Laethem <aykevanlaethem@gmail.com> | 2018-06-14 15:57:29 +0200 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2019-03-08 22:49:00 +1100 |
commit | 2e516074daee76fb3e0710a893a0f40532bb3252 (patch) | |
tree | d871d641c10aff22e3d80ad4711310c4b7be4b31 /docs/reference | |
parent | cf22f4793cb04e8e63a0d11f479a69c9be6c93ba (diff) |
py: Implement a module system for external, user C modules.
This system makes it a lot easier to include external libraries as static,
native modules in MicroPython. Simply pass USER_C_MODULES (like
FROZEN_MPY_DIR) as a make parameter.
Diffstat (limited to 'docs/reference')
-rw-r--r-- | docs/reference/cmodules.rst | 86 | ||||
-rw-r--r-- | docs/reference/index.rst | 8 | ||||
-rw-r--r-- | docs/reference/speed_python.rst | 2 |
3 files changed, 96 insertions, 0 deletions
diff --git a/docs/reference/cmodules.rst b/docs/reference/cmodules.rst new file mode 100644 index 000000000..f361af4a3 --- /dev/null +++ b/docs/reference/cmodules.rst @@ -0,0 +1,86 @@ +Extending MicroPython with C +============================ + +Some specialized code would be unacceptably slow or needs to access hardware in +a way that cannot be done from MicroPython. Therefore, it supports a way of +extending the language with custom modules written in C. But before you consider +writing a module in C, please take a look at :ref:`speed_python`. + +`Unlike CPython <https://docs.python.org/3/extending/building.html>`_, these +modules are (currently) embedded directly in the program image instead of being +dynamically loaded. This requires a `custom build of MicroPython +<https://github.com/micropython/micropython/wiki/Getting-Started>`_. + + +Writing a module +---------------- + +A module is a directory with the following files: + + * ``micropython.mk``, which contains the Makefile fragment for this module. + * All C files you would like included. + +Put the required build commands in ``micropython.mk``. For a simple module, you +will only have to add the file paths to ``SRC_MOD``, which will include these C +files in the build: + +.. highlight:: make +.. code:: + + # Add all C files to SRC_MOD. + SRC_MOD += $(USER_C_MODULES)/example/example.c + +This is a very bare bones module named ``example`` that provides +``example.double(x)``. Note that the name of the module must be equal to the +directory name and is also used in the name of the ``mp_obj_module_t`` object at +the bottom. + +.. highlight:: c +.. code:: + + // Include required definitions first. + #include "py/obj.h" + #include "py/runtime.h" + + // This is the function you will call using example.double(n). + STATIC mp_obj_t example_double(mp_obj_t x_obj) { + // Check input value and convert it to a C type. + if (!MP_OBJ_IS_SMALL_INT(x_obj)) { + mp_raise_ValueError("x is not a small int"); + } + int x = mp_obj_int_get_truncated(x_obj); + + // Calculate the double, and convert back to MicroPython object. + return mp_obj_new_int(x + x); + } + STATIC MP_DEFINE_CONST_FUN_OBJ_1(example_double_obj, example_double); + + // Define all properties of the example module, which currently are the name (a + // string) and a function. + // All identifiers and strings are written as MP_QSTR_xxx and will be + // optimized to word-sized integers by the build system (interned strings). + STATIC const mp_rom_map_elem_t example_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_example) }, + { MP_ROM_QSTR(MP_QSTR_double), MP_ROM_PTR(&example_double_obj) }, + }; + STATIC MP_DEFINE_CONST_DICT(example_module_globals, example_module_globals_table); + + // Define module object. + const mp_obj_module_t example_user_cmodule = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&example_module_globals, + }; + + +Using a module +-------------- + +To build such a module, compile MicroPython (see `getting started +<https://github.com/micropython/micropython/wiki/Getting-Started>`_) with an +extra ``make`` flag named ``USER_C_MODULES`` set to the directory containing +all modules you want included (not to the module itself!). For example: + +.. highlight:: shell +.. code:: + + $ make USER_C_MODULES=path-to-modules-folder all diff --git a/docs/reference/index.rst b/docs/reference/index.rst index d0c7f69de..e2e08a7f7 100644 --- a/docs/reference/index.rst +++ b/docs/reference/index.rst @@ -26,3 +26,11 @@ implementation and the best practices to use them. constrained.rst packages.rst asm_thumb2_index.rst + cmodules.rst + +.. only:: port_pyboard + + .. toctree:: + :maxdepth: 1 + + asm_thumb2_index.rst diff --git a/docs/reference/speed_python.rst b/docs/reference/speed_python.rst index 4db60ec14..c5aa80c6e 100644 --- a/docs/reference/speed_python.rst +++ b/docs/reference/speed_python.rst @@ -1,3 +1,5 @@ +.. _speed_python: + Maximising MicroPython Speed ============================ |