feat(fs): default drive letter + ESP FS docs (#6367)
Co-authored-by: Gabor Kiss-Vamosi <kisvegabor@gmail.com>
This commit is contained in:
@@ -597,6 +597,9 @@
|
||||
|
||||
/*File system interfaces for common APIs */
|
||||
|
||||
/*Setting a default driver letter allows skipping the driver prefix in filepaths*/
|
||||
#define LV_FS_DEFAULT_DRIVE_LETTER '\0'
|
||||
|
||||
/*API for fopen, fread, etc*/
|
||||
#define LV_USE_FS_STDIO 1
|
||||
#if LV_USE_FS_STDIO
|
||||
|
||||
22
Kconfig
22
Kconfig
@@ -1124,10 +1124,16 @@ menu "LVGL configuration"
|
||||
endmenu
|
||||
|
||||
menu "3rd Party Libraries"
|
||||
config LV_FS_DEFAULT_DRIVE_LETTER
|
||||
int "Default drive letter (e.g. 65 for 'A')"
|
||||
default 0
|
||||
help
|
||||
Setting a default drive letter allows skipping the driver prefix in filepaths
|
||||
|
||||
config LV_USE_FS_STDIO
|
||||
bool "File system on top of stdio API"
|
||||
config LV_FS_STDIO_LETTER
|
||||
int "Set an upper cased letter on which the drive will accessible (e.g. 'A' i.e. 65 )"
|
||||
int "Set an upper cased letter on which the drive will accessible (e.g. 65 for 'A')"
|
||||
default 0
|
||||
depends on LV_USE_FS_STDIO
|
||||
config LV_FS_STDIO_PATH
|
||||
@@ -1141,7 +1147,7 @@ menu "LVGL configuration"
|
||||
config LV_USE_FS_POSIX
|
||||
bool "File system on top of posix API"
|
||||
config LV_FS_POSIX_LETTER
|
||||
int "Set an upper cased letter on which the drive will accessible (e.g. 'A' i.e. 65)"
|
||||
int "Set an upper cased letter on which the drive will accessible (e.g. 65 for 'A')"
|
||||
default 0
|
||||
depends on LV_USE_FS_POSIX
|
||||
config LV_FS_POSIX_PATH
|
||||
@@ -1155,7 +1161,7 @@ menu "LVGL configuration"
|
||||
config LV_USE_FS_WIN32
|
||||
bool "File system on top of Win32 API"
|
||||
config LV_FS_WIN32_LETTER
|
||||
int "Set an upper cased letter on which the drive will accessible (e.g. 'A' i.e. 65)"
|
||||
int "Set an upper cased letter on which the drive will accessible (e.g. 65 for 'A')"
|
||||
default 0
|
||||
depends on LV_USE_FS_WIN32
|
||||
config LV_FS_WIN32_PATH
|
||||
@@ -1169,7 +1175,7 @@ menu "LVGL configuration"
|
||||
config LV_USE_FS_FATFS
|
||||
bool "File system on top of FatFS"
|
||||
config LV_FS_FATFS_LETTER
|
||||
int "Set an upper cased letter on which the drive will accessible (e.g. 'A' i.e. 65)"
|
||||
int "Set an upper cased letter on which the drive will accessible (e.g. 65 for 'A')"
|
||||
default 0
|
||||
depends on LV_USE_FS_FATFS
|
||||
config LV_FS_FATFS_CACHE_SIZE
|
||||
@@ -1180,28 +1186,28 @@ menu "LVGL configuration"
|
||||
config LV_USE_FS_MEMFS
|
||||
bool "File system on top of memory-mapped API"
|
||||
config LV_FS_MEMFS_LETTER
|
||||
int "Set an upper cased letter on which the drive will accessible (e.g. 'A' i.e. 65)"
|
||||
int "Set an upper cased letter on which the drive will accessible (e.g. 65 for 'A')"
|
||||
default 0
|
||||
depends on LV_USE_FS_MEMFS
|
||||
|
||||
config LV_USE_FS_LITTLEFS
|
||||
bool "File system on top of littlefs API"
|
||||
config LV_FS_LITTLEFS_LETTER
|
||||
int "Set an upper cased letter on which the drive will accessible (e.g. 'A' i.e. 65)"
|
||||
int "Set an upper cased letter on which the drive will accessible (e.g. 65 for 'A')"
|
||||
default 0
|
||||
depends on LV_USE_FS_LITTLEFS
|
||||
|
||||
config LV_USE_FS_ARDUINO_ESP_LITTLEFS
|
||||
bool "File system on top of Arduino ESP littlefs API"
|
||||
config LV_FS_ARDUINO_ESP_LITTLEFS_LETTER
|
||||
int "Set an upper cased letter on which the drive will accessible (e.g. 'A' i.e. 65)"
|
||||
int "Set an upper cased letter on which the drive will accessible (e.g. 65 for 'A')"
|
||||
default 0
|
||||
depends on LV_USE_FS_ARDUINO_ESP_LITTLEFS
|
||||
|
||||
config LV_USE_FS_ARDUINO_SD
|
||||
bool "File system on top of Arduino SD API"
|
||||
config LV_FS_ARDUINO_SD_LETTER
|
||||
int "Set an upper cased letter on which the drive will accessible (e.g. 'A' i.e. 65)"
|
||||
int "Set an upper cased letter on which the drive will accessible (e.g. 65 for 'A')"
|
||||
default 0
|
||||
depends on LV_USE_FS_ARDUINO_SD
|
||||
config LV_FS_ARDUINO_SD_CS_PIN
|
||||
|
||||
@@ -78,5 +78,120 @@ These components share a common public API, making it easy to migrate your proje
|
||||
To add a display or touch driver to your project, use a command like:
|
||||
|
||||
.. code:: sh
|
||||
|
||||
idf.py add-dependency "espressif/esp_lcd_gc9a01^2.0.0"
|
||||
|
||||
Using the File System under ESP-IDF
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
ESP-IDF uses the standard C functions (``fopen``, ``fread``) in all storage related APIs.
|
||||
This allows seamless interoperability with LVGL when enabling the :c:macro:`LV_USE_FS_STDIO` configuration.
|
||||
The process is described in details below, using ``SPIFFS`` as demonstration.
|
||||
|
||||
- **Decide what storage system you want to use**
|
||||
|
||||
ESP-IDF has many, ready-to-use examples like
|
||||
`SPIFFS <https://github.com/espressif/esp-idf/tree/master/examples/storage/spiffsgen>`__
|
||||
,
|
||||
`SD Card <https://github.com/espressif/esp-idf/tree/master/examples/storage/sd_card/sdspi>`__
|
||||
and
|
||||
`LittleFS <https://github.com/espressif/esp-idf/tree/master/examples/storage/littlefs>`__
|
||||
.
|
||||
|
||||
- **Re-configure your own project**
|
||||
|
||||
The example project should be examined for details, but in general the changes involve:
|
||||
|
||||
- Enabling LVGL's STDIO file system in the configuration
|
||||
|
||||
You can use ``menuconfig``:
|
||||
|
||||
- ``Component config → LVGL configuration → 3rd Party Libraries``: enable ``File system on top of stdio API``
|
||||
- Then select ``Set an upper cased letter on which the drive will accessible`` and set it to ``65`` (ASCII **A**)
|
||||
- You can also set ``Default driver letter`` to 65 to skip the prefix in file paths.
|
||||
|
||||
- Modifying the partition table
|
||||
|
||||
The exact configuration depends on your flash size and existing partitions,
|
||||
but the new final result should look something like this:
|
||||
|
||||
.. code:: csv
|
||||
|
||||
nvs, data, nvs, 0x9000, 0x6000,
|
||||
phy_init, data, phy, 0xf000, 0x1000,
|
||||
factory, app, factory, 0x10000, 1400k,
|
||||
storage, data, spiffs, , 400k,
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
If you are not using a custom ``parition.csv`` yet, it can be added
|
||||
via ``menuconfig`` (``Partition Table → Partition Table → Custom partition table CSV``).
|
||||
|
||||
- Apply changes to the build system
|
||||
|
||||
Some ESP file systems provide automatic generation from a host folder using CMake. The proper line(s) must be copied to ``main/CMakeLists.txt``
|
||||
|
||||
.. note::
|
||||
|
||||
``LittleFS`` has extra dependencies that should be added to ``main/idf_component.yml``
|
||||
|
||||
- **Prepare the image files**
|
||||
|
||||
LVGL's ``LVGLImage.py`` Python tool can be used to convert images to binary pixel map files.
|
||||
It supports various formats and compression.
|
||||
|
||||
Meanwhile 3rd party libraries
|
||||
(like :ref:`LodePNG<lodepng>` and :ref:`Tiny JPEG<tjpgd>`)
|
||||
allow using image files without conversion.
|
||||
|
||||
After preparing the files, they should be moved to the target device:
|
||||
|
||||
- If properly activated a **SPIFFS** file system based on the ``spiffs_image`` folder should be automatically generated and later flashed to the target
|
||||
- Similar mechanism for **LittleFS** uses the ``flash_data`` folder, but it's only available for Linux hosts
|
||||
- For the **SD Card**, a traditional file browser can be used
|
||||
|
||||
- **Invoke proper API calls in the application code**
|
||||
|
||||
The core functionality requires only a few lines. The following example draws the image as well.
|
||||
|
||||
.. code:: c
|
||||
|
||||
#include "esp_spiffs.h"
|
||||
|
||||
void lv_example_image_from_esp_fs(void) {
|
||||
|
||||
esp_vfs_spiffs_conf_t conf = {
|
||||
.base_path = "/spiffs",
|
||||
.partition_label = NULL,
|
||||
.max_files = 5,
|
||||
.format_if_mount_failed = false
|
||||
};
|
||||
|
||||
esp_err_t ret = esp_vfs_spiffs_register(&conf);
|
||||
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to register SPIFF filesystem");
|
||||
return;
|
||||
}
|
||||
|
||||
lv_obj_t * obj = lv_image_create(lv_screen_active());
|
||||
lv_image_set_src(obj, "A:/spiffs/logo.bin");
|
||||
lv_obj_center(obj);
|
||||
}
|
||||
|
||||
- **Build and flash**
|
||||
|
||||
After calling ``idf.py build flash`` the picture should be displayed on the screen.
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
Changes made by ``menuconfig`` are not being tracked in the repository if the ``sdkconfig`` file is added to ``.gitignore``, which is the default for many ESP-IDF projects.
|
||||
To make your configuration permanent, add the following lines to ``sdkconfig.defaults``:
|
||||
|
||||
.. code:: c
|
||||
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_LV_USE_FS_STDIO=y
|
||||
CONFIG_LV_FS_STDIO_LETTER=65
|
||||
CONFIG_LV_LV_FS_DEFAULT_DRIVE_LETTER=65
|
||||
|
||||
@@ -150,7 +150,7 @@ Get started with the Renesas ecosystem
|
||||
The compiler must be activated in e² studio:
|
||||
|
||||
- Go to go to ``Help`` -> ``Add Renesas Toolchains``
|
||||
- Press the ``Add... `` button
|
||||
- Press the ``Add...`` button
|
||||
- Browse the installation folder of the toolchain
|
||||
|
||||
|
|
||||
|
||||
@@ -16,7 +16,7 @@ Using the simulator on a PC has the following advantages:
|
||||
- Easy Validation: The simulator is also very useful to report bugs because it
|
||||
provides a common platform for every user.
|
||||
- Better developer experience: On PC Debuggers are usually faster and better, you can log to files,
|
||||
add a lot of ``printf``s, do profiling, and so on.
|
||||
add a lot of ``printf``-s, do profiling, and so on.
|
||||
|
||||
|
||||
Select an IDE
|
||||
|
||||
@@ -8,6 +8,7 @@ LittleFS is a little fail-safe filesystem designed for microcontrollers and inte
|
||||
when used with ESP32 and ESP8266.
|
||||
|
||||
Detailed introduction:
|
||||
|
||||
- https://github.com/esp8266/Arduino
|
||||
- https://github.com/espressif/arduino-esp32
|
||||
|
||||
@@ -15,7 +16,7 @@ Detailed introduction:
|
||||
Usage
|
||||
-----
|
||||
|
||||
Enable :c:macro:`LV_USE_FS_ARDUINO_ESP_LITTLEFS` and define a :c:macro`LV_FS_ARDUINO_ESP_LITTLEFS_LETTER` in ``lv_conf.h``.
|
||||
Enable :c:macro:`LV_USE_FS_ARDUINO_ESP_LITTLEFS` and define a :c:macro:`LV_FS_ARDUINO_ESP_LITTLEFS_LETTER` in ``lv_conf.h``.
|
||||
|
||||
|
||||
API
|
||||
@@ -9,13 +9,14 @@ Once an SD memory card is connected to the SPI interface of the Arduino or Genui
|
||||
and read/write on them. You can also move through directories on the SD card..
|
||||
|
||||
Detailed introduction:
|
||||
|
||||
- https://www.arduino.cc/reference/en/libraries/sd/
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
Enable :c:macro:`LV_USE_FS_ARDUINO_SD` and define a :c:macro`LV_FS_ARDUINO_SD_LETTER` in ``lv_conf.h``.
|
||||
Enable :c:macro:`LV_USE_FS_ARDUINO_SD` and define a :c:macro:`LV_FS_ARDUINO_SD_LETTER` in ``lv_conf.h``.
|
||||
You probably need to configure the :c:macro:`LV_FS_ARDUINO_SD_CS_PIN` and :c:macro:`LV_FS_ARDUINO_SD_FREQUENCY` that
|
||||
corresponds to the pin connected and the frequency used by the chip of the SD CARD.
|
||||
|
||||
@@ -30,9 +30,24 @@ In ``lv_conf.h`` enable ``LV_USE_FS_...`` and assign an upper cased
|
||||
letter to ``LV_FS_..._LETTER`` (e.g. ``'S'``). After that you can access
|
||||
files using that driver letter. E.g. ``"S:path/to/file.txt"``.
|
||||
|
||||
The work directory can be set with ``LV_FS_..._PATH``. E.g.
|
||||
Working with common prefixes
|
||||
""""""""""""""""""""""""""""
|
||||
|
||||
A **default driver letter** can be set by ``LV_FS_DEFAULT_DRIVE_LETTER``,
|
||||
which allows skipping the drive prefix in file paths.
|
||||
|
||||
For example if ``LV_FS_DEFAULT_DRIVE_LETTER`` is set the ``'S'`` *"path/to/file.txt"* will mean *"S:path/to/file.txt"*.
|
||||
|
||||
This feature is useful if you have only a single driver and don't want to bother with LVGL's driver layer in the file paths.
|
||||
It also helps to use a unified path with LVGL's file system and normal file systems.
|
||||
The original mechanism is not affected, so a path starting with drive letter will still work.
|
||||
|
||||
The **working directory** can be set with ``LV_FS_..._PATH``. E.g.
|
||||
``"/home/joe/projects/"`` The actual file/directory paths will be
|
||||
appended to it.
|
||||
appended to it, allowing to skip the common part.
|
||||
|
||||
Caching
|
||||
"""""""
|
||||
|
||||
:ref:`Cached reading <overview_file_system_cache>` is also supported if ``LV_FS_..._CACHE_SIZE`` is set to
|
||||
not ``0`` value. :cpp:func:`lv_fs_read` caches this size of data to lower the
|
||||
|
||||
@@ -12,7 +12,7 @@ Detailed introduction: https://github.com/littlefs-project/littlefs
|
||||
Usage
|
||||
-----
|
||||
|
||||
Enable :c:macro:`LV_USE_FS_LITTLEFS` and define a :c:macro`LV_FS_LITTLEFS_LETTER` in ``lv_conf.h``.
|
||||
Enable :c:macro:`LV_USE_FS_LITTLEFS` and define a :c:macro:`LV_FS_LITTLEFS_LETTER` in ``lv_conf.h``.
|
||||
|
||||
When enabled :c:macro:`lv_littlefs_set_handler` can be used to set up a mount point.
|
||||
|
||||
|
||||
@@ -9,6 +9,10 @@ any type of file system. A file system is identified by an assigned
|
||||
drive letter. For example, if an SD card is associated with the letter
|
||||
``'S'``, a file can be reached using ``"S:path/to/file.txt"``.
|
||||
|
||||
.. note::
|
||||
|
||||
If you want to skip the drive prefix from the path, you can use the :c:macro:`LV_FS_DEFAULT_DRIVE_LETTER` config parameter.
|
||||
|
||||
Ready to use drivers
|
||||
********************
|
||||
|
||||
|
||||
@@ -160,7 +160,7 @@ are rendered directly in the frame buffer so they cannot be
|
||||
rotated later. Therefore in direct mode only the whole frame buffer can be rotated.
|
||||
The same is true for :cpp:enumerator:`LV_DISPLAY_RENDER_MODE_FULL`.
|
||||
|
||||
In the case of :cpp:enumerator:`LV_DISPLAY_RENDER_MODE_PARTIAL`the small rendered areas
|
||||
In the case of :cpp:enumerator:`LV_DISPLAY_RENDER_MODE_PARTIAL` the small rendered areas
|
||||
can be rotated on their own before flushing to the frame buffer.
|
||||
|
||||
Color format
|
||||
@@ -246,7 +246,7 @@ Force refreshing
|
||||
----------------
|
||||
|
||||
Normally the invalidated areas (marked for redraw) are rendered in :cpp:func:`lv_timer_handler` in every
|
||||
:cpp:macro:`LV_DEF_REFR_PERIOD`milliseconds. However, by using :cpp:func:`lv_refr_now(display)` you can ask LVGL to
|
||||
:c:macro:`LV_DEF_REFR_PERIOD` milliseconds. However, by using :cpp:func:`lv_refr_now(display)` you can ask LVGL to
|
||||
redraw the invalid areas immediately. The refreshing will happen in :cpp:func:`lv_refr_now` which might take
|
||||
longer time.
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ The rotary sensitivity can be adjusted on 2 levels:
|
||||
|
||||
The final diff is calculated like this:
|
||||
|
||||
``diff_final = diff_in * (indev_sensitivity / 256) + (widget_sensitivity / 256); ``
|
||||
``diff_final = diff_in * (indev_sensitivity / 256) + (widget_sensitivity / 256);``
|
||||
|
||||
For example, if both the indev and widget sensitivity is set to 128 (0.5), the input diff. will be
|
||||
multiplied by 0.25 (divided by 4). The value of the widget will be incremented by this value or
|
||||
|
||||
@@ -41,7 +41,7 @@ To set the source of an image, use :cpp:expr:`lv_image_set_src(img, src)`.
|
||||
To generate a pixel array from a PNG, JPG or BMP image, use the `Online image converter tool <https://lvgl.io/tools/imageconverter>`__
|
||||
and set the converted image with its pointer :cpp:expr:`lv_image_set_src(img1, &converted_img_var)`
|
||||
To make the variable visible in the C file, you need to declare it with
|
||||
:cpp:macro:`LV_IMAGE_DECLARE(converted_img_var)`.
|
||||
:cpp:expr:`LV_IMAGE_DECLARE(converted_img_var)`.
|
||||
|
||||
To use external files, you also need to convert the image files using
|
||||
the online converter tool but now you should select the binary output
|
||||
|
||||
@@ -685,6 +685,9 @@
|
||||
|
||||
/*File system interfaces for common APIs */
|
||||
|
||||
/*Setting a default driver letter allows skipping the driver prefix in filepaths*/
|
||||
#define LV_FS_DEFAULT_DRIVE_LETTER '\0'
|
||||
|
||||
/*API for fopen, fread, etc*/
|
||||
#define LV_USE_FS_STDIO 0
|
||||
#if LV_USE_FS_STDIO
|
||||
|
||||
@@ -4,6 +4,19 @@
|
||||
#include "../../core/lv_global.h"
|
||||
#include "LittleFS.h"
|
||||
|
||||
#if LV_FS_ARDUINO_ESP_LITTLEFS_LETTER == '\0'
|
||||
#error "LV_FS_ARDUINO_ESP_LITTLEFS_LETTER must be set to a valid value"
|
||||
#else
|
||||
#if (LV_FS_ARDUINO_ESP_LITTLEFS_LETTER < 'A') || (LV_FS_ARDUINO_ESP_LITTLEFS_LETTER > 'Z')
|
||||
#if LV_FS_DEFAULT_DRIVE_LETTER != '\0' /*When using default drive letter, strict format (X:) is mandatory*/
|
||||
#error "LV_FS_ARDUINO_ESP_LITTLEFS_LETTER must be an upper case ASCII letter"
|
||||
#else /*Lean rules for backward compatibility*/
|
||||
#warning LV_FS_ARDUINO_ESP_LITTLEFS_LETTER should be an upper case ASCII letter. \
|
||||
Using a slash symbol as drive letter should be replaced with LV_FS_DEFAULT_DRIVE_LETTER mechanism
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef struct ArduinoEspLittleFile {
|
||||
File file;
|
||||
} ArduinoEspLittleFile;
|
||||
@@ -178,4 +191,11 @@ static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p)
|
||||
return (int32_t)(*pos_p) < 0 ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK;
|
||||
}
|
||||
|
||||
#else /*LV_USE_FS_ARDUINO_ESP_LITTLEFS == 0*/
|
||||
|
||||
#if defined(LV_FS_ARDUINO_ESP_LITTLEFS_LETTER) && LV_FS_ARDUINO_ESP_LITTLEFS_LETTER != '\0'
|
||||
#warning "LV_USE_FS_ARDUINO_ESP_LITTLEFS is not enabled but LV_FS_ARDUINO_ESP_LITTLEFS_LETTER is set"
|
||||
#endif
|
||||
|
||||
#endif /*LV_USE_FS_ARDUINO_ESP_LITTLEFS*/
|
||||
|
||||
|
||||
@@ -5,6 +5,19 @@
|
||||
#include <SPI.h>
|
||||
#include "SD.h"
|
||||
|
||||
#if LV_FS_ARDUINO_SD_LETTER == '\0'
|
||||
#error "LV_FS_ARDUINO_SD_LETTER must be set to a valid value"
|
||||
#else
|
||||
#if (LV_FS_ARDUINO_SD_LETTER < 'A') || (LV_FS_ARDUINO_SD_LETTER > 'Z')
|
||||
#if LV_FS_DEFAULT_DRIVE_LETTER != '\0' /*When using default drive letter, strict format (X:) is mandatory*/
|
||||
#error "LV_FS_ARDUINO_SD_LETTER must be an upper case ASCII letter"
|
||||
#else /*Lean rules for backward compatibility*/
|
||||
#warning LV_FS_ARDUINO_SD_LETTER should be an upper case ASCII letter. \
|
||||
Using a slash symbol as drive letter should be replaced with LV_FS_DEFAULT_DRIVE_LETTER mechanism
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef struct SdFile {
|
||||
File file;
|
||||
} SdFile;
|
||||
@@ -184,4 +197,10 @@ static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p)
|
||||
return (int32_t)(*pos_p) < 0 ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK;
|
||||
}
|
||||
|
||||
#else /*LV_USE_FS_ARDUINO_SD == 0*/
|
||||
|
||||
#if defined(LV_FS_ARDUINO_SD_LETTER) && LV_FS_ARDUINO_SD_LETTER != '\0'
|
||||
#warning "LV_USE_FS_ARDUINO_SD is not enabled but LV_FS_ARDUINO_SD_LETTER is set"
|
||||
#endif
|
||||
|
||||
#endif /*LV_USE_FS_ARDUINO_SD*/
|
||||
|
||||
@@ -21,7 +21,16 @@
|
||||
#endif
|
||||
|
||||
#if LV_FS_FATFS_LETTER == '\0'
|
||||
#error "LV_FS_FATFS_LETTER must be an upper case ASCII letter"
|
||||
#error "LV_FS_FATFS_LETTER must be set to a valid value"
|
||||
#else
|
||||
#if (LV_FS_FATFS_LETTER < 'A') || (LV_FS_FATFS_LETTER > 'Z')
|
||||
#if LV_FS_DEFAULT_DRIVE_LETTER != '\0' /*When using default drive letter, strict format (X:) is mandatory*/
|
||||
#error "LV_FS_FATFS_LETTER must be an upper case ASCII letter"
|
||||
#else /*Lean rules for backward compatibility*/
|
||||
#warning LV_FS_FATFS_LETTER should be an upper case ASCII letter. \
|
||||
Using a slash symbol as drive letter should be replaced with LV_FS_DEFAULT_DRIVE_LETTER mechanism
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
|
||||
@@ -4,6 +4,19 @@
|
||||
#include "lfs.h"
|
||||
#include "../../core/lv_global.h"
|
||||
|
||||
#if LV_FS_LITTLEFS_LETTER == '\0'
|
||||
#error "LV_FS_LITTLEFS_LETTER must be set to a valid value"
|
||||
#else
|
||||
#if (LV_FS_LITTLEFS_LETTER < 'A') || (LV_FS_LITTLEFS_LETTER > 'Z')
|
||||
#if LV_FS_DEFAULT_DRIVE_LETTER != '\0' /*When using default drive letter, strict format (X:) is mandatory*/
|
||||
#error "LV_FS_LITTLEFS_LETTER must be an upper case ASCII letter"
|
||||
#else /*Lean rules for backward compatibility*/
|
||||
#warning LV_FS_LITTLEFS_LETTER should be an upper case ASCII letter. \
|
||||
Using a slash symbol as drive letter should be replaced with LV_FS_DEFAULT_DRIVE_LETTER mechanism
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef struct LittleFile {
|
||||
lfs_file_t file;
|
||||
} LittleFile;
|
||||
|
||||
@@ -47,6 +47,18 @@
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#if LV_FS_MEMFS_LETTER == '\0'
|
||||
#error "LV_FS_MEMFS_LETTER must be set to a valid value"
|
||||
#else
|
||||
#if (LV_FS_MEMFS_LETTER < 'A') || (LV_FS_MEMFS_LETTER > 'Z')
|
||||
#if LV_FS_DEFAULT_DRIVE_LETTER != '\0' /*When using default drive letter, strict format (X:) is mandatory*/
|
||||
#error "LV_FS_MEMFS_LETTER must be an upper case ASCII letter"
|
||||
#else /*Lean rules for backward compatibility*/
|
||||
#warning LV_FS_MEMFS_LETTER should be an upper case ASCII letter. \
|
||||
Using a slash symbol as drive letter should be replaced with LV_FS_DEFAULT_DRIVE_LETTER mechanism
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
|
||||
@@ -23,7 +23,16 @@
|
||||
*********************/
|
||||
|
||||
#if LV_FS_POSIX_LETTER == '\0'
|
||||
#error "LV_FS_POSIX_LETTER must be an upper case ASCII letter"
|
||||
#error "LV_FS_POSIX_LETTER must be set to a valid value"
|
||||
#else
|
||||
#if (LV_FS_POSIX_LETTER < 'A') || (LV_FS_POSIX_LETTER > 'Z')
|
||||
#if LV_FS_DEFAULT_DRIVE_LETTER != '\0' /*When using default drive letter, strict format (X:) is mandatory*/
|
||||
#error "LV_FS_POSIX_LETTER must be an upper case ASCII letter"
|
||||
#else /*Lean rules for backward compatibility*/
|
||||
#warning LV_FS_POSIX_LETTER should be an upper case ASCII letter. \
|
||||
Using a slash symbol as drive letter should be replaced with LV_FS_DEFAULT_DRIVE_LETTER mechanism
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/** The reason for 'fd + 1' is because open() may return a legal fd with a value of 0,
|
||||
|
||||
@@ -21,6 +21,19 @@
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#if LV_FS_STDIO_LETTER == '\0'
|
||||
#error "LV_FS_STDIO_LETTER must be set to a valid value"
|
||||
#else
|
||||
#if (LV_FS_STDIO_LETTER < 'A') || (LV_FS_STDIO_LETTER > 'Z')
|
||||
#if LV_FS_DEFAULT_DRIVE_LETTER != '\0' /*When using default drive letter, strict format (X:) is mandatory*/
|
||||
#error "LV_FS_STDIO_LETTER must be an upper case ASCII letter"
|
||||
#else /*Lean rules for backward compatibility*/
|
||||
#warning LV_FS_STDIO_LETTER should be an upper case ASCII letter. \
|
||||
Using a slash symbol as drive letter should be replaced with LV_FS_DEFAULT_DRIVE_LETTER mechanism
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define MAX_PATH_LEN 256
|
||||
|
||||
/**********************
|
||||
|
||||
@@ -17,6 +17,19 @@
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#if LV_FS_WIN32_LETTER == '\0'
|
||||
#error "LV_FS_WIN32_LETTER must be set to a valid value"
|
||||
#else
|
||||
#if (LV_FS_WIN32_LETTER < 'A') || (LV_FS_WIN32_LETTER > 'Z')
|
||||
#if LV_FS_DEFAULT_DRIVE_LETTER != '\0' /*When using default drive letter, strict format (X:) is mandatory*/
|
||||
#error "LV_FS_WIN32_LETTER must be an upper case ASCII letter"
|
||||
#else /*Lean rules for backward compatibility*/
|
||||
#warning LV_FS_WIN32_LETTER should be an upper case ASCII letter. \
|
||||
Using a slash symbol as drive letter should be replaced with LV_FS_DEFAULT_DRIVE_LETTER mechanism
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define MAX_PATH_LEN 256
|
||||
|
||||
/**********************
|
||||
|
||||
@@ -2284,6 +2284,15 @@
|
||||
|
||||
/*File system interfaces for common APIs */
|
||||
|
||||
/*Setting a default driver letter allows skipping the driver prefix in filepaths*/
|
||||
#ifndef LV_FS_DEFAULT_DRIVE_LETTER
|
||||
#ifdef CONFIG_LV_FS_DEFAULT_DRIVE_LETTER
|
||||
#define LV_FS_DEFAULT_DRIVE_LETTER CONFIG_LV_FS_DEFAULT_DRIVE_LETTER
|
||||
#else
|
||||
#define LV_FS_DEFAULT_DRIVE_LETTER '\0'
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*API for fopen, fread, etc*/
|
||||
#ifndef LV_USE_FS_STDIO
|
||||
#ifdef CONFIG_LV_USE_FS_STDIO
|
||||
|
||||
@@ -17,16 +17,25 @@
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#if LV_FS_DEFAULT_DRIVE_LETTER != '\0' && (LV_FS_DEFAULT_DRIVE_LETTER < 'A' || 'Z' < LV_FS_DEFAULT_DRIVE_LETTER)
|
||||
#error "When enabled, LV_FS_DEFAULT_DRIVE_LETTER needs to be a capital ASCII letter (A-Z)"
|
||||
#endif
|
||||
|
||||
#define fsdrv_ll_p &(LV_GLOBAL_DEFAULT()->fsdrv_ll)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
typedef struct {
|
||||
char drive_letter;
|
||||
const char * real_path;
|
||||
} resolved_path_t;
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static const char * lv_fs_get_real_path(const char * path);
|
||||
static resolved_path_t lv_fs_resolve_path(const char * path);
|
||||
static lv_fs_res_t lv_fs_read_cached(lv_fs_file_t * file_p, void * buf, uint32_t btr, uint32_t * br);
|
||||
static lv_fs_res_t lv_fs_write_cached(lv_fs_file_t * file_p, const void * buf, uint32_t btw, uint32_t * bw);
|
||||
static lv_fs_res_t lv_fs_seek_cached(lv_fs_file_t * file_p, uint32_t pos, lv_fs_whence_t whence);
|
||||
@@ -71,8 +80,9 @@ lv_fs_res_t lv_fs_open(lv_fs_file_t * file_p, const char * path, lv_fs_mode_t mo
|
||||
return LV_FS_RES_INV_PARAM;
|
||||
}
|
||||
|
||||
char letter = path[0];
|
||||
lv_fs_drv_t * drv = lv_fs_get_drv(letter);
|
||||
resolved_path_t resolved_path = lv_fs_resolve_path(path);
|
||||
|
||||
lv_fs_drv_t * drv = lv_fs_get_drv(resolved_path.drive_letter);
|
||||
|
||||
if(drv == NULL) {
|
||||
LV_LOG_WARN("Can't open file (%s): unknown driver letter", path);
|
||||
@@ -100,8 +110,7 @@ lv_fs_res_t lv_fs_open(lv_fs_file_t * file_p, const char * path, lv_fs_mode_t mo
|
||||
file_p->file_d = file_p;
|
||||
}
|
||||
else {
|
||||
const char * real_path = lv_fs_get_real_path(path);
|
||||
void * file_d = drv->open_cb(drv, real_path, mode);
|
||||
void * file_d = drv->open_cb(drv, resolved_path.real_path, mode);
|
||||
if(file_d == NULL || file_d == (void *)(-1)) {
|
||||
LV_PROFILER_END;
|
||||
return LV_FS_RES_UNKNOWN;
|
||||
@@ -297,8 +306,9 @@ lv_fs_res_t lv_fs_dir_open(lv_fs_dir_t * rddir_p, const char * path)
|
||||
{
|
||||
if(path == NULL) return LV_FS_RES_INV_PARAM;
|
||||
|
||||
char letter = path[0];
|
||||
lv_fs_drv_t * drv = lv_fs_get_drv(letter);
|
||||
resolved_path_t resolved_path = lv_fs_resolve_path(path);
|
||||
|
||||
lv_fs_drv_t * drv = lv_fs_get_drv(resolved_path.drive_letter);
|
||||
|
||||
if(drv == NULL) {
|
||||
return LV_FS_RES_NOT_EX;
|
||||
@@ -316,8 +326,7 @@ lv_fs_res_t lv_fs_dir_open(lv_fs_dir_t * rddir_p, const char * path)
|
||||
|
||||
LV_PROFILER_BEGIN;
|
||||
|
||||
const char * real_path = lv_fs_get_real_path(path);
|
||||
void * dir_d = drv->dir_open_cb(drv, real_path);
|
||||
void * dir_d = drv->dir_open_cb(drv, resolved_path.real_path);
|
||||
|
||||
if(dir_d == NULL || dir_d == (void *)(-1)) {
|
||||
LV_PROFILER_END;
|
||||
@@ -494,16 +503,36 @@ const char * lv_fs_get_last(const char * path)
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Skip the driver letter and the possible : after the letter
|
||||
* Extract the drive letter and the real path from LVGL's "abstracted file system" path string
|
||||
* @param path path string (E.g. S:/folder/file.txt)
|
||||
* @return pointer to the beginning of the real path (E.g. /folder/file.txt)
|
||||
*/
|
||||
static const char * lv_fs_get_real_path(const char * path)
|
||||
static resolved_path_t lv_fs_resolve_path(const char * path)
|
||||
{
|
||||
path++; /*Ignore the driver letter*/
|
||||
if(*path == ':') path++;
|
||||
resolved_path_t resolved;
|
||||
|
||||
return path;
|
||||
#if LV_FS_DEFAULT_DRIVE_LETTER != '\0' /*When using default drive letter, strict format (X:) is mandatory*/
|
||||
bool has_drive_prefix = ('A' <= path[0]) && (path[0] <= 'Z') && (path[1] == ':');
|
||||
|
||||
if(has_drive_prefix) {
|
||||
resolved.drive_letter = path[0];
|
||||
resolved.real_path = path + 2;
|
||||
}
|
||||
else {
|
||||
resolved.drive_letter = LV_FS_DEFAULT_DRIVE_LETTER;
|
||||
resolved.real_path = path;
|
||||
}
|
||||
# else /*Lean rules for backward compatibility*/
|
||||
resolved.drive_letter = path[0];
|
||||
|
||||
if(*path != '\0') {
|
||||
path++; /*Ignore the driver letter*/
|
||||
if(*path == ':') path++;
|
||||
}
|
||||
|
||||
resolved.real_path = path;
|
||||
#endif
|
||||
|
||||
return resolved;
|
||||
}
|
||||
|
||||
static lv_fs_res_t lv_fs_read_cached(lv_fs_file_t * file_p, void * buf, uint32_t btr, uint32_t * br)
|
||||
|
||||
Reference in New Issue
Block a user