Tryb interaktywnego interpretera MicroPython (czyli REPL)

Ta sekcja omawia niektóre cechy trybu interaktywnego interpretera MicroPython. Powszechnie używanym określeniem dla niego jest REPL (read-eval-print-loop) i ten termin będzie używany w odniesieniu do tego interaktywnego znaku zachęty.

Informacja

Kamery OpenMV Cam udostępniają ten REPL przez swój port szeregowy USB (CDC). Ma to znaczenie tylko wtedy, gdy łączysz się z kamerą bezpośrednio za pomocą emulatora terminala szeregowego (lub narzędzia takiego jak Zdalne sterowanie MicroPython: mpremote). OpenMV IDE nie korzysta z REPL — komunikuje się z kamerą za pomocą osobnego protokołu debugowania, aby uruchamiać skrypty, przesyłać pliki i strumieniować bufor ramki. Wszystko opisane na tej stronie dotyczy wyłącznie bezpośrednich sesji terminalowych.

Automatyczne wcięcia

Podczas wpisywania instrukcji Pythona kończących się dwukropkiem (na przykład if, for, while) znak zachęty zmieni się na trzy kropki (…), a kursor zostanie wcięty o 4 spacje. Po naciśnięciu klawisza return następny wiersz będzie kontynuowany na tym samym poziomie wcięcia dla zwykłych instrukcji lub na dodatkowym poziomie wcięcia tam, gdzie jest to właściwe. Naciśnięcie klawisza backspace cofa jeden poziom wcięcia.

Jeśli kursor znajduje się z powrotem na samym początku, naciśnięcie RETURN spowoduje wykonanie wprowadzonego kodu. Poniżej pokazano, co zobaczysz po wprowadzeniu instrukcji for (podkreślenie wskazuje, gdzie ostatecznie znajdzie się kursor):

>>> for i in range(30):
...     _

Jeśli następnie wprowadzisz instrukcję if, zapewniony zostanie dodatkowy poziom wcięcia:

>>> for i in range(30):
...     if i > 3:
...         _

Teraz wpisz break, naciśnij RETURN, a następnie naciśnij BACKSPACE:

>>> for i in range(30):
...     if i > 3:
...         break
...     _

Na koniec wpisz print(i), naciśnij RETURN, naciśnij BACKSPACE i ponownie naciśnij RETURN:

>>> for i in range(30):
...     if i > 3:
...         break
...     print(i)
...
0
1
2
3
>>>

Automatyczne wcięcia nie zostaną zastosowane, jeśli poprzednie dwa wiersze składały się wyłącznie ze spacji. Oznacza to, że możesz zakończyć wprowadzanie instrukcji złożonej, naciskając RETURN dwukrotnie, a trzecie naciśnięcie zakończy ją i wykona.

Automatyczne uzupełnianie

Podczas wpisywania polecenia w REPL, jeśli wpisany dotąd wiersz odpowiada początkowi nazwy czegoś, naciśnięcie TAB pokaże możliwe rzeczy, które mogą zostać wprowadzone. Na przykład najpierw zaimportuj moduł machine, wpisując import machine i naciskając RETURN. Następnie wpisz m i naciśnij TAB, a powinno to rozwinąć się do machine. Wprowadź kropkę . i ponownie naciśnij TAB. Powinieneś zobaczyć coś takiego:

>>> machine.
__name__        info            unique_id       reset
bootloader      freq            rng             idle
sleep           deepsleep       disable_irq     enable_irq
Pin

Słowo zostanie rozwinięte tak bardzo, jak to możliwe, dopóki nie pojawi się wiele możliwości. Na przykład wpisz machine.Pin.PULL i naciśnij TAB, a rozwinie się to do machine.Pin.PULL_. Ponowne naciśnięcie TAB pokaże możliwe rozwinięcia:

>>> machine.Pin.PULL_
PULL_DOWN       PULL_UP
>>> machine.Pin.PULL_

Przerywanie uruchomionego programu

Możesz przerwać uruchomiony program, naciskając Ctrl-C. Spowoduje to zgłoszenie wyjątku KeyboardInterrupt, który przywróci Cię do REPL, o ile Twój program nie przechwytuje wyjątku KeyboardInterrupt.

Na przykład:

>>> for i in range(1000000):
...     print(i)
...
0
1
2
3
...
6466
6467
6468
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
KeyboardInterrupt:
>>>

Tryb wklejania

Jeśli chcesz wkleić jakiś kod do okna terminala, funkcja automatycznych wcięć namiesza. Na przykład, jeśli masz następujący kod Pythona:

def foo():
    print('This is a test to show paste mode')
    print('Here is a second line')
foo()

i spróbujesz wkleić go do zwykłego REPL, zobaczysz coś takiego:

>>> def foo():
...         print('This is a test to show paste mode')
...             print('Here is a second line')
...             foo()
...
Traceback (most recent call last):
  File "<stdin>", line 3
IndentationError: unexpected indent

Jeśli naciśniesz Ctrl-E, wejdziesz w tryb wklejania, który zasadniczo wyłącza funkcję automatycznych wcięć i zmienia znak zachęty z >>> na ===. Na przykład:

>>>
paste mode; Ctrl-C to cancel, Ctrl-D to finish
=== def foo():
===     print('This is a test to show paste mode')
===     print('Here is a second line')
=== foo()
===
This is a test to show paste mode
Here is a second line
>>>

Tryb wklejania pozwala na wklejanie pustych wierszy. Wklejony tekst jest kompilowany tak, jakby był plikiem. Naciśnięcie Ctrl-D wychodzi z trybu wklejania i inicjuje kompilację.

Miękki reset

Miękki reset zresetuje interpreter Pythona, ale stara się nie resetować metody, za pomocą której jesteś połączony z OpenMV Cam (USB).

Miękki reset możesz wykonać z poziomu REPL, naciskając Ctrl-D, lub z poziomu kodu Pythona, wykonując:

machine.soft_reset()

Na przykład, jeśli zresetujesz swój OpenMV Cam i wykonasz polecenie dir(), zobaczysz coś takiego:

>>> dir()
['__name__']

Teraz utwórz kilka zmiennych i powtórz polecenie dir():

>>> i = 1
>>> j = 23
>>> x = 'abc'
>>> dir()
['j', 'x', '__name__', 'i']
>>>

Teraz, jeśli wprowadzisz Ctrl-D i powtórzysz polecenie dir(), zobaczysz, że Twoje zmienne już nie istnieją:

MPY: sync filesystems
MPY: soft reboot
MicroPython v1.25.0 on 2025-05-15; OpenMV Cam H7 with STM32H743
Type "help()" for more information.
>>> dir()
['__name__']
>>>

Więcej informacji o typach resetu i procesie uruchamiania znajdziesz w Sekwencja resetu i rozruchu.

Zmienna specjalna _ (podkreślenie)

Gdy korzystasz z REPL, możesz wykonywać obliczenia i widzieć ich wyniki. MicroPython przechowuje wynik poprzedniej instrukcji w zmiennej _ (podkreślenie). Możesz więc użyć podkreślenia, aby zapisać wynik w zmiennej. Na przykład:

>>> 1 + 2 + 3 + 4 + 5
15
>>> x = _
>>> x
15
>>>

Tryb surowy i tryb surowego wklejania

Tryb surowy (nazywany również surowym REPL) nie jest czymś, czego normalnie używałaby osoba. Jest przeznaczony do użytku programowego i zasadniczo zachowuje się jak tryb wklejania z wyłączonym echem oraz opcjonalną kontrolą przepływu.

Do trybu surowego wchodzi się za pomocą Ctrl-A. Następnie wysyłasz swój kod Pythona, po którym następuje Ctrl-D. Ctrl-D zostanie potwierdzone przez «OK», a następnie kod Pythona zostanie skompilowany i wykonany. Wszelkie dane wyjściowe (lub błędy) zostaną odesłane z powrotem. Wprowadzenie Ctrl-B opuści tryb surowy i przywróci zwykły (czyli przyjazny) REPL.

Tryb surowego wklejania to dodatkowy tryb w ramach surowego REPL, który obejmuje kontrolę przepływu i kompiluje kod w miarę jego otrzymywania. Czyni to go bardziej odpornym przy szybkim przesyłaniu kodu do urządzenia, a także zużywa mniej pamięci RAM podczas odbioru, ponieważ nie musi przechowywać dosłownej kopii kodu przed kompilacją (w przeciwieństwie do standardowego trybu surowego).

Tryb surowego wklejania używa następującego protokołu:

  1. Wejdź do surowego REPL w zwykły sposób za pomocą ctrl-A.

  2. Zapisz 3 bajty: b"\x05A\x01" (czyli ctrl-E, następnie „A”, a następnie ctrl-A).

  3. Odczytaj 2 bajty, aby ustalić, czy urządzenie weszło w tryb surowego wklejania:

    • Jeśli wynikiem jest b"R\x00", oznacza to, że urządzenie rozumie polecenie, ale nie obsługuje surowego wklejania.

    • Jeśli wynikiem jest b"R\x01", oznacza to, że urządzenie obsługuje surowe wklejanie i weszło w ten tryb.

    • W przeciwnym razie wynikiem powinno być b"ra" — urządzenie nie obsługuje surowego wklejania i należy odczytać oraz odrzucić ciąg b"w REPL; CTRL-B to exit\r\n>".

  4. Jeśli urządzenie jest w trybie surowego wklejania, kontynuuj; w przeciwnym razie wróć do standardowego trybu surowego.

  5. Odczytaj 2 bajty — jest to przyrost rozmiaru okna kontroli przepływu (w bajtach) przechowywany jako 16-bitowa liczba całkowita bez znaku w formacie little endian. Początkową wartość zmiennej pozostałego rozmiaru okna należy ustawić na tę liczbę.

  6. Zapisz kod do urządzenia:

    • Dopóki są bajty do wysłania, zapisz bajty w liczbie do pozostałego rozmiaru okna i zmniejsz pozostały rozmiar okna o liczbę zapisanych bajtów.

    • Jeśli pozostały rozmiar okna wynosi 0 lub jest bajt oczekujący na odczyt, odczytaj 1 bajt. Jeśli tym bajtem jest b"\x01", zwiększ pozostały rozmiar okna o przyrost rozmiaru okna z kroku 5. Jeśli tym bajtem jest b"\x04", urządzenie chce zakończyć odbiór danych — należy zapisać do urządzenia b"\x04" i nie wysyłać już więcej kodu. (Uwaga: jeśli jest bajt oczekujący na odczyt z urządzenia, nie trzeba go odczytywać i reagować na niego natychmiast; urządzenie będzie nadal pobierać przychodzące bajty, dopóki pozostały rozmiar okna jest większy od 0.)

  7. Gdy cały kod zostanie zapisany do urządzenia, zapisz b"\x04", aby wskazać koniec danych.

  8. Odczytuj z urządzenia, dopóki nie zostanie odebrane b"\x04". W tym momencie urządzenie odebrało i skompilowało cały wysłany kod oraz go wykonuje.

  9. Urządzenie wyprowadza wszelkie znaki wytworzone przez wykonywany kod. Gdy (jeśli) kod się zakończy, wyprowadzone zostanie b"\x04", po którym nastąpi każdy nieprzechwycony wyjątek, a następnie ponownie b"\x04". Następnie urządzenie wraca do standardowego surowego REPL i wyprowadza b">".

Na przykład, zaczynając od nowego wiersza w zwykłym (przyjaznym) REPL, jeśli zapiszesz:

b"\x01\x05A\x01print(123)\x04"

Wtedy urządzenie odpowie czymś w rodzaju:

b"\r\nraw REPL; CTRL-B to exit\r\n>R\x01\x80\x00\x01\x04123\r\n\x04\x04>"

Rozłożone w czasie wygląda to tak:

# Step 1: enter raw REPL
write: b"\x01"
read: b"\r\nraw REPL; CTRL-B to exit\r\n>"

# Step 2-5: enter raw-paste mode
write: b"\x05A\x01"
read: b"R\x01\x80\x00\x01"

# Step 6-8: write out code
write: b"print(123)\x04"
read: b"\x04"

# Step 9: code executes and result is read
read: b"123\r\n\x04\x04>"

W tym przypadku przyrost rozmiaru okna kontroli przepływu wynosi 128 i na początku natychmiast dostępne są dwa okna danych — jedno z początkowej wartości przyrostu rozmiaru okna, a drugie z jawnej wartości b"\x01", która jest wysyłana. Oznacza to więc, że na początek można zapisać do 256 bajtów, zanim trzeba będzie czekać lub sprawdzać kolejne przychodzące znaki kontroli przepływu.

Narzędzie Zdalne sterowanie MicroPython: mpremote używa surowego REPL, w tym trybu surowego wklejania, do wykonywania kodu Pythona na kamerach OpenMV Cam.