Implementare un modulo

Questo capitolo descrive in dettaglio come implementare un modulo principale in MicroPython. I moduli MicroPython possono essere uno dei seguenti tipi:

  • Modulo integrato: un modulo generico che fa parte del repository MicroPython.

  • Modulo utente: un modulo utile per il tuo progetto specifico che mantieni nel tuo repository o in un codebase privato.

  • Modulo dinamico: un modulo che può essere distribuito e importato a runtime sul tuo dispositivo.

Un modulo in MicroPython può essere implementato in una delle seguenti posizioni:

  • py/: una libreria principale che rispecchia le funzionalità principali di CPython.

  • extmod/: un modulo specifico di CPython o MicroPython condiviso tra più port.

  • ports/<port>/: un modulo specifico di un port.

Nota

Questo capitolo descrive i moduli implementati in py/, ovvero i moduli principali. Consulta Estendere MicroPython in C per i dettagli sull’implementazione di un modulo esterno. Per i dettagli sui moduli specifici di un port, consulta Porting di MicroPython.

Implementare un modulo principale

Come CPython, MicroPython dispone di moduli integrati principali accessibili tramite istruzioni import. Un esempio è il modulo gc discusso in Gestione della memoria.

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

MicroPython dispone di diversi altri moduli standard/principali integrati come io, array, ecc. L’aggiunta di un nuovo modulo principale comporta diverse modifiche.

Per prima cosa, crea il file C nella directory py/. In questo esempio aggiungiamo un ipotetico nuovo modulo subsystem nel file 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

L’implementazione include una definizione di tutte le funzioni relative al modulo e aggiunge le funzioni alla tabella globale del modulo in mp_module_subsystem_globals_table. Crea inoltre l’oggetto modulo con mp_module_subsystem. Il modulo viene quindi registrato nel sistema più ampio tramite la macro MP_REGISTER_MODULE.

Dopo aver compilato ed eseguito il MicroPython modificato, il modulo dovrebbe ora essere importabile:

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

La nostra funzione info() attualmente restituisce solo un singolo numero, ma può essere estesa per fare qualsiasi cosa. Allo stesso modo, è possibile aggiungere altre funzioni a questo nuovo modulo.