目录

一、前言

二、硬件

三、lv_fs_if库移植及sdspi自定义接口库

3.1 sdspi自定义接口库

3.1.1 CMakeLists.txt

3.1.2 sdspi.h

3.1.3 sdspi.c

3.2 lv_fs_if库移植

3.2.1 CMakeLists.txt文件

3.2.2 调用sdspi库

3.2.3 修改lv_fs_if.h

3.2.4 修改DIR为FF_DIR

3.3 main文件

四、bug修改

参考资料

一、前言

在2.3中图片显示的实现方式中提到过,直接将图片写入程序内并不是一个很好的选择,以读取文件的形式(无论是以bin还是解码库的方式)显示图片既可以提高图片的分辨率,还减少程序的大小,因此这里写一下如何在esp32上移植文件系统。

二、硬件

开发板:ESP-WROOM-32

SD卡插及驱动电路:esp32_lvgl_board: 自制LVGL学习扩展板!

·       SD卡:SanDisk 32GB TF(MicroSD)存储卡

三、lv_fs_if库移植及sdspi自定义接口库

esp32基于lvgl取实现文件系统一般需要两个库,一个是利用FATFS库实现SD卡的驱动,另一个是将lvgl和FATFS库关联。这里建立一个新建一个自定义sdspi库实现基于FATFS库的SD卡驱动,另一个就是基于lv_fs_if库将lvgl和FATFS库关联。

3.1 sdspi自定义接口库

这一自定义库是基于FATFS实现的,严格来说要先建立FATFS与esp32的适配,但好消息是ESP-IDF内已经集成了FATFS库,直接调用即可。而且乐鑫官方给了一个esp32驱动sd卡建立文件系统的示例程序,在这个程序的基础上封装成库就可以很方便的调用了。sdspi库包括基本的三个文件:

3.1.1 CMakeLists.txt

idf_component_register(SRCS"sdspi.c"INCLUDE_DIRS"."REQUIRESfatfs
)

这里主要是把fatfs库加入依赖,毕竟这个库就是基于fatfs建立的。

3.1.2 sdspi.h

#ifndef SD_SPI_H
#define SD_SPI_H#include <string.h>
#include <sys/unistd.h>
#include <sys/stat.h>
#include "esp_vfs_fat.h"
#include "sdmmc_cmd.h"#define MOUNT_POINT "/sdcard"// Pin mapping
#define PIN_NUM_MISO 19
#define PIN_NUM_MOSI 23
#define PIN_NUM_CLK  18
#define PIN_NUM_CS   5
#define PIN_NUM_CD   17esp_err_t sdCard_Init();#endif

h文件就是一些端口的设定和函数的声明,根据自己的硬件设置即可。sdCard_Init函数是库的主要内容,就是将文件系统初始化,便于后续lv_fs_if库进行调用。

3.1.3 sdspi.c

#include "sdspi.h"static const char *TAG = "SD_CARD";esp_err_t sdCard_Init(){esp_err_t ret;// Options for mounting the filesystem.// If format_if_mount_failed is set to true, SD card will be partitioned and// formatted in case when mounting fails.esp_vfs_fat_sdmmc_mount_config_t mount_config = {
#ifdef CONFIG_EXAMPLE_FORMAT_IF_MOUNT_FAILED.format_if_mount_failed = true,
#else.format_if_mount_failed = false,
#endif // EXAMPLE_FORMAT_IF_MOUNT_FAILED.max_files = 5,.allocation_unit_size = 16 * 1024};sdmmc_card_t *card;const char mount_point[] = MOUNT_POINT;ESP_LOGI(TAG, "Initializing SD card");// Use settings defined above to initialize SD card and mount FAT filesystem.// Note: esp_vfs_fat_sdmmc/sdspi_mount is all-in-one convenience functions.// Please check its source code and implement error recovery when developing// production applications.ESP_LOGI(TAG, "Using SPI peripheral");sdmmc_host_t host = SDSPI_HOST_DEFAULT();host.slot = VSPI_HOST; //修改总线spi_bus_config_t bus_cfg = {.mosi_io_num = PIN_NUM_MOSI,.miso_io_num = PIN_NUM_MISO,.sclk_io_num = PIN_NUM_CLK,.quadwp_io_num = -1,.quadhd_io_num = -1,.max_transfer_sz = 4000,};ret = spi_bus_initialize(host.slot, &bus_cfg, host.slot);//SDSPI_DEFAULT_DMA->host.slotif (ret != ESP_OK) {ESP_LOGE(TAG, "Failed to initialize bus.");return ret;}// This initializes the slot without card detect (CD) and write protect (WP) signals.// Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals.sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT();slot_config.gpio_cs = PIN_NUM_CS;slot_config.gpio_cd = PIN_NUM_CD;           /* SD插拔检测信号线端口 */slot_config.host_id = host.slot;ESP_LOGI(TAG, "Mounting filesystem");ret = esp_vfs_fat_sdspi_mount(mount_point, &host, &slot_config, &mount_config, &card);if (ret != ESP_OK) {if (ret == ESP_FAIL) {ESP_LOGE(TAG, "Failed to mount filesystem. ""If you want the card to be formatted, set the CONFIG_EXAMPLE_FORMAT_IF_MOUNT_FAILED menuconfig option.");} else {ESP_LOGE(TAG, "Failed to initialize the card (%s). ""Make sure SD card lines have pull-up resistors in place.", esp_err_to_name(ret));}return ESP_FAIL;}ESP_LOGI(TAG, "Filesystem mounted");// Card has been initialized, print its propertiessdmmc_card_print_info(stdout, card);return ESP_OK;
}

这个文件主要就是sdCard_Init这个函数,基本和官方的示例程序一致,但是有几个根据自己的硬件的适配。主要是增加以下两行():

host.slot = VSPI_HOST;                      /* 修改总线 */
slot_config.gpio_cd = PIN_NUM_CD;           /* SD插拔检测信号线端口 */

分别是修改总线和新增插入检测端口。修改总线主要是因为默认总线是HSPI,但是已经被屏幕使用了,这里借鉴了b站一位大佬的思路把总线换成VSPI,否则会报错:

(876) SD_CARD: Initializing SD card
I (876) SD_CARD: Using SPI peripheral
E (876) spi: spi_bus_initialize(756): SPI bus already initialized.
E (876) SD_CARD: Failed to initialize bus.

另一个就是增加了一个插拔检测的端口,因为我们硬件上有这端口,把这个也写进程序里。

3.2 lv_fs_if库移植

lvgl官方已经提供了一个库来实现读写文件系统,即lv_fs_if库。我们首先把这个库下载下来放在工程的组件里。之后有几个地方需要进行更改:

  • 增加CMakeLists.txt文件
  • 调用sdspi库
  • 修改lv_fs_if.h
  • 修改DIR为FF_DIR

3.2.1 CMakeLists.txt文件

idf_component_register(SRCS "lv_fs_fatfs.c""lv_fs_pc.c""lv_fs_posix.c""lv_fs_if.c"INCLUDE_DIRS"./"REQUIRESlvglsdspifatfs
)

3.2.2 调用sdspi库

#include "sdspi.h"/* Initialize your Storage device and File system. */
static void fs_init(void)
{/* Initialize the SD card and FatFS itself.* Better to do it in your code to keep this library utouched for easy updating*/sdCard_Init();
}

这里主要是在lv_fs_fatfs.c文件下的fs_init函数内进行文件系统的初始化,调用我们在sdspi库内建立的sdCard_Init函数即可,当然相应的也需要加入头文件 #include "sdspi.h"。

3.2.3 修改lv_fs_if.h

/*File system interface*/
#define LV_USE_FS_IF    1
#if LV_USE_FS_IF
#  define LV_FS_IF_FATFS    'S'
#  define LV_FS_IF_PC       '\0'
#  define LV_FS_IF_POSIX    '\0'
#endif  /*LV_USE_FS_IF*/

在头文件新增如上代码,否则会出现没有定义lv_fs_if_init函数的报错,这里主要是在lv_fs_if.h内增加一段LV_USE_FS_IF的定义, 否则下面的lv_fs_if.c内#if LV_USE_FS_IF会把lv_fs_if_init函数的定义跳过,就会报这个错:

../main/main.c: In function 'app_main':
../main/main.c:8:5: error: implicit declaration of function 'lv_fs_if_init'; did you mean 'lv_fs_drv_init'? [-Werror=implicit-function-declaration]
     lv_fs_if_init();
     ^~~~~~~~~~~~~
     lv_fs_drv_init

3.2.4 修改DIR为FF_DIR

/*** Initialize a 'fs_read_dir_t' variable for directory reading* @param drv pointer to a driver where this function belongs* @param dir_p pointer to a 'fs_read_dir_t' variable* @param path path to a directory* @return LV_FS_RES_OK or any error from lv_fs_res_t enum*/
static void * fs_dir_open (lv_fs_drv_t * drv, const char *path)
{FF_DIR * d = lv_mem_alloc(sizeof(FF_DIR));if(d == NULL) return NULL;FRESULT res = f_opendir(d, path);if(res != FR_OK) {lv_mem_free(d);d = NULL;}return d;
}

把lv_fs_fatfs.c内的fs_dir_open函数下DIR都改成FF_DIR,否则就会这样报错,暂时不知道原因,解决方法是参考的这篇文章:

../components/lv_fs_if/lv_fs_fatfs.c: In function 'fs_dir_open':
../components/lv_fs_if/lv_fs_fatfs.c:226:5: error: unknown type name 'DIR'; did you mean 'DDR'?
     DIR * d = lv_mem_alloc(sizeof(DIR));
     ^~~
     DDR

3.3 main文件

#include "disp_port.h"
#include "lv_fs_if.h"
#include "lvgl.h"void app_main(void)
{    /*加载界面*///guiInit();lv_init();lv_fs_if_init();//guiTaskCreatePinnedToCore();
}

主要是调用lv_fs_if_init函数进行文件系统的初始化(sdCard_Init是lv_fs_if_init的一部分),而这之前需要进行lvgl的初始化即lv_init。当然我们也可以把lv_init放在别函数里,例如先初始化gui(gui的初始化内部会调用lv_init)。

四、bug修改

此外这里遇到一个卡住很久的问题,简单记录一下给自己

【esp32lvgl】-2.4 #lvgl-SD卡文件系统相关推荐

  1. Qt SD卡 文件系统挂载、文件预览

    /*********************************************************************************** Qt SD卡 文件系统挂载.文 ...

  2. android获取sd卡文件系统,HTML5 FileSystem API Android Chrome访问SD卡

    从this article on HTML5 Rocks开始: 重要的是要记住,此文件系统是沙盒式的,这意味着一个Web应用程序无法访问另一个应用程序的文件.这也意味着您无法将文件读/写到用户硬盘驱动 ...

  3. Maix Bit(K210) 裸机开发教程(七) SD卡文件系统使用

    SD卡使用 1.代码获取 2.代码修改 3. SD卡常用API 4.修改 5.效果展示 K210 裸机使用SD卡,下图是SD卡接口 1.代码获取 在我前面一篇博客里面简述了代码如何下载以及使用.htt ...

  4. SD卡文件系统类型是raw

    可能是你的SD卡没有没配分区.打开计算机管理中的磁盘管理,分配一下就可以了.

  5. 启明云端分享|SSD20X 如何使用SD卡根文件系统

    提示:作为Espressif(乐鑫科技)大中华区合作伙伴及sigmastar(厦门星宸)VAD合作伙伴,我们不仅用心整理了你在开发过程中可能会遇到的问题以及快速上手的简明教程供开发小伙伴参考.同时也用 ...

  6. 【FatFs】基于STM32 SD卡移植FatFs文件系统

    相关文章 <[SDIO]SDIO.SD卡.FatFs文件系统相关文章索引> 1.前言 FatFs是一个通用的FAT/exFAT文件系统模块,用于小型嵌入式系统.它完全是由 ANSI C 语 ...

  7. 从sd卡启动之文件系统制作

    在调试andriod的代码时候发现了一个问题.在andriod调试的时候无法进入常规的文件系统进行简单的操作.由于想要把alsa移植到210的开发板中,发现"/"文件系统是无法进行 ...

  8. STM32 HAL库 实现基于SPI模式的SD卡、TF卡FATS文件系统+模拟U盘的应用笔记

    前言 很多单片机不带SDIO接口,所以在使用SD卡时必须使用SPI模式进行读写. 想做一个基于SPI的SD卡文件系统读写SD卡上的文件,再配合USB接口做一个模拟U盘.只能利用业余时间慢慢更新,也不知 ...

  9. SD卡中FAT32文件格式快速入门(图文详细介绍)

    说明: MBR :Master Boot Record ( 主引导记录) DBR :DOS Boot Record ( 引导扇区) FAT :File Allocation Table ( 文件分配表 ...

最新文章

  1. 删除mysql的root用户恢复方法
  2. iOS 9 学习系列: Xcode Code Coverage
  3. java cxf 搭soa,WebService CXF入门问题 SOA 骑着上帝去环游 - 贪吃蛇学院-专业IT技术平台...
  4. 预训练永不止步,游戏问答语言模型实操
  5. 关于 SAP Spartacus feature library 里的 _index.scss 文件,和神奇的下划线省略行为
  6. 2018年海南计算机职称考试,海南省2018年全国计算机等级考试报名时间
  7. java 继承作用_java三大特性之继承
  8. 洛谷 P3258 [JLOI2014]松鼠的新家 解题报告
  9. 生僻词汇(地名,动植物名)
  10. Typora简易教程
  11. Python学生成绩计算和平均值
  12. 深度学习 —— 偏差与方差
  13. 中国心率监测器行业市场供需与战略研究报告
  14. 手机版浏览器f12_小科普 | 如何用浏览器的F12装逼?
  15. 怎么压缩gif图大小?试试这个图片压缩攻略
  16. Ride测试用例报 Suite xxxx contains no tests matching name
  17. 哦麦艾斯!AI设计的丑衣服将引领时尚?数据结构与算法代码面试题;将文件藏在图片里的隐写工具;蒙古语语音合成语料库
  18. TM1637 MSP430 单片机 数码管 程序 驱动 G2553
  19. [Unity3D]Unity3D游戏开发之继续探索NGUI
  20. rsync+xinetd+inotify+sersync

热门文章

  1. iOS的动画一篇入门
  2. 指定计算机上虚拟磁盘位置,管理虚拟硬盘 (VHD)
  3. 嵌入式的发展前景及趋势
  4. PRISM(棱镜)监听计划的善与恶
  5. Hadoop集群搭建教程(超级版本2.0)
  6. 关税新政策给代购带来了什么??
  7. 全球及中国点胶机行业市场需求及投资风险评估报告2022-2028年
  8. 30多个小程序一键发布——miniprogram-ci
  9. Html+Css+Javascript项目实战
  10. 如何让设计作品更具亮点 哪些因素值得参考