1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-27 08:38:07 +00:00

core/fatfs: rework low-level FatFS API

Instead of having possibly multiple FatFS objects, each with its own
`fs` struct, there is one global static fs_instance. This is to match
the mode of operation of ff.c, which assumes a global list of mounts,
and all functions operate on the global based on path.

Methods of FatFS were converted to functions on the fatfs module.

fatfs.unmount() does not call ff.c's unmount, but simply invalidates
fs_instance. This is basically what ff.c would do, except without
messing with ff.c's global list of mounts.
This commit is contained in:
matejcik 2020-02-26 14:18:41 +01:00
parent 6722215c66
commit fa746e2990
5 changed files with 236 additions and 218 deletions

View File

@ -27,7 +27,12 @@
#include "sdcard.h"
// clang-format on
/// package: trezorio.__init__
/// package: trezorio.fatfs
static FATFS fs_instance;
bool _fatfs_instance_is_mounted() { return fs_instance.fs_type != 0; }
void _fatfs_unmount_instance() { fs_instance.fs_type = 0; }
DSTATUS disk_initialize(BYTE pdrv) { return disk_status(pdrv); }
@ -315,33 +320,13 @@ STATIC const mp_obj_type_t mod_trezorio_FatFSDir_type = {
.iternext = mod_trezorio_FatFSDir_iternext,
};
/// class FatFS:
/// """
/// Class encapsulating FAT filesystem
/// """
typedef struct _mp_obj_FatFS_t {
mp_obj_base_t base;
FATFS fs;
} mp_obj_FatFS_t;
/// mock:global
/// def __init__(self) -> None:
/// """
/// """
STATIC mp_obj_t mod_trezorio_FatFS_make_new(const mp_obj_type_t *type,
size_t n_args, size_t n_kw,
const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 0, 0, false);
mp_obj_FatFS_t *o = m_new_obj(mp_obj_FatFS_t);
o->base.type = type;
return MP_OBJ_FROM_PTR(o);
}
/// def open(self, path: str, flags: str) -> FatFSFile:
/// def open(path: str, flags: str) -> FatFSFile:
/// """
/// Open or create a file
/// """
STATIC mp_obj_t mod_trezorio_FatFS_open(mp_obj_t self, mp_obj_t path,
mp_obj_t flags) {
STATIC mp_obj_t mod_trezorio_fatfs_open(mp_obj_t path, mp_obj_t flags) {
mp_buffer_info_t _path, _flags;
mp_get_buffer_raise(path, &_path, MP_BUFFER_READ);
mp_get_buffer_raise(flags, &_flags, MP_BUFFER_READ);
@ -376,14 +361,14 @@ STATIC mp_obj_t mod_trezorio_FatFS_open(mp_obj_t self, mp_obj_t path,
f->fp = fp;
return f;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_3(mod_trezorio_FatFS_open_obj,
mod_trezorio_FatFS_open);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorio_fatfs_open_obj,
mod_trezorio_fatfs_open);
/// def listdir(self, path: str) -> FatFSDir:
/// def listdir(path: str) -> FatFSDir:
/// """
/// List a directory (return generator)
/// """
STATIC mp_obj_t mod_trezorio_FatFS_listdir(mp_obj_t self, mp_obj_t path) {
STATIC mp_obj_t mod_trezorio_fatfs_listdir(mp_obj_t path) {
mp_buffer_info_t _path;
mp_get_buffer_raise(path, &_path, MP_BUFFER_READ);
DIR dp;
@ -396,19 +381,19 @@ STATIC mp_obj_t mod_trezorio_FatFS_listdir(mp_obj_t self, mp_obj_t path) {
d->dp = dp;
return d;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorio_FatFS_listdir_obj,
mod_trezorio_FatFS_listdir);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorio_fatfs_listdir_obj,
mod_trezorio_fatfs_listdir);
/// def mkdir(self, path: str, exist_ok: bool=False) -> None:
/// def mkdir(path: str, exist_ok: bool=False) -> None:
/// """
/// Create a sub directory
/// """
STATIC mp_obj_t mod_trezorio_FatFS_mkdir(size_t n_args, const mp_obj_t *args) {
STATIC mp_obj_t mod_trezorio_fatfs_mkdir(size_t n_args, const mp_obj_t *args) {
mp_buffer_info_t path;
mp_get_buffer_raise(args[1], &path, MP_BUFFER_READ);
mp_get_buffer_raise(args[0], &path, MP_BUFFER_READ);
FRESULT res = f_mkdir(path.buf);
// directory exists and exist_ok is True, return without failure
if (res == FR_EXIST && n_args > 2 && args[2] == mp_const_true) {
if (res == FR_EXIST && n_args > 1 && args[1] == mp_const_true) {
return mp_const_none;
}
if (res != FR_OK) {
@ -416,14 +401,14 @@ STATIC mp_obj_t mod_trezorio_FatFS_mkdir(size_t n_args, const mp_obj_t *args) {
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorio_FatFS_mkdir_obj, 2, 3,
mod_trezorio_FatFS_mkdir);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorio_fatfs_mkdir_obj, 1, 2,
mod_trezorio_fatfs_mkdir);
/// def unlink(self, path: str) -> None:
/// def unlink(path: str) -> None:
/// """
/// Delete an existing file or directory
/// """
STATIC mp_obj_t mod_trezorio_FatFS_unlink(mp_obj_t self, mp_obj_t path) {
STATIC mp_obj_t mod_trezorio_fatfs_unlink(mp_obj_t path) {
mp_buffer_info_t _path;
mp_get_buffer_raise(path, &_path, MP_BUFFER_READ);
FRESULT res = f_unlink(_path.buf);
@ -432,14 +417,14 @@ STATIC mp_obj_t mod_trezorio_FatFS_unlink(mp_obj_t self, mp_obj_t path) {
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorio_FatFS_unlink_obj,
mod_trezorio_FatFS_unlink);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorio_fatfs_unlink_obj,
mod_trezorio_fatfs_unlink);
/// def stat(self, path: str) -> Tuple[int, str, str]:
/// def stat(path: str) -> Tuple[int, str, str]:
/// """
/// Get file status
/// """
STATIC mp_obj_t mod_trezorio_FatFS_stat(mp_obj_t self, mp_obj_t path) {
STATIC mp_obj_t mod_trezorio_fatfs_stat(mp_obj_t path) {
mp_buffer_info_t _path;
mp_get_buffer_raise(path, &_path, MP_BUFFER_READ);
FILINFO info;
@ -449,15 +434,14 @@ STATIC mp_obj_t mod_trezorio_FatFS_stat(mp_obj_t self, mp_obj_t path) {
}
return filinfo_to_tuple(&info);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorio_FatFS_stat_obj,
mod_trezorio_FatFS_stat);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorio_fatfs_stat_obj,
mod_trezorio_fatfs_stat);
/// def rename(self, oldpath: str, newpath: str) -> None:
/// """
/// Rename/Move a file or directory
/// """
STATIC mp_obj_t mod_trezorio_FatFS_rename(mp_obj_t self, mp_obj_t oldpath,
mp_obj_t newpath) {
STATIC mp_obj_t mod_trezorio_fatfs_rename(mp_obj_t oldpath, mp_obj_t newpath) {
mp_buffer_info_t _oldpath, _newpath;
mp_get_buffer_raise(oldpath, &_oldpath, MP_BUFFER_READ);
mp_get_buffer_raise(newpath, &_newpath, MP_BUFFER_READ);
@ -467,44 +451,52 @@ STATIC mp_obj_t mod_trezorio_FatFS_rename(mp_obj_t self, mp_obj_t oldpath,
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_3(mod_trezorio_FatFS_rename_obj,
mod_trezorio_FatFS_rename);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorio_fatfs_rename_obj,
mod_trezorio_fatfs_rename);
/// def mount(self) -> None:
/// def mount() -> None:
/// """
/// Mount/Unmount a logical drive
/// Mount the SD card filesystem.
/// """
STATIC mp_obj_t mod_trezorio_FatFS_mount(mp_obj_t self) {
mp_obj_FatFS_t *o = MP_OBJ_TO_PTR(self);
FRESULT res = f_mount(&(o->fs), "", 1);
STATIC mp_obj_t mod_trezorio_fatfs_mount() {
FRESULT res = f_mount(&fs_instance, "", 1);
if (res != FR_OK) {
mp_raise_OSError(fresult_to_errno_table[res]);
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorio_FatFS_mount_obj,
mod_trezorio_FatFS_mount);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorio_fatfs_mount_obj,
mod_trezorio_fatfs_mount);
/// def unmount(self) -> None:
/// def unmount() -> None:
/// """
/// Unmount a logical drive
/// Unmount the SD card filesystem.
/// """
STATIC mp_obj_t mod_trezorio_FatFS_unmount(mp_obj_t self) {
// to unmount we have to call mount with the first parameter NULL
FRESULT res = f_mount(NULL, "", 0);
if (res != FR_OK) {
mp_raise_OSError(fresult_to_errno_table[res]);
}
STATIC mp_obj_t mod_trezorio_fatfs_unmount() {
_fatfs_unmount_instance();
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorio_FatFS_unmount_obj,
mod_trezorio_FatFS_unmount);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorio_fatfs_unmount_obj,
mod_trezorio_fatfs_unmount);
/// def mkfs(self) -> None:
/// def is_mounted() -> bool:
/// """
/// Check if the filesystem is mounted.
/// """
STATIC mp_obj_t mod_trezorio_fatfs_is_mounted() {
return mp_obj_new_bool(_fatfs_instance_is_mounted());
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorio_fatfs_is_mounted_obj,
mod_trezorio_fatfs_is_mounted);
/// def mkfs() -> None:
/// """
/// Create a FAT volume
/// Create a FAT volume on the SD card,
/// """
STATIC mp_obj_t mod_trezorio_FatFS_mkfs(mp_obj_t self) {
STATIC mp_obj_t mod_trezorio_fatfs_mkfs() {
if (_fatfs_instance_is_mounted()) {
mp_raise_OSError(MP_EBUSY);
}
MKFS_PARM params = {FM_FAT32, 0, 0, 0, 0};
uint8_t working_buf[FF_MAX_SS];
FRESULT res = f_mkfs("", &params, working_buf, sizeof(working_buf));
@ -513,14 +505,17 @@ STATIC mp_obj_t mod_trezorio_FatFS_mkfs(mp_obj_t self) {
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorio_FatFS_mkfs_obj,
mod_trezorio_FatFS_mkfs);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorio_fatfs_mkfs_obj,
mod_trezorio_fatfs_mkfs);
/// def setlabel(self, label: str) -> None:
/// def setlabel(label: str) -> None:
/// """
/// Set volume label
/// """
STATIC mp_obj_t mod_trezorio_FatFS_setlabel(mp_obj_t self, mp_obj_t label) {
STATIC mp_obj_t mod_trezorio_fatfs_setlabel(mp_obj_t label) {
if (_fatfs_instance_is_mounted()) {
mp_raise_OSError(MP_EBUSY);
}
mp_buffer_info_t _label;
mp_get_buffer_raise(label, &_label, MP_BUFFER_READ);
FRESULT res = f_setlabel(_label.buf);
@ -529,28 +524,32 @@ STATIC mp_obj_t mod_trezorio_FatFS_setlabel(mp_obj_t self, mp_obj_t label) {
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorio_FatFS_setlabel_obj,
mod_trezorio_FatFS_setlabel);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorio_fatfs_setlabel_obj,
mod_trezorio_fatfs_setlabel);
STATIC const mp_rom_map_elem_t mod_trezorio_FatFS_locals_dict_table[] = {
{MP_ROM_QSTR(MP_QSTR_open), MP_ROM_PTR(&mod_trezorio_FatFS_open_obj)},
{MP_ROM_QSTR(MP_QSTR_listdir), MP_ROM_PTR(&mod_trezorio_FatFS_listdir_obj)},
{MP_ROM_QSTR(MP_QSTR_mkdir), MP_ROM_PTR(&mod_trezorio_FatFS_mkdir_obj)},
{MP_ROM_QSTR(MP_QSTR_unlink), MP_ROM_PTR(&mod_trezorio_FatFS_unlink_obj)},
{MP_ROM_QSTR(MP_QSTR_rename), MP_ROM_PTR(&mod_trezorio_FatFS_rename_obj)},
{MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&mod_trezorio_FatFS_stat_obj)},
{MP_ROM_QSTR(MP_QSTR_mount), MP_ROM_PTR(&mod_trezorio_FatFS_mount_obj)},
{MP_ROM_QSTR(MP_QSTR_unmount), MP_ROM_PTR(&mod_trezorio_FatFS_unmount_obj)},
{MP_ROM_QSTR(MP_QSTR_mkfs), MP_ROM_PTR(&mod_trezorio_FatFS_mkfs_obj)},
STATIC const mp_rom_map_elem_t mod_trezorio_fatfs_globals_table[] = {
{MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_fatfs)},
{MP_ROM_QSTR(MP_QSTR_FatFSFile), MP_ROM_PTR(&mod_trezorio_FatFSFile_type)},
{MP_ROM_QSTR(MP_QSTR_FatFSDir), MP_ROM_PTR(&mod_trezorio_FatFSDir_type)},
{MP_ROM_QSTR(MP_QSTR_open), MP_ROM_PTR(&mod_trezorio_fatfs_open_obj)},
{MP_ROM_QSTR(MP_QSTR_listdir), MP_ROM_PTR(&mod_trezorio_fatfs_listdir_obj)},
{MP_ROM_QSTR(MP_QSTR_mkdir), MP_ROM_PTR(&mod_trezorio_fatfs_mkdir_obj)},
{MP_ROM_QSTR(MP_QSTR_unlink), MP_ROM_PTR(&mod_trezorio_fatfs_unlink_obj)},
{MP_ROM_QSTR(MP_QSTR_rename), MP_ROM_PTR(&mod_trezorio_fatfs_rename_obj)},
{MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&mod_trezorio_fatfs_stat_obj)},
{MP_ROM_QSTR(MP_QSTR_mount), MP_ROM_PTR(&mod_trezorio_fatfs_mount_obj)},
{MP_ROM_QSTR(MP_QSTR_unmount), MP_ROM_PTR(&mod_trezorio_fatfs_unmount_obj)},
{MP_ROM_QSTR(MP_QSTR_is_mounted),
MP_ROM_PTR(&mod_trezorio_fatfs_is_mounted_obj)},
{MP_ROM_QSTR(MP_QSTR_mkfs), MP_ROM_PTR(&mod_trezorio_fatfs_mkfs_obj)},
{MP_ROM_QSTR(MP_QSTR_setlabel),
MP_ROM_PTR(&mod_trezorio_FatFS_setlabel_obj)},
MP_ROM_PTR(&mod_trezorio_fatfs_setlabel_obj)},
};
STATIC MP_DEFINE_CONST_DICT(mod_trezorio_FatFS_locals_dict,
mod_trezorio_FatFS_locals_dict_table);
STATIC MP_DEFINE_CONST_DICT(mod_trezorio_fatfs_globals,
mod_trezorio_fatfs_globals_table);
STATIC const mp_obj_type_t mod_trezorio_FatFS_type = {
{&mp_type_type},
.name = MP_QSTR_FatFS,
.make_new = mod_trezorio_FatFS_make_new,
.locals_dict = (void *)&mod_trezorio_FatFS_locals_dict,
STATIC const mp_obj_module_t mod_trezorio_fatfs_module = {
.base = {&mp_type_module},
.globals = (mp_obj_dict_t *)&mod_trezorio_fatfs_globals,
};

View File

@ -111,6 +111,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_trezorio_sdcard_write_obj,
mod_trezorio_sdcard_write);
STATIC const mp_rom_map_elem_t mod_trezorio_sdcard_globals_table[] = {
{MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_sdcard)},
{MP_ROM_QSTR(MP_QSTR_is_present),
MP_ROM_PTR(&mod_trezorio_sdcard_is_present_obj)},
{MP_ROM_QSTR(MP_QSTR_power_on),

View File

@ -62,7 +62,7 @@
STATIC const mp_rom_map_elem_t mp_module_trezorio_globals_table[] = {
{MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_trezorio)},
{MP_ROM_QSTR(MP_QSTR_FatFS), MP_ROM_PTR(&mod_trezorio_FatFS_type)},
{MP_ROM_QSTR(MP_QSTR_fatfs), MP_ROM_PTR(&mod_trezorio_fatfs_module)},
{MP_ROM_QSTR(MP_QSTR_FlashOTP), MP_ROM_PTR(&mod_trezorio_FlashOTP_type)},

View File

@ -1,131 +1,6 @@
from typing import *
# extmod/modtrezorio/modtrezorio-fatfs.h
class FatFSFile:
"""
Class encapsulating file
"""
def __enter__(self) -> FatFSFile:
"""
Return an open file object
"""
from types import TracebackType
def __exit__(
self, type: Optional[Type[BaseException]],
value: Optional[BaseException],
traceback: Optional[TracebackType],
) -> None:
"""
Close an open file object
"""
def close(self) -> None:
"""
Close an open file object
"""
def read(self, data: bytearray) -> int:
"""
Read data from the file
"""
def write(self, data: Union[bytes, bytearray]) -> int:
"""
Write data to the file
"""
def seek(self, offset: int) -> None:
"""
Move file pointer of the file object
"""
def truncate(self) -> None:
"""
Truncate the file
"""
def sync(self) -> None:
"""
Flush cached data of the writing file
"""
# extmod/modtrezorio/modtrezorio-fatfs.h
class FatFSDir(Iterator[Tuple[int, str, str]]):
"""
Class encapsulating directory
"""
def __next__(self) -> Tuple[int, str, str]:
"""
Read an entry in the directory
"""
# extmod/modtrezorio/modtrezorio-fatfs.h
class FatFS:
"""
Class encapsulating FAT filesystem
"""
def __init__(self) -> None:
"""
"""
def open(self, path: str, flags: str) -> FatFSFile:
"""
Open or create a file
"""
def listdir(self, path: str) -> FatFSDir:
"""
List a directory (return generator)
"""
def mkdir(self, path: str, exist_ok: bool=False) -> None:
"""
Create a sub directory
"""
def unlink(self, path: str) -> None:
"""
Delete an existing file or directory
"""
def stat(self, path: str) -> Tuple[int, str, str]:
"""
Get file status
"""
def rename(self, oldpath: str, newpath: str) -> None:
"""
Rename/Move a file or directory
"""
def mount(self) -> None:
"""
Mount/Unmount a logical drive
"""
def unmount(self) -> None:
"""
Unmount a logical drive
"""
def mkfs(self) -> None:
"""
Create a FAT volume
"""
def setlabel(self, label: str) -> None:
"""
Set volume label
"""
# extmod/modtrezorio/modtrezorio-flash.h
class FlashOTP:
"""

View File

@ -0,0 +1,142 @@
from typing import *
# extmod/modtrezorio/modtrezorio-fatfs.h
class FatFSFile:
"""
Class encapsulating file
"""
def __enter__(self) -> FatFSFile:
"""
Return an open file object
"""
from types import TracebackType
def __exit__(
self, type: Optional[Type[BaseException]],
value: Optional[BaseException],
traceback: Optional[TracebackType],
) -> None:
"""
Close an open file object
"""
def close(self) -> None:
"""
Close an open file object
"""
def read(self, data: bytearray) -> int:
"""
Read data from the file
"""
def write(self, data: Union[bytes, bytearray]) -> int:
"""
Write data to the file
"""
def seek(self, offset: int) -> None:
"""
Move file pointer of the file object
"""
def truncate(self) -> None:
"""
Truncate the file
"""
def sync(self) -> None:
"""
Flush cached data of the writing file
"""
# extmod/modtrezorio/modtrezorio-fatfs.h
class FatFSDir(Iterator[Tuple[int, str, str]]):
"""
Class encapsulating directory
"""
def __next__(self) -> Tuple[int, str, str]:
"""
Read an entry in the directory
"""
# extmod/modtrezorio/modtrezorio-fatfs.h
def open(path: str, flags: str) -> FatFSFile:
"""
Open or create a file
"""
# extmod/modtrezorio/modtrezorio-fatfs.h
def listdir(path: str) -> FatFSDir:
"""
List a directory (return generator)
"""
# extmod/modtrezorio/modtrezorio-fatfs.h
def mkdir(path: str, exist_ok: bool=False) -> None:
"""
Create a sub directory
"""
# extmod/modtrezorio/modtrezorio-fatfs.h
def unlink(path: str) -> None:
"""
Delete an existing file or directory
"""
# extmod/modtrezorio/modtrezorio-fatfs.h
def stat(path: str) -> Tuple[int, str, str]:
"""
Get file status
"""
# extmod/modtrezorio/modtrezorio-fatfs.h
def rename(self, oldpath: str, newpath: str) -> None:
"""
Rename/Move a file or directory
"""
# extmod/modtrezorio/modtrezorio-fatfs.h
def mount() -> None:
"""
Mount the SD card filesystem.
"""
# extmod/modtrezorio/modtrezorio-fatfs.h
def unmount() -> None:
"""
Unmount the SD card filesystem.
"""
# extmod/modtrezorio/modtrezorio-fatfs.h
def is_mounted() -> bool:
"""
Check if the filesystem is mounted.
"""
# extmod/modtrezorio/modtrezorio-fatfs.h
def mkfs() -> None:
"""
Create a FAT volume on the SD card,
"""
# extmod/modtrezorio/modtrezorio-fatfs.h
def setlabel(label: str) -> None:
"""
Set volume label
"""