MicroPython 交互式解释器模式 (又名 REPL)¶
本节介绍 MicroPython 交互式解释器模式的一些特性。一个常用的术语是 REPL (read-eval-print-loop),它将用来指代这个交互式提示。
自动缩进¶
当输入以冒号结尾的 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 (回车)来导入机器模块。然后输入 m
并按 TAB,它应该能补全为 machine
。此时输入一个句点 .
并再次按 TAB。你应该会看到如下内容:
>>> machine.
__name__ info unique_id reset
bootloader freq rng idle
sleep deepsleep disable_irq enable_irq
Pin
输入的词将尽可能地补全,直到存在多种可补全的选项而导致无法默认选择时。例如,输入 machine.Pin.AF3
并按 TAB,它将补全为 machine.Pin.AF3_TIM
。再次按 TAB 将显示可能的扩展:
>>> machine.Pin.AF3_TIM
AF3_TIM10 AF3_TIM11 AF3_TIM8 AF3_TIM9
>>> machine.Pin.AF3_TIM
中断正在运行的程序¶
你可以通过按 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()
...
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 解释器,但不会重置你连接到 MicroPython 板的方式(例如 USB 串口或 Wifi)。
你可以通过按 Ctrl-D 从 REPL 执行软复位,或者通过从你的 python 代码执行:
machine.soft_reset()
例如,如果你重置 MicroPython 板,并执行 dir() 命令,你会看到如下内容:
>>> dir()
['__name__', 'pyb']
现在创建一些变量再重复 dir() 命令:
>>> i = 1
>>> j = 23
>>> x = 'abc'
>>> dir()
['j', 'x', '__name__', 'pyb', 'i']
>>>
现在,如果你输入 Ctrl-D,并重复执行 dir() 命令,你会看到你的变量已经不再存在:
MPY: sync filesystems
MPY: soft reboot
MicroPython v1.5-51-g6f70283-dirty on 2015-10-30; PYBv1.0 with STM32F405RG
Type "help()" for more information.
>>> dir()
['__name__', 'pyb']
>>>
特殊变量 _ (下划线)¶
当你使用 REPL 时,你可以执行计算并查看结果。MicroPython 将前一条语句的结果存储在变量 _(下划线)中。因此,你可以使用下划线将结果保存在变量中。例如:
>>> 1 + 2 + 3 + 4 + 5
15
>>> x = _
>>> x
15
>>>
Raw 模式和 Raw 粘贴模式¶
Raw 模式(也称为 Raw REPL),它并不是人们通常会使用的东西。它旨在用于编写程序,本质上类似于粘贴模式,关闭了输出,并且拥有可选的流控制。
使用 Ctrl-A 即可进入 Raw 模式。然后发送你的 python 代码,然后按下 Ctrl-D。Ctrl-D 代表 ‘OK’ 确认,接着 python 代码将被编译和执行。任何输出(或错误)都将被发回。按下 Ctrl-B 即可离开原始模式并返回常规(又名友好)的 REPL。
Raw 粘贴模式是 Raw REPL 中的一种附加模式,它包括流控制,并在收到代码时就对其进行编译。这使得它在将代码高速传输到设备时更加健壮,并且在接收时也使用更少的 RAM,因为它不需要在编译之前逐字存储代码的副本(与标准 raw 模式不同)
Raw 粘贴模式使用以下协议:
和一般情况一样通过 ctrl-A 输入 Raw REPL
写入 3 个字节:
(b"\x05A\x01"
即 ctrl-E,然后是 “A”,再然后是 ctrl-A)。读取 2 个字节以确定设备是否进入 Raw 粘贴模式:
如果结果是
b"R\x00"
,则说明设备理解命令但不支持 Raw 粘贴模式。如果结果是
b"R\x01"
,则说明设备确实支持 Raw 粘贴并已进入此模式。其他情况下,结果应该是
b"ra"
且代表设备不支持 Raw 粘贴;然后你将看到字符串``b”w REPL; CTRL-B to exitrn>”`` ,并放弃当前操作。
如果设备处于 Raw 粘贴模式,则继续,否则回退到标准 Raw 模式。
读取 2 个字节,这是存储为 16 位无符号小端整数的流控制窗口增量大小(以字节为单位)。剩余窗口大小变量的初始值应设置为此数字。
将代码写入设备
当有字节要发送时,写入剩余窗口大小的字节,并将剩余窗口大小减少写入的字节数。
如果剩余窗口大小等于 0,或者有一个字节等待读取,则读取 1 个字节。如果这个字节是
b"\x01"
然后将剩余窗口大小增加步骤 5 中的窗口大小增量。如果这个字节是b"\x04"
那么代表设备想要结束数据接收,并且b"\x04"
应该写回设备并且之后不再发送代码。(注意:如果有一个字节等待从设备读取,也不需要立即读取和操作,只要当剩余窗口大小大于 0,设备就将继续消耗传入的字节。)
将所有代码写入设备后,写入
b"\x04"
以标识数据结束。从设备读取数据直到收到
b"\x04"
。此时,设备已经接收到并编译了所有发送的代码,并且开始执行。设备输出执行代码产生的任何字符。当代码结束(如果能)时,
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 个字节。
在 tools/pyboard.py
程序中,使用了 Raw REPL(包括 Raw 粘贴模式),用以在支持 MicroPython 的开发板上执行 Python 代码。