vfs — controllo del filesystem virtuale¶
Il modulo vfs contiene funzioni per creare oggetti filesystem e montarli/smontarli nel Filesystem Virtuale.
Montaggio del filesystem¶
Alcune porte forniscono un Filesystem Virtuale (VFS) e la possibilità di montare più filesystem «reali» all’interno di questo VFS. Gli oggetti filesystem possono essere montati sia alla radice del VFS, sia in una sottodirectory che risiede nella radice. Questo consente una configurazione dinamica e flessibile del filesystem visto dai programmi Python. Le porte che dispongono di questa funzionalità forniscono le funzioni mount() e umount(), ed eventualmente varie implementazioni di filesystem rappresentate dalle classi VFS.
- vfs.mount(fsobj: Any, mount_point: str, *, readonly: bool = False) None¶
Monta l’oggetto filesystem fsobj nella posizione del VFS indicata dalla stringa mount_point. fsobj può essere un oggetto VFS dotato di un metodo
mount(), oppure un block device. Se si tratta di un block device, il tipo di filesystem viene rilevato automaticamente (viene sollevata un’eccezione se non viene riconosciuto alcun filesystem). mount_point può essere'/'per montare fsobj alla radice, oppure'/<name>'per montarlo in una sottodirectory sotto la radice.Se readonly è
True, il filesystem viene montato in sola lettura.Durante il processo di montaggio viene chiamato il metodo
mount()sull’oggetto filesystem.Solleva
OSError(EPERM)se mount_point è già montato.
- vfs.mount() List[Tuple[Any, str]]
Senza argomenti,
mount()restituisce una lista di tuple che rappresentano tutti i punti di montaggio attivi.La lista restituita ha la forma [(fsobj, mount_point), …].
- vfs.umount(mount_point: str | Any) None¶
Smonta un filesystem. mount_point può essere una stringa che indica la posizione di montaggio, oppure un oggetto filesystem precedentemente montato. Durante il processo di smontaggio viene chiamato il metodo
umount()sull’oggetto filesystem.Solleva
OSError(EINVAL)se mount_point non viene trovato.
- class vfs.VfsFat(block_dev: AbstractBlockDev)¶
Crea un oggetto filesystem che utilizza il formato di filesystem FAT. L’archiviazione del filesystem FAT è fornita da block_dev. Gli oggetti creati da questo costruttore possono essere montati usando
mount().- static mkfs(block_dev: AbstractBlockDev) None¶
Costruisce un filesystem FAT su block_dev.
- class vfs.VfsRom(buffer: bytes | bytearray | memoryview)¶
Crea un oggetto filesystem che utilizza il formato di filesystem in sola lettura ROMFS.
bufferdeve essere un oggetto che supporta il protocollo buffer (bytes,bytearrayomemoryview) e che contiene un’immagine ROMFS valida.Gli oggetti creati da questo costruttore possono essere montati usando
mount().Vedi Lavorare con ROMFS per i dettagli completi, incluso come costruire e distribuire immagini ROMFS con mpremote.
- vfs.rom_ioctl(op: int, *args: Any) Any¶
Interfaccia di basso livello per accedere alle partizioni di memoria in sola lettura (ROM) del dispositivo. Le operazioni supportate sono:
Chiamata
Comportamento
rom_ioctl(1)Restituisce il numero di partizioni ROM disponibili.
rom_ioctl(2, id)Restituisce la partizione
idcomememoryview.rom_ioctl(3, id, length)Cancella i primi
lengthbyte della partizioneidin preparazione alla scrittura. Restituisce l’allineamento minimo di scrittura in byte.rom_ioctl(4, id, offset, buf)Scrive
bufnella partizioneidal byteoffset.rom_ioctl(5, id)Finalizza una sequenza di scrittura sulla partizione
id(svuota le cache, ecc.).Queste operazioni vengono normalmente invocate indirettamente da mpremote durante la distribuzione di un’immagine ROMFS; la maggior parte delle applicazioni non ha bisogno di chiamarle direttamente.
- class vfs.VfsPosix(root: str | None = None)¶
Crea un oggetto filesystem che accede al filesystem POSIX dell’host. Se root è specificato, deve essere un percorso nel filesystem dell’host da utilizzare come radice dell’oggetto
VfsPosix. In caso contrario viene usata la directory corrente del filesystem dell’host.Nota
VfsPosixè disponibile solo sulla porta Unix di MicroPython; non è presente nel firmware delle OpenMV Cam.
Block device¶
Un block device è un oggetto che implementa il protocollo a blocchi. Questo consente a un dispositivo di supportare i filesystem MicroPython. L’hardware fisico è rappresentato da una classe definita dall’utente. La classe AbstractBlockDev è un modello per la progettazione di una tale classe: MicroPython non fornisce effettivamente quella classe, ma una vera classe di block device deve implementare i metodi descritti di seguito.
Un’implementazione concreta di questa classe consente solitamente di accedere alle funzionalità di tipo memoria di un componente hardware (come la memoria flash). Un block device può essere formattato con qualsiasi filesystem supportato e montato usando i metodi di os.
Vedi Lavorare con i filesystem per esempi di implementazioni di block device che usano le due varianti del protocollo a blocchi descritte di seguito.
Interfaccia semplice ed estesa¶
Esistono due firme compatibili per i metodi readblocks e writeblocks (vedi sotto), al fine di supportare una varietà di casi d’uso. Un dato block device può implementare una forma o l’altra, oppure entrambe contemporaneamente. La seconda forma (con il parametro offset) è denominata «interfaccia estesa».
Alcuni filesystem richiedono un maggiore controllo sulle operazioni di scrittura – ad esempio, la scrittura su regioni di sotto-blocco senza cancellazione – e necessitano che il block device supporti l’interfaccia estesa.
- class vfs.AbstractBlockDev¶
Modello di documentazione per il protocollo dei block device. MicroPython non espone effettivamente questa classe — è mostrata qui solo per documentare i metodi che una classe di block device definita dall’utente deve implementare. Gli argomenti del costruttore sono interamente a discrezione dell’implementazione (tipicamente cose come il bus della flash, il pin di chip-select, la dimensione del settore, ecc.).
- readblocks(block_num: int, buf: bytearray) None¶
- readblocks(block_num: int, buf: bytearray, offset: int) None
Legge byte dal dispositivo in buf. Due overload espongono le interfacce semplice ed estesa.
Forma semplice (
readblocks(block_num, buf)): legge interi blocchi a partire dall’indice di blocco block_num.len(buf)deve essere un multiplo della dimensione del blocco, e il numero di blocchi letti èlen(buf) // block_size.Forma estesa (
readblocks(block_num, buf, offset)): leggelen(buf)byte – non necessariamente un numero intero di blocchi – a partire dal byteoffsetall’interno del blocco block_num. Usa questa forma quando il filesystem necessita di accesso in lettura a livello di sotto-blocco.
- writeblocks(block_num: int, buf: bytes) None¶
- writeblocks(block_num: int, buf: bytes, offset: int) None
Scrive byte da buf sul dispositivo.
Forma semplice (
writeblocks(block_num, buf)): scrive interi blocchi a partire dall’indice di blocco block_num.len(buf)deve essere un multiplo della dimensione del blocco, e il numero di blocchi scritti èlen(buf) // block_size. L’implementazione è responsabile di cancellare prima ciascun blocco di destinazione se l’hardware sottostante lo richiede.Forma estesa (
writeblocks(block_num, buf, offset)): scrivelen(buf)byte – non necessariamente un numero intero di blocchi – a partire dal byteoffsetall’interno del blocco block_num. Possono cambiare solo i byte effettivamente scritti; il chiamante è responsabile di assicurarsi che i blocchi interessati siano stati cancellati tramite una precedente chiamataioctl(6, block_num). Le implementazioni di questa forma non devono mai cancellare implicitamente un blocco, neppure quandooffsetè zero.
- ioctl(op: int, arg: int) int | None¶
Controlla il block device e interroga i suoi parametri. L’operazione da eseguire è indicata da op, che è uno dei seguenti interi:
1 – inizializza il dispositivo (arg non è usato)
2 – arresta il dispositivo (arg non è usato)
3 – sincronizza il dispositivo (arg non è usato)
4 – ottiene il conteggio del numero di blocchi, deve restituire un intero (arg non è usato)
5 – ottiene il numero di byte in un blocco, deve restituire un intero, oppure
Nonenel qual caso viene usato il valore predefinito di 512 (arg non è usato)6 – cancella un blocco, arg è il numero del blocco da cancellare
Come minimo deve essere intercettato
ioctl(4, ...); i filesystem che usano l’interfaccia estesa richiedono inoltreioctl(6, ...). La necessità delle altre operazioni dipende dall’hardware.Prima di qualsiasi chiamata a
writeblocks(block, ...), un filesystem che usa l’interfaccia estesa emetteioctl(6, block)in modo che il driver possa cancellare prima il blocco se l’hardware lo richiede. Un driver può invece intercettareioctl(6, block)e restituire 0 (successo), assumendosi la responsabilità di rilevare autonomamente quando è necessaria la cancellazione.Salvo indicazione contraria,
ioctl(op, arg)può restituireNone. Di conseguenza un’implementazione può ignorare i valori diopnon utilizzati. Quandoopviene intercettato, i valori restituiti per le operazioni 4 e 5 sono quelli dettagliati sopra. Le altre operazioni dovrebbero restituire 0 in caso di successo e un valore diverso da zero in caso di fallimento, con il valore restituito che è un codice errno diOSError.