14.2.2.2. Construirea unei imagini ROMFS¶
O imagine ROMFS este un sistem de fișiere read-only, rezident în flash, pe care runtime-ul îl montează automat la /rom. Rezolvă problema activelor cu care s-a încheiat pagina anterioară: fișiere de model de învățare automată, tabele de etichete, configurare JSON, șabloane de imagini – orice deschide și citește aplicația, dar nu scrie niciodată – ajung în build fără a plăti costul încorporării ca literali Python.
Trei lucruri fac din ROMFS instrumentul potrivit pentru activele livrate:
Sistemul de fișiere este parte din imaginea firmware-ului. Utilizatorii finali nu pot șterge un fișier din
/rom, edita unul sau înlocui unul cu al lor propriu.Fișierele din
/romsunt accesibile pe loc. Consumatori precum modululmlcare încarcă un fișier de model obțin o vedere directă în flash, fără o copie în RAM – un model de mai mulți megaocteți pe/romse „încarcă” practic gratuit, în timp ce același fișier pe/sdcardeste citit în RAM la momentul încărcării și rămâne acolo pe toată durata de viață a referinței. Funcția obișnuităopen()+readcopiază la cerere: fiecare apelread(n)copiazănocteți din flash în RAM în momentul apelului, cu unread()gol care cere întregul fișier./romși/rom/libsunt adăugate lasys.pathla pornire. Pachetele Python plasate în imagine pot fi importate după nume; nimic special la locul apelului.
14.2.2.2.1. Construirea unei imagini¶
Imaginile ROMFS sunt create, editate și programate prin OpenMV IDE. Folosiți-l ca sursă de adevăr pentru conținutul fiecărei partiții ROMFS livrate.
Motivul pentru care contează: fișierele de model vin cu cerințe de aliniere pe care loader-ul le impune la execuție. Fișierele .tflite trebuie completate până la limite de 16 octeți, iar NPU-ul plăcii N6 necesită aliniere la 32 de octeți pentru modelele compilate. OpenMV IDE aplică automat acea completare atunci când scrie imaginea. Instrumentele care parcurg arborele sursă fără a aplica completarea – în special mpremote romfs – produc o imagine care se montează corect, dar ale cărei modele eșuează la primul apel de inferență.
Editorul ROMFS din OpenMV IDE este o vizualizare interactivă a conținutului imaginii. Fișierele și folderele pot fi adăugate, redenumite și șterse în memorie; salvarea scrie rezultatul ca un fișier .img gata de programat. O structură tipică pentru o aplicație care livrează un model alături de câteva active și un pachet Python arată astfel:
model.tflite
labels.txt
config.json
templates/
calibration.jpg
lib/
mylib/
__init__.py
helpers.py
Sfat
Atât OpenMV IDE, cât și mpremote compilează încrucișat fișierele .py în bytecode .mpy pe drumul spre o imagine ROMFS, astfel încât camera le importă fără a plăti costul parsării la momentul încărcării. Fișierele sursă din editor rămân .py; imaginea conține .mpy.
Odată ce imaginea este programată, arborele este vizibil din MicroPython la /rom/
>>> 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. Cea mai mare parte a aplicației se află în ROMFS¶
ROMFS este locul potrivit pentru aproape tot ceea ce livrează o aplicație: bibliotecile pe care le importă, fișierele de model pe care le încarcă, configurarea pe care o citește, orice activ a cărui ieșire a venit de la un instrument de build care emite un arbore de fișiere (convertoare de modele, pipeline-uri de imagini, împachetatoare de active) și – important – codul aplicației însuși.
Partea cu modulele înghețate ar trebui să rămână mică: boot.py pentru configurarea înainte de REPL, main.py ca punct de intrare subțire și doar bibliotecile fără de care camera chiar nu poate porni. Tot restul merge în ROMFS, unde iterarea asupra lui înseamnă o nouă imagine .img salvată din OpenMV IDE și reprogramată – fără reconstruirea firmware-ului, fără un lanț de instrumente la îndemână pentru a o face.
Modelul care rezultă este un main.py care nu face nimic altceva decât să delege către aplicația rezidentă în ROMFS:
# main.py (frozen)
import app
app.run()
# /rom/app/__init__.py (in ROMFS)
def run():
...
O modificare a lui app înseamnă o editare ROMFS și o reprogramare. Build-ul firmware-ului rămâne neschimbat pe toată durata de viață a produsului, cu excepția cazului în care ceva de pe partea înghețată chiar trebuie să se schimbe.