vfs — styrning av virtuellt filsystem

Modulen vfs innehåller funktioner för att skapa filsystemsobjekt och montera/avmontera dem i det virtuella filsystemet.

Montering av filsystem

Vissa portar tillhandahåller ett virtuellt filsystem (VFS) och möjligheten att montera flera ”riktiga” filsystem inom detta VFS. Filsystemsobjekt kan monteras antingen i roten av VFS eller i en underkatalog som finns i roten. Detta möjliggör en dynamisk och flexibel konfiguration av det filsystem som Python-program ser. Portar med denna funktionalitet tillhandahåller funktionerna mount() och umount(), och möjligen olika filsystemsimplementationer representerade av VFS-klasser.

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

Montera filsystemsobjektet fsobj på platsen i VFS som anges av strängen mount_point. fsobj kan vara ett VFS-objekt som har en mount()-metod, eller en blockenhet. Om det är en blockenhet detekteras filsystemstypen automatiskt (ett undantag uppstår om inget filsystem kändes igen). mount_point kan vara '/' för att montera fsobj i roten, eller '/<name>' för att montera det i en underkatalog under roten.

Om readonly är True monteras filsystemet skrivskyddat.

Under monteringsprocessen anropas metoden mount() på filsystemsobjektet.

Genererar OSError(EPERM) om mount_point redan är monterat.

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

Utan argument till mount() returneras en lista med tupler som representerar alla aktiva monteringspunkter.

Den returnerade listan har formen [(fsobj, mount_point), …].

vfs.umount(mount_point: str | Any) None

Avmontera ett filsystem. mount_point kan vara en sträng som namnger monteringsplatsen, eller ett tidigare monterat filsystemsobjekt. Under avmonteringsprocessen anropas metoden umount() på filsystemsobjektet.

Genererar OSError(EINVAL) om mount_point inte hittas.

class vfs.VfsFat(block_dev: AbstractBlockDev)

Skapa ett filsystemsobjekt som använder FAT-filsystemsformatet. Lagringen av FAT-filsystemet tillhandahålls av block_dev. Objekt som skapas av denna konstruktor kan monteras med mount().

static mkfs(block_dev: AbstractBlockDev) None

Bygg ett FAT-filsystem på block_dev.

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

Skapa ett filsystemsobjekt som använder det skrivskyddade ROMFS-filsystemsformatet. buffer måste vara ett objekt som stöder buffertprotokollet (bytes, bytearray eller memoryview) och som innehåller en giltig ROMFS-avbildning.

Objekt som skapas av denna konstruktor kan monteras med mount().

Se Arbeta med ROMFS för fullständiga detaljer, inklusive hur man bygger och distribuerar ROMFS-avbildningar med mpremote.

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

Lågnivågränssnitt för åtkomst till enhetens skrivskyddade minnespartition(er) (ROM). De operationer som stöds är:

Anrop

Beteende

rom_ioctl(1)

Returnera antalet tillgängliga ROM-partitioner.

rom_ioctl(2, id)

Returnera partition id som en memoryview.

rom_ioctl(3, id, length)

Radera de första length byten i partition id som förberedelse inför skrivning. Returnerar minsta skrivjustering i byte.

rom_ioctl(4, id, offset, buf)

Skriv buf till partition id vid byte offset.

rom_ioctl(5, id)

Slutför en skrivsekvens till partition id (tömmer cacheminnen osv.).

Dessa operationer anropas normalt indirekt av mpremote vid distribution av en ROMFS-avbildning; de flesta applikationer behöver inte anropa dem direkt.

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

Skapa ett filsystemsobjekt som kommer åt värdens POSIX-filsystem. Om root anges ska det vara en sökväg i värdfilsystemet att använda som rot för VfsPosix-objektet. Annars används värdfilsystemets aktuella katalog.

Anteckning

VfsPosix är endast tillgänglig på MicroPythons Unix-port; den finns inte i den fasta programvaran för OpenMV Cam.

Blockenheter

En blockenhet är ett objekt som implementerar blockprotokollet. Detta gör att en enhet kan stödja MicroPython-filsystem. Den fysiska hårdvaran representeras av en användardefinierad klass. Klassen AbstractBlockDev är en mall för utformningen av en sådan klass: MicroPython tillhandahåller inte denna klass i verkligheten, men en faktisk blockenhetsklass måste implementera de metoder som beskrivs nedan.

En konkret implementation av denna klass möjliggör vanligtvis åtkomst till den minnesliknande funktionaliteten hos en hårdvarukomponent (som flashminne). En blockenhet kan formateras till valfritt filsystem som stöds och monteras med os-metoder.

Se Arbeta med filsystem för exempel på implementationer av blockenheter som använder de två varianterna av blockprotokollet som beskrivs nedan.

Enkelt och utökat gränssnitt

Det finns två kompatibla signaturer för metoderna readblocks och writeblocks (se nedan), för att stödja en mängd olika användningsfall. En given blockenhet kan implementera den ena eller den andra formen, eller båda samtidigt. Den andra formen (med offset-parametern) kallas det ”utökade gränssnittet”.

Vissa filsystem kräver mer kontroll över skrivoperationer – till exempel skrivning till delblocksregioner utan radering – och behöver att blockenheten stöder det utökade gränssnittet.

class vfs.AbstractBlockDev

Dokumentationsmall för blockenhetsprotokollet. MicroPython exponerar inte denna klass i verkligheten — den visas här endast för att dokumentera de metoder som en användardefinierad blockenhetsklass måste implementera. Konstruktorargumenten är helt upp till implementationen (vanligtvis saker som flashbuss, chip-select-stift, sektorstorlek osv.).

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

Läs byte från enheten till buf. Två överlagringar exponerar de enkla och utökade gränssnitten.

Enkel form (readblocks(block_num, buf)): läser hela block med start vid blockindex block_num. len(buf) måste vara en multipel av blockstorleken, och antalet block som läses är len(buf) // block_size.

Utökad form (readblocks(block_num, buf, offset)): läser len(buf) byte – inte nödvändigtvis ett helt antal block – med start vid byte offset inom block block_num. Använd denna form när filsystemet behöver läsåtkomst på delblocksnivå.

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

Skriv byte från buf till enheten.

Enkel form (writeblocks(block_num, buf)): skriver hela block med start vid blockindex block_num. len(buf) måste vara en multipel av blockstorleken, och antalet block som skrivs är len(buf) // block_size. Implementationen ansvarar för att först radera varje destinationsblock om den underliggande hårdvaran kräver det.

Utökad form (writeblocks(block_num, buf, offset)): skriver len(buf) byte – inte nödvändigtvis ett helt antal block – med start vid byte offset inom block block_num. Endast de byte som skrivs får ändras; anroparen ansvarar för att säkerställa att berörda block har raderats via ett föregående anrop till ioctl(6, block_num). Implementationer av denna form får aldrig implicit radera ett block, inte ens när offset är noll.

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

Styr blockenheten och fråga efter dess parametrar. Vilken operation som ska utföras anges av op som är ett av följande heltal:

  • 1 – initiera enheten (arg används inte)

  • 2 – stäng av enheten (arg används inte)

  • 3 – synkronisera enheten (arg används inte)

  • 4 – hämta ett antal av antalet block, ska returnera ett heltal (arg används inte)

  • 5 – hämta antalet byte i ett block, ska returnera ett heltal, eller None varvid standardvärdet 512 används (arg används inte)

  • 6 – radera ett block, arg är blocknumret som ska raderas

Som ett minimum måste ioctl(4, ...) fångas upp; filsystem som använder det utökade gränssnittet kräver dessutom ioctl(6, ...). Behovet av övriga operationer är hårdvaruberoende.

Före varje anrop till writeblocks(block, ...) utfärdar ett filsystem som använder det utökade gränssnittet ioctl(6, block) så att drivrutinen kan radera blocket först om hårdvaran kräver det. En drivrutin kan istället fånga upp ioctl(6, block) och returnera 0 (lyckat), och själv ta på sig ansvaret för att upptäcka när radering behövs.

Om inget annat anges kan ioctl(op, arg) returnera None. Följaktligen kan en implementation ignorera värden på op som inte används. Där op fångas upp är returvärdet för operation 4 och 5 enligt vad som beskrivs ovan. Andra operationer ska returnera 0 vid lyckat resultat och ett värde skilt från noll vid misslyckande, där det returnerade värdet är en OSError-errnokod.