mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
fat_vfs: added fast seek capable file operation
This commit is contained in:
parent
8815a3dfa0
commit
32e760adfb
@ -182,14 +182,23 @@ menu "FAT Filesystem support"
|
||||
|
||||
|
||||
config FATFS_USE_FASTSEEK
|
||||
bool "Enable fast seek algorithm when using f_lseek function"
|
||||
bool "Enable fast seek algorithm when using lseek function through VFS FAT"
|
||||
default n
|
||||
help
|
||||
The fast seek feature enables fast backward/long seek operations without
|
||||
FAT access by using an in-memory CLMT (cluster link map table).
|
||||
It is applied to f_read and f_write function as well, however,
|
||||
the file size cannot be expanded by f_write.
|
||||
f_lseek function while the file is at fast seek mode.
|
||||
the file size cannot be expanded by write function.
|
||||
|
||||
|
||||
config FATFS_FAST_SEEK_BUFFER_SIZE
|
||||
int "Fast seek CLMT buffer size"
|
||||
default 64
|
||||
depends on FATFS_USE_FASTSEEK
|
||||
help
|
||||
If fast seek algorithm is enabled, this defines the size of
|
||||
CLMT buffer used by this algorithm in 32-bit word units.
|
||||
This value should be chosen based on prior knowledge of
|
||||
maximum elements of each file entry would store.
|
||||
|
||||
endmenu
|
||||
|
@ -307,6 +307,7 @@ static int vfs_fat_open(void* ctx, const char * path, int flags, int mode)
|
||||
errno = ENFILE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
FRESULT res = f_open(&fat_ctx->files[fd], path, fat_mode_conv(flags));
|
||||
if (res != FR_OK) {
|
||||
file_cleanup(fat_ctx, fd);
|
||||
@ -315,6 +316,34 @@ static int vfs_fat_open(void* ctx, const char * path, int flags, int mode)
|
||||
errno = fresult_to_errno(res);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FATFS_USE_FASTSEEK
|
||||
FIL* file = &fat_ctx->files[fd];
|
||||
DWORD *clmt_mem = ff_memalloc(sizeof(DWORD) * CONFIG_FATFS_FAST_SEEK_BUFFER_SIZE);
|
||||
if (clmt_mem == NULL) {
|
||||
f_close(file);
|
||||
file_cleanup(fat_ctx, fd);
|
||||
_lock_release(&fat_ctx->lock);
|
||||
ESP_LOGE(TAG, "open: Failed to pre-allocate CLMT buffer for fast-seek");
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
file->cltbl = clmt_mem;
|
||||
file->cltbl[0] = CONFIG_FATFS_FAST_SEEK_BUFFER_SIZE;
|
||||
res = f_lseek(file, CREATE_LINKMAP);
|
||||
ESP_LOGD(TAG, "%s: fast-seek has: %s",
|
||||
__func__,
|
||||
(res == FR_OK) ? "activated" : "failed");
|
||||
if(res != FR_OK) {
|
||||
ESP_LOGW(TAG, "%s: fast-seek not activated reason code: %d",
|
||||
__func__, res);
|
||||
//If linkmap creation fails, fallback to the non fast seek.
|
||||
ff_memfree(file->cltbl);
|
||||
file->cltbl = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
// O_APPEND need to be stored because it is not compatible with FA_OPEN_APPEND:
|
||||
// - FA_OPEN_APPEND means to jump to the end of file only after open()
|
||||
// - O_APPEND means to jump to the end only before each write()
|
||||
@ -465,6 +494,11 @@ static int vfs_fat_close(void* ctx, int fd)
|
||||
vfs_fat_ctx_t* fat_ctx = (vfs_fat_ctx_t*) ctx;
|
||||
_lock_acquire(&fat_ctx->lock);
|
||||
FIL* file = &fat_ctx->files[fd];
|
||||
|
||||
#ifdef CONFIG_FATFS_USE_FASTSEEK
|
||||
ff_memfree(file->cltbl);
|
||||
#endif
|
||||
|
||||
FRESULT res = f_close(file);
|
||||
file_cleanup(fat_ctx, fd);
|
||||
_lock_release(&fat_ctx->lock);
|
||||
@ -494,6 +528,9 @@ static off_t vfs_fat_lseek(void* ctx, int fd, off_t offset, int mode)
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "%s: offset=%ld, filesize:=%d", __func__, new_pos, f_size(file));
|
||||
|
||||
FRESULT res = f_lseek(file, new_pos);
|
||||
if (res != FR_OK) {
|
||||
ESP_LOGD(TAG, "%s: fresult=%d", __func__, res);
|
||||
|
@ -345,6 +345,7 @@ UT_002:
|
||||
|
||||
UT_003:
|
||||
extends: .unit_test_template
|
||||
parallel: 2
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- UT_T1_SDMODE
|
||||
|
3
tools/unit-test-app/configs/fatfs_fast_seek
Normal file
3
tools/unit-test-app/configs/fatfs_fast_seek
Normal file
@ -0,0 +1,3 @@
|
||||
TEST_COMPONENTS=fatfs
|
||||
CONFIG_FATFS_USE_FASTSEEK=y
|
||||
CONFIG_FATFS_FAST_SEEK_BUFFER_SIZE=64
|
Loading…
x
Reference in New Issue
Block a user