Controllo remoto di MicroPython: mpremote

Lo strumento da riga di comando mpremote fornisce un insieme integrato di utility per interagire da remoto con un dispositivo MicroPython, gestirne il filesystem e automatizzarlo tramite una connessione seriale. Funziona con tutte le OpenMV Cam attraverso la loro connessione seriale USB ed è un’alternativa da riga di comando a OpenMV IDE per i flussi di lavoro di scripting e automazione.

Per usare mpremote, installalo prima tramite pip:

$ pip install --user mpremote

Oppure tramite pipx:

$ pipx install mpremote

Il modo più semplice per usare questo strumento è semplicemente richiamarlo senza alcun argomento:

$ mpremote

Questo comando rileva e si connette automaticamente al primo dispositivo seriale USB disponibile e fornisce un terminale interattivo che puoi usare per accedere al REPL e all’output del tuo programma. Le porte seriali vengono aperte in modalità esclusiva, quindi l’esecuzione di una seconda (o terza, ecc.) istanza di mpremote si connetterà ai dispositivi seriali successivi, se ne sono disponibili.

Inoltre pipx ti consente anche di eseguire direttamente mpremote senza installarlo prima:

$ pipx run mpremote ...args

Comandi

mpremote supporta una serie di comandi forniti sulla riga di comando che eseguiranno in sequenza varie azioni su un dispositivo MicroPython remoto. Consulta la sezione degli esempi qui sotto per farti un’idea di come funziona e per alcune combinazioni comuni di comandi.

Ogni comando ha la forma <command name> [--options] [args...]. Per i comandi che supportano più argomenti (ad esempio un elenco di file), la lista degli argomenti può essere terminata con +.

Se non viene specificato alcun comando, il comando predefinito è repl. Inoltre, se un comando ha bisogno di accedere al dispositivo e non è stato specificato prima alcun connect, viene aggiunto implicitamente un connect auto.

Per portare il dispositivo in uno stato noto prima di qualsiasi comando di azione (eccetto repl), una volta connesso mpremote interromperà qualsiasi programma in esecuzione ed eseguirà un soft-reset del dispositivo prima di eseguire il primo comando. Puoi controllare questo comportamento usando i comandi resume e soft-reset. Consulta auto-connessione e auto-soft-reset per maggiori dettagli.

È possibile specificare più comandi che verranno eseguiti in sequenza.

L’elenco completo dei comandi supportati è:

connect

Si connette al dispositivo specificato tramite nome:

$ mpremote connect <device>

<device> può essere uno tra:

  • list: elenca i dispositivi disponibili

  • auto: si connette alla prima porta seriale USB disponibile

  • id:<serial>: si connette al dispositivo con il numero di serie USB <serial> (la seconda colonna nell’output del comando connect list)

  • port:<path>: si connette al dispositivo con il percorso indicato (la prima colonna nell’output del comando connect list

  • rfc2217://<host>:<port>: si connette al dispositivo usando la seriale su TCP (ad esempio una porta seriale di rete basata su RFC2217)

  • qualsiasi nome/percorso di dispositivo valido, per connettersi a quel dispositivo

Nota: Invece di usare il comando connect, sono disponibili diverse scorciatoie predefinite per i percorsi comuni dei dispositivi. Ad esempio il comando scorciatoia a0 equivale a connect /dev/ttyACM0 (Linux), oppure c1 per COM1 (Windows).

Nota: L’opzione auto rileverà solo le porte seriali USB, ovvero una porta seriale che ha un VID/PID USB associato (cioè dispositivi CDC/ACM o di tipo FTDI). Gli altri tipi di porte seriali non verranno rilevati automaticamente.

disconnect

Disconnette il dispositivo corrente:

$ mpremote disconnect

Dopo una disconnessione, l”auto-soft-reset viene abilitato.

resume

Mantiene lo stato esistente dell’interprete per i comandi successivi:

$ mpremote resume

Questo disabilita l”auto-soft-reset. È utile se vuoi eseguire un comando successivo su una scheda senza prima eseguirne il soft-reset.

soft-reset

Esegue un soft-reset del dispositivo:

$ mpremote soft-reset

Questo svuoterà l’heap di Python e riavvierà l’interprete. Inoltre impedisce che il comando successivo attivi l”auto-soft-reset.

repl

Entra nel REPL sul dispositivo connesso:

$ mpremote repl [--options]

Le opzioni sono:

  • --escape-non-printable, per stampare i byte/caratteri non stampabili come il loro codice esadecimale

  • --capture <file>, per catturare l’output della sessione REPL nel file indicato

  • --inject-code <string>, per specificare i caratteri da iniettare nel REPL quando viene premuto Ctrl-J. Questo ti consente di automatizzare un comando comune.

  • --inject-file <file>, per specificare un file da iniettare nel REPL quando viene premuto Ctrl-K. Questo ti consente di eseguire un file (ad esempio contenente del codice di setup utile, o persino il programma su cui stai lavorando).

Mentre il comando repl è in esecuzione, puoi usare Ctrl-] o Ctrl-x per uscire.

Nota: Il nome «REPL» qui riflette l’uso comune di questo comando per accedere al Read Eval Print Loop in esecuzione sul dispositivo MicroPython. A rigore, il comando repl funziona semplicemente come un terminale (o «monitor seriale») per accedere al dispositivo. Poiché questo comando non attiva il comportamento di auto-reset, ciò significa che se un programma è attualmente in esecuzione dovrai prima interromperlo con Ctrl-C per arrivare al REPL, il che ti permetterà poi di accedere allo stato del programma. Puoi anche usare mpremote soft-reset repl per ottenere un REPL «pulito» con tutto lo stato del programma azzerato.

eval

Valuta e stampa il risultato di un’espressione Python:

$ mpremote eval <string>

exec

Esegue il codice Python indicato:

$ mpremote exec <string>

Per impostazione predefinita, mpremote exec mostrerà qualsiasi output dell’espressione fino al suo termine. È possibile specificare il flag --no-follow per restituire il controllo immediatamente e lasciare il dispositivo a eseguire l’espressione in background.

run

Esegue uno script dal filesystem locale:

$ mpremote run <file.py>

Questo eseguirà il file direttamente dalla RAM sul dispositivo senza copiarlo nel filesystem. È un modo molto utile per iterare sullo sviluppo di un singolo blocco di codice senza doversi preoccupare di distribuirlo nel filesystem.

Per impostazione predefinita, mpremote run mostrerà qualsiasi output dello script fino al suo termine. È possibile specificare il flag --no-follow per restituire il controllo immediatamente e lasciare il dispositivo a eseguire lo script in background.

fs

Esegue comandi del filesystem sul dispositivo:

$ mpremote fs <sub-command>

<sub-command> può essere:

  • cat <file..> per mostrare il contenuto di uno o più file sul dispositivo

  • ls per elencare la directory corrente

  • ls <dirs...> per elencare le directory indicate

  • cp [-rf] <src...> <dest> per copiare file

  • rm [-r] <src...> per rimuovere file o cartelle sul dispositivo

  • mkdir <dirs...> per creare directory sul dispositivo

  • rmdir <dirs...> per rimuovere directory sul dispositivo

  • touch <file..> per creare i file (se non esistono già)

  • sha256sum <file..> per calcolare la somma SHA256 dei file

  • tree [-vsh] <dirs...> per stampare un albero delle directory indicate

Il comando cp usa una convenzione in cui un : iniziale rappresenta un percorso remoto. L’assenza di un : iniziale indica un percorso locale. Questo si basa sulla convenzione usata dal client Secure Copy Protocol (scp).

Quindi, ad esempio, mpremote fs cp main.py :main.py copia main.py dalla directory locale corrente al filesystem remoto, mentre mpremote fs cp :main.py main.py copia main.py dal dispositivo nella directory corrente.

Il comando mpremote rm -r accetta sia percorsi relativi che assoluti. Usa : per fare riferimento alla directory di lavoro corrente (cwd) remota per consentire la rimozione di un albero di directory dal percorso predefinito del dispositivo (ad esempio /flash, /). Usa -v/--verbose per vedere i file che vengono rimossi.

Ad esempio:

  • mpremote rm -r :libs rimuoverà la directory libs e tutti i suoi elementi figli dal dispositivo.

  • mpremote rm -rv :/sd rimuoverà tutti i file da una scheda SD montata e genererà un avviso non bloccante. Il punto di mount verrà mantenuto.

  • mpremote rm -rv :/ rimuoverà tutti i file sul dispositivo, inclusi quelli situati in vfs montati come /sd o /flash. Dopo aver rimosso tutte le cartelle e i file, restituirà anche un errore per imitare il comportamento di rm -rf / su unix.

Avvertimento

Non esiste un modo supportato per recuperare i file rimossi da mpremote rm -r :. Usalo con cautela.

Il comando tree stamperà un albero delle directory indicate. Usando l’opzione --size/-s verrà stampata la dimensione di ogni file, oppure usa --human/-h per usare un formato più leggibile. Nota: la dimensione della directory viene stampata solo quando il filesystem del dispositivo riporta una dimensione diversa da zero. L’opzione -v può essere usata per includere il nome del dispositivo seriale nell’output.

Tutti gli altri comandi assumono implicitamente che il percorso sia un percorso remoto, ma il : può essere usato facoltativamente per maggiore chiarezza.

Tutti i sotto-comandi del filesystem accettano più argomenti di percorso, quindi se nella sequenza è presente un altro comando devi usare + per terminare gli argomenti, ad esempio:

$ mpremote fs cp main.py :main.py + repl

Questo copierà il file sul dispositivo e poi entrerà nel REPL. Il + impedisce che "repl" venga interpretato come un percorso.

Il comando cp supporta l’opzione -r per effettuare una copia ricorsiva. Per impostazione predefinita cp salterà la copia dei file sul dispositivo remoto se l’hash SHA256 del file di origine e di destinazione coincide. Per forzare una copia indipendentemente dall’hash usa l’opzione -f.

Nota: Per comodità, tutti i sotto-comandi del filesystem sono anche aliasati come comandi normali, ovvero puoi scrivere mpremote cp ... invece di mpremote fs cp ....

df

Interroga lo spazio libero/usato del dispositivo:

$ mpremote df

Il comando df stamperà le statistiche di dimensione/usato/libero per il filesystem del dispositivo, in modo simile al comando Unix df.

edit

Modifica un file sul dispositivo:

$ mpremote edit <files...>

Il comando edit copierà ogni file dal dispositivo in una directory temporanea locale e poi avvierà il tuo editor per ciascun file (definito dalla variabile d’ambiente $EDITOR). Se l’editor esce con successo, il file aggiornato verrà ricopiato sul dispositivo.

mip

Installa pacchetti da micropython-lib (o da GitHub) usando lo strumento mip:

$ mpremote mip install <packages...>

Consulta Gestione dei pacchetti per maggiori informazioni.

mount

Monta la directory locale sul dispositivo remoto:

$ mpremote mount [options] <local-dir>

Questo consente al dispositivo remoto di vedere la directory dell’host locale come se fosse il proprio filesystem. È utile per lo sviluppo ed evita la necessità di copiare i file sul dispositivo mentre ci stai lavorando.

Il dispositivo installa un driver di filesystem, che viene poi montato nel VFS del dispositivo come /remote, il quale usa la connessione seriale verso mpremote come canale laterale per accedere ai file. Il dispositivo avrà la sua directory di lavoro corrente (tramite os.chdir) impostata su /remote in modo che le importazioni e l’accesso ai file avvengano lì invece che nel percorso del filesystem predefinito, finché il mount è attivo.

Nota: Se il comando mount non è seguito da un’altra azione nella sequenza, verrà aggiunto implicitamente un comando repl alla fine della sequenza.

Durante l’uso, Ctrl-D attiverà un soft-reset come di consueto, ma il mount verrà ricollegato automaticamente. Se però l’unità ha un main.py in esecuzione all’avvio, il rimontaggio non può avvenire. In questo caso si può usare un riavvio soft in modalità raw: Ctrl-A Ctrl-D per riavviare, poi Ctrl-B per tornare al repl normale, momento in cui il mount sarà pronto.

Le opzioni sono:

  • -l, --unsafe-links: Per impostazione predefinita viene generato un errore se il dispositivo accede a un file o a una directory che si trova al di fuori (uno o più livelli di directory più in alto) della directory locale montata. Questa opzione disabilita questo controllo per i link simbolici, consentendo al dispositivo di seguire i link simbolici al di fuori della directory locale.

unmount

Smonta la directory locale dal dispositivo remoto:

$ mpremote umount

Questo avviene automaticamente quando mpremote termina, ma può essere usato in una sequenza per smontare un mount precedente prima dell’esecuzione dei comandi successivi.

romfs

Gestisce le partizioni ROMFS sul dispositivo:

$ mpremote romfs <sub-command>

<sub-command> può essere:

  • romfs query per elencare tutte le partizioni ROMFS disponibili e la loro dimensione

  • romfs [-o <output>] build <source> per creare un’immagine ROMFS dalla directory di origine indicata; il file di output predefinito è la sorgente con l’aggiunta di .romfs

  • romfs [-p <partition>] deploy <source> per distribuire un’immagine ROMFS sul dispositivo; creerà anche un’immagine ROMFS temporanea se la sorgente è una directory

I sotto-comandi build e deploy supportano entrambi l’opzione -m/--mpy per compilare automaticamente i file .py in .mpy durante la creazione dell’immagine ROMFS. Questa opzione è abilitata per impostazione predefinita, ma funziona solo se è stato installato il pacchetto Python mpy_cross (ad esempio tramite pip install mpy_cross). Se il pacchetto non è installato, viene stampato un avviso e i file .py rimangono invariati. La compilazione dei file .py può essere disabilitata con l’opzione --no-mpy.

rtc

Imposta/legge l’orologio del dispositivo (RTC):

$ mpremote rtc

Questo interrogherà l’RTC del dispositivo per l’ora corrente e la stamperà come una tupla datetime.

$ mpremote rtc --set

Questo imposterà l’RTC del dispositivo sull’ora corrente del PC host.

sleep

Attende (ritardo) prima di eseguire il comando successivo:

$ mpremote sleep 0.5

Questo metterà in pausa l’esecuzione della sequenza di comandi per la durata specificata in secondi, ad esempio per attendere che il dispositivo faccia qualcosa.

reset

Esegue un hard reset del dispositivo:

$ mpremote reset

Nota: l’hard reset equivale a machine.reset().

bootloader

Entra nel bootloader:

$ mpremote bootloader

Questo farà entrare il dispositivo nel suo bootloader. Il bootloader è specifico per la scheda — consulta la sezione Recovery and debug pins della guida rapida della tua scheda per i dettagli.

Auto connessione e soft-reset

La connessione e la disconnessione verranno eseguite automaticamente all’inizio e alla fine dell’esecuzione dello strumento, se tali comandi non vengono forniti esplicitamente. La connessione automatica cercherà il primo dispositivo seriale USB disponibile.

Una volta connesso a un dispositivo, mpremote eseguirà automaticamente il soft-reset del dispositivo se necessario. Questo svuota l’heap di Python e riavvia l’interprete, assicurando che il codice Python successivo venga eseguito in un ambiente pulito. L’auto-soft-reset viene eseguito la prima volta che viene eseguito uno dei seguenti comandi: mount, eval, exec, run, fs. Dopo aver eseguito un soft-reset per la prima volta, non verrà più eseguito automaticamente finché non viene impartito un comando disconnect.

Il comportamento di auto-soft-reset può essere controllato con il comando resume. Questo può essere utile per usare il comando eval per ispezionare lo stato del dispositivo. Il comando soft-reset può essere usato per eseguire un soft reset esplicito nel mezzo di una sequenza di comandi.

Scorciatoie

Le scorciatoie possono essere definite usando il sistema di macro. Le scorciatoie integrate sono:

  • devs: Alias di connect list

  • a0, a1, a2, a3: Alias di connect /dev/ttyACMn

  • u0, u1, u2, u3: Alias di connect /dev/ttyUSBn

  • c0, c1, c2, c3: Alias di connect COMn

  • cat, edit, ls, cp, rm, mkdir, rmdir, touch: Alias di fs <sub-command>

È possibile definire scorciatoie aggiuntive nel file di configurazione utente mpremote/config.py, situato nella directory di configurazione utente. La posizione corretta per ciascun sistema operativo viene determinata usando il modulo platformdirs.

Questa è in genere: - $XDG_CONFIG_HOME/mpremote/config.py - $HOME/.config/mpremote/config.py - $env:LOCALAPPDATA/mpremote/config.py

Il file config.py deve definire un dizionario di nome commands. Le chiavi di questo dizionario sono le scorciatoie e i valori sono una stringa oppure una lista di stringhe:

"c33": "connect id:334D335C3138",

Il comando c33 viene sostituito da connect id:334D335C3138.

"test": ["mount", ".", "exec", "import test"],

Il comando test viene sostituito da mount . exec "import test".

Le scorciatoie possono anche accettare argomenti. Ad esempio:

"multiply x=4 y=7": "eval x*y",

Eseguendo mpremote multiply 3 7 verranno impostate x e y come variabili sul dispositivo, e poi verrà valutata l’espressione x*y.

Un esempio di config.py potrebbe avere questo aspetto:

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

Esempi

mpremote

Si connette al primo dispositivo disponibile ed esegue implicitamente il comando repl.

mpremote a1

Si connette al dispositivo all’indirizzo /dev/ttyACM1 (Linux) ed esegue implicitamente il comando repl. Consulta le scorciatoie qui sopra.

mpremote c1

Si connette al dispositivo all’indirizzo COM1 (Windows) ed esegue implicitamente il comando repl. Consulta le scorciatoie qui sopra.

mpremote connect /dev/ttyUSB0

Specifica esplicitamente a quale dispositivo connettersi e, come sopra, esegue implicitamente il comando repl.

mpremote a1 ls

Si connette al dispositivo all’indirizzo /dev/ttyACM1 e poi esegue il comando ls.

Equivale a mpremote connect /dev/ttyACM1 fs ls.

mpremote exec "import micropython; micropython.mem_info()"

Esegue il comando Python specificato e mostra qualsiasi output. Equivale a digitare il comando al prompt del REPL.

mpremote eval 1/2 eval 3/4

Valuta a turno ogni espressione e stampa i risultati.

mpremote a0 eval 1/2 a1 eval 3/4

Valuta 1/2 sul dispositivo all’indirizzo /dev/ttyACM0, poi 3/4 sul dispositivo all’indirizzo /dev/ttyACM1, stampando ogni risultato.

mpremote resume exec "print_state_info()" soft-reset

Si connette al dispositivo senza attivare un soft reset ed esegue la funzione print_state_info() (ad esempio per ottenere informazioni sullo stato corrente del programma), poi attiva un soft reset.

mpremote reset sleep 0.5 bootloader

Esegue un hard-reset del dispositivo, attende 500 ms che diventi disponibile, poi entra nel bootloader.

mpremote cp utils/driver.py :utils/driver.py + run test.py

Aggiorna la copia di utils/driver.py sul dispositivo, poi esegue lo script locale test.py sul dispositivo. test.py non viene mai copiato nel filesystem del dispositivo, bensì viene eseguito dalla RAM.

mpremote cp utils/driver.py :utils/driver.py + exec "import app"

Aggiorna la copia di utils/driver.py sul dispositivo, poi esegue app.py sul dispositivo.

Questo è un flusso di lavoro di sviluppo comune per aggiornare un singolo file e poi riavviare il programma. In questo scenario, il tuo main.py sul dispositivo eseguirebbe anche import app.

mpremote cp utils/driver.py :utils/driver.py + soft-reset repl

Aggiorna la copia di utils/driver.py sul dispositivo, poi attiva un soft-reset per riavviare il programma e infine monitora l’output tramite il comando repl.

mpremote cp -r utils/ :utils/ + soft-reset repl

Come sopra, ma aggiorna prima l’intera directory utils.

mpremote mount .

Monta la directory locale corrente su /remote sul dispositivo e avvia una sessione repl che userà /remote come directory di lavoro.

mpremote mount . exec "import demo"

Dopo aver montato la directory locale corrente, esegue demo.py dalla directory montata.

mpremote mount app run test.py

Dopo aver montato la directory locale app come /remote sul dispositivo, esegue il file locale test.py dalla directory corrente dell’host senza copiarlo nel filesystem.

mpremote mount . repl --inject-code "import demo"

Dopo aver montato la directory locale corrente, esegue demo.py dalla directory montata ogni volta che viene premuto Ctrl-J.

Dovrai prima premere Ctrl-D per reimpostare lo stato dell’interprete (il che preserverà il mount) prima di premere Ctrl-J per re-importare demo.py.

mpremote mount app repl --inject-file demo.py

Come sopra, ma esegue il contenuto del file locale demo.py al REPL ogni volta che viene premuto Ctrl-K. Come sopra, usa Ctrl-D per reimpostare prima lo stato dell’interprete.

mpremote cat boot.py

Mostra il contenuto di boot.py sul dispositivo.

mpremote edit utils/driver.py

Modifica utils/driver.py sul dispositivo usando il tuo $EDITOR locale.

mpremote cp :main.py .

Copia main.py dal dispositivo alla directory locale.

mpremote cp main.py :

Copia main.py dalla directory locale al dispositivo.

mpremote cp :a.py :b.py

Copia a.py sul dispositivo in b.py sul dispositivo.

mpremote cp -r dir/ :

Copia ricorsivamente la directory locale dir sul dispositivo remoto.

mpremote cp a.py b.py : + repl

Copia a.py e b.py dalla directory locale al dispositivo, poi esegue il comando repl.

mpremote mip install aioble

Installa il pacchetto aioble da micropython-lib sul dispositivo. Consulta Gestione dei pacchetti.

mpremote mip install github:org/repo@branch

Installa il pacchetto dal branch specificato su org/repo su GitHub sul dispositivo. Consulta Gestione dei pacchetti.

mpremote mip install gitlab:org/repo@branch

Installa il pacchetto dal branch specificato su org/repo su GitLab sul dispositivo. Consulta Gestione dei pacchetti.

mpremote mip install --target /flash/third-party functools

Installa il pacchetto functools da micropython-lib nella directory /flash/third-party sul dispositivo. Consulta Gestione dei pacchetti.