Description
Im trying to implement Littlev Filesystem with SPIFFS from the esp-idf. I copied the functions from the WIN32 Implementation lv_fs_pc.c and changed some small things, but basically its the same.
What MCU/Processor/Board and compiler are you using?
ESP32
xtensa-esp32-elf-gcc
What do you experience?
I’m trying to draw an image which is flashed in a spiffs image. But after “spiffs_driver_open” is called in “spiffs_driver_read” the file can’t be read, because it’s already at end of file.
What do you expect?
Normally read the file.
Code to reproduce
This is my spiffs implementation.
#include "esp_spi_flash.h"
#include "esp_log.h"
#include "esp_spiffs.h"
#include "lvgl/lvgl.h"
#include "lv_fs.h"
#include "spiffs_driver.h"
/* Create a type to store the required data about your file. */
typedef FILE * file_t;
static const char *TAG = "SPIFFS-DRIVER";
static lv_fs_res_t spiffs_driver_open(struct _lv_fs_drv_t *drv, void *file_p, const char *path, lv_fs_mode_t mode)
{
(void) drv; /*Unused*/
const char * flags = "";
if(mode == LV_FS_MODE_WR) flags = "w";
else if(mode == LV_FS_MODE_RD) flags = "r";
else if(mode == (LV_FS_MODE_WR | LV_FS_MODE_RD)) flags = "rb+";
/*Make the path relative to the current directory (the projects root folder)*/
char complete_path[strlen(path) + 1];
complete_path[0] = '/';
complete_path[1] = '\0';
strcat(complete_path, path);
file_t f = fopen(complete_path, flags);
if(f == NULL) return LV_FS_RES_UNKNOWN;
/*Be sure we are the beginning of the file*/
fseek(f, 0, SEEK_SET);
ESP_LOGI(TAG, "Open eof f %d", feof(f));
/* '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;
ESP_LOGI(TAG, "Open eof file_p %d", feof(file_p));
return LV_FS_RES_OK;
}
static lv_fs_res_t spiffs_driver_read(struct _lv_fs_drv_t *drv, void *file_p, void *buf, uint32_t btr, uint32_t *br)
{
ESP_LOGI(TAG, "Read eof %d", feof(file_p));
(void) drv; /*Unused*/
file_t * fp = file_p; /*Just avoid the confusing casings*/
*br = fread(buf, 1, btr, *fp);
return LV_FS_RES_OK;
}
static lv_fs_res_t spiffs_driver_close(struct _lv_fs_drv_t *drv, void *file_p)
{
(void) drv; /*Unused*/
file_t * fp = file_p; /*Just avoid the confusing casings*/
fclose(*fp);
return LV_FS_RES_OK;
}
static lv_fs_res_t spiffs_driver_seek(struct _lv_fs_drv_t *drv, void *file_p, uint32_t pos)
{
(void) drv; /*Unused*/
file_t * fp = file_p; /*Just avoid the confusing casings*/
fseek(*fp, pos, SEEK_SET);
return LV_FS_RES_OK;
}
static lv_fs_res_t spiffs_driver_tell(struct _lv_fs_drv_t *drv, void *file_p, uint32_t *pos_p)
{
(void) drv; /*Unused*/
file_t * fp = file_p; /*Just avoid the confusing casings*/
*pos_p = ftell(*fp);
return LV_FS_RES_OK;
}
esp_err_t spiffs_driver_init()
{
esp_vfs_spiffs_conf_t conf = {
.base_path = SPIFFS_BASE,
.partition_label = "spiffs",
.max_files = 20,
.format_if_mount_failed = false};
esp_err_t ret = esp_vfs_spiffs_register(&conf);
if (ret != ESP_OK)
{
if (ret == ESP_FAIL)
{
ESP_LOGE(TAG, "Failed to mount or format filesystem");
}
else if (ret == ESP_ERR_NOT_FOUND)
{
ESP_LOGE(TAG, "Failed to find SPIFFS partition");
}
else
{
ESP_LOGE(TAG, "Failed to initialize SPIFFS (%s)", esp_err_to_name(ret));
}
return ESP_FAIL;
}
size_t total = 0, used = 0;
ret = esp_spiffs_info(conf.partition_label, &total, &used);
if (ret != ESP_OK)
{
ESP_LOGE(TAG, "Failed to get SPIFFS partition information (%s)", esp_err_to_name(ret));
}
else
{
ESP_LOGI(TAG, "Partition size: total: %d, used: %d", total, used);
}
lv_fs_drv_t drv;
lv_fs_drv_init(&drv);
drv.letter = 'F';
drv.file_size = sizeof(FILE);
drv.rddir_size = 0; //TODO: maybe not zero
drv.open_cb = spiffs_driver_open;
drv.read_cb = spiffs_driver_read;
drv.close_cb = spiffs_driver_close;
drv.seek_cb = spiffs_driver_seek;
drv.tell_cb = spiffs_driver_tell;
drv.ready_cb = NULL;
drv.trunc_cb = NULL;
drv.size_cb = NULL;
drv.rename_cb = NULL;
drv.write_cb = NULL;
drv.dir_open_cb = NULL;
drv.dir_read_cb = NULL;
drv.dir_close_cb = NULL;
drv.free_space_cb = NULL;
lv_fs_drv_register(&drv);
lv_obj_t* img_obj = lv_img_create(lv_scr_act(), NULL);
lv_img_set_src(img_obj, "F:spiffs/01_shop_device_welcome.jpg");
return ESP_OK;
}
To conform that the spiffs image is working i just read the file without Littlev and it’s working.
FILE* f = fopen("/spiffs/01_shop_device_welcome.jpg", "r");
if (f == NULL) {
ESP_LOGE(TAG, "Failed to open file for reading");
return;
}
fseek (f , 0 , SEEK_END);
long lSize = ftell (f);
rewind (f);
ESP_LOGI(TAG, "Lsize %ld", lSize);
void* buf = (char*) malloc (sizeof(char)*lSize);
int br = fread(buf, 1, lSize, f);
ESP_LOGI(TAG, "Bytes read %d", br);
Screenshot and/or video
Here a screenshot from the monitor. I put some foef between to show the problem.