FATFS 下载地址:FATFS源码下载
FATFS 移植的过程中,主要用到三个文件:ff.c、diskio.c、ffconf.h。
移植FATFS不需要过多的操作,过程很是方便,步骤为:
补全 diskio.c 中的存储介质底层驱动文件。(一般为SD卡、SPI-Flash,直接copy别人的就行)修改 ffconf.h 中的配置。包括 磁盘数目、文件名语言、存储介质的块大小。实例化 逻辑磁盘的结构体FATFS、文件对象结构体FIL(这两个实例化对象占用RAM,大小取决于 ffconf.h 中配置的存储介质的块大小)使用 f_mount 挂载磁盘,使用 f_open、f_read、f_write、f_opendir、f_readdir、f_closedir、f_size、f_mkdir、f_unlink、f_rename、f_mkfs、f_getlabel、f_setlabel 等函数对磁盘进行操作。
移植好后编译,发现占用的 Flash 和 RAM 资源过多。打开 .map文件查看。
ROM 占用过多的为 cc936.c,占用170多KB。对于Flash大小只有 128/64KB 的MCU来说肯定是不够用的。
cc936 是对中文文件名的支持包,可以不要,只使用英文文件名。
将 ffconf.h 中的 #define _USE_LFN,由3改为0,移除掉语言包的支持,修改后的文件系统只支持英文文件名。
Tips:cc936.c 中的数据类型均为const,所以也可以编译好后放入外部存储介质,不占用MCU-Flash。
编译后报错:
..\FATFS\src\option\cc936.c(11): error: #35: #error directive: This file is not needed in current configuration. Remove from the project.
原因是 cc936.c 中的这句:
需要将 cc936.c 移除工程。
移除后编译。
Flash 空间占用,一下子就少了 170多KB。
一共占用 69.16 KB,主要是由于 lcd、uart、sdio 等文件。实际 FATFS 仅占用十多K的 Flash。
工程使用的是正点原子F407的FATFS例程。其中为FATFS分配的RAM使用了动态内存。
其实只需要在栈中根据存储介质的块大小,分配一块大小合适的RAM即可,没必要使用动态内存,栈内分配即可。
例如 SD卡的块大小为 512 Byte,那么我们只需要分配 512 Byte给FATFS即可。W25qxx的块略大,为 4KB。
正点原子的例程中,RAM占用过大的文件主要为 malloc.c,而实际使用到 malloc 的为 exfun.c。
其中,exfun.c 有
FATFS *fs[_VOLUMES];//逻辑磁盘工作区 FIL *file; //文件1 FIL *ftemp; //文件2 u8 *fatbuf; //SD卡数据缓存区 fs[i]=(FATFS*)mymalloc(SRAMIN,sizeof(FATFS)); //为磁盘i工作区申请内存 file=(FIL*)mymalloc(SRAMIN,sizeof(FIL)); //为file申请内存 ftemp=(FIL*)mymalloc(SRAMIN,sizeof(FIL)); //为ftemp申请内存 fatbuf=(u8*)mymalloc(SRAMIN,512); //为fatbuf申请内存FATFS 为FATFS逻辑磁盘结构体,FIL 为FATFS文件对象结构体。对象有用不可删除。
fatbuf 是为 fattester.c和usmart.c 服务,目的是串口调试。与 FATFS的功能无关,可以删除。
故可以将 fattester.c/h,malloc.c/h,usmart.c/h,usmart_config.c/h,usmart_str.c/h,lcd.c/h 完全移除。将 exfuns.c/h 去除u8 *fatbuf; ,并将整个文件重写,将 FATFS *fs[_VOLUMES]; FIL *file; 改为使用栈上RAM: FATFS fs[_VOLUMES]; FIL file;
FATFS 特点就是轻量化,移植好后,Flash仅占用10多Kb。RAM占用于 ffconf.h 中配置的存储介质的块大小、逻辑磁盘的数目、文件对象的数目 共同决定。(如果存储介质只为SD卡,只有1个逻辑磁盘,1/2个文件对象,RAM占用仅为1Kb多)
由于正点原子的工程文件过于冗余,实际应用可能还不如自己重新移植FATFS来的方便。