14.2.2.2. ROMFS-kép buildelése¶
A ROMFS-kép egy flash memóriában lévő, csak olvasható fájlrendszer, amelyet a futtatókörnyezet automatikusan a /rom ponton csatol. Megoldja az előző oldalon felvetett eszköz-problémát: gépi tanulási modellfájlok, címketáblázatok, JSON-konfiguráció, képsablonok – bármi, amit az alkalmazás megnyit és olvas, de soha nem ír – belekerül a buildbe anélkül, hogy meg kellene fizetni a Python-literálként való beágyazás árát.
Három dolog teszi a ROMFS-t a megfelelő eszközzé a szállított eszközökhöz:
A fájlrendszer a firmware-kép része. A végfelhasználók nem tudnak fájlt törölni a
/romkönyvtárból, nem tudnak szerkeszteni egyet, és nem tudnak egyet a sajátjukra cserélni.A
/romkönyvtárban lévő fájlok helyben érhetők el. Az olyan fogyasztók, mint egy modellfájlt betöltőmlmodul, közvetlen rálátást kapnak a flash memóriára RAM-másolat nélkül – egy többmegabájtos modell a/romkönyvtárban lényegében ingyen „töltődik be”, míg ugyanaz a fájl a/sdcardkönyvtáron betöltéskor a RAM-ba olvasódik, és a hivatkozás élettartama alatt ott is marad. A közönségesopen()+readigény szerint másol: minden egyesread(n)hívásnbájtot másol a flash memóriából a RAM-ba a hívás pillanatában, egy pusztaread()pedig a teljes fájlt kéri.A
/romés a/rom/libindításkor hozzáadódik asys.pathútvonalhoz. A képbe ejtett Python-csomagok név szerint importálhatók; a hívás helyén nincs semmi különös.
14.2.2.2.1. Kép buildelése¶
A ROMFS-képek létrehozása, szerkesztése és flashelése az IDE-n keresztül történik. Használd ezt minden szállított ROMFS-partíció tartalmának egyetlen igazságforrásaként.
Ennek az az oka, hogy ez számít: a modellfájlok igazítási követelményekkel érkeznek, amelyeket a betöltő futásidőben kikényszerít. A .tflite fájlokat 16 bájtos határokra kell kitölteni, az N6 NPU-ja pedig a lefordított modellekhez 32 bájtos igazítást igényel. Az IDE automatikusan alkalmazza ezt a kitöltést, amikor a képet írja. Azok az eszközök, amelyek a forrásfát kitöltés alkalmazása nélkül járják be – különösen az mpremote romfs –, olyan képet állítanak elő, amely tisztán csatolódik, de amelynek modelljei az első következtetési hívásnál meghibásodnak.
Az IDE ROMFS-szerkesztője a kép tartalmának interaktív nézete. Fájlok és mappák adhatók hozzá, nevezhetők át és törölhetők a memóriában; a mentés az eredményt egy flashelésre kész .img fájlként írja ki. Egy modellt néhány eszköz és egy Python-csomag mellett szállító alkalmazás tipikus szerkezete így néz ki:
model.tflite
labels.txt
config.json
templates/
calibration.jpg
lib/
mylib/
__init__.py
helpers.py
Javaslat
Mind az IDE, mind az mpremote a .py fájlokat .mpy bájtkóddá fordítja keresztfordítóval, miközben azok bekerülnek egy ROMFS-képbe, így a kamera betöltéskor a feldolgozási költség megfizetése nélkül importálja őket. A forrásfájlok a szerkesztőben .py formátumban maradnak; a kép .mpy fájlokat tartalmaz.
Miután a kép flashelve van, a fa a MicroPythonból a /rom/ ponton látható:
>>> import os
>>> os.listdir('/rom')
['model.tflite', 'labels.txt', 'config.json', 'templates', 'lib']
>>> import mylib
>>> mylib.helpers
<module 'mylib.helpers' from '/rom/lib/mylib/helpers.mpy'>
14.2.2.2.2. Az alkalmazás nagy része a ROMFS-ben él¶
A ROMFS a megfelelő otthon szinte mindennek, amit egy alkalmazás szállít: az általa importált könyvtáraknak, az általa betöltött modellfájloknak, az általa beolvasott konfigurációnak, bármely eszköznek, amelynek kimenete egy fájlfát kibocsátó build-eszközből származik (modellkonvertálók, képfeldolgozó folyamatok, eszközcsomagolók), és – ami fontos – magának az alkalmazás kódjának.
A befagyasztott modulok oldalának kicsinek kell maradnia: boot.py a REPL előtti beállításhoz, main.py mint vékony belépési pont, és csak azok a könyvtárak, amelyek nélkül a kamera valóban nem tud elindulni. Minden más a ROMFS-be kerül, ahol az iterálás egy friss, az IDE-ből kimentett és újraflashelt .img – nincs szükség firmware-újrabuildelésre, és nincs szükség kéznél lévő eszközláncra.
Az ebből adódó minta egy olyan main.py, amely semmi mást nem tesz, csak átadja a vezérlést a ROMFS-ben lévő alkalmazásnak:
# main.py (frozen)
import app
app.run()
# /rom/app/__init__.py (in ROMFS)
def run():
...
Az app megváltoztatása egy ROMFS-szerkesztés és egy újraflashelés. A firmware-build a termék teljes élettartama alatt változatlan marad, hacsak a befagyasztott oldalon valóban nem kell megváltoztatni valamit.