forked from espressif/esp-bsp
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
c90025b
commit f623eed
Showing
47 changed files
with
2,861 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# ChangeLog | ||
|
||
## v0.1.0 Initial Version (2024-07-29) | ||
|
||
* Dependence on esp_mmap_assets to build filesystem for LVGL. | ||
* Supported functions: fopen, fclose, fread, ftell, fseek. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
idf_component_register( | ||
SRCS "esp_lv_fs.c" | ||
INCLUDE_DIRS "include" | ||
) | ||
|
||
include(package_manager) | ||
cu_pkg_define_version(${CMAKE_CURRENT_LIST_DIR}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
[](https://components.espressif.com/components/espressif/esp_lv_fs) | ||
|
||
## Instructions and Details | ||
|
||
`esp_lv_fs` allows LVGL to use filesystems for accessing assets. This component integrates with `esp_mmap_assets` to efficiently manage file operations and supports multiple partitions. | ||
|
||
### Features | ||
- Integrates with `esp_mmap_assets` for filesystem creation. | ||
|
||
- Supports standard file operations: fopen, fclose, fread, ftell, and fseek. | ||
|
||
- Uses the `esp_partition_read` API for efficient file access. | ||
|
||
- Supports multiple partitions. | ||
|
||
## Add to project | ||
|
||
Packages from this repository are uploaded to [Espressif's component service](https://components.espressif.com/). | ||
You can add them to your project via `idf.py add-dependancy`, e.g. | ||
``` | ||
idf.py add-dependency esp_lv_fs | ||
``` | ||
|
||
## Usage | ||
|
||
### Dependencies | ||
The [esp_mmap_assets](https://components.espressif.com/components/espressif/esp_mmap_assets) component is required. It provides file offset index relationship. | ||
|
||
### Initialization | ||
```c | ||
#include "esp_lv_fs.h" | ||
#include "esp_mmap_assets.h" | ||
|
||
esp_lv_fs_handle_t fs_drive_a_handle; | ||
mmap_assets_handle_t mmap_drive_a_handle; | ||
|
||
const mmap_assets_config_t asset_cfg = { | ||
.partition_label = "assets_A", | ||
.max_files = MMAP_DRIVE_A_FILES, | ||
.checksum = MMAP_DRIVE_A_CHECKSUM, | ||
.flags = { | ||
.mmap_enable = true, | ||
} | ||
}; | ||
mmap_assets_new(&asset_cfg, &mmap_drive_a_handle); | ||
|
||
const fs_cfg_t fs_drive_a_cfg = { | ||
.fs_letter = 'A', | ||
.fs_assets = mmap_drive_a_handle, | ||
.fs_nums = MMAP_DRIVE_A_FILES | ||
}; | ||
esp_lv_fs_desc_init(&fs_drive_a_cfg, &fs_drive_a_handle); //Initialize this after lvgl starts | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,272 @@ | ||
/* | ||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include "esp_log.h" | ||
#include "esp_check.h" | ||
#include "esp_lv_fs.h" | ||
|
||
#include "lvgl.h" | ||
#include <string.h> | ||
|
||
static char *TAG = "lv_fs"; | ||
|
||
typedef struct { | ||
const char *name; | ||
const uint8_t *data; // asset_mem | ||
size_t size; // asset_size | ||
} file_descriptor_t; | ||
|
||
typedef struct { | ||
int file_count; | ||
file_descriptor_t **desc; | ||
mmap_assets_handle_t fs_assets; | ||
lv_fs_drv_t *fs_drv; | ||
} file_system_t; | ||
|
||
typedef struct { | ||
int fd; | ||
size_t pos; | ||
bool is_open; // Moved flag to indicate if the file is open | ||
} FILE_t; | ||
|
||
static void *fs_open(lv_fs_drv_t *drv, const char *path, lv_fs_mode_t mode) | ||
{ | ||
LV_UNUSED(drv); | ||
file_system_t *fs = drv->user_data; | ||
|
||
for (int i = 0; i < fs->file_count; i++) { | ||
if (strcmp(fs->desc[i]->name, path) == 0) { | ||
FILE_t *fp = (FILE_t *)malloc(sizeof(FILE_t)); | ||
if (!fp) { | ||
return NULL; | ||
} | ||
fp->is_open = true; | ||
fp->fd = i; | ||
fp->pos = 0; | ||
return (void *)fp; | ||
} | ||
} | ||
|
||
return NULL; // file not found | ||
} | ||
|
||
static lv_fs_res_t fs_close(lv_fs_drv_t *drv, void *file_p) | ||
{ | ||
LV_UNUSED(drv); | ||
file_system_t *fs = drv->user_data; | ||
|
||
FILE_t *fp = (FILE_t *)file_p; | ||
if (!fp || fp->fd < 0 || fp->fd >= fs->file_count) { | ||
return LV_FS_RES_FS_ERR; | ||
} | ||
|
||
fp->is_open = false; | ||
free(fp); | ||
return LV_FS_RES_OK; | ||
} | ||
|
||
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); | ||
file_system_t *fs = drv->user_data; | ||
|
||
FILE_t *fp = (FILE_t *)file_p; | ||
if (!fp || fp->fd < 0 || fp->fd >= fs->file_count || !fp->is_open) { | ||
return LV_FS_RES_FS_ERR; | ||
} | ||
|
||
file_descriptor_t *file = fs->desc[fp->fd]; | ||
if (fp->pos + btr > file->size) { | ||
btr = file->size - fp->pos; | ||
} | ||
|
||
mmap_assets_copy_mem(fs->fs_assets, (size_t)(file->data + fp->pos), buf, btr); | ||
fp->pos += btr; | ||
*br = btr; | ||
return LV_FS_RES_OK; | ||
} | ||
|
||
static lv_fs_res_t fs_write(lv_fs_drv_t *drv, void *file_p, const void *buf, uint32_t btw, uint32_t *bw) | ||
{ | ||
LV_UNUSED(drv); | ||
file_system_t *fs = drv->user_data; | ||
|
||
FILE_t *fp = (FILE_t *)file_p; | ||
if (!fp || fp->fd < 0 || fp->fd >= fs->file_count || !fp->is_open) { | ||
return LV_FS_RES_FS_ERR; | ||
} | ||
|
||
return LV_FS_RES_DENIED; | ||
} | ||
|
||
static lv_fs_res_t fs_seek(lv_fs_drv_t *drv, void *file_p, uint32_t pos, lv_fs_whence_t whence) | ||
{ | ||
LV_UNUSED(drv); | ||
file_system_t *fs = drv->user_data; | ||
|
||
FILE_t *fp = (FILE_t *)file_p; | ||
if (!fp || fp->fd < 0 || fp->fd >= fs->file_count || !fp->is_open) { | ||
return LV_FS_RES_FS_ERR; | ||
} | ||
|
||
file_descriptor_t *file = fs->desc[fp->fd]; | ||
size_t new_pos; | ||
switch (whence) { | ||
case LV_FS_SEEK_SET: | ||
new_pos = pos; | ||
break; | ||
case LV_FS_SEEK_CUR: | ||
new_pos = fp->pos + pos; | ||
break; | ||
case LV_FS_SEEK_END: | ||
new_pos = file->size + pos; | ||
break; | ||
default: | ||
return LV_FS_RES_INV_PARAM; | ||
} | ||
|
||
if (new_pos > file->size) { | ||
new_pos = file->size; | ||
} | ||
fp->pos = new_pos; | ||
return LV_FS_RES_OK; | ||
} | ||
|
||
static lv_fs_res_t fs_tell(lv_fs_drv_t *drv, void *file_p, uint32_t *pos_p) | ||
{ | ||
LV_UNUSED(drv); | ||
file_system_t *fs = drv->user_data; | ||
|
||
FILE_t *fp = (FILE_t *)file_p; | ||
if (!fp || fp->fd < 0 || fp->fd >= fs->file_count || !fp->is_open) { | ||
return LV_FS_RES_FS_ERR; | ||
} | ||
|
||
*pos_p = fp->pos; | ||
return LV_FS_RES_OK; | ||
} | ||
|
||
static void *fs_dir_open(lv_fs_drv_t *drv, const char *path) | ||
{ | ||
LV_UNUSED(drv); | ||
// Return an error indicating that write operations are not supported | ||
return NULL; | ||
} | ||
|
||
static lv_fs_res_t fs_dir_read(lv_fs_drv_t *drv, void *dir_p, char *fn, uint32_t fn_len) | ||
// static lv_fs_res_t fs_dir_read(lv_fs_drv_t *drv, void *dir_p, char *fn) | ||
{ | ||
LV_UNUSED(drv); | ||
// Return an error indicating that write operations are not supported | ||
return LV_FS_RES_DENIED; | ||
} | ||
|
||
static lv_fs_res_t fs_dir_close(lv_fs_drv_t *drv, void *dir_p) | ||
{ | ||
LV_UNUSED(drv); | ||
// Return an error indicating that write operations are not supported | ||
return LV_FS_RES_DENIED; | ||
} | ||
|
||
/** | ||
* Register a driver for the File system interface | ||
*/ | ||
static void lv_fs_flash_init(char fs_letter, file_system_t *handle) | ||
{ | ||
/*--------------------------------------------------- | ||
* Register the file system interface in LVGL | ||
*--------------------------------------------------*/ | ||
|
||
/*Add a simple drive to open images*/ | ||
lv_fs_drv_init(handle->fs_drv); | ||
|
||
/*Set up fields...*/ | ||
handle->fs_drv->letter = fs_letter; | ||
|
||
handle->fs_drv->open_cb = fs_open; | ||
handle->fs_drv->close_cb = fs_close; | ||
handle->fs_drv->read_cb = fs_read; | ||
handle->fs_drv->write_cb = fs_write; | ||
handle->fs_drv->seek_cb = fs_seek; | ||
handle->fs_drv->tell_cb = fs_tell; | ||
|
||
handle->fs_drv->dir_open_cb = fs_dir_open; | ||
handle->fs_drv->dir_read_cb = fs_dir_read; | ||
handle->fs_drv->dir_close_cb = fs_dir_close; | ||
|
||
#if LVGL_VERSION_MAJOR >= 9 || LV_USE_USER_DATA | ||
handle->fs_drv->user_data = handle; | ||
#else | ||
#error "LV_USE_USER_DATA is disabled. Please enable it in lv_conf.h" | ||
#endif | ||
lv_fs_drv_register(handle->fs_drv); | ||
} | ||
|
||
esp_err_t esp_lv_fs_desc_deinit(esp_lv_fs_handle_t handle) | ||
{ | ||
ESP_RETURN_ON_FALSE(handle, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); | ||
|
||
file_system_t *fs = (file_system_t *)handle; | ||
|
||
if (fs->fs_drv) {//fs_drv can't be deleted, you can just delete them all | ||
free(fs->fs_drv); | ||
} | ||
|
||
for (int i = 0; i < fs->file_count; i++) { | ||
free(fs->desc[i]); | ||
} | ||
if (fs->desc) { | ||
free(fs->desc); | ||
} | ||
|
||
free(fs); | ||
|
||
return ESP_OK; | ||
} | ||
|
||
esp_err_t esp_lv_fs_desc_init(const fs_cfg_t *cfg, esp_lv_fs_handle_t *ret_handle) | ||
{ | ||
esp_err_t ret = ESP_OK; | ||
|
||
ESP_RETURN_ON_FALSE(cfg && ret_handle && cfg->fs_nums && cfg->fs_assets, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); | ||
|
||
file_system_t *fs = (file_system_t *)calloc(1, sizeof(file_system_t)); | ||
ESP_GOTO_ON_FALSE(fs, ESP_ERR_NO_MEM, err, TAG, "no mem for fs handle"); | ||
|
||
fs->desc = (file_descriptor_t **)calloc(1, cfg->fs_nums * sizeof(file_descriptor_t *)); | ||
ESP_GOTO_ON_FALSE(fs, ESP_ERR_NO_MEM, err, TAG, "no mem for desc list"); | ||
|
||
fs->fs_assets = cfg->fs_assets; | ||
fs->file_count = 0; | ||
|
||
for (int i = 0; i < cfg->fs_nums; i++) { | ||
fs->desc[i] = (file_descriptor_t *)calloc(1, sizeof(file_descriptor_t)); | ||
ESP_GOTO_ON_FALSE(fs, ESP_ERR_NO_MEM, err, TAG, "no mem for file descriptor"); | ||
|
||
fs->desc[i]->name = mmap_assets_get_name(fs->fs_assets, i); | ||
fs->desc[i]->data = mmap_assets_get_mem(fs->fs_assets, i); | ||
fs->desc[i]->size = mmap_assets_get_size(fs->fs_assets, i); | ||
|
||
fs->file_count++; | ||
} | ||
|
||
fs->fs_drv = (lv_fs_drv_t *)calloc(1, sizeof(lv_fs_drv_t)); | ||
ESP_GOTO_ON_FALSE(fs->fs_drv, ESP_ERR_NO_MEM, err, TAG, "no mem for fs_drv"); | ||
|
||
lv_fs_flash_init(cfg->fs_letter, fs); | ||
|
||
*ret_handle = (esp_lv_fs_handle_t)fs; | ||
ESP_LOGD(TAG, "new fs handle:@%p", fs); | ||
|
||
ESP_LOGI(TAG, "Drive '%c' successfully created, version: %d.%d.%d", | ||
cfg->fs_letter, ESP_LV_FS_VER_MAJOR, ESP_LV_FS_VER_MINOR, ESP_LV_FS_VER_PATCH); | ||
|
||
return ret; | ||
|
||
err: | ||
esp_lv_fs_desc_deinit((esp_lv_fs_handle_t)fs); | ||
return ret; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
version: "0.1.0" | ||
targets: | ||
- esp32 | ||
- esp32c2 | ||
- esp32c3 | ||
- esp32c6 | ||
- esp32h2 | ||
- esp32s2 | ||
- esp32s3 | ||
description: File system for LVGL, supports reading files directly from flash. | ||
url: https://github.com/espressif/esp-iot-solution/tree/master/components/display/tools/esp_lv_fs | ||
issues: https://github.com/espressif/esp-iot-solution/issues | ||
repository: https://github.com/espressif/esp-iot-solution.git | ||
documentation: https://docs.espressif.com/projects/esp-iot-solution/en/latest/display/tools/esp_lv_fs.html | ||
dependencies: | ||
idf: ">=4.4" | ||
lvgl/lvgl: | ||
version: ">=8,<10" | ||
esp_mmap_assets: | ||
version: ">=1.2" | ||
override_path: "../esp_mmap_assets" | ||
cmake_utilities: "0.*" | ||
examples: | ||
- path: ../../../../examples/hmi/perf_benchmark |
Oops, something went wrong.