micropython --- 存取與控制 MicroPython 內部機制

函式

micropython.const(expr: int) int

用於宣告該運算式為常數,使編譯器得以最佳化它。此函式的使用方式應如下所示:

from micropython import const

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

以此方式宣告的常數仍可作為全域變數,從宣告它的模組外部存取。另一方面,若常數以底線開頭,則它會被隱藏,無法作為全域變數使用,並且在執行期間不會佔用任何記憶體。

const 函式會被 MicroPython 剖析器直接辨識,並作為 micropython 模組的一部分提供,主要是為了讓所撰寫的指令碼可以依循上述模式同時在 CPython 與 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

印出目前已駐留(interned)字串的資訊。若有給定 verbose 引數,則會印出額外資訊。

所印出的資訊取決於實作,但目前包含已駐留字串的數量以及它們所使用的 RAM 量。在 verbose 模式下,它會印出所有 RAM 駐留字串的名稱。

micropython.stack_use() int

回傳一個代表目前所使用堆疊量的整數。其絕對值並無特別用處,而是應用於計算不同時間點堆疊使用量的差異。

micropython.heap_lock() None

鎖定堆積。在鎖定期間,不會發生任何記憶體配置,且若嘗試任何堆積配置都會引發 MemoryError

鎖定可巢狀:多次呼叫 heap_lock() 會增加鎖定深度。堆積會維持鎖定狀態,直到 heap_unlock() 被呼叫相同次數為止。

若 REPL 在堆積鎖定的情況下變為作用中,則它會被強制解鎖。

micropython.heap_unlock() int

將堆積鎖定深度減一,並以非負整數回傳新的深度。回傳值為 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 操作(例如附加至串列)都保證是不可分割的(atomic)。

  • 特定的移植版本可能會定義「臨界區(critical region)」,在其中已排程的函式絕不會被執行。函式可以在臨界區內被排程,但要等到該區結束後才會執行。臨界區的一個例子是搶佔式中斷處理常式(IRQ)。

  • 在原生程式碼函式內,已排程的函式不會被呼叫,除非該原生程式碼呼叫了某個會特別這麼做的函式。

  • 某些函式,包括 poll.pollpoll.ipolltime.sleeptime.sleep_ms(包含零時長的睡眠),會呼叫已排程的函式。

此函式的一個用途是從搶佔式 IRQ 排程回呼。這類 IRQ 對在其中執行的程式碼施加限制(例如堆積可能被鎖定),而排程一個稍後呼叫的函式便可解除這些限制。

在多執行緒移植版本上,已排程函式的行為取決於該特定移植版本是否啟用全域直譯器鎖(GIL):

  • 若啟用 GIL,該函式可以搶佔任何執行緒並在其情境中執行。

  • 若停用 GIL,該函式只會搶佔主執行緒並在其情境中執行。

註:若 schedule() 是從搶佔式 IRQ 呼叫(此時不允許記憶體配置),且要傳給 schedule() 的回呼是繫結方法(bound method),直接傳入它會失敗。這是因為建立對繫結方法的參考會導致記憶體配置。解決方法是在類別建構函式中建立對該方法的參考,並將該參考傳給 schedule()。此問題在「Creation of Python objects」一節的 參考文件 中有詳細討論。

用於存放已排程函式的佇列是有限的,若佇列已滿,schedule() 會引發 RuntimeError

類別

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

為位元組提供具有串流介面的固定大小環形緩衝區(ringbuffer)。可視為 io.BytesIO 的 FIFO 佇列變體。兩種建構函式形式的差異僅在於後備緩衝區的提供方式:

  • RingIO(size) 會在內部配置後備緩衝區。經典的環形緩衝區演算法會保留一個位元組用於追蹤,因此所配置的緩衝區會比 size 大一個位元組,而該實例可容納完整 size 位元組的資料。例如,RingIO(16) 會配置一個 17 位元組的緩衝區,並容納 16 位元組的資料。

  • RingIO(buffer) 會就地使用所提供的 buffer,而非自行配置。由於有一個位元組保留用於追蹤,該實例可容納 len(buffer) - 1 位元組的資料。例如,RingIO(bytearray(16)) 容納 15 位元組的資料。

當 RingIO 實例用於單一方向傳遞資料時(例如從 IRQ 寫入、由非 IRQ 函式讀取,或反之),它是 IRQ/執行緒安全的。但若單一實例同時從 IRQ 與非 IRQ 情境寫入,此保證便不成立,這通常會導致資料損毀。

any() int

回傳一個整數,計數可供讀取的字元數量。

read(nbytes: int | None = None) bytes

讀取可用的字元。這是一個非阻塞函式。若有指定 nbytes,則最多讀取該數量的位元組,否則盡可能讀取最多的資料。

回傳值:一個包含所讀取位元組的 bytes 物件。若無可用資料,則為長度為零的 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)。對環形緩衝區中的資料沒有任何影響。