使用檔案系統¶
本教學說明 OpenMV Cam 如何在裝置上提供檔案系統,讓標準的 Python 檔案 I/O 方法能搭配持久性儲存空間使用。
OpenMV Cam 會建立預設組態,並在開機時自動偵測並掛載主要檔案系統,因此本教學主要適用於想要重新分割 flash、變更檔案系統類型或使用自訂區塊裝置的情況。
檔案系統由內部 flash 記憶體支援,若安裝了 SD 卡,則由 SD 卡支援。
VFS¶
MicroPython 實作了類似 Unix 的虛擬檔案系統(VFS)層。所有已掛載的檔案系統都會合併成單一虛擬檔案系統,從根目錄 / 開始。檔案系統會掛載到此結構中的目錄裡,而在啟動時,工作目錄會設定為主要檔案系統。
在 OpenMV Cam 上,內部 flash 掛載於 /flash,並作為工作目錄。若安裝了 SD 卡,則會掛載於 /sdcard,並改為作為工作目錄。
區塊裝置¶
區塊裝置是實作了 vfs.AbstractBlockDev 協定之類別的實例。
開機時,OpenMV Cam 會嘗試偵測內部 flash(或 SD 卡)上的檔案系統,並自動加以設定及掛載。若找不到任何檔案系統,便會建立一個橫跨整個 flash 的 FAT 檔案系統。若要清除或重新格式化板載檔案系統,最簡便的方式是使用 OpenMV IDE 或執行 恢復原廠設定;下方較低階的 Python API 則供進階/程式化用途使用。
內部 flash¶
在基於 STM32 的 OpenMV Cam 上,pyb.Flash 類別提供對內部 flash 的存取。在具有較大外部 flash 的板子上,則會改用外部 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 會將內部 flash 格式化為 FAT,如此一來,在透過 USB 大容量儲存裝置公開檔案系統的板子上,主機 PC 無需額外驅動程式即可讀寫該檔案系統。
FAT 在寫入過程中無法容忍斷電,這可能導致檔案系統損毀。在關閉相機電源之前,請先在主機上退出/卸載該磁碟機,且對於指令碼會寫回的資料,建議優先使用 SD 卡而非內部 flash。
在基於 STM32 的 OpenMV Cam 上,可從 Python 重新格式化內部 flash:
import os, vfs, pyb
vfs.umount('/flash')
vfs.VfsFat.mkfs(pyb.Flash(start=0))
vfs.mount(pyb.Flash(start=0), '/flash')
os.chdir('/flash')