📄 fat16.c
字号:
#include "uart.h"
#include "sd.h"
#include "FAT16.h"
unsigned int FirstDataSector; // The first sector number of data
unsigned int BytesPerSector; // unsigned chars per sector
unsigned int FATsectors; // The amount sector a FAT occupied
unsigned int SectorsPerClust; // Sector per cluster
unsigned int FirstFATSector; // The first FAT sector
unsigned int FirstDirSector; // The first Dir sector
unsigned int RootDirSectors; // The sector number a Root dir occupied
unsigned int RootDirCount; // The count of directory in root dir
struct FileInfoStruct FileInfo;//temporarily buffer for file information
unsigned char xdata buffer[512];
unsigned long lb2bb(unsigned char *dat,unsigned char len)
{
unsigned long temp=0;
unsigned long fact=1;
unsigned char i=0;
for(i=0;i<len;i++)
{
temp+=dat[i]*fact;
fact*=256;
}
return temp;
}
unsigned char FAT16_ReadSector(unsigned long lba,unsigned char *buf)
{
MMC_get_data_LBA(lba,512,buf);
return 0;
}
unsigned char FAT16_WriteSector(unsigned long lba,unsigned char *buf)
{
return MMC_write_sector(lba,buf);
}
//unsigned char (* FAT16_ReadSector)(unsigned long,unsigned char *);
//unsigned char (* FAT16_WriteSector)(unsigned long,unsigned char *);
//unsigned char (* FAT16_ReadSector)(unsigned long sector, unsigned char * buffer)=MMC_SD_ReadSingleBlock;//device read
//unsigned char (* FAT16_WriteSector)(unsigned long sector, unsigned char * buffer)=MMC_SD_WriteSingleBlock;//device write
void free(unsigned char *b)
{
unsigned int i=0;
for(i=0;i<512;i++)
{
b[i]=0;
}
}
unsigned char FAT16_Init()//Initialize of FAT16
{
struct bootsector50 *bs;
struct bpb50 *bpb;
unsigned int hidsec;
for(hidsec=100;hidsec<200;hidsec++)//Some card the BPB is not locat at secter 0
{
if(FAT16_ReadSector(hidsec,buffer))
return 1;
if(buffer[0]==0xeb || buffer[0]==0xe9)
break;
}
if(hidsec==200)
return 1; //error maybe the card hasn't been formated
bs=(struct bootsector50 *)buffer;
bs->bsOemName[7]=0;
send_s(bs->bsOemName);
if(bs->bsJump[0]!=0xE9 && bs->bsJump[0]!=0xEB)
return 1;
bpb=(struct bpb50 *)bs->bsBPB;
BytesPerSector =lb2bb((unsigned char *)(&(bpb->bpbBytesPerSec)),2);
Printf("BytesPerSector",BytesPerSector);
FATsectors = lb2bb((unsigned char *)(&(bpb->bpbFATsecs)),2);
Printf("FATsectors=",FATsectors);
SectorsPerClust = (unsigned char)bpb->bpbSecPerClust;
Printf("SectorsPerClust=",SectorsPerClust);
FirstFATSector = lb2bb((unsigned char *)(&(bpb->bpbResSectors)),2)+hidsec;
Printf("FirstFATSector=",FirstFATSector);
RootDirCount = lb2bb((unsigned char *)(&(bpb->bpbRootDirEnts)),2);
Printf("RootDirCount=",RootDirCount);
RootDirSectors = (RootDirCount*32)>>9;
Printf("RootDirSectors=",RootDirSectors);
FirstDirSector = FirstFATSector+bpb->bpbFATs*FATsectors;
Printf("FirstDirSector=",FirstDirSector);
FirstDataSector = FirstDirSector+RootDirSectors;
Printf("FirstDataSector=",FirstDataSector);
return 0;
}
unsigned char FAT16_LoadPartCluster(unsigned int cluster,unsigned long part,unsigned char * buffer)
{
unsigned long sector;
sector=FirstDataSector+(unsigned long)(cluster-2)*(unsigned long)SectorsPerClust;//calculate the actual sector number
if(FAT16_ReadSector(sector+part,buffer))
return 1;
else
return 0;
}
//Read the a cluster
//Not suitable for system which has few data RAM
unsigned char FAT16_LoadCluster(unsigned int cluster,unsigned char * buffer)
{
unsigned long sector;
unsigned char i;
sector=FirstDataSector+(unsigned long)(cluster-2)*(unsigned long)SectorsPerClust;//calculate the actual sector number
for(i=0;i<SectorsPerClust;i++)
{
if(FAT16_ReadSector(sector+i,buffer+(i<<9)))
break;
}
if(i==SectorsPerClust)
return 0;
else
return 1;
}
//Return the cluster number of next cluster of file
//Suitable for system which has limited RAM
unsigned int FAT16_NextCluster(unsigned int cluster)
{
//unsigned char buffer[512];
unsigned long sector;
unsigned long offset=cluster/256;
if(cluster<2)return 0xfff8;
sector=FirstFATSector+offset;//calculate the actual sector
if(FAT16_ReadSector(sector,buffer))return 0xfff8;//read fat table / return 0xfff8 when error occured
offset=cluster%256;//find the position
//offset<<=1;
//sector=buffer[offset+1];
// sector<<=8;
//sector+=buffer[offset];
sector=((unsigned int *)buffer)[offset];
return (unsigned int)sector;//return the cluste number
}
//Find a free cluster return the cluster number
unsigned int FAT16_FindFreeCluster()
{
//unsigned char buffer[512];
//unsigned long sector;
unsigned int i;
unsigned int cnt;
// sector=FirstFATSector+offset;//calculate the actual sector
//sector=FirstFATSector;
for(cnt=0;cnt<FATsectors;cnt++)//find in the FAT table
{
if(FAT16_ReadSector(FirstFATSector+cnt,buffer))
return 1;//error
for(i=0;i<256;i++)
{
if(((unsigned int *)buffer)[i]==0x0000)
break;//an unused cluster
}
if(i!=256)
{
cnt=cnt*512+i;
return cnt;//return the free cluster number
}
}
return 1;//error
}
//find a position to place a item withe the given directory, the parameter is FileInfo who brought the message
unsigned int FAT16_FindFreeItem(unsigned int cluster, struct FileInfoStruct *FileInfo)
{
//unsigned char *buffer;
unsigned long tempclust;
unsigned long sector;
unsigned char cnt;
unsigned int offset;
// unsigned char i;
struct direntry *item;
if(cluster==0)// root directory
{
//buffer=malloc(512);//apply memory
//if(buffer==0)return 1;//if failed
for(cnt=0;cnt<RootDirSectors;cnt++)
{
if(FAT16_ReadSector(FirstDirSector+cnt,buffer))
{
free(buffer);
return 1;
}//read sector
for(offset=0;offset<512;offset+=32)
{
item=(struct direntry *)(&buffer[offset]);
//used item
if((item->deName[0] != 0x00) & (item->deName[0] != 0xe5) & (item->deAttributes != 0x0f));
//unused item
else
{
FileInfo->StartCluster = item->deStartCluster;//don't care
FileInfo->Size = item->deFileSize;//don't care
FileInfo->Attr = item->deAttributes;//don't care
FileInfo->Sector = FirstDirSector+cnt;//The key parameter record the secoter nuber which the item stored
FileInfo->Offset = offset; //The key parameter record the offset in the sector
free(buffer);//realease
return 0;//done
}
}
}
free(buffer);//release
}
else//other folders
{
tempclust=cluster;
while(1)
{
sector=FirstDataSector+(tempclust-2)*SectorsPerClust;//calculate the actual sector number
//buffer=malloc(512);//apply memory
//if(buffer==0)return 1;//if failed
for(cnt=0;cnt<SectorsPerClust;cnt++)
{
if(FAT16_ReadSector(sector+cnt,buffer))
{
free(buffer);
return 1;
}
for(offset=0;offset<512;offset+=32)
{
item=(struct direntry *)(&buffer[offset]);
if((item->deName[0] != 0x2e) & (item->deName[0] != 0x00) & (item->deName[0] != 0xe5) & (item->deAttributes != 0x0f));
else
{
FileInfo->StartCluster = item->deStartCluster;
FileInfo->Size = item->deFileSize;
FileInfo->Attr = item->deAttributes;
FileInfo->Sector = sector+cnt;
FileInfo->Offset = offset;
free(buffer);
return 0;
}
}
}
free(buffer);//release
tempclust=FAT16_NextCluster(tempclust);//next cluster
if(tempclust == 0xffff || tempclust == 0xfff8)
return 1;
}
}
return 1;
}
//Find a item in the directory which specify by the parameter "cluster"
//Return the start cluster number
unsigned int FAT16_FindItem(unsigned int cluster, unsigned char *name, struct FileInfoStruct *FileInfo)
{
//unsigned char *buffer;
unsigned long tempclust;
unsigned long sector;
unsigned char cnt;
unsigned int offset;
unsigned char i;
struct direntry *item = 0;
if(cluster==0)// root directory
{
//buffer=malloc(512);//apply memory
//if(buffer==0)return 1;//if failed
Printf("enter the fat16_finditem file name is ",0);
Printf(name,0);
for(cnt=0;cnt<RootDirSectors;cnt++)
{
if(FAT16_ReadSector(FirstDirSector+cnt,buffer)){free(buffer);return 1;}
for(offset=0;offset<512;offset+=32)
{
item=(struct direntry *)(&buffer[offset]);
if((item->deName[0] != 0x00) & (item->deName[0] != 0xe5) & (item->deAttributes != 0x0f))
{
for(i=0;i<11;i++)
{
if(buffer[offset+i]!=name[i])
break;
}
if(i==11)
{
//return the parameter of the item
FileInfo->StartCluster = item->deStartCluster;
Printf("StartCluster",FileInfo->StartCluster);
FileInfo->Size = item->deFileSize;
FileInfo->Attr = item->deAttributes;
FileInfo->Sector = FirstDirSector+cnt;
FileInfo->Offset = offset;
free(buffer);
return 0;
}
}
}
}
free(buffer);//release
}
else//other folders
{
tempclust=cluster;
while(1)
{
sector=FirstDataSector+(unsigned long)(tempclust-2)*(unsigned long)SectorsPerClust;//calculate the actual sector number
//buffer=malloc(512);//apply memory
//if(buffer==0)return 1;//if failed
for(cnt=0;cnt<SectorsPerClust;cnt++)
{
if(FAT16_ReadSector(sector+cnt,buffer))
{
free(buffer);
return 1;
}
for(offset=0;offset<512;offset+=32)
{
item=(struct direntry *)(&buffer[offset]);
if((item->deName[0] != 0x00) & (item->deName[0] != 0xe5) & (item->deAttributes != 0x0f))
{
for(i=0;i<11;i++)
{
if(buffer[offset+i]!=name[i])
break;
}
if(i==11)
{
FileInfo->StartCluster = item->deStartCluster;
FileInfo->Size = item->deFileSize;
FileInfo->Attr = item->deAttributes;
FileInfo->Sector = sector+cnt;
FileInfo->Offset = offset;
free(buffer);
return 0;
}
}
}
}
free(buffer);//release
tempclust=FAT16_NextCluster(tempclust);//next cluster
if(tempclust == 0xffff || tempclust == 0xfff8)break;
}
}
return 1;
}
// find the location with the given path
unsigned int FAT16_Open(unsigned char * dir)
{
unsigned char name[13];
unsigned char *p=dir;
unsigned char deep=0;
unsigned char i,j;
unsigned long cluster=0;
Printf("Fat16 open!!",0);
if(*p != '\\')return 1;//invalid path
while(*p)
{
if(*p == '\\')
{
deep++;
}
p++;
}
p=dir;
for(i=0;i<deep-1;i++)
{
p++;
for(j=0;j<11;j++)name[j]=0x20;
j=0;
while(*p != '\\')
{
if((*p) >= 'a' && (*p) <= 'z')name[j] = (*p++)-0x20;
else name[j] = *p++;
j++;
}
name[j]=0;
Printf(name,0);
if(FAT16_FindItem(cluster,name, &FileInfo))
return 1;//find the directory
cluster = FileInfo.StartCluster;
}
p++;
for(j=0;j<11;j++)name[j]=0x20;
j=0;
while(*p != '.')//file must have a extention
{
if(*p>='a' && *p<='z')name[j]=(*p++)-0x20;
else name[j]=*p++;
j++;
}
j=8;
p++;
while(*p)
{
if(*p>='a' && *p<='z')name[j]=(*p++)-0x20;
else name[j]=*p++;
j++;
}
if(FAT16_FindItem(cluster,name, &FileInfo))
return 1;//find the file
cluster = FileInfo.StartCluster;
return cluster;
}
// find a directory with the given path
unsigned int FAT16_OpenDir(unsigned char * dir)
{
unsigned char name[11];
unsigned char *p=dir;
unsigned char deep=0;
unsigned char i,j;
unsigned long cluster=0;
if(*p != '\\')
{
return 1;//invalid path
}
Printf("FAT 16 OPENDIR ,it is valid path!!",0);
while(*p)
{
if(*p == '\\')
{
deep++;
}
p++;
}
p=dir;
for(i=0;i<deep-1;i++)
{
p++;
for(j=0;j<11;j++)name[j]=0x20;
j=0;
while(*p != '\\')
{
if((*p) >= 'a' && (*p) <= 'z')name[j] = (*p++)-0x20;
else name[j] = *p++;
j++;
}
if(FAT16_FindItem(cluster,name, &FileInfo))
return 1;//find the directory
cluster = FileInfo.StartCluster;
}
p++;
for(j=0;j<11;j++)name[j]=0x20;
j=0;
while(*p)
{
if(*p>='a' && *p<='z')name[j]=(*p++)-0x20;
else name[j]=*p++;
j++;
}
if(j == 0)return 0;
if(FAT16_FindItem(cluster,name, &FileInfo))
return 1;//find the final directory
cluster = FileInfo.StartCluster;
return cluster;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -