עבודה עם ROMFS¶
סקירה כללית¶
ROMFS (Read-Only Memory Filesystem) היא מערכת קבצים קלת משקל לקריאה בלבד שתוכננה עבור התקני MicroPython. היא מותאמת למיקרו-בקרים ולמערכות מוטמעות שבהן יש לאחסן קוד ונתונים בזיכרון פלאש (flash) ולגשת אליהם ביעילות מבלי להעתיק אותם ל-RAM.
היתרונות העיקריים של ROMFS הם:
ייבוא ללא העתקה (zero-copy): קבצי קוד ביניים מסוג
.mpyהמאוחסנים ב-ROMFS ניתנים להרצה ישירות מזיכרון פלאש (flash) (ממופה לזיכרון) במקום שיועתקו תחילה ל-RAM. זה דומה לאופן שבו פועלים מודולים מוקפאים, אך אינו דורש צריבה מחדש של הקושחה כולה.עומס RAM נמוך: עצמים קבועים (מחרוזות, בייטים וכדומה) בקבצי
.mpyהנטענים מ-ROMFS מאוזכרים ישירות מהפלאש, ולא משוכפלים ב-RAM.פריסה גמישה: ניתן לבנות תמונת ROMFS על מחשב מארח ולפרוס אותה להתקן באמצעות mpremote, מבלי לבנות מחדש את הקושחה.
ממשק מערכת קבצים סטנדרטי: ROMFS מותקנת ב-VFS ונגישה דרך פעולות קבצים רגילות של Python (
open,os.listdir,importוכדומה).
ROMFS משלימה הן את מערכות הקבצים FAT/LittleFS לקריאה-כתיבה (השוכנות במחיצות פלאש אחרות) והן את המודולים המוקפאים (המהודרים לתוך הקושחה עצמה).
תמיכה בלוחות¶
ROMFS מופעלת בקושחת OpenMV בכל לוח מצלמה שיש בו מחיצת ROMFS שמורה במבנה הפלאש שלו. בלוחות אלה מחיצת ה-ROMFS מזוהה אוטומטית באתחול ומותקנת ב-/rom; הן /rom והן /rom/lib מתווספים ל-sys.path כך שניתן לייבא ישירות מודולים המאוחסנים שם.
לוח |
תמיכה ב-ROMFS |
|---|---|
OpenMV Cam N6 |
כן |
OpenMV AE3 |
כן |
OpenMV Cam RT1062 |
כן |
OpenMV Cam Pure Thermal |
כן |
OpenMV Cam M4 / M7 / H7 / H7 Plus |
כן |
Arduino Giga |
כן |
Arduino Portenta H7 |
כן |
Arduino Nicla Vision |
כן |
Arduino Nano 33 BLE Sense |
לא (אין מחיצת ROMFS) |
Arduino Nano RP2040 Connect |
לא (אין מחיצת ROMFS) |
ראו romfs לעוזר ייחודי ל-OpenMV הבוחן את ה-ROMFS המותקנת ב-/rom.
תהליך העבודה¶
תהליך העבודה הטיפוסי לשימוש ב-ROMFS הוא:
צרו ספרייה במחשב שלכם עם קובצי ה-Python (או קובצי
.mpy) שברצונכם לפרוס.השתמשו ב-
mpremote romfs deploy <directory>כדי לבנות ולפרוס את תמונת ה-ROMFS להתקן.ה-ROMFS תותקן ב-
/romבאתחול הבא (או ניתן להתקין אותה מיד אם ההתקן יאותחל מחדש).קוד Python בהתקן יכול אז לבצע
importלמודולים מה-ROMFS בדיוק כמו מכל מערכת קבצים אחרת.
לדוגמה:
# On the host PC, with a directory "myapp/" containing app.py:
$ mpremote romfs deploy myapp/
לאחר אתחול-רך, יהיה זמין בהתקן /rom/app.py (או /rom/app.mpy אם mpy_cross מותקן) לייבוא.
ראו את החלק תת-הפקודות mpremote romfs להלן לפרטים מלאים על תת-הפקודות של mpremote.
ממשק Python API¶
ה-Python API של ROMFS מסופק דרך המודול vfs.
- class vfs.VfsRom(buffer)
יצירת עצם מערכת קבצים ROMFS מתוך buffer, שחייב להיות עצם התומך בפרוטוקול החוצץ (buffer) (לדוגמה עצם
bytes,bytearrayאוmemoryview) המכיל תמונת ROMFS תקפה.הבנאי מאמת ש-buffer מתחיל בבייטי הקסם של ROMFS (
b"\xd2\xcd\x31"). אם החוצץ קטן מדי או אינו ROMFS תקף, מופעOSError(ENODEV).עצמים שנוצרו על ידי בנאי זה ניתנים להתקנה באמצעות
vfs.mount().דוגמה:
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')
או, כדי להתקין תמונת ROMFS המאוחסנת בקובץ:
import vfs with open('/flash/app.romfs', 'rb') as f: romfs_data = f.read() fs = vfs.VfsRom(romfs_data) vfs.mount(fs, '/rom2')
השיטות הבאות זמינות על עצם
VfsRom:- VfsRom.open(path, mode)
פתיחת קובץ מה-ROMFS. נתמכים מצבי קריאה בלבד (
'','r','rt','rb'). ניסיון לפתוח קובץ לכתיבה יגרום ל-OSError(EROFS).עצם הקובץ המוחזר תומך ב-
read(),seek(),tell()ו-close(). עבור קבצים בינאריים הנפתחים במצב קריאה, העצם המוחזר תומך גם בפרוטוקול החוצץ (buffer) כך שניתן להשיגmemoryviewשל נתוני הקובץ, המפנה ישירות לתוך זיכרון ה-ROMFS (ללא העתקה).
- VfsRom.ilistdir(path)
החזרת איטרטור על הרשומות בספרייה path. כל רשומה היא תוּפֶל
(name, type, inode, size)שבה type הוא0x8000עבור קובץ או0x4000עבור ספרייה.
- VfsRom.stat(path)
החזרת תוּפֶל בן 10 איברים בסגנון
os.statעבור path. גורם ל-OSError(ENOENT)אם הנתיב אינו קיים.
- VfsRom.statvfs(path)
החזרת סטטיסטיקות מערכת הקבצים. גודל הבלוק מדווח כ-1 ומספר הבלוקים מייצג את הגודל הכולל של תמונת ה-ROMFS בבייטים. בלוקים פנויים וקבצים פנויים הם תמיד 0 (מערכת קבצים לקריאה בלבד).
- VfsRom.chdir(path)
שינוי ספרייה בתוך ה-ROMFS. נתמך רק השורש (
'/'); מעבר לכל תת-ספרייה גורם ל-OSError(EOPNOTSUPP).
- VfsRom.getcwd()
החזרת ספריית העבודה הנוכחית בתוך ה-ROMFS. מחזירה תמיד
'/'.
- vfs.rom_ioctl(op, ...)
ממשק ברמה נמוכה לגישה למחיצות הזיכרון לקריאה בלבד (ROM) של ההתקן.
הפעולות הנתמכות הן:
vfs.rom_ioctl(1)– החזרת מספר מחיצות ה-ROM הזמינות.vfs.rom_ioctl(2, id)– החזרת מחיצת ה-ROM עם האינדקס id כעצםmemoryview. ניתן לקרוא מהזיכרון אך לא לכתוב אליו ישירות.vfs.rom_ioctl(3, id, length)– הכנת מחיצת ROM לכתיבה. מוחקת את length הבייטים הראשונים של המחיצה עם האינדקס id. מחזירה את גודל הכתיבה המינימלי בבייטים (היישור הנדרש לכתיבות עוקבות).vfs.rom_ioctl(4, id, offset, buf)– כתיבת buf (עצם דמוי-בייטים) למחיצת ה-ROM עם האינדקס id בהיסט offset בבייטים.vfs.rom_ioctl(5, id)– השלמת רצף כתיבה למחיצה id (מבצעת כל סיום נדרש לאחר הכתיבה, כגון רוקון מטמון).
פעולות אלה משמשות באופן פנימי את
mpremoteלפריסת תמונות ROMFS. רוב המשתמשים אינם צריכים לקרוא ל-vfs.rom_ioctl()ישירות.דוגמה (תשאול מחיצות זמינות):
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")
התקנה אוטומטית באתחול¶
כאשר תמיכת ROMFS מופעלת בקושחה, MicroPython ינסה אוטומטית להתקין את מחיצת ה-ROM הראשונה ב-/rom במהלך האתחול. אם המחיצה מכילה תמונת ROMFS תקפה, היא מותקנת והן /rom והן /rom/lib מתווספים ל-sys.path אוטומטית.
משמעות הדבר היא שלאחר פריסת תמונת ROMFS עם mpremote, אתחול-רך מספיק כדי להפוך את המודולים החדשים לניתנים לייבוא.
אם לא נמצאת תמונת ROMFS תקפה במחיצה (לדוגמה בלוח שזה עתה תוכנת), ההתקנה מדולגת בשקט.
שימוש ב-mpremote לניהול ROMFS¶
הכלי mpremote מספק שלוש תת-פקודות לניהול תמונות ROMFS בהתקן מחובר.
romfs query¶
$ mpremote romfs query
מפרטת את כל מחיצות ה-ROMFS הזמינות בהתקן ואת גודלן. מציגה גם את 12 הבייטים הראשונים של כל מחיצה בהקסדצימלי ומדווחת אם קיימת תמונת ROMFS תקפה.
פלט לדוגמה:
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>
בניית תמונת ROMFS מהספרייה source במחשב המארח. התמונה נכתבת אל output (ברירת מחדל: <source>.romfs).
אפשרויות:
-o <output>,--output <output>: ציון נתיב קובץ הפלט.-m,--mpy(ברירת מחדל): הידור אוטומטי של קובצי.pyל-.mpyבאמצעותmpy_crossלפני הוספתם לתמונה. דורש את חבילת ה-Pythonmpy_cross(pip install mpy_cross).--no-mpy: השבתת ההידור האוטומטי של קובצי.py.
דוגמה:
$ 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>
פריסת תמונת ROMFS להתקן. source יכול להיות אחד מהשניים:
ספרייה במארח: תמונת ה-ROMFS נבנית בזיכרון ונפרסת ישירות.
קובץ
.romfsאו.img: התמונה נקראת מהדיסק ונפרסת.
אפשרויות:
-p <partition>,--partition <partition>: ציון אינדקס מחיצת היעד (ברירת מחדל:0).-m,--mpy(ברירת מחדל): הידור.pyל-.mpyכאשר source הוא ספרייה.--no-mpy: השבתת ההידור האוטומטי של קובצי.py.
לאחר הפריסה, יש לבצע אתחול-רך להתקן כדי שה-ROMFS החדשה תותקן ב-/rom.
דוגמה:
$ 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
דוגמאות¶
פריסת יישום פשוט¶
נניח שיש לכם ספריית פרויקט myapp/ עם המבנה הבא:
myapp/
main.py
utils.py
lib/
helper.py
כדי לפרוס אותה ל-ROMFS של ההתקן:
$ mpremote romfs deploy myapp/
לאחר אתחול-רך, המודולים ניתנים לייבוא מה-ROMFS:
import main
import utils
from lib import helper
פירוט תוכן ROMFS מתוך Python¶
לאחר ההתקנה, ניתן לחקור את תוכן ה-ROMFS כמו כל מערכת קבצים אחרת:
import os
for entry in os.ilistdir('/rom'):
print(entry)
# Or simply:
print(os.listdir('/rom'))
OpenMV גם כוללת עוזר romfs קטן המדפיס פירוט מעוצב הכולל את כתובת הזיכרון הממופה ואת היישור של כל קובץ:
from omv import romfs
romfs.ls_romfs()
קינון ROMFS בתוך ROMFS¶
תמונת ROMFS המאוחסנת כקובץ בתוך ROMFS חיצונית ניתנת להתקנה כמערכת קבצים מקוננת. לדוגמה, אם /rom/inner.romfs קיים. מאחר ש-/rom היא ROMFS, עצמי קבצים הנפתחים ממנה תומכים בפרוטוקול החוצץ (buffer), כך שניתן להשיג memoryview ללא העתקה ישירות:
import vfs
with open('/rom/inner.romfs', 'rb') as f:
inner = vfs.VfsRom(memoryview(f))
vfs.mount(inner, '/inner')
print(os.listdir('/inner'))
תבנית תמונת ROMFS¶
תבנית תמונת ה-ROMFS היא תבנית בינארית קומפקטית שתוכננה לגישה ממופת-זיכרון במיקרו-בקרים. סקירה קצרה:
התמונה מתחילה בבייטי הקסם
0xd2 0xcd 0x31(מקודדים כ-"RM1"כאשר הביטים הגבוהים של שני הבייטים הראשונים מוגדרים).שאר התמונה מורכבת מ-רשומות, שלכל אחת תג סוג (varuint), אורך (varuint) ומטען.
סוגי הרשומות כוללים: ריפוד, נתונים מילוליים, מצביע נתונים עקיף, ספרייה, קובץ.
שמות ספריות וקבצים מאוחסנים כמחרוזות בייטים עם תחילית אורך.
נתוני קבצים ניתנים לאחסון באופן מילולי (inline) או דרך מצביע עקיף למקום אחר בתמונה, מה שמאפשר יישור לגישה ממופת-זיכרון.
סוגי רשומות לא ידועים מדולגים בשקט, מה שמספק תאימות קדימה.
תבנית זו מוגדרת ב-extmod/vfs_rom.c בקוד המקור של MicroPython. מימוש ה-Python שבו משתמש mpremote לבניית תמונות נמצא ב-tools/mpremote/mpremote/romfs.py.
ראה גם
עבודה עם מערכות קבצים – סקירה של ה-VFS של MicroPython וסוגי מערכות הקבצים הזמינים.
קובצי manifest של MicroPython – כיצד להקפיא מודולי Python לתוך הקושחה.
קובצי .mpy של MicroPython – תבנית הקובץ הבינארי .mpy של MicroPython.
שליטה מרחוק ב-MicroPython: mpremote – מדריך הפקודות המלא של mpremote.
romfs – עוזר OpenMV לבחינת מערכת הקבצים המותקנת /rom.