Skip to content

Commit 470ad28

Browse files
committed
examples/usercmodule: Add atexit, __init__ and root pointer to cexample.
Signed-off-by: Andrew Leech <[email protected]>
1 parent 54508e2 commit 470ad28

File tree

1 file changed

+48
-0
lines changed

1 file changed

+48
-0
lines changed

examples/usercmodule/cexample/examplemodule.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
// Include MicroPython API.
22
#include "py/runtime.h"
3+
#include "py/modatexit.h"
34

45
// Used to get the time in the Timer class example.
56
#include "py/mphal.h"
67

8+
static bool custom_library_initialised = false;
9+
710
// This is the function which will be called from Python as cexample.add_ints(a, b).
811
static mp_obj_t example_add_ints(mp_obj_t a_obj, mp_obj_t b_obj) {
912
// Extract the ints from the micropython input objects.
@@ -149,13 +152,58 @@ MP_DEFINE_CONST_OBJ_TYPE(
149152
locals_dict, &example_Timer_locals_dict
150153
);
151154

155+
// If any data/struct needs to be allocated it should
156+
// be stored in a root pointer to inform the gc not to
157+
// collect it.
158+
// Note this will be reset during a soft-reset.
159+
MP_REGISTER_ROOT_POINTER(uint8_t *example_c_mod_buffer);
160+
161+
MP_DECLARE_CONST_FUN_OBJ_0(example_deinit_obj);
162+
163+
// This __init__ function will be run during module import if
164+
// micropython is built with MICROPY_MODULE_BUILTIN_INIT enabled.
165+
static mp_obj_t example___init__(void) {
166+
if (!custom_library_initialised) {
167+
// __init__ for builtins is called each time the module is imported,
168+
// so ensure that initialisation only happens once.
169+
custom_library_initialised = true;
170+
// this is a good place to create any buffers needed and initialise c libraries or
171+
// hardware peripherals that only need setup once before use by your application.
172+
MP_STATE_VM(example_c_mod_buffer) = m_malloc(8);
173+
174+
#if MICROPY_PY_ATEXIT
175+
mp_atexit_register(MP_OBJ_FROM_PTR(&example_deinit_obj));
176+
#endif
177+
}
178+
return mp_const_none;
179+
}
180+
static MP_DEFINE_CONST_FUN_OBJ_0(example___init___obj, example___init__);
181+
182+
// This will be run during exit / soft-reset (if MICROPY_PY_ATEXIT and
183+
// MICROPY_MODULE_BUILTIN_INIT are enabled) and can be used to reset any
184+
// global static verifies
185+
static mp_obj_t example_deinit(void) {
186+
// This is registered in __init__ be run during exit / soft-reset.
187+
if (custom_library_initialised) {
188+
// global / static are not automatically reset during exit so reset here.
189+
custom_library_initialised = false;
190+
// this can also be used to reset hardware peripherals or c library
191+
// resources such that they're safe to re-initialise in __init__
192+
// again after the soft-reset is complete.
193+
}
194+
return mp_const_none;
195+
}
196+
MP_DEFINE_CONST_FUN_OBJ_0(example_deinit_obj, example_deinit);
197+
152198
// Define all attributes of the module.
153199
// Table entries are key/value pairs of the attribute name (a string)
154200
// and the MicroPython object reference.
155201
// All identifiers and strings are written as MP_QSTR_xxx and will be
156202
// optimized to word-sized integers by the build system (interned strings).
157203
static const mp_rom_map_elem_t example_module_globals_table[] = {
158204
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_cexample) },
205+
{ MP_ROM_QSTR(MP_QSTR___init__), MP_ROM_PTR(&example___init___obj) },
206+
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&example_deinit_obj) },
159207
{ MP_ROM_QSTR(MP_QSTR_add_ints), MP_ROM_PTR(&example_add_ints_obj) },
160208
{ MP_ROM_QSTR(MP_QSTR_Timer), MP_ROM_PTR(&example_type_Timer) },
161209
{ MP_ROM_QSTR(MP_QSTR_AdvancedTimer), MP_ROM_PTR(&example_type_AdvancedTimer) },

0 commit comments

Comments
 (0)