Работа с файловыми системами

В этом руководстве описывается, как OpenMV Cam предоставляет файловую систему на устройстве, позволяя использовать стандартные методы файлового ввода-вывода Python для постоянного хранения данных.

OpenMV Cam создаёт конфигурацию по умолчанию, а также автоматически определяет и монтирует основную файловую систему при включении питания, поэтому данное руководство в основном полезно, если вы хотите переразбить флеш-память на разделы, изменить тип файловой системы или использовать пользовательское блочное устройство.

Файловая система располагается во внутренней флеш-памяти или на SD-карте, если она установлена.

VFS

MicroPython реализует Unix-подобный слой виртуальной файловой системы (VFS). Все смонтированные файловые системы объединяются в единую виртуальную файловую систему, начинающуюся с корня /. Файловые системы монтируются в каталоги этой структуры, и при запуске рабочим каталогом устанавливается основная файловая система.

На OpenMV Cam внутренняя флеш-память монтируется в /flash и является рабочим каталогом. Если установлена SD-карта, она монтируется в /sdcard и становится рабочим каталогом вместо флеш-памяти.

Блочные устройства

Блочное устройство — это экземпляр класса, реализующего протокол vfs.AbstractBlockDev.

При включении питания OpenMV Cam пытается обнаружить файловую систему во внутренней флеш-памяти (или на SD-карте), а затем настроить и смонтировать её автоматически. Если файловая система не найдена, создаётся файловая система FAT, занимающая всю флеш-память. Для стирания или переформатирования встроенной файловой системы проще всего воспользоваться OpenMV IDE или сбросом к заводским настройкам; низкоуровневый Python API, описанный ниже, предназначен для продвинутого/программного использования.

Внутренняя флеш-память

На OpenMV Cam на базе STM32 класс pyb.Flash предоставляет доступ к внутренней флеш-памяти. На платах с большей внешней флеш-памятью будет использоваться она. Именованный аргумент start следует всегда указывать, то есть pyb.Flash(start=0).

Примечание: для обратной совместимости при создании без аргументов (то есть pyb.Flash()) реализуется только простой блочный интерфейс, отражающий виртуальное устройство, представляемое USB-накопителем (то есть включающее виртуальную таблицу разделов в начале).

Пользовательские блочные устройства

Вы также можете создать собственное блочное устройство на Python и смонтировать его — например, RAM-диск. Следующий класс реализует простое блочное устройство, хранящее свои данные в ОЗУ с помощью bytearray:

class RAMBlockDev:
    def __init__(self, block_size, num_blocks):
        self.block_size = block_size
        self.data = bytearray(block_size * num_blocks)

    def readblocks(self, block_num, buf):
        for i in range(len(buf)):
            buf[i] = self.data[block_num * self.block_size + i]

    def writeblocks(self, block_num, buf):
        for i in range(len(buf)):
            self.data[block_num * self.block_size + i] = buf[i]

    def ioctl(self, op, arg):
        if op == 4: # get number of blocks
            return len(self.data) // self.block_size
        if op == 5: # get block size
            return self.block_size

Его можно использовать следующим образом:

import vfs

bdev = RAMBlockDev(512, 50)
vfs.VfsFat.mkfs(bdev)
vfs.mount(bdev, '/ramdisk')

После монтирования файловую систему можно использовать обычным образом из кода Python, например:

with open('/ramdisk/hello.txt', 'w') as f:
    f.write('Hello world')
print(open('/ramdisk/hello.txt').read())

Файловые системы

OpenMV Cam форматирует внутреннюю флеш-память как FAT, чтобы на платах, предоставляющих файловую систему через USB-накопитель, хост-ПК мог читать и записывать её без дополнительных драйверов.

FAT не устойчива к сбоям питания во время записи, что может привести к повреждению файловой системы. Извлекайте/размонтируйте накопитель на хосте перед выключением камеры и предпочитайте SD-карту внутренней флеш-памяти для данных, которые записывает скрипт.

На OpenMV Cam на базе STM32 внутреннюю флеш-память можно переформатировать из Python:

import os, vfs, pyb
vfs.umount('/flash')
vfs.VfsFat.mkfs(pyb.Flash(start=0))
vfs.mount(pyb.Flash(start=0), '/flash')
os.chdir('/flash')