📄 fat.c
字号:
#include "fat.h"
#include "ch375wr.h"
unsigned int fat_offset;
unsigned int data_offset;
unsigned char FatFlags;
unsigned long blocknow;
unsigned char SecPerClus;
unsigned int VBRadd;
//############################################################################
//从BPB中获取FDT表的地址,同时判断FAT制式
unsigned int fat_root_dir_addr(unsigned char *buff)
//############################################################################
{
struct BootSec *bootp; //根目录文件表结构
struct BootSec32 *bootp32;
unsigned int FirstRootDirSecNum;
mmcReadSector(BIOS_PARAMETER_BLOCK,buff);
if(buff[0] != 0xEB) //this is mbr
{
VBRadd = buff[0x1C6] + (buff[0x1C7] << 8); //real BPB address
}
else
{
VBRadd = 0;
}
mmcReadSector(VBRadd,buff);
bootp=(struct BootSec *)buff;
bootp32=(struct BootSec32 *)buff;
if(bootp->BPB_RootEntCnt == 0)
{
FatFlags = FAT_Flg_32;
fat_offset = bootp32->BPB_RsvdSecCnt + VBRadd; //偏移扇区数
//FDT偏移地址=保留扇区+FAT占用扇区
FirstRootDirSecNum = VBRadd + (bootp32->BPB_RsvdSecCnt +
(bootp32->BPB_NumFATs * bootp32->BPB_FATSz32));
}
else
{
if(bootp->BPB_SysID[4] == '2')
FatFlags = FAT_Flg_12;
else
FatFlags = FAT_Flg_16;
fat_offset = bootp->BPB_RsvdSecCnt + VBRadd;
//FDT偏移地址=保留扇区+FAT占用扇区
FirstRootDirSecNum = VBRadd + (bootp->BPB_RsvdSecCnt +
(bootp->BPB_NumFATs * bootp->BPB_FATSz16));
}
SecPerClus = bootp->BPB_SecPerClus;
data_offset = FirstRootDirSecNum + 32; //+FDT size
return(FirstRootDirSecNum);
}
//############################################################################
//解析FAT链表
void fat_load(unsigned long Cluster, //文件起始扇区
unsigned long *Block, //返回文件下一扇区
unsigned char *TMP_Buffer) //函数所需buffer
//############################################################################
{
unsigned int FAT_Byte_Addresse;
unsigned long FAT_Block_Addresse;
//读取FAT表,根据FAT制式搜寻扇区
if(FatFlags == FAT_Flg_16)
{
if(Cluster == 0xFFFF)
{
return; //文件已经到达末尾
}
FAT_Byte_Addresse = ((Cluster<<1) & 0x1FF); FAT_Block_Addresse = ((Cluster<<1)/BlockSize) + fat_offset;
mmcReadSector(FAT_Block_Addresse,TMP_Buffer);
*Block = (TMP_Buffer[FAT_Byte_Addresse + 1] << 8) + TMP_Buffer[FAT_Byte_Addresse];
if(*Block == 0xFFFF)
*Block = 0xFFFFFFFF;
}
else if(FatFlags == FAT_Flg_12)
{
if(Cluster == 0xFFF)
{
return; //文件已经到达末尾
}
FAT_Byte_Addresse = (((Cluster*3)>>1) & 0x1FF);
FAT_Block_Addresse = (((Cluster*3)>>1) / BlockSize) + fat_offset;
if(FAT_Byte_Addresse == 0x1FF)
{
mmcReadSector(FAT_Block_Addresse,TMP_Buffer);
if((Cluster % 2) == 0)
{
*Block = TMP_Buffer[FAT_Byte_Addresse];
}
else
{
*Block = (TMP_Buffer[FAT_Byte_Addresse] >> 4);
}
mmcReadSector(FAT_Block_Addresse+1,TMP_Buffer);
if((Cluster % 2) == 0)
{
*Block += ((TMP_Buffer[0] & 0x0F) << 8);
}
else
{
*Block += (TMP_Buffer[0] << 4);
}
}
else
{
mmcReadSector(FAT_Block_Addresse,TMP_Buffer);
if((Cluster % 2) == 0)
{
*Block = ((TMP_Buffer[FAT_Byte_Addresse + 1] & 0x0F) << 8) + TMP_Buffer[FAT_Byte_Addresse];
}
else
{
*Block = (TMP_Buffer[FAT_Byte_Addresse + 1] << 4) + (TMP_Buffer[FAT_Byte_Addresse] >> 4);
}
}
if(*Block == 0xFFF)
*Block = 0xFFFFFFFF;
}
else if(FatFlags == FAT_Flg_32)
{
if(Cluster == 0xFFFFFFFF)
{
return; //文件已经到达末尾
}
FAT_Byte_Addresse = ((Cluster<<2) & 0x1FF);
FAT_Block_Addresse = ((Cluster<<2) / BlockSize) + fat_offset;
mmcReadSector (FAT_Block_Addresse,TMP_Buffer);
*Block = (TMP_Buffer[FAT_Byte_Addresse + 3] << 24) +
(TMP_Buffer[FAT_Byte_Addresse + 2] << 16) +
(TMP_Buffer[FAT_Byte_Addresse + 1] << 8) +
TMP_Buffer[FAT_Byte_Addresse];
}
return;
}
//############################################################################
//读取文件目录区相关信息
unsigned int fat_read_dir_ent(unsigned long dir_cluster, //目录所在簇
unsigned int Entry_Count, //目录中文件序号
unsigned long *Size, //文件长度
unsigned char *Dir_Attrib, //文件属性
unsigned char *buff) //函数所需buffer
//############################################################################
{
unsigned char *pointer;
unsigned int TMP_Entry_Count = 0;
unsigned long Block=0; //目录所在扇区地址
unsigned int blk;
unsigned int a;
unsigned char b;
struct DirEntry *dir; //文件目录指针
pointer = buff;
if (dir_cluster == 0) //根目录
{
Block = fat_root_dir_addr(buff);
}
else //子目录
{
Block = (dir_cluster-2)*SecPerClus+data_offset;
}
for (blk = Block;;blk++)
{
mmcReadSector(blk,buff);
for (a=0;a<BlockSize; a = a + 32)
{
dir=(struct DirEntry *)&buff[a]; //装载目录内容
if (dir->DIR_Name[0] == 0) //目录已经删除
{
return (0xFFFF);
}
//非长文件名,并且文件没有删除
if ((dir->DIR_Attr != ATTR_LONG_NAME) &&
(dir->DIR_Name[0] != DIR_ENTRY_IS_FREE))
{
//第Entery_Count个文件目录
if (TMP_Entry_Count == Entry_Count)
{
//装载文件名
for(b=0;b<11;b++)
{
if (dir->DIR_Name[b] != SPACE)
{
if (b == 8)
{
*pointer++= '.';
}
*pointer++=dir->DIR_Name[b];
}
}
*pointer++='\0';
*Dir_Attrib = dir->DIR_Attr;
//文件长度
*Size=dir->DIR_FileSize;
//文件起始簇的低16位
dir_cluster = dir->DIR_FstClusLO + (dir->DIR_FstClusHI<<16);
//返回起始簇
return(dir_cluster);
}
TMP_Entry_Count++;
}
}
}
return (0xFFFF); //Kein Eintrag mehr gefunden R點ksprung mit 0xFFFF
}
//############################################################################
//读取文件内容每次512bytes
unsigned char fat_read_file(unsigned int Cluster,
unsigned char *buff,
unsigned long BlockCount,
unsigned char *blockserial)
//############################################################################
{
unsigned long Block;
static unsigned char serial=0;
if(BlockCount == 0)
{
fat_load(Cluster,&Block,buff);
mmcReadSector((Cluster-2)*SecPerClus+data_offset+serial,buff);
serial++;
blocknow = Cluster;
*blockserial = SecPerClus-serial;
if(serial == SecPerClus)
serial = 0;
}
else
{
fat_load(blocknow,&Block,buff);
mmcReadSector((blocknow-2)*SecPerClus+data_offset+serial,buff);
serial++;
*blockserial = SecPerClus-serial;
if(serial == SecPerClus)
serial = 0;
}
if(serial == 0)
blocknow = Block;
if(blocknow == 0xFFFFFFFF)
return 1;
else
return 0;
}
unsigned char strscmp(unsigned char *src,unsigned char *dist)
{
while(*src)
{
if((*src) != (*dist))
{
if((*src) > (*dist))
return 1;
else
return 2;
}
src++;
dist++;
}
return 0;
}
//####################################################################################
//Sucht ein File im Directory
unsigned char fat_search_file (unsigned char *File_Name, //要查找的文件名
unsigned long *Cluster, //要查找的文件所在簇
unsigned long *Size, //查到的文件大小
unsigned char *Dir_Attrib,//查到的文件属性
unsigned char *buff) //查到的文件名称
//####################################################################################
{
unsigned int Dir_Cluster_Store = *Cluster;
unsigned char a;
for (a = 0;a < 100;a++)
{
*Cluster = fat_read_dir_ent(Dir_Cluster_Store,a,Size,Dir_Attrib,buff);
if (*Cluster == 0xffff)
{
return(0); //File not Found
}
if(strscmp(File_Name,buff) == 0)
{
return(1); //File Found
}
}
return(2); //Error
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -