LVGL移植FATFS后显示.bin文件图片问题

玩玩 STM32F103+lvgl+Fatfs+SD 视频播放 最近偶然看到B站bad apple的视频, 是基于stm32单片机的,心血来潮自己也来弄了一个车模小视频,哈哈。。。 和bad apple的播放原理一样,视频其实就是一张张小图片,保存为.bin二进制文件格式,放在SDcard里面,通过stm单片机读取SD的bin文件,再显示在TFT上面。 第一步,截取视频图片。 截取视频图片的方法很多,这里选择通过KMPlayer播放截取一段视频。 右键视频,打开提取窗口. 因为用的是160*80的16位TFT屏,想要视频播放速度正常,我选择Ever.. 阅读详情
AI摘要

文章讲述了作者在移植FATFS并集成到LVGL后,遇到图片无法显示的问题,经排查发现是路径解析导致。通过修改函数参数和FATFS配置,解决了LVGL文件系统打开文件失败的问题,最终实现了图片的正确显示。

遇到的问题:移植完FATFS后调用FATFS的文件系统函数打开目录下的文件是可以的(我使用的是外置的SPI Flash,将文件存放到SPI Flash中,再读出来),查找目录下 的文件也是可以找到的,但是使用lv_img_set_src函数就是无法显示图片,代码一行一行地调试后,发现是lvgl层的文件系统没用,打开文件失败,下面详细介绍遇到的问题和解决办法。

一、进行FATFS文件系统的移植

这个网上有许多教程,就不多做介绍了。

二、LVGL的文件系统移植

首先打开lv_conf.h中的宏定义,开启文件系统。

/*API for FATFS (needs to be added separately). Uses f_open, f_read, etc*/
#define LV_USE_FS_FATFS 1 // 开启,置为1
#if LV_USE_FS_FATFS
    #define LV_FS_FATFS_LETTER 'A'     /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
    #define LV_FS_FATFS_CACHE_SIZE 0    /*>0 to cache this number of bytes in lv_fs_read()*/
#endif

LV_FS_FATFS_LETTER是用来设置盘符的,盘符可以在ffconf.h中查看,用哪个就填哪个如果用的是sd卡就设置为'2',我用的是spi,设置为'3'。

LV_FS_FATFS_CACHE_SIZE是用来设置缓存大小的,可以根据需求调整大小。

开启宏定义后,在lv_extra.c中会进行文件系统的初始化,lv_fs_fatfs_init()这个函数在lv_fs_fatfs.c里面,确保你的工程里面有这个文件,不然编译报错,找不到该文件。lv_fs_fatfs.c在LVGLv8后应该是自带的,不需要我们去编写了。这个文件会进行回调函数的注册,编写函数实现,实际就是对LVGL里面的文件函数定向到FATFS的文件函数。

现在就移植完了,我以为就结束了,可以显示图片了,没想到是我想的太简单了。

三、验证函数是否可以使用

  lv_fs_file_t f;
  lv_fs_res_t res = lv_fs_open(&f, "3:/image.bin", LV_FS_MODE_RD);
  printf("res: %d\n", res);

 打印结果res: 12,对应下图的LV_FS_RES_UNKNOWN,未知错误

追到函数内部查看什么情况返回的未知错误:

// lv_fs_open的函数实现
lv_fs_res_t lv_fs_open(lv_fs_file_t * file_p, const char * path, lv_fs_mode_t mode)
{
    if(path == NULL) {
        LV_LOG_WARN("Can't open file: path is NULL");
        return LV_FS_RES_INV_PARAM;
    }

    char letter = path[0];
    lv_fs_drv_t * drv = lv_fs_get_drv(letter);

    if(drv == NULL) {
        LV_LOG_WARN("Can't open file (%s): unknown driver letter", path);
        return LV_FS_RES_NOT_EX;
    }

    if(drv->ready_cb) {
        if(drv->ready_cb(drv) == false) {
            LV_LOG_WARN("Can't open file (%s): driver not ready", path);
            return LV_FS_RES_HW_ERR;
        }
    }

    if(drv->open_cb == NULL) {
        LV_LOG_WARN("Can't open file (%s): open function not exists", path);
        return LV_FS_RES_NOT_IMP;
    }

    const char * real_path = lv_fs_get_real_path(path);
    void * file_d = drv->open_cb(drv, real_path, mode);

    if(file_d == NULL || file_d == (void *)(-1)) {
        return LV_FS_RES_UNKNOWN;  // ------> 此处返回未知
    }

    file_p->drv = drv;
    file_p->file_d = file_d;

    if(drv->cache_size) {
        file_p->cache = lv_mem_alloc(sizeof(lv_fs_file_cache_t));
        LV_ASSERT_MALLOC(file_p->cache);
        lv_memset_00(file_p->cache, sizeof(lv_fs_file_cache_t));
        file_p->cache->start = UINT32_MAX;  /*Set an invalid range by default*/
        file_p->cache->end = UINT32_MAX - 1;
    }

    return LV_FS_RES_OK;
}

分析可知,当file_d这个变量为空或者为(void*)(-1)时返回未知,file_d的值是drv->open_cb(drv, real_path, mode)这个函数返回的,而这个回调函数实际是调用的lv_fs_fatfs.c中的fs_open函数,而这个函数是定向到FATFS的f_open函数,前面我也提到,我调用FATFS的函数打开文件是没有任何问题的,那么问题出在哪呢?通过debug后,查看这个函数内部的所有变量值,发现是文件路径的问题,我传入的路径是"3:/image.bin",而传入函数drv->open_cb中的是"/image.bin",盘符没了,导致打开失败。文件路径在lv_fs_get_real_path中修改了,函数实现如下:

好家伙,把我的盘符取消了,怪不得打不开。那么现在找到问题了,就开始解决吧。

四、解决方法

方法一:修改函数,

既然路径被lv_fs_get_real_path修改了,那么我们就吧这个函数注释掉,传入全部的路径

    // const char * real_path = lv_fs_get_real_path(path);
    void * file_d = drv->open_cb(drv, path, mode);

这样res就是0了。

方法二:修改FATFS的默认盘符

(有可能有的人的FATFS移植后就默认开启的,但是我的没有开启)

在FATFS源文件中,找到ffconf.h文件,找到FF_FS_RPATH:

打开宏定义,设置为1,启用f_chdir() and f_chdrive()用于设置默认盘符。在lv_fs_fatfs.c中,找到fs_init这个函数添加如下代码:

f_chdrive("3:");  /* Set drive 3 as current drive */

这样就OK了。

五、图片显示

主函数中加入如下代码,实现bin文件的图片显示

		lv_obj_t *mainPage = lv_obj_create(lv_scr_act());
		lv_obj_t * img = lv_img_create(mainPage);
		lv_img_set_src(img, "3:/image.bin");
		lv_obj_set_size(img, LV_HOR_RES, LV_VER_RES); // 屏幕的长宽
		lv_obj_center(img);
		lv_obj_clear_flag(mainPage, LV_OBJ_FLAG_SCROLLABLE);
		lv_obj_set_size(mainPage, LV_HOR_RES, LV_VER_RES);
		lv_obj_set_style_border_side(mainPage, LV_BORDER_SIDE_NONE, 0);
		lv_obj_set_style_radius(mainPage, LV_STATE_DEFAULT, 0);

【esp32&lvgl】-2.3 #lvgl-图片 lvgl的图片显示 阅读详情

相关推荐

ESP32开发-LVGL显示图片

图片使用方式 LVGL中可以使用两种方式显示图片 1、作为内部存储器(RAM 或 ROM)中的变量 2、作为文件 内部读取图片 优点:数据跟代码一起编译成固件,使用方便。 缺点:图片需要用工具转化成数组形式,图片过多或者图片分辨率过大时可能会出现编译错误(常量数据超出DROM)。 使用方法跟外部字体库类似,使用工具将图片转为成一个 .c 文件,文件里会有存储图片数据的常量数组和 LVGL 的图片数据类型结构体,同时结构体变量即可使用图片。 const lv_img_dsc_t test = { .he

起风的博客 1万+

【Luat-air105】2.2 lvgl显示图片bin格式

air105+st7735 lvgl显示bin格式图片

qq_38091632的博客 4337

LVGL+Fats系统移植+外部SPI flash

写完之后,我以为可以了,然并卵,还是啥也没显示,经排查,路径1:/rose.bin,到fs_open后,只剩下/rose.bin,那传给f_open的路径都错了,因而打不开。只要test1_map数组中数据,与red.bin一致,需要注意的是,前32位是fats的簇,所以对比时从第五个字节开始,到此fats的工作就算完成了。二、移植完,想要用fats系统文件,读外部flash的图片,遂移植fats系统文件,毕竟屏幕显示,不能只靠片上那点空间,也不够用。case EX_FLASH://外部flash。

m0_56411494的博客 2263

LVGL8移植FATFS并适配到STM32F407

移植FATFS到LVGL8,同时下载到STM32F407中。在LVGL8版本中使用文件系统。

山的博客 4936

STM32H7 LVGL 9.x 借助Python3实现SPI Flash图片存储与高效显示方案

本文详细介绍STM32H7平台结合LVGL 9.x图形库,通过Python3工具将图片转换为bin格式并存储到外部SPI Flash的高效方案。涵盖从图片转换、Flash烧录、文件系统配置到LVGL集成显示的完整流程,重点解决嵌入式GUI开发中的存储空间与性能瓶颈,适用于智能家居、工业HMI等应用场景。

5f4d3s2a1q的博客 945

不止于读写:用FatFs在LVGL界面上动态加载图片和字体(嵌入式UI实战)

本文详细介绍了如何在嵌入式系统中使用FatFs文件系统与LVGL界面实现动态加载图片和字体的完整方案。通过优化FatFs移植和LVGL桥接层设计,开发者可以显著提升UI开发效率和产品灵活性,同时降低维护成本。文章包含实战案例、性能优化策略及疑难问题解决方案,特别适合嵌入式开发人员参考。

weixin_42544461的博客 364

LVGL移植FATFS,lv_fs_dir_open,lv_fs_open问题

分析可知,当file_d这个变量为空或者为(void*)(-1)时返回未知,file_d的值是drv->open_cb(drv, real_path, mode)这个函数返回的,而这个回调函数实际是调用的lv_fs_fatfs.c中的fs_open函数,而这个函数是定向到FATFS的f_open函数,前面我也提到,我调用FATFS的函数打开文件是没有任何问题的,那么问题出在哪呢?// ------> 此处返回未知。

laxvfu的博客 2358

LVGL8.3文件系统配置指南:如何让PNG图片从SD卡秒加载(附FATFS移植技巧)

本文深入解析LVGL 8.3文件系统抽象层与FATFS移植技巧,指导开发者实现从SD卡高效加载PNG图片。通过优化存储结构、配置缓存及解码流程,结合异步加载等进阶方法,有效解决图片加载性能瓶颈,助力嵌入式GUI实现流畅的“秒加载”体验。

weixin_29229261的博客 501

【stm32H7 LVGL 9.x 使用python3将图片转化成bin文件放到外部Flash中显示】

LVGL 9.x 使用python3将图片转化成bin文件放到外部Flash中显示

qq_45204114的博客 2103

STM32+LVGL文件系统实战:从FatFS挂载到UI资源动态加载

本文详细介绍了如何在STM32嵌入式平台上,通过集成FatFS文件系统与LVGL图形库,实现UI资源的动态加载与管理。文章从解决内部Flash空间不足的痛点出发,逐步讲解了驱动编写、接口适配、资源转换与存储等核心步骤,帮助开发者构建灵活、可维护的GUI应用,并支持UI资源的动态更新。

weixin_29193259的博客 264

LVGL实战:手把手教你为STM32+FatFS项目添加图片资源加载功能(附完整代码)

本文详细介绍了如何在STM32项目中结合LVGL和FatFS实现从SD卡加载图片资源的功能。涵盖图片格式转换、文件系统配置优化、内存管理技巧及常见问题解决方案,帮助开发者高效完成嵌入式UI开发。特别适合需要处理动态图片资源的STM32开发者参考。

weixin_30378623的博客 503

LVGL与FATFS整合后.bin图片加载路径解析与优化

本文深入解析LVGL与FATFS整合后.bin图片加载失败的路径问题。通过分析LVGL文件系统接口与底层FATFS驱动的路径传递机制,提供了两种解决方案:修改LVGL路径处理函数或配置FATFS默认盘符,帮助开发者优化图片显示性能,解决嵌入式GUI开发中的常见难题。

nn3456的博客 397

告别内存焦虑!用ESP32+SD卡扩展LVGL显示资源(图片、字体、二维码全搞定)

本文详细介绍了如何利用ESP32和SD卡扩展LVGL显示资源,实现图片、字体和二维码的动态加载。通过硬件配置、文件系统整合和优化技巧,解决了嵌入式GUI开发中的内存限制问题,提升界面设计的灵活性和性能。

weixin_30847063的博客 278

guiguider读取sd卡的png图片lvgl

然后app.main中写然后cmake文件中添加头文件搜索路径和fatfs(文件系统)、vfs(虚拟文件系统)、sdmmc(SD/MMC 卡驱动)这三个组件就这两行。

2501_92263832的博客 677

富芮坤fr8008gp lvgl图片:lv_img_conv生成bin文件格式;在代码中直接引用图片;合并成一个bin给代码引用;LvglImgTool转换图片lvgl_image生成C文件

富芮坤fr8008gp lvgl图片:lv_img_conv生成bin文件格式;直接把图片放到代码钟引用

cheng___yi的博客 2054

海外最新AI营销AI销售书籍推荐AI营销培训讲师AI销售培训讲师人工智能营销培训师人工智能销售培训师AI赋能营销培训AI赋能销售培训企业AI营销内训企业AI销售内训AI营销课程讲师AI销售课程讲师

专栏|AI营销与AI销售实战 · 第46期在这个人类与算法共舞的时代,销售,已经不是你我熟悉的那个“打电话、见客户、做PPT”的老行当了。你还以为销售是“打感情牌”?错了,情感要继续,但方式已经升级。你还以为AI只是“写写文案”?错了,文案只是皮毛,真正的杀器,是思维方式的重构,是认知地图的重绘。首先,我们需要明确一个事实:AI并不会消灭销售这个职业,但它必然会重新定义销售的本质。在销售领域,真正的制胜之道不是简单地采用AI工具,而是的能力。

Akibfrycc的博客 1101

【LVGL-文件系统移植】

【代码】【LVGL-文件系统移植】

sinat_23896491的博客 970

深入解析UE5内存分析:从Memreport到Unreal Insights

本文深入解析了UE5内存分析的两大核心工具:Memreport与Unreal Insights。Memreport提供详细的内存快照,帮助定位UObject等资源的内存占用;而Unreal Insights则能进行实时监控与历史回溯,精准追踪内存泄漏。掌握这两款工具是优化UE5项目性能、确保大型项目稳定运行的必备技能。

lg888的博客 1010

别再硬塞图片到Flash了!手把手教你用STM32+LVGL+FatFS读取外部图片(附完整工程)

本文详细介绍了如何在STM32嵌入式系统中使用LVGL图形库和FatFS文件系统高效管理外部图片资源。通过将图片存储在外部Flash或SD卡中,开发者可以释放宝贵的内部存储空间,实现灵活UI更新和多主题支持。文章包含完整的工程实现步骤、性能优化技巧和高级应用场景,为嵌入式GUI开发提供实用解决方案。

weixin_30839881的博客 480

Halcon dyn_threshold详解

dyn_threshold 原型 dyn_threshold(OrigImage, ThresholdImage : RegionDynThresh : Offset, LightDark : ) 功能 利用局部阈值分割图像 参数列表 OrigImage (input_object):原始图像 ThresholdImage (input_object):处理后图像(一般采用滤波处理) RegionDynThresh (output_object):分割后区域 Offset (input_control):灰

ZiLiangQin的博客 1万+

STM32串口调试踩坑记:HAL_UART_ErrorCallback里不先解锁,你的中断接收就废了

本文深入分析了STM32串口调试中HAL_UART_ErrorCallback的锁机制陷阱,指出在错误回调中不先解锁会导致中断接收失效的问题。通过解析HAL库源码,提出了正确的错误处理实现方法,并分享了预防措施与最佳实践,帮助开发者提升串口通信的可靠性。

weixin_33733810的博客 513

LVGL图片显示优化:从文件系统到C数组的高效实践

本文深度解析了LVGL中图片显示的两种核心方案:文件系统与C数组。通过对比分析、实战教程与性能测试,指出文件系统方案在资源占用和灵活性上的显著优势,并提供了C数组在特定场景下的正确使用方法。文章最后提出“高频小图用数组,低频大图走文件”的混合策略,帮助开发者在嵌入式UI项目中实现性能与资源的最佳平衡。

weixin_29164497的博客 301

化工设备应力分析软件:STAAD.Pro二次开发_(24).非线性分析技术

在STAAD.Pro 中,可以通过命令。

kkchenjj的博客 661
稀妄
博客等级 码龄4年 47粉丝 1原创
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值