文件系统

LVGL 提供了一个“文件系统”抽象模块,使您可以挂载任何类型的文件系统。 文件系统通过分配的驱动器字母来标识。 例如,如果 SD 卡被分配了字母 'S',则可以通过 "S:path/to/file.txt" 访问文件。

可用的驱动程序

lv_fs_if 仓库包含了使用 POSIX、标准 C 和 FATFS API 的预备驱动程序。 详情请参阅其 README

添加驱动程序

注册驱动程序

要添加驱动程序,需要像下面这样初始化一个 lv_fs_drv_tlv_fs_drv_t 必须是静态、全局或动态分配的,不能是局部变量。

static lv_fs_drv_t drv;                   /*需要是静态或全局变量*/
lv_fs_drv_init(&drv);                     /*基本初始化*/

drv.letter = 'S';                         /*一个大写字母,用于标识驱动器*/
drv.cache_size = my_cache_size;           /*读取时的缓存大小(字节)。0 表示不缓存。*/

drv.ready_cb = my_ready_cb;               /*回调函数,用于判断驱动器是否可用*/
drv.open_cb = my_open_cb;                 /*回调函数,用于打开文件*/
drv.close_cb = my_close_cb;               /*回调函数,用于关闭文件*/
drv.read_cb = my_read_cb;                 /*回调函数,用于读取文件*/
drv.write_cb = my_write_cb;               /*回调函数,用于写入文件*/
drv.seek_cb = my_seek_cb;                 /*回调函数,用于在文件中定位(移动光标)*/
drv.tell_cb = my_tell_cb;                 /*回调函数,用于获取光标位置*/

drv.dir_open_cb = my_dir_open_cb;         /*回调函数,用于打开目录以读取其内容*/
drv.dir_read_cb = my_dir_read_cb;         /*回调函数,用于读取目录内容*/
drv.dir_close_cb = my_dir_close_cb;       /*回调函数,用于关闭目录*/

drv.user_data = my_user_data;             /*如果需要,可以使用任何自定义数据*/

lv_fs_drv_register(&drv);                 /*最后注册驱动器*/

任何回调函数都可以是 NULL,表示不支持该操作。

实现回调函数

打开回调函数

open_cb 的原型如下:

void * (*open_cb)(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode);

path 是驱动器字母后的路径(例如 "S:path/to/file.txt" -> "path/to/file.txt")。mode 可以是 LV_FS_MODE_WRLV_FS_MODE_RD,分别表示以写入或读取模式打开。

返回值是一个指向文件对象的指针,该对象描述了已打开的文件;如果有任何问题(例如文件未找到),则返回 NULL。 返回的文件对象将传递给其他与文件系统相关的回调函数。(见下文)

其他回调函数

其他回调函数非常相似。例如 write_cb 如下:

lv_fs_res_t (*write_cb)(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw);

对于 file_p,LVGL 传递 open_cb 的返回值,buf 是要写入的数据,btw 是要写入的字节数,bw 是实际写入的字节数。

有关这些回调函数的模板,请参阅 lv_fs_template.c

使用示例

下面的示例展示了如何从文件中读取:

lv_fs_file_t f;
lv_fs_res_t res;
res = lv_fs_open(&f, "S:folder/file.txt", LV_FS_MODE_RD);
if(res != LV_FS_RES_OK) my_error_handling();

uint32_t read_num;
uint8_t buf[8];
res = lv_fs_read(&f, buf, 8, &read_num);
if(res != LV_FS_RES_OK || read_num != 8) my_error_handling();

lv_fs_close(&f);

lv_fs_open 中的模式可以是 LV_FS_MODE_WR,表示仅以写入模式打开,或者 LV_FS_MODE_RD | LV_FS_MODE_WR,表示同时以读取和写入模式打开。

此示例展示了如何读取目录的内容。如何在结果中标记目录取决于驱动程序,但在每个目录名称前插入 '/' 是一个不错的做法。

lv_fs_dir_t dir;
lv_fs_res_t res;
res = lv_fs_dir_open(&dir, "S:/folder");
if(res != LV_FS_RES_OK) my_error_handling();

char fn[256];
while(1) {
    res = lv_fs_dir_read(&dir, fn);
    if(res != LV_FS_RES_OK) {
        my_error_handling();
        break;
    }

    /*如果没有更多文件可读取,fn 为空*/
    if(strlen(fn) == 0) {
        break;
    }

    printf("%s\n", fn);
}

lv_fs_dir_close(&dir);

在图像中使用驱动器

Image 对象也可以从文件中打开(除了存储在已编译程序中的变量)。

要在图像小部件中使用文件,需要以下回调函数:

  • 打开

  • 关闭

  • 读取

  • 定位

  • 获取位置

API

Typedefs

typedef uint8_t lv_fs_res_t
typedef uint8_t lv_fs_mode_t
typedef struct _lv_fs_drv_t lv_fs_drv_t

Enums

Errors in the file system module.

Values:

enumerator LV_FS_RES_OK
enumerator LV_FS_RES_HW_ERR
enumerator LV_FS_RES_FS_ERR
enumerator LV_FS_RES_NOT_EX
enumerator LV_FS_RES_FULL
enumerator LV_FS_RES_LOCKED
enumerator LV_FS_RES_DENIED
enumerator LV_FS_RES_BUSY
enumerator LV_FS_RES_TOUT
enumerator LV_FS_RES_NOT_IMP
enumerator LV_FS_RES_OUT_OF_MEM
enumerator LV_FS_RES_INV_PARAM
enumerator LV_FS_RES_UNKNOWN

File open mode.

Values:

enumerator LV_FS_MODE_WR
enumerator LV_FS_MODE_RD
enum lv_fs_whence_t

Seek modes.

Values:

enumerator LV_FS_SEEK_SET

Set the position from absolutely (from the start of file)

enumerator LV_FS_SEEK_CUR

Set the position from the current position

enumerator LV_FS_SEEK_END

Set the position from the end of the file

Functions

void _lv_fs_init(void)

Initialize the File system interface

void lv_fs_drv_init(lv_fs_drv_t *drv)

Initialize a file system driver with default values. It is used to surly have known values in the fields ant not memory junk. After it you can set the fields.

Parameters

drv -- pointer to driver variable to initialize

void lv_fs_drv_register(lv_fs_drv_t *drv)

Add a new drive

Parameters

drv -- pointer to an lv_fs_drv_t structure which is inited with the corresponding function pointers. Only pointer is saved, so the driver should be static or dynamically allocated.

lv_fs_drv_t *lv_fs_get_drv(char letter)

Give a pointer to a driver from its letter

Parameters

letter -- the driver letter

Returns

pointer to a driver or NULL if not found

bool lv_fs_is_ready(char letter)

Test if a drive is ready or not. If the ready function was not initialized true will be returned.

Parameters

letter -- letter of the drive

Returns

true: drive is ready; false: drive is not ready

lv_fs_res_t lv_fs_open(lv_fs_file_t *file_p, const char *path, lv_fs_mode_t mode)

Open a file

Parameters
  • file_p -- pointer to a lv_fs_file_t variable

  • path -- path to the file beginning with the driver letter (e.g. S:/folder/file.txt)

  • mode -- read: FS_MODE_RD, write: FS_MODE_WR, both: FS_MODE_RD | FS_MODE_WR

Returns

LV_FS_RES_OK or any error from lv_fs_res_t enum

lv_fs_res_t lv_fs_close(lv_fs_file_t *file_p)

Close an already opened file

Parameters

file_p -- pointer to a lv_fs_file_t variable

Returns

LV_FS_RES_OK or any error from lv_fs_res_t enum

lv_fs_res_t lv_fs_read(lv_fs_file_t *file_p, void *buf, uint32_t btr, uint32_t *br)

Read from a file

Parameters
  • file_p -- pointer to a lv_fs_file_t variable

  • buf -- pointer to a buffer where the read bytes are stored

  • btr -- Bytes To Read

  • br -- the number of real read bytes (Bytes Read). NULL if unused.

Returns

LV_FS_RES_OK or any error from lv_fs_res_t enum

lv_fs_res_t lv_fs_write(lv_fs_file_t *file_p, const void *buf, uint32_t btw, uint32_t *bw)

Write into a file

Parameters
  • file_p -- pointer to a lv_fs_file_t variable

  • buf -- pointer to a buffer with the bytes to write

  • btw -- Bytes To Write

  • bw -- the number of real written bytes (Bytes Written). NULL if unused.

Returns

LV_FS_RES_OK or any error from lv_fs_res_t enum

lv_fs_res_t lv_fs_seek(lv_fs_file_t *file_p, uint32_t pos, lv_fs_whence_t whence)

Set the position of the 'cursor' (read write pointer) in a file

Parameters
  • file_p -- pointer to a lv_fs_file_t variable

  • pos -- the new position expressed in bytes index (0: start of file)

  • whence -- tells from where set the position. See @lv_fs_whence_t

Returns

LV_FS_RES_OK or any error from lv_fs_res_t enum

lv_fs_res_t lv_fs_tell(lv_fs_file_t *file_p, uint32_t *pos)

Give the position of the read write pointer

Parameters
  • file_p -- pointer to a lv_fs_file_t variable

  • pos_p -- pointer to store the position of the read write pointer

Returns

LV_FS_RES_OK or any error from 'fs_res_t'

lv_fs_res_t lv_fs_dir_open(lv_fs_dir_t *rddir_p, const char *path)

Initialize a 'fs_dir_t' variable for directory reading

Parameters
  • rddir_p -- pointer to a 'lv_fs_dir_t' variable

  • path -- path to a directory

Returns

LV_FS_RES_OK or any error from lv_fs_res_t enum

lv_fs_res_t lv_fs_dir_read(lv_fs_dir_t *rddir_p, char *fn)

Read the next filename form a directory. The name of the directories will begin with '/'

Parameters
  • rddir_p -- pointer to an initialized 'fs_dir_t' variable

  • fn -- pointer to a buffer to store the filename

Returns

LV_FS_RES_OK or any error from lv_fs_res_t enum

lv_fs_res_t lv_fs_dir_close(lv_fs_dir_t *rddir_p)

Close the directory reading

Parameters

rddir_p -- pointer to an initialized 'fs_dir_t' variable

Returns

LV_FS_RES_OK or any error from lv_fs_res_t enum

char *lv_fs_get_letters(char *buf)

Fill a buffer with the letters of existing drivers

Parameters

buf -- buffer to store the letters ('\0' added after the last letter)

Returns

the buffer

const char *lv_fs_get_ext(const char *fn)

Return with the extension of the filename

Parameters

fn -- string with a filename

Returns

pointer to the beginning extension or empty string if no extension

char *lv_fs_up(char *path)

Step up one level

Parameters

path -- pointer to a file name

Returns

the truncated file name

const char *lv_fs_get_last(const char *path)

Get the last element of a path (e.g. U:/folder/file -> file)

Parameters

path -- pointer to a file name

Returns

pointer to the beginning of the last element in the path

struct _lv_fs_drv_t

Public Members

char letter
uint16_t cache_size
bool (*ready_cb)(struct _lv_fs_drv_t *drv)
void *(*open_cb)(struct _lv_fs_drv_t *drv, const char *path, lv_fs_mode_t mode)
lv_fs_res_t (*close_cb)(struct _lv_fs_drv_t *drv, void *file_p)
lv_fs_res_t (*read_cb)(struct _lv_fs_drv_t *drv, void *file_p, void *buf, uint32_t btr, uint32_t *br)
lv_fs_res_t (*write_cb)(struct _lv_fs_drv_t *drv, void *file_p, const void *buf, uint32_t btw, uint32_t *bw)
lv_fs_res_t (*seek_cb)(struct _lv_fs_drv_t *drv, void *file_p, uint32_t pos, lv_fs_whence_t whence)
lv_fs_res_t (*tell_cb)(struct _lv_fs_drv_t *drv, void *file_p, uint32_t *pos_p)
void *(*dir_open_cb)(struct _lv_fs_drv_t *drv, const char *path)
lv_fs_res_t (*dir_read_cb)(struct _lv_fs_drv_t *drv, void *rddir_p, char *fn)
lv_fs_res_t (*dir_close_cb)(struct _lv_fs_drv_t *drv, void *rddir_p)
void *user_data

Custom file user data

struct lv_fs_file_cache_t

Public Members

uint32_t start
uint32_t end
uint32_t file_position
void *buffer
struct lv_fs_file_t

Public Members

void *file_d
lv_fs_drv_t *drv
lv_fs_file_cache_t *cache
struct lv_fs_dir_t

Public Members

void *dir_d
lv_fs_drv_t *drv