Skip to content

Commit 14dfc25

Browse files
pi-anlandrewleech
authored andcommitted
examples/usercmodule: Add atexit, __init__ and root pointer to cexample.
Signed-off-by: Andrew Leech <[email protected]>
1 parent b920df3 commit 14dfc25

File tree

1 file changed

+46
-0
lines changed

1 file changed

+46
-0
lines changed

examples/usercmodule/cexample/examplemodule.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
// Used to get the time in the Timer class example.
55
#include "py/mphal.h"
66

7+
static bool custom_library_initialised = false;
8+
79
// This is the function which will be called from Python as cexample.add_ints(a, b).
810
static mp_obj_t example_add_ints(mp_obj_t a_obj, mp_obj_t b_obj) {
911
// Extract the ints from the micropython input objects.
@@ -149,13 +151,57 @@ MP_DEFINE_CONST_OBJ_TYPE(
149151
locals_dict, &example_Timer_locals_dict
150152
);
151153

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

0 commit comments

Comments
 (0)