feat(fs): add support for memory-mapped files (#4462)
Co-authored-by: Zoltan Janosy <zjanosy@fishman.com> Co-authored-by: Gabor Kiss-Vamosi <kisvegabor@gmail.com>
This commit is contained in:
218
src/libs/fsdrv/lv_fs_memfs.c
Normal file
218
src/libs/fsdrv/lv_fs_memfs.c
Normal file
@@ -0,0 +1,218 @@
|
||||
/**
|
||||
* @file lv_fs_memfs.c
|
||||
*
|
||||
* File System Interface driver for memory-mapped files
|
||||
*
|
||||
* This driver allows using a memory area as a file that can be read by normal file operations. It can
|
||||
* be used, e.g., to store font files in slow flash memory, and load them into RAM on demand.
|
||||
*
|
||||
* You can enable it in lv_conf.h:
|
||||
*
|
||||
* #define LV_USE_FS_MEMFS 1
|
||||
*
|
||||
* The actual implementation uses the built-in cache mechanism of the file system interface.
|
||||
*
|
||||
* Since this is not an actual file system, file write and directories are not supported.
|
||||
*
|
||||
* The default drive letter is 'M', but this can be changed in lv_conf.h:
|
||||
*
|
||||
* #define LV_FS_MEMFS_LETTER 'M'
|
||||
*
|
||||
* To use it seamlessly with the file system interface a new extended path object has been introduced:
|
||||
*
|
||||
* lv_fs_path_ex_t mempath;
|
||||
*
|
||||
* This structure can be initialized with the helper function:
|
||||
*
|
||||
* lv_fs_make_path_ex(&mempath, (const uint8_t *) & my_mem_buffer, sizeof(my_mem_buffer));
|
||||
*
|
||||
* Then the "file" can be opened with:
|
||||
*
|
||||
* lv_fs_file_t file;
|
||||
* lv_fs_res_t res = lv_fs_open(&file, (const char *) & mempath, LV_FS_MODE_RD);
|
||||
*
|
||||
* The path object can be used at any place where a file path is required, e.g.:
|
||||
*
|
||||
* lv_font_t* my_font = lv_font_load((const char *) & mempath);
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../../../lvgl.h"
|
||||
#if LV_USE_FS_MEMFS
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode);
|
||||
static lv_fs_res_t fs_close(lv_fs_drv_t * drv, void * file_p);
|
||||
static lv_fs_res_t fs_read(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br);
|
||||
static lv_fs_res_t fs_seek(lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence);
|
||||
static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
static lv_fs_drv_t fs_drv; /*A driver descriptor*/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Register a driver for the File system interface
|
||||
*/
|
||||
void lv_fs_memfs_init(void)
|
||||
{
|
||||
/*---------------------------------------------------
|
||||
* Register the file system interface in LVGL
|
||||
*--------------------------------------------------*/
|
||||
|
||||
/*Add a simple drive to open images*/
|
||||
lv_fs_drv_init(&fs_drv);
|
||||
|
||||
/*Set up fields...*/
|
||||
fs_drv.letter = LV_FS_MEMFS_LETTER;
|
||||
fs_drv.cache_size = LV_FS_CACHE_FROM_BUFFER;
|
||||
|
||||
fs_drv.open_cb = fs_open;
|
||||
fs_drv.close_cb = fs_close;
|
||||
fs_drv.read_cb = fs_read;
|
||||
fs_drv.write_cb = NULL;
|
||||
fs_drv.seek_cb = fs_seek;
|
||||
fs_drv.tell_cb = fs_tell;
|
||||
|
||||
fs_drv.dir_close_cb = NULL;
|
||||
fs_drv.dir_open_cb = NULL;
|
||||
fs_drv.dir_read_cb = NULL;
|
||||
|
||||
lv_fs_drv_register(&fs_drv);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Open a file
|
||||
* @param drv pointer to a driver where this function belongs
|
||||
* @param path pointer to an extended path object containing the memory buffer address and size
|
||||
* @param mode read: FS_MODE_RD (currently only reading from the buffer is supported)
|
||||
* @return pointer to FIL struct or NULL in case of fail
|
||||
*/
|
||||
static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode)
|
||||
{
|
||||
LV_UNUSED(drv);
|
||||
LV_UNUSED(mode);
|
||||
return (void *)path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close an opened file
|
||||
* @param drv pointer to a driver where this function belongs
|
||||
* @param file_p pointer to a FILE variable. (opened with fs_open)
|
||||
* @return LV_FS_RES_OK: no error, the file is read
|
||||
* any error from lv_fs_res_t enum
|
||||
*/
|
||||
static lv_fs_res_t fs_close(lv_fs_drv_t * drv, void * file_p)
|
||||
{
|
||||
LV_UNUSED(drv);
|
||||
LV_UNUSED(file_p);
|
||||
return LV_FS_RES_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read data from an opened file
|
||||
* @param drv pointer to a driver where this function belongs
|
||||
* @param file_p pointer to a FILE variable.
|
||||
* @param buf pointer to a memory block where to store the read data
|
||||
* @param btr number of Bytes To Read
|
||||
* @param br the real number of read bytes (Byte Read)
|
||||
* @return LV_FS_RES_OK: no error, the file is read
|
||||
* any error from lv_fs_res_t enum
|
||||
*/
|
||||
static lv_fs_res_t fs_read(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br)
|
||||
{
|
||||
LV_UNUSED(drv);
|
||||
LV_UNUSED(file_p);
|
||||
LV_UNUSED(buf);
|
||||
LV_UNUSED(btr);
|
||||
*br = 0;
|
||||
return LV_FS_RES_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the read pointer.
|
||||
* @param drv pointer to a driver where this function belongs
|
||||
* @param file_p pointer to a FILE variable. (opened with fs_open )
|
||||
* @param pos the new position of read pointer
|
||||
* @return LV_FS_RES_OK: no error, the file is read
|
||||
* any error from lv_fs_res_t enum
|
||||
*/
|
||||
static lv_fs_res_t fs_seek(lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence)
|
||||
{
|
||||
/* NOTE: this function is only called to determine the end of the buffer when LV_FS_SEEK_END was given to lv_fs_seek() */
|
||||
LV_UNUSED(drv);
|
||||
lv_fs_file_t * fp = (lv_fs_file_t *)file_p;
|
||||
switch(whence) {
|
||||
case LV_FS_SEEK_SET: {
|
||||
fp->cache->file_position = pos;
|
||||
break;
|
||||
}
|
||||
case LV_FS_SEEK_CUR: {
|
||||
fp->cache->file_position += pos;
|
||||
break;
|
||||
}
|
||||
case LV_FS_SEEK_END: {
|
||||
fp->cache->file_position = fp->cache->end - pos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(fp->cache->file_position < fp->cache->start)
|
||||
fp->cache->file_position = fp->cache->start;
|
||||
else if(fp->cache->file_position > fp->cache->end)
|
||||
fp->cache->file_position = fp->cache->end;
|
||||
return LV_FS_RES_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Give the position of the read write pointer
|
||||
* @param drv pointer to a driver where this function belongs
|
||||
* @param file_p pointer to a FILE variable.
|
||||
* @param pos_p pointer to to store the result
|
||||
* @return LV_FS_RES_OK: no error, the file is read
|
||||
* any error from lv_fs_res_t enum
|
||||
*/
|
||||
static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p)
|
||||
{
|
||||
LV_UNUSED(drv);
|
||||
*pos_p = ((lv_fs_file_t *)file_p)->cache->file_position;
|
||||
return LV_FS_RES_OK;
|
||||
}
|
||||
|
||||
|
||||
#else /*LV_USE_FS_MEMFS == 0*/
|
||||
|
||||
#if defined(LV_FS_MEMFS_LETTER) && LV_FS_MEMFS_LETTER != '\0'
|
||||
#warning "LV_USE_FS_MEMFS is not enabled but LV_FS_MEMFS_LETTER is set"
|
||||
#endif
|
||||
|
||||
#endif /*LV_USE_FS_MEMFS*/
|
||||
|
||||
Reference in New Issue
Block a user