文章目录

  • 小熊派 LVGL 移植文件系统
    • 一、移植前言
    • 二、CubeMX 开启 SDIO 接口
    • 三、CubeMX 开启 FATFS
    • 四、LVGL对接FATFS
    • 五、测试代码
    • 六、实验现象

小熊派 LVGL 移植文件系统

一、移植前言

之前使用小熊派实现了鸿蒙动画的开机界面,具体使用的技术栈为 STM32 + LiteOS + LVGL + FATFS +DMA 方式实现,刷新效率非常高,预览视频如下:

关于这个的实现过程我会写一系列的教程分享出来,主要分为下面几个部分,本节为第三部分,给 LVGL 移植 FATFS 文件系统接口

  • 小熊派移植华为 LiteOS-M(基于MDK):链接;
  • 小熊派基于 LiteOS 移植 LVGL 显示接口:链接;
  • 小熊派基于 LiteOS 移植 LVGL 文件系统:链接;
  • 小熊派实现鸿蒙开机界面(LiteOS+LVGL):链接;

本节的教程基于上一节配置好的工程,使用 STM32CubeMX 进一步配置 SDIO 总线接口,同时移植 FATFS 文件系统,关于 CubeMX 配置 SDIO 的教程,可以参考 mculover666 大神的:

【STM32Cube_20】在SD卡上移植FATFS文件系统

二、CubeMX 开启 SDIO 接口

开启 SD 单线模式

配置 SDIO 参数(保持默认):

三、CubeMX 开启 FATFS

在开启 SD 卡后,我们添加 FATFS 的文件系统支持

参数保持默认,mculover666 教程中开启了 FATFS 对文件中文名称的支持,但会占据很大的 rom 空间(180k),所以我们就不开启了,直接使用英文名称

配置完成后生成代码,这里生成代码我们要修改一下栈的大小,因为 FATFS 和 LVGL 都使用到了栈,所以改大一些

生成代码,有个警告,就是有些没用到的参数没配置,我们不管他

四、LVGL对接FATFS

代码生成了,我们先编写个小 Demo 测试一下 FAT 有没有移植成功,主函数插入如下代码:

定义一个文件系统对象和返回值

/* USER CODE BEGIN PV */
FATFS   fs;         /* FATFS 文件系统对象 */
FRESULT fr;         /* FATFS API 返回值 */
/* USER CODE END PV */

在初始化前添加如下代码

 /* USER CODE BEGIN 2 */printf("FATFS test...\r\n");/* 挂载SD卡 */fr = f_mount(&fs, "", 0);if(fr == FR_OK){printf("SD card mount ok!\r\n");}else{printf("SD card mount error, error code:%d.\r\n",fr);}

编译下载,观察串口输出:

测试正常,有的时候运行程序时会出现内存分配不够的报错,可能是因为 LiteOS 内存管理设置没有配置好,导致 LVGL 的内存池不够分配 ,LiteOS 系统启动需要手动设置系统 SRAM 的起止地址以及空间大小,因为我使用的是 MDK IDE,LiteOS 不能获得芯片 RAM 大小,所以我们把它改成 64k 就行:

当 FATFS 测试成功后,下一个就是移植到 LVGL 上,移植文件系统过程和移植显示接口过程很相似,先使能 lv_port_fs.c 和 .h 里面的宏定义

同时在 lv_conf.h 里面开启文件系统使能

编译一下代码,通过

下面就是修改 fs 文件接口了,进入 lv_port_fs.c 文件,看到 lv_port_fs_init 函数,函数里面是有关文件系统的接口初始化,代码如下

void lv_port_fs_init(void)
{/*----------------------------------------------------* Initialize your storage device and File System* -------------------------------------------------*/fs_init();/*---------------------------------------------------* Register the file system interface in LVGL*--------------------------------------------------*//* Add a simple drive to open images */lv_fs_drv_t fs_drv;lv_fs_drv_init(&fs_drv);/*Set up fields...*/fs_drv.file_size = sizeof(file_t);fs_drv.letter = 'P';fs_drv.open_cb = fs_open;fs_drv.close_cb = fs_close;fs_drv.read_cb = fs_read;fs_drv.write_cb = fs_write;fs_drv.seek_cb = fs_seek;fs_drv.tell_cb = fs_tell;fs_drv.free_space_cb = fs_free;fs_drv.size_cb = fs_size;fs_drv.remove_cb = fs_remove;fs_drv.rename_cb = fs_rename;fs_drv.trunc_cb = fs_trunc;fs_drv.rddir_size = sizeof(dir_t);fs_drv.dir_close_cb = fs_dir_close;fs_drv.dir_open_cb = fs_dir_open;fs_drv.dir_read_cb = fs_dir_read;lv_fs_drv_register(&fs_drv);
}

fs_init() 是初始化 SD 卡和文件系统接口,这里初始化接口我们已经在 CubeMX 生成的代码中初始化过了,所以不用再初始化,只需要在改代码里面放上挂载 SD 卡设备代码就行,下面的代码就是建立一个文件系统驱动

    /* Add a simple drive to open images */lv_fs_drv_t fs_drv;lv_fs_drv_init(&fs_drv);

然后配置驱动的函数入口

    /*Set up fields...*/fs_drv.file_size = sizeof(file_t);fs_drv.letter = 'P';fs_drv.open_cb = fs_open;fs_drv.close_cb = fs_close;fs_drv.read_cb = fs_read;fs_drv.write_cb = fs_write;fs_drv.seek_cb = fs_seek;fs_drv.tell_cb = fs_tell;fs_drv.free_space_cb = fs_free;fs_drv.size_cb = fs_size;fs_drv.remove_cb = fs_remove;fs_drv.rename_cb = fs_rename;fs_drv.trunc_cb = fs_trunc;fs_drv.rddir_size = sizeof(dir_t);fs_drv.dir_close_cb = fs_dir_close;fs_drv.dir_open_cb = fs_dir_open;fs_drv.dir_read_cb = fs_dir_read;

最后注册驱动

 lv_fs_drv_register(&fs_drv);

注册完成后,lvgl 会根据注册驱动的函数入口去执行对应的函数,我们只要修改对应的函数就行,这里我们先修改我们使用到的函数主要是

fs_open //打开文件
fs_close //关闭文件
fs_read //读文件
fs_write //写文件
fs_seek //重定位文件

下面修改这些函数,现在头部包含头文件,然后重新定义文件类型

添加头文件

/**********************      INCLUDES*********************/
#include "lv_port_fs.h"
#include "fatfs.h"
#include "usart.h"

覆盖掉原型的类型定义

/***********************      TYPEDEFS**********************/typedef FIL file_t;     // 把FIL类型定义成file_t
typedef DIR dir_t;      // 把DIR类型定义成dir_t

修改 fs_init() 函数

static void fs_init(void)
{/*E.g. for FatFS initialize the SD card and FatFS itself*/static FATFS  fs;            /* FATFS 文件系统对象 */FRESULT fr;       /* FATFS API 返回值 */printf("LVGL FATFS INIT...\r\n");fr = f_mount(&fs, "", 0);if (fr != FR_OK) {printf("SD Card mounted error: (%d)\r\n", fr);} elseprintf("SD Card mounted successfully!\r\n");/*You code here*/
}

修改打开文件函数:

static lv_fs_res_t fs_open (lv_fs_drv_t * drv, void * file_p, const char * path, lv_fs_mode_t mode)
{lv_fs_res_t res = LV_FS_RES_NOT_IMP;FRESULT fr;       /* FATFS API 返回值 */if(mode == LV_FS_MODE_WR){/*Open a file for write*/fr = f_open((FIL*)file_p, path, LV_FS_MODE_WR);if(fr != FR_OK){printf("open file \"%s\" error : %d\r\n", path, fr);}elseres = LV_FS_RES_OK;}else if(mode == LV_FS_MODE_RD){/*Open a file for read*/fr = f_open((FIL*)file_p, path, LV_FS_MODE_RD);if(fr != FR_OK){printf("open file \"%s\" error : %d\r\n", path, fr);}elseres = LV_FS_RES_OK;}else if(mode == (LV_FS_MODE_WR | LV_FS_MODE_RD)){/*Open a file for read and write*/fr = f_open((FIL*)file_p, path, LV_FS_MODE_WR | LV_FS_MODE_RD);if(fr != FR_OK){printf("open file \"%s\" error : %d\r\n", path, fr);}elseres = LV_FS_RES_OK;}return res;
}

关闭文件接口

static lv_fs_res_t fs_close (lv_fs_drv_t * drv, void * file_p)
{lv_fs_res_t res = LV_FS_RES_NOT_IMP;FRESULT fr;       /* FATFS API 返回值 */printf("close file\r\n");/* 操作完成,关闭文件 */fr = f_close((FIL*)file_p);if(fr != FR_OK){printf("close file error! error : %d\r\n", fr);}elseres = LV_FS_RES_OK;return res;
}

定位文件接口

static lv_fs_res_t fs_seek (lv_fs_drv_t * drv, void * file_p, uint32_t pos)
{lv_fs_res_t res = LV_FS_RES_NOT_IMP;FRESULT fr;       /* FATFS API 返回值 */fr = f_lseek((FIL*)file_p, pos);if (fr != FR_OK) {printf("read file error! error : %d\r\n", fr);}elseres = LV_FS_RES_OK;return res;
}

读写文件接口

static lv_fs_res_t fs_read (lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br)
{lv_fs_res_t res = LV_FS_RES_NOT_IMP;FRESULT fr;       /* FATFS API 返回值 */fr = f_read((FIL*)file_p, buf, btr, br);if (fr != FR_OK) {printf("read file error! error : %d\r\n", fr);}elseres = LV_FS_RES_OK;return res;
}static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw)
{lv_fs_res_t res = LV_FS_RES_NOT_IMP;FRESULT fr;       /* FATFS API 返回值 */fr = f_write((FIL*)file_p, buf, btw, bw);if (fr != FR_OK) {printf("read file error! error : %d\r\n", fr);}elseres = LV_FS_RES_OK;return res;
}

到此移植文件系统接口基本上完成,下面编写一个测试代码

五、测试代码

在lcd任务中添加如下代码,打开 SD 卡下面的 lvgl.txt 文件,写入 test 字符串

 lv_port_fs_init();lv_fs_file_t *file1 = lv_mem_alloc(sizeof(lv_fs_file_t *));fs_res=lv_fs_open(file1,"S:/lvgl.txt",LV_FS_MODE_WR | LV_FS_MODE_RD);if(fs_res != LV_FS_RES_OK)printf("open error! code:%d\r\n",fs_res);fs_res=lv_fs_write(file1,"test",4,NULL);if(fs_res != LV_FS_RES_OK)printf("write error! code:%d\r\n",fs_res);fs_res=lv_fs_close(file1);if(fs_res != LV_FS_RES_OK)printf("close error! code:%d\r\n",fs_res);lv_mem_free(file1);

下载编译

六、实验现象

串口返回写入成功:

打开sd卡下面的文件,观察写入情况,写入成功:

小熊派 LVGL 移植文件系统相关推荐

  1. 小熊派移植华为 LiteOS-M(基于MDK)

    文章目录 小熊派移植华为 LiteOS-M(基于MDK) 前言 一.软硬件介绍 1.1 小熊派开发板 1.2 LiteOS介绍 1.3 移植前言 二.CubeMX 配置 三.获取源码 四.源码移植 4 ...

  2. 手把手教你丨小熊派移植华为 LiteOS-M

    摘要:本文详细讲解如何移植 LiteOS 到小熊派. 本文分享自华为云社区<小熊派移植华为 LiteOS-M(基于MDK)>,作者: JeckXu666. 前言 之前使用小熊派实现了鸿蒙动 ...

  3. stm32mp157系统移植 | 移植ST官方5.10内核到小熊派开发板

    Linux内核移植流程 移植Linux内核到一个新的板子上时,需要以下步骤: (1)选择一个硬件设计接近的板子,基于此板相关文件开始移植 (2)拷贝单板配置文件(arch/arm/configs) ( ...

  4. 小熊派开发实践丨漫谈LiteOS之传感器移植

    摘要:本文基于小熊派开发板简单介绍了如何在LiteOS中移植传感器,从而实现对于传感器的相关控制. 1 hello world 相信大家无论在学习编程语言开始的第一个函数应该是HelloWorld,本 ...

  5. 【华为云技术分享】小熊派华为物联网操作系统LiteOS裸机驱动移植02-LCD驱动移植及使用

    1. LCD裸机驱动 小熊派开发板使用的LCD屏幕为1.3寸的TFT彩屏,色彩深度16bit,分辨率240*240,使用 SPI 接口与 MCU 之间通信. 如果你对裸机玩转LCD屏幕还不熟悉,请先阅 ...

  6. 小熊派 移植TencentOS-tiny+EC20+MQTT对接腾讯云

    1.参考文档 TencentOS tiny端云对接开发指南(IoTHub)以及Tencent tiny源码库 TencentOS-tiny官网 2.云端配置 登陆腾讯云,点击"云产品&quo ...

  7. 小熊派开发板移植RT-FOTA

    前言 买了小熊派的开发板,将demo code验证完成之后就放下了.刚好最近工作也在做OTA相关的开发,发现自己对于升级的功能还不够了解,在码云找到了一位大神基于RTThread的RT-FOTA代码, ...

  8. 实战贴:GUI STemWin在小熊派上的移植(显示很漂亮、很细腻,棒!)

    开篇前来一首歌放松一下,推荐简弘亦的新歌:忽如一面,妥妥的歌唱实力派,可是不知道为啥感觉一直不温不火,我是听了他的不染喜欢上的,好了,进入正题. 现在市面上有很多成熟的GUI,老早前就听说过STemW ...

  9. 小熊派开发板移植emwin_小熊派开发实践丨小熊派+合宙Cat.1接入云服务器

    摘要:使用小熊派开发板,以合宙的AIR724为通信模组(Cat.1),以AT指令方式,通过mqtt协议接入云服务器. 本贴使用小熊派开发板+合宙的Air724(Cat.1模组),接入自己搭建的EMQ服 ...

  10. 小熊派 FreeRTOS+SPI+DMA 驱动 TFT-LCD

    文章目录 小熊派 FreeRTOS+SPI+DMA 驱动 TFT-LCD 一.文章前言 二.SPI+DMA 配置 三.FreeRTOS 配置 四.代码编写 五.实验现象 小熊派 FreeRTOS+SP ...

最新文章

  1. 为Qt扩展QextSerialPort类
  2. Java 多线程编程(锁优化)
  3. 本田、大众宣布智能路口研究新进展 以安全为重点
  4. 菜鸟学Java(十一)——GET与POST
  5. 【python基础】用字典做一个小型的查询数据库
  6. MariaDB数据库5-password、galera
  7. Swift教程之继承
  8. Makefile之静态模式(7)
  9. 【clickhouse】docker安装clickhouse后本地无法连接
  10. 算法学习:最小生成树
  11. Python的视频分析
  12. 把你的 Mac 从 Catalina 降级回 Mojave 系统的避坑指南
  13. 什么是MCU、MPU、DSP与FPGA
  14. 2022 开源之夏 | Serverless Devs 陪你“变得更强”
  15. matlab保存nii_Matlab实现NIfTI(ANALYZE)核磁共振图像读写
  16. Linux新建分区值超出范围,关于安装Linux (FC6)频率超出范围与显卡驱动
  17. Android模拟器检测体系梳理
  18. 色温(Temperature)转RGB (JavaScript)
  19. 为什么需要传递HINSTANCE给CreateWindow?
  20. 中国诗歌艺术之人文之魂1,2(四川大学文学与新闻学院王红)

热门文章

  1. 一款轻量的支付宝支付组件
  2. 解决word、typora等打不开超链接问题
  3. loadrunner icrosoft Visual c++2005 sp1 提示命令行选项语法错误,键入“命令/?”
  4. python下一代工作流引擎_几大工作流引擎对比
  5. 【中文分词】最大熵马尔可夫模型MEMM
  6. EasyExcel(一)导入excel的分析监听器
  7. 蓝牙耳机无法与计算机连接,电脑连接蓝牙耳机时无法连接
  8. 工厂模式 (简单工厂、工厂方法、抽象工厂)
  9. C语言读取GPT分区信息
  10. html页面中的路径问题(相对路径和绝对路径)