vfs — ovládání virtuálního souborového systému

Modul vfs obsahuje funkce pro vytváření objektů souborového systému a jejich připojování/odpojování ve virtuálním souborovém systému.

Připojování souborových systémů

Některé porty poskytují virtuální souborový systém (VFS) a možnost připojit v rámci tohoto VFS více „reálných“ souborových systémů. Objekty souborového systému lze připojit buď do kořene VFS, nebo do podadresáře umístěného v kořeni. To umožňuje dynamickou a flexibilní konfiguraci souborového systému, který vidí programy v Pythonu. Porty, které tuto funkcionalitu mají, poskytují funkce mount() a umount() a případně různé implementace souborových systémů reprezentované třídami VFS.

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

Připojí objekt souborového systému fsobj na místo ve VFS určené řetězcem mount_point. fsobj může být objekt VFS, který má metodu mount(), nebo blokové zařízení. Pokud jde o blokové zařízení, typ souborového systému se detekuje automaticky (pokud žádný souborový systém není rozpoznán, vyvolá se výjimka). mount_point může být '/' pro připojení fsobj do kořene, nebo '/<name>' pro připojení do podadresáře pod kořenem.

Pokud je readonly True, souborový systém je připojen pouze pro čtení.

Během procesu připojování se na objektu souborového systému zavolá metoda mount().

Vyvolá OSError(EPERM), pokud je mount_point již připojen.

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

Bez argumentů mount() vrátí seznam n-tic reprezentujících všechny aktivní body připojení.

Vrácený seznam má tvar [(fsobj, mount_point), …].

vfs.umount(mount_point: str | Any) None

Odpojí souborový systém. mount_point může být řetězec pojmenovávající místo připojení, nebo dříve připojený objekt souborového systému. Během procesu odpojování se na objektu souborového systému zavolá metoda umount().

Vyvolá OSError(EINVAL), pokud mount_point není nalezen.

class vfs.VfsFat(block_dev: AbstractBlockDev)

Vytvoří objekt souborového systému, který používá formát souborového systému FAT. Úložiště souborového systému FAT poskytuje block_dev. Objekty vytvořené tímto konstruktorem lze připojit pomocí mount().

static mkfs(block_dev: AbstractBlockDev) None

Vytvoří souborový systém FAT na block_dev.

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

Vytvoří objekt souborového systému, který používá formát souborového systému ROMFS určeného pouze pro čtení. buffer musí být objekt podporující buffer protokol (bytes, bytearray nebo memoryview), který obsahuje platný obraz ROMFS.

Objekty vytvořené tímto konstruktorem lze připojit pomocí mount().

Úplné podrobnosti, včetně toho, jak sestavit a nasadit obrazy ROMFS pomocí mpremote, najdete v Práce s ROMFS.

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

Nízkoúrovňové rozhraní pro přístup k oddílu (oddílům) paměti určené pouze pro čtení (ROM) zařízení. Podporované operace jsou:

Volání

Chování

rom_ioctl(1)

Vrátí počet dostupných ROM oddílů.

rom_ioctl(2, id)

Vrátí oddíl id jako memoryview.

rom_ioctl(3, id, length)

Vymaže prvních length bajtů oddílu id jako přípravu na zápis. Vrátí minimální zarovnání zápisu v bajtech.

rom_ioctl(4, id, offset, buf)

Zapíše buf do oddílu id na bajtovém offsetu offset.

rom_ioctl(5, id)

Dokončí sekvenci zápisu do oddílu id (vyprázdní cache atd.).

Tyto operace obvykle vyvolává nepřímo mpremote při nasazování obrazu ROMFS; většina aplikací je nemusí volat přímo.

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

Vytvoří objekt souborového systému, který přistupuje k hostitelskému POSIX souborovému systému. Pokud je zadán root, mělo by jít o cestu v hostitelském souborovém systému, která se použije jako kořen objektu VfsPosix. Jinak se použije aktuální adresář hostitelského souborového systému.

Poznámka

VfsPosix je k dispozici pouze na Unix portu MicroPythonu; ve firmwaru OpenMV Cam není přítomna.

Bloková zařízení

Blokové zařízení je objekt, který implementuje blokový protokol. To umožňuje zařízení podporovat souborové systémy MicroPythonu. Fyzický hardware je reprezentován uživatelsky definovanou třídou. Třída AbstractBlockDev je šablonou pro návrh takové třídy: MicroPython tuto třídu ve skutečnosti neposkytuje, ale skutečná třída blokového zařízení musí implementovat níže popsané metody.

Konkrétní implementace této třídy obvykle umožňuje přístup k paměti podobné funkcionalitě určitého hardwaru (jako je flash paměť). Blokové zařízení lze naformátovat na libovolný podporovaný souborový systém a připojit pomocí metod os.

Příklady implementací blokových zařízení používajících obě varianty níže popsaného blokového protokolu najdete v Práce se souborovými systémy.

Jednoduché a rozšířené rozhraní

Pro metody readblocks a writeblocks existují dvě kompatibilní signatury (viz níže), aby bylo možné podporovat různé scénáře použití. Dané blokové zařízení může implementovat jednu nebo druhou formu, případně obě současně. Druhá forma (s parametrem offset) se označuje jako „rozšířené rozhraní“.

Některé souborové systémy vyžadují větší kontrolu nad operacemi zápisu – například zápis do oblastí menších než blok bez mazání – a potřebují, aby blokové zařízení podporovalo rozšířené rozhraní.

class vfs.AbstractBlockDev

Dokumentační šablona pro protokol blokového zařízení. MicroPython tuto třídu ve skutečnosti neposkytuje — je zde uvedena pouze k zdokumentování metod, které musí uživatelsky definovaná třída blokového zařízení implementovat. Argumenty konstruktoru jsou zcela na implementaci (obvykle věci jako flash sběrnice, pin chip-select, velikost sektoru atd.).

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

Načte bajty ze zařízení do buf. Dvě varianty zpřístupňují jednoduché a rozšířené rozhraní.

Jednoduchá forma (readblocks(block_num, buf)): čte celé bloky počínaje indexem bloku block_num. len(buf) musí být násobkem velikosti bloku a počet přečtených bloků je len(buf) // block_size.

Rozšířená forma (readblocks(block_num, buf, offset)): čte len(buf) bajtů – ne nutně celý počet bloků – počínaje bajtovým offsetem offset v bloku block_num. Tuto formu použijte, když souborový systém potřebuje přístup ke čtení menšímu než blok.

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

Zapíše bajty z buf do zařízení.

Jednoduchá forma (writeblocks(block_num, buf)): zapisuje celé bloky počínaje indexem bloku block_num. len(buf) musí být násobkem velikosti bloku a počet zapsaných bloků je len(buf) // block_size. Pokud to podkladový hardware vyžaduje, je implementace zodpovědná za to, aby každý cílový blok nejprve vymazala.

Rozšířená forma (writeblocks(block_num, buf, offset)): zapisuje len(buf) bajtů – ne nutně celý počet bloků – počínaje bajtovým offsetem offset v bloku block_num. Změnit se smí pouze zapisované bajty; volající je zodpovědný za to, že dotčené bloky byly vymazány předchozím voláním ioctl(6, block_num). Implementace této formy nikdy nesmějí implicitně vymazat blok, a to ani když je offset nulový.

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

Ovládá blokové zařízení a dotazuje se na jeho parametry. Operace, která se má provést, je dána op, což je jedno z následujících celých čísel:

  • 1 – inicializace zařízení (arg se nepoužívá)

  • 2 – vypnutí zařízení (arg se nepoužívá)

  • 3 – synchronizace zařízení (arg se nepoužívá)

  • 4 – získání počtu bloků, mělo by vrátit celé číslo (arg se nepoužívá)

  • 5 – získání počtu bajtů v bloku, mělo by vrátit celé číslo, nebo None, v kterémžto případě se použije výchozí hodnota 512 (arg se nepoužívá)

  • 6 – vymazání bloku, arg je číslo bloku, který se má vymazat

Minimálně musí být zachyceno ioctl(4, ...); souborové systémy používající rozšířené rozhraní navíc vyžadují ioctl(6, ...). Potřeba ostatních operací závisí na hardwaru.

Před každým voláním writeblocks(block, ...) vydá souborový systém používající rozšířené rozhraní ioctl(6, block), aby ovladač mohl blok nejprve vymazat, pokud to hardware vyžaduje. Ovladač může místo toho zachytit ioctl(6, block) a vrátit 0 (úspěch), čímž na sebe převezme zodpovědnost za rozpoznání, kdy je mazání potřeba.

Pokud není uvedeno jinak, ioctl(op, arg) může vrátit None. Implementace tedy může ignorovat nepoužívané hodnoty op. Tam, kde je op zachycen, jsou návratové hodnoty pro operace 4 a 5 takové, jak je podrobně uvedeno výše. Ostatní operace by měly při úspěchu vrátit 0 a při selhání nenulovou hodnotu, přičemž vrácená hodnota je chybový kód OSError errno.