summaryrefslogtreecommitdiff
path: root/docs/reference
diff options
context:
space:
mode:
authorAyke van Laethem <aykevanlaethem@gmail.com>2018-06-14 15:57:29 +0200
committerDamien George <damien.p.george@gmail.com>2019-03-08 22:49:00 +1100
commit2e516074daee76fb3e0710a893a0f40532bb3252 (patch)
treed871d641c10aff22e3d80ad4711310c4b7be4b31 /docs/reference
parentcf22f4793cb04e8e63a0d11f479a69c9be6c93ba (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.rst86
-rw-r--r--docs/reference/index.rst8
-rw-r--r--docs/reference/speed_python.rst2
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
============================