216 lines
6.4 KiB
C
216 lines
6.4 KiB
C
/**
|
|
* @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_binfont_create((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*/
|