Práce s ROMFS¶
Přehled¶
ROMFS (Read-Only Memory Filesystem) je odlehčený souborový systém určený pouze pro čtení, navržený pro zařízení s MicroPythonem. Je optimalizovaný pro mikrokontroléry a vestavěné systémy, kde je potřeba ukládat kód a data ve flash paměti a efektivně k nim přistupovat bez nutnosti kopírovat je do RAM.
Hlavní výhody ROMFS jsou:
Importy bez kopírování: Soubory s bytecode
.mpyuložené v ROMFS lze spouštět přímo z flash paměti (mapované do paměti) místo toho, aby se nejprve kopírovaly do RAM. Je to podobné tomu, jak fungují zamrzlé moduly, ale nevyžaduje to přeflashování celého firmwaru.Nízká režie RAM: Konstantní objekty (řetězce, bajty atd.) v souborech
.mpynačtených z ROMFS jsou odkazovány přímo z flash paměti, nikoli duplikovány v RAM.Flexibilní nasazení: Obraz ROMFS lze sestavit na hostitelském PC a nasadit do zařízení pomocí mpremote, aniž by bylo nutné znovu sestavovat firmware.
Standardní rozhraní souborového systému: ROMFS je připojen ve VFS a přistupuje se k němu pomocí běžných souborových operací Pythonu (
open,os.listdir,importatd.).
ROMFS doplňuje jak souborové systémy FAT/LittleFS pro čtení i zápis (které se nacházejí v jiných oddílech flash paměti), tak zamrzlé moduly (které jsou zkompilovány přímo do firmwaru).
Podpora desek¶
ROMFS je ve firmwaru OpenMV povolen na každé kameře, která má ve svém rozložení flash paměti vyhrazený oddíl pro ROMFS. Na těchto deskách je oddíl ROMFS automaticky detekován při startu a připojen na /rom; jak /rom, tak /rom/lib jsou přidány do sys.path, takže moduly tam uložené lze importovat přímo.
Deska |
Podpora ROMFS |
|---|---|
OpenMV Cam N6 |
Ano |
OpenMV AE3 |
Ano |
OpenMV Cam RT1062 |
Ano |
OpenMV Cam Pure Thermal |
Ano |
OpenMV Cam M4 / M7 / H7 / H7 Plus |
Ano |
Arduino Giga |
Ano |
Arduino Portenta H7 |
Ano |
Arduino Nicla Vision |
Ano |
Arduino Nano 33 BLE Sense |
Ne (žádný oddíl ROMFS) |
Arduino Nano RP2040 Connect |
Ne (žádný oddíl ROMFS) |
Viz romfs pro pomocníka specifického pro OpenMV, který zkoumá připojený ROMFS na /rom.
Pracovní postup¶
Typický pracovní postup pro použití ROMFS je:
Vytvořte na svém PC adresář se soubory Pythonu (nebo soubory
.mpy), které chcete nasadit.Použijte
mpremote romfs deploy <directory>k sestavení a nasazení obrazu ROMFS do zařízení.ROMFS bude připojen na
/rompři příštím startu (nebo může být připojen okamžitě, pokud se zařízení restartuje).Kód Pythonu v zařízení pak může pomocí
importimportovat moduly z ROMFS stejně jako z jakéhokoli jiného souborového systému.
Například:
# On the host PC, with a directory "myapp/" containing app.py:
$ mpremote romfs deploy myapp/
Po měkkém restartu bude mít zařízení k dispozici pro import /rom/app.py (nebo /rom/app.mpy, pokud je nainstalován mpy_cross).
Úplné podrobnosti o dílčích příkazech mpremote naleznete v sekci dílčí příkazy mpremote romfs níže.
Python API¶
Python API pro ROMFS je poskytováno prostřednictvím modulu vfs.
- class vfs.VfsRom(buffer)
Vytvoří objekt souborového systému ROMFS z buffer, který musí být objektem podporujícím buffer protokol (např. objekt
bytes,bytearraynebomemoryview) obsahujícím platný obraz ROMFS.Konstruktor ověří, že buffer začíná magickými bajty ROMFS (
b"\xd2\xcd\x31"). Pokud je buffer příliš malý nebo se nejedná o platný ROMFS, je vyvolána výjimkaOSError(ENODEV).Objekty vytvořené tímto konstruktorem lze připojit pomocí
vfs.mount().Příklad:
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')
Nebo, pro připojení obrazu ROMFS uloženého v souboru:
import vfs with open('/flash/app.romfs', 'rb') as f: romfs_data = f.read() fs = vfs.VfsRom(romfs_data) vfs.mount(fs, '/rom2')
Na objektu
VfsRomjsou k dispozici následující metody:- VfsRom.open(path, mode)
Otevře soubor z ROMFS. Podporovány jsou pouze režimy pro čtení (
'','r','rt','rb'). Pokus o otevření souboru pro zápis vyvoláOSError(EROFS).Vrácený souborový objekt podporuje
read(),seek(),tell()aclose(). U binárních souborů otevřených v režimu čtení vrácený objekt také podporuje buffer protokol, takže lze získatmemoryviewdat souboru, který odkazuje přímo do paměti ROMFS (bez kopírování).
- VfsRom.ilistdir(path)
Vrátí iterátor přes položky v adresáři path. Každá položka je n-tice
(name, type, inode, size), kde type je0x8000pro soubor nebo0x4000pro adresář.
- VfsRom.stat(path)
Vrátí 10prvkovou n-tici podobnou
os.statpro path. VyvoláOSError(ENOENT), pokud cesta neexistuje.
- VfsRom.statvfs(path)
Vrátí statistiky souborového systému. Velikost bloku je uváděna jako 1 a počet bloků představuje celkovou velikost obrazu ROMFS v bajtech. Počet volných bloků a volných souborů je vždy 0 (souborový systém pouze pro čtení).
- VfsRom.chdir(path)
Změní adresář v rámci ROMFS. Podporován je pouze kořen (
'/'); změna na jakýkoli podadresář vyvoláOSError(EOPNOTSUPP).
- VfsRom.getcwd()
Vrátí aktuální pracovní adresář v rámci ROMFS. Vždy vrací
'/'.
- vfs.rom_ioctl(op, ...)
Nízkoúrovňové rozhraní pro přístup k oddílu (oddílům) paměti pouze pro čtení (ROM) zařízení.
Podporované operace jsou:
vfs.rom_ioctl(1)– Vrátí počet dostupných oddílů ROM.vfs.rom_ioctl(2, id)– Vrátí oddíl ROM s indexem id jako objektmemoryview. Paměť lze číst, ale ne přímo zapisovat.vfs.rom_ioctl(3, id, length)– Připraví oddíl ROM pro zápis. Vymaže prvních length bajtů oddílu s indexem id. Vrátí minimální velikost zápisu v bajtech (zarovnání požadované pro následné zápisy).vfs.rom_ioctl(4, id, offset, buf)– Zapíše buf (objekt podobný bytes) do oddílu ROM s indexem id na bajtový posun offset.vfs.rom_ioctl(5, id)– Dokončí sekvenci zápisu do oddílu id (provede případné dokončovací operace potřebné po zápisu, jako je vyprázdnění mezipaměti).
Tyto operace používá interně
mpremotek nasazování obrazů ROMFS. Většina uživatelů nepotřebuje volatvfs.rom_ioctl()přímo.Příklad (dotazování dostupných oddílů):
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")
Automatické připojení při startu¶
Když je podpora ROMFS povolena ve firmwaru, MicroPython se během inicializace automaticky pokusí připojit první oddíl ROM na /rom. Pokud oddíl obsahuje platný obraz ROMFS, je připojen a jak /rom, tak /rom/lib jsou automaticky přidány do sys.path.
To znamená, že po nasazení obrazu ROMFS pomocí mpremote stačí měkký restart, aby byly nové moduly importovatelné.
Pokud v oddílu není nalezen žádný platný obraz ROMFS (např. na čerstvě naprogramované desce), připojení je tiše přeskočeno.
Použití mpremote ke správě ROMFS¶
Nástroj mpremote poskytuje tři dílčí příkazy pro správu obrazů ROMFS na připojeném zařízení.
romfs query¶
$ mpremote romfs query
Vypíše všechny dostupné oddíly ROMFS na zařízení a jejich velikosti. Také zobrazí prvních 12 bajtů každého oddílu v hexadecimálním tvaru a uvede, zda je přítomen platný obraz ROMFS.
Příklad výstupu:
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>
Sestaví obraz ROMFS z adresáře source na hostitelském PC. Obraz je zapsán do output (výchozí: <source>.romfs).
Možnosti:
-o <output>,--output <output>: Určuje cestu k výstupnímu souboru.-m,--mpy(výchozí): Automaticky zkompiluje soubory.pyna.mpypomocímpy_crosspřed jejich přidáním do obrazu. Vyžaduje balíček Pythonumpy_cross(pip install mpy_cross).--no-mpy: Zakáže automatickou kompilaci souborů.py.
Příklad:
$ 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>
Nasadí obraz ROMFS do zařízení. source může být buď:
Adresář na hostiteli: obraz ROMFS je sestaven v paměti a nasazen přímo.
Soubor
.romfsnebo.img: obraz je načten z disku a nasazen.
Možnosti:
-p <partition>,--partition <partition>: Určuje index cílového oddílu (výchozí:0).-m,--mpy(výchozí): Zkompiluje.pyna.mpy, pokud je source adresář.--no-mpy: Zakáže automatickou kompilaci souborů.py.
Po nasazení musí být zařízení měkce restartováno, aby byl nový ROMFS připojen na /rom.
Příklad:
$ 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říklady¶
Nasazení jednoduché aplikace¶
Předpokládejme, že máte projektový adresář myapp/ s následující strukturou:
myapp/
main.py
utils.py
lib/
helper.py
Pro jeho nasazení do ROMFS zařízení:
$ mpremote romfs deploy myapp/
Po měkkém restartu jsou moduly importovatelné z ROMFS:
import main
import utils
from lib import helper
Výpis obsahu ROMFS z Pythonu¶
Po připojení lze obsah ROMFS prozkoumat jako u jakéhokoli jiného souborového systému:
import os
for entry in os.ilistdir('/rom'):
print(entry)
# Or simply:
print(os.listdir('/rom'))
OpenMV také dodává malého pomocníka romfs, který vypíše formátovaný výpis včetně do paměti mapované adresy a zarovnání každého souboru:
from omv import romfs
romfs.ls_romfs()
Vnoření ROMFS do ROMFS¶
Obraz ROMFS uložený jako soubor uvnitř vnějšího ROMFS lze připojit jako vnořený souborový systém. Například pokud existuje /rom/inner.romfs. Protože /rom je ROMFS, souborové objekty z něj otevřené podporují buffer protokol, takže lze získat memoryview bez kopírování přímo:
import vfs
with open('/rom/inner.romfs', 'rb') as f:
inner = vfs.VfsRom(memoryview(f))
vfs.mount(inner, '/inner')
print(os.listdir('/inner'))
Formát obrazu ROMFS¶
Formát obrazu ROMFS je kompaktní binární formát navržený pro do paměti mapovaný přístup na mikrokontrolérech. Stručný přehled:
Obraz začíná magickými bajty
0xd2 0xcd 0x31(zakódovanými jako"RM1"s nastavenými horními bity prvních dvou bajtů).Zbytek obrazu se skládá ze záznamů, z nichž každý má typovou značku (varuint), délku (varuint) a obsah.
Typy záznamů zahrnují: výplň, doslovná data, nepřímý datový ukazatel, adresář, soubor.
Názvy adresářů a souborů jsou uloženy jako bajtové řetězce s předponou délky.
Data souboru mohou být uložena doslovně (vložená) nebo prostřednictvím nepřímého ukazatele na jiné místo v obrazu, což umožňuje zarovnání pro do paměti mapovaný přístup.
Neznámé typy záznamů jsou tiše přeskočeny, což zajišťuje dopřednou kompatibilitu.
Tento formát je definován v extmod/vfs_rom.c ve zdrojovém kódu MicroPythonu. Implementace v Pythonu používaná nástrojem mpremote k sestavování obrazů se nachází v tools/mpremote/mpremote/romfs.py.
Viz také
Práce se souborovými systémy – Přehled VFS MicroPythonu a dostupných typů souborových systémů.
Soubory manifestu MicroPython – Jak zamrazit moduly Pythonu do firmwaru.
Soubory .mpy v MicroPythonu – Binární formát souborů .mpy MicroPythonu.
Vzdálené ovládání MicroPythonu: mpremote – Úplná referenční příručka příkazu mpremote.
romfs – Pomocník OpenMV pro zkoumání připojeného souborového systému /rom.