vfs — בקרת מערכת קבצים וירטואלית

המודול vfs מכיל פונקציות ליצירת אובייקטים של מערכת קבצים ולעיגון/ניתוק עיגון שלהם במערכת הקבצים הווירטואלית.

עיגון מערכת קבצים

חלק מהפורטים מספקים מערכת קבצים וירטואלית (VFS) ואת היכולת לעגן בתוכה מספר מערכות קבצים ”אמיתיות“. ניתן לעגן אובייקטים של מערכת קבצים בשורש של ה-VFS, או בתת-ספרייה השוכנת בשורש. הדבר מאפשר תצורה דינמית וגמישה של מערכת הקבצים הנראית לתוכניות Python. פורטים בעלי פונקציונליות זו מספקים את הפונקציות mount() ו-umount(), ואולי גם מימושים שונים של מערכות קבצים המיוצגים על ידי מחלקות VFS.

vfs.mount(fsobj: Any, mount_point: str, *, readonly: bool = False) None

עיגון אובייקט מערכת הקבצים fsobj במיקום ב-VFS הנתון על ידי המחרוזת mount_point. fsobj יכול להיות אובייקט VFS שיש לו מתודה mount(), או התקן בלוקים. אם מדובר בהתקן בלוקים, סוג מערכת הקבצים מזוהה אוטומטית (נזרקת חריגה אם לא זוהתה מערכת קבצים). mount_point יכול להיות '/' כדי לעגן את fsobj בשורש, או '/<name>' כדי לעגן אותו בתת-ספרייה תחת השורש.

אם readonly הוא True, מערכת הקבצים מעוגנת לקריאה בלבד.

במהלך תהליך העיגון נקראת המתודה mount() על אובייקט מערכת הקבצים.

תיזרק OSError(EPERM) אם mount_point כבר מעוגן.

vfs.mount() List[Tuple[Any, str]]

ללא ארגומנטים ל-mount(), מוחזרת רשימת tuples המייצגת את כל נקודות העיגון הפעילות.

לרשימה המוחזרת הצורה [(fsobj, mount_point), …].

vfs.umount(mount_point: str | Any) None

ניתוק עיגון של מערכת קבצים. mount_point יכול להיות מחרוזת המציינת את מיקום העיגון, או אובייקט מערכת קבצים שעוגן קודם לכן. במהלך תהליך ניתוק העיגון נקראת המתודה umount() על אובייקט מערכת הקבצים.

תיזרק OSError(EINVAL) אם mount_point לא נמצא.

class vfs.VfsFat(block_dev: AbstractBlockDev)

יצירת אובייקט מערכת קבצים המשתמש בפורמט מערכת הקבצים FAT. האחסון של מערכת הקבצים FAT מסופק על ידי block_dev. ניתן לעגן אובייקטים שנוצרו על ידי בנאי זה באמצעות mount().

static mkfs(block_dev: AbstractBlockDev) None

בניית מערכת קבצים FAT על block_dev.

class vfs.VfsRom(buffer: bytes | bytearray | memoryview)

יצירת אובייקט מערכת קבצים המשתמש בפורמט מערכת הקבצים ROMFS לקריאה בלבד. buffer חייב להיות אובייקט התומך בפרוטוקול ה-buffer (bytes, bytearray או memoryview) המכיל תמונת ROMFS תקפה.

ניתן לעגן אובייקטים שנוצרו על ידי בנאי זה באמצעות mount().

ראו עבודה עם ROMFS לפרטים מלאים, כולל כיצד לבנות ולפרוס תמונות ROMFS באמצעות mpremote.

vfs.rom_ioctl(op: int, *args: Any) Any

ממשק ברמה נמוכה לגישה אל מחיצת/מחיצות הזיכרון לקריאה בלבד (ROM) של ההתקן. הפעולות הנתמכות הן:

קריאה

התנהגות

rom_ioctl(1)

מחזיר את מספר מחיצות ה-ROM הזמינות.

rom_ioctl(2, id)

מחזיר את מחיצה id בתור memoryview.

rom_ioctl(3, id, length)

מוחק את length הבתים הראשונים של מחיצה id כהכנה לכתיבה. מחזיר את יישור הכתיבה המינימלי בבתים.

rom_ioctl(4, id, offset, buf)

כותב את buf למחיצה id בבית offset.

rom_ioctl(5, id)

מסיים רצף כתיבה למחיצה id (שוטף מטמונים וכדומה).

פעולות אלה מופעלות בדרך כלל בעקיפין על ידי mpremote בעת פריסת תמונת ROMFS; רוב היישומים אינם צריכים לקרוא להן ישירות.

class vfs.VfsPosix(root: str | None = None)

יצירת אובייקט מערכת קבצים הניגש למערכת הקבצים POSIX של המארח. אם מצוין root, עליו להיות נתיב במערכת הקבצים של המארח שישמש כשורש של אובייקט ה-VfsPosix. אחרת נעשה שימוש בספרייה הנוכחית של מערכת הקבצים של המארח.

הערה

VfsPosix זמין רק בפורט Unix של MicroPython; הוא אינו קיים בקושחת OpenMV Cam.

התקני בלוקים

התקן בלוקים הוא אובייקט המממש את פרוטוקול הבלוקים. הדבר מאפשר להתקן לתמוך במערכות קבצים של MicroPython. החומרה הפיזית מיוצגת על ידי מחלקה מוגדרת-משתמש. המחלקה AbstractBlockDev היא תבנית לעיצוב מחלקה כזו: MicroPython אינה מספקת בפועל מחלקה זו, אך מחלקת התקן בלוקים ממשית חייבת לממש את המתודות המתוארות להלן.

מימוש קונקרטי של מחלקה זו יאפשר בדרך כלל גישה לפונקציונליות הדמוית-זיכרון של פיסת חומרה (כמו זיכרון פלאש (flash)). ניתן לפרמט התקן בלוקים לכל מערכת קבצים נתמכת ולעגן אותו באמצעות מתודות os.

ראו עבודה עם מערכות קבצים לדוגמאות מימוש של התקני בלוקים תוך שימוש בשני הווריאנטים של פרוטוקול הבלוקים המתוארים להלן.

ממשק פשוט ומורחב

קיימות שתי חתימות תואמות עבור המתודות readblocks ו-writeblocks (ראו להלן), כדי לתמוך במגוון מקרי שימוש. התקן בלוקים נתון עשוי לממש צורה זו או אחרת, או את שתיהן בו-זמנית. הצורה השנייה (עם פרמטר ה-offset) מכונה ”הממשק המורחב“.

חלק ממערכות הקבצים דורשות שליטה רבה יותר בפעולות הכתיבה – לדוגמה, כתיבה לאזורי תת-בלוק ללא מחיקה – וזקוקות לכך שהתקן הבלוקים יתמוך בממשק המורחב.

class vfs.AbstractBlockDev

תבנית תיעוד לפרוטוקול התקן הבלוקים. MicroPython אינה חושפת בפועל מחלקה זו — היא מוצגת כאן רק כדי לתעד את המתודות שמחלקת התקן בלוקים מוגדרת-משתמש חייבת לממש. ארגומנטי הבנאי תלויים לחלוטין במימוש (בדרך כלל דברים כמו אפיק ה-flash, פין ה-chip-select, גודל סקטור וכדומה).

readblocks(block_num: int, buf: bytearray) None
readblocks(block_num: int, buf: bytearray, offset: int) None

קריאת בתים מההתקן אל buf. שני העמסות חושפות את הממשקים הפשוט והמורחב.

צורה פשוטה (readblocks(block_num, buf)): קוראת בלוקים שלמים החל מאינדקס הבלוק block_num. len(buf) חייב להיות כפולה של גודל הבלוק, ומספר הבלוקים הנקראים הוא len(buf) // block_size.

צורה מורחבת (readblocks(block_num, buf, offset)): קוראת len(buf) בתים – לא בהכרח מספר שלם של בלוקים – החל מהבית offset בתוך בלוק block_num. השתמשו בצורה זו כאשר מערכת הקבצים זקוקה לגישת קריאה ברמת תת-בלוק.

writeblocks(block_num: int, buf: bytes) None
writeblocks(block_num: int, buf: bytes, offset: int) None

כתיבת בתים מ-buf אל ההתקן.

צורה פשוטה (writeblocks(block_num, buf)): כותבת בלוקים שלמים החל מאינדקס הבלוק block_num. len(buf) חייב להיות כפולה של גודל הבלוק, ומספר הבלוקים הנכתבים הוא len(buf) // block_size. המימוש אחראי למחוק תחילה כל בלוק יעד אם החומרה הבסיסית דורשת זאת.

צורה מורחבת (writeblocks(block_num, buf, offset)): כותבת len(buf) בתים – לא בהכרח מספר שלם של בלוקים – החל מהבית offset בתוך בלוק block_num. רק הבתים הנכתבים עשויים להשתנות; הקורא אחראי לוודא שהבלוקים המושפעים נמחקו באמצעות קריאת ioctl(6, block_num) קודמת. מימושים של צורה זו לעולם אינם רשאים למחוק בלוק במשתמע, גם כאשר offset הוא אפס.

ioctl(op: int, arg: int) int | None

בקרה על התקן הבלוקים ושאילתת הפרמטרים שלו. הפעולה לביצוע נתונה על ידי op שהוא אחד מהמספרים השלמים הבאים:

  • 1 – אתחול ההתקן (arg אינו בשימוש)

  • 2 – כיבוי ההתקן (arg אינו בשימוש)

  • 3 – סנכרון ההתקן (arg אינו בשימוש)

  • 4 – קבלת ספירה של מספר הבלוקים, צריך להחזיר מספר שלם (arg אינו בשימוש)

  • 5 – קבלת מספר הבתים בבלוק, צריך להחזיר מספר שלם, או None ובמקרה זה נעשה שימוש בערך ברירת המחדל 512 (arg אינו בשימוש)

  • 6 – מחיקת בלוק, arg הוא מספר הבלוק שיש למחוק

כמינימום יש ליירט את ioctl(4, ...); מערכות קבצים המשתמשות בממשק המורחב דורשות בנוסף את ioctl(6, ...). הצורך בפעולות האחרות תלוי בחומרה.

לפני כל קריאה ל-writeblocks(block, ...), מערכת קבצים המשתמשת בממשק המורחב מנפיקה ioctl(6, block) כך שהדרייבר יוכל למחוק תחילה את הבלוק אם החומרה דורשת זאת. דרייבר יכול במקום זאת ליירט את ioctl(6, block) ולהחזיר 0 (הצלחה), תוך נטילת האחריות לזיהוי מתי נדרשת מחיקה בעצמו.

אלא אם צוין אחרת, ioctl(op, arg) יכול להחזיר None. כתוצאה מכך מימוש יכול להתעלם מערכים בלתי מנוצלים של op. במקום שבו op מיורט, ערכי ההחזרה עבור פעולות 4 ו-5 הם כמפורט לעיל. פעולות אחרות צריכות להחזיר 0 בהצלחה וערך שונה מאפס בכישלון, כאשר הערך המוחזר הוא קוד errno של OSError.