Implementacja modułu

Ten rozdział szczegółowo opisuje, jak zaimplementować rdzenny moduł w MicroPython. Moduły MicroPython mogą być jednym z następujących typów:

  • Moduł wbudowany: ogólny moduł będący częścią repozytorium MicroPython.

  • Moduł użytkownika: moduł przydatny dla Twojego konkretnego projektu, który utrzymujesz we własnym repozytorium lub prywatnej bazie kodu.

  • Moduł dynamiczny: moduł, który można wdrożyć i zaimportować na urządzeniu w czasie wykonywania.

Moduł w MicroPython można zaimplementować w jednej z następujących lokalizacji:

  • py/: rdzenna biblioteka odzwierciedlająca podstawową funkcjonalność CPython.

  • extmod/: moduł specyficzny dla CPython lub MicroPython, współdzielony przez wiele portów.

  • ports/<port>/: moduł specyficzny dla portu.

Informacja

Ten rozdział opisuje moduły zaimplementowane w py/, czyli moduły rdzenne. Szczegóły dotyczące implementacji modułu zewnętrznego znajdziesz w Rozszerzanie MicroPython w języku C. Szczegóły dotyczące modułów specyficznych dla portu znajdziesz w Portowanie MicroPython.

Implementacja modułu rdzennego

Podobnie jak CPython, MicroPython posiada rdzenne moduły wbudowane, do których można uzyskać dostęp za pomocą instrukcji import. Przykładem jest moduł gc omówiony w Zarządzanie pamięcią.

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

MicroPython posiada kilka innych wbudowanych modułów standardowych/rdzennych, takich jak io, array itp. Dodanie nowego modułu rdzennego wymaga kilku modyfikacji.

Najpierw utwórz plik C w katalogu py/. W tym przykładzie dodajemy hipotetyczny nowy moduł subsystem w pliku 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

Implementacja zawiera definicję wszystkich funkcji związanych z modułem i dodaje te funkcje do tablicy globalnej modułu w mp_module_subsystem_globals_table. Tworzy ona również obiekt modułu za pomocą mp_module_subsystem. Następnie moduł jest rejestrowany w szerszym systemie za pomocą makra MP_REGISTER_MODULE.

Po zbudowaniu i uruchomieniu zmodyfikowanego MicroPython moduł powinien być teraz możliwy do zaimportowania:

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

Nasza funkcja info() zwraca obecnie tylko jedną liczbę, ale można ją rozszerzyć tak, aby wykonywała dowolne działania. Podobnie do tego nowego modułu można dodać więcej funkcji.