@@ -49,133 +49,123 @@ A MicroPython user C module is a directory with the following files:
4949 expanded copy of ``$(USERMOD_DIR) `` to ``SRC_USERMOD ``, eg
5050 ``SRC_USERMOD += $(EXAMPLE_MOD_DIR)/example.c ``
5151
52- If you have custom ``CFLAGS `` settings or include folders to define, these
53- should be added to ``CFLAGS_USERMOD ``, or ``CXXFLAGS_USERMOD ``.
52+ If you have custom compiler options (like ``-I `` to add directories to search
53+ for header files), these should be added to ``CFLAGS_USERMOD `` for C code
54+ and to ``CXXFLAGS_USERMOD `` for C++ code.
5455
5556 See below for full usage example.
5657
5758
5859Basic example
5960-------------
6061
61- This simple module named ``example `` provides a single function
62- ``example.add_ints(a, b) `` which adds the two integer args together and returns
63- the result.
62+ This simple module named ``cexample `` provides a single function
63+ ``cexample.add_ints(a, b) `` which adds the two integer args together and returns
64+ the result. It can be found in the MicroPython source tree and has
65+ a source file and a Makefile fragment with content as descibed above::
6466
65- Directory::
67+ micropython/
68+ └──examples/
69+ └──usercmodule/
70+ └──cexample/
71+ ├── examplemodule.c
72+ └── micropython.mk
6673
67- example/
68- ├── example.c
69- └── micropython.mk
74+ Refer to the comments in these 2 files for additional explanation.
75+ Next to the ``cexample `` module there's also ``cppexample `` which
76+ works in the same way but shows one way of mixing C and C++ code
77+ in MicroPython.
7078
7179
72- ``example.c ``
73-
74- .. code-block :: c
75-
76- // Include required definitions first.
77- #include "py/obj.h"
78- #include "py/runtime.h"
79- #include "py/builtin.h"
80-
81- // This is the function which will be called from Python as example.add_ints(a, b).
82- STATIC mp_obj_t example_add_ints(mp_obj_t a_obj, mp_obj_t b_obj) {
83- // Extract the ints from the micropython input objects
84- int a = mp_obj_get_int(a_obj);
85- int b = mp_obj_get_int(b_obj);
80+ Compiling the cmodule into MicroPython
81+ --------------------------------------
8682
87- // Calculate the addition and convert to MicroPython object.
88- return mp_obj_new_int(a + b);
89- }
90- // Define a Python reference to the function above
91- STATIC MP_DEFINE_CONST_FUN_OBJ_2(example_add_ints_obj, example_add_ints);
83+ To build such a module, compile MicroPython (see `getting started
84+ <https://github.com/micropython/micropython/wiki/Getting-Started> `_),
85+ applying 2 modifications:
9286
93- // Define all properties of the example module.
94- // Table entries are key/value pairs of the attribute name (a string)
95- // and the MicroPython object reference.
96- // All identifiers and strings are written as MP_QSTR_xxx and will be
97- // optimized to word-sized integers by the build system (interned strings).
98- STATIC const mp_rom_map_elem_t example_module_globals_table[] = {
99- { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_example) },
100- { MP_ROM_QSTR(MP_QSTR_add_ints), MP_ROM_PTR(&example_add_ints_obj) },
101- };
102- STATIC MP_DEFINE_CONST_DICT(example_module_globals, example_module_globals_table);
87+ - an extra ``make `` flag named ``USER_C_MODULES `` set to the directory
88+ containing all modules you want included (not to the module itself).
89+ For building the example modules which come with MicroPython,
90+ set ``USER_C_MODULES `` to the ``examples/usercmodule `` directory.
91+ For your own projects it's more convenient to keep custom code out of
92+ the main source tree so a typical project directory structure will look
93+ like this::
10394
104- // Define module object.
105- const mp_obj_module_t example_user_cmodule = {
106- .base = { &mp_type_module },
107- .globals = (mp_obj_dict_t*)&example_module_globals,
108- };
95+ my_project/
96+ ├── modules/
97+ │ └──example1/
98+ │ ├──example1.c
99+ │ └──micropython.mk
100+ │ └──example2/
101+ │ ├──example2.c
102+ │ └──micropython.mk
103+ └── micropython/
104+ ├──ports/
105+ ... ├──stm32/
106+ ...
109107
110- // Register the module to make it available in Python
111- MP_REGISTER_MODULE(MP_QSTR_example, example_user_cmodule, MODULE_EXAMPLE_ENABLED);
112108
109+ with ``USER_C_MODULES `` set to the ``my_project/modules `` directory.
113110
114- ``micropython.mk ``
111+ - all modules found in this directory will be compiled, but only those
112+ which are explicitly enabled will be availabe for importing. Enabling a
113+ module is done by setting the preprocessor define from its module
114+ registration to 1. For example if the source code defines the module with
115115
116- .. code-block :: make
116+ .. code-block :: c
117117
118- EXAMPLE_MOD_DIR := $(USERMOD_DIR)
118+ MP_REGISTER_MODULE(MP_QSTR_cexample, example_user_cmodule, MODULE_CEXAMPLE_ENABLED);
119119
120- # Add all C files to SRC_USERMOD.
121- SRC_USERMOD += $(EXAMPLE_MOD_DIR)/example.c
122120
123- # We can add our module folder to include paths if needed
124- # This is not actually needed in this example.
125- CFLAGS_USERMOD += -I$(EXAMPLE_MOD_DIR)
121+ then ``MODULE_CEXAMPLE_ENABLED `` has to be set to 1 to make the module available.
122+ This can be done by adding ``CFLAGS_EXTRA=-DMODULE_CEXAMPLE_ENABLED=1 `` to
123+ the ``make `` command, or editing ``mpconfigport.h `` or ``mpconfigboard.h ``
124+ to add
126125
127- Finally you will need to define ``MODULE_EXAMPLE_ENABLED `` to 1. This
128- can be done by adding ``CFLAGS_EXTRA=-DMODULE_EXAMPLE_ENABLED=1 `` to
129- the ``make `` command, or editing ``mpconfigport.h `` or
130- ``mpconfigboard.h `` to add
126+ .. code-block :: c
131127
132- .. code-block :: c
128+ #define MODULE_CEXAMPLE_ENABLED (1)
133129
134- #define MODULE_EXAMPLE_ENABLED (1)
135130
136- Note that the exact method depends on the port as they have different
137- structures. If not done correctly it will compile but importing will
138- fail to find the module.
131+ Note that the exact method depends on the port as they have different
132+ structures. If not done correctly it will compile but importing will
133+ fail to find the module.
139134
135+ To sum up, here's how the ``cexample `` module from the ``examples/usercmodule ``
136+ directory can be built for the unix port:
140137
141- Compiling the cmodule into MicroPython
142- --------------------------------------
138+ .. code-block :: bash
143139
144- To build such a module, compile MicroPython (see `getting started
145- <https://github.com/micropython/micropython/wiki/Getting-Started> `_) with an
146- extra ``make `` flag named ``USER_C_MODULES `` set to the directory containing
147- all modules you want included (not to the module itself). For example:
140+ cd micropython/ports/unix
141+ make USER_C_MODULES=../../examples/usercmodule CFLAGS_EXTRA=-DMODULE_CEXAMPLE_ENABLED=1 all
148142
143+ The build output will show the modules found::
149144
150- Directory::
145+ ...
146+ Including User C Module from ../../examples/usercmodule/cexample
147+ Including User C Module from ../../examples/usercmodule/cppexample
148+ ...
151149
152- my_project/
153- ├── modules/
154- │ └──example/
155- │ ├──example.c
156- │ └──micropython.mk
157- └── micropython/
158- ├──ports/
159- ... ├──stm32/
160- ...
161150
162- Building for stm32 port:
151+ Or for your own project with a directory structure as shown above,
152+ including both modules and building the stm32 port for example:
163153
164154.. code-block :: bash
165155
166156 cd my_project/micropython/ports/stm32
167- make USER_C_MODULES=../../../modules CFLAGS_EXTRA=-DMODULE_EXAMPLE_ENABLED=1 all
157+ make USER_C_MODULES=../../../modules \
158+ CFLAGS_EXTRA=" -DMODULE_EXAMPLE1_ENABLED=1 -DMODULE_EXAMPLE2_ENABLED=1" all
168159
169160
170161 Module usage in MicroPython
171162---------------------------
172163
173- Once built into your copy of MicroPython, the module implemented
174- in ``example.c `` above can now be accessed in Python just
175- like any other builtin module, eg
164+ Once built into your copy of MicroPython, the module
165+ can now be accessed in Python just like any other builtin module, e.g.
176166
177167.. code-block :: python
178168
179- import example
180- print (example .add_ints(1 , 3 ))
169+ import cexample
170+ print (cexample .add_ints(1 , 3 ))
181171 # should display 4
0 commit comments