vfs — contrôle du système de fichiers virtuel

Le module vfs contient des fonctions permettant de créer des objets système de fichiers et de les monter/démonter dans le système de fichiers virtuel.

Montage de systèmes de fichiers

Certains ports fournissent un système de fichiers virtuel (VFS) ainsi que la possibilité de monter plusieurs systèmes de fichiers « réels » au sein de ce VFS. Les objets système de fichiers peuvent être montés soit à la racine du VFS, soit dans un sous-répertoire situé à la racine. Cela permet une configuration dynamique et flexible du système de fichiers vu par les programmes Python. Les ports disposant de cette fonctionnalité fournissent les fonctions mount() et umount(), ainsi qu’éventuellement diverses implémentations de systèmes de fichiers représentées par des classes VFS.

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

Monte l’objet système de fichiers fsobj à l’emplacement du VFS indiqué par la chaîne mount_point. fsobj peut être un objet VFS doté d’une méthode mount(), ou un périphérique bloc. S’il s’agit d’un périphérique bloc, le type de système de fichiers est détecté automatiquement (une exception est levée si aucun système de fichiers n’est reconnu). mount_point peut valoir '/' pour monter fsobj à la racine, ou '/<name>' pour le monter dans un sous-répertoire sous la racine.

Si readonly vaut True, le système de fichiers est monté en lecture seule.

Pendant le processus de montage, la méthode mount() est appelée sur l’objet système de fichiers.

Lève OSError(EPERM) si mount_point est déjà monté.

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

Sans argument, mount() renvoie une liste de tuples représentant tous les points de montage actifs.

La liste renvoyée a la forme [(fsobj, mount_point), …].

vfs.umount(mount_point: str | Any) None

Démonte un système de fichiers. mount_point peut être une chaîne nommant l’emplacement de montage, ou un objet système de fichiers précédemment monté. Pendant le processus de démontage, la méthode umount() est appelée sur l’objet système de fichiers.

Lève OSError(EINVAL) si mount_point est introuvable.

class vfs.VfsFat(block_dev: AbstractBlockDev)

Crée un objet système de fichiers utilisant le format de système de fichiers FAT. Le stockage du système de fichiers FAT est assuré par block_dev. Les objets créés par ce constructeur peuvent être montés à l’aide de mount().

static mkfs(block_dev: AbstractBlockDev) None

Construit un système de fichiers FAT sur block_dev.

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

Crée un objet système de fichiers utilisant le format de système de fichiers en lecture seule ROMFS. buffer doit être un objet prenant en charge le protocole tampon (bytes, bytearray ou memoryview) qui contient une image ROMFS valide.

Les objets créés par ce constructeur peuvent être montés à l’aide de mount().

Voir Utilisation de ROMFS pour tous les détails, y compris comment construire et déployer des images ROMFS avec mpremote.

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

Interface de bas niveau pour accéder à la ou aux partitions de mémoire morte (ROM) du périphérique. Les opérations prises en charge sont les suivantes :

Appel

Comportement

rom_ioctl(1)

Renvoie le nombre de partitions ROM disponibles.

rom_ioctl(2, id)

Renvoie la partition id sous forme de memoryview.

rom_ioctl(3, id, length)

Efface les premiers length octets de la partition id en préparation d’une écriture. Renvoie l’alignement d’écriture minimal en octets.

rom_ioctl(4, id, offset, buf)

Écrit buf dans la partition id à l’octet offset.

rom_ioctl(5, id)

Finalise une séquence d’écriture dans la partition id (vide les caches, etc.).

Ces opérations sont normalement invoquées indirectement par mpremote lors du déploiement d’une image ROMFS ; la plupart des applications n’ont pas besoin de les appeler directement.

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

Crée un objet système de fichiers qui accède au système de fichiers POSIX hôte. Si root est spécifié, il doit s’agir d’un chemin du système de fichiers hôte à utiliser comme racine de l’objet VfsPosix. Sinon, le répertoire courant du système de fichiers hôte est utilisé.

Note

VfsPosix n’est disponible que sur le port Unix de MicroPython ; il est absent du micrologiciel de l’OpenMV Cam.

Périphériques bloc

Un périphérique bloc est un objet qui implémente le protocole bloc. Cela permet à un périphérique de prendre en charge les systèmes de fichiers MicroPython. Le matériel physique est représenté par une classe définie par l’utilisateur. La classe AbstractBlockDev sert de modèle pour la conception d’une telle classe : MicroPython ne fournit pas réellement cette classe, mais une véritable classe de périphérique bloc doit implémenter les méthodes décrites ci-dessous.

Une implémentation concrète de cette classe permet généralement d’accéder aux fonctionnalités de type mémoire d’un élément matériel (comme la mémoire flash). Un périphérique bloc peut être formaté dans n’importe quel système de fichiers pris en charge et monté à l’aide des méthodes de os.

Voir Utilisation des systèmes de fichiers pour des exemples d’implémentations de périphériques bloc utilisant les deux variantes du protocole bloc décrites ci-dessous.

Interface simple et étendue

Il existe deux signatures compatibles pour les méthodes readblocks et writeblocks (voir ci-dessous), afin de prendre en charge divers cas d’utilisation. Un périphérique bloc donné peut implémenter l’une ou l’autre forme, voire les deux à la fois. La seconde forme (avec le paramètre offset) est appelée « interface étendue ».

Certains systèmes de fichiers nécessitent un contrôle plus fin des opérations d’écriture – par exemple, l’écriture dans des régions sous-bloc sans effacement – et ont besoin que le périphérique bloc prenne en charge l’interface étendue.

class vfs.AbstractBlockDev

Modèle de documentation pour le protocole de périphérique bloc. MicroPython n’expose pas réellement cette classe — elle est présentée ici uniquement pour documenter les méthodes qu’une classe de périphérique bloc définie par l’utilisateur doit implémenter. Les arguments du constructeur dépendent entièrement de l’implémentation (typiquement des éléments comme le bus flash, la broche de sélection de puce, la taille de secteur, etc.).

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

Lit des octets depuis le périphérique dans buf. Deux surcharges exposent les interfaces simple et étendue.

Forme simple (readblocks(block_num, buf)) : lit des blocs entiers à partir de l’indice de bloc block_num. len(buf) doit être un multiple de la taille de bloc, et le nombre de blocs lus est len(buf) // block_size.

Forme étendue (readblocks(block_num, buf, offset)) : lit len(buf) octets – pas nécessairement un nombre entier de blocs – à partir de l’octet offset au sein du bloc block_num. Utilisez cette forme lorsque le système de fichiers a besoin d’un accès en lecture sous-bloc.

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

Écrit des octets de buf vers le périphérique.

Forme simple (writeblocks(block_num, buf)) : écrit des blocs entiers à partir de l’indice de bloc block_num. len(buf) doit être un multiple de la taille de bloc, et le nombre de blocs écrits est len(buf) // block_size. L’implémentation est chargée d’effacer au préalable chaque bloc de destination si le matériel sous-jacent l’exige.

Forme étendue (writeblocks(block_num, buf, offset)) : écrit len(buf) octets – pas nécessairement un nombre entier de blocs – à partir de l’octet offset au sein du bloc block_num. Seuls les octets en cours d’écriture peuvent changer ; l’appelant est chargé de s’assurer que les blocs concernés ont été effacés via un appel préalable à ioctl(6, block_num). Les implémentations de cette forme ne doivent jamais effacer implicitement un bloc, même lorsque offset vaut zéro.

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

Contrôle le périphérique bloc et interroge ses paramètres. L’opération à effectuer est donnée par op, qui est l’un des entiers suivants :

  • 1 – initialise le périphérique (arg est inutilisé)

  • 2 – arrête le périphérique (arg est inutilisé)

  • 3 – synchronise le périphérique (arg est inutilisé)

  • 4 – obtient le nombre de blocs, doit renvoyer un entier (arg est inutilisé)

  • 5 – obtient le nombre d’octets dans un bloc, doit renvoyer un entier, ou None auquel cas la valeur par défaut de 512 est utilisée (arg est inutilisé)

  • 6 – efface un bloc, arg est le numéro du bloc à effacer

Au minimum, ioctl(4, ...) doit être intercepté ; les systèmes de fichiers utilisant l’interface étendue nécessitent en outre ioctl(6, ...). La nécessité des autres opérations dépend du matériel.

Avant tout appel à writeblocks(block, ...), un système de fichiers utilisant l’interface étendue émet ioctl(6, block) afin que le pilote puisse effacer le bloc au préalable si le matériel l’exige. Un pilote peut au contraire intercepter ioctl(6, block) et renvoyer 0 (succès), prenant alors lui-même la responsabilité de détecter quand un effacement est nécessaire.

Sauf indication contraire, ioctl(op, arg) peut renvoyer None. Par conséquent, une implémentation peut ignorer les valeurs inutilisées de op. Lorsque op est intercepté, les valeurs de retour des opérations 4 et 5 sont telles que détaillées ci-dessus. Les autres opérations doivent renvoyer 0 en cas de succès et une valeur non nulle en cas d’échec, la valeur renvoyée étant un code errno OSError.