summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/develop/cmodules.rst163
-rw-r--r--docs/develop/index.rst15
-rw-r--r--docs/index.rst1
-rw-r--r--docs/reference/cmodules.rst86
-rw-r--r--docs/reference/index.rst8
5 files changed, 179 insertions, 94 deletions
diff --git a/docs/develop/cmodules.rst b/docs/develop/cmodules.rst
new file mode 100644
index 000000000..c3de90a0f
--- /dev/null
+++ b/docs/develop/cmodules.rst
@@ -0,0 +1,163 @@
+MicroPython external C modules
+==============================
+
+When developing modules for use with MicroPython you may find you run into
+limitations with the Python environment, often due to an inability to access
+certain hardware resources or Python speed limitations.
+
+If your limitations can't be resolved with suggestions in :ref:`speed_python`,
+writing some or all of your module in C is a viable option.
+
+If your module is designed to access or work with commonly available
+hardware or libraries please consider implementing it inside the MicroPython
+source tree alongside similar modules and submitting it as a pull request.
+If however you're targeting obscure or proprietary systems it may make
+more sense to keep this external to the main MicroPython repository.
+
+This chapter describes how to compile such external modules into the
+MicroPython executable or firmware image.
+
+
+Structure of an external C module
+---------------------------------
+
+A MicroPython user C module is a directory with the following files:
+
+* ``*.c`` and/or ``*.h`` source code files for your module.
+
+ These will typically include the low level functionality being implemented and
+ the MicroPython binding functions to expose the functions and module(s).
+
+ Currently the best reference for writing these functions/modules is
+ to find similar modules within the MicroPython tree and use them as examples.
+
+* ``micropython.mk`` contains the Makefile fragment for this module.
+
+ ``$(USERMOD_DIR)`` is available in ``micropython.mk`` as the path to your
+ module directory. As it's redefined for each c module, is should be expanded
+ in your ``micropython.mk`` to a local make variable,
+ eg ``EXAMPLE_MOD_DIR := $(USERMOD_DIR)``
+
+ Your ``micropython.mk`` must add your modules C files relative to your
+ expanded copy of ``$(USERMOD_DIR)`` to ``SRC_USERMOD``, eg
+ ``SRC_USERMOD += $(EXAMPLE_MOD_DIR)/example.c``
+
+ If you have custom ``CFLAGS`` settings or include folders to define, these
+ should be added to ``CFLAGS_USERMOD``.
+
+ See below for full usage example.
+
+
+Basic Example
+-------------
+
+This simple module named ``example`` provides a single function
+``example.add_ints(a, b)`` which adds the two integer args together and returns
+the result.
+
+Directory::
+
+ example/
+ ├── example.c
+ └── micropython.mk
+
+
+``example.c``
+
+.. code-block:: c
+
+ // Include required definitions first.
+ #include "py/obj.h"
+ #include "py/runtime.h"
+ #include "py/builtin.h"
+
+ #define MODULE_EXAMPLE_ENABLED (1)
+
+ // This is the function which will be called from Python as example.add_ints(a, b).
+ STATIC mp_obj_t example_add_ints(mp_obj_t a_obj, mp_obj_tab_obj) {
+ // Extract the ints from the micropython input objects
+ int a = mp_obj_get_int(a_obj);
+ int b = mp_obj_get_int(b_obj);
+
+ // Calculate the addition and convert to MicroPython object.
+ return mp_obj_new_int(a + b);
+ }
+ // Define a Python reference to the function above
+ STATIC MP_DEFINE_CONST_FUN_OBJ_1(example_add_ints_obj, example_add_ints);
+
+ // Define all properties of the example module.
+ // Table entries are key/value pairs of the attribute name (a string)
+ // and the MicroPython object reference.
+ // 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_add_ints), MP_ROM_PTR(&example_add_ints_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,
+ };
+
+ // Register the module to make it available in Python
+ MP_REGISTER_MODULE(MP_QSTR_example, example_user_cmodule, MODULE_EXAMPLE_ENABLED);
+
+
+``micropython.mk``
+
+.. code-block:: make
+
+ EXAMPLE_MOD_DIR := $(USERMOD_DIR)
+
+ # Add all C files to SRC_USERMOD.
+ SRC_USERMOD += $(EXAMPLE_MOD_DIR)/example.c
+
+ # We can add our module folder to include paths if needed
+ # This is not actually needed in this example.
+ CFLAGS_USERMOD += -I$(EXAMPLE_MOD_DIR)
+
+
+Compiling the cmodule into MicroPython
+--------------------------------------
+
+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:
+
+
+Directory::
+
+ my_project/
+ ├── modules/
+ │ └──example/
+ │ ├──example.c
+ │ └──micropython.mk
+ └── micropython/
+ ├──ports/
+ ... ├──stm32/
+ ...
+
+Building for stm32 port:
+
+.. code-block:: bash
+
+ cd my_project/micropython/ports/stm32
+ make USER_C_MODULES=../../../modules all
+
+
+Module usage in MicroPython
+---------------------------
+
+Once built into your copy of MicroPython, the module implemented
+in ``example.c`` above can now be accessed in Python just
+like any other builtin module, eg
+
+.. code-block:: python
+
+ import example
+ print(example.add_ints(1, 3))
+ # should display 4
diff --git a/docs/develop/index.rst b/docs/develop/index.rst
new file mode 100644
index 000000000..6b7b3c391
--- /dev/null
+++ b/docs/develop/index.rst
@@ -0,0 +1,15 @@
+Developing and building MicroPython
+===================================
+
+This chapter describes modules (function and class libraries) which are built
+into MicroPython. There are a few categories of such modules:
+
+This chapter describes some options for extending MicroPython in C. Note
+that it doesn't aim to be a complete guide for developing with MicroPython.
+See the `getting started guide
+<https://github.com/micropython/micropython/wiki/Getting-Started>`_ for further information.
+
+.. toctree::
+ :maxdepth: 1
+
+ cmodules.rst
diff --git a/docs/index.rst b/docs/index.rst
index 235185b6c..c0417c227 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -6,6 +6,7 @@ MicroPython documentation and references
library/index.rst
reference/index.rst
genrst/index.rst
+ develop/index.rst
license.rst
pyboard/quickref.rst
esp8266/quickref.rst
diff --git a/docs/reference/cmodules.rst b/docs/reference/cmodules.rst
deleted file mode 100644
index f361af4a3..000000000
--- a/docs/reference/cmodules.rst
+++ /dev/null
@@ -1,86 +0,0 @@
-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 e2e08a7f7..d0c7f69de 100644
--- a/docs/reference/index.rst
+++ b/docs/reference/index.rst
@@ -26,11 +26,3 @@ 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