MicroPython 远程控制:mpremote¶
mpremote 命令行工具提供了一组集成实用程序,可通过串行连接远程与 MicroPython 设备交互、管理其文件系统并实现自动化。它可与所有 OpenMV Cam 通过 USB 串行连接配合使用,是 OpenMV IDE 在脚本编写和自动化工作流方面的命令行替代方案。
要使用 mpremote,请先通过 pip 安装它:
$ pip install --user mpremote
或通过 pipx 安装:
$ pipx install mpremote
使用此工具最简单的方法就是不带任何参数直接调用它:
$ mpremote
此命令会自动检测并连接到第一个可用的 USB 串行设备,并提供一个交互式终端,你可以用它访问 REPL 以及程序的输出。串行端口以独占模式打开,因此运行第二个(或第三个等)mpremote 实例时,会连接到后续的串行设备(如果有可用的话)。
此外,pipx 还允许你无需先安装即可直接运行 mpremote:
$ pipx run mpremote ...args
命令¶
mpremote 支持在命令行上给出一系列命令,这些命令将在远程 MicroPython 设备上依次执行各种操作。请参阅下面的 示例部分 以了解其工作原理以及一些常见的命令组合。
每个命令的形式为 <command name> [--options] [args...]。对于支持多个参数的命令(例如文件列表),参数列表可以用 + 来终止。
如果未指定命令,则默认命令为 repl。此外,如果任何命令需要访问设备,并且之前没有指定 connect,则会隐式添加一个 connect auto。
为了让设备在执行任何操作命令(repl 除外)前处于已知状态,连接后 mpremote 会在运行第一个命令之前停止所有正在运行的程序并对设备执行软复位。你可以使用 resume 和 soft-reset 命令来控制此行为。更多详情请参阅 自动连接与自动软复位。
可以指定多个命令,它们将按顺序运行。
支持的命令完整列表如下:
connect¶
通过名称连接到指定设备:
$ mpremote connect <device>
<device> 可以是以下之一:
list:列出可用设备auto:连接到第一个可用的 USB 串行端口id:<serial>:连接到 USB 序列号为<serial>的设备(即connect list命令输出的第二列)port:<path>:连接到具有给定路径的设备(即connect list命令输出的第一列)rfc2217://<host>:<port>:使用基于 TCP 的串行连接设备(例如基于 RFC2217 的网络串行端口)任何有效的设备名称/路径,以连接到该设备
注意: 除了使用 connect 命令外,还有几个针对常见设备路径的 预定义快捷方式。例如,a0 快捷命令等价于 connect /dev/ttyACM0(Linux),或者 c1 等价于 COM1(Windows)。
注意: auto 选项只会检测 USB 串行端口,即具有关联 USB VID/PID 的串行端口(即 CDC/ACM 或 FTDI 风格的设备)。其他类型的串行端口不会被自动检测。
disconnect¶
断开当前设备的连接:
$ mpremote disconnect
断开连接后,自动软复位 将被启用。
resume¶
为后续命令保持现有的解释器状态:
$ mpremote resume
这会禁用 自动软复位。如果你想在板子上运行后续命令而不先对其进行软复位,这会很有用。
soft-reset¶
对设备执行软复位:
$ mpremote soft-reset
这将清除 Python 堆并重启解释器。它还会阻止后续命令触发 自动软复位。
repl¶
进入已连接设备上的 REPL:
$ mpremote repl [--options]
选项有:
--escape-non-printable,以十六进制代码形式打印不可打印的字节/字符--capture <file>,将 REPL 会话的输出捕获到指定文件--inject-code <string>,指定在按下Ctrl-J时注入到 REPL 的字符。这允许你将常用命令自动化。--inject-file <file>,指定在按下Ctrl-K时注入到 REPL 的文件。这允许你运行一个文件(例如包含一些有用的初始化代码,甚至是你当前正在编写的程序)。
在 repl 命令运行期间,你可以使用 Ctrl-] 或 Ctrl-x 退出。
注意: 此处“REPL”这个名称反映了该命令通常用于访问运行在 MicroPython 设备上的 Read Eval Print Loop(读取-求值-打印循环)。严格来说,repl 命令仅是充当一个终端(或“串行监视器”)来访问设备。由于此命令不会触发 自动复位行为,这意味着如果当前有程序正在运行,你需要先用 Ctrl-C 中断它才能进入 REPL,然后才能访问程序状态。你也可以使用 mpremote soft-reset repl 来获得一个清除了所有程序状态的“干净”REPL。
eval¶
求值并打印 Python 表达式的结果:
$ mpremote eval <string>
exec¶
执行给定的 Python 代码:
$ mpremote exec <string>
默认情况下,mpremote exec 会显示该表达式的所有输出,直到其终止。可以指定 --no-follow 标志以立即返回,并让设备在后台继续运行该表达式。
run¶
从本地文件系统运行脚本:
$ mpremote run <file.py>
这将直接从设备的 RAM 中执行该文件,而不会将其复制到文件系统。这是一种非常有用的方法,可以迭代开发单段代码,而无需担心将其部署到文件系统。
默认情况下,mpremote run 会显示该脚本的所有输出,直到其终止。可以指定 --no-follow 标志以立即返回,并让设备在后台继续运行该脚本。
fs¶
在设备上执行文件系统命令:
$ mpremote fs <sub-command>
<sub-command> 可以是:
cat <file..>显示设备上一个或多个文件的内容ls列出当前目录ls <dirs...>列出给定的目录cp [-rf] <src...> <dest>复制文件rm [-r] <src...>删除设备上的文件或文件夹mkdir <dirs...>在设备上创建目录rmdir <dirs...>删除设备上的目录touch <file..>创建文件(如果它们尚不存在)sha256sum <file..>计算文件的 SHA256 校验和tree [-vsh] <dirs...>打印给定目录的树状结构
cp 命令采用一种约定,其中前导的 : 表示远程路径。没有前导 : 则表示本地路径。这基于 安全复制协议(scp)客户端 所使用的约定。
例如,mpremote fs cp main.py :main.py 会将 main.py 从当前本地目录复制到远程文件系统,而 mpremote fs cp :main.py main.py 则会将 main.py 从设备复制回当前目录。
mpremote rm -r 命令同时接受相对路径和绝对路径。使用 : 来引用当前远程工作目录(cwd),以便从设备的默认路径(例如 /flash、/)中删除整个目录树。使用 -v/--verbose 可查看正在被删除的文件。
例如:
mpremote rm -r :libs将从设备中删除libs目录及其所有子项。mpremote rm -rv :/sd将删除已挂载 SD 卡中的所有文件,并产生一个非阻塞警告。挂载点将被保留。mpremote rm -rv :/将删除设备上的所有文件,包括位于已挂载 vfs(例如/sd或/flash)中的文件。删除所有文件夹和文件后,它还会返回一个错误,以模仿 unix 的rm -rf /行为。
警告
没有任何受支持的方法可以恢复被 mpremote rm -r : 删除的文件。请谨慎使用。
tree 命令将打印给定目录的树状结构。使用 --size/-s 选项将打印每个文件的大小,或使用 --human/-h 以更易于阅读的格式显示。注意:只有当设备的文件系统报告非零大小时,才会打印目录大小。可以使用 -v 选项在输出中包含串行设备的名称。
所有其他命令都隐式假定路径为远程路径,但为了清晰起见,也可以选择性地使用 :。
所有文件系统子命令都接受多个路径参数,因此如果序列中还有另一个命令,你必须使用 + 来终止参数,例如:
$ mpremote fs cp main.py :main.py + repl
这会将文件复制到设备,然后进入 REPL。+ 可防止 "repl" 被解释为路径。
cp 命令支持 -r 选项以进行递归复制。默认情况下,如果源文件和目标文件的 SHA256 哈希值匹配,cp 会跳过将文件复制到远程设备。要强制复制而不论哈希值如何,请使用 -f 选项。
注意: 为方便起见,所有文件系统子命令也都 被别名为常规命令,即你可以写 mpremote cp ... 来代替 mpremote fs cp ...。
df¶
查询设备的空闲/已用空间:
$ mpremote df
df 命令将打印设备文件系统的大小/已用/空闲统计信息,类似于 Unix 的 df 命令。
edit¶
编辑设备上的文件:
$ mpremote edit <files...>
edit 命令会将每个文件从设备复制到本地临时目录,然后为每个文件启动你的编辑器(由环境变量 $EDITOR 定义)。如果编辑器成功退出,更新后的文件将被复制回设备。
mip¶
使用 mip 工具从 micropython-lib(或 GitHub)安装软件包:
$ mpremote mip install <packages...>
更多信息请参阅 包管理。
mount¶
将本地目录挂载到远程设备上:
$ mpremote mount [options] <local-dir>
这允许远程设备将本地主机目录视为其自己的文件系统。这对开发很有用,并且避免了在处理文件时需要将其复制到设备上。
设备会安装一个文件系统驱动程序,然后将其挂载到 设备 VFS 中作为 /remote,它使用与 mpremote 的串行连接作为旁路通道来访问文件。设备的当前工作目录(通过 os.chdir)将被设置为 /remote,这样在挂载处于活动状态时,导入和文件访问都将发生在那里,而不是默认的文件系统路径。
注意: 如果 mount 命令后面没有跟随序列中的另一个操作,则会在序列末尾隐式添加一个 repl 命令。
在使用期间,Ctrl-D 会像往常一样触发软复位,但挂载将自动重新连接。然而,如果设备在启动时运行了 main.py,则无法重新挂载。在这种情况下,可以使用原始模式软重启:按 Ctrl-A Ctrl-D 重启,然后按 Ctrl-B 返回正常的 repl,此时挂载将就绪。
选项有:
-l、--unsafe-links:默认情况下,如果设备访问的文件或目录位于所挂载的本地目录之外(向上一个或多个目录层级),将引发错误。此选项会对符号链接禁用此检查,允许设备跟随指向本地目录之外的符号链接。
unmount¶
从远程设备卸载本地目录:
$ mpremote umount
这会在 mpremote 终止时自动发生,但它也可以在序列中使用,以便在运行后续命令之前卸载先前的挂载。
romfs¶
管理设备上的 ROMFS 分区:
$ mpremote romfs <sub-command>
<sub-command> 可以是:
romfs query列出所有可用的 ROMFS 分区及其大小romfs [-o <output>] build <source>从给定的源目录创建 ROMFS 镜像;默认输出文件为源名称附加.romfsromfs [-p <partition>] deploy <source>将 ROMFS 镜像部署到设备;如果源是目录,还会创建一个临时 ROMFS 镜像
build 和 deploy 子命令都支持 -m/--mpy 选项,以在创建 ROMFS 镜像时自动将 .py 文件编译为 .mpy。此选项默认启用,但仅在已安装 mpy_cross Python 软件包时才有效(例如通过 pip install mpy_cross)。如果未安装该软件包,则会打印警告,并且 .py 文件保持原样。可以使用 --no-mpy 选项禁用 .py 文件的编译。
rtc¶
设置/获取设备时钟(RTC):
$ mpremote rtc
这将查询设备 RTC 的当前时间,并将其打印为一个 datetime 元组。
$ mpremote rtc --set
这将把设备 RTC 设置为主机 PC 的当前时间。
sleep¶
在执行下一个命令之前休眠(延迟):
$ mpremote sleep 0.5
这将使命令序列的执行暂停指定的秒数,例如以等待设备完成某些操作。
reset¶
对设备进行硬复位:
$ mpremote reset
注意: 硬复位等价于 machine.reset()。
bootloader¶
进入引导加载程序:
$ mpremote bootloader
这将使设备进入其引导加载程序。引导加载程序是因板而异的——详情请参阅你的板子的 快速参考 中的 Recovery and debug pins 部分。
自动连接与软复位¶
如果没有显式给出连接和断开连接命令,则会在工具执行的开始和结束时自动完成连接和断开连接。自动连接将搜索第一个可用的 USB 串行设备。
连接到设备后,mpremote 会在需要时自动对设备进行软复位。这会清除 Python 堆并重启解释器,确保后续的 Python 代码在全新的环境中执行。首次执行以下命令之一时会执行自动软复位:mount、eval、exec、run、fs。首次执行软复位后,将不会再自动执行,直到发出 disconnect 命令。
自动软复位行为可以通过 resume 命令来控制。这在使用 eval 命令检查设备状态时可能会很有用。soft-reset 命令可用于在一系列命令的中间执行显式的软复位。
快捷方式¶
可以使用宏系统来定义快捷方式。内置的快捷方式有:
devs:connect list的别名a0、a1、a2、a3:connect /dev/ttyACMn的别名u0、u1、u2、u3:connect /dev/ttyUSBn的别名c0、c1、c2、c3:connect COMn的别名cat、edit、ls、cp、rm、mkdir、rmdir、touch:fs <sub-command>的别名
可以在用户配置文件 mpremote/config.py 中定义额外的快捷方式,该文件位于用户配置目录中。每个操作系统的正确位置使用 platformdirs 模块确定。
通常为:- $XDG_CONFIG_HOME/mpremote/config.py - $HOME/.config/mpremote/config.py - $env:LOCALAPPDATA/mpremote/config.py
config.py 文件应定义一个名为 commands 的字典。该字典的键是快捷方式,值则是字符串或字符串列表:
"c33": "connect id:334D335C3138",
命令 c33 会被替换为 connect id:334D335C3138。
"test": ["mount", ".", "exec", "import test"],
命令 test 会被替换为 mount . exec "import test"。
快捷方式也可以接受参数。例如:
"multiply x=4 y=7": "eval x*y",
运行 mpremote multiply 3 7 会在设备上将 x 和 y 设置为变量,然后求值表达式 x*y。
一个示例 config.py 可能如下所示:
commands = {
"c33": "connect id:334D335C3138", # Connect to a specific device by ID.
"bl": "bootloader", # Shorter alias for bootloader.
"double x=4": "eval x*2", # x is an argument, with default 4
"wl_scan": ["exec", """
import network
wl = network.WLAN()
wl.active(1)
for ap in wl.scan():
print(ap)
""",], # Print out nearby WiFi networks.
"wl_ipconfig": [
"exec",
"import network; sta_if = network.WLAN(network.WLAN.IF_STA); print(sta_if.ipconfig('addr4'))",
], # Print ip address of station interface.
"test": ["mount", ".", "exec", "import test"], # Mount current directory and run test.py.
"demo": ["run", "path/to/demo.py"], # Execute demo.py on the device.
}
示例¶
mpremote
连接到第一个可用设备并隐式运行 repl 命令。
mpremote a1
连接到位于 /dev/ttyACM1(Linux)的设备并隐式运行 repl 命令。请参阅上面的 快捷方式。
mpremote c1
连接到位于 COM1(Windows)的设备并隐式运行 repl 命令。请参阅上面的 快捷方式。
mpremote connect /dev/ttyUSB0
显式指定要连接的设备,并如上所述隐式运行 repl 命令。
mpremote a1 ls
连接到位于 /dev/ttyACM1 的设备,然后运行 ls 命令。
这等价于 mpremote connect /dev/ttyACM1 fs ls。
mpremote exec "import micropython; micropython.mem_info()"
运行指定的 Python 命令并显示所有输出。这等价于在 REPL 提示符下键入该命令。
mpremote eval 1/2 eval 3/4
依次求值每个表达式并打印结果。
mpremote a0 eval 1/2 a1 eval 3/4
在位于 /dev/ttyACM0 的设备上求值 1/2,然后在位于 /dev/ttyACM1 的设备上求值 3/4,并打印每个结果。
mpremote resume exec "print_state_info()" soft-reset
连接到设备而不触发 软复位,并执行 print_state_info() 函数(例如以查明有关当前程序状态的信息),然后触发软复位。
mpremote reset sleep 0.5 bootloader
对设备进行硬复位,等待 500ms 使其变为可用状态,然后进入引导加载程序。
mpremote cp utils/driver.py :utils/driver.py + run test.py
更新设备上 utils/driver.py 的副本,然后在设备上执行本地的 test.py 脚本。test.py 永远不会被复制到设备文件系统,而是从 RAM 中运行。
mpremote cp utils/driver.py :utils/driver.py + exec "import app"
更新设备上 utils/driver.py 的副本,然后在设备上执行 app.py。
这是一种常见的开发工作流,即更新单个文件然后重新启动程序。在这种情况下,设备上的 main.py 也会执行 import app。
mpremote cp utils/driver.py :utils/driver.py + soft-reset repl
更新设备上 utils/driver.py 的副本,然后触发软复位以重启程序,然后通过 repl 命令监视输出。
mpremote cp -r utils/ :utils/ + soft-reset repl
与上面相同,但首先更新整个 utils 目录。
mpremote mount .
将当前本地目录挂载到设备上的 /remote,并启动一个 repl 会话,该会话将使用 /remote 作为工作目录。
mpremote mount . exec "import demo"
挂载当前本地目录后,从挂载的目录中执行 demo.py。
mpremote mount app run test.py
将本地目录 app 作为 /remote 挂载到设备后,从主机的当前目录执行本地的 test.py,而不将其复制到文件系统。
mpremote mount . repl --inject-code "import demo"
挂载当前本地目录后,每次按下 Ctrl-J 时都会从挂载的目录中执行 demo.py。
你需要先按 Ctrl-D 来复位解释器状态(这会保留挂载),然后再按 Ctrl-J 来重新导入 demo.py。
mpremote mount app repl --inject-file demo.py
与上面相同,但每次按下 Ctrl-K 时都会在 REPL 中执行本地文件 demo.py 的内容。如上所述,请先使用 Ctrl-D 复位解释器状态。
mpremote cat boot.py
显示设备上 boot.py 的内容。
mpremote edit utils/driver.py
使用你本地的 $EDITOR 编辑设备上的 utils/driver.py。
mpremote cp :main.py .
将 main.py 从设备复制到本地目录。
mpremote cp main.py :
将 main.py 从本地目录复制到设备。
mpremote cp :a.py :b.py
将设备上的 a.py 复制为设备上的 b.py。
mpremote cp -r dir/ :
将本地目录 dir 递归复制到远程设备。
mpremote cp a.py b.py : + repl
将 a.py 和 b.py 从本地目录复制到设备,然后运行 repl 命令。
mpremote mip install aioble
将 aioble 软件包从 micropython-lib 安装到设备。请参阅 包管理。
mpremote mip install github:org/repo@branch
将 GitHub 上 org/repo 指定分支的软件包安装到设备。请参阅 包管理。
mpremote mip install gitlab:org/repo@branch
将 GitLab 上 org/repo 指定分支的软件包安装到设备。请参阅 包管理。
mpremote mip install --target /flash/third-party functools
将 functools 软件包从 micropython-lib 安装到设备上的 /flash/third-party 目录。请参阅 包管理。