Munka a ROMFS-sel¶
Áttekintés¶
A ROMFS (Read-Only Memory Filesystem) egy könnyűsúlyú, csak olvasható fájlrendszer, amelyet MicroPython eszközökhöz terveztek. Mikrokontrollerekre és beágyazott rendszerekre van optimalizálva, ahol a kódot és az adatokat flash memóriában kell tárolni, és hatékonyan kell hozzájuk férni anélkül, hogy RAM-ba másolnánk őket.
A ROMFS fő előnyei a következők:
Másolás nélküli importálás: a ROMFS-ben tárolt
.mpybájtkód-fájlok közvetlenül a flash memóriából (memóriába leképezve) futtathatók, ahelyett, hogy előbb RAM-ba másolnánk őket. Ez hasonló ahhoz, ahogyan a befagyasztott modulok működnek, de nem igényli a teljes firmware újraflashelését.Alacsony RAM-igény: a ROMFS-ből betöltött
.mpyfájlokban lévő állandó objektumokra (sztringek, bájtok stb.) közvetlenül a flash memóriából hivatkozunk, nem duplikálódnak a RAM-ban.Rugalmas telepítés: a ROMFS-kép gazdagépen (PC-n) is felépíthető, és a mpremote segítségével telepíthető az eszközre, a firmware újrafordítása nélkül.
Szabványos fájlrendszer-interfész: a ROMFS a VFS rendszerbe van csatolva, és normál Python fájlműveletekkel (
open,os.listdir,importstb.) érhető el.
A ROMFS kiegészíti mind az írható-olvasható FAT/LittleFS fájlrendszereket (amelyek más flash partíciókon helyezkednek el), mind a befagyasztott modulokat (amelyek magába a firmware-be vannak fordítva).
Eszköztámogatás¶
A ROMFS az OpenMV firmware-ben minden olyan kameramodulon engedélyezve van, amelynek a flash elrendezésében fenn van tartva egy ROMFS partíció. Ezeken a modulokon a ROMFS partíciót a rendszer indításkor automatikusan felismeri és a /rom útvonalra csatolja; mind a /rom, mind a /rom/lib hozzáadásra kerül a sys.path listához, így az ott tárolt modulok közvetlenül importálhatók.
Eszköz |
ROMFS-támogatás |
|---|---|
OpenMV Cam N6 |
Igen |
OpenMV AE3 |
Igen |
OpenMV Cam RT1062 |
Igen |
OpenMV Cam Pure Thermal |
Igen |
OpenMV Cam M4 / M7 / H7 / H7 Plus |
Igen |
Arduino Giga |
Igen |
Arduino Portenta H7 |
Igen |
Arduino Nicla Vision |
Igen |
Arduino Nano 33 BLE Sense |
Nem (nincs ROMFS partíció) |
Arduino Nano RP2040 Connect |
Nem (nincs ROMFS partíció) |
Lásd a romfs modult egy OpenMV-specifikus segédeszközhöz, amely a /rom útvonalra csatolt ROMFS-t vizsgálja.
Munkafolyamat¶
A ROMFS használatának tipikus munkafolyamata a következő:
Hozz létre egy könyvtárat a PC-den a telepíteni kívánt Python fájlokkal (vagy
.mpyfájlokkal).Használd az
mpremote romfs deploy <directory>parancsot a ROMFS-kép felépítéséhez és az eszközre történő telepítéséhez.A ROMFS a következő indításkor a
/romútvonalra lesz csatolva (vagy azonnal csatolható, ha az eszközt újraindítod).Az eszközön futó Python kód ezután ugyanúgy
import-álhat modulokat a ROMFS-ből, mint bármely más fájlrendszerből.
Például:
# On the host PC, with a directory "myapp/" containing app.py:
$ mpremote romfs deploy myapp/
Soft-reset után az eszközön a /rom/app.py (vagy a /rom/app.mpy, ha az mpy_cross telepítve van) elérhető lesz importáláshoz.
Az mpremote alparancsainak teljes részleteiért lásd az alábbi mpremote romfs alparancsok szakaszt.
Python API¶
A ROMFS Python API-ját a vfs modul biztosítja.
- class vfs.VfsRom(buffer)
Létrehoz egy ROMFS fájlrendszer-objektumot a buffer alapján, amelynek a pufferprotokollt támogató objektumnak kell lennie (pl. egy
bytes,bytearrayvagymemoryviewobjektum), és egy érvényes ROMFS-képet kell tartalmaznia.A konstruktor ellenőrzi, hogy a buffer a ROMFS varázsbájtjaival (
b"\xd2\xcd\x31") kezdődik-e. Ha a puffer túl kicsi, vagy nem érvényes ROMFS, akkorOSError(ENODEV)kivétel keletkezik.Az ezzel a konstruktorral létrehozott objektumok a
vfs.mount()függvénnyel csatolhatók.Példa:
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')
Vagy egy fájlban tárolt ROMFS-kép csatolásához:
import vfs with open('/flash/app.romfs', 'rb') as f: romfs_data = f.read() fs = vfs.VfsRom(romfs_data) vfs.mount(fs, '/rom2')
A
VfsRomobjektumon a következő metódusok érhetők el:- VfsRom.open(path, mode)
Megnyit egy fájlt a ROMFS-ből. Csak az olvasási módok (
'','r','rt','rb') támogatottak. Egy fájl írásra történő megnyitásának kísérleteOSError(EROFS)kivételt vált ki.A visszaadott fájlobjektum támogatja a
read(),seek(),tell()ésclose()műveleteket. Az olvasási módban megnyitott bináris fájlok esetén a visszaadott objektum a pufferprotokollt is támogatja, így a fájl adataiból egymemoryviewszerezhető, amely közvetlenül a ROMFS memóriájára hivatkozik (másolás nélkül).
- VfsRom.ilistdir(path)
Visszaad egy iterátort a path könyvtár bejegyzésein. Minden bejegyzés egy
(name, type, inode, size)tuple, ahol a type fájl esetén0x8000, könyvtár esetén0x4000.
- VfsRom.stat(path)
Visszaad egy
os.stat-szerű, 10 elemű tuple-t a path útvonalhoz.OSError(ENOENT)kivételt vált ki, ha az útvonal nem létezik.
- VfsRom.statvfs(path)
Visszaadja a fájlrendszer statisztikáit. A blokkméret 1-ként van megadva, a blokkszám pedig a ROMFS-kép teljes méretét jelöli bájtban. A szabad blokkok és a szabad fájlok száma mindig 0 (csak olvasható fájlrendszer).
- VfsRom.chdir(path)
Könyvtárat vált a ROMFS-en belül. Csak a gyökér (
'/') támogatott; bármely alkönyvtárra való váltásOSError(EOPNOTSUPP)kivételt vált ki.
- VfsRom.getcwd()
Visszaadja az aktuális munkakönyvtárat a ROMFS-en belül. Mindig
'/'-t ad vissza.
- vfs.rom_ioctl(op, ...)
Alacsony szintű interfész az eszköz csak olvasható memória- (ROM-) partíciójának/partícióinak eléréséhez.
A támogatott műveletek a következők:
vfs.rom_ioctl(1)– Visszaadja az elérhető ROM partíciók számát.vfs.rom_ioctl(2, id)– Visszaadja az id indexű ROM partíciótmemoryviewobjektumként. A memória olvasható, de közvetlenül nem írható.vfs.rom_ioctl(3, id, length)– Előkészít egy ROM partíciót íráshoz. Törli az id indexű partíció első length bájtját. Visszaadja a minimális írási méretet bájtban (a későbbi írásokhoz szükséges igazítást).vfs.rom_ioctl(4, id, offset, buf)– A buf-ot (egy bytes-szerű objektumot) az id indexű ROM partícióra írja a offset bájt eltolásnál.vfs.rom_ioctl(5, id)– Befejez egy írási sorozatot az id partícióra (elvégzi az írás után szükséges véglegesítést, például a gyorsítótár kiürítését).
Ezeket a műveleteket az
mpremotebelsőleg használja ROMFS-képek telepítéséhez. A legtöbb felhasználónak nem kell közvetlenül meghívnia avfs.rom_ioctl()függvényt.Példa (az elérhető partíciók lekérdezése):
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")
Automatikus csatolás indításkor¶
Ha a firmware-ben engedélyezve van a ROMFS-támogatás, a MicroPython az inicializálás során automatikusan megkísérli az első ROM partíciót a /rom útvonalra csatolni. Ha a partíció érvényes ROMFS-képet tartalmaz, csatolásra kerül, és mind a /rom, mind a /rom/lib automatikusan hozzáadódik a sys.path listához.
Ez azt jelenti, hogy egy ROMFS-kép mpremote segítségével történő telepítése után egy soft-reset elegendő ahhoz, hogy az új modulok importálhatóvá váljanak.
Ha a partícióban nem található érvényes ROMFS-kép (pl. egy frissen programozott modulon), a csatolás csendben kihagyásra kerül.
Az mpremote használata a ROMFS kezeléséhez¶
A mpremote eszköz három alparancsot biztosít a csatlakoztatott eszközön lévő ROMFS-képek kezeléséhez.
romfs query¶
$ mpremote romfs query
Felsorolja az eszközön elérhető összes ROMFS partíciót és azok méretét. Emellett megjeleníti az egyes partíciók első 12 bájtját hexadecimálisan, és jelzi, hogy van-e jelen érvényes ROMFS-kép.
Példakimenet:
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>
Felépít egy ROMFS-képet a gazdagépen (PC-n) lévő source könyvtárból. A kép a output helyre íródik (alapértelmezett: <source>.romfs).
Opciók:
-o <output>,--output <output>: A kimeneti fájl útvonalának megadása.-m,--mpy(alapértelmezett): A.pyfájlok automatikus fordítása.mpyformátumba azmpy_crosssegítségével, mielőtt hozzáadná őket a képhez. Igényli azmpy_crossPython csomagot (pip install mpy_cross).--no-mpy: A.pyfájlok automatikus fordításának letiltása.
Példa:
$ 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>
ROMFS-kép telepítése az eszközre. A source a következők egyike lehet:
Egy könyvtár a gazdagépen: a ROMFS-kép a memóriában épül fel, és közvetlenül kerül telepítésre.
Egy
.romfsvagy.imgfájl: a kép lemezről kerül beolvasásra és telepítésre.
Opciók:
-p <partition>,--partition <partition>: A cél partíció indexének megadása (alapértelmezett:0).-m,--mpy(alapértelmezett): A.pyfájlok.mpyformátumba fordítása, amikor a source egy könyvtár.--no-mpy: A.pyfájlok automatikus fordításának letiltása.
A telepítés után az eszközt soft-reset-elni kell, hogy az új ROMFS a /rom útvonalra csatolódjon.
Példa:
$ 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
Példák¶
Egy egyszerű alkalmazás telepítése¶
Tegyük fel, hogy van egy myapp/ projektkönyvtárad a következő szerkezettel:
myapp/
main.py
utils.py
lib/
helper.py
Az eszköz ROMFS-ére történő telepítéshez:
$ mpremote romfs deploy myapp/
Soft-reset után a modulok importálhatók a ROMFS-ből:
import main
import utils
from lib import helper
A ROMFS tartalmának listázása Pythonból¶
A csatolás után a ROMFS tartalma bármely más fájlrendszerhez hasonlóan böngészhető:
import os
for entry in os.ilistdir('/rom'):
print(entry)
# Or simply:
print(os.listdir('/rom'))
Az OpenMV egy kis romfs segédeszközt is szállít, amely formázott listát nyomtat, beleértve az egyes fájlok memóriába leképezett címét és igazítását:
from omv import romfs
romfs.ls_romfs()
ROMFS beágyazása egy ROMFS-be¶
Egy külső ROMFS-en belül fájlként tárolt ROMFS-kép beágyazott fájlrendszerként csatolható. Például, ha létezik a /rom/inner.romfs. Mivel a /rom egy ROMFS, az onnan megnyitott fájlobjektumok támogatják a pufferprotokollt, így közvetlenül egy másolás nélküli memoryview szerezhető:
import vfs
with open('/rom/inner.romfs', 'rb') as f:
inner = vfs.VfsRom(memoryview(f))
vfs.mount(inner, '/inner')
print(os.listdir('/inner'))
A ROMFS képformátuma¶
A ROMFS képformátuma egy kompakt bináris formátum, amelyet mikrokontrollereken történő, memóriába leképezett hozzáférésre terveztek. Rövid áttekintés:
A kép a
0xd2 0xcd 0x31varázsbájtokkal kezdődik ("RM1"-ként kódolva, az első két bájt felső bitjeit beállítva).A kép fennmaradó része rekordokból áll, mindegyik egy típuscímkével (varuint), egy hosszal (varuint) és egy hasznos adattal (payload).
A rekordtípusok közé tartozik: kitöltés, szó szerinti adat, közvetett adatmutató, könyvtár, fájl.
A könyvtár- és fájlnevek hossz-előtagos bájtsztringekként vannak tárolva.
A fájladatok tárolhatók szó szerint (beágyazva) vagy a képen belül máshova mutató közvetett mutatón keresztül, ami lehetővé teszi az igazítást a memóriába leképezett hozzáféréshez.
Az ismeretlen rekordtípusokat a rendszer csendben kihagyja, ami előremenő kompatibilitást biztosít.
Ez a formátum a MicroPython forráskódjában az extmod/vfs_rom.c fájlban van definiálva. Az mpremote által képek felépítéséhez használt Python implementáció a tools/mpremote/mpremote/romfs.py fájlban található.
Lásd még
Munka a fájlrendszerekkel – A MicroPython VFS és az elérhető fájlrendszer-típusok áttekintése.
MicroPython manifest fájlok – Hogyan fagyaszthatók be a Python modulok a firmware-be.
MicroPython .mpy fájlok – A MicroPython .mpy bináris fájlformátuma.
MicroPython távoli vezérlés: mpremote – A teljes mpremote parancsreferencia.
romfs – OpenMV segédeszköz a csatolt /rom fájlrendszer vizsgálatához.