14.2.2.2. การสร้าง ROMFS image¶
ROMFS image คือระบบไฟล์แบบอ่านอย่างเดียวที่อยู่ในแฟลช ซึ่งรันไทม์เมาท์อัตโนมัติที่ /rom มันแก้ปัญหา asset ที่หน้าก่อนหน้าปิดท้ายด้วย: ไฟล์โมเดล machine learning, ตารางป้ายกำกับ, การกำหนดค่า JSON, เทมเพลตภาพ -- สิ่งใดก็ตามที่แอปพลิเคชันเปิดและอ่านแต่ไม่เขียน -- เข้าสู่การสร้างโดยไม่ต้องเสียค่าใช้จ่ายในการฝังเป็น Python literals
สามสิ่งทำให้ ROMFS เป็นเครื่องมือที่เหมาะสมสำหรับ asset ที่จัดส่ง:
ระบบไฟล์ เป็นส่วนหนึ่งของเฟิร์มแวร์ image ผู้ใช้ปลายทางไม่สามารถลบไฟล์จาก
/rom, แก้ไขหนึ่ง, หรือแทนที่หนึ่งด้วยของตัวเองได้ไฟล์ใน
/romสามารถเข้าถึง ณ ตำแหน่งนั้น ผู้ใช้อย่างโมดูลmlที่โหลดไฟล์โมเดลได้รับมุมมองโดยตรงเข้าสู่แฟลชโดยไม่มีสำเนา RAM -- โมเดลหลาย megabyte บน/rom"โหลด" โดยแทบไม่มีต้นทุน ในขณะที่ไฟล์เดียวกันบน/sdcardจะถูกอ่านเข้า RAM เมื่อโหลดและอยู่ที่นั่นตลอดอายุของการอ้างอิง การใช้open()+readทั่วไปจะคัดลอกตามความต้องการ: แต่ละการเรียกread(n)จะคัดลอกnbytes จากแฟลชไปยัง RAM ณ เวลาที่เรียก โดยread()เปล่าจะขอไฟล์ทั้งหมด/romและ/rom/libถูกเพิ่มในsys.pathเมื่อบูต Python packages ที่วางลงใน image สามารถ import ตามชื่อได้ โดยไม่มีอะไรพิเศษที่จุดที่เรียกใช้
14.2.2.2.1. การสร้าง image¶
ROMFS images ถูกสร้าง, แก้ไข, และแฟลชผ่าน IDE ใช้เป็นแหล่งความจริงสำหรับเนื้อหาของทุก ROMFS partition ที่จัดส่ง
เหตุผลที่เรื่องนี้สำคัญ: ไฟล์โมเดลมีข้อกำหนดการจัดตำแหน่งที่ loader ณ รันไทม์บังคับใช้ ไฟล์ .tflite ต้องถูก pad ให้ครบ 16-byte boundaries และ NPU ของ N6 ต้องการการจัดตำแหน่ง 32-byte สำหรับโมเดลที่คอมไพล์แล้ว IDE จะใส่ padding นั้นโดยอัตโนมัติเมื่อเขียน image เครื่องมือที่เดิน source tree โดยไม่ใส่ padding -- mpremote romfs โดยเฉพาะ -- จะสร้าง image ที่เมาท์ได้สะอาดแต่โมเดลล้มเหลวเมื่อการอนุมานครั้งแรก
โปรแกรมแก้ไข ROMFS ของ IDE เป็นมุมมองแบบโต้ตอบของเนื้อหา image ไฟล์และโฟลเดอร์สามารถเพิ่ม, เปลี่ยนชื่อ, และลบในหน่วยความจำ; การบันทึกจะเขียนผลลัพธ์ออกมาเป็นไฟล์ .img ที่พร้อมแฟลช โครงสร้างทั่วไปสำหรับแอปพลิเคชันที่จัดส่งโมเดลพร้อม asset และ Python package มีลักษณะดังนี้:
model.tflite
labels.txt
config.json
templates/
calibration.jpg
lib/
mylib/
__init__.py
helpers.py
Tip
ทั้ง IDE และ mpremote จะ cross-compile ไฟล์ .py เป็น .mpy bytecode เมื่อเข้า ROMFS image ดังนั้นกล้องจะ import โดยไม่ต้องเสียค่าใช้จ่ายในการ parse เมื่อโหลด ไฟล์ซอร์สในโปรแกรมแก้ไขยังคงเป็น .py; image จะมี .mpy
เมื่อ image ถูกแฟลชแล้ว โครงสร้างจะมองเห็นได้จาก 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 คือที่อยู่ที่เหมาะสมสำหรับเกือบทุกอย่างที่แอปพลิเคชันจัดส่ง: ไลบรารีที่ import, ไฟล์โมเดลที่โหลด, การกำหนดค่าที่อ่าน, asset ใด ๆ ที่ผลลัพธ์มาจาก build tool ที่ปล่อย file tree (ตัวแปลงโมเดล, image pipeline, ตัวบรรจุ asset), และ -- สำคัญ -- โค้ดแอปพลิเคชันเอง
ด้าน frozen-modules ควรอยู่เล็กน้อย: boot.py สำหรับการตั้งค่าก่อน REPL, main.py เป็น entry point บาง, และเฉพาะไลบรารีที่กล้องจำเป็นต้องมีจริงๆ เพื่อบูต สิ่งอื่นทั้งหมดไปใน ROMFS ที่การทำซ้ำคือการบันทึก .img ใหม่จาก IDE และแฟลชใหม่ -- ไม่ต้องสร้างเฟิร์มแวร์ใหม่ ไม่ต้องมี toolchain
รูปแบบที่เกิดขึ้นคือ main.py ที่ทำอะไรก็แค่มอบหมายงานให้แอปพลิเคชันที่อยู่ใน ROMFS:
# main.py (frozen)
import app
app.run()
# /rom/app/__init__.py (in ROMFS)
def run():
...
การเปลี่ยนแปลง app คือการแก้ไข ROMFS และการแฟลชใหม่ การสร้างเฟิร์มแวร์ยังคงเดิมตลอดอายุของผลิตภัณฑ์ เว้นแต่สิ่งใดสิ่งหนึ่งบนด้าน frozen จำเป็นต้องเปลี่ยนจริงๆ