ESP32-S3 IDF V5.4.1 LVGL 9.2.0 fatfs

为什么要使用fatfs

  1. 如果将图片等资源编译进入代码,则代码存储空间的占用则会较大
  2. 加载图像资源(如 JPG/PNG/BMP)
    (1) LVGL 可以从 SD 卡等存储中加载图片资源,而不是编译进固件中,节省内存。
    (2) 使用 lv_img_set_src() 时可以传入文件路径,如:lv_img_set_src(img, "S:/cat.jpg");
  3. 读取字体文件:
    (1) 支持从外部文件系统加载 .bin 或 .lv_font_t 格式的字体,而不是将字体嵌入代码中。
  4. 主题/界面配置的动态读取:
    (1) 从配置文件中读取界面布局、颜色、参数等,便于 OTA 更新或热更新界面资源。
  5. 文件浏览器组件:
    (1) 使用 LVGL 的文件浏览器组件(如 file explorer demo)时需要读取目录、文件信息等。

partition table

partitions-16MiB.csv

生成fatfs的bin文件

CMakeLists.txt

shell 复制代码
set(image ../fatfs_image)

if(CONFIG_EXAMPLE_FATFS_MODE_READ_ONLY)
    fatfs_create_rawflash_image(vfs ${image} FLASH_IN_PROJECT PRESERVE_TIME)
else()
    fatfs_create_spiflash_image(vfs ${image} FLASH_IN_PROJECT PRESERVE_TIME)
endif()

建立fatfs_image文件夹

编译之后,就能够看到生成了fastfs的bin文件

vfs-flash_args则是包含烧录的参数

shell 复制代码
--flash_mode dio --flash_freq 80m --flash_size 16MB
0x3f0000 vfs.bin

初始化fatfs

c 复制代码
err = esp_vfs_fat_spiflash_mount_ro(base_path, "vfs", &mount_config);
if (err != ESP_OK) {
   ESP_LOGE(TAG, "Failed to mount FATFS (%s)", esp_err_to_name(err));
   return;
 } else {
   ESP_LOGI(TAG, "FATFS mounted successfully");
 }

📌 参数解释

base_path: 挂载点路径,比如 "/spiflash",挂载后文件路径是 /spiflash/xxx.txt。

"vfs": 分区标签,必须是 partitions.csv 中定义的分区名。

&mount_config: esp_vfs_fat_mount_config_t 类型,配置文件系统挂载行为(例如是否格式化等)。

🧠 函数用途

这个函数的作用是:

✅ 将 SPI Flash 中的 FAT 文件系统挂载为只读

将提前烧录好数据文件(图片、字库、配置等)到 SPI Flash 的情况。

比如你将 .bin 字库或 .jpg 图片打包成 FAT 镜像写入 SPI Flash,然后用 LVGL+FatFS 动态加载。

LVGL 配置

配置fs_open

需要将路径,在前面加上fatfs文件系统挂载点的路径。

c 复制代码
/**
 * Open a file
 * @param drv   pointer to a driver where this function belongs
 * @param path  path to the file beginning with the driver letter (e.g. S:/folder/file.txt)
 * @param mode  read: FS_MODE_RD, write: FS_MODE_WR, both: FS_MODE_RD | FS_MODE_WR
 * @return pointer to FIL struct or NULL in case of fail
 */
static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode)
{
    LV_UNUSED(drv);
    uint8_t flags = 0;
    char full_path[256];

    if(mode == LV_FS_MODE_WR) flags = FA_WRITE | FA_OPEN_ALWAYS;
    else if(mode == LV_FS_MODE_RD) flags = FA_READ;
    else if(mode == (LV_FS_MODE_WR | LV_FS_MODE_RD)) flags = FA_READ | FA_WRITE | FA_OPEN_ALWAYS;

    FIL * f = lv_malloc(sizeof(FIL));
    if(f == NULL) return NULL;

    snprintf(full_path, sizeof(full_path), "/spiflash/%s", path);
    FRESULT res = f_open(f, full_path, flags);
    if(res == FR_OK) {
        return f;
    }
    else {
        lv_free(f);
        return NULL;
    }
}

使用

c 复制代码
load_file_and_display("A:/hellolongname.txt", screen);
void load_file_and_display(const char *file_path, lv_obj_t *parent) {
    // 打开文件
    lv_fs_file_t file;
    if (lv_fs_open(&file, file_path, LV_FS_MODE_RD) != LV_FS_RES_OK) {
        printf("Failed to open file: %s\n", file_path);
        return;
    }
}

reference

fatfsgen

相关推荐
jomoly2 天前
【LC实战派】小智固件编译
乐鑫·esp32-s3·立创·小智·实战派
学生哥-_-4 天前
STM32通过KEIL pack包轻松移植LVGL,并学会使用GUI guider
stm32·lvgl·tftlcd·gui guider·gt911
HelloTonyGo10 天前
在MDK中自动部署LVGL,在stm32f407ZGT6移植LVGL-8.3,运行demo,显示label
stm32·嵌入式硬件·lvgl
花落已飘15 天前
LVGL(lv_keyboard键盘)
c语言·ui·lvgl
A-code22 天前
如何在LVGL之外的线程更新UI内容
ui·嵌入式·lvgl
小_楠_天_问1 个月前
第二课:ESP32 使用 PWM 渐变控制——实现模拟呼吸灯或音调变化
c语言·嵌入式硬件·mcu·esp32·arduino·pwm·esp32-s3
花落已飘1 个月前
LVGL(lv_btnmatrix矩阵按钮)
ui·c·lvgl
HHONGQI1231 个月前
LVGL -meter的应用
lvgl·meter
Jaron JI1 个月前
LVGL模拟器:NXP GUIDER+VSCODE
lvgl