|
4 | 4 | // Used to get the time in the Timer class example. |
5 | 5 | #include "py/mphal.h" |
6 | 6 |
|
| 7 | +static bool custom_library_initialised = false; |
| 8 | + |
7 | 9 | // This is the function which will be called from Python as cexample.add_ints(a, b). |
8 | 10 | static mp_obj_t example_add_ints(mp_obj_t a_obj, mp_obj_t b_obj) { |
9 | 11 | // Extract the ints from the micropython input objects. |
@@ -149,13 +151,57 @@ MP_DEFINE_CONST_OBJ_TYPE( |
149 | 151 | locals_dict, &example_Timer_locals_dict |
150 | 152 | ); |
151 | 153 |
|
| 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 | + |
152 | 196 | // Define all attributes of the module. |
153 | 197 | // Table entries are key/value pairs of the attribute name (a string) |
154 | 198 | // and the MicroPython object reference. |
155 | 199 | // All identifiers and strings are written as MP_QSTR_xxx and will be |
156 | 200 | // optimized to word-sized integers by the build system (interned strings). |
157 | 201 | static const mp_rom_map_elem_t example_module_globals_table[] = { |
158 | 202 | { 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) }, |
159 | 205 | { MP_ROM_QSTR(MP_QSTR_add_ints), MP_ROM_PTR(&example_add_ints_obj) }, |
160 | 206 | { MP_ROM_QSTR(MP_QSTR_Timer), MP_ROM_PTR(&example_type_Timer) }, |
161 | 207 | { MP_ROM_QSTR(MP_QSTR_AdvancedTimer), MP_ROM_PTR(&example_type_AdvancedTimer) }, |
|
0 commit comments