使用文件系统¶
本教程介绍 OpenMV Cam 如何提供片上文件系统,从而可以使用标准的 Python 文件 I/O 方法来进行持久化存储。
OpenMV Cam 在上电时会创建默认配置,并自动检测和挂载主文件系统,因此本教程主要适用于你想要对闪存重新分区、更改文件系统类型或使用自定义块设备的场景。
文件系统由内部闪存提供支持,若安装了 SD 卡,则由 SD 卡提供支持。
VFS¶
MicroPython 实现了类 Unix 的虚拟文件系统(VFS)层。所有已挂载的文件系统都会合并到一个单一的虚拟文件系统中,从根目录 / 开始。文件系统被挂载到该结构中的各个目录里,启动时工作目录被设置为主文件系统。
在 OpenMV Cam 上,内部闪存挂载于 /flash 并作为工作目录。如果安装了 SD 卡,则它会挂载于 /sdcard,并改为成为工作目录。
块设备¶
块设备是实现了 vfs.AbstractBlockDev 协议的类的一个实例。
上电时,OpenMV Cam 会尝试检测内部闪存(或 SD 卡)上的文件系统,并自动对其进行配置和挂载。如果未找到文件系统,则会创建一个跨越整个闪存的 FAT 文件系统。要擦除或重新格式化板载文件系统,最简便的途径是使用 OpenMV IDE 或进行 恢复出厂设置;下文中较底层的 Python API 适用于高级/编程化的用途。
内部闪存¶
在基于 STM32 的 OpenMV Cam 上,pyb.Flash 类提供对内部闪存的访问。在配备更大外部闪存的板子上,它会改用外部闪存。应始终指定 start 关键字参数,即 pyb.Flash(start=0)。
注意:为了向后兼容,当不带参数构造时(即 pyb.Flash()),它仅实现简单的块接口,并反映呈现给 USB 大容量存储的虚拟设备(即在起始处包含一个虚拟分区表)。
自定义块设备¶
你也可以用 Python 创建自己的块设备并挂载它——例如 RAM 磁盘。下面的类实现了一个简单的块设备,它使用 bytearray 将数据存储在 RAM 中::
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 大容量存储暴露文件系统的板子上,主机 PC 无需额外驱动即可读写它。
FAT 对写入期间的断电没有容错能力,这可能导致文件系统损坏。在给摄像头断电之前,请先在主机上弹出/卸载该驱动器,并且对于脚本回写的数据,应优先使用 SD 卡而非内部闪存。
在基于 STM32 的 OpenMV Cam 上,内部闪存可以从 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')