micropython — acces și control al componentelor interne MicroPython

Funcții

micropython.const(expr: int) int

Folosită pentru a declara că o expresie este o constantă, astfel încât compilatorul să o poată optimiza. Această funcție ar trebui folosită după cum urmează:

from micropython import const

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

Constantele declarate în acest mod sunt în continuare accesibile ca variabile globale din afara modulului în care sunt declarate. Pe de altă parte, dacă o constantă începe cu un underscore, atunci ea este ascunsă, nu este disponibilă ca variabilă globală și nu ocupă memorie în timpul execuției.

Această funcție const este recunoscută direct de analizatorul (parser) MicroPython și este furnizată ca parte a modulului micropython în principal pentru a permite scrierea de scripturi care rulează atât sub CPython, cât și sub MicroPython, urmând modelul de mai sus.

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

Dacă level este specificat, atunci această funcție setează nivelul de optimizare pentru compilarea ulterioară a scripturilor și returnează None. În caz contrar, returnează nivelul de optimizare curent.

Nivelul de optimizare controlează următoarele caracteristici de compilare:

  • Aserțiuni: la nivelul 0 instrucțiunile de aserțiune sunt activate și compilate în bytecode; la nivelurile 1 și mai mari aserțiunile nu sunt compilate.

  • Variabila încorporată __debug__: la nivelul 0 această variabilă se extinde la True; la nivelurile 1 și mai mari se extinde la False.

  • Numerele de linie din codul sursă: la nivelurile 0, 1 și 2 numerele de linie din codul sursă sunt stocate împreună cu bytecode-ul, astfel încât excepțiile să poată raporta linia la care au apărut; la nivelurile 3 și mai mari numerele de linie nu sunt stocate.

Nivelul de optimizare implicit este de obicei nivelul 0.

micropython.alloc_emergency_exception_buf(size: int) None

Alocă size octeți de RAM pentru tamponul de excepții de urgență (o dimensiune bună este de aproximativ 100 de octeți). Tamponul este folosit pentru a crea excepții în cazurile în care alocarea normală de RAM ar eșua (de exemplu în interiorul unei rutine de gestionare a întreruperilor) și astfel să ofere informații utile de traceback în aceste situații.

O modalitate bună de a folosi această funcție este să o plasați la începutul scriptului principal (de exemplu boot.py sau main.py), iar atunci tamponul de excepții de urgență va fi activ pentru tot codul care îl urmează.

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

Afișează informații despre memoria utilizată în prezent. Dacă argumentul verbose este specificat, atunci sunt afișate informații suplimentare.

Informațiile afișate depind de implementare, dar în prezent includ cantitatea de stivă (stack) și heap utilizată. În modul verbose, este afișat întregul heap, indicând care blocuri sunt folosite și care sunt libere.

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

Afișează informații despre șirurile de caractere internalizate (interned) în prezent. Dacă argumentul verbose este specificat, atunci sunt afișate informații suplimentare.

Informațiile afișate depind de implementare, dar în prezent includ numărul de șiruri internalizate și cantitatea de RAM pe care o folosesc. În modul verbose, sunt afișate numele tuturor șirurilor internalizate în RAM.

micropython.stack_use() int

Returnează un întreg care reprezintă cantitatea curentă de stivă (stack) utilizată. Valoarea absolută a acestuia nu este deosebit de utilă; ar trebui mai degrabă folosită pentru a calcula diferențele de utilizare a stivei în diferite puncte.

micropython.heap_lock() None

Blochează heap-ul. Cât timp este blocat, nu poate avea loc nicio alocare de memorie, iar dacă se încearcă vreo alocare în heap se va genera o MemoryError.

Blocările se cuibăresc: apelarea heap_lock() de mai multe ori crește adâncimea blocării. Heap-ul rămâne blocat până când heap_unlock() a fost apelat de același număr de ori.

Dacă REPL-ul devine activ cu heap-ul blocat, atunci acesta va fi deblocat forțat.

micropython.heap_unlock() int

Decrementează adâncimea blocării heap-ului cu unu și returnează noua adâncime ca întreg non-negativ. O valoare returnată de 0 înseamnă că heap-ul nu mai este blocat și alocările sunt din nou permise.

micropython.heap_locked() int

Returnează adâncimea curentă a blocării heap-ului ca întreg non-negativ; 0 înseamnă că heap-ul nu este blocat.

Notă: această funcție nu este disponibilă pe OpenMV Cam.

micropython.kbd_intr(chr: int) None

Setează caracterul care va genera o excepție KeyboardInterrupt. În mod implicit, acesta este setat la 3 în timpul execuției scriptului, corespunzând Ctrl-C. Transmiterea valorii -1 către această funcție va dezactiva capturarea Ctrl-C, iar transmiterea valorii 3 o va restabili.

Această funcție poate fi folosită pentru a împiedica capturarea Ctrl-C din fluxul de caractere de intrare care este de obicei utilizat pentru REPL, în cazul în care acel flux este folosit în alte scopuri.

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

Programează funcția func pentru a fi executată „foarte curând”. Funcției i se transmite valoarea arg ca unic argument. „Foarte curând” înseamnă că mediul de execuție MicroPython va face tot posibilul să execute funcția cât mai devreme cu putință, dat fiind că încearcă totodată să fie eficient și că sunt îndeplinite următoarele condiții:

  • O funcție programată nu va întrerupe niciodată (preempt) o altă funcție programată.

  • Funcțiile programate sunt întotdeauna executate „între coduri de operație”, ceea ce înseamnă că toate operațiile fundamentale Python (cum ar fi adăugarea la o listă) sunt garantat atomice.

  • Un anumit port poate defini „regiuni critice” în interiorul cărora funcțiile programate nu vor fi niciodată executate. Funcțiile pot fi programate în interiorul unei regiuni critice, dar nu vor fi executate până la ieșirea din acea regiune. Un exemplu de regiune critică este o rutină de gestionare a întreruperilor cu prioritate (un IRQ).

  • În interiorul funcțiilor de cod nativ, funcțiile programate nu sunt apelate decât dacă codul nativ apelează o funcție care face acest lucru în mod specific.

  • Anumite funcții, inclusiv poll.poll, poll.ipoll, time.sleep și time.sleep_ms (inclusiv pauzele cu durată zero), vor apela funcțiile programate.

O utilizare a acestei funcții este programarea unei funcții de retroapelare (callback) dintr-un IRQ cu prioritate. Un astfel de IRQ impune restricții asupra codului care rulează în IRQ (de exemplu, heap-ul poate fi blocat), iar programarea unei funcții pentru a fi apelată ulterior va elimina aceste restricții.

Pe porturile cu mai multe fire de execuție (multi-threaded), comportamentul funcției programate depinde de faptul dacă Global Interpreter Lock (GIL) este activat pentru portul respectiv:

  • Dacă GIL este activat, funcția poate întrerupe (preempt) orice fir de execuție și rula în contextul acestuia.

  • Dacă GIL este dezactivat, funcția va întrerupe (preempt) doar firul principal și va rula în contextul acestuia.

Notă: Dacă schedule() este apelată dintr-un IRQ cu prioritate, când alocarea de memorie nu este permisă, iar funcția de retroapelare transmisă către schedule() este o metodă legată (bound method), transmiterea directă a acesteia va eșua. Acest lucru se întâmplă deoarece crearea unei referințe la o metodă legată provoacă alocare de memorie. O soluție este crearea unei referințe la metodă în constructorul clasei și transmiterea acelei referințe către schedule(). Acest aspect este discutat în detaliu aici, în documentația de referință, la secțiunea „Creation of Python objects”.

Există o coadă finită care păstrează funcțiile programate, iar schedule() va genera o RuntimeError dacă coada este plină.

Clase

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

Furnizează un tampon inelar (ringbuffer) de dimensiune fixă pentru octeți, cu o interfață de tip flux (stream). Poate fi considerat o variantă de coadă FIFO a lui io.BytesIO. Cele două forme ale constructorului diferă doar prin modul în care este furnizat tamponul de suport:

  • RingIO(size) alocă tamponul de suport intern. Algoritmul clasic de ringbuffer rezervă un octet pentru urmărire, astfel încât tamponul alocat este cu un octet mai mare decât size, iar instanța poate conține întreaga cantitate de size octeți de date. De exemplu, RingIO(16) alocă un tampon de 17 octeți și conține 16 octeți de date.

  • RingIO(buffer) folosește tamponul buffer furnizat în loc să aloce unul. Deoarece un octet este rezervat pentru urmărire, instanța poate conține len(buffer) - 1 octeți de date. De exemplu, RingIO(bytearray(16)) conține 15 octeți de date.

O instanță RingIO este sigură din punct de vedere IRQ/fir de execuție atunci când este folosită pentru a transmite date într-o singură direcție (de exemplu, scrisă dintr-un IRQ și citită dintr-o funcție non-IRQ, sau invers). Acest lucru nu este valabil dacă o singură instanță este scrisă atât din contexte IRQ, cât și non-IRQ, ceea ce ar cauza adesea coruperea datelor.

any() int

Returnează un întreg care numără caracterele ce pot fi citite.

read(nbytes: int | None = None) bytes

Citește caracterele disponibile. Aceasta este o funcție non-blocantă. Dacă nbytes este specificat, atunci citește cel mult acel număr de octeți; în caz contrar, citește cât mai multe date posibil.

Valoare returnată: un obiect bytes care conține octeții citiți. Va fi un obiect bytes de lungime zero dacă nu sunt disponibile date.

readline(nbytes: int | None = None) bytes

Citește o linie, terminată cu un caracter de linie nouă sau cu return dacă unul există în tampon, altfel returnează octeții disponibili din tampon. Dacă nbytes este specificat, atunci citește cel mult acel număr de octeți.

Valoare returnată: un obiect bytes care conține linia citită.

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

Citește octeții disponibili în buf-ul furnizat. Dacă nbytes este specificat, atunci citește cel mult acel număr de octeți. În caz contrar, citește cel mult len(buf) octeți.

Valoare returnată: numărul întreg de octeți citiți în buf.

write(buf: bytes | bytearray | memoryview) int

Scriere non-blocantă a octeților din buf în ringbuffer, limitată de spațiul disponibil în ringbuffer.

Valoare returnată: numărul întreg de octeți scriși.

close() None

Operație nulă (no-op) furnizată ca parte a interfeței standard stream. Nu are niciun efect asupra datelor din ringbuffer.