モジュールの実装

この章では、MicroPython でコアモジュールを実装する方法を詳しく説明します。MicroPython のモジュールは、次のいずれかになります。

  • 組み込みモジュール: MicroPython リポジトリの一部である一般的なモジュールです。

  • ユーザーモジュール: 自身のリポジトリやプライベートなコードベースで管理する、特定のプロジェクトに役立つモジュールです。

  • 動的モジュール: 実行時にデバイスへデプロイしてインポートできるモジュールです。

MicroPython のモジュールは、次のいずれかの場所に実装できます。

  • py/: コアの CPython 機能を反映するコアライブラリです。

  • extmod/: 複数のポート間で共有される、CPython または MicroPython 固有のモジュールです。

  • ports/<port>/: ポート固有のモジュールです。

注釈

この章では、py/ に実装されるモジュール、すなわちコアモジュールについて説明します。外部モジュールの実装の詳細については CによるMicroPythonの拡張 を参照してください。ポート固有のモジュールの詳細については MicroPython の移植 を参照してください。

コアモジュールの実装

CPython と同様に、MicroPython には import 文を通じてアクセスできるコア組み込みモジュールがあります。一例として、メモリ管理 で説明した gc モジュールがあります。

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

MicroPython には、ioarray など、その他にもいくつかの組み込み標準/コアモジュールがあります。新しいコアモジュールを追加するには、いくつかの変更が必要です。

まず、py/ ディレクトリに C ファイルを作成します。この例では、modsubsystem.c というファイルに、架空の新しいモジュール subsystem を追加します。

#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

この実装には、モジュールに関連するすべての関数の定義が含まれており、それらの関数を mp_module_subsystem_globals_table 内のモジュールのグローバルテーブルに追加します。また、mp_module_subsystem でモジュールオブジェクトを作成します。続いて、MP_REGISTER_MODULE マクロを介して、このモジュールがより広いシステムに登録されます。

変更した MicroPython をビルドして実行すると、このモジュールがインポートできるようになっているはずです。

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

私たちの info() 関数は現在のところ 1 つの数値を返すだけですが、何でも行えるように拡張できます。同様に、この新しいモジュールにさらに多くの関数を追加することもできます。