• ARM32开发-fat_fs文件系统


    FAT_FS 文件系统

    FAT (File Allocation Table) 文件系统是一种广泛使用的基于磁盘的文件系统,尤其适用于小型嵌入式系统和存储卡。FAT_FS 就是一个专门针对 FAT 文件系统的开源实现。

    FAT_FS 的主要特点

    1. 轻量级和高度可移植:
      • FAT_FS 是一个非常轻量级的文件系统实现,占用资源少,非常适合嵌入式系统。
      • 它被设计为可以在不同的硬件平台和操作系统上运行,具有很强的可移植性。
    1. 支持 FAT12/16/32 文件系统:
      • FAT_FS 支持 FAT12、FAT16 和 FAT32 三种常见的 FAT 文件系统格式。
      • 可以方便地在这些文件系统格式之间进行切换和转换。
    1. 功能丰富:
      • FAT_FS 提供了完整的文件系统功能,包括文件和目录的创建、读写、删除等。
      • 还支持长文件名、时间戳、属性标志等特性。

    FAT_FS 与 SDIO 的关系

    SDIO (Secure Digital Input Output) 是一种通信协议,用于与 SD/SDHC/SDXC 存储卡进行数据交互。而 FAT_FS 则是一种文件系统,用于管理存储在这些存储卡上的文件数据。

    通常情况下,嵌入式系统会将 FAT_FS 文件系统与 SDIO 驱动程序集成在一起,形成一个完整的存储子系统。SDIO 驱动程序负责与物理存储卡进行底层的数据交互,而 FAT_FS 则提供上层的文件系统功能,使得应用程序可以方便地访问存储卡上的文件数据。

    这种组合使得嵌入式系统能够轻松地支持基于 SD 卡的文件存储和交换功能,广泛应用于各种电子设备中。

    fat_fs仓库地址:FatFs - Generic FAT Filesystem Module

    1. SDIO

    1. 从GD32固件库的SDIO文件夹中复制sdcard.hsdcard.c文件到自己的工程中
    2. 核对2366行代码中,引脚是否与自己的开发板相符合,若不相符,则修改引脚

    1. 在sdcard.c文件中,声明变量
    sd_card_info_struct sd_cardinfo;  
    1. 在sd_init函数中,增加获取sd卡信息的函数,方便后续调用
    1. if(SD_OK == status) {
    2. status = sd_card_information_get(&sd_cardinfo);
    3. }

    2. fat_fs

    将下载的文件导入到工程中

    替换diskio.c文件内容

    📎diskio.c

    2.1. 测试代码

    1. #include "ff.h"
    2. FATFS fs;
    3. u8 buff_tx[512]="SD卡扇区读写测试,fat文件系统读写测试www.icheima.com\r\n";
    4. u8 buff_rx[512];
    5. void test_fatfs_write(const TCHAR *file_name,u8 *buff,u32 len);
    6. void test_fatfs_read(const TCHAR *file_name,u8 *buff,u32 len);
    7. void test_fatfs(){
    8. uint8_t stat=f_mount(&fs,"0:",1);//SD卡挂载
    9. printf("stat=%d\r\n",stat);
    10. if(stat==0) printf("磁盘挂载成功\r\n");
    11. test_fatfs_write("0:/icheima.txt",buff_tx,strlen((char *)buff_tx));
    12. test_fatfs_read("0:/icheima.txt",buff_rx,strlen((char *)buff_tx));
    13. printf("rx:%s\r\n",buff_rx);
    14. //while(1){}
    15. }
    16. void test_fatfs_write(const TCHAR *file_name,u8 *buff,u32 len)
    17. {
    18. /*1.打开文件*/
    19. FIL fp;
    20. FRESULT res;
    21. UINT bw;
    22. res=f_open(&fp,file_name,FA_WRITE|FA_CREATE_ALWAYS);//+创建
    23. if(res!=FR_OK)
    24. {
    25. printf("文件打开或创建失败:ERR%d\r\n",res);
    26. return ;
    27. }
    28. printf("文件创建或打开成功\r\n");
    29. res=f_write(&fp,buff,len,&bw);
    30. if(res==FR_OK)
    31. {
    32. printf("数据写入成功 %d Byte\r\n",bw);
    33. }
    34. else printf("写入失败ERR:%d\r\n",res);
    35. f_close(&fp);//关闭文件
    36. }
    37. void test_fatfs_read(const TCHAR *file_name,u8 *buff,u32 len)
    38. {
    39. /*1.打开文件*/
    40. FIL fp;
    41. FRESULT res;
    42. UINT br;
    43. res=f_open(&fp,file_name,FA_READ);//
    44. if(res!=FR_OK)
    45. {
    46. printf("文件打开失败:ERR%d\r\n",res);
    47. return ;
    48. }
    49. printf("文件打开成功\r\n");
    50. res=f_read(&fp,buff,len,&br);
    51. if(res!=FR_OK)
    52. {
    53. printf("读取数据失败ERR:%d \r\n",res);
    54. }
    55. else
    56. {
    57. printf("读取数据成功 %d byte\r\n",br);
    58. }
    59. f_close(&fp);//关闭文件
    60. }

    2.2. error:13

    uint8_t stat=f_mount(&fs,"0:",1);//SD卡挂载

    调用以上代码,如果出现13错误码,则使用SDFormatter对SD卡进行格式化即可

    3. lvgl中启用文件系统

    3.1. 模拟器中

    在lv_conf配置文件中,启用文件系统

    1. #define LV_USE_FS_WIN32 1
    2. #if LV_USE_FS_WIN32
    3. #define LV_FS_WIN32_LETTER 'D' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
    4. #define LV_FS_WIN32_PATH "D:/videos/code/lv_port_pc_eclipse-release-v8.3/images" /*Set the working directory. File/directory paths will be appended to it.*/
    5. #define LV_FS_WIN32_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/
    6. #endif

    其中“D:/videos/code/lv_port_pc_eclipse-release-v8.3/images”表示windows上面的路径,我们将它映射为lvgl中的文件盘符为D

    例如,我们想访问“D:/videos/code/lv_port_pc_eclipse-release-v8.3/images”下的aaa.txt文件,在代码中我们其实只需要写"D:/aaa.txt"即可

    在代码中调用

    1. void demo14(){
    2. printf("demo14\n");
    3. lv_fs_dir_t d;
    4. if (lv_fs_dir_open(&d, "/") == LV_FS_RES_OK)
    5. {
    6. char b[50];
    7. memset(b, 0, 50);
    8. while (lv_fs_dir_read(&d, b) == LV_FS_RES_OK)
    9. {
    10. printf("%s\n", b);
    11. }
    12. lv_fs_dir_close(&d);
    13. }
    14. lv_fs_file_t file_p;
    15. lv_fs_res_t res = lv_fs_open(&file_p,"D:/mergeBinFile.c",LV_FS_MODE_RD);
    16. // 1. 获取屏幕
    17. lv_obj_t* screen = lv_scr_act();
    18. // 2. 创建要显示的内容
    19. lv_obj_t* img = lv_img_create(screen);
    20. // 3. 对内容进行设置 参数1:img, 参数2:要显示的图片
    21. lv_img_set_src(img,"D:/a0001.bin");
    22. int i = 1;
    23. int time_count=0;
    24. char buffer[10];
    25. while(1){
    26. if(time_count%5 == 0){
    27. if(i > 392){
    28. i=0;
    29. }
    30. sprintf(buffer, "D:/a%04d.bin", i);
    31. printf("%s \n",buffer);
    32. lv_img_set_src(img,buffer);
    33. i++;
    34. }
    35. time_count++;
    36. lv_timer_handler();
    37. usleep(5 * 1000);
    38. }
    39. }

    运行上述代码,我们可以看到视频画面

    3.2. 单片机中

    在lv_conf文件中配置

    在代码中,初始化SD卡

    1. uint8_t stat=f_mount(&fs,"D",1);//SD卡挂载
    2. printf("stat=%d\r\n",stat);

    初始化lvgl中的文件系统

    lv_fs_fatfs_init();

    参考示例代码

    1. // 1. 获取屏幕
    2. lv_obj_t* screen = lv_scr_act();
    3. // 2. 创建要显示的内容
    4. lv_obj_t* img = lv_img_create(screen);
    5. // 3. 对内容进行设置 参数1:img, 参数2:要显示的图片
    6. lv_img_set_src(img,"D:/images/a0001.bin");

    注: 上面代码需要在sd根目录新建images文件夹,并在其中放入a0001.bin文件

  • 相关阅读:
    在线通过dd命令备份分区
    力扣记录:Hot100(10)——461-739
    C语言源代码系列-管理系统之机房机位预定系统
    go语言学习日记【三十四】golang中并发详解
    从服务间的一次调用分析整个springcloud的调用过程(二)
    数据库容灾 | MySQL MGR与阿里云PolarDB-X Paxos的深度对比
    104. Go单测系列4---编写可测试的代码
    C语言 动态内存管理
    如何与Excel聊天?
    Git 客户端基本使用及新手常见问题
  • 原文地址:https://blog.csdn.net/xuewenyu_/article/details/139802567