注册 登录
电子工程世界-论坛 返回首页 EEWORLD首页 频道 EE大学堂 下载中心 Datasheet 专题
liufan的个人空间 https://home.eeworld.com.cn/space-uid-53362.html [收藏] [复制] [分享] [RSS]
日志

关于FATFS文件系统挂载多个磁盘以及SPI FLASH的应用问题!

已有 21200 次阅读2014-12-10 17:34 |个人分类:ARM| SPI, FLASH, FATFS, 文件系统, SPI, FATFS

FATFS 版本: R0.09b

这里FATFS 挂载了2个磁盘,1个是SPI FLASH, 一个是SD卡。

SPI Flash的配置: 型号是 SST25VF032B( 4Mbytes ),该FLASH是4096字节/扇区,FATFS有2重配置可以考虑,

1. 直接在FFCONF.H中,设置

#define _MAX_SS 4096        /* 512, 1024, 2048 or 4096 */

其他根据需要配置即可,其中有一个_USE_ERASE 可以设置为0, 此选项是设置擦除扇区。在代码中,只有在f_mkfs和remove_chain 两个函数中添加擦除的代码,一般可以不用,当然有兴趣可以具体看一下代码,看在什么条件下使用。因为项目的原因,没有仔细研究。假如这个选项设为1的话,在DISKIO.C文件中,要增加相关指令选项CTRL_ERASE_SECTOR,该指令直接调用底层的扇区擦除函数。要注意一下的。

2. DISKIO.C中,编写相关指令的底层函数,主要就是扇区数据读取函数,扇区数据写入函数,因为FATFS在底层是按照扇区/块来操作的。要注意下,在扇区数据写入函数里面,在写入数据前必须要先擦数扇区,再写入数据,否则会出错。

3. 在读写文件的时候,一般会设置一个数据缓冲区,这个数据缓冲区的大小建议和 _MAX_SS 保持一致的大小,可以避免出现错误,还有最好在读写函数的最前面,将缓冲区清零,如果缓冲区是局部变量,那么在进入函数后,是动态从堆栈中得到的存储区域,里面可能会有无效的数据。所以最好清零。假如缓冲区是全局变量,那么也最好清零,因为里面会有上次操作是留下的数据。

SPI FLASH 大致就这么多吧!

    因为在项目应用中是要保存数据记录,而每条记录的大小也不大,小于512字节,于是想修改DISKIO.C中的扇区读写函数,将4096字节/扇区大小虚拟为512字节/扇区,思路是这样的,配置 _MAX_SS = 512,那么对于FATFS来说,他会按照512字节/扇区的大小来对底层进行操作,所以要做的事就是修改读写函数,读扇区一般好改,不介绍。写函数的思路是这样的,根据FATFS扇区号计算出当前要写入的芯片的扇区号,然后定义一个4096的缓冲区,大小和芯片扇区大小相等,然后复制这个扇区的数据到缓冲区中,然后擦除该扇区,然后在根据FATFS的扇区号计算出芯片扇区内的偏移量,将数据写入缓冲区中,然后将缓冲区内的4096个字节一次写入到芯片的扇区中,这就完成了虚拟式的转换。改写后经过调试使用一次通过。后来在网络也找到了一些这样的做法,基本上思路是一致的。
虚拟出来存在2点问题: 1. 速度上有所欠缺; 2. 需要定义一个大的RAM缓冲区,对于STM32来说,是没有啥问题的,如果是8位的MCU的话,可能就无法实现了。

    下面再说多个磁盘的挂载问题,要在以上配置的基础上作如下2个地方的配置

1.  设置要挂载的磁盘数目,我是2个磁盘,所以设置为2.
#define _VOLUMES
/* 
支持的逻辑设备数目; 
*/

2. 这个地方必须要设置1,或者2
#define _FS_RPATH 1 /* 0 to 2 */
/* 
    0:去除相对路径支持和函数;
    1:开启相对路径并且开启f_chdrive()和f_chdir()两个函数;
    2:在1 的基础上添加f_getcwd()函数。
*/

说明一下,在操作另外一个磁盘的时候,一定要调用 f_chdrive()切换磁盘的函数,入口参数是磁盘的编号,也就是在DISKIO.C中 指令函数中的磁盘判断号。如下:
    switch (pdrv) 
{
case ATA :
break;
case MMC: 
        if( SDCard0_Init() == 0 ) stat = STA_OK;
break;
case USB :
break;
case SPI_FLASH :
if( SPIFLASH_disk_initialize() == 0 ) stat = STA_OK;
break;
}

ATA , MMC , USB , SPI_FLASH  就是对应的磁盘号:

/* Definitions of physical drive number for each media */
#define MMC 0
#define ATA 1
#define USB 2
#define SPI_FLASH 3

在DISKIO.H中定义,磁盘的编号最好按顺序写,我这里用了2个,那么这样定义,不要定义成上面这样,

/* Definitions of physical drive number for each media */
#define MMC 0
#define SPI_FLASH 1
#define USB 2
#define ATA 3

如果定义成最上面的形式,那么 _VOLUMES要定义成4了,因为在FF.C中有如下的定义:
#if _VOLUMES
static
FATFS *FatFs[_VOLUMES]; /* Pointer to the file system objects (logical drives) */
#else
#error Number of volumes must not be 0.
#endif

原因就不说了,都看的懂的吧!!!

就到这里了,下班了。。。。。。
 
评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

热门文章