14.2.2.2. Створення образу ROMFS#

Образ ROMFS – це файлова система у флеш-пам’яті, доступна лише для читання, яку середовище виконання автоматично монтує в /rom. Вона вирішує проблему з ресурсами, порушену на попередній сторінці: файли моделей машинного навчання, таблиці міток, конфігурація JSON, шаблони зображень – усе, що застосунок відкриває та читає, але ніколи не записує – потрапляє у збірку без витрат на вбудовування у вигляді літералів Python.

Три речі роблять ROMFS правильним інструментом для ресурсів у готовому продукті:

  • Файлова система є частиною образу мікропрограми. Кінцеві користувачі не можуть видалити, редагувати або замінити жоден файл у /rom.

  • Файли в /rom доступні безпосередньо. Споживачі на кшталт модуля ml, що завантажує файл моделі, отримують пряме відображення флеш-пам’яті без копіювання в оперативну пам’ять – багатомегабайтна модель з /rom «завантажується» фактично безкоштовно, тоді як той самий файл з /sdcard читається в оперативну пам’ять під час завантаження і залишається там протягом усього часу існування посилання. Звичайний open() + read копіює за потребою: кожен виклик read(n) копіює n байт з флеш-пам’яті в оперативну пам’ять у момент виклику, а голий read() запитує весь файл.

  • /rom та /rom/lib додаються до sys.path при завантаженні. Пакети Python, розміщені в образі, можна імпортувати за іменем; місце виклику не потребує нічого особливого.

14.2.2.2.1. Створення образу#

Образи ROMFS створюються, редагуються та прошиваються через IDE. Використовуйте IDE як основне джерело істини щодо вмісту кожного постачального розділу ROMFS.

Чому це важливо: файли моделей мають вимоги до вирівнювання, які завантажувач під час виконання перевіряє. Файли .tflite повинні бути доповнені до кратності 16 байт, а NPU мікросхеми N6 вимагає вирівнювання по 32 байти для скомпільованих моделей. IDE автоматично застосовує це доповнення під час запису образу. Інструменти, що обходять дерево вихідних файлів без застосування доповнення – зокрема mpremote romfs – створюють образ, який монтується без помилок, але моделі якого не спрацьовують при першому виклику інференсу.

Редактор ROMFS в IDE – це інтерактивний перегляд вмісту образу. Файли та папки можна додавати, перейменовувати та видаляти в пам’яті; збереження записує результат як файл .img, готовий до прошивки. Типова структура для застосунку, що постачається з моделлю разом із деякими ресурсами та пакетом Python, виглядає так:

model.tflite
labels.txt
config.json
templates/
    calibration.jpg
lib/
    mylib/
        __init__.py
        helpers.py

Порада

Як IDE, так і mpremote крос-компілюють файли .py у байткод .mpy під час включення до образу ROMFS, тому камера імпортує їх без витрат на синтаксичний аналіз під час завантаження. Вихідні файли в редакторі залишаються .py; образ містить .mpy.

Після прошивки образу дерево стає доступним з MicroPython за шляхом /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. Більша частина застосунку знаходиться в ROMFS#

ROMFS – це правильне місце для майже всього, що постачається з застосунком: бібліотеки, які він імпортує, файли моделей, які він завантажує, конфігурація, яку він читає, будь-який ресурс, вихід якого отримано з інструменту збирання, що генерує дерево файлів (конвертери моделей, конвеєри зображень, пакувальники ресурсів), і – що важливо – сам код застосунку.

Частина заморожених модулів повинна залишатися невеликою: boot.py для налаштування перед REPL, main.py як тонка точка входу, і лише ті бібліотеки, без яких камера справді не може завантажитись. Все інше переходить до ROMFS, де ітерування – це збереження нового .img з IDE та перепрошивка – без необхідності перебирати мікропрограму, без наявного набору інструментів для цього.

Патерн, що з цього виходить, – це main.py, який нічого не робить, крім делегування до застосунку в ROMFS:

# main.py (frozen)
import app
app.run()

# /rom/app/__init__.py (in ROMFS)
def run():
    ...

Зміна в app – це редагування ROMFS та перепрошивка. Збірка мікропрограми залишається незмінною протягом усього терміну служби продукту, якщо щось у замороженій частині справді не потребує змін.