micropython — a MicroPython belső működésének elérése és vezérlése

Függvények

micropython.const(expr: int) int

Annak deklarálására szolgál, hogy a kifejezés konstans, így a fordító optimalizálhatja azt. Ezt a függvényt a következőképpen kell használni:

from micropython import const

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

Az így deklarált konstansok továbbra is elérhetők globális változókként azon a modulon kívülről, amelyben deklarálva lettek. Másrészt ha egy konstans aláhúzásjellel kezdődik, akkor rejtett, nem érhető el globális változóként, és nem foglal memóriát a végrehajtás során.

Ezt a const függvényt közvetlenül felismeri a MicroPython értelmező, és a micropython modul részeként biztosított, főként azért, hogy olyan szkripteket lehessen írni, amelyek a fenti minta követésével CPython és MicroPython alatt is futnak.

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

Ha a level meg van adva, akkor ez a függvény beállítja az optimalizálási szintet a szkriptek későbbi fordításához, és None értéket ad vissza. Egyébként az aktuális optimalizálási szintet adja vissza.

Az optimalizálási szint a következő fordítási jellemzőket vezérli:

  • Assertion-ök: 0-s szinten az assertion utasítások engedélyezettek és a bájtkódba fordulnak; 1-es és magasabb szinteken az assertion-ök nem fordulnak le.

  • Beépített __debug__ változó: 0-s szinten ez a változó True értékre bővül; 1-es és magasabb szinteken False értékre.

  • Forráskódsor-számok: 0-s, 1-es és 2-es szinten a forráskód sorszámai a bájtkóddal együtt tárolódnak, így a kivételek jelenthetik azt a sorszámot, ahol előfordultak; 3-as és magasabb szinteken a sorszámok nem tárolódnak.

Az alapértelmezett optimalizálási szint általában a 0-s szint.

micropython.alloc_emergency_exception_buf(size: int) None

Lefoglal size byte RAM-ot a vész-kivételpuffer számára (a jó méret 100 byte körül van). A puffer olyan esetekben szolgál kivételek létrehozására, amikor a normál RAM-foglalás sikertelen lenne (pl. egy megszakításkezelőn belül), és ezáltal hasznos visszakövetési információt nyújt ezekben a helyzetekben.

Ezt a függvényt jó módja a használatának, ha a fő szkripted elejére helyezed (pl. boot.py vagy main.py), így a vész-kivételpuffer az utána következő összes kódhoz aktív lesz.

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

Információt ír ki az aktuálisan használt memóriáról. Ha a verbose argumentum meg van adva, akkor extra információ is kiíródik.

A kiírt információ megvalósításfüggő, de jelenleg tartalmazza a használt verem és kupac (heap) mennyiségét. Bőbeszédű módban kiírja a teljes kupacot, jelezve, hogy mely blokkok használtak és melyek szabadok.

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

Információt ír ki az aktuálisan internált sztringekről. Ha a verbose argumentum meg van adva, akkor extra információ is kiíródik.

A kiírt információ megvalósításfüggő, de jelenleg tartalmazza az internált sztringek számát és az általuk használt RAM mennyiségét. Bőbeszédű módban kiírja az összes RAM-ba internált sztring nevét.

micropython.stack_use() int

Egész számot ad vissza, amely a verem aktuálisan használt mennyiségét jelöli. Ennek abszolút értéke nem különösebben hasznos, inkább a veremhasználat különböző pontok közötti különbségeinek kiszámítására érdemes használni.

micropython.heap_lock() None

Zárolja a kupacot. Zárolt állapotban semmilyen memóriafoglalás nem történhet, és MemoryError váltódik ki, ha bármilyen kupacfoglalást kísérelnek meg.

A zárolások egymásba ágyazódnak: a heap_lock() többszöri meghívása növeli a zárolási mélységet. A kupac zárolva marad mindaddig, amíg a heap_unlock() ugyanannyiszor meg nem hívódik.

Ha a REPL aktívvá válik a kupac zárolt állapotában, akkor az erőszakosan feloldódik.

micropython.heap_unlock() int

Eggyel csökkenti a kupac zárolási mélységét, és visszaadja az új mélységet nem negatív egész számként. A 0 visszatérési érték azt jelenti, hogy a kupac többé nem zárolt, és a foglalások ismét engedélyezettek.

micropython.heap_locked() int

Visszaadja az aktuális kupac-zárolási mélységet nem negatív egész számként; a 0 azt jelenti, hogy a kupac nincs zárolva.

Megjegyzés: ez a függvény nem érhető el az OpenMV Cam eszközön.

micropython.kbd_intr(chr: int) None

Beállítja azt a karaktert, amely KeyboardInterrupt kivételt vált ki. Alapértelmezetten ez a szkript végrehajtása során 3-ra van állítva, ami a Ctrl-C-nek felel meg. A függvénynek -1-et átadva letiltható a Ctrl-C elkapása, 3-at átadva pedig visszaállítható.

Ezzel a függvénnyel megakadályozható a Ctrl-C elkapása a beérkező karakterek folyamán, amelyet általában a REPL használ, arra az esetre, ha azt a folyamot más célokra használják.

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

Ütemezi a func függvény „nagyon hamarosan” történő végrehajtását. A függvény egyetlen argumentumaként az arg értéket kapja. A „nagyon hamarosan” azt jelenti, hogy a MicroPython futtatókörnyezet a tőle telhető legkorábbi időpontban próbálja végrehajtani a függvényt, figyelembe véve azt is, hogy hatékony próbál lenni, és hogy a következő feltételek teljesülnek:

  • Egy ütemezett függvény soha nem előz meg egy másik ütemezett függvényt.

  • Az ütemezett függvények mindig „opkódok között” hajtódnak végre, ami azt jelenti, hogy az összes alapvető Python-művelet (például egy listához fűzés) garantáltan atomi.

  • Egy adott port definiálhat „kritikus régiókat”, amelyeken belül az ütemezett függvények soha nem hajtódnak végre. A függvények ütemezhetők egy kritikus régión belül, de csak a régió elhagyása után hajtódnak végre. Egy kritikus régió példája egy előzető megszakításkezelő (IRQ).

  • Natív kódfüggvényeken belül az ütemezett függvények nem hívódnak meg, hacsak a natív kód nem hív meg egy olyan függvényt, amely kifejezetten ezt teszi.

  • Bizonyos függvények, köztük a poll.poll, poll.ipoll, time.sleep és time.sleep_ms (a nulla időtartamú alvásokat is beleértve) meghívják az ütemezett függvényeket.

E függvény egyik felhasználása egy visszahívás ütemezése egy előzető IRQ-ból. Egy ilyen IRQ korlátozásokat szab az IRQ-ban futó kódra (például a kupac zárolt lehet), és egy függvény későbbi hívásra történő ütemezése feloldja ezeket a korlátozásokat.

Többszálú portokon az ütemezett függvény viselkedése attól függ, hogy a Global Interpreter Lock (GIL) engedélyezve van-e az adott porton:

  • Ha a GIL engedélyezve van, a függvény bármely szálat megelőzhet és annak kontextusában futhat.

  • Ha a GIL le van tiltva, a függvény csak a fő szálat előzheti meg és annak kontextusában fut.

Megjegyzés: Ha a schedule() egy előzető IRQ-ból hívódik meg, amikor a memóriafoglalás nem engedélyezett, és a schedule() függvénynek átadandó visszahívás egy kötött metódus, akkor ennek közvetlen átadása sikertelen lesz. Ennek oka, hogy egy kötött metódusra való hivatkozás létrehozása memóriafoglalást okoz. A megoldás az, hogy az osztály konstruktorában hozol létre egy hivatkozást a metódusra, és azt a hivatkozást adod át a schedule() függvénynek. Ezt részletesen tárgyalja a referenciadokumentáció a „Creation of Python objects” cím alatt.

Van egy véges sor az ütemezett függvények tárolására, és a schedule() RuntimeError kivételt vált ki, ha a sor megtelt.

Osztályok

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

Rögzített méretű gyűrűpuffert biztosít byte-ok számára adatfolyam-interfésszel. Tekinthető az io.BytesIO FIFO-sor változatának. A két konstruktorforma csak abban különbözik, hogy hogyan kapja meg a háttérpuffert:

  • A RingIO(size) belsőleg foglalja le a háttérpuffert. A klasszikus gyűrűpuffer-algoritmus egy byte-ot fenntart a nyilvántartáshoz, így a lefoglalt puffer egy byte-tal nagyobb, mint a size, és a példány a teljes size byte adatot tárolhatja. Például a RingIO(16) egy 17 byte-os puffert foglal le, és 16 byte adatot tárol.

  • A RingIO(buffer) a megadott buffer puffert használja helyben, ahelyett, hogy újat foglalna le. Mivel egy byte a nyilvántartásra van fenntartva, a példány len(buffer) - 1 byte adatot tárolhat. Például a RingIO(bytearray(16)) 15 byte adatot tárol.

Egy RingIO példány IRQ-/szálbiztos, amikor adatok egyetlen irányba történő átadására használják (például egy IRQ-ból írják és egy nem IRQ-függvényből olvassák, vagy fordítva). Ez nem áll fenn, ha egyetlen példányba IRQ- és nem IRQ-kontextusból egyaránt írnak, ami gyakran adatkorrupciót okozna.

any() int

Egész számot ad vissza, amely az olvasható karakterek számát számolja.

read(nbytes: int | None = None) bytes

Beolvassa az elérhető karaktereket. Ez egy nem blokkoló függvény. Ha az nbytes meg van adva, akkor legfeljebb annyi byte-ot olvas, egyébként a lehető legtöbb adatot olvassa be.

Visszatérési érték: egy bytes objektum, amely a beolvasott byte-okat tartalmazza. Nulla hosszúságú bytes objektum lesz, ha nincs elérhető adat.

readline(nbytes: int | None = None) bytes

Beolvas egy sort, amely újsor karakterrel végződik, vagy visszatér, ha ilyen van a pufferben, egyébként visszaadja a pufferben elérhető byte-okat. Ha az nbytes meg van adva, akkor legfeljebb annyi byte-ot olvas.

Visszatérési érték: egy bytes objektum, amely a beolvasott sort tartalmazza.

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

Beolvassa az elérhető byte-okat a megadott buf pufferbe. Ha az nbytes meg van adva, akkor legfeljebb annyi byte-ot olvas. Egyébként legfeljebb len(buf) byte-ot olvas.

Visszatérési érték: a buf pufferbe beolvasott byte-ok számának egész értéke.

write(buf: bytes | bytearray | memoryview) int

Nem blokkoló byte-írás a buf pufferből a gyűrűpufferbe, a gyűrűpufferben elérhető hely által korlátozva.

Visszatérési érték: a kiírt byte-ok számának egész értéke.

close() None

Üres művelet, amely a szabványos stream interfész részeként biztosított. Nincs hatása a gyűrűpufferben lévő adatokra.