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

遇到的问题:移植完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);

  • 9
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值