深入理解文件系统,以fatfs为例
什么是文件系统,为什么要引入文件系统。这个问题一直困扰着我,记得之前经验少,但涉猎广,了解过许多比较新奇的东西,但不知是用来干什么的,知道后来接触的东西多了,理解也慢慢变得深刻了。之前用过一款华邦公司的FLASH芯片w25q64,即64Mbit,8MB的flash芯片,当时需要对它进行数据的存储与读取操作,但数据项目比较多,每个项目需要存储的数据也比较多,在这个大容量的flash芯片上需要划分大量的空间,依次对每个空间进行读写操作。因此涉及到以下问题:
1. 如何合理的划分存储空间,有效的管理flash区域,保证存储区域合理的被使用。
2. 如何应对诸如对一块空间多次追加写操作,读操作,擦除操作这些问题。
初次尝试自己动手管理flash芯片
如下图所示,将flash区域进行了划分,存储区域用来存储实际的文件信息,索引区域用来记录每个文件区域的存储状态,如占用或者没被占用、起始地址、当前文件的大小等信息。
struct FileBlockManage
{
u32 block; /* 文件所存储的块 */
u8 flag ;
u32 file_len;
u8* filename;
u8 number; /* 编号:按文件的播放顺序 */
}
struct FileInfo
{
#define FileNumMax 256
u8 count; /* 当前存储的有效文件数目 */
u8 CurAddrFileSta[FileNumMax]; /* 当前存储位置的文件状态 1:占用 0:空闲*/
}
使用如上结构体,用来管理flash存储空间,如上信息按照特定格式被写入到文件索引区,进而实现了对当前flash存储状态信息的记录。
具体实现如下:
struct FileBlockManage CurFileSta[FileNumMax]; //文件管理控制块,管理FLASH芯片的1--255块
void initFileBlockManage(void)
{
int i;
for(i = 1;i < FileNumMax;i++)
{
CurFileSta[i].flag = 0;
CurFileSta[i].filename = NULL;
CurFileSta[i].file_len = 0;
}
}
/**@brief:寻找当前的空闲块
*@retval:0:没有空闲块 i:空闲块的编号
*/
int searchIdleBlock(void)
{
int i;
for(i = 1;i < FileNumMax;i++)
{
if(CurFileSta[i].flag == 0)
return i;
}
return 0;
}
void writeForFlash(u8* pBuffer,u16 NumByteToWrite)
{
u16 IdleBlockNum;
IdleBlockNum= searchIdleBlock();
if(CurFileSta[IdleBlockNum].flag == 0)
{
CurFileSta[IdleBlockNum].flag = 1;
CurFileSta[IdleBlockNum].filename = file;
}
CurFileSta[IdleBlockNum].file_len += Num;
Flash_Block_Write(pBuffer, IdleBlockNum, NumByteToWrite)
}
/**@brief:将w25q64分为256个块,每8扇作为一个块,按块操作
*@param:
*@param:第n个块,范围0 -- 255;每个块的大小8*4kB
*@param:需要写入的字节数,最大FFFF
*/
void Flash_Block_Write(u8* pBuffer,u32 n,u16 NumByteToWrite)
{
static u16 LastNum;
if(n > 255) return;
SPI_Flash_Write(pBuffer, 4096 * 8 * n + LastNum, NumByteToWrite);
LastNum = NumByteToWrite;
}
void Flash_Block_Read(u8* pBuffer, u32 n, u16 NumByteToRead)
{
if(n > 255) return;
SPI_Flash_Read(pBuffer, 4096 * 8 * n, NumByteToRead);
}
该方法仅作为一个实现参考,当然在实际的应用过程中还遇到了许多困难,最后不得不去移植fatfs文件系统。照我的理解,文件系统的引入就是为了让上层应用操作存储空间的时候简单方便,不用有过多的顾虑,文件系统做为中间层同时在底层硬件驱动的协助下,安全有效的管理大容量的存储空间,实现良好的分层设计,进一步简化系统设计。