micropython — dostęp do wewnętrznych mechanizmów MicroPython i ich kontrola¶
Funkcje¶
- micropython.const(expr: int) int¶
Używane do zadeklarowania, że wyrażenie jest stałą, tak aby kompilator mógł je zoptymalizować. Tej funkcji należy używać w następujący sposób:
from micropython import const CONST_X = const(123) CONST_Y = const(2 * CONST_X + 1)
Stałe zadeklarowane w ten sposób są nadal dostępne jako zmienne globalne spoza modułu, w którym je zadeklarowano. Z drugiej strony, jeśli stała zaczyna się od podkreślenia, jest ukryta, nie jest dostępna jako zmienna globalna i nie zajmuje żadnej pamięci podczas wykonywania.
Funkcja
constjest rozpoznawana bezpośrednio przez parser MicroPython i jest udostępniana jako część modułumicropythongłównie po to, aby można było pisać skrypty działające zarówno pod CPython, jak i MicroPython, stosując powyższy wzorzec.
- micropython.opt_level(level: int | None = None) int | None¶
Jeśli podano level, to funkcja ustawia poziom optymalizacji dla kolejnych kompilacji skryptów i zwraca
None. W przeciwnym razie zwraca bieżący poziom optymalizacji.Poziom optymalizacji steruje następującymi funkcjami kompilacji:
Asercje: na poziomie 0 instrukcje asercji są włączone i kompilowane do kodu bajtowego; na poziomach 1 i wyższych asercje nie są kompilowane.
Wbudowana zmienna
__debug__: na poziomie 0 zmienna ta rozwija się doTrue; na poziomach 1 i wyższych rozwija się doFalse.Numery wierszy kodu źródłowego: na poziomach 0, 1 i 2 numery wierszy kodu źródłowego są przechowywane wraz z kodem bajtowym, dzięki czemu wyjątki mogą zgłaszać numer wiersza, w którym wystąpiły; na poziomach 3 i wyższych numery wierszy nie są przechowywane.
Domyślny poziom optymalizacji to zazwyczaj poziom 0.
- micropython.alloc_emergency_exception_buf(size: int) None¶
Przydziela size bajtów pamięci RAM dla awaryjnego bufora wyjątków (dobrym rozmiarem jest około 100 bajtów). Bufor jest używany do tworzenia wyjątków w sytuacjach, gdy normalny przydział pamięci RAM by się nie powiódł (np. wewnątrz procedury obsługi przerwania), i dzięki temu dostarcza w takich sytuacjach przydatnych informacji o śladzie wykonania.
Dobrym sposobem użycia tej funkcji jest umieszczenie jej na początku głównego skryptu (np.
boot.pylubmain.py) – wtedy awaryjny bufor wyjątków będzie aktywny dla całego następującego po nim kodu.
- micropython.mem_info(verbose: Any | None = None) None¶
Wypisuje informacje o aktualnie wykorzystywanej pamięci. Jeśli podano argument verbose, wypisywane są dodatkowe informacje.
Wypisywane informacje zależą od implementacji, ale obecnie obejmują ilość użytego stosu i sterty. W trybie szczegółowym wypisywana jest cała sterta ze wskazaniem, które bloki są używane, a które wolne.
- micropython.qstr_info(verbose: Any | None = None) None¶
Wypisuje informacje o aktualnie internowanych łańcuchach znaków. Jeśli podano argument verbose, wypisywane są dodatkowe informacje.
Wypisywane informacje zależą od implementacji, ale obecnie obejmują liczbę internowanych łańcuchów znaków i ilość zajmowanej przez nie pamięci RAM. W trybie szczegółowym wypisywane są nazwy wszystkich łańcuchów internowanych w pamięci RAM.
- micropython.stack_use() int¶
Zwraca liczbę całkowitą reprezentującą bieżącą ilość wykorzystywanego stosu. Wartość bezwzględna nie jest szczególnie użyteczna – raczej należy jej używać do obliczania różnic w wykorzystaniu stosu w różnych punktach.
- micropython.heap_lock() None¶
Blokuje stertę. W stanie zablokowanym nie może nastąpić żaden przydział pamięci, a próba jakiegokolwiek przydziału na stercie spowoduje zgłoszenie
MemoryError.Blokady się zagnieżdżają: wielokrotne wywołanie
heap_lock()zwiększa głębokość blokady. Sterta pozostaje zablokowana, dopókiheap_unlock()nie zostanie wywołane tę samą liczbę razy.Jeśli REPL stanie się aktywny przy zablokowanej stercie, zostanie ona przymusowo odblokowana.
- micropython.heap_unlock() int¶
Zmniejsza głębokość blokady sterty o jeden i zwraca nową głębokość jako nieujemną liczbę całkowitą. Wartość zwracana
0oznacza, że sterta nie jest już zablokowana, a przydziały są ponownie dozwolone.
- micropython.heap_locked() int¶
Zwraca bieżącą głębokość blokady sterty jako nieujemną liczbę całkowitą;
0oznacza, że sterta nie jest zablokowana.Uwaga: ta funkcja nie jest dostępna na OpenMV Cam.
- micropython.kbd_intr(chr: int) None¶
Ustawia znak, który będzie zgłaszał wyjątek
KeyboardInterrupt. Domyślnie podczas wykonywania skryptu jest to ustawione na 3, co odpowiada Ctrl-C. Przekazanie do tej funkcji -1 wyłączy przechwytywanie Ctrl-C, a przekazanie 3 przywróci je.Tej funkcji można użyć, aby zapobiec przechwytywaniu Ctrl-C w przychodzącym strumieniu znaków zwykle używanym dla REPL, na wypadek gdyby ten strumień był używany do innych celów.
- micropython.schedule(func: Callable[[Any], Any], arg: Any) None¶
Planuje wykonanie funkcji func „już wkrótce”. Funkcji przekazywana jest wartość arg jako jej jedyny argument. „Już wkrótce” oznacza, że środowisko uruchomieniowe MicroPython dołoży wszelkich starań, aby wykonać funkcję jak najwcześniej, biorąc pod uwagę, że stara się ono również być wydajne oraz że spełnione są następujące warunki:
Zaplanowana funkcja nigdy nie wywłaszczy innej zaplanowanej funkcji.
Zaplanowane funkcje są zawsze wykonywane „pomiędzy opcode’ami”, co oznacza, że wszystkie podstawowe operacje Pythona (takie jak dołączanie do listy) są gwarantowanie atomowe.
Dany port może definiować „obszary krytyczne”, w obrębie których zaplanowane funkcje nigdy nie będą wykonywane. Funkcje mogą być planowane w obszarze krytycznym, ale nie zostaną wykonane, dopóki ten obszar nie zostanie opuszczony. Przykładem obszaru krytycznego jest wywłaszczająca procedura obsługi przerwania (IRQ).
Wewnątrz funkcji natywnego kodu zaplanowane funkcje nie są wywoływane, chyba że natywny kod wywoła funkcję, która konkretnie to robi.
Niektóre funkcje, w tym
poll.poll,poll.ipoll,time.sleeporaztime.sleep_ms(w tym sleepy o zerowym czasie trwania), wywołają zaplanowane funkcje.
Zastosowaniem tej funkcji jest zaplanowanie wywołania zwrotnego z wywłaszczającego IRQ. Taki IRQ nakłada ograniczenia na kod uruchamiany w IRQ (na przykład sterta może być zablokowana), a zaplanowanie funkcji do późniejszego wywołania zniesie te ograniczenia.
Na portach wielowątkowych zachowanie zaplanowanej funkcji zależy od tego, czy dla danego portu włączona jest globalna blokada interpretera (GIL):
Jeśli GIL jest włączony, funkcja może wywłaszczyć dowolny wątek i działać w jego kontekście.
Jeśli GIL jest wyłączony, funkcja wywłaszczy tylko wątek główny i będzie działać w jego kontekście.
Uwaga: Jeśli
schedule()jest wywoływane z wywłaszczającego IRQ, gdy przydział pamięci nie jest dozwolony, a wywołanie zwrotne przekazywane doschedule()jest metodą związaną, przekazanie jej bezpośrednio się nie powiedzie. Dzieje się tak, ponieważ utworzenie referencji do metody związanej powoduje przydział pamięci. Rozwiązaniem jest utworzenie referencji do metody w konstruktorze klasy i przekazanie tej referencji doschedule(). Jest to szczegółowo omówione tutaj reference documentation w sekcji „Creation of Python objects”.Istnieje skończona kolejka do przechowywania zaplanowanych funkcji i
schedule()zgłosiRuntimeError, jeśli kolejka jest pełna.
Klasy¶
- class micropython.RingIO(size: int)¶
- class micropython.RingIO(buffer: bytes | bytearray | memoryview)
Zapewnia bufor pierścieniowy o stałym rozmiarze dla bajtów z interfejsem strumienia. Można go traktować jako wariant kolejki FIFO klasy
io.BytesIO. Dwie formy konstruktora różnią się jedynie sposobem dostarczenia bufora bazowego:RingIO(size)przydziela bufor bazowy wewnętrznie. Klasyczny algorytm bufora pierścieniowego rezerwuje jeden bajt do śledzenia, więc przydzielony bufor jest o jeden bajt większy niżsize, a instancja może pomieścić pełnesizebajtów danych. Na przykładRingIO(16)przydziela 17-bajtowy bufor i mieści 16 bajtów danych.RingIO(buffer)używa dostarczonegobufferw miejscu, zamiast przydzielać nowy. Ponieważ jeden bajt jest zarezerwowany do śledzenia, instancja może pomieścićlen(buffer) - 1bajtów danych. Na przykładRingIO(bytearray(16))mieści 15 bajtów danych.
Instancja RingIO jest bezpieczna dla IRQ/wątków, gdy jest używana do przekazywania danych w jednym kierunku (na przykład zapisywana z IRQ i odczytywana z funkcji spoza IRQ, lub odwrotnie). Nie obowiązuje to, jeśli pojedyncza instancja jest zapisywana zarówno z kontekstu IRQ, jak i spoza IRQ, co często powodowałoby uszkodzenie danych.
- read(nbytes: int | None = None) bytes¶
Odczytuje dostępne znaki. Jest to funkcja nieblokująca. Jeśli określono
nbytes, to odczytuje co najwyżej tyle bajtów, w przeciwnym razie odczytuje jak najwięcej danych.Wartość zwracana: obiekt bytes zawierający odczytane bajty. Będzie obiektem bytes o zerowej długości, jeśli żadne dane nie są dostępne.
- readline(nbytes: int | None = None) bytes¶
Odczytuje wiersz zakończony znakiem nowego wiersza lub powrotu karetki, jeśli taki istnieje w buforze, w przeciwnym razie zwraca dostępne bajty z bufora. Jeśli określono
nbytes, to odczytuje co najwyżej tyle bajtów.Wartość zwracana: obiekt bytes zawierający odczytany wiersz.
- readinto(buf: bytearray | memoryview, nbytes: int | None = None) int¶
Odczytuje dostępne bajty do dostarczonego
buf. Jeśli określononbytes, to odczytuje co najwyżej tyle bajtów. W przeciwnym razie odczytuje co najwyżejlen(buf)bajtów.Wartość zwracana: liczba całkowita zliczająca liczbę bajtów odczytanych do
buf.
- write(buf: bytes | bytearray | memoryview) int¶
Nieblokujący zapis bajtów z
bufdo bufora pierścieniowego, ograniczony dostępnym miejscem w buforze pierścieniowym.Wartość zwracana: liczba całkowita zliczająca zapisane bajty.