|
发表于 2007-4-11 15:01:41
|
显示全部楼层
#define file_delete 0xE5
#define BPB_addr 32
#define dir_begin_clusId 2
//=============================
//you can not use little a,b you must use AB,or they consider it use the same name
uint8 buf[512] ;
uint16 BPB_BytesPerSec;
uint8 BPB_SecPerClus;
uint16 BPB_RsvdSecCnt;
uint8 BPB_NumFATs;
uint32 BPB_TotSec32;
uint32 BPB_FATsize;
uint32 BPB_HiddSec;
uint32 fat1_addr;
uint32 fat2_addr;
//=====================
uint8 file_clus_sec;
uint8 file_clus_sec_num;
//============================
typedef struct
{
uint8 BS_jmpBoot[3];
uint8 BS_OEMName[8];
uint16 BPB_BytesPerSec;
uint8 BPB_SecPerClus;
uint16 BPB_RsvdSecCnt;
uint8 BPB_NumFATs;
uint16 BPB_4null;
uint16 BPB_5null;
uint8 BPB_Media;
uint16 BPB_3null;
uint16 BPB_SecPerTrk;
uint16 BPB_NumHeads;
uint32 BPB_HiddSec;
uint32 BPB_TotSec32;
uint32 BPB_FATsize;
uint16 BS_null;
uint16 BPB_FATversion;
uint32 BPB_begin_clus;
uint16 BS_FilSysinfor;
uint16 BS_bootbk;
uint8 BS_resnull[12];
uint8 BS_drivnum;
uint8 BS_2null;
uint8 BS_Extendid;
uint8 BS_serial_num[4];
uint8 BS_partion_name[11];
uint8 BS_FAT_name[8];
uint8 ExecutableCode[420];
uint8 ExecutableMarker[2];
} FAT_BPB;
typedef struct
{
uint8 NAME[8];
uint8 TYPE[3];
} FILE_NAME;
typedef struct
{
FILE_NAME FileName;
uint8 FileAttrib;
uint8 UnUsed[8];
uint16 File_Start_H;
uint16 FileUpdateData[2];
uint16 File_Start_L;
uint32 Size;
} DIR;
typedef struct
{
uint16 ClusID;
uint16 SecOfClus;
uint16 ByteOfSec;
} DATA_POSIT;
//********************************************************************************************
//读一个扇区
uint8 ReadBlock(uint32 LBA)
//********************************************************************************************
{
return SD_Read_Single_Block(LBA, buf);
}
//********************************************************************************************
//写一个扇区
uint8 WriteBlock(uint32 LBA)
//********************************************************************************************
{
return SD_Write_Single_Block(LBA, buf);
}
//*****************************************
//********************************************************************************************
//读取BPB数据结构
void ReadBPB(void)
//********************************************************************************************
{
FAT_BPB* BPB = (FAT_BPB*)buf;
ReadBlock(BPB_addr);
//获取参数
BPB_BytesPerSec = BPB->BPB_BytesPerSec;
BPB_SecPerClus = BPB->BPB_SecPerClus;
BPB_RsvdSecCnt = BPB->BPB_RsvdSecCnt;
BPB_NumFATs=BPB->BPB_NumFATs; //how many fats ==2
BPB_TotSec32 = BPB->BPB_TotSec32;
BPB_FATsize = BPB->BPB_FATsize;
BPB_HiddSec = BPB->BPB_HiddSec;
fat1_addr=BPB_addr+BPB_RsvdSecCnt;
fat2_addr=BPB_addr+BPB_RsvdSecCnt+BPB_FATsize;
}
//==============
//获取根目录开始扇区号
uint32 DirStartSec(void)
//***********************************************************
{
return BPB_addr+BPB_RsvdSecCnt + BPB_FATsize * BPB_NumFATs;//32+38+973*2=2016
}
//**********************************************************
//*******************************************************************************
//获取一个簇的开始扇区
uint32 Clus2LBA(uint32 ClusID)
//****************************************************************
{
return DirStartSec() + BPB_SecPerClus * (ClusID - 2);
}
//**************************************************************
void EmptyBytes(void* D, uint32 size)
//********************************************************************************************
{
uint32 i;
uint8* data = (uint8*)D;
for(i = 0; i < size; i++)
{
*data++ = 0;
}
}
//******************************************************************
//********************************************************************************************
uint8 IsEqual(void* A, void* B, uint8 Size)
//********************************************************************************************
{
uint8 i, *a = A, *b = B;
for(i = 0; i < Size; i++)
if(a != b)
return 0;
return 1;
}
//***********************************************************
void CopyBytes(void* S, void* D, uint32 size)
//********************************************************************************************
{
uint8 *s = S, *d = D;
uint32 i;
for(i = 0; i < size; i++)
*d++ = *s++;
}
//*******************************************
//写文件分配表的指定项
void WriteFAT(uint32 Index, uint32 Value)
//********************************************************************************************
{
uint32 *RAM = (uint32*)buf;
uint32 SecID;
SecID = fat1_addr + Index / 128;
ReadBlock(SecID);
RAM[Index % 128] = Value;
WriteBlock(SecID);
SecID = fat2_addr + Index / 128;
WriteBlock(SecID);
}
//*******************************
//写根目录的指定项
void WriteDIR(uint16 Index, DIR* Value)
//********************************************************************************************
{
uint32 LBA =Clus2LBA(Index)+file_clus_sec;
ReadBlock(LBA);
CopyBytes(Value, &buf[file_clus_sec_num * 32], 32);
WriteBlock(LBA);
}
//读取文件分配表的指定项
uint32 ReadFAT(uint32 Index)
//********************************************************************************************
{
uint32 *RAM = (uint32*)buf;//init piont address
ReadBlock(fat1_addr + Index /128);
return RAM[Index % 128];
}
//*************************************************
void clr_this_clus(uint32 index)//簇号
{
uint8 i;
for(i = 0; i < BPB_SecPerClus; i++)
{
EmptyBytes(buf,512);
WriteBlock(Clus2LBA(index)+i);//清空一个簇
}
}
//获取一个空的FAT项,只要有空间就可以获得
uint32 Get_blank_FATid(void)
//********************************************************************************************
{ uint16 j;
uint32 FAT_Count, i;
uint32 *RAM = (uint32*)buf;
FAT_Count =BPB_FATsize ; //FAT表总项数
for(i = 0; i < FAT_Count; i++)
{ ReadBlock(fat1_addr + i);
for(j=0;j<128;j++)
if(RAM[j] == 0)
return i*128+j;
}
return 0;
}
//获取根目录中可以使用的一项
//可以向目录中加入新的簇链,,这样只要有磁盘空间就总可以找到目录
uint32 GetEmptyDIR(void)
//*********************************************************
{
uint32 Dir_index,dir_fat_num,next_fat_index;
uint8 i,m;
dir_fat_num=dir_begin_clusId;//2
Dir_index= Clus2LBA(dir_fat_num);//2016
next_dir0_clus: for(i = 0; i < BPB_SecPerClus; i++)
{
ReadBlock(Dir_index + i);
for(m = 0; m <16; m++)
{
if((buf[m * 32] == 0) )//|| (buf[m * 32] == 0xe5))
{ file_clus_sec=i;
file_clus_sec_num=m;
return dir_fat_num; //找到对应的目录项,返回其簇号
}
}
}
next_fat_index=ReadFAT(dir_fat_num);//read next fat num,,or no
if(next_fat_index==0x0fffffff) //you must creat a new fat address to save your new dir
{
next_fat_index=Get_blank_FATid();
clr_this_clus(next_fat_index);//
WriteFAT(dir_fat_num,next_fat_index);// write_old_fat_index
WriteFAT(next_fat_index,0x0fffffff);// write_new_fat_index
Dir_index = Clus2LBA(next_fat_index); goto next_dir0_clus ;
}
else {dir_fat_num=next_fat_index;Dir_index = Clus2LBA(dir_fat_num);
goto next_dir0_clus ; }
}
//********************************************************************
//获得和文件名对应的目录项的簇号
uint32 Get_Same_FileID(uint8 * Name)
//********************************************************************************************
{
uint32 Dir_index,dir_fat_num;
uint8 i,m;
dir_fat_num=dir_begin_clusId;//2
Dir_index= Clus2LBA(dir_fat_num);//2016
next_dir_clus: for(i = 0; i < BPB_SecPerClus; i++)
{
ReadBlock(Dir_index + i);
for(m = 0; m <16; m++)
{ if(buf[m * 32]==0) return 0xffffffff;//end and you donot find it
if(IsEqual(Name, &((DIR*)&buf[m * 32])->FileName, 11))
{
//H= ((DIR*)&buf[m * 32])->File_Start_H;
//L= ((DIR*)&buf[m * 32])->File_Start_L;
file_clus_sec=i;
file_clus_sec_num=m;
return dir_fat_num; //找到对应的目录项,返回其簇号
}
}
}
dir_fat_num=ReadFAT(dir_fat_num);//read next fat num,,or no
if(dir_fat_num==0x0fffffff) return 0xffffffff;//没有找到对应的目录项,返回ffffffff
else {Dir_index = Clus2LBA(dir_fat_num); goto next_dir_clus ; }
}
//*****************************************************************
//创建一个空文件
uint8 CreateFile(uint8* FileName)
//********************************************************************************************
{
//uint32 Fat_Id;
uint32 Dir_id;
uint8 Creat_time[8] = {0x18,0x14,0x58,0xb5,0x88,0x36,0x89,0x36};
DIR FileDir;
if(Get_Same_FileID(FileName)!=0xffffffff) return 1;//有了这个文件了,,你不能
CopyBytes(FileName, &FileDir.FileName, 11);
FileDir.FileAttrib=0x20;
CopyBytes(Creat_time, &FileDir.UnUsed, 8);
//Fat_Id=Get_blank_FATid(); //获得一个空白的fat cluster num
FileDir.File_Start_H=0;
FileDir.File_Start_L=0;
FileDir.Size=0;
//生成一个文件结构
Dir_id=GetEmptyDIR(); //获得一个空白的目录
//get_hex(Dir_id/256);get_hex(Dir_id%256);
WriteDIR(Dir_id,&FileDir);
//WriteFAT(Fat_Id, 0x0fffffff); //写入fat表同时写好2个fat表
//get_hex(Fat_Id/256);get_hex(Fat_Id%256);
return 0;
}
uint8 WriteFile(uint8* FileName,uint8 *data,uint32 size)
{
//uint32 Dir_index;
uint32 dir_fat_num,H,L;
uint32 file_size ;
uint32 Fat_Id;
//DIR FileDir;
dir_fat_num=Get_Same_FileID(FileName); //获得其目录簇号
if(dir_fat_num==0xffffffff) return 1;//没有找到该文件
ReadBlock(Clus2LBA(dir_fat_num)+file_clus_sec);
file_size=((DIR*)&buf[file_clus_sec_num * 32])->Size;//获得其长度
//============================================================
if(file_size==0)
{Fat_Id=Get_blank_FATid(); //获得一个空白的fat cluster num
H=Fat_Id/65536;//(uint16)Fat_Id>>16;
L=Fat_Id%65536;//(uint16)Fat_Id&0x0000ffff;
ReadBlock(Clus2LBA(dir_fat_num)+file_clus_sec);
((DIR*)&buf[file_clus_sec_num * 32])->File_Start_H=H;
((DIR*)&buf[file_clus_sec_num * 32])->File_Start_L=L;
((DIR*)&buf[file_clus_sec_num * 32])->Size=size;
WriteBlock(Clus2LBA(dir_fat_num)+file_clus_sec);
WriteFAT(Fat_Id, 0x0fffffff); //写入fat表同时写好2个fat表
ReadBlock(Clus2LBA(dir_fat_num)+file_clus_sec);
}
H= ((DIR*)&buf[file_clus_sec_num * 32])->File_Start_H;
L= ((DIR*)&buf[file_clus_sec_num * 32])->File_Start_L;
dir_fat_num=(H*65536+L); //获得其簇号
EmptyBytes(buf,512);//清空一个扇区的数据
CopyBytes(&data[0], &buf[0], size);
WriteBlock(Clus2LBA(dir_fat_num));//现在只能写一个扇区
return 0;
}
//=======================================
uint8 ReadFile(uint8* FileName)
{
uint32 Dir_index,dir_fat_num,H,L;
uint32 r_file_size ;
uint16 j;
uint8 i;
dir_fat_num=Get_Same_FileID(FileName); //获得其目录簇号
if(dir_fat_num==0xffffffff) return 1;//没有找到该文件
ReadBlock(Clus2LBA(dir_fat_num)+file_clus_sec);
r_file_size=((DIR*)&buf[file_clus_sec_num * 32])->Size;//获得其长度
H= ((DIR*)&buf[file_clus_sec_num * 32])->File_Start_H;
L= ((DIR*)&buf[file_clus_sec_num * 32])->File_Start_L;
dir_fat_num=(H*65536+L);
Dir_index= Clus2LBA(dir_fat_num);//获得文件第一个数据簇
next_file_clus: for(i = 0; i<BPB_SecPerClus; i++)
{
ReadBlock(Dir_index +i);
for(j=0;j<512;j++)
{w_dat(buf[j]); _delay_ms(1);if((r_file_size--)==0) return 0; }
}
dir_fat_num=ReadFAT(dir_fat_num);//read next fat num,,or no
if(dir_fat_num==0x0fffffff) return 0;
else {Dir_index = Clus2LBA(dir_fat_num); goto next_file_clus ; }
} |
|