FATFS文件系统移植

2019-04-15 14:10发布

FATFS文件系统移植

FATFS简介 : FatFs Module是一种完全免费开源的FAT文件系统模块,专门为小型的嵌入式系统而设计。它完全用标准C语言编写,所以具有良好的硬件平台独立性,可以移植到8051、PIC、AVR、SH、Z80、H8、ARM等系列单片机上而只需做简单的修改。它支持FATl2、FATl6和FAT32,支持多个存储媒介;有独立的缓冲区,可以对多个文件进行读/写,并特别对8位单片机和16位单片机做了优化。
FATFS源代码的获取,可以到官网下载: [http://elm-chan.org/fsw/ff/00index_e.html ]
在官网中也可以查询相关应用程序接口函数:
下载下来的FatFs的FatFs有两个文件夹,一个是 doc ,FatFs的说明,包括特性,系统函数,以及可能的一些问题,另一个就是源代码文件夹src了,总共8个文件,diskio.c和diskio.h是硬件层,ff.c和ff.h是FatFs的文件系统层和文件系统的API层,integer.h是文件系统所用到的数据类型的定义,tff.c和tff.h是Tiny的文件系统层和文件系统的API层,还有一个00readme.txt简要的介绍了FatFSHE FatFs/Tiny,包括他们所支持的API,怎么配置等等。 ffconf.h存放着模块的配置项,用户可以按照自己的需求来修改这些配置项,下面介绍几个移植时需要注意的配置项。 _FFCONF是代表了版本号,不做处理。 函数和缓冲区配置
  • _FS_TINY设置缓冲区的位置,假如设置为0,也就是每个文件(FIL结构体)中带一个buf,否则的话,整个文件系统公用一个buf。内存还是够的,所以选择为0。
  • _FS_READONLY设置是否文件只读,系统需要可读写的,设置为0。
  • _FS_MINIMIZE设置为0,因为以下的那些函数要用到,不简化。
  • _USE_STRFUNC设置是否使用字符串函数,主要有f_gets, f_putc, f_puts, f_printf四个函数,暂时不用,因为我们的数据都是自定义结构体的存储方式,为了节省空间这个设置为0。
  • _USE_MKFS设置是否实现f_mkfs函数。我们需要在设备初始化时完全格式化Flash,所以此函数需要。
  • _USE_FORWORD设置
  • _USE_FASTSEEK设置是否支持文件快速定位,它主要采用缓冲区来存储簇链映射图,以空间换时间,对于我们系统不合算,还是采用普通定位方式好。
    本地化和命名空间配置
  • _CODE_PAGE设置目标系统的本地化设置,本系统有ASCII支持就足够了,支持本地化的情况下,模块的大小将大幅增加,反而不符合我们选择FatFs的初衷,所以选择1。
  • _USE_LFN设置长文件名,我们系统不支持,设为0。
  • _MAX_LFN不用设置,因为不支持长文件名。
  • _LFN_UNICODE设置长文件名是否支持Unicode,我们选择不支持,因为不支持长文件名。
  • _FS_RPATH设置相对路径支持。相对路径在编程的时候特别方便,但是为了先移植成功,暂不支持。
    物理驱动器配置
  • _VOLUMES设置逻辑驱动器的个数,默认为1。
  • _MULTI_PARTITION设置是否多个分区。不分区,设为0。
  • _USE_ERASE设置擦除扇区。在f_mkfs和remove_chain两个函数中添加擦除的代码,设置为0。
    系统配置
  • _WORD_ACCESS设置是否支持字访问。不支持。
  • _FS_REENTRANT设置是否重入。因为我们的系统文件访问不是很频繁,而且都是在一个任务中访问,所以不支持重入。
  • _FS_TIMEOUT超时设置。
  • _SYNC_t访问重入时的同步句柄。
  • _FS_SHARE设置文件共享,能同时被几个文件同时打开。设置为0。
我们看下Ffconf.h的配置:

在integer.h定义好数据类型,这个要根据编译器所使用的数据类型来定:

FATFS模块与磁盘I/O 层分开的,因此需要以下函数来实现底层物理磁盘的读写与获取当前时间,底层磁盘I/O 模块并不是FATFS的一部分,并且必须由用户提供。在diskio.c中需要编写的6个驱动函数,如下图所示: 在usbh_msc_scsi.c文件中实现五个函数以支持f_open,f_read,f_write: DSTATUS disk_initialize (BYTE);//初始化 DSTATUS disk_status (BYTE);//获取状态,这里可以不用管 DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE);//读取U盘中数据 DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE);//将数据写入U盘,若该文件系统为只读文件系统则不用实现该函数 DRESULT disk_ioctl (BYTE, BYTE, void*);//获取U盘文件系统相关信息









这么一来我们就可以使用f_open();f_write()等函数了。 还记得USB_OTG博客中的USBH_USR_MSC_Application(void)函数么。 升级任务将在这里完成: if (f_mount(0, &fatfs) != FR_OK) switch (USBH_USR_ApplicationState){ case USH_USR_FS_INIT: case USH_USR_FS_OPENUSBFILE: 现在就剩下最后一步内存的覆盖了。 请移步至: 以下是我参考的博客链接: http://blog.csdn.net/ab198604/article/details/7299072 http://www.cnblogs.com/GL-BBL/archive/2012/08/20/2647347.html https://www.amobbs.com/forum.php?mod=viewthread&tid=5464257 http://www.voidcn.com/article/p-hlwexcos-bkn.html CRC校验:
(http://blog.csdn.net/weicao1990/article/details/51669853)