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__ */