LVGL + Fatfs 调试踩坑

/ 2评 / 1

其实LVGL对移植真的非常方便了,比如Fatfs这么流行的库,都有例子,基本照抄,这里基本就是因为踩坑了,先从这里抄代码.

https://github.com/lvgl/lv_fs_if/blob/master/lv_fs_fatfs.c

可见,他剩下一个函数没实现,毕竟平台相关,我一开始是这么做的.

/*Initialize your Storage device and File system.*/
static void fs_init(void)
{
    Ctrl_status status;
    FATFS fs;
    FRESULT fr; 
    
    /*E.g. for FatFS initialize the SD card and FatFS itself*/
    sd_mmc_init();
    
    /* Wait card present and ready */
    do {
            status = sd_mmc_test_unit_ready(0);
            if (CTRL_FAIL == status) {
                    while (CTRL_NO_PRESENT != sd_mmc_check(0)) {
                    }
            }
    } while (CTRL_GOOD != status);
    
    fr = f_mount(&fs, "0:", 0);
    if (fr != FR_OK)
    {
        for(;;);
    }
}

看起来没有任何问题对吧,不,当读取一个文件.

lv_res = lv_fs_open(&lv_file, "0:img1.png", LV_FS_MODE_RD);

读取后发生FR_INT_ERR.

即内部断言错误,断言错?断言什么错,一步一步分析,为了不浪费大家生命,我这里给大家看到关键线索位置以及call_stack.

得到的是乱的数据,为什么,看了看他地址是20016E50,这似乎是在栈区啊,跟踪验证,他居然把我局部变量直接取地址赋值到全局FATFS指针中,当然局部变量用完就丢了,所以,这个白存啊.

解决办法也很简单,以静态方式重新定义他,就会存在于全局变量区,因此顺利移植.

修改后的初始化函数.

/*Initialize your Storage device and File system.*/
static void fs_init(void)
{
    Ctrl_status status;
    FRESULT fr; 
    static FATFS fs;
    
    /*E.g. for FatFS initialize the SD card and FatFS itself*/
    sd_mmc_init();
    
    /* Wait card present and ready */
    do {
            status = sd_mmc_test_unit_ready(0);
            if (CTRL_FAIL == status) {
                    while (CTRL_NO_PRESENT != sd_mmc_check(0)) {
                    }
            }
    } while (CTRL_GOOD != status);
    
    fr = f_mount(&fs, "0:", 0);
    if (fr != FR_OK)
    {
        for(;;);
    }
}

当然也可以用LV_USE_USER_DATA来做一些绑定,不过这里如果这么做会更麻烦.

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注