mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-01 19:54:32 +02:00
fat_vfs: added fast seek capable file operation
This commit is contained in:
@@ -182,14 +182,23 @@ menu "FAT Filesystem support"
|
|||||||
|
|
||||||
|
|
||||||
config FATFS_USE_FASTSEEK
|
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
|
default n
|
||||||
help
|
help
|
||||||
The fast seek feature enables fast backward/long seek operations without
|
The fast seek feature enables fast backward/long seek operations without
|
||||||
FAT access by using an in-memory CLMT (cluster link map table).
|
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,
|
It is applied to f_read and f_write function as well, however,
|
||||||
the file size cannot be expanded by f_write.
|
the file size cannot be expanded by write function.
|
||||||
f_lseek function while the file is at fast seek mode.
|
|
||||||
|
|
||||||
|
|
||||||
|
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
|
endmenu
|
||||||
|
@@ -307,6 +307,7 @@ static int vfs_fat_open(void* ctx, const char * path, int flags, int mode)
|
|||||||
errno = ENFILE;
|
errno = ENFILE;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
FRESULT res = f_open(&fat_ctx->files[fd], path, fat_mode_conv(flags));
|
FRESULT res = f_open(&fat_ctx->files[fd], path, fat_mode_conv(flags));
|
||||||
if (res != FR_OK) {
|
if (res != FR_OK) {
|
||||||
file_cleanup(fat_ctx, fd);
|
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);
|
errno = fresult_to_errno(res);
|
||||||
return -1;
|
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:
|
// 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()
|
// - 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()
|
// - 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;
|
vfs_fat_ctx_t* fat_ctx = (vfs_fat_ctx_t*) ctx;
|
||||||
_lock_acquire(&fat_ctx->lock);
|
_lock_acquire(&fat_ctx->lock);
|
||||||
FIL* file = &fat_ctx->files[fd];
|
FIL* file = &fat_ctx->files[fd];
|
||||||
|
|
||||||
|
#ifdef CONFIG_FATFS_USE_FASTSEEK
|
||||||
|
ff_memfree(file->cltbl);
|
||||||
|
#endif
|
||||||
|
|
||||||
FRESULT res = f_close(file);
|
FRESULT res = f_close(file);
|
||||||
file_cleanup(fat_ctx, fd);
|
file_cleanup(fat_ctx, fd);
|
||||||
_lock_release(&fat_ctx->lock);
|
_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;
|
errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ESP_LOGD(TAG, "%s: offset=%ld, filesize:=%d", __func__, new_pos, f_size(file));
|
||||||
|
|
||||||
FRESULT res = f_lseek(file, new_pos);
|
FRESULT res = f_lseek(file, new_pos);
|
||||||
if (res != FR_OK) {
|
if (res != FR_OK) {
|
||||||
ESP_LOGD(TAG, "%s: fresult=%d", __func__, res);
|
ESP_LOGD(TAG, "%s: fresult=%d", __func__, res);
|
||||||
|
@@ -345,6 +345,7 @@ UT_002:
|
|||||||
|
|
||||||
UT_003:
|
UT_003:
|
||||||
extends: .unit_test_template
|
extends: .unit_test_template
|
||||||
|
parallel: 2
|
||||||
tags:
|
tags:
|
||||||
- ESP32_IDF
|
- ESP32_IDF
|
||||||
- UT_T1_SDMODE
|
- 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
|
Reference in New Issue
Block a user