micropython — Zugriff auf und Steuerung von MicroPython-Interna¶
Funktionen¶
- micropython.const(expr: int) int¶
Wird verwendet, um zu deklarieren, dass der Ausdruck eine Konstante ist, sodass der Compiler ihn optimieren kann. Diese Funktion sollte wie folgt verwendet werden:
from micropython import const CONST_X = const(123) CONST_Y = const(2 * CONST_X + 1)
Auf diese Weise deklarierte Konstanten sind nach wie vor als globale Variablen von außerhalb des Moduls zugänglich, in dem sie deklariert wurden. Beginnt eine Konstante dagegen mit einem Unterstrich, dann ist sie verborgen, steht nicht als globale Variable zur Verfügung und belegt während der Ausführung keinen Speicher.
Diese
const-Funktion wird vom MicroPython-Parser direkt erkannt und wird als Teil des Modulsmicropythonhauptsächlich deshalb bereitgestellt, damit Skripte geschrieben werden können, die nach dem obigen Muster sowohl unter CPython als auch unter MicroPython laufen.
- micropython.opt_level(level: int | None = None) int | None¶
Wenn level angegeben ist, legt diese Funktion die Optimierungsstufe für die anschließende Kompilierung von Skripten fest und gibt
Nonezurück. Andernfalls gibt sie die aktuelle Optimierungsstufe zurück.Die Optimierungsstufe steuert die folgenden Kompilierungsmerkmale:
Assertions: Auf Stufe 0 sind Assertion-Anweisungen aktiviert und werden in den Bytecode kompiliert; auf Stufe 1 und höher werden Assertions nicht kompiliert.
Eingebaute
__debug__-Variable: Auf Stufe 0 wird diese Variable zuTrueausgewertet; auf Stufe 1 und höher zuFalse.Quellcode-Zeilennummern: Auf Stufe 0, 1 und 2 werden die Quellcode-Zeilennummern zusammen mit dem Bytecode gespeichert, sodass Exceptions die Zeilennummer melden können, an der sie aufgetreten sind; auf Stufe 3 und höher werden Zeilennummern nicht gespeichert.
Die Standard-Optimierungsstufe ist üblicherweise Stufe 0.
- micropython.alloc_emergency_exception_buf(size: int) None¶
Reserviert size Bytes RAM für den Notfall-Exception-Puffer (eine gute Größe sind etwa 100 Bytes). Der Puffer wird verwendet, um Exceptions in Fällen zu erzeugen, in denen die normale RAM-Reservierung fehlschlagen würde (z. B. innerhalb eines Interrupt-Handlers), und liefert in diesen Situationen daher nützliche Traceback-Informationen.
Eine gute Möglichkeit, diese Funktion zu verwenden, besteht darin, sie an den Anfang Ihres Hauptskripts zu setzen (z. B.
boot.pyodermain.py); dann ist der Notfall-Exception-Puffer für den gesamten nachfolgenden Code aktiv.
- micropython.mem_info(verbose: Any | None = None) None¶
Gibt Informationen über den aktuell verwendeten Speicher aus. Wenn das Argument verbose angegeben ist, werden zusätzliche Informationen ausgegeben.
Die ausgegebenen Informationen sind implementierungsabhängig, umfassen derzeit aber die Menge des verwendeten Stacks und Heaps. Im verbose-Modus wird der gesamte Heap ausgegeben, wobei angezeigt wird, welche Blöcke belegt und welche frei sind.
- micropython.qstr_info(verbose: Any | None = None) None¶
Gibt Informationen über die aktuell internierten Strings aus. Wenn das Argument verbose angegeben ist, werden zusätzliche Informationen ausgegeben.
Die ausgegebenen Informationen sind implementierungsabhängig, umfassen derzeit aber die Anzahl der internierten Strings und die Menge des RAM, den sie belegen. Im verbose-Modus werden die Namen aller im RAM internierten Strings ausgegeben.
- micropython.stack_use() int¶
Gibt eine Ganzzahl zurück, die die aktuell verwendete Menge an Stack darstellt. Der absolute Wert ist nicht besonders nützlich; vielmehr sollte er verwendet werden, um Unterschiede in der Stack-Nutzung an verschiedenen Punkten zu berechnen.
- micropython.heap_lock() None¶
Sperrt den Heap. Während er gesperrt ist, kann keine Speicherreservierung erfolgen, und ein
MemoryErrorwird ausgelöst, wenn eine Heap-Reservierung versucht wird.Sperren sind verschachtelbar: Ein mehrfacher Aufruf von
heap_lock()erhöht die Sperrtiefe. Der Heap bleibt gesperrt, bisheap_unlock()gleich oft aufgerufen wurde.Wenn die REPL aktiv wird, während der Heap gesperrt ist, wird er zwangsweise entsperrt.
- micropython.heap_unlock() int¶
Verringert die Heap-Sperrtiefe um eins und gibt die neue Tiefe als nichtnegative Ganzzahl zurück. Ein Rückgabewert von
0bedeutet, dass der Heap nicht mehr gesperrt ist und Reservierungen wieder erlaubt sind.
- micropython.heap_locked() int¶
Gibt die aktuelle Heap-Sperrtiefe als nichtnegative Ganzzahl zurück;
0bedeutet, dass der Heap nicht gesperrt ist.Hinweis: Diese Funktion ist auf der OpenMV Cam nicht verfügbar.
- micropython.kbd_intr(chr: int) None¶
Legt das Zeichen fest, das eine
KeyboardInterrupt-Exception auslöst. Standardmäßig ist dies während der Skriptausführung auf 3 gesetzt, was Strg-C entspricht. Die Übergabe von -1 an diese Funktion deaktiviert die Erfassung von Strg-C, und die Übergabe von 3 stellt sie wieder her.Diese Funktion kann verwendet werden, um die Erfassung von Strg-C im eingehenden Zeichenstrom zu verhindern, der normalerweise für die REPL verwendet wird, falls dieser Strom für andere Zwecke genutzt wird.
- micropython.schedule(func: Callable[[Any], Any], arg: Any) None¶
Plant die Funktion func zur Ausführung „sehr bald“. Der Funktion wird der Wert arg als ihr einziges Argument übergeben. „Sehr bald“ bedeutet, dass die MicroPython-Laufzeitumgebung ihr Bestes tut, die Funktion zum frühestmöglichen Zeitpunkt auszuführen, wobei sie auch versucht, effizient zu sein, und sofern die folgenden Bedingungen gelten:
Eine geplante Funktion wird niemals eine andere geplante Funktion verdrängen.
Geplante Funktionen werden stets „zwischen Opcodes“ ausgeführt, was bedeutet, dass alle grundlegenden Python-Operationen (wie etwa das Anhängen an eine Liste) garantiert atomar sind.
Ein bestimmter Port kann „kritische Bereiche“ definieren, innerhalb derer geplante Funktionen niemals ausgeführt werden. Funktionen können innerhalb eines kritischen Bereichs geplant werden, aber sie werden erst ausgeführt, wenn dieser Bereich verlassen wird. Ein Beispiel für einen kritischen Bereich ist ein verdrängender Interrupt-Handler (ein IRQ).
Innerhalb von Native-Code-Funktionen werden geplante Funktionen nicht aufgerufen, es sei denn, der Native-Code ruft eine Funktion auf, die dies ausdrücklich tut.
Bestimmte Funktionen wie
poll.poll,poll.ipoll,time.sleepundtime.sleep_ms(einschließlich Sleeps mit der Dauer null) rufen geplante Funktionen auf.
Eine Verwendungsmöglichkeit dieser Funktion besteht darin, einen Callback aus einem verdrängenden IRQ heraus zu planen. Ein solcher IRQ legt Einschränkungen für den im IRQ ausgeführten Code fest (zum Beispiel kann der Heap gesperrt sein), und das Planen einer Funktion zur späteren Ausführung hebt diese Einschränkungen auf.
Auf Ports mit mehreren Threads hängt das Verhalten der geplanten Funktion davon ab, ob das Global Interpreter Lock (GIL) für den jeweiligen Port aktiviert ist:
Wenn das GIL aktiviert ist, kann die Funktion jeden Thread verdrängen und in dessen Kontext laufen.
Wenn das GIL deaktiviert ist, verdrängt die Funktion nur den Haupt-Thread und läuft in dessen Kontext.
Hinweis: Wenn
schedule()aus einem verdrängenden IRQ heraus aufgerufen wird, wenn keine Speicherreservierung erlaubt ist und der anschedule()zu übergebende Callback eine gebundene Methode ist, schlägt die direkte Übergabe fehl. Das liegt daran, dass das Erstellen einer Referenz auf eine gebundene Methode eine Speicherreservierung verursacht. Eine Lösung besteht darin, im Klassenkonstruktor eine Referenz auf die Methode zu erstellen und diese Referenz anschedule()zu übergeben. Dies wird ausführlich hier in der Referenzdokumentation unter „Creation of Python objects“ behandelt.Es gibt eine endliche Warteschlange für die geplanten Funktionen, und
schedule()löst einenRuntimeErroraus, wenn die Warteschlange voll ist.
Klassen¶
- class micropython.RingIO(size: int)¶
- class micropython.RingIO(buffer: bytes | bytearray | memoryview)
Stellt einen Ringpuffer fester Größe für Bytes mit einer Stream-Schnittstelle bereit. Kann als FIFO-Warteschlangenvariante von
io.BytesIObetrachtet werden. Die beiden Konstruktorformen unterscheiden sich nur darin, wie der zugrunde liegende Puffer bereitgestellt wird:RingIO(size)reserviert den zugrunde liegenden Puffer intern. Der klassische Ringpuffer-Algorithmus reserviert ein Byte zur Nachverfolgung, sodass der reservierte Puffer ein Byte größer alssizeist und die Instanz die vollensizeBytes an Daten aufnehmen kann. Zum Beispiel reserviertRingIO(16)einen 17-Byte-Puffer und nimmt 16 Bytes an Daten auf.RingIO(buffer)verwendet den bereitgestelltenbufferdirekt, anstatt einen zu reservieren. Da ein Byte zur Nachverfolgung reserviert ist, kann die Instanzlen(buffer) - 1Bytes an Daten aufnehmen. Zum Beispiel nimmtRingIO(bytearray(16))15 Bytes an Daten auf.
Eine RingIO-Instanz ist IRQ-/Thread-sicher, wenn sie verwendet wird, um Daten in eine einzige Richtung zu übergeben (zum Beispiel aus einem IRQ heraus beschrieben und von einer Nicht-IRQ-Funktion gelesen oder umgekehrt). Dies gilt nicht, wenn eine einzelne Instanz sowohl aus IRQ- als auch aus Nicht-IRQ-Kontexten beschrieben wird, was häufig zu Datenkorruption führen würde.
- read(nbytes: int | None = None) bytes¶
Liest verfügbare Zeichen. Dies ist eine nicht blockierende Funktion. Wenn
nbytesangegeben ist, werden höchstens so viele Bytes gelesen, andernfalls werden so viele Daten wie möglich gelesen.Rückgabewert: ein Bytes-Objekt, das die gelesenen Bytes enthält. Es ist ein Bytes-Objekt der Länge null, wenn keine Daten verfügbar sind.
- readline(nbytes: int | None = None) bytes¶
Liest eine Zeile, die mit einem Zeilenumbruchzeichen endet, oder gibt zurück, falls ein solches im Puffer existiert, andernfalls werden die im Puffer verfügbaren Bytes zurückgegeben. Wenn
nbytesangegeben ist, werden höchstens so viele Bytes gelesen.Rückgabewert: ein Bytes-Objekt, das die gelesene Zeile enthält.
- readinto(buf: bytearray | memoryview, nbytes: int | None = None) int¶
Liest verfügbare Bytes in den bereitgestellten
buf. Wennnbytesangegeben ist, werden höchstens so viele Bytes gelesen. Andernfalls werden höchstenslen(buf)Bytes gelesen.Rückgabewert: Ganzzahl, die die Anzahl der in
bufgelesenen Bytes angibt.
- write(buf: bytes | bytearray | memoryview) int¶
Nicht blockierendes Schreiben von Bytes aus
bufin den Ringpuffer, begrenzt durch den verfügbaren Platz im Ringpuffer.Rückgabewert: Ganzzahl, die die Anzahl der geschriebenen Bytes angibt.