Rad s ROMFS¶
Pregled¶
ROMFS (Read-Only Memory Filesystem) je lagani datotečni sustav samo za čitanje, namijenjen MicroPython uređajima. Optimiran je za mikrokontrolere i ugrađene sustave gdje se kôd i podaci moraju pohraniti u flash memoriju i učinkovito im pristupati bez kopiranja u RAM.
Ključne prednosti ROMFS-a su:
Uvoz bez kopiranja:
.mpydatoteke s bajtkodom pohranjene u ROMFS-u mogu se izvršavati izravno iz flash memorije (mapirane u memoriju) umjesto da se najprije kopiraju u RAM. To je slično načinu na koji rade zamrznuti moduli, ali ne zahtijeva ponovno upisivanje cijelog ugrađenog programa (firmware).Mali zauzet RAM: Konstantni objekti (nizovi, bajtovi itd.) u
.mpydatotekama učitanima iz ROMFS-a referenciraju se izravno iz flash memorije, a ne dupliciraju u RAM-u.Fleksibilna implementacija: Slika ROMFS-a može se izraditi na host računalu i postaviti na uređaj pomoću mpremote, bez ponovne izgradnje ugrađenog programa (firmware).
Standardno sučelje datotečnog sustava: ROMFS se montira u VFS i pristupa mu se uobičajenim Python operacijama nad datotekama (
open,os.listdir,importitd.).
ROMFS nadopunjuje i datotečne sustave FAT/LittleFS za čitanje i pisanje (koji se nalaze u drugim flash particijama) i zamrznute module (koji se kompiliraju u sam ugrađeni program).
Podrška za pločice¶
ROMFS je omogućen u OpenMV ugrađenom programu (firmware) na svakoj pločici kamere koja ima rezerviranu ROMFS particiju u svom rasporedu flash memorije. Na tim se pločicama ROMFS particija automatski otkriva pri pokretanju i montira na /rom; i /rom i /rom/lib dodaju se u sys.path kako bi se moduli pohranjeni ondje mogli izravno uvoziti.
Pločica |
Podrška za ROMFS |
|---|---|
OpenMV Cam N6 |
Da |
OpenMV AE3 |
Da |
OpenMV Cam RT1062 |
Da |
OpenMV Cam Pure Thermal |
Da |
OpenMV Cam M4 / M7 / H7 / H7 Plus |
Da |
Arduino Giga |
Da |
Arduino Portenta H7 |
Da |
Arduino Nicla Vision |
Da |
Arduino Nano 33 BLE Sense |
Ne (nema ROMFS particije) |
Arduino Nano RP2040 Connect |
Ne (nema ROMFS particije) |
Pogledajte romfs za OpenMV-specifični pomoćnik koji pregledava montirani ROMFS na /rom.
Tijek rada¶
Tipičan tijek rada za korištenje ROMFS-a je:
Stvorite direktorij na računalu s Python datotekama (ili
.mpydatotekama) koje želite postaviti.Koristite
mpremote romfs deploy <directory>za izgradnju i postavljanje slike ROMFS-a na uređaj.ROMFS će biti montiran na
/rompri sljedećem pokretanju (ili se može montirati odmah ako se uređaj ponovno pokrene).Python kôd na uređaju zatim može
importmodule iz ROMFS-a baš kao i iz bilo kojeg drugog datotečnog sustava.
Na primjer:
# On the host PC, with a directory "myapp/" containing app.py:
$ mpremote romfs deploy myapp/
Nakon mekog ponovnog pokretanja, uređaj će imati /rom/app.py (ili /rom/app.mpy ako je instaliran mpy_cross) dostupan za uvoz.
Pogledajte odjeljak mpremote romfs podnaredbe u nastavku za sve pojedinosti o mpremote podnaredbama.
Python API¶
Python API za ROMFS pružen je putem modula vfs.
- class vfs.VfsRom(buffer)
Stvara objekt ROMFS datotečnog sustava iz buffer, koji mora biti objekt koji podržava protokol međuspremnika (npr. objekt
bytes,bytearrayilimemoryview) koji sadrži valjanu sliku ROMFS-a.Konstruktor provjerava počinje li buffer magičnim bajtovima ROMFS-a (
b"\xd2\xcd\x31"). Ako je međuspremnik premalen ili nije valjan ROMFS, podiže seOSError(ENODEV).Objekti stvoreni ovim konstruktorom mogu se montirati pomoću
vfs.mount().Primjer:
import vfs # Load a ROMFS image from flash into a memoryview. dev = vfs.rom_ioctl(2, 0) # get partition 0 as a memoryview fs = vfs.VfsRom(dev) vfs.mount(fs, '/rom')
Ili, za montiranje slike ROMFS-a pohranjene u datoteci:
import vfs with open('/flash/app.romfs', 'rb') as f: romfs_data = f.read() fs = vfs.VfsRom(romfs_data) vfs.mount(fs, '/rom2')
Sljedeće metode dostupne su na
VfsRomobjektu:- VfsRom.open(path, mode)
Otvara datoteku iz ROMFS-a. Podržani su samo načini čitanja (
'','r','rt','rb'). Pokušaj otvaranja datoteke za pisanje podići ćeOSError(EROFS).Vraćeni objekt datoteke podržava
read(),seek(),tell()iclose(). Za binarne datoteke otvorene u načinu čitanja, vraćeni objekt također podržava protokol međuspremnika tako da se može dobitimemoryviewpodataka datoteke, koji se izravno odnosi na ROMFS memoriju (bez kopiranja).
- VfsRom.ilistdir(path)
Vraća iterator nad unosima u direktoriju path. Svaki unos je n-torka
(name, type, inode, size)gdje je type jednak0x8000za datoteku ili0x4000za direktorij.
- VfsRom.stat(path)
Vraća 10-torku sličnu
os.statza path. PodižeOSError(ENOENT)ako putanja ne postoji.
- VfsRom.statvfs(path)
Vraća statistiku datotečnog sustava. Veličina bloka prijavljuje se kao 1, a broj blokova predstavlja ukupnu veličinu slike ROMFS-a u bajtovima. Slobodni blokovi i slobodne datoteke uvijek su 0 (datotečni sustav samo za čitanje).
- VfsRom.chdir(path)
Mijenja direktorij unutar ROMFS-a. Podržan je samo korijenski (
'/'); promjena u bilo koji poddirektorij podižeOSError(EOPNOTSUPP).
- VfsRom.getcwd()
Vraća trenutni radni direktorij unutar ROMFS-a. Uvijek vraća
'/'.
- vfs.rom_ioctl(op, ...)
Niskorazinsko sučelje za pristup particiji(ama) memorije samo za čitanje (ROM) na uređaju.
Podržane operacije su:
vfs.rom_ioctl(1)– Vraća broj dostupnih ROM particija.vfs.rom_ioctl(2, id)– Vraća ROM particiju s indeksom id kaomemoryviewobjekt. Memorija se može čitati, ali ne i izravno pisati.vfs.rom_ioctl(3, id, length)– Priprema ROM particiju za pisanje. Briše prvih length bajtova particije s indeksom id. Vraća minimalnu veličinu zapisa u bajtovima (poravnanje potrebno za naknadne zapise).vfs.rom_ioctl(4, id, offset, buf)– Upisuje buf (objekt sličan bajtovima) u ROM particiju s indeksom id na bajtnom pomaku offset.vfs.rom_ioctl(5, id)– Dovršava sekvencu pisanja na particiju id (izvodi sve potrebne završne radnje nakon pisanja, poput pražnjenja predmemorije).
Te operacije interno koristi
mpremoteza postavljanje slika ROMFS-a. Većini korisnika nije potrebno izravno pozivativfs.rom_ioctl().Primjer (ispitivanje dostupnih particija):
import vfs n = vfs.rom_ioctl(1) print("Number of ROM partitions:", n) for i in range(n): dev = vfs.rom_ioctl(2, i) print(f" Partition {i}: {len(dev)} bytes")
Automatsko montiranje pri pokretanju¶
Kada je podrška za ROMFS omogućena u ugrađenom programu (firmware), MicroPython će tijekom inicijalizacije automatski pokušati montirati prvu ROM particiju na /rom. Ako particija sadrži valjanu sliku ROMFS-a, montira se i i /rom i /rom/lib automatski se dodaju u sys.path.
To znači da je nakon postavljanja slike ROMFS-a pomoću mpremote meko ponovno pokretanje dovoljno da novi moduli postanu uvozivi.
Ako se u particiji ne pronađe valjana slika ROMFS-a (npr. na svježe programiranoj pločici), montiranje se tiho preskače.
Korištenje mpremote za upravljanje ROMFS-om¶
Alat mpremote pruža tri podnaredbe za upravljanje slikama ROMFS-a na povezanom uređaju.
romfs query¶
$ mpremote romfs query
Prikazuje sve dostupne ROMFS particije na uređaju i njihove veličine. Također prikazuje prvih 12 bajtova svake particije u heksadecimalnom obliku i prijavljuje je li prisutna valjana slika ROMFS-a.
Primjer izlaza:
ROMFS0 partition has size 131072 bytes (32 blocks of 4096 bytes each)
Raw contents: d2:cd:31:XX:XX:XX:XX:XX:XX:XX:XX:XX ...
ROMFS image size: 1234
romfs build¶
$ mpremote romfs [-o <output>] build <source>
Izgrađuje sliku ROMFS-a iz direktorija source na host računalu. Slika se upisuje u output (zadano: <source>.romfs).
Opcije:
-o <output>,--output <output>: Određuje putanju izlazne datoteke.-m,--mpy(zadano): Automatski kompilira.pydatoteke u.mpypomoćumpy_crossprije njihova dodavanja u sliku. Zahtijevampy_crossPython paket (pip install mpy_cross).--no-mpy: Onemogućuje automatsku kompilaciju.pydatoteka.
Primjer:
$ mpremote romfs build myapp/
Building romfs filesystem, source directory: myapp/
/
|-- main.py -> .mpy
\-- lib/
\-- helper.py -> .mpy
Writing 2048 bytes to output file myapp.romfs
romfs deploy¶
$ mpremote romfs [-p <partition>] deploy <source>
Postavlja sliku ROMFS-a na uređaj. source može biti:
Direktorij na hostu: slika ROMFS-a izgrađuje se u memoriji i postavlja izravno.
Datoteka
.romfsili.img: slika se čita s diska i postavlja.
Opcije:
-p <partition>,--partition <partition>: Određuje indeks ciljne particije (zadano:0).-m,--mpy(zadano): Kompilira.pyu.mpykada je source direktorij.--no-mpy: Onemogućuje automatsku kompilaciju.pydatoteka.
Nakon postavljanja, uređaj se mora meko ponovno pokrenuti kako bi se novi ROMFS montirao na /rom.
Primjer:
$ mpremote romfs deploy myapp/
Building romfs filesystem, source directory: myapp/
/
|-- main.py -> .mpy
\-- lib/
\-- helper.py -> .mpy
Image size is 2048 bytes
ROMFS0 partition has size 131072 bytes (32 blocks of 4096 bytes each)
Preparing ROMFS0 partition for writing
Deploying ROMFS to ROMFS0 partition
ROMFS image deployed
$ mpremote soft-reset
Primjeri¶
Postavljanje jednostavne aplikacije¶
Pretpostavimo da imate projektni direktorij myapp/ sa sljedećom strukturom:
myapp/
main.py
utils.py
lib/
helper.py
Za postavljanje na ROMFS uređaja:
$ mpremote romfs deploy myapp/
Nakon mekog ponovnog pokretanja, moduli se mogu uvoziti iz ROMFS-a:
import main
import utils
from lib import helper
Ispisivanje sadržaja ROMFS-a iz Pythona¶
Nakon montiranja, sadržaj ROMFS-a može se istraživati kao i kod bilo kojeg drugog datotečnog sustava:
import os
for entry in os.ilistdir('/rom'):
print(entry)
# Or simply:
print(os.listdir('/rom'))
OpenMV također isporučuje mali romfs pomoćnik koji ispisuje formatirani popis uključujući memorijski mapiranu adresu i poravnanje svake datoteke:
from omv import romfs
romfs.ls_romfs()
Ugnježđivanje ROMFS-a unutar ROMFS-a¶
Slika ROMFS-a pohranjena kao datoteka unutar vanjskog ROMFS-a može se montirati kao ugniježđeni datotečni sustav. Na primjer, ako postoji /rom/inner.romfs. Budući da je /rom ROMFS, objekti datoteka otvoreni iz njega podržavaju protokol međuspremnika, pa se izravno može dobiti memoryview bez kopiranja:
import vfs
with open('/rom/inner.romfs', 'rb') as f:
inner = vfs.VfsRom(memoryview(f))
vfs.mount(inner, '/inner')
print(os.listdir('/inner'))
Format slike ROMFS-a¶
Format slike ROMFS-a kompaktan je binarni format namijenjen pristupu mapiranom u memoriju na mikrokontrolerima. Kratki pregled:
Slika počinje magičnim bajtovima
0xd2 0xcd 0x31(kodirani kao"RM1"s postavljenim visokim bitovima prva dva bajta).Ostatak slike sastoji se od zapisa, svaki s oznakom tipa (varuint), duljinom (varuint) i korisnim sadržajem.
Tipovi zapisa uključuju: ispunu, doslovne podatke, neizravni pokazivač na podatke, direktorij, datoteku.
Imena direktorija i datoteka pohranjuju se kao bajtni nizovi s prefiksom duljine.
Podaci datoteke mogu se pohraniti doslovno (umetnuto) ili putem neizravnog pokazivača na drugo mjesto u slici, što omogućuje poravnanje za pristup mapiran u memoriju.
Nepoznati tipovi zapisa tiho se preskaču, čime se osigurava kompatibilnost s budućim verzijama.
Ovaj je format definiran u extmod/vfs_rom.c u izvornom kodu MicroPythona. Python implementacija koju mpremote koristi za izgradnju slika nalazi se u tools/mpremote/mpremote/romfs.py.
Više informacija
Rad s datotečnim sustavima – Pregled MicroPython VFS-a i dostupnih tipova datotečnih sustava.
MicroPython manifest datoteke – Kako zamrznuti Python module u ugrađeni program.
MicroPython .mpy datoteke – MicroPython .mpy format binarne datoteke.
Daljinsko upravljanje MicroPythonom: mpremote – Potpuna referenca naredbi mpremote.
romfs – OpenMV pomoćnik za pregledavanje montiranog /rom datotečnog sustava.