⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fat.c

📁 最新版IAR FOR ARM(EWARM)5.11中的代码例子
💻 C
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************\
*              efs - General purpose Embedded Filesystem library              *
*          --------------------- -----------------------------------          *
*                                                                             *
* Filename : fat.c                                                            *
* Description : This file contains all the functions dealing with the FAT     *
*               in a Microsoft FAT filesystem. It belongs under fs.c          *
*                                                                             *
* This program is free software; you can redistribute it and/or               *
* modify it under the terms of the GNU General Public License                 *
* as published by the Free Software Foundation; version 2                     *
* of the License.                                                             *
                                                                              *
* This program is distributed in the hope that it will be useful,             *
* but WITHOUT ANY WARRANTY; without even the implied warranty of              *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               *
* GNU General Public License for more details.                                *
*                                                                             *
* As a special exception, if other files instantiate templates or             *
* use macros or inline functions from this file, or you compile this          *
* file and link it with other works to produce a work based on this file,     *
* this file does not by itself cause the resulting work to be covered         *
* by the GNU General Public License. However the source code for this         *
* file must still be made available in accordance with section (3) of         *
* the GNU General Public License.                                             *
*                                                                             *
* This exception does not invalidate any other reasons why a work based       *
* on this file might be covered by the GNU General Public License.            *
*                                                                             *
*                                                    (c)2006 Lennart Yseboodt *
*                                                    (c)2006 Michael De Nil   *
\*****************************************************************************/

/*****************************************************************************/
#include "fs.h"
#include "fat.h"
/*****************************************************************************/

/* ****************************************************************************
 * unsigned long fat_getSectorAddressFatEntry(FileSystem *fs,unsigned long cluster_addr)
 * Description: Returns the sectornumber that holds the fat entry for cluster cluster_addr.
 * This works for all FAT types.
 * Return value: Sectornumber, or 0. Warning, no boundary check.
*/
euint32 fat_getSectorAddressFatEntry(FileSystem *fs,euint32 cluster_addr)
{
    euint32 base = fs->volumeId.ReservedSectorCount,res;
    
    switch(fs->type){
        case FAT12:
            res=(cluster_addr*3/1024);
            if(res>=fs->FatSectorCount){
                return(0);
            }
          return(base+res);
        case FAT16:
            res=cluster_addr/256;
            if(res>=fs->FatSectorCount){
                return(0);
            }
          return(base+res);
        case FAT32:
            res=cluster_addr/128;
            if(res>=fs->FatSectorCount){
                return(0);
            }
          return(base+res);
    }
    return(0);
}
/*****************************************************************************/


/* ****************************************************************************
 * unsigned long fat_getNextClusterAddress(FileSystem *fs,unsigned long cluster_addr
 * Description: This function loads the sector of the fat which contains the entry
 * for cluster_addr. It then fetches and (if required) calculates it's value.
 * This value is the EoC marker -or- the number of the next cluster in the chain.
 * Return value: Clusternumber or EoC
*/
euint32 fat_getNextClusterAddress(FileSystem *fs,euint32 cluster_addr,euint16 *linear)
{
    euint8 *buf;
    euint8 hb,lb;
    euint16 offset;
    euint32 sector;
    euint32 nextcluster=0;
    
    sector=fat_getSectorAddressFatEntry(fs,cluster_addr);
    if( (fs->FatSectorCount <= (sector-fs->volumeId.ReservedSectorCount)) || sector==0 )
    {
        return(0);
    }
    
    buf=part_getSect(fs->part,sector,IOM_MODE_READONLY);
        
    switch(fs->type)
    {
        case FAT12:
            offset = ((cluster_addr%1024)*3/2)%512;
            hb = buf[offset];
            if(offset == 511){
                part_relSect(fs->part,buf);
                buf=part_getSect(fs->part,sector+1,IOM_MODE_READONLY);
                lb = buf[0];
            }else{
                lb = buf[offset + 1];
            }
            if(cluster_addr%2==0){
                nextcluster = ( ((lb&0x0F)<<8) + (hb) );
            }else{
                nextcluster = ( (lb<<4) + (hb>>4) );
            }
            break;
        case FAT16:
            offset=cluster_addr%256;
            nextcluster = *((euint16 *)buf + offset);
            break;
        case FAT32:
            offset=cluster_addr%128;
            nextcluster = *((euint32 *)buf + offset);
            break;
    }
    
    part_relSect(fs->part,buf);
    
    return(nextcluster);
}
/*****************************************************************************/


/* ****************************************************************************
 * void fat_setNextClusterAddress(FileSystem *fs,unsigned long cluster_addr,unsigned long next_cluster_addr)
 * Description: This function makes an entry in the fattable for cluster_addr. The value it puts there
 * is next_cluster_addr.
*/
void fat_setNextClusterAddress(FileSystem *fs,euint32 cluster_addr,euint32 next_cluster_addr)
{
    euint8 *buf,*buf2;
    euint16 offset;
    euint32 sector;
    
    sector=fat_getSectorAddressFatEntry(fs,cluster_addr);
    if(fs->FatSectorCount<sector){
        DBG((TXT("HARDERROR:::fat_getNextClusterAddress READ PAST FAT BOUNDARY\n")));
        return;
    }
    
    buf=part_getSect(fs->part,sector,IOM_MODE_READWRITE);
        
    switch(fs->type){
        case FAT12:
            offset = ((cluster_addr%1024)*3/2)%512;
            if(offset == 511){
                if(cluster_addr%2==0){
                    buf[offset]=next_cluster_addr&0xFF;
                }else{
                    buf[offset]=(buf[offset]&0xF)+((next_cluster_addr<<4)&0xF0);
                }
                buf2=part_getSect(fs->part,fat_getSectorAddressFatEntry(fs,cluster_addr)+1,IOM_MODE_READWRITE);
                if(cluster_addr%2==0){
                    buf2[0]=(buf2[0]&0xF0)+((next_cluster_addr>>8)&0xF);
                }else{
                    buf2[0]=(next_cluster_addr>>4)&0xFF;
                }
                part_relSect(fs->part,buf2);
            }else{
                if(cluster_addr%2==0){
                    buf[offset]=next_cluster_addr&0xFF;
                    buf[offset+1]=(buf[offset+1]&0xF0)+((next_cluster_addr>>8)&0xF);
                }else{
                    buf[offset]=(buf[offset]&0xF)+((next_cluster_addr<<4)&0xF0);
                    buf[offset+1]=(next_cluster_addr>>4)&0xFF;
                }
            }
            part_relSect(fs->part,buf);
            break;
        case FAT16:
            offset=cluster_addr%256;
            *((euint16*)buf+offset)=next_cluster_addr;
            part_relSect(fs->part,buf);
            break;
        case FAT32:
            offset=cluster_addr%128;
            *((euint32*)buf+offset)=next_cluster_addr;
            part_relSect(fs->part,buf);
            break;
    }
    
}
/*****************************************************************************/


/* ****************************************************************************
 * short fat_isEocMarker(FileSystem *fs,unsigned long fat_entry)
 * Description: Checks if a certain value is the EoC marker for the filesystem
 * noted in fs->type.
 * Return value: Returns 0 when it is the EoC marker, and 1 otherwise.
*/
eint16 fat_isEocMarker(FileSystem *fs,euint32 fat_entry)
{
    switch(fs->type){
        case FAT12:
            if(fat_entry<0xFF8){
                return(0);
            }
            break;
        case FAT16:
            if(fat_entry<0xFFF8){
                return(0);
            }
            break;
        case FAT32:
            if((fat_entry&0x0FFFFFFF)<0xFFFFFF8){
                return(0);
            }
            break;
    }
    return(1);
}
/*****************************************************************************/


/* ****************************************************************************
 * unsigned long fat_giveEocMarker(FileSystem *fs)
 * Description: Returns an EoC markernumber valid for the filesystem noted in
 * fs->type.
 * Note, for FAT32, the upper 4 bits are set to zero, although they should be un
 * touched according to MicroSoft specifications. I didn't care.
 * Return value: The EoC marker cast to an ulong.
*/
euint32 fat_giveEocMarker(FileSystem *fs)
{
    switch(fs->type)
    {
        case FAT12:
            return(0xFFF);
        case FAT16:
            return(0xFFFF);
        case FAT32:
            return(0x0FFFFFFF);
    }
    return(0);
}
/*****************************************************************************/

/* ****************************************************************************
 * euint32 fat_getNextClusterAddressWBuf(FileSystem *fs,euint32 cluster_addr, euint8* buf)
 * Description: This function retrieves the contents of a FAT field. It does not fetch
 * it's own buffer, it is given as a parameter. (ioman makes this function rather obsolete)
 * Only in the case of a FAT12 crosssector data entry a sector is retrieved here.
 * Return value: The value of the clusterfield is returned.
*/
euint32 fat_getNextClusterAddressWBuf(FileSystem *fs,euint32 cluster_addr, euint8* buf)
{
    euint8  *buf2; /* For FAT12 fallover only */
    euint8 hb,lb;
    euint16 offset;
    euint32 nextcluster=0;
    
    switch(fs->type)
    {
        case FAT12:
            offset = ((cluster_addr%1024)*3/2)%512;
            hb = buf[offset];
            if(offset == 511){
                buf2=part_getSect(fs->part,fat_getSectorAddressFatEntry(fs,cluster_addr)+1,IOM_MODE_READONLY);
                lb = buf2[0];
                part_relSect(fs->part,buf2);
            }else{
                lb = buf[offset + 1];
            }
            if(cluster_addr%2==0){
                nextcluster = ( ((lb&0x0F)<<8) + (hb) );
            }else{
                nextcluster = ( (lb<<4) + (hb>>4) );
            }
            break;
        case FAT16:
            offset=cluster_addr%256;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -