FAT文件源代码
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
FAT文件源代码
#define IN_FAT
#include "User.h"
#include "UNICODE.H"
#define MAX_DIR_NU_List 32
#define MAX_CACHE_SIZE 544
ShortFileDirTab *pF;
extern INT8U MP3Handle;
struct QueueDL
{
ShortFileDirTab SFDT[MAX_DIR_NU_List];
INT8U front,frontE,rear,len,lenE,MaxSize;
INT8U ListNu;
}QuDirList;
struct QueueDC
{
INT8U Buf[MAX_CACHE_SIZE];
INT16U front,rear,len;
INT16U MaxSize;
}Disk_Cache;
extern Disk_Info * GetDiskInfo(INT8U DriveID);
void IintQueueDL(struct QueueDL *Q)
{
INT8U i;
Q->front = 0;
Q->frontE = 0;
Q->rear = 0;
Q->len = 0;
Q->lenE = 0;
Q->ListNu = 0;
Q->MaxSize = MAX_DIR_NU_List - 2;
for(i=0; i<MAX_DIR_NU_List; i++)
{
Q->SFDT[i].FDP.Len = 0;
Q->SFDT[i].FDP.OfClu = 0;
Q->SFDT[i].FDP.OfSec = 0;
Q->SFDT[i].FDP.OfByte = 0;
}
}
void EnQueueDL(struct QueueDL *Q, ShortFileDirTab *x)
{//向队列插入元素
INT8U i;
if((Q->rear == Q->frontE) && Q->lenE != 0)
{//队列满时将产生覆盖
Q->frontE = (Q->frontE + 1) % Q->MaxSize; //使队首元素指向下一个位置
}
for(i=0; i<11; i++)
{
Q->SFDT[Q->rear].SName[i] = x->SName[i];
}
Q->SFDT[Q->rear].Attr = x->Attr;
Q->SFDT[Q->rear].FstClu = x->FstClu;
Q->SFDT[Q->rear].FileSize = x->FileSize;
Q->SFDT[Q->rear].FDP.OfClu = x->FstClu;
Q->rear = (Q->rear + 1) % Q->MaxSize;//求出新队尾
if(Q->len < Q->MaxSize)
Q->len += 1;//队列长度加1
if(Q->lenE < Q->MaxSize)
Q->lenE += 1;
}
ShortFileDirTab * PeekQueueDL(struct QueueDL *Q)
{//取出队首元素
ShortFileDirTab *pSFDT;
pSFDT = &Q->SFDT[Q->front];
Q->front = (Q->front + 1) % Q->MaxSize;//求出新队首位置if(Q->len >0)
Q->len -= 1;//队列长度-1
return(pSFDT);
}
ShortFileDirTab * GetElemQDL(struct QueueDL *Q,INT8U pos) {//读取POS位置的元素
if((pos < 1) || (pos > Q->lenE))
{
return(NULL);
}
return(&Q->SFDT[(Q->frontE + pos - 1) % Q->MaxSize]); }
INT8U GetSizeQDL(struct QueueDL *Q)
{
if(Q != NULL)
return(Q->len);
else
return 0;
}
void InitQueueDC(struct QueueDC *Q)
{
Q->front = 0;
Q->rear = 0;
Q->len = 0;
Q->MaxSize = 544;
}
INT16U GetSizeDC(struct QueueDC *Q)
{
if(Q != NULL)
return(Q->len);
else
return 0;
}
void EnQueueDC(struct QueueDC *Q,INT8U x)
{//不考虑队列满的情况,实际使用中不出现这种情况
Q->Buf[Q->rear] = x;//新值赋给队尾
Q->rear = (Q->rear + 1) % Q->MaxSize;//求出队尾的下一个位置
if(Q->len < Q->MaxSize)
Q->len += 1;//队列长度+1
}
INT8U PeekQueueDC(struct QueueDC *Q)
{//取出队首元素
INT8U temp;
if(Q->len == 0)
{
return 0;
}
temp = Q->Buf[Q->front];
Q->front = (Q->front + 1) % Q->MaxSize;//求出
新队首位置
if(Q->len >0)
Q->len -= 1;//队列长度-1
return(temp);
}
void Uincode_to_GB(INT16U * x)
{//UNICODE码转换为GB2313汉字编码
INT16U a,b,c;
if(((*x) >= 0x0020) && ((*x) <= 0x007E))
if(
(*x) >= 'a' && (*x) <= 'z')
(*x)-='a'-'A';
*x+=0xA380;
return;
}
if((*x)<Unicode[0][0])
{
*x=0x3F3F;
return;
}
if((*x)>Unicode[UNICODE_MAX-1][0]) {
*x=0x3F3F;
return;
}
a=0;
b=UNICODE_MAX-1;
do //采用二分查表法,因为该表为顺序表{
c=(a+b)/2;
if((*x)==Unicode[c][0])
{
*x=Unicode[c][1];
return;
}
if((*x)<Unicode[c][0])
{
b=(a+b)/2;
else
{
a=(a+b+1)/2;
}
} while(a!=b);
if((*x)==Unicode[a][0])
{
*x=Unicode[a][1];
return;
}
*x=0x3F3F; //如果找不到,则显示??
}
ShortFileDirTab * OpenFile(INT8U DirListIndex) {
ShortFileDirTab *pSFDT;
pSFDT = GetElemQDL(&QuDirList, DirListIndex); return pSFDT;
}
INT8U CloseFile(ShortFileDirTab **ppSFDT) {
if(*ppSFDT == NULL)
return 1;
(*ppSFDT)->FDP.Len = 0;
(*ppSFDT)->FDP.OfClu = (*ppSFDT)->FstClu; (*ppSFDT)->FDP.OfSec = 0;
(*ppSFDT)->FDP.OfByte = 0;
*ppSFDT = NULL;
return 0;
}
void PrintDir(void)
{
INT8U i,j,tempa,tempb,tempc,len; ShortFileDirTab *pSFDT;
len = GetSizeQDL(& QuDirList);
for(i=0; i<len; i++)
{
QuDirList.ListNu += 1;
tempa = QuDirList.ListNu / 100 + 48; if(tempa > 48)
UartPutchar(tempa);
else
UartPutchar(' ');
tempb = QuDirList.ListNu % 100; tempc = tempb % 10 + 48;
tempb = tempb / 10 + 48;
if(tempa > 48 || tempb > 48) UartPutchar(tempb);
else
UartPutchar(' ');
UartPutchar(tempc);
UartPutchar('-');
pSFDT = PeekQueueDL(&QuDirList); for(j=0; j<11; j++)
{
if(j == 8)
{
if(pSFDT->SName[j] != ' ')
UartPutchar('.');
}
if(pSFDT->SName[j] != ' ')
UartPutchar(pSFDT->SName[j]);
}
UartPutchar('\n');
}
}
INT32U GetNextClu(INT32U Index, INT8U DiskID)
{
INT32U FATOffset;
INT32U NextClu; //下一个簇号
INT32U ThisFATSceNum; //FAT表中包含该簇号N的扇区号
INT16U ThisFATEntOffset; //该簇号N位于FAT表中FAT项的偏移量
INT8U Data_Buf[512];
Disk_Info *pDI;
Disk_RW_Parameter DP;
pDI = GetDiskInfo(DiskID);
switch(pDI->FilSysType)
{
case FAT16:
FATOffset = Index * 2;
ThisFATSceNum = FATOffset / pDI->BytsPerSec + pDI->RsvdSecCnt + pDI->RelaStaSect;
DP.SectorIndex = ThisFATSceNum;
DP.Buf = Data_Buf;
(* pDI->DiskDrive)(ReadSec, &DP);
ThisFATEntOffset = FATOffset % pDI->BytsPerSec;
NextClu = (INT32U)Data_Buf[ThisFATEntOffset] | (INT32U)(Data_Buf[ThisFATEntOffset + 1] << 8);
break;
case FAT32:
FATOffset = Index * 4;
ThisFATSceNum = FATOffset / pDI->BytsPerSec + pDI->RsvdSecCnt + pDI->RelaStaSect;
DP.SectorIndex = ThisFATSceNum;
DP.B
uf = Data_Buf;
(* pDI->DiskDrive)(ReadSec, &DP);
ThisFATEntOffset = FATOffset % pDI->BytsPerSec;
NextClu = (INT32U)Data_Buf[ThisFATEntOffset] |
(INT32U)(Data_Buf[ThisFATEntOffset + 1] <<
8) |
(INT32U)(Data_Buf[ThisFATEntOffset + 2] << 16) |
(INT32U)(Data_Buf[ThisFATEntOffset + 3] << 24);
break;
}
return(NextClu);
}
INT8U GetFDI(ShortFileDirTab *pSFDT, INT8U DiskID)
{
INT8U i,k,temp,flag;
INT8U Data_Buf[512];
INT16U j;
INT32U NextCluOfFAT; //文件簇链中下一个簇号
INT32U FirstSectorOfCluster; //该簇号第一个扇区号
INT32U FistRootDirSecNum; //根目录第一个扇区号
Disk_Info *pDI;
Disk_RW_Parameter DP;
ShortFileDirTab SFDT;
pDI = GetDiskInfo(DiskID);
IintQueueDL(&QuDirList);
if((pSFDT->Attr == 0xF0) && (pSFDT->FstClu == 0))
{//该卷为FAT16且读的是根目录
FistRootDirSecNum = pDI->RsvdSecCnt + (pDI->NumFATs * pDI->FATSz16) + pDI->RelaStaSect;
FirstSectorOfCluster = FistRootDirSecNum;
flag = 1;
}
else
{
FirstSectorOfCluster = ((pSFDT->FstClu - 2) * pDI->SecPerClus) + pDI->FirstDataSector;
flag = 0;
}
DP.Buf = Data_Buf;
DP.SectorIndex = FirstSectorOfCluster + pSFDT->FDP.OfSec;
(* pDI->DiskDrive)(ReadSec, &DP);
for(i=0; ; )
{
j = pSFDT->FDP.OfByte;
SFDT.SName[0] = Data_Buf[j + OFSDIR_SName];
SFDT.SName[1] = Data_Buf[j + OFSDIR_SName + 1];
SFDT.Attr = Data_Buf[j + OFSDIR_Attr];
if(((SFDT.Attr & ATTR_LONG_NAME_MASK) != ATTR_LONG_NAME) && (SFDT.SName[0] != 0xE5) && (SFDT.SName[0] != 0))
{//找到一个活动的短目录项
if((SFDT.Attr & ATTR_VOLUME) == 0)
{//找到一个文件或子目录
for(k=2; k<11; k++)
{
SFDT.SName[k] = Data_Buf[j + OFSDIR_SName + k];
}
SFDT.FstClu = ((INT32U)Data_Buf[j + OFSDIR_FstCluH + 1] << 24) |
((INT32U)Data_Buf[j + OFSDIR_FstCluH] << 16) |
((INT32U)Data_Buf[j + OFSDIR_FstCluL +1 ] << 8) |
((INT32U)Data_Buf[j + OFSDIR_FstCluL]);
SFDT.FileSize = ((INT32U)Data_Buf[j + OFSDIR_FileSize + 3] << 24) |
((INT32U)Data_Buf[j + OFSDIR_FileSize + 2] << 16) |
((INT32U)Data_Buf[j + OFSDIR_FileSize + 1] << 8) |
((INT32U)Data_Buf[j + OFSDIR_FileSize]);
if((SFDT.SName[0] == '.') && (SFDT.SName[1] == '.'))
{//是dotdot目录(指向上级目录)
for(k=2; k<11; k++)
{
QuDirList.SFDT[MAX_DIR_NU_List -1].SName[k] = SFDT.SName[k];
}
QuDirList.SFDT[MAX_DIR_NU_List -1].Attr = SFDT.Attr;
QuDirList.SFDT[MAX_DIR_NU_List -1].FstClu = SFDT.FstClu;
QuDirList.SFDT[MAX_DIR_NU_List -1].FileSize = SFDT.FileSize;
}
else if(SFDT.SName[0] == '.')
{//是dot目录(指向该目录本身)
for(k=2; k<11; k++)
{
QuDirList.SFDT[MAX_DIR_NU_List -2].SName[k] = SFDT.SName[k];
}
QuDirList.SFDT[MAX_DIR_NU_List -2].Attr = SFDT.Attr;
QuDirList.SFDT[MAX_DIR_NU_List -2].FstClu = SFDT.FstClu;
QuDirLis
t.SFDT[MAX_DIR_NU_List -2].FileSize = SFDT.FileSize;
}
else
{//是普通子目录或文件
EnQueueDL(&QuDirLis
t, &SFDT);
i ++;
}
}
}
else if(SFDT.SName[0] == 0x00)
{//此目录为空,并且后续的磁盘空间都为空
pSFDT->FDP.OfClu = pSFDT->FstClu;
pSFDT->FDP.Len = 0;
pSFDT->FDP.OfByte = 0;
PrintDir();
return 0;
}
j += 32;
if(j > (pDI->BytsPerSec - 32))
{
j = 0;
pSFDT->FDP.OfSec += 1;
if(flag == 0)
{
if(pSFDT->FDP.OfSec >= pDI->SecPerClus)
{//读下一个簇
pSFDT->FDP.OfSec = 0;
pSFDT->FDP.OfClu = GetNextClu(pSFDT->FDP.OfClu, DiskID);
NextCluOfFAT = pSFDT->FDP.OfClu;
if(pDI->FilSysType == FAT16)
{
if((NextCluOfFAT >= 0x0002) && (NextCluOfFAT <= 0xFFEF)) {
FirstSectorOfCluster = ((NextCluOfFAT - 2) * pDI->SecPerClus) + pDI->FirstDataSector;
}
else
{//所有簇已读完
pSFDT->FDP.OfClu = pSFDT->FstClu;
pSFDT->FDP.Len = 0;
pSFDT->FDP.OfSec = 0;
pSFDT->FDP.OfByte = 0;
return 0;
}
}
else if(pDI->FilSysType == FAT32)
{
if((NextCluOfFAT >= 0x00000002) && (NextCluOfFAT <= 0xFFFFFFEF))
{
FirstSectorOfCluster = ((NextCluOfFAT - 2) * pDI->SecPerClus) + pDI->FirstDataSector;
}
else
{//所有簇已读完
pSFDT->FDP.OfClu = pSFDT->FstClu;
pSFDT->FDP.Len = 0;
pSFDT->FDP.OfSec = 0;
pSFDT->FDP.OfByte = 0;
return 0;
}
}
}
}
else if(flag == 1)
{
if(pSFDT->FDP.OfSec >= pDI->RootDirSectors)
{//所有簇已读完
pSFDT->FDP.OfClu = pSFDT->FstClu;
pSFDT->FDP.Len = 0;
pSFDT->FDP.OfSec = 0;
pSFDT->FDP.OfByte = 0;
return 0;
}
}
DP.SectorIndex = FirstSectorOfCluster + pSFDT->FDP.OfSec; (* pDI->DiskDrive)(ReadSec, &DP);//读下一个扇区
}
pSFDT->FDP.OfByte = j;
pSFDT->FDP.Len += 32;
temp = QuDirList.MaxSize - GetSizeQDL(&QuDirList);
if(temp == 0)
{
PrintDir();
i = 0;
}
}
}
INT8U ChangeDir(INT8U DirListIndex, INT8U DriveID)
{
Disk_Info *pDI;
ShortFileDirTab *pSFDT;
pDI = GetDiskInfo(DriveID);
switch(DirListIndex)
{
case '\\':
if(pDI->FilSysType == FAT16)
{
QuDirList.SFDT[MAX_DIR_NU_List - 1].Attr = 0xF0;
QuDirList.SFDT[MAX_DIR_NU_List - 1].FstClu = 0;
QuDirList.SFDT[MAX_DIR_NU_List - 1].FileSize = 0;
GetFDI(&QuDirList.SFDT[MAX_DIR_NU_List - 1],DriveID);
}
else if(pDI->FilSysType == FAT32)
{
QuDirList.SFDT[MAX_DIR_NU_List - 1].Attr = 0xF0;
QuDirList.SFDT[MAX_DIR_NU_List - 1].FstClu = pDI->RootClus;
QuDirList.SFDT[MAX_DIR_NU_List - 1].FileSize = 0;
GetFDI(&QuDirList.SFDT[MAX_DIR_NU_List - 1],DriveID);
}
break;
case '*':
GetFDI(&QuDirList.SFDT[MAX_DIR_NU_List - 1], DriveID);
break;
case '.':
GetFDI(&QuDirList.SFDT[MAX_DIR_NU_List - 2], DriveID);
break;
default:
pSFDT = GetElemQDL(&QuDirList, DirListIndex);
G
etFD
I(pSFDT, DriveID);
}
return 0;
}
INT8U ReadFile(ShortFileDirTab *pSFDT, INT16U Len, INT8U DiskID)
{
INT8U Data_Buf[512];
INT16U i;
INT32U NextCluOfFAT; //文件簇链中下一个簇号
INT32U FirstSectorOfCluster; //该簇号第一个扇区号
Disk_Info *pDI;
Disk_RW_Parameter DP;
if(Len > 512)
{
return PARAMETER_ERR;
}
pDI = GetDiskInfo(DiskID);
DP.Buf = Data_Buf;
if((pSFDT->FDP.Len + Len) <= pSFDT->FileSize)
{
DP.Len = Len;
}
else
{
DP.Len = pSFDT->FileSize - pSFDT->FDP.Len;
}
FirstSectorOfCluster = ((pSFDT->FDP.OfClu - 2) * pDI->SecPerClus) + pDI->FirstDataSector;
DP.SectorIndex = (FirstSectorOfCluster + pSFDT->FDP.OfSec) * 512 + pSFDT->FDP.OfByte;
(* pDI->DiskDrive)(ReadBlock, &DP);
pSFDT->FDP.Len = (pSFDT->FDP.Len + DP.Len) % pSFDT->FileSize;
pSFDT->FDP.OfByte += Len;
pSFDT->FDP.OfSec += pSFDT->FDP.OfByte / 512;
pSFDT->FDP.OfByte %= 512;
for(i=0; i<DP.Len; i++)
{
EnQueueDC(&Disk_Cache, Data_Buf[i]);
}
if(pSFDT->FDP.OfSec >= pDI->SecPerClus)
{//取下一个簇号
pSFDT->FDP.OfSec = 0;
pSFDT->FDP.OfClu = GetNextClu(pSFDT->FDP.OfClu, DiskID);
NextCluOfFAT = pSFDT->FDP.OfClu;
if(pDI->FilSysType == FAT16)
{
if((NextCluOfFAT < 0x0002) || (NextCluOfFAT > 0xFFEF))
{//所有簇已读完
pSFDT->FDP.OfClu = pSFDT->FstClu;
pSFDT->FDP.Len = pSFDT->FileSize;
pSFDT->FDP.OfSec = 0;
pSFDT->FDP.OfByte = 0;
return FILE_EOF;
}
}
else if(pDI->FilSysType == FAT32)
{
if((NextCluOfFAT < 0x00000002) || (NextCluOfFAT > 0xFFFFFFEF))
{//所有簇已读完
pSFDT->FDP.OfClu = pSFDT->FstClu;
pSFDT->FDP.Len = pSFDT->FileSize;
pSFDT->FDP.OfSec = 0;
pSFDT->FDP.OfByte = 0;
return FILE_EOF;
}
}
}
return 0;
}
INT32U GetFileSize(void)
{
return pF->FileSize;
}
INT8U ReadFileByte(void)
{
void FileOperation(INT8U List_NU);
INT8U data;
INT16U len;
data = PeekQueueDC(&Disk_Cache);
len = GetSizeDC(&Disk_Cache);
if(len < 480)
FileOperation('r');
return data;
}
void FileOperation(INT8U List_NU) {
INT8U temp,j;
//INT16U flen;
switch(List_NU)
{
case '\\':
case '*':
case '.':
ChangeDir(List_NU, 'A');
break;
case 'c':
CloseFile(&pF);
break;
case 'r':
if(pF != NULL)
{
if(pF->FDP.Len < pF->FileSize) temp = ReadFile(pF, 32, 'A');
else
CloseFile(&pF);
/*flen = GetSizeDC(&Disk_Cache); if((temp = FILE_EOF) && (flen == 0))
{
UartPrint((void *)("\nfile end"));
}
else
for(i=0; i<flen; i++)
{
temp = PeekQueueDC(&Disk_Cache);
UartPutchar(temp);
}*/
}
break;
default:
if(List_NU > 0 && List_NU <= QuDirList.MaxSize)
{
CloseFile(&pF);
pF = OpenFile(List_NU);
if((pF->Attr & (ATTR_DIRECTORY | ATTR_VOLUME)) == 0x00) {//读取文件中数据
InitQueueDC(&Disk_Cache);
if(p
F != NULL)
{
temp = ReadFile(pF, 512, 'A');
if(temp != FILE_EOF)
{
if(pF->SName[8] == 'M' && pF->SName[9] == 'P' && pF->SName[10] == '3')
{
MP3Handle = MP3CMD_Play;
UartPrint((void *)("\nPlaying "));
for(j=0; j<11; j++)
{
if(j == 8)
{
if(pF->SName[j] != ' ')
UartPutchar('.');
}
if(pF->SName[j] != ' ')
UartPutchar(pF->SName[j]);
}
}
}
/*flen = GetSizeDC(&Disk_Cache);
if((temp = FILE_EOF) && (flen == 0))
{
UartPrint((void *)("\nfile end"));
}
else
for(i=0; i<flen; i++)
{
temp = PeekQueueDC(&Disk_Cache);
UartPutchar(temp);
}*/
}
}
else if((pF->Attr & (ATTR_DIRECTORY | ATTR_VOLUME)) == ATTR_DIRECTORY)
{//改变当前目录
ChangeDir(List_NU, 'A'); }
}
}
}。