打印

FAT32的结构反而比FAT16要简单

[复制链接]
2160|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
su_mj000|  楼主 | 2008-1-15 03:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
除了支持长文件名外,其实FAT32基本上只是在族(cluster)的定义上加长为32bit而已。反过来,FAT32实际上简化了整个结构:它的根目录区被简化为一个族。所以
对FAT32文件系统的根目录操作不必另眼看待,可与普通子目录的操作相同。

以下是一个对FAT32读操作的实例 (在PIC18F2520上实现):

#include <string.h>
#include "define.h"
#include "mmcspi.h"
#include "mmcfile.h"
#include "fat32.h"
#include "lcd3310.h"

#define fileStartCluster(dir)    ((dir->startClusterHi << 16) | dir->startClusterLo)

static FileDesc_t *FAT32_FindFileInSubDir (unsigned long cluster, unsigned int *cntptr, unsigned char depth);
static void FAT32_searchFileInSubDir (unsigned long cluster, unsigned int *cnt, unsigned char depth);

///////////////////////////////////////////////////////////////////////
char FAT32_InitEntry (BootSector_t_FAT32 *pp)
{
    if ( pp->numOfFAT == 2 && pp->rootEntries == 0 &&
         pp->sectorPerCluster && pp->sectorSize == MMC_SECTOR_SIZE )
    {
        FILE_entry.sectorPerCluster = pp->sectorPerCluster;
        FILE_entry.sectorPerFAT32   = pp->numOfSectorPerFAT;
//        FILE_entry.totalSectors         = pp->totalSectors;        // size of volume
//        FILE_entry.startOfFileSys   = FILE_entry.startSector + pp->sectorOfFileSysInfo;
        FILE_entry.fatStart         = FILE_entry.startSector + pp->reserveSectors;                // fat area start sector #
//        FILE_entry.rootStart        = FILE_entry.fatStart + FILE_entry.sectorPerFAT32 * FILE_entry.numOfFAT;
        FILE_entry.dataStart        = FILE_entry.fatStart + FILE_entry.sectorPerFAT32 * 2;    // data area start sector #
        FILE_entry.startClusterOfRoot= pp->clusterOfRootDir;                                    // root directory start cluster #
/*
        char buf[20];
        ltoa (FILE_entry.fatStart,  buf, 10);    LCD_write_string (0, 3, buf);
        ltoa (FILE_entry.dataStart, buf, 10);    LCD_write_string (0, 4, buf);
        ltoa (pp->clusterOfRootDir, buf, 10);    LCD_write_string (0, 5, buf);

        for(;;);
*/
           return FILE_OK;
    }

    return FILE_ERR_FMT;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
FileDesc_t * FAT32_ReturnFileHandle (DirEntry_t_FAT32 *dir)
{
    memcpy (fileDesc.fileName, dir->fileName, 11);        // get filename+ext
    fileDesc.size     = dir->fileSize;                    // get file size
    fileDesc.cluster = fileStartCluster(dir);            // get file (start) cluster)
    fileDesc.sector  = 0;
    return &fileDesc;
}

///////////////////////////////////////////////////////////////////////////////
//
//    now it supports N-level directory structure ... (Ha-Ha!) May, 2004
//
///////////////////////////////////////////////////////////////////////////////
FileDesc_t *FAT32_FindFile (unsigned int index)
{
    return FAT32_FindFileInSubDir (FILE_entry.startClusterOfRoot, &index, 0);
}

///////////////////////////////////////////////////////////////////////////////
#pragma recursive_function
static FileDesc_t *FAT32_FindFileInSubDir (unsigned long cluster, unsigned int *cntptr, unsigned char depth)
{
    subDirDesc.cluster = cluster;
    subDirDesc.sector  = 0;

    while ( FAT32_readFileSector (&subDirDesc) != NULL )
    {
        unsigned int j;
        FileDesc_t *fdes;

        for (j = 0; j < MMC_SECTOR_SIZE; j += DIR_ENTRY_SIZE)
        {
            DirEntry_t_FAT32 *dir = (DirEntry_t_FAT32 *)&FILE_tempBuf[j];

            switch ( FILE_EntryType (dir) )
            {
                case MP3_FILE:
                    (*cntptr)--;    // it's an MP3 file

                    if ( *cntptr == 0 )
                        return FAT32_ReturnFileHandle (dir);
                    break;

                case SUB_DIR:    // it's a sub-directory!
                    if ( depth < MAX_DIR_DEPTH )
                    {
                        // save the cluster/sector
                        unsigned long this_cluster= subDirDesc.cluster;
                        unsigned char this_sector = subDirDesc.sector;

                        // recursive searching for sub-directory
                        fdes = FAT32_FindFileInSubDir (fileStartCluster(dir), cntptr, depth+1);

                        if ( fdes != NULL )
                            return fdes;

                        // restore the cluster/sector
                        subDirDesc.cluster= this_cluster;
                        subDirDesc.sector = this_sector - 1;

                        FAT32_readFileSector (&subDirDesc);    // read back the sector
                    }
                    break;
            }
        }
    }
    return NULL;
}


///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
static unsigned long FAT32_GetDataSector (unsigned long cluster)
{
    return FILE_entry.dataStart + (cluster - FILE_entry.startClusterOfRoot) * FILE_entry.sectorPerCluster;
}

#define FILE_ClusterFatOffset(cluster)    ((cluster & 0x7f) << 2)

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
static unsigned long FAT32_NextCluster (unsigned long cluster)
{
    unsigned long sector;

//#pragma short_branch
    if ( cluster < 2 || cluster >= 0x0ffffff0 )
        return 0xffffffff;

    // FAT32: 128 cluster items per sector
    sector = FILE_entry.fatStart + cluster / 128;

    if ( MMC_ReadSector (FILE_tempBuf, sector) == MMC_OK )
    {
        unsigned int offset = FILE_ClusterFatOffset (cluster);
        return *((unsigned long *)&FILE_tempBuf[offset]);
    }

    return 0xffffffff;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
unsigned char *FAT32_readFileSector (FileDesc_t *file)
{
    if ( file->sector >= FILE_entry.sectorPerCluster )
    {
        file->cluster = FAT32_NextCluster (file->cluster);
        file->sector  = 0;
    }

    if ( file->cluster >= 0x0ffffff0 )
        return NULL;

    if ( file->sector == 0 )
        file->startSector = FAT32_GetDataSector (file->cluster);

    unsigned long sector = file->startSector + file->sector++;

    if ( MMC_ReadSector (FILE_tempBuf, sector) != MMC_OK )
        return NULL;

    return FILE_tempBuf;
}

///////////////////////////////////////////////////////////////////////////////
/*
    only get data sector number, not read the sector data!
*/
char FAT32_nextFileSector (FileDesc_t *file)
{
    if ( file->sector >= FILE_entry.sectorPerCluster )
    {
        file->cluster = FAT32_NextCluster (file->cluster);
        file->sector  = 0;
    }

    if ( file->cluster >= 0xffffff0 )
        return 0;

    if ( file->sector == 0 )
        file->startSector = FAT32_GetDataSector (file->cluster);

    file->sector++;
    return -1;
}

///////////////////////////////////////////////////////////////////////////////
unsigned int FAT32_searchMP3Files (void)
{
    unsigned int cnt = 0;

    FAT32_searchFileInSubDir (FILE_entry.startClusterOfRoot, &cnt, 0);
    return cnt;
}

///////////////////////////////////////////////////////////////////////////////
#pragma recursive_function
static void FAT32_searchFileInSubDir (unsigned long cluster, unsigned int *cnt, unsigned char depth)
{
    subDirDesc.cluster = cluster;
    subDirDesc.sector  = 0;

    while ( FAT32_readFileSector (&subDirDesc) != NULL )
    {
        unsigned int i;

        for (i = 0; i < MMC_SECTOR_SIZE; i += DIR_ENTRY_SIZE)
        {
            DirEntry_t_FAT32 *dir = &FILE_tempBuf;

            switch ( FILE_EntryType (dir) )
            {
                case MP3_FILE:
                    (*cnt)++;    // it's an MP3 file
                    break;

                case SUB_DIR:    // it's a sub-directory!
                    if ( depth < MAX_DIR_DEPTH )
                    {
                        // save the cluster/sector
                        unsigned long this_cluster= subDirDesc.cluster;
                        unsigned char this_sector = subDirDesc.sector;

                        // recursive searching for sub-directory
                        FAT32_searchFileInSubDir (fileStartCluster (dir), cnt, depth+1);

                        // restore the cluster/sector
                        subDirDesc.cluster = this_cluster;
                        subDirDesc.sector  = this_sector - 1;
                        FAT32_readFileSector (&subDirDesc);
                    }
                    break;
            }
        }
    }
}
沙发
computer00| | 2008-1-15 10:12 | 只看该作者

支持共享~~~顶一个。貌似这个是做MP3播放器的一些代码~~~

使用特权

评论回复
板凳
xwj| | 2008-1-15 10:29 | 只看该作者

呵呵,FAT搞清楚它的结构后就会觉得很简单了

就那么几样东西

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

39

主题

286

帖子

1

粉丝