MicroPython 대화형 인터프리터 모드(일명 REPL)

이 절에서는 MicroPython 대화형 인터프리터 모드의 몇 가지 특성을 다룹니다. 이를 가리키는 데 흔히 사용되는 용어가 REPL(read-eval-print-loop, 읽기-평가-출력-반복)이며, 이 대화형 프롬프트를 지칭할 때 이 용어를 사용합니다.

참고

OpenMV Cam은 이 REPL을 USB 직렬(CDC) 포트를 통해 노출합니다. 이는 직렬 터미널 에뮬레이터(또는 MicroPython 원격 제어: mpremote와 같은 도구)로 카메라에 직접 연결할 때만 해당됩니다. OpenMV IDE는 REPL을 사용하지 않습니다 — IDE는 스크립트를 실행하고, 파일을 전송하고, 프레임 버퍼를 스트리밍하기 위해 별도의 디버그 프로토콜로 카메라와 통신합니다. 이 페이지에서 설명하는 모든 내용은 직접 터미널 세션에만 적용됩니다.

자동 들여쓰기

콜론으로 끝나는 Python 문(예: if, for, while)을 입력하면 프롬프트가 점 세 개(…)로 바뀌고 커서가 4칸 들여쓰기됩니다. 엔터를 누르면 다음 줄은 일반 문의 경우 동일한 들여쓰기 수준에서 계속되거나, 적절한 경우 한 단계 더 들여쓰기됩니다. 백스페이스 키를 누르면 들여쓰기 한 단계가 취소됩니다.

커서가 맨 앞까지 되돌아간 상태에서 RETURN을 누르면 입력한 코드가 실행됩니다. 다음은 for 문을 입력한 후 보게 되는 화면입니다(밑줄은 커서가 위치하는 곳을 나타냅니다):

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

이어서 if 문을 입력하면 들여쓰기가 한 단계 더 추가됩니다:

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

이제 break를 입력하고 RETURN을 누른 다음 BACKSPACE를 누르세요:

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

마지막으로 print(i)를 입력하고 RETURN을 누른 다음 BACKSPACE를 누르고 다시 RETURN을 누르세요:

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

이전 두 줄이 모두 공백이었다면 자동 들여쓰기가 적용되지 않습니다. 즉, 복합문 입력을 마치려면 RETURN을 두 번 누르면 되고, 세 번째로 누르면 입력이 완료되어 실행됩니다.

자동 완성

REPL에서 명령을 입력하는 도중, 지금까지 입력한 줄이 어떤 이름의 시작 부분과 일치하면 TAB을 눌러 입력 가능한 후보들을 표시할 수 있습니다. 예를 들어 먼저 import machine을 입력하고 RETURN을 눌러 machine 모듈을 가져옵니다. 그런 다음 m을 입력하고 TAB을 누르면 machine으로 확장됩니다. 점 .을 입력하고 다시 TAB을 누르세요. 다음과 같은 화면이 나타날 것입니다:

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

여러 가능성이 존재하기 전까지 단어가 최대한 확장됩니다. 예를 들어 machine.Pin.PULL을 입력하고 TAB을 누르면 machine.Pin.PULL_로 확장됩니다. TAB을 한 번 더 누르면 가능한 확장 목록이 표시됩니다:

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

실행 중인 프로그램 중단하기

Ctrl-C를 눌러 실행 중인 프로그램을 중단할 수 있습니다. 이는 KeyboardInterrupt를 발생시켜 REPL로 돌아오게 하는데, 단 프로그램이 KeyboardInterrupt 예외를 가로채지 않는 경우에 한합니다.

예를 들면:

>>> 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:
>>>

붙여넣기 모드

터미널 창에 코드를 붙여넣으려고 할 때 자동 들여쓰기 기능이 내용을 망쳐버립니다. 예를 들어 다음과 같은 Python 코드가 있다고 합시다:

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

이것을 일반 REPL에 붙여넣으려고 하면 다음과 같은 화면이 보일 것입니다:

>>> 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

Ctrl-E를 누르면 붙여넣기 모드로 진입하는데, 이는 본질적으로 자동 들여쓰기 기능을 끄고 프롬프트를 >>>에서 ===로 바꿉니다. 예를 들면:

>>>
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
>>>

붙여넣기 모드에서는 빈 줄도 붙여넣을 수 있습니다. 붙여넣은 텍스트는 마치 파일인 것처럼 컴파일됩니다. Ctrl-D를 누르면 붙여넣기 모드를 종료하고 컴파일을 시작합니다.

소프트 리셋

소프트 리셋은 Python 인터프리터를 재설정하지만, OpenMV Cam에 연결된 방식(USB)은 가급적 재설정하지 않으려 합니다.

REPL에서 Ctrl-D를 눌러 소프트 리셋을 수행하거나, Python 코드에서 다음을 실행하여 수행할 수 있습니다:

machine.soft_reset()

예를 들어 OpenMV Cam을 재설정하고 dir() 명령을 실행하면 다음과 같은 화면이 보일 것입니다:

>>> dir()
['__name__']

이제 변수 몇 개를 만들고 dir() 명령을 반복합니다:

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

이제 Ctrl-D를 입력하고 dir() 명령을 반복하면, 만들었던 변수들이 더 이상 존재하지 않음을 알 수 있습니다:

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__']
>>>

재설정 유형과 시작 과정에 대한 자세한 내용은 리셋 및 부팅 시퀀스을 참조하세요.

특수 변수 _ (밑줄)

REPL을 사용할 때 계산을 수행하고 그 결과를 볼 수 있습니다. MicroPython은 이전 문의 결과를 변수 _ (밑줄)에 저장합니다. 따라서 밑줄을 사용해 결과를 변수에 저장할 수 있습니다. 예를 들면:

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

Raw 모드와 raw-paste 모드

Raw 모드(raw REPL이라고도 함)는 사람이 일반적으로 사용하는 것이 아닙니다. 이는 프로그래밍 방식의 사용을 위한 것으로, 본질적으로 에코가 꺼진 붙여넣기 모드처럼 동작하며 선택적 흐름 제어를 갖춥니다.

Raw 모드는 Ctrl-A로 진입합니다. 그런 다음 Python 코드를 보내고 이어서 Ctrl-D를 보냅니다. Ctrl-D는 ‘OK’로 확인 응답되며, 그 후 Python 코드가 컴파일되어 실행됩니다. 모든 출력(또는 오류)이 다시 전송됩니다. Ctrl-B를 입력하면 raw 모드를 벗어나 일반(일명 친근한) REPL로 돌아갑니다.

Raw-paste 모드는 raw REPL 내의 추가 모드로, 흐름 제어를 포함하며 코드를 받는 대로 컴파일합니다. 이로 인해 장치로 코드를 고속 전송할 때 더 견고하며, 또한 컴파일 전에 코드의 그대로의 사본을 저장할 필요가 없기 때문에(표준 raw 모드와 달리) 수신 시 RAM을 더 적게 사용합니다.

Raw-paste 모드는 다음 프로토콜을 사용합니다:

  1. 평소와 같이 ctrl-A로 raw REPL에 진입합니다.

  2. 3바이트를 씁니다: b"\x05A\x01" (즉 ctrl-E 다음 “A” 다음 ctrl-A).

  3. 장치가 raw-paste 모드에 진입했는지 확인하기 위해 2바이트를 읽습니다:

    • 결과가 b"R\x00"이면 장치는 명령을 이해하지만 raw paste를 지원하지 않습니다.

    • 결과가 b"R\x01"이면 장치는 raw paste를 지원하며 이 모드에 진입했습니다.

    • 그 외의 경우 결과는 b"ra"여야 하며, 이는 장치가 raw paste를 지원하지 않음을 의미하므로 문자열 b"w REPL; CTRL-B to exit\r\n>"를 읽어서 폐기해야 합니다.

  4. 장치가 raw-paste 모드이면 계속 진행하고, 그렇지 않으면 표준 raw 모드로 대체합니다.

  5. 2바이트를 읽습니다. 이것은 16비트 부호 없는 리틀 엔디언 정수로 저장된 흐름 제어 윈도 크기 증가량(바이트 단위)입니다. 남은 윈도 크기 변수의 초기값은 이 숫자로 설정해야 합니다.

  6. 장치로 코드를 써냅니다:

    • 보낼 바이트가 남아 있는 동안, 남은 윈도 크기만큼의 바이트를 쓰고, 쓴 바이트 수만큼 남은 윈도 크기를 줄입니다.

    • 남은 윈도 크기가 0이거나 읽을 바이트가 대기 중이면 1바이트를 읽습니다. 이 바이트가 b"\x01"이면 5단계의 윈도 크기 증가량만큼 남은 윈도 크기를 늘립니다. 이 바이트가 b"\x04"이면 장치가 데이터 수신을 끝내고자 하는 것이므로 b"\x04"를 장치에 써야 하며 그 이후로는 더 이상 코드를 보내지 않습니다. (참고: 장치에서 읽을 바이트가 대기 중이더라도 즉시 읽고 처리할 필요는 없습니다. 남은 윈도 크기가 0보다 큰 한 장치는 들어오는 바이트를 계속 소비합니다.)

  7. 모든 코드를 장치에 다 썼으면 데이터 끝을 나타내기 위해 b"\x04"를 씁니다.

  8. b"\x04"를 받을 때까지 장치에서 읽습니다. 이 시점에서 장치는 보내진 모든 코드를 수신하고 컴파일하여 실행하고 있습니다.

  9. 장치는 실행 중인 코드가 생성하는 모든 문자를 출력합니다. 코드가 끝나면(끝나는 경우) b"\x04"가 출력되고, 이어서 잡히지 않은 예외가 있으면 그것이 출력되며, 다시 b"\x04"가 출력됩니다. 그런 다음 표준 raw REPL로 돌아가 b">"를 출력합니다.

예를 들어 일반(친근한) REPL에서 새 줄에서 시작하여 다음을 쓰면:

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

그러면 장치는 다음과 같은 식으로 응답합니다:

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

시간 순으로 나누어 보면 다음과 같습니다:

# 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>"

이 경우 흐름 제어 윈도 크기 증가량은 128이며, 시작 시점에 즉시 사용 가능한 데이터가 두 윈도 분량 있습니다. 하나는 초기 윈도 크기 증가량 값에서 오고, 다른 하나는 명시적으로 전송되는 b"\x01" 값에서 옵니다. 따라서 이는 대기하거나 추가로 들어오는 흐름 제어 문자를 확인하기 전에 처음에 최대 256바이트까지 쓸 수 있음을 의미합니다.

MicroPython 원격 제어: mpremote 도구는 OpenMV Cam에서 Python 코드를 실행하기 위해 raw-paste 모드를 포함한 raw REPL을 사용합니다.