Werken met ROMFS¶
Overzicht¶
ROMFS (Read-Only Memory Filesystem) is een lichtgewicht, alleen-lezen bestandssysteem dat is ontworpen voor MicroPython-apparaten. Het is geoptimaliseerd voor microcontrollers en embedded systemen waar code en gegevens in het flashgeheugen moeten worden opgeslagen en efficiënt toegankelijk moeten zijn zonder naar het RAM te worden gekopieerd.
De belangrijkste voordelen van ROMFS zijn:
Zero-copy imports:
.mpy-bytecodebestanden die in een ROMFS zijn opgeslagen, kunnen rechtstreeks vanuit het flashgeheugen worden uitgevoerd (memory-mapped) in plaats van eerst naar het RAM te worden gekopieerd. Dit lijkt op de werking van frozen modules, maar vereist niet dat de volledige firmware opnieuw wordt geflasht.Lage RAM-overhead: Constante objecten (strings, bytes, enz.) in
.mpy-bestanden die vanuit ROMFS worden geladen, worden rechtstreeks vanuit het flashgeheugen gerefereerd en niet in het RAM gedupliceerd.Flexibele uitrol: Een ROMFS-image kan op een host-pc worden gebouwd en met mpremote naar het apparaat worden uitgerold, zonder de firmware opnieuw te bouwen.
Standaard bestandssysteeminterface: Een ROMFS wordt gekoppeld in de VFS en is toegankelijk via normale Python-bestandsbewerkingen (
open,os.listdir,import, enz.).
ROMFS is complementair aan zowel de lees-schrijf-bestandssystemen FAT/LittleFS (die zich in andere flashpartities bevinden) als aan frozen modules (die in de firmware zelf worden gecompileerd).
Ondersteuning per board¶
ROMFS is ingeschakeld in de OpenMV-firmware op elk camerabord dat een ROMFS-partitie heeft gereserveerd in zijn flash-indeling. Op deze boards wordt de ROMFS-partitie automatisch gedetecteerd bij het opstarten en gekoppeld aan /rom; zowel /rom als /rom/lib worden toegevoegd aan sys.path zodat modules die daar zijn opgeslagen rechtstreeks kunnen worden geïmporteerd.
Board |
ROMFS-ondersteuning |
|---|---|
OpenMV Cam N6 |
Ja |
OpenMV AE3 |
Ja |
OpenMV Cam RT1062 |
Ja |
OpenMV Cam Pure Thermal |
Ja |
OpenMV Cam M4 / M7 / H7 / H7 Plus |
Ja |
Arduino Giga |
Ja |
Arduino Portenta H7 |
Ja |
Arduino Nicla Vision |
Ja |
Arduino Nano 33 BLE Sense |
Nee (geen ROMFS-partitie) |
Arduino Nano RP2040 Connect |
Nee (geen ROMFS-partitie) |
Zie romfs voor een OpenMV-specifieke hulpfunctie die de gekoppelde ROMFS op /rom inspecteert.
Workflow¶
De typische workflow voor het gebruik van ROMFS is:
Maak een map op uw pc met de Python-bestanden (of
.mpy-bestanden) die u wilt uitrollen.Gebruik
mpremote romfs deploy <directory>om de ROMFS-image te bouwen en naar het apparaat uit te rollen.De ROMFS wordt bij de volgende keer opstarten gekoppeld aan
/rom(of kan onmiddellijk worden gekoppeld als het apparaat opnieuw wordt opgestart).Python-code op het apparaat kan vervolgens modules
import-eren vanuit de ROMFS, net als vanuit elk ander bestandssysteem.
Bijvoorbeeld:
# On the host PC, with a directory "myapp/" containing app.py:
$ mpremote romfs deploy myapp/
Na een soft-reset heeft het apparaat /rom/app.py (of /rom/app.mpy als mpy_cross is geïnstalleerd) beschikbaar om te importeren.
Zie de sectie mpremote romfs sub-commands hieronder voor volledige details over de mpremote-subcommando’s.
Python-API¶
De ROMFS Python-API wordt geleverd via de vfs-module.
- class vfs.VfsRom(buffer)
Maak een ROMFS-bestandssysteemobject van buffer, dat een object moet zijn dat het bufferprotocol ondersteunt (bijv. een
bytes-,bytearray- ofmemoryview-object) dat een geldige ROMFS-image bevat.De constructor controleert of buffer begint met de ROMFS-magic-bytes (
b"\xd2\xcd\x31"). Als de buffer te klein is of geen geldige ROMFS is, wordtOSError(ENODEV)opgeworpen.Objecten die door deze constructor zijn gemaakt, kunnen worden gekoppeld met
vfs.mount().Voorbeeld:
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')
Of, om een ROMFS-image te koppelen die in een bestand is opgeslagen:
import vfs with open('/flash/app.romfs', 'rb') as f: romfs_data = f.read() fs = vfs.VfsRom(romfs_data) vfs.mount(fs, '/rom2')
De volgende methoden zijn beschikbaar op een
VfsRom-object:- VfsRom.open(path, mode)
Open een bestand vanuit de ROMFS. Alleen leesmodi (
'','r','rt','rb') worden ondersteund. Een poging om een bestand te openen om te schrijven, werptOSError(EROFS)op.Het geretourneerde bestandsobject ondersteunt
read(),seek(),tell()enclose(). Voor binaire bestanden die in leesmodus zijn geopend, ondersteunt het geretourneerde object ook het bufferprotocol, zodat eenmemoryviewvan de bestandsgegevens kan worden verkregen, die rechtstreeks naar het ROMFS-geheugen verwijst (zero-copy).
- VfsRom.ilistdir(path)
Retourneer een iterator over de items in de map path. Elk item is een tuple
(name, type, inode, size)waarbij type gelijk is aan0x8000voor een bestand of0x4000voor een map.
- VfsRom.stat(path)
Retourneer een
os.stat-achtige 10-tuple voor path. WerptOSError(ENOENT)op als het pad niet bestaat.
- VfsRom.statvfs(path)
Retourneer statistieken van het bestandssysteem. De blokgrootte wordt gerapporteerd als 1 en het aantal blokken vertegenwoordigt de totale grootte van de ROMFS-image in bytes. Vrije blokken en vrije bestanden zijn altijd 0 (alleen-lezen bestandssysteem).
- VfsRom.chdir(path)
Wijzig de map binnen de ROMFS. Alleen de root (
'/') wordt ondersteund; overschakelen naar een submap werptOSError(EOPNOTSUPP)op.
- VfsRom.getcwd()
Retourneer de huidige werkmap binnen de ROMFS. Retourneert altijd
'/'.
- vfs.rom_ioctl(op, ...)
Low-level interface voor toegang tot de alleen-lezen geheugenpartitie(s) (ROM) van het apparaat.
De ondersteunde bewerkingen zijn:
vfs.rom_ioctl(1)– Retourneert het aantal beschikbare ROM-partities.vfs.rom_ioctl(2, id)– Retourneert de ROM-partitie met index id als eenmemoryview-object. Het geheugen kan worden gelezen, maar niet rechtstreeks worden beschreven.vfs.rom_ioctl(3, id, length)– Bereidt een ROM-partitie voor op schrijven. Wist de eerste length bytes van de partitie met index id. Retourneert de minimale schrijfgrootte in bytes (de uitlijning die vereist is voor latere schrijfbewerkingen).vfs.rom_ioctl(4, id, offset, buf)– Schrijft buf (een bytes-achtig object) naar de ROM-partitie met index id op byte-offset offset.vfs.rom_ioctl(5, id)– Voltooit een schrijfsequentie naar partitie id (voert eventuele afronding uit die nodig is na het schrijven, zoals het leegmaken van de cache).
Deze bewerkingen worden intern gebruikt door
mpremoteom ROMFS-images uit te rollen. De meeste gebruikers hoevenvfs.rom_ioctl()niet rechtstreeks aan te roepen.Voorbeeld (beschikbare partities opvragen):
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")
Automatisch koppelen bij het opstarten¶
Wanneer ROMFS-ondersteuning is ingeschakeld in de firmware, probeert MicroPython tijdens de initialisatie automatisch de eerste ROM-partitie te koppelen aan /rom. Als de partitie een geldige ROMFS-image bevat, wordt deze gekoppeld en worden zowel /rom als /rom/lib automatisch toegevoegd aan sys.path.
Dit betekent dat na het uitrollen van een ROMFS-image met mpremote een soft-reset voldoende is om de nieuwe modules importeerbaar te maken.
Als er geen geldige ROMFS-image in de partitie wordt gevonden (bijv. op een vers geprogrammeerd board), wordt het koppelen stilzwijgend overgeslagen.
mpremote gebruiken om ROMFS te beheren¶
Het hulpprogramma mpremote biedt drie subcommando’s voor het beheren van ROMFS-images op een aangesloten apparaat.
romfs query¶
$ mpremote romfs query
Toont alle beschikbare ROMFS-partities op het apparaat en hun groottes. Toont ook de eerste 12 bytes van elke partitie in hexadecimaal en rapporteert of er een geldige ROMFS-image aanwezig is.
Voorbeelduitvoer:
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>
Bouw een ROMFS-image van de map source op de host-pc. De image wordt naar output geschreven (standaard: <source>.romfs).
Opties:
-o <output>,--output <output>: Geef het pad van het uitvoerbestand op.-m,--mpy(standaard): Compileert.py-bestanden automatisch naar.mpymet behulp vanmpy_crossvoordat ze aan de image worden toegevoegd. Vereist hetmpy_crossPython-pakket (pip install mpy_cross).--no-mpy: Schakelt automatische compilatie van.py-bestanden uit.
Voorbeeld:
$ 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>
Rol een ROMFS-image uit naar het apparaat. source kan een van beide zijn:
Een map op de host: de ROMFS-image wordt in het geheugen gebouwd en rechtstreeks uitgerold.
Een
.romfs- of.img-bestand: de image wordt van schijf gelezen en uitgerold.
Opties:
-p <partition>,--partition <partition>: Geef de index van de doelpartitie op (standaard:0).-m,--mpy(standaard): Compileert.pynaar.mpywanneer source een map is.--no-mpy: Schakelt automatische compilatie van.py-bestanden uit.
Na de uitrol moet het apparaat een soft-reset krijgen om de nieuwe ROMFS te koppelen aan /rom.
Voorbeeld:
$ 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
Voorbeelden¶
Een eenvoudige applicatie uitrollen¶
Stel dat u een projectmap myapp/ heeft met de volgende structuur:
myapp/
main.py
utils.py
lib/
helper.py
Om deze uit te rollen naar de ROMFS van het apparaat:
$ mpremote romfs deploy myapp/
Na een soft-reset zijn de modules importeerbaar vanuit de ROMFS:
import main
import utils
from lib import helper
ROMFS-inhoud weergeven vanuit Python¶
Na het koppelen kan de inhoud van de ROMFS worden verkend zoals elk ander bestandssysteem:
import os
for entry in os.ilistdir('/rom'):
print(entry)
# Or simply:
print(os.listdir('/rom'))
OpenMV levert ook een kleine romfs-hulpfunctie die een opgemaakte lijst afdrukt, inclusief het memory-mapped adres en de uitlijning van elk bestand:
from omv import romfs
romfs.ls_romfs()
Een ROMFS nesten binnen een ROMFS¶
Een ROMFS-image die als bestand binnen een buitenste ROMFS is opgeslagen, kan worden gekoppeld als een genest bestandssysteem. Bijvoorbeeld, als /rom/inner.romfs bestaat. Omdat /rom een ROMFS is, ondersteunen bestandsobjecten die daaruit worden geopend het bufferprotocol, zodat een zero-copy memoryview rechtstreeks kan worden verkregen:
import vfs
with open('/rom/inner.romfs', 'rb') as f:
inner = vfs.VfsRom(memoryview(f))
vfs.mount(inner, '/inner')
print(os.listdir('/inner'))
ROMFS-imageformaat¶
Het ROMFS-imageformaat is een compact binair formaat dat is ontworpen voor memory-mapped toegang op microcontrollers. Een kort overzicht:
De image begint met de magic-bytes
0xd2 0xcd 0x31(gecodeerd als"RM1"met de hoge bits van de eerste twee bytes ingesteld).De rest van de image bestaat uit records, elk met een type-tag (varuint), een lengte (varuint) en een payload.
Recordtypes zijn onder andere: padding, verbatim-gegevens, indirecte gegevenspointer, map, bestand.
Map- en bestandsnamen worden opgeslagen als bytestrings met een lengtevoorvoegsel.
Bestandsgegevens kunnen verbatim (inline) worden opgeslagen of via een indirecte pointer naar elders in de image, wat uitlijning voor memory-mapped toegang mogelijk maakt.
Onbekende recordtypes worden stilzwijgend overgeslagen, wat voorwaartse compatibiliteit biedt.
Dit formaat is gedefinieerd in extmod/vfs_rom.c in de MicroPython-broncode. De Python-implementatie die door mpremote wordt gebruikt om images te bouwen, bevindt zich in tools/mpremote/mpremote/romfs.py.
Zie ook
Werken met bestandssystemen – Overzicht van de MicroPython VFS en de beschikbare bestandssysteemtypes.
MicroPython manifest-bestanden – Hoe u Python-modules in firmware kunt freezen.
MicroPython .mpy-bestanden – MicroPython .mpy binair bestandsformaat.
MicroPython op afstand bedienen: mpremote – De volledige mpremote-commandoreferentie.
romfs – OpenMV-hulpfunctie voor het inspecteren van het gekoppelde /rom-bestandssysteem.