You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2021/01/03 14:04:44 UTC
[incubator-nuttx-apps] branch master updated: lvgl: Add file system
interface.
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx-apps.git
The following commit(s) were added to refs/heads/master by this push:
new 1b5b8c5 lvgl: Add file system interface.
1b5b8c5 is described below
commit 1b5b8c51674dde7e68803bcc27689d9146500b2a
Author: pengyiqiang <pe...@xiaomi.com>
AuthorDate: Tue Dec 22 19:35:11 2020 +0800
lvgl: Add file system interface.
N/A
Change-Id: Iae291f0250284ef7fe8af60e02f66c326b54d979
Signed-off-by: pengyiqiang <pe...@xiaomi.com>
---
graphics/lvgl/Kconfig | 8 +
graphics/lvgl/Makefile | 4 +
graphics/lvgl/lv_fs_interface.c | 575 ++++++++++++++++++++++++++++++++++++++++
graphics/lvgl/lv_fs_interface.h | 66 +++++
4 files changed, 653 insertions(+)
diff --git a/graphics/lvgl/Kconfig b/graphics/lvgl/Kconfig
index 993a40e..7fc211a 100644
--- a/graphics/lvgl/Kconfig
+++ b/graphics/lvgl/Kconfig
@@ -162,6 +162,14 @@ config USE_LV_FILESYSTEM
bool "Enable filesystem (required for images, lv_img)"
default y
+if USE_LV_FILESYSTEM
+
+config LV_FILESYSTEM_MOUNTPOINT
+ string "File system mount point"
+ default "/data"
+
+endif
+
config USE_LV_MULTI_LANG
int "Number of languages for labels to store (0 to disable)"
default 0
diff --git a/graphics/lvgl/Makefile b/graphics/lvgl/Makefile
index fc40619..502feec 100644
--- a/graphics/lvgl/Makefile
+++ b/graphics/lvgl/Makefile
@@ -57,6 +57,10 @@ CFLAGS += -Wno-format
CSRCS += lv_tick_interface.c
+ifneq ($(CONFIG_USE_LV_FILESYSTEM),)
+CSRCS += lv_fs_interface.c
+endif
+
# Set up build configuration and environment
WD := ${shell echo $(CURDIR) | sed -e 's/ /\\ /g'}
diff --git a/graphics/lvgl/lv_fs_interface.c b/graphics/lvgl/lv_fs_interface.c
new file mode 100644
index 0000000..5256b66
--- /dev/null
+++ b/graphics/lvgl/lv_fs_interface.c
@@ -0,0 +1,575 @@
+/****************************************************************************
+ * graphics/lvgl/lv_fs_interface.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <fcntl.h>
+#include <errno.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/statfs.h>
+#include "lv_fs_interface.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define LV_FS_LETTER '/'
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/* Create a type to store the required data about your file. */
+
+typedef int file_t;
+
+/* Similarly to `file_t` create a type for directory reading too */
+
+typedef DIR *dir_t;
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static lv_fs_res_t fs_open(lv_fs_drv_t *drv, void *file_p,
+ 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_write(lv_fs_drv_t *drv, void *file_p,
+ const void *buf, uint32_t btw, uint32_t *bw);
+static lv_fs_res_t fs_seek(lv_fs_drv_t *drv, void *file_p,
+ uint32_t pos);
+static lv_fs_res_t fs_size(lv_fs_drv_t *drv, void *file_p,
+ uint32_t *size_p);
+static lv_fs_res_t fs_tell(lv_fs_drv_t *drv, void *file_p,
+ uint32_t *pos_p);
+static lv_fs_res_t fs_remove(lv_fs_drv_t *drv, const char *path);
+static lv_fs_res_t fs_trunc(lv_fs_drv_t *drv, void *file_p);
+static lv_fs_res_t fs_rename(lv_fs_drv_t *drv, const char *oldname,
+ const char *newname);
+static lv_fs_res_t fs_free(lv_fs_drv_t *drv, uint32_t *total_p,
+ uint32_t *free_p);
+static lv_fs_res_t fs_dir_open(lv_fs_drv_t *drv, void *dir_p,
+ const char *path);
+static lv_fs_res_t fs_dir_read(lv_fs_drv_t *drv, void *dir_p, char *fn);
+static lv_fs_res_t fs_dir_close(lv_fs_drv_t *drv, void *dir_p);
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: fs_open
+ *
+ * Description:
+ * Open a file.
+ *
+ * Input Parameters:
+ * drv - pointer to a driver where this function belongs.
+ * file_p - pointer to a file_t variable.
+ * path - path to the file beginning with the driver letter.
+ * (e.g. /folder/file.txt)
+ * mode - read: FS_MODE_RD, write: FS_MODE_WR,
+ * both: FS_MODE_RD | FS_MODE_WR
+ *
+ * Returned Value:
+ * LV_FS_RES_OK or any error from lv_fs_res_t enum.
+ *
+ ****************************************************************************/
+
+static lv_fs_res_t fs_open(lv_fs_drv_t *drv, void *file_p,
+ const char *path, lv_fs_mode_t mode)
+{
+ uint32_t flags = 0;
+ if (mode == LV_FS_MODE_WR)
+ {
+ flags = O_WRONLY | O_CREAT;
+ }
+ else if (mode == LV_FS_MODE_RD)
+ {
+ flags = O_RDONLY;
+ }
+ else if (mode == (LV_FS_MODE_WR | LV_FS_MODE_RD))
+ {
+ flags = O_RDWR | O_CREAT;
+ }
+ else
+ {
+ return LV_FS_RES_UNKNOWN;
+ }
+
+ file_t f = open(--path, flags);
+ if (f < 0)
+ {
+ return LV_FS_RES_FS_ERR;
+ }
+
+ /* 'file_p' is pointer to a file descriptor and
+ * we need to store our file descriptor here
+ */
+
+ file_t *fp = file_p; /* Just avoid the confusing casings */
+ *fp = f;
+
+ return LV_FS_RES_OK;
+}
+
+/****************************************************************************
+ * Name: fs_close
+ *
+ * Description:
+ * Close an opened file.
+ *
+ * Input Parameters:
+ * drv - pointer to a driver where this function belongs.
+ * file_p - pointer to a file_t variable.
+ *
+ * Returned Value:
+ * 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)
+{
+ /* Just avoid the confusing casings */
+
+ file_t *fp = file_p;
+
+ return close(*fp) < 0 ? LV_FS_RES_FS_ERR : LV_FS_RES_OK;
+}
+
+/****************************************************************************
+ * Name: fs_read
+ *
+ * Description:
+ * Read data from an opened file.
+ *
+ * Input Parameters:
+ * drv - pointer to a driver where this function belongs.
+ * file_p - pointer to a file_t variable.
+ * buf - pointer to a memory block where to store the read data.
+ * btr - number of Bytes To Read.
+ * br - the real number of read bytes (Byte Read).
+ *
+ * Returned Value:
+ * 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)
+{
+ /* Just avoid the confusing casings */
+
+ file_t *fp = file_p;
+
+ *br = read(*fp, buf, btr);
+
+ return (int32_t)*br < 0 ? LV_FS_RES_FS_ERR : LV_FS_RES_OK;
+}
+
+/****************************************************************************
+ * Name: fs_write
+ *
+ * Description:
+ * Write into a file.
+ *
+ * Input Parameters:
+ * drv - pointer to a driver where this function belongs.
+ * file_p - pointer to a 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.
+ *
+ * Returned Value:
+ * LV_FS_RES_OK or any error from lv_fs_res_t enum.
+ *
+ ****************************************************************************/
+
+static lv_fs_res_t fs_write(lv_fs_drv_t *drv, void *file_p,
+ const void *buf, uint32_t btw, uint32_t *bw)
+{
+ /* Just avoid the confusing casings */
+
+ file_t *fp = file_p;
+
+ *bw = write(*fp, buf, btw);
+
+ return (int32_t)*bw < 0 ? LV_FS_RES_FS_ERR : LV_FS_RES_OK;
+}
+
+/****************************************************************************
+ * Name: fs_seek
+ *
+ * Description:
+ * Set the read write pointer. Also expand the file size if necessary.
+ *
+ * Input Parameters:
+ * drv - pointer to a driver where this function belongs.
+ * file_p - pointer to a file_t variable.
+ * pos - the new position of read write pointer.
+ *
+ * Returned Value:
+ * 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)
+{
+ /* Just avoid the confusing casings */
+
+ file_t *fp = file_p;
+
+ off_t offset = lseek(*fp, pos, SEEK_SET);
+
+ return offset < 0 ? LV_FS_RES_FS_ERR : LV_FS_RES_OK;
+}
+
+/****************************************************************************
+ * Name: fs_size
+ *
+ * Description:
+ * Give the size of a file bytes.
+ *
+ * Input Parameters:
+ * drv - pointer to a driver where this function belongs.
+ * file_p - pointer to a file_t variable.
+ * size - pointer to a variable to store the size.
+ *
+ * Returned Value:
+ * LV_FS_RES_OK or any error from lv_fs_res_t enum.
+ *
+ ****************************************************************************/
+
+static lv_fs_res_t fs_size(lv_fs_drv_t *drv, void *file_p,
+ uint32_t *size_p)
+{
+ /* Just avoid the confusing casings */
+
+ file_t *fp = file_p;
+
+ off_t cur = lseek(*fp, 0, SEEK_CUR);
+
+ *size_p = lseek(*fp, 0L, SEEK_END);
+
+ /* Restore file pointer */
+
+ lseek(*fp, cur, SEEK_SET);
+
+ return (int32_t)*size_p < 0 ? LV_FS_RES_FS_ERR : LV_FS_RES_OK;
+}
+
+/****************************************************************************
+ * Name: fs_tell
+ *
+ * Description:
+ * Give the position of the read write pointer.
+ *
+ * Input Parameters:
+ * drv - pointer to a driver where this function belongs.
+ * file_p - pointer to a file_t variable.
+ * pos_p - pointer to to store the result.
+ *
+ * Returned Value:
+ * 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)
+{
+ /* Just avoid the confusing casings */
+
+ file_t *fp = file_p;
+
+ *pos_p = lseek(*fp, 0, SEEK_CUR);
+
+ return (int32_t)*pos_p < 0 ? LV_FS_RES_FS_ERR : LV_FS_RES_OK;
+}
+
+/****************************************************************************
+ * Name: fs_remove
+ *
+ * Description:
+ * Delete a file.
+ *
+ * Input Parameters:
+ * drv - pointer to a driver where this function belongs.
+ * path - path of the file to delete.
+ *
+ * Returned Value:
+ * LV_FS_RES_OK or any error from lv_fs_res_t enum.
+ *
+ ****************************************************************************/
+
+static lv_fs_res_t fs_remove(lv_fs_drv_t *drv, const char *path)
+{
+ return remove(--path) < 0 ? LV_FS_RES_FS_ERR : LV_FS_RES_OK;
+}
+
+/****************************************************************************
+ * Name: fs_trunc
+ *
+ * Description:
+ * Truncate the file size to the current position of
+ * the read write pointer.
+ *
+ * Input Parameters:
+ * drv - pointer to a driver where this function belongs.
+ * file_p - pointer to a file_t variable.
+ *
+ * Returned Value:
+ * LV_FS_RES_OK or any error from lv_fs_res_t enum.
+ *
+ ****************************************************************************/
+
+static lv_fs_res_t fs_trunc(lv_fs_drv_t *drv, void *file_p)
+{
+ /* Just avoid the confusing casings */
+
+ file_t *fp = file_p;
+
+ off_t p = lseek(*fp, 0, SEEK_CUR);
+
+ return ftruncate(*fp, p) < 0 ? LV_FS_RES_FS_ERR : LV_FS_RES_OK;
+}
+
+/****************************************************************************
+ * Name: fs_rename
+ *
+ * Description:
+ * Rename a file.
+ *
+ * Input Parameters:
+ * drv - pointer to a driver where this function belongs.
+ * oldname - path to the file.
+ * newname - path with the new name
+ *
+ * Returned Value:
+ * LV_FS_RES_OK or any error from lv_fs_res_t enum.
+ *
+ ****************************************************************************/
+
+static lv_fs_res_t fs_rename(lv_fs_drv_t *drv, const char *oldname,
+ const char *newname)
+{
+ return rename(--oldname, --newname) < 0 ? LV_FS_RES_FS_ERR : LV_FS_RES_OK;
+}
+
+/****************************************************************************
+ * Name: fs_free
+ *
+ * Description:
+ * Get the free and total size of a driver in kB.
+ *
+ * Input Parameters:
+ * drv - pointer to a driver where this function belongs.
+ * total_p - pointer to store the total size [kB].
+ * free_p - pointer to store the free size [kB]
+ *
+ * Returned Value:
+ * LV_FS_RES_OK or any error from lv_fs_res_t enum.
+ *
+ ****************************************************************************/
+
+static lv_fs_res_t fs_free(lv_fs_drv_t *drv, uint32_t *total_p,
+ uint32_t *free_p)
+{
+ struct statfs sfs;
+
+ if (statfs(CONFIG_LV_FILESYSTEM_MOUNTPOINT, &sfs) < 0)
+ {
+ return LV_FS_RES_FS_ERR;
+ }
+ else
+ {
+ *total_p = sfs.f_blocks * sfs.f_bsize / 1024;
+ *free_p = sfs.f_bfree * sfs.f_bsize / 1024;
+ return LV_FS_RES_OK;
+ }
+}
+
+/****************************************************************************
+ * Name: fs_dir_open
+ *
+ * Description:
+ * Initialize a 'fs_read_dir_t' variable for directory reading.
+ *
+ * Input Parameters:
+ * drv - pointer to a driver where this function belongs.
+ * dir_p - pointer to a 'fs_read_dir_t' variable.
+ * path - path to a directory.
+ *
+ * Returned Value:
+ * LV_FS_RES_OK or any error from lv_fs_res_t enum.
+ *
+ ****************************************************************************/
+
+static lv_fs_res_t fs_dir_open(lv_fs_drv_t *drv, void *dir_p,
+ const char *path)
+{
+ dir_t d;
+
+ /* Make the path relative to the current directory
+ * (the projects root folder)
+ */
+
+ if ((d = opendir(--path)) == NULL)
+ {
+ return LV_FS_RES_FS_ERR;
+ }
+ else
+ {
+ /* 'dir_p' is pointer to a file descriptor and
+ * we need to store our file descriptor here
+ */
+
+ /* Just avoid the confusing casings */
+
+ dir_t *dp = dir_p;
+ *dp = d;
+ }
+
+ return LV_FS_RES_OK;
+}
+
+/****************************************************************************
+ * Name: fs_dir_read
+ *
+ * Description:
+ * Read the next filename form a directory.
+ * The name of the directories will begin with '/'.
+ *
+ * Input Parameters:
+ * drv - pointer to a driver where this function belongs.
+ * dir_p - pointer to an initialized 'fs_read_dir_t' variable.
+ * fn - pointer to a buffer to store the filename.
+ *
+ * Returned Value:
+ * LV_FS_RES_OK or any error from lv_fs_res_t enum.
+ *
+ ****************************************************************************/
+
+static lv_fs_res_t fs_dir_read(lv_fs_drv_t *drv, void *dir_p, char *fn)
+{
+ /* Just avoid the confusing casings */
+
+ dir_t *dp = dir_p;
+
+ do
+ {
+ struct dirent *entry = readdir(*dp);
+
+ if (entry)
+ {
+ if (entry->d_type == DT_DIR)
+ {
+ sprintf(fn, "/%s", entry->d_name);
+ }
+ else
+ {
+ strcpy(fn, entry->d_name);
+ }
+ }
+ else
+ {
+ strcpy(fn, "");
+ }
+ }
+ while (strcmp(fn, "/.") == 0 || strcmp(fn, "/..") == 0);
+
+ return LV_FS_RES_OK;
+}
+
+/****************************************************************************
+ * Name: fs_dir_read
+ *
+ * Description:
+ * Close the directory reading.
+ *
+ * Input Parameters:
+ * drv - pointer to a driver where this function belongs.
+ * dir_p - pointer to an initialized 'fs_read_dir_t' variable.
+ *
+ * Returned Value:
+ * LV_FS_RES_OK or any error from lv_fs_res_t enum.
+ *
+ ****************************************************************************/
+
+static lv_fs_res_t fs_dir_close(lv_fs_drv_t *drv, void *dir_p)
+{
+ dir_t *dp = dir_p;
+
+ return closedir(*dp) < 0 ? LV_FS_RES_FS_ERR : LV_FS_RES_OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: lv_fs_interface_init
+ *
+ * Description:
+ * Register a driver for the File system interface.
+ *
+ ****************************************************************************/
+
+void lv_fs_interface_init(void)
+{
+ /* Add a simple drive to open images */
+
+ lv_fs_drv_t fs_drv; /* A driver descriptor */
+
+ lv_fs_drv_init(&fs_drv);
+
+ /* Set up fields... */
+
+ fs_drv.file_size = sizeof(file_t);
+ fs_drv.letter = LV_FS_LETTER;
+ fs_drv.open_cb = fs_open;
+ fs_drv.close_cb = fs_close;
+ fs_drv.read_cb = fs_read;
+ fs_drv.write_cb = fs_write;
+ fs_drv.seek_cb = fs_seek;
+ fs_drv.tell_cb = fs_tell;
+ fs_drv.free_space_cb = fs_free;
+ fs_drv.size_cb = fs_size;
+ fs_drv.remove_cb = fs_remove;
+ fs_drv.rename_cb = fs_rename;
+ fs_drv.trunc_cb = fs_trunc;
+
+ fs_drv.rddir_size = sizeof(dir_t);
+ fs_drv.dir_close_cb = fs_dir_close;
+ fs_drv.dir_open_cb = fs_dir_open;
+ fs_drv.dir_read_cb = fs_dir_read;
+
+ lv_fs_drv_register(&fs_drv);
+}
diff --git a/graphics/lvgl/lv_fs_interface.h b/graphics/lvgl/lv_fs_interface.h
new file mode 100644
index 0000000..42dea4d
--- /dev/null
+++ b/graphics/lvgl/lv_fs_interface.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+ * graphics/lvgl/lv_fs_interface.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __LV_FS_INTERFACE_H__
+#define __LV_FS_INTERFACE_H__
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <lvgl/lvgl.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#if LV_USE_FILESYSTEM
+
+/****************************************************************************
+ * Type Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+void lv_fs_interface_init(void);
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LV_USE_FILESYSTEM */
+
+#endif /* __LV_FS_INTERFACE_H__ */