vfs — upravljanje virtualnim datotečnim sustavom

Modul vfs sadrži funkcije za stvaranje objekata datotečnog sustava te njihovo montiranje i odmontiranje u virtualnom datotečnom sustavu (Virtual Filesystem).

Montiranje datotečnog sustava

Neki portovi pružaju virtualni datotečni sustav (VFS) i mogućnost montiranja više „stvarnih” datotečnih sustava unutar tog VFS-a. Objekti datotečnog sustava mogu se montirati ili u korijenu VFS-a ili u poddirektoriju koji se nalazi u korijenu. To omogućuje dinamičku i fleksibilnu konfiguraciju datotečnog sustava koji vide Python programi. Portovi koji imaju ovu funkcionalnost pružaju funkcije mount() i umount(), a moguće i razne implementacije datotečnih sustava predstavljene VFS klasama.

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

Montira objekt datotečnog sustava fsobj na lokaciju u VFS-u zadanu nizom mount_point. fsobj može biti VFS objekt koji ima metodu mount() ili blok uređaj. Ako je riječ o blok uređaju, tip datotečnog sustava se automatski prepoznaje (podiže se iznimka ako nijedan datotečni sustav nije prepoznat). mount_point može biti '/' za montiranje fsobj u korijenu ili '/<name>' za montiranje u poddirektoriju ispod korijena.

Ako je readonly postavljen na True, datotečni sustav se montira samo za čitanje.

Tijekom postupka montiranja na objektu datotečnog sustava poziva se metoda mount().

Podiže OSError(EPERM) ako je mount_point već montiran.

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

Bez argumenata, mount() vraća popis n-torki koje predstavljaju sve aktivne točke montiranja.

Vraćeni popis ima oblik [(fsobj, mount_point), …].

vfs.umount(mount_point: str | Any) None

Odmontira datotečni sustav. mount_point može biti niz koji imenuje lokaciju montiranja ili prethodno montirani objekt datotečnog sustava. Tijekom postupka odmontiranja na objektu datotečnog sustava poziva se metoda umount().

Podiže OSError(EINVAL) ako mount_point nije pronađen.

class vfs.VfsFat(block_dev: AbstractBlockDev)

Stvara objekt datotečnog sustava koji koristi format datotečnog sustava FAT. Pohranu FAT datotečnog sustava pruža block_dev. Objekti stvoreni ovim konstruktorom mogu se montirati pomoću mount().

static mkfs(block_dev: AbstractBlockDev) None

Izgrađuje FAT datotečni sustav na block_dev.

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

Stvara objekt datotečnog sustava koji koristi ROMFS format datotečnog sustava samo za čitanje. buffer mora biti objekt koji podržava protokol međuspremnika (bytes, bytearray ili memoryview) i koji sadrži valjanu ROMFS sliku.

Objekti stvoreni ovim konstruktorom mogu se montirati pomoću mount().

Za sve pojedinosti, uključujući kako izgraditi i postaviti ROMFS slike pomoću mpremote, pogledajte Rad s ROMFS.

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

Niskorazinsko sučelje za pristup particijama memorije samo za čitanje (ROM) uređaja. Podržane operacije su:

Poziv

Ponašanje

rom_ioctl(1)

Vraća broj dostupnih ROM particija.

rom_ioctl(2, id)

Vraća particiju id kao memoryview.

rom_ioctl(3, id, length)

Briše prvih length bajtova particije id u pripremi za pisanje. Vraća minimalno poravnanje za pisanje u bajtovima.

rom_ioctl(4, id, offset, buf)

Zapisuje buf u particiju id na bajt offset.

rom_ioctl(5, id)

Finalizira slijed pisanja u particiju id (prazni predmemorije itd.).

Te operacije obično neizravno poziva mpremote prilikom postavljanja ROMFS slike; većina aplikacija ih ne treba pozivati izravno.

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

Stvara objekt datotečnog sustava koji pristupa POSIX datotečnom sustavu domaćina. Ako je root naveden, treba biti putanja u datotečnom sustavu domaćina koja se koristi kao korijen VfsPosix objekta. Inače se koristi trenutni direktorij datotečnog sustava domaćina.

Napomena

VfsPosix je dostupan samo na MicroPython Unix portu; nije prisutan u ugrađenom programu (firmware) OpenMV Cam-a.

Blok uređaji

Blok uređaj je objekt koji implementira protokol blokova. To omogućuje uređaju da podržava MicroPython datotečne sustave. Fizički hardver predstavlja korisnički definirana klasa. Klasa AbstractBlockDev je predložak za dizajn takve klase: MicroPython tu klasu zapravo ne pruža, ali stvarna klasa blok uređaja mora implementirati metode opisane u nastavku.

Konkretna implementacija ove klase obično omogućuje pristup funkcionalnosti sličnoj memoriji nekog dijela hardvera (poput flash memorije). Blok uređaj može se formatirati u bilo koji podržani datotečni sustav i montirati pomoću metoda os.

Pogledajte Rad s datotečnim sustavima za primjere implementacija blok uređaja pomoću dvije varijante protokola blokova opisane u nastavku.

Jednostavno i prošireno sučelje

Postoje dva kompatibilna potpisa za metode readblocks i writeblocks (vidi dolje), kako bi se podržali razni slučajevi upotrebe. Određeni blok uređaj može implementirati jedan ili drugi oblik, ili oba istovremeno. Drugi oblik (s parametrom offset) naziva se „prošireno sučelje”.

Neki datotečni sustavi zahtijevaju veću kontrolu nad operacijama pisanja – na primjer, pisanje u podregije bloka bez brisanja – te zahtijevaju da blok uređaj podržava prošireno sučelje.

class vfs.AbstractBlockDev

Predložak dokumentacije za protokol blok uređaja. MicroPython zapravo ne izlaže ovu klasu — ovdje je prikazana samo radi dokumentiranja metoda koje korisnički definirana klasa blok uređaja mora implementirati. Argumenti konstruktora u potpunosti ovise o implementaciji (obično stvari poput flash sabirnice, pina za odabir čipa, veličine sektora itd.).

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

Čita bajtove s uređaja u buf. Dvije preopterećene varijante izlažu jednostavno i prošireno sučelje.

Jednostavni oblik (readblocks(block_num, buf)): čita cijele blokove počevši od indeksa bloka block_num. len(buf) mora biti višekratnik veličine bloka, a broj pročitanih blokova je len(buf) // block_size.

Prošireni oblik (readblocks(block_num, buf, offset)): čita len(buf) bajtova – ne nužno cijeli broj blokova – počevši od bajta offset unutar bloka block_num. Koristite ovaj oblik kada datotečni sustav treba pristup čitanju unutar bloka.

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

Zapisuje bajtove iz buf na uređaj.

Jednostavni oblik (writeblocks(block_num, buf)): zapisuje cijele blokove počevši od indeksa bloka block_num. len(buf) mora biti višekratnik veličine bloka, a broj zapisanih blokova je len(buf) // block_size. Implementacija je odgovorna za prethodno brisanje svakog odredišnog bloka ako to zahtijeva osnovni hardver.

Prošireni oblik (writeblocks(block_num, buf, offset)): zapisuje len(buf) bajtova – ne nužno cijeli broj blokova – počevši od bajta offset unutar bloka block_num. Mijenjaju se samo bajtovi koji se zapisuju; pozivatelj je odgovoran za osiguravanje da su zahvaćeni blokovi obrisani prethodnim pozivom ioctl(6, block_num). Implementacije ovog oblika nikada ne smiju implicitno obrisati blok, čak ni kada je offset jednak nuli.

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

Upravlja blok uređajem i ispituje njegove parametre. Operacija koja se izvodi zadana je s op, što je jedan od sljedećih cijelih brojeva:

  • 1 – inicijalizacija uređaja (arg se ne koristi)

  • 2 – gašenje uređaja (arg se ne koristi)

  • 3 – sinkronizacija uređaja (arg se ne koristi)

  • 4 – dohvat broja blokova, treba vratiti cijeli broj (arg se ne koristi)

  • 5 – dohvat broja bajtova u bloku, treba vratiti cijeli broj ili None u kojem se slučaju koristi zadana vrijednost 512 (arg se ne koristi)

  • 6 – brisanje bloka, arg je broj bloka koji se briše

Kao minimum mora se presresti ioctl(4, ...); datotečni sustavi koji koriste prošireno sučelje dodatno zahtijevaju ioctl(6, ...). Potreba za ostalim operacijama ovisi o hardveru.

Prije svakog poziva writeblocks(block, ...) datotečni sustav koji koristi prošireno sučelje izdaje ioctl(6, block) kako bi upravljački program prvo obrisao blok ako to hardver zahtijeva. Upravljački program može umjesto toga presresti ioctl(6, block) i vratiti 0 (uspjeh), preuzimajući na sebe odgovornost za samostalno otkrivanje kada je brisanje potrebno.

Osim ako nije drugačije navedeno, ioctl(op, arg) može vratiti None. Slijedom toga, implementacija može zanemariti nekorištene vrijednosti za op. Tamo gdje se op presreće, povratna vrijednost za operacije 4 i 5 je kako je gore detaljno opisano. Ostale operacije trebaju vratiti 0 u slučaju uspjeha i različito od nule u slučaju neuspjeha, pri čemu je vraćena vrijednost OSError errno kod.