micropython --- MicroPython の内部へのアクセスと制御

関数

micropython.const(expr: int) int

式が定数であることを宣言して、コンパイラがそれを最適化できるようにするために使用します。この関数は次のように使用します:

from micropython import const

CONST_X = const(123)
CONST_Y = const(2 * CONST_X + 1)

この方法で宣言された定数は、宣言されたモジュールの外部からもグローバル変数としてアクセス可能です。一方、定数がアンダースコアで始まる場合は隠され、グローバル変数として利用できず、実行中にメモリを一切消費しません。

この const 関数は MicroPython パーサーによって直接認識され、主に上記のパターンに従うことで CPython と MicroPython の両方で動作するスクリプトを記述できるように、micropython モジュールの一部として提供されています。

micropython.opt_level(level: int | None = None) int | None

level が指定された場合、この関数は以降のスクリプトのコンパイルの最適化レベルを設定し、None を返します。それ以外の場合は現在の最適化レベルを返します。

最適化レベルは以下のコンパイル機能を制御します:

  • アサーション: レベル 0 ではアサーション文が有効になりバイトコードにコンパイルされます。レベル 1 以上ではアサーションはコンパイルされません。

  • 組み込みの __debug__ 変数: レベル 0 ではこの変数は True に展開されます。レベル 1 以上では False に展開されます。

  • ソースコードの行番号: レベル 0、1、2 ではソースコードの行番号がバイトコードとともに格納され、例外が発生した行番号を報告できます。レベル 3 以上では行番号は格納されません。

デフォルトの最適化レベルは通常レベル 0 です。

micropython.alloc_emergency_exception_buf(size: int) None

緊急例外バッファ用に size バイトの RAM を割り当てます(適切なサイズは 100 バイト程度です)。このバッファは、通常の RAM 割り当てが失敗するような状況(例えば割り込みハンドラ内)で例外を作成するために使用され、そのような状況で有用なトレースバック情報を提供します。

この関数を使用する良い方法は、メインスクリプト(例えば boot.pymain.py)の先頭に配置することです。そうすれば、それに続くすべてのコードに対して緊急例外バッファが有効になります。

micropython.mem_info(verbose: Any | None = None) None

現在使用されているメモリに関する情報を出力します。verbose 引数が指定された場合は、追加情報が出力されます。

出力される情報は実装に依存しますが、現在はスタックとヒープの使用量を含みます。verbose モードでは、ヒープ全体を出力し、どのブロックが使用中でどのブロックが空いているかを示します。

micropython.qstr_info(verbose: Any | None = None) None

現在インターン化されている文字列に関する情報を出力します。verbose 引数が指定された場合は、追加情報が出力されます。

出力される情報は実装に依存しますが、現在はインターン化された文字列の数とそれらが使用する RAM の量を含みます。verbose モードでは、RAM にインターン化されたすべての文字列の名前を出力します。

micropython.stack_use() int

現在使用されているスタックの量を表す整数を返します。この絶対値は特に有用ではなく、むしろ異なる時点でのスタック使用量の差分を計算するために使用すべきです。

micropython.heap_lock() None

ヒープをロックします。ロックされている間はメモリ割り当てが一切発生せず、ヒープの割り当てが試みられると MemoryError が発生します。

ロックはネストします。heap_lock() を複数回呼び出すとロックの深さが増加します。heap_unlock() が同じ回数呼び出されるまで、ヒープはロックされたままになります。

ヒープがロックされた状態で REPL がアクティブになると、強制的にロックが解除されます。

micropython.heap_unlock() int

ヒープのロックの深さを 1 つ減らし、新しい深さを非負整数として返します。戻り値が 0 の場合は、ヒープがもはやロックされておらず、割り当てが再び許可されることを意味します。

micropython.heap_locked() int

現在のヒープのロックの深さを非負整数として返します。0 はヒープがロックされていないことを意味します。

注: この関数は OpenMV Cam では利用できません。

micropython.kbd_intr(chr: int) None

KeyboardInterrupt 例外を発生させる文字を設定します。デフォルトでは、スクリプト実行中はこれが 3 に設定されており、Ctrl-C に対応します。この関数に -1 を渡すと Ctrl-C のキャプチャが無効になり、3 を渡すと復元されます。

この関数は、通常 REPL に使用される入力文字ストリームを他の目的に使用する場合に、そのストリームでの Ctrl-C のキャプチャを防ぐために使用できます。

micropython.schedule(func: Callable[[Any], Any], arg: Any) None

関数 func を「ごく近いうちに」実行するようにスケジュールします。関数には単一の引数として値 arg が渡されます。「ごく近いうちに」とは、MicroPython ランタイムが効率性も保とうとしていることと、以下の条件が満たされることを前提に、可能な限り早い時点で関数を実行するよう最善を尽くすことを意味します:

  • スケジュールされた関数が別のスケジュールされた関数をプリエンプトすることは決してありません。

  • スケジュールされた関数は常に「オペコードの間」で実行されます。これは、すべての基本的な Python 操作(リストへの追加など)がアトミックであることが保証されることを意味します。

  • あるポートは、スケジュールされた関数が決して実行されない「クリティカルリージョン」を定義する場合があります。関数はクリティカルリージョン内でスケジュールできますが、そのリージョンが終了するまで実行されません。クリティカルリージョンの例は、プリエンプトする割り込みハンドラ(IRQ)です。

  • ネイティブコード関数の内部では、ネイティブコードが明示的にそれを行う関数を呼び出さない限り、スケジュールされた関数は呼び出されません。

  • poll.pollpoll.ipolltime.sleeptime.sleep_ms(持続時間ゼロのスリープを含む)などの特定の関数は、スケジュールされた関数を呼び出します。

この関数の用途の 1 つは、プリエンプトする IRQ からコールバックをスケジュールすることです。そのような IRQ は IRQ 内で実行されるコードに制約を課しますが(例えばヒープがロックされている場合があります)、後で呼び出す関数をスケジュールすることでそれらの制約を取り除くことができます。

マルチスレッドのポートでは、スケジュールされた関数の動作は、その特定のポートでグローバルインタプリタロック(GIL)が有効かどうかに依存します:

  • GIL が有効な場合、関数は任意のスレッドをプリエンプトしてそのコンテキストで実行できます。

  • GIL が無効な場合、関数はメインスレッドのみをプリエンプトしてそのコンテキストで実行されます。

注: schedule() がプリエンプトする IRQ から呼び出され、メモリ割り当てが許可されておらず、schedule() に渡すコールバックがバインドされたメソッドである場合、これを直接渡すと失敗します。これは、バインドされたメソッドへの参照を作成するとメモリ割り当てが発生するためです。解決策は、クラスのコンストラクタ内でメソッドへの参照を作成し、その参照を schedule() に渡すことです。これについては リファレンスドキュメント の「Creation of Python objects」で詳しく説明されています。

スケジュールされた関数を保持するキューは有限であり、キューが一杯の場合 schedule()RuntimeError を発生させます。

クラス

class micropython.RingIO(size: int)
class micropython.RingIO(buffer: bytes | bytearray | memoryview)

ストリームインターフェースを持つバイト用の固定サイズのリングバッファを提供します。io.BytesIO の FIFO キュー変種と考えることができます。2 つのコンストラクタ形式は、バッキングバッファの供給方法のみが異なります:

  • RingIO(size) はバッキングバッファを内部で割り当てます。古典的なリングバッファのアルゴリズムは追跡用に 1 バイトを予約するため、割り当てられるバッファは size より 1 バイト大きくなり、インスタンスは size バイトのデータをすべて保持できます。例えば RingIO(16) は 17 バイトのバッファを割り当て、16 バイトのデータを保持します。

  • RingIO(buffer) は新たに割り当てる代わりに、供給された buffer をその場で使用します。追跡用に 1 バイトが予約されるため、インスタンスは len(buffer) - 1 バイトのデータを保持できます。例えば RingIO(bytearray(16)) は 15 バイトのデータを保持します。

RingIO インスタンスは、データを一方向に渡すために使用される場合(例えば IRQ から書き込まれ非 IRQ 関数から読み取られる場合、またはその逆の場合)、IRQ およびスレッドセーフです。単一のインスタンスが IRQ コンテキストと非 IRQ コンテキストの両方から書き込まれる場合はこれが成り立たず、しばしばデータ破損を引き起こします。

any() int

読み取れる文字数を数えた整数を返します。

read(nbytes: int | None = None) bytes

利用可能な文字を読み取ります。これは非ブロッキング関数です。nbytes が指定された場合は最大でそのバイト数を読み取り、それ以外の場合は可能な限り多くのデータを読み取ります。

戻り値: 読み取ったバイトを含む bytes オブジェクト。データが利用できない場合は長さ 0 の bytes オブジェクトになります。

readline(nbytes: int | None = None) bytes

バッファ内に存在する場合は改行文字または復帰で終わる行を読み取り、それ以外の場合はバッファ内の利用可能なバイトを返します。nbytes が指定された場合は最大でそのバイト数を読み取ります。

戻り値: 読み取った行を含む bytes オブジェクト。

readinto(buf: bytearray | memoryview, nbytes: int | None = None) int

利用可能なバイトを提供された buf に読み込みます。nbytes が指定された場合は最大でそのバイト数を読み取ります。それ以外の場合は最大で len(buf) バイトを読み取ります。

戻り値: buf に読み込まれたバイト数の整数カウント。

write(buf: bytes | bytearray | memoryview) int

buf からリングバッファへのバイトの非ブロッキング書き込みです。リングバッファ内の利用可能なスペースによって制限されます。

戻り値: 書き込まれたバイト数の整数カウント。

close() None

標準の stream インターフェースの一部として提供される No-op です。リングバッファ内のデータには影響しません。