关于MicroPython mpremote工具 的一些用例,闲聊

2022-10-29,,

关于MicroPython mpremote工具 的一些用例,闲聊

我尝试了很多不同的第三方micropython工具,有些是Windows应用程序,有些是VScode插件。

但是当我尝试过MicroPython的mpremote工具后,我几乎决定它将成为我的首选工具。

我通常将其与VScode结合使用。它的代码突出显示,自动完成和自动缩进非常有用。同时打开其他插件也很容易。另外VScode也是一个多平台的IDE,我比较习惯在几个不同的操作系统里用同一个IDE,来回切换不会生手。

也许有些极简主义者,我认为mpremote工具也会很合适,只需将系统的终端与任何文本编辑器一起使用即可,如果你是命令行老手,则只需要一个终端即可完成所有操作。

目录 (Table of Contents)

目录
关于MicroPython mpremote工具 的一些用例,闲聊
链接
1. cp
1.1 在终端的当前路径中复制文件
1.2 复制绝对路径中的文件
1.3 同时复制多个文件
2. exec, run
2.1 执行给定的 Python 代码
2.2 从本地文件系统运行脚本
3. mount
3.1 在远程设备上挂载本地目录
3.2 在挂载了本地目录后继续使用原flash中的脚本
3.3 加快测试速度的一种方法

链接

PyPI 页面 在终端用pip install mpremote命令即可安装。(推荐)

GitHub 页面

MicroPython文档页面

本文在GitHub micropython/discussions/9096的页面

1. cp

这可能是除 repl 之外最常见的命令,用于将文件从本地复制到设备,或从设备复制到本地。可能是因为我还不熟悉终端命令语法,起初我无法从MicroPython文档中的几个用例中完全掌握cp命令的用法,反复运用和尝试后就渐渐上手了。

1.1 在终端的当前路径中复制文件

首先创建一个干净的临时文件夹,并在其中写入一个main.py文件。

print ("start")
for i in range(2):
print(i)
print ("end")

最简单的用例,在终端中输入此文件夹路径,将文件从本地复制到设备:

mpremote connect COM1 cp main.py : 

mpremote connect COM1 cp main.py :main.py

这两个命令实现完全相同的功能。

:符号之后,如果输入文件名,则文件在复制到设备时将重命名为此文件名。

将文件从设备复制到本地 :

mpremote connect COM1 cp :main.py .

mpremote connect COM1 cp :main.py main.py

这两个命令实现完全相同的功能。

如果要重命名,可以删除.符号并输入所需的文件名。

1.2 复制绝对路径中的文件

它有点复杂。

在 Windows 上,使用文件的绝对路径从本地复制到设备:

mpremote connect COM1 cp D:\temp\main.py :main.py

将文件从设备复制到本地 :

mpremote connect COM1 cp :main.py D:\temp\main.py

目前在mpremote 0.3.0版本,应特别注意在Windows中不能省略目标文件名!

我在 GitHub 上已提交PR #9148 对 Windows 路径名分隔符的支持,下一个版本应该就可以随意在Windows里使用相对路径和绝对路径了,不影响其他功能。

在 Linux(如 Ubuntu)中,从绝对路径复制文件可以省略目标文件名:

mpremote connect /dev/ttyACM0 cp ~/temp/main.py :

mpremote connect /dev/ttyACM0 cp /home/wind/temp/main.py :

mpremote connect /dev/ttyACM0 cp :main.py ~/temp/

mpremote connect /dev/ttyACM0 cp :main.py /home/wind/temp/

1.3 同时复制多个文件

在Linux中,例如Ubuntu,将多个文件从本地复制到具有绝对路径的设备:

mpremote connect /dev/ttyACM0 cp ~/temp/main.py ~/temp/main2.py :

将多个文件从设备复制到本地绝对路径:

mpremote connect /dev/ttyACM0 cp :main.py :main2.py ~/temp/

2. exec, run

这些命令用于控制远程设备在不复制文件的情况下运行 Python 代码或脚本。

2.1 执行给定的 Python 代码

mpremote connect COM1 exec "print(1234)"

就像在REPL中输入一行Python代码一样。

2.2 从本地文件系统运行脚本

mpremote connect COM1 run test_1.py

就像在REPL中进入粘贴模式一样,将代码复制并粘贴到指定的Python脚本中,然后运行它。

3. mount

我未曾想过有这种使用MicroPython设备的方法,请看以下用例并尝试理解它,随后你就会像我一样对这个功能爱不释手~~

3.1 在远程设备上挂载本地目录

首先创建一个干净的临时目录,并在其中写入一些Python脚本,如下所示:

# numbers.py
num_1 = 21
num_2 = 22
num_3 = 23
num_4 = 24
# test_1.py
print("test_1 start")
import numbers
print(numbers.num_1)
print(numbers.num_2)
print(numbers.num_4)
print("test_1 end")
# test_2.py
print("test_2 start")
import numbers
temp1 = numbers.num_3 - numbers.num_2
print(temp1)
temp1 = numbers.num_3 - numbers.num_1
print(temp1)
print("test_2 end")

在终端中输入此目录的路径。

我们先确认一些信息,列出设备上的文件:

mpremote connect COM1 ls

ls :
139 boot.py

进入 REPL 并再次确认:

mpremote connect COM1 repl
>>> uos.listdir()
['boot.py']
>>>

退出 REPL,挂载本地目录,再次进入 repl:

mpremote connect COM1 mount . repl

再次确认文件:

>>> uos.listdir()
['numbers.py','test_1.py', 'test_2.py']

这里没有boot.py,但我们在本地目录创建的Python脚本出现在列表中。

导入并运行两个测试脚本:

>>> import test_1,test_2
test_1 start
21
22
24
test_1 end
test_2 start
1
2
test_2 end
>>>

查看一个文件:

>>> f=open("numbers.py")
>>> print(f.read())
# numbers.py
num_1 = 21
num_2 = 22
num_3 = 23
num_4 = 24 >>>

惊讶之余,你可能想知道,这些python脚本文件是不是全部都上传到设备上并存储起来了?我最初也是这么猜测的。

现在,我们将终端保留在REPL中,在本地修改此文件:

# numbers.py
num_1 = 1
num_2 = 12
num_3 = 23
num_4 = 35

返回 REPL 并再次检查:

>>> f=open("numbers.py")
>>> print(f.read())
# numbers.py
num_1 = 1
num_2 = 12
num_3 = 23
num_4 = 35 >>>

这样就解除疑惑了,文件只保存在本地目录中,并且这个目录被挂载在设备上。

软件重置后,并将重新挂载目录。

这就像是一个移动硬盘,或者是说像是NAS,云盘,连在MicroPython设备上,显然这个功能能极大节约设备的flash寿命,通常只需要在必须脱机运行的时候再把python脚本文件拷贝到flash里即可。

推荐使用以下组合命令执行python脚本:

mpremote connect COM1 mount . exec "import test_1"

3.2 在挂载了本地目录后继续使用原flash中的脚本

在REPL中使用uos.listdir("/")命令你将看到原来存储在flash中的文件:

>>> uos.listdir("/")
['remote', 'boot.py', 'main.py']

如果你想保持挂载本地目录的状态下使用flash中的脚本(例如main.py),你可以使用如下命令将原flash根目录路径添加进sys.path列表中:

>>> import sys
>>> sys.path
['', '.frozen', '/lib']
>>> sys.path.append("/")
>>> sys.path
['', '.frozen', '/lib', '/']
>>> import main

如果挂载的本地目录中已有main.py,则仅会运行本地目录的main.py,可通过reverse()调换列表顺序:

>>> sys.path
['', '.frozen', '/lib', '/']
>>> sys.path.reverse()
>>> sys.path
['/', '/lib', '.frozen', '']
>>> import main

现在就会优先运行flash中的脚本。

3.3 加快测试速度的一种方法

如果我们需要对一个脚本一遍测试一遍修改,而脚本中已经导入了很多存储在本地的脚本模块,这样的情况下,每一次挂载测试都将花费数秒甚至数十秒的时间。

我总结了一种方法,在REPL中设法不重复的import模块即可有效减少运行时间。

以测试SSD1306 OLED显示屏为例,main.py是主程序,ssd1306.py是驱动模块,此处就不再完整列举程序代码了。

通过time.tick_ms()来验证测试本地目录的main.py脚本所需的时间,可见大概需要6秒:

>>> import time;t1 = time.ticks_ms();import main;time.ticks_diff(time.ticks_ms(),t1)
6032

使用sys.modules可以查看当前已经导入的脚本模块,可见ssd1306.py已经导入:

>>> import sys;sys.modules
{'main': <module 'main' from 'main.py'>, 'ssd1306': <module 'ssd1306' from 'ssd1306.py'>, 'flashbdev': <module 'flashbdev' from 'flashbdev.py'>}

我们仅需移除main而保留其他的模块:

>>> del main;sys.modules.pop('main')
<module 'main' from 'main.py'>
>>> import sys;sys.modules
{'ssd1306': <module 'ssd1306' from 'ssd1306.py'>, 'flashbdev': <module 'flashbdev' from 'flashbdev.py'>}

再次测试:

>>> import time;t1 = time.ticks_ms();import main;time.ticks_diff(time.ticks_ms(),t1)
1612

得到明显改善。

关于MicroPython mpremote工具 的一些用例,闲聊的相关教程结束。

《关于MicroPython mpremote工具 的一些用例,闲聊.doc》

下载本文的Word格式文档,以方便收藏与打印。