📄 fat32.h
字号:
#define file_delete 0xE5
//#define BPB_org_secid 0
#define dir_org_clusId 2
#define endclus_valu 0x0fffffff
#define docum 0x20
//=============================
//you can not use little a,b you must use AB,or they consider it use the same name
uint8 sd_buf[512] ;
uint16 BPB_BytesPerSec=512;
uint8 BPB_SecPerClus;//4
uint32 BPB_FAT_sec_size;
uint32 FAT1_org_secid;
uint32 FAT2_org_secid;
volatile uint32 DirStartSecid=1984;
uint32 BPB_org_secid=0;
//========================
//=======
typedef struct
{
uint8 BS_jmpBoot[3];
uint8 BS_OEMName[8];//
uint16 BPB_BytesPerSec;
uint8 BPB_SecPerClus;//
uint16 BPB_RsvdSecCnt;//38
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_FAT_sec_size;
uint16 BS_null;//
uint16 BPB_FATversion;
uint32 BPB_org_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 Creat_time[8];
uint16 File_Start_H;
uint16 FileUpdateData[2];
uint16 File_Start_L;
uint32 Size;
} DIR;
typedef struct
{
uint32 ClusID;
uint8 SecOfClus;
uint16 ByteOfSec;
uint8 state;
} DATA_POSIT;
typedef struct
{ FILE_NAME name;
DATA_POSIT dir_posit;//dir infor for change size
DATA_POSIT dat_posit;//data infor for data
uint32 size ;
uint32 file_org_clusid;
uint32 file_last_clusid;
uint8 state;
} FILE_HANDLE;
typedef struct
{ uint8 LDIR_Ord;
uint16 LDIR_Name1[5];//dir infor for change size
uint8 LDIR_Atrr;//data infor for data
uint8 LDIR_Type;
uint8 LDIR_Chksum;
uint8 LDIR_Name2[6];
uint16 LDIR_FstClus;
uint8 LDIR_Name3[2];
} LDIR;
//===========================api
DATA_POSIT Is_Same_File_there(FILE_NAME * file_name_ty,uint32 clusid);
DATA_POSIT GetEmptyDIR(uint32 clusid);
FILE_NAME unicode_Filename(uint8 * name_str);
uint8 CreateFile(uint8* FileName_str,uint32 clusid);
FILE_HANDLE OpenFile(uint8* FileName_str,uint32 clusid);
uint8 WriteFile(FILE_HANDLE * file_inforhd,uint8 * dat_str,uint16 size);
uint32 POSIT2LBA(DATA_POSIT *posit);
void CopyBytes(void* S, void* D, uint32 size);
//============================
//********************************************************************************************
//读一个扇区
uint8 ReadBlock(uint32 LBA)
//********************************************************************************************
{
return SD_Read_Single_Block(LBA,sd_buf);
}
//********************************************************************************************
//写一个扇区
uint8 WriteBlock(uint32 LBA)
//********************************************************************************************
{
return SD_Write_Single_Block(LBA,sd_buf);
}
//*****************************************
#define uart_dubeg_ReadBPB 0
//********************************************************************************************
//读取BPB数据结构
uint8 ReadBPB(void)
//********************************************************************************************
{ uint16 retry=0;
FAT_BPB* BPB = (FAT_BPB*)sd_buf; //1
uint8 MSDOS[5]={'M','S','D','O','S'};
uint32 BPB_HiddSec;
uint16 BPB_RsvdSecCnt;
uint8 BPB_NumofFATs;
uint32 BPB_TotSec32;
/* CopyBytes("this is aim to find bpb",&sd_buf[0],128);
WriteBlock(500);*/
retry=0;
BPB_org_secid=0;
while(retry++<8)
{ReadBlock(BPB_org_secid);
if(IsEqual(&BPB->BS_OEMName, &MSDOS[0], 5)==error)
{BPB_org_secid+=8;}
else break;
}
/* ReadBlock(32);
diruart[0]=0xaa;
diruart[1]=0xaa;
CopyBytes((uint8 *)&(retry),&diruart[2],2);
uart_send2(&diruart[0],4);
CopyBytes(&sd_buf[0],&diruart[0],128);//FB FC 00 00
uart_send2(&diruart[0],128);
CopyBytes(&sd_buf[128],&diruart[0],128);//FB FC 00 00
uart_send2(&diruart[0],128);
CopyBytes(&sd_buf[256],&diruart[0],128);//FB FC 00 00
uart_send2(&diruart[0],128);
CopyBytes(&sd_buf[384],&diruart[0],128);//FB FC 00 00
uart_send2(&diruart[0],128);*/
//PutString(1,1,"next sec",0xF800,0xFFE0);
//display_add_string_s(0,0,sd_buf,12);
//获取参数
BPB_BytesPerSec = BPB->BPB_BytesPerSec;//3 //每扇区的字节数
BPB_SecPerClus = BPB->BPB_SecPerClus; //每个簇的扇区数
BPB_RsvdSecCnt = BPB->BPB_RsvdSecCnt; //保留扇区数
BPB_NumofFATs=BPB->BPB_NumFATs; // fats个数 ==2
BPB_TotSec32 = BPB->BPB_TotSec32; //总扇区数
BPB_FAT_sec_size = BPB->BPB_FAT_sec_size; //fat占用的扇区数
BPB_HiddSec = BPB->BPB_HiddSec; // 隐藏扇区数
//===
FAT1_org_secid=BPB_org_secid+BPB_RsvdSecCnt; //算出fat1_org_secid 32+38=70
FAT2_org_secid=BPB_org_secid+BPB_RsvdSecCnt+BPB_FAT_sec_size;//算出fat2_org_secid =1043
DirStartSecid=BPB_org_secid+BPB_RsvdSecCnt + BPB_FAT_sec_size * BPB_NumofFATs;//32+38+973*2=2016
#if uart_dubeg_ReadBPB==1
diruart[0]=0xff;
CopyBytes((uint8 *)&(DirStartSecid),&diruart[1],4);
uart_send2(&diruart[0],5);
#endif
//CopyBytes("this is a test",&sd_buf[0],14);//FB FC 00 00
//WriteBlock(2024);
//WriteBlock(2026);
return ok;
}
//==============
/*=====================================
获取根目录开始扇区号
uint32 DirStartSec(void)
{
return BPB_org_secid+BPB_RsvdSecCnt + BPB_FAT_sec_size * BPB_NumofFATs;//32+38+973*2=2016
}
=====================================*/
//*******************************************************************************
//获取一个簇的开始扇区
uint32 Clus2LBA(uint32 ClusID)
//****************************************************************
{
return (DirStartSecid + BPB_SecPerClus * (ClusID - 2));
}
//**************************************************************
uint32 POSIT2LBA(DATA_POSIT *posit)
{
return (Clus2LBA(posit->ClusID)+posit->SecOfClus);
}
//===========================================
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[i] != b[i])
return error;
return ok;
}
//***********************************************************
void CopyBytes(void* S, void* D, uint32 size)
//********************************************************************************************
{
uint8 *s = S, *d = D;
uint32 i;
for(i = 0; i < size; i++)
*d++ = *s++;
}
//*******************************************
/*
功 能: 写文件分配表的指定簇号的属性
说 明: 用于对fat簇链进行修改
代入参数: 要修改属性的簇号,写入其属性值,要么是下一个簇链或该链终止endclus_valu
返 回 值: 无
示 范: WriteFAT(4, 5) 用了4号簇下一个5
*///=============================================================
void WriteFAT(uint32 clusid, uint32 Value)
//********************************************************************************************
{
uint32 *RAM = (uint32*)sd_buf;
uint32 SecID;
SecID = FAT1_org_secid + clusid / 128;
ReadBlock(SecID);
RAM[clusid % 128] = Value;
WriteBlock(SecID); //write fat1
SecID = FAT2_org_secid + clusid / 128;
WriteBlock(SecID); //write fat2
}
/*==================================================
功 能: 在根目录的指定地址上写入一个目录
说 明: 用于对目录进行修改
代入参数: 要写入的字节地址, 是一个DATA_POSIT ;目录数据
返 回 值: 无
示 范: WriteFAT(data_posit, new_dir)
==============================================*/
void WriteDIR(DATA_POSIT data_Index, DIR* dir_dat)
//********************************************************************************************
{
uint32 LBA =Clus2LBA(data_Index.ClusID)+data_Index.SecOfClus;
ReadBlock(LBA);
CopyBytes(dir_dat, &sd_buf[data_Index.ByteOfSec], 32);
WriteBlock(LBA);
}
/*==========================================
功 能:读取文件分配表的指定簇号对应的fat内容
代入参数:簇号
返 回 值: 其簇号对应的fat内容
示 范: ReadFAT(4) read the value of clus
*///**********************************************
uint32 ReadFAT(uint32 clusid)
{
uint32 *RAM = (uint32*)sd_buf;//init piont address
ReadBlock(FAT1_org_secid + clusid /128);
return RAM[clusid % 128];
}
//==============================================
/*==========================================
功 能:清空一个簇的内容 write 0 to all of clus
代入参数:簇号
返 回 值: no
示 范: clr_this_clus(4) clr the value of clus
*******************************************/
void clr_this_clus(uint32 clusid)//簇号
{
uint8 i;
for(i = 0; i < BPB_SecPerClus; i++)
{
EmptyBytes(sd_buf,512);
WriteBlock(Clus2LBA(clusid)+i);//清空一个簇
}
}
/*==========================================
功 能:获取一个空的FAT项,只要有空间就可以获得
代入参数:no
返 回 值: 空白簇号
示 范: ReadFAT(4) read the value of clus
*****************************************/
uint32 Get_blank_FATid(void)
//********************************************************************************************
{ uint16 j;
uint32 i;
uint32 *RAM = (uint32*)sd_buf;
for(i = 0; i < BPB_FAT_sec_size; i++)//FAT表总clus项数
{ ReadBlock(FAT1_org_secid + i);
for(j=0;j<128;j++)
if(RAM[j] == 0)
return i*128+j;
}
return error;
}
/*==========================================
功 能:获取根目录中可以使用的一项的data_posit地址 ; 可以向目录中
加入新的簇链,,这样只要有磁盘空间就总可以找到目录
代入参数
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -