vfs --- การควบคุมระบบไฟล์เสมือน

โมดูล 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() โดยไม่มีอาร์กิวเมนต์ จะคืนค่ารายการของทูเพิลที่แสดงจุดเชื่อมต่อที่ใช้งานอยู่ทั้งหมด

รายการที่คืนค่ามีรูปแบบ [(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 ต้องเป็นออบเจ็กต์ที่รองรับโปรโตคอลบัฟเฟอร์ (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 มิฉะนั้นจะใช้ไดเรกทอรีปัจจุบันของระบบไฟล์โฮสต์

Note

VfsPosix ใช้ได้เฉพาะบนพอร์ต MicroPython Unix เท่านั้น และไม่มีในเฟิร์มแวร์ OpenMV Cam

อุปกรณ์บล็อก

อุปกรณ์บล็อกคือออบเจ็กต์ที่นำโปรโตคอลบล็อกไปใช้งาน ซึ่งช่วยให้อุปกรณ์รองรับระบบไฟล์ MicroPython ฮาร์ดแวร์จริงถูกแสดงโดยคลาสที่ผู้ใช้กำหนด คลาส AbstractBlockDev เป็นแม่แบบสำหรับการออกแบบคลาสดังกล่าว: MicroPython ไม่ได้ให้คลาสนั้นจริงๆ แต่คลาสอุปกรณ์บล็อกที่ใช้งานจริงต้องนำเมธอดที่อธิบายด้านล่างนี้ไปใช้

การนำคลาสนี้ไปใช้งานจริงโดยทั่วไปจะช่วยให้เข้าถึงฟังก์ชันที่คล้ายหน่วยความจำของฮาร์ดแวร์ชิ้นหนึ่ง (เช่น หน่วยความจำแฟลช) อุปกรณ์บล็อกสามารถฟอร์แมตเป็นระบบไฟล์ที่รองรับใดก็ได้และติดตั้งโดยใช้เมธอด os

ดู การทำงานกับระบบไฟล์ สำหรับตัวอย่างการนำอุปกรณ์บล็อกไปใช้งานโดยใช้สองรูปแบบของโปรโตคอลบล็อกที่อธิบายด้านล่าง

อินเทอร์เฟซอย่างง่ายและแบบขยาย

มีลายเซ็นที่เข้ากันได้สองแบบสำหรับเมธอด readblocks และ writeblocks (ดูด้านล่าง) เพื่อรองรับกรณีการใช้งานที่หลากหลาย อุปกรณ์บล็อกที่กำหนดอาจนำรูปแบบใดรูปแบบหนึ่งหรือทั้งสองรูปแบบไปใช้พร้อมกัน รูปแบบที่สอง (ที่มีพารามิเตอร์ offset) เรียกว่า "อินเทอร์เฟซแบบขยาย"

ระบบไฟล์บางระบบต้องการการควบคุมการดำเนินการเขียนมากขึ้น เช่น การเขียนในบริเวณย่อยของบล็อกโดยไม่ต้องลบ และต้องการให้อุปกรณ์บล็อกรองรับอินเทอร์เฟซแบบขยาย

class vfs.AbstractBlockDev

แม่แบบเอกสารสำหรับโปรโตคอลอุปกรณ์บล็อก MicroPython ไม่ได้เปิดเผยคลาสนี้จริงๆ --- แสดงไว้ที่นี่เพื่อจัดทำเอกสารเมธอดที่คลาสอุปกรณ์บล็อกที่ผู้ใช้กำหนดต้องนำไปใช้ อาร์กิวเมนต์ตัวสร้างขึ้นอยู่กับการนำไปใช้งานทั้งหมด (โดยทั่วไปเป็นสิ่งต่างๆ เช่น บัสแฟลช พินเลือกชิป ขนาดเซกเตอร์ เป็นต้น)

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