Een module implementeren

Dit hoofdstuk beschrijft hoe je een kernmodule in MicroPython implementeert. MicroPython-modules kunnen een van de volgende zijn:

  • Ingebouwde module: een algemene module die deel uitmaakt van de MicroPython-repository.

  • Gebruikersmodule: een module die nuttig is voor jouw specifieke project en die je onderhoudt in je eigen repository of privé-codebase.

  • Dynamische module: een module die tijdens runtime naar je apparaat kan worden gedeployed en geïmporteerd.

Een module in MicroPython kan op een van de volgende locaties worden geïmplementeerd:

  • py/: een kernbibliotheek die de kernfunctionaliteit van CPython weerspiegelt.

  • extmod/: een CPython- of MicroPython-specifieke module die over meerdere ports wordt gedeeld.

  • ports/<port>/: een port-specifieke module.

Notitie

Dit hoofdstuk beschrijft modules die zijn geïmplementeerd in py/, oftewel kernmodules. Zie MicroPython uitbreiden in C voor details over het implementeren van een externe module. Zie MicroPython porten voor details over port-specifieke modules.

Een kernmodule implementeren

Net als CPython heeft MicroPython ingebouwde kernmodules die toegankelijk zijn via import-statements. Een voorbeeld is de gc-module die wordt besproken in Geheugenbeheer.

>>> import gc
>>> gc.enable()
>>>

MicroPython heeft verschillende andere ingebouwde standaard-/kernmodules zoals io, array, enzovoort. Het toevoegen van een nieuwe kernmodule vereist verschillende aanpassingen.

Maak eerst het C-bestand in de map py/. In dit voorbeeld voegen we een hypothetische nieuwe module subsystem toe in het bestand modsubsystem.c:

#include "py/builtin.h"
#include "py/runtime.h"

#if MICROPY_PY_SUBSYSTEM

// info()
static mp_obj_t py_subsystem_info(void) {
    return MP_OBJ_NEW_SMALL_INT(42);
}
MP_DEFINE_CONST_FUN_OBJ_0(subsystem_info_obj, py_subsystem_info);

static const mp_rom_map_elem_t mp_module_subsystem_globals_table[] = {
    { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_subsystem) },
    { MP_ROM_QSTR(MP_QSTR_info), MP_ROM_PTR(&subsystem_info_obj) },
};
static MP_DEFINE_CONST_DICT(mp_module_subsystem_globals, mp_module_subsystem_globals_table);

const mp_obj_module_t mp_module_subsystem = {
    .base = { &mp_type_module },
    .globals = (mp_obj_dict_t *)&mp_module_subsystem_globals,
};

MP_REGISTER_MODULE(MP_QSTR_subsystem, mp_module_subsystem);

#endif

De implementatie bevat een definitie van alle functies die betrekking hebben op de module en voegt de functies toe aan de globale tabel van de module in mp_module_subsystem_globals_table. Het maakt ook het module-object aan met mp_module_subsystem. De module wordt vervolgens geregistreerd bij het bredere systeem via de macro MP_REGISTER_MODULE.

Na het bouwen en uitvoeren van de gewijzigde MicroPython zou de module nu importeerbaar moeten zijn:

>>> import subsystem
>>> subsystem.info()
42
>>>

Onze info()-functie retourneert momenteel slechts één getal, maar kan worden uitgebreid om van alles te doen. Op vergelijkbare wijze kunnen er meer functies aan deze nieuwe module worden toegevoegd.