?? fat.c
字號:
/**********************************************************************************************
**
** Copyright(c) Semitek
**
** 模 塊 名:fat.c
**
** 模塊功能:實現有關FAT16文件系統的操作
**
** 修改日期:2007年4月5日
**
**********************************************************************************************/
#include "fat.h"
BYTE cluster_size = 0;//每簇的扇區數
WORD sector_size = 0;//每扇區的字節數
DWORD RootDir_Start_SecNum = 0;//根目錄開始扇區號
DWORD Data_Start_SecNum = 0;//數據區開始扇區號
DWORD FAT1_Start_SecNum = 0;//FAT1開始扇區號
DWORD FAT2_Start_SecNum = 0;//FAT2開始扇區號
WORD DIR_FstClusHI = 0;//起始簇號的高16位
WORD DIR_FstClusLO = 0;//起始簇號的低16位
DWORD EmptyCluster = 0;//FAT中空閑的簇號
DWORD TotalSector = 0;
DWORD WriteData_Addr = 0;//寫數據地址
extern BYTE MMCRDData[MMC_DATA_SIZE];
extern BYTE MMCWRData[MMC_DATA_SIZE];
/**********************************************************************************************
**
** 函數名稱:GetFatInfo
**
** 函數功能:讀MMC的0扇區,獲得有關FAT的基本信息
**
** 輸入參數:無
**
** 返 回 值:無
**
** 影響參數:cluster_size,fat_offset,cluster_offset,RootDir_Start_SecNum,Data_Start_SecNum
**
** 調用模塊:mmc_read_block()
**
** 說 明:無
**
**********************************************************************************************/
void GetFatInfo()
{
BYTE BS_jmpBoot[3]; //跳轉指令
BYTE BS_OEMName[8]; //制造商名稱
WORD BPB_BytesPerSec;//字節/扇區
BYTE BPB_SecPerClus; //扇區/簇
WORD BPB_RsvdSecCnt; //保留扇區數
BYTE BPB_NumFATs; //FAT表數目
WORD BPB_RootEntCnt; //根目錄項數
WORD BPB_TotSec16; //小于32MB的扇區數
BYTE BPB_Media; //媒體描述符
WORD BPB_FATSz16; //每個FAT表所占扇區數
WORD BPB_SecPerTrk; //每磁道上的扇區數
WORD BPB_NumHeads; //磁頭數
DWORD BPB_HiddSec; //隱藏扇區數
DWORD BPB_TotSec32; //大于32MB的扇區數
mmc_read_block(MASTER_BOOT_RECORD);
BPB_BytesPerSec = MMCRDData[OFFSET_BPB_BytesPerSec] | (MMCRDData[OFFSET_BPB_BytesPerSec+1]<<8);
BPB_SecPerClus = MMCRDData[OFFSET_BPB_SecPerClus];
BPB_RsvdSecCnt = MMCRDData[OFFSET_BPB_RsvdSec] | (MMCRDData[OFFSET_BPB_RsvdSec+1]<<8);
BPB_NumFATs = MMCRDData[OFFSET_BPB_NumFATs];
BPB_RootEntCnt = MMCRDData[OFFSET_BPB_RootEntCnt] | (MMCRDData[OFFSET_BPB_RootEntCnt+1]<<8);
BPB_TotSec16 = MMCRDData[OFFSET_BPB_TotSec16] | (MMCRDData[OFFSET_BPB_TotSec16+1]<<8);
BPB_Media = MMCRDData[OFFSET_BPB_Media];
BPB_FATSz16 = MMCRDData[OFFSET_BPB_FATSz16] | (MMCRDData[OFFSET_BPB_FATSz16+1]<<8);
BPB_SecPerTrk = MMCRDData[OFFSET_BPB_SecPerTrk] | (MMCRDData[OFFSET_BPB_SecPerTrk+1]<<8);
BPB_NumHeads = MMCRDData[OFFSET_BPB_NumHeads] | (MMCRDData[OFFSET_BPB_NumHeads+1]<<8);
BPB_HiddSec = MMCRDData[OFFSET_BPB_HiddSec] | (MMCRDData[OFFSET_BPB_HiddSec+1]<<8) | (MMCRDData[OFFSET_BPB_HiddSec+2]<<16) | (MMCRDData[OFFSET_BPB_HiddSec+3]<<24);
BPB_TotSec32 = MMCRDData[OFFSET_BPB_TotSec32] | (MMCRDData[OFFSET_BPB_TotSec32+1]<<8) | (MMCRDData[OFFSET_BPB_TotSec32+2]<<16) | (MMCRDData[OFFSET_BPB_TotSec32+3]<<24);
RootDir_Start_SecNum = BPB_RsvdSecCnt + (BPB_NumFATs * BPB_FATSz16);
Data_Start_SecNum = RootDir_Start_SecNum + (32*BPB_RootEntCnt + (BPB_BytesPerSec -1))/BPB_BytesPerSec;
cluster_size = BPB_SecPerClus;
sector_size = BPB_BytesPerSec;
FAT1_Start_SecNum = BPB_RsvdSecCnt;
FAT2_Start_SecNum = BPB_RsvdSecCnt + BPB_FATSz16;
TotalSector = BPB_TotSec32;
return;
}
/**********************************************************************************************
**
** 函數名稱:UpDataRootDir
**
** 函數功能:更新根目錄內容
**
** 輸入參數:文件名,文件大小
**
** 返 回 值:暫無
**
** 影響參數:暫無
**
** 調用模塊:mmc_read_block,mmc_write_block
**
** 說 明:根目錄是以32字節為單位進行讀寫,讀寫前要將文件名轉換成大寫字母
**
**********************************************************************************************/
void UpDataRootDir(BYTE *Name,DWORD FileSize,BYTE FileAttrib)
{
BYTE Buffer[11];
BYTE i,j,k = 0;
for(i=0;i<8;i++)
{
if(*Name != '.' && *Name != '\0')
{
Buffer[i] = *Name;
}
else
{
goto Label;
}
Name++;
Label: Buffer[i+1] = 0x20;
}
for(i=0;i<3;i++)
{
Name++;
if(*Name != 0) Buffer[i+8] = *Name;
else Buffer[i+8] = 0x20;
}
mmc_read_block(RootDir_Start_SecNum);
for(i=0;i<16;i++)
{
if(MMCRDData[i*32] == 0x00 || MMCRDData[i*32] == 0xE5)
{
break;
}
}
k = i << 5;
for(j=0;j<11;j++)
MMCRDData[k + j] = Buffer[j];//主文件名+擴展文件名,為8.3格式
MMCRDData[k + 11] = FileAttrib;//文件屬性
MMCRDData[k + 12] = 0x00;//僅長文件名目錄使用,對于FAT16不使用
MMCRDData[k + 13] = 0x00;
MMCRDData[k + 14] = 0X79;//文件建立時間
MMCRDData[k + 15] = 0X6C;
MMCRDData[k + 16] = 0X85;//文件建立日期
MMCRDData[k + 17] = 0X36;
MMCRDData[k + 18] = 0x85;//文件最近訪問日期
MMCRDData[k + 19] = 0x36;
MMCRDData[k + 20] = 0x00;//系統保留
MMCRDData[k + 21] = 0x00;
MMCRDData[k + 22] = 0x68;//最新修改時間
MMCRDData[k + 23] = 0X77;
MMCRDData[k + 24] = 0x83;//最新修改日期
MMCRDData[k + 25] = 0x36;
MMCRDData[k + 26] = (DIR_FstClusLO & 0x00FF) >> 0x00;//起始簇號16位
MMCRDData[k + 27] = (DIR_FstClusLO & 0xFF00) >> 0x08;
MMCRDData[k + 28] = (FileSize & 0x000000FF) >> 0x00;//文件大小
MMCRDData[k + 29] = (FileSize & 0x0000FF00) >> 0x08;
MMCRDData[k + 30] = (FileSize & 0x00FF0000) >> 0x10;
MMCRDData[k + 31] = (FileSize & 0xFF000000) >> 0x18;
mmc_write_block(RootDir_Start_SecNum,MMCRDData);
return;
}
/**********************************************************************************************
**
** 函數名稱:FATGetNextClus
**
** 函數功能:返回FAT表指定簇的下一個簇號
**
** 輸入參數:從FAT表中讀到的數組
**
** 返 回 值:下一個簇號
**
** 影響參數:暫無
**
** 調用模塊:暫無
**
** 說 明:暫無
**
**********************************************************************************************/
DWORD FATGetNextClus(BYTE *Buf)
{
WORD i;
for(i=0;i<512;i+=2)
{
if(*(Buf+i) == 0xFF && *(Buf+i+1)== 0xFF && *(Buf+i+2) == 0x00 && *(Buf+i+3) == 0x00) break;
}
return ((i+2) >> 1);
}
/**********************************************************************************************
**
** 函數名稱:UpDataFAT
**
** 函數功能:更新FAT表
**
** 輸入參數:文件大小
**
** 返 回 值:暫無
**
** 影響參數:暫無
**
** 調用模塊:mmc_read_block,mmc_write_block,FATGetNextClus
**
** 說 明:FAT表是個鏈表,在根目錄中得到簇號,然后根據文件所占的簇數進行寫入
**
**********************************************************************************************/
void UpDataFAT(DWORD FileSize)
{
DWORD File_TolCluster = 0;
WORD i = 0,j = 0,k = 0,cluster = 0;
for(k=0;k<64;k++)
{
mmc_read_block(FAT1_Start_SecNum+k);
if(k ==0)
{
EmptyCluster = FATGetNextClus(MMCRDData);
j = EmptyCluster+1;
cluster = EmptyCluster;
}
for(i = 0;i < 512;i += 2)
{
cluster++;
if(k == 0)
{
MMCRDData[i+4] = cluster & 0x00FF;
MMCRDData[i+5] = (cluster & 0xFF00) >> 8;
if(i == 506) break;
}
else
{
MMCRDData[i] = cluster & 0x00FF;
MMCRDData[i+1] = (cluster & 0xFF00) >> 8;
}
}
if(k == 63)
{
MMCRDData[i-2] = 0xFF;
MMCRDData[i-1] = 0xFF;
}
mmc_write_block(FAT1_Start_SecNum+k,MMCRDData);
mmc_write_block(FAT2_Start_SecNum+k,MMCRDData);
}
DIR_FstClusHI = (EmptyCluster & 0xFFFF0000) >> 0x10;
DIR_FstClusLO = (EmptyCluster & 0x0000FFFF) >> 0x00;
File_TolCluster = FileSize >> 0x0A; //文件所占的簇數 = 文件大小 >> 10
WriteData_Addr = Data_Start_SecNum + (EmptyCluster - 2) * sector_size;//文件內容所寫的地址=數據區起始扇區號+(簇號-2)*每扇區所占字節數
return;
}
/**********************************************************************************************
**
** 函數名稱:CreateFile
**
** 函數功能:創建以FileName為文件名、WriteData為文件內容的文件
**
** 輸入參數:FileName->文件名;WriteData->待寫數據
**
** 返 回 值:暫無
**
** 影響參數:暫無
**
** 調用模塊:UpDataFAT,UpDataRootDir,WriteFile
**
** 說 明:創建文件流程:WriteFat->WriteRootDir->WriteData
**
**********************************************************************************************/
void CreateFile(BYTE *FileName,BYTE *WriteData,DWORD FileSize)
{
BYTE Rt,Name_Buffer[12];
DWORD Time=0,LastAddr = 0;
memcpy(Name_Buffer,FileName,12);
strupr(Name_Buffer);
Time = GetRecord();
LastAddr = FindFileEnd();
Rt = ChkFileExist(Name_Buffer);
if(Rt == 0)//文件不存在,新建文件并寫入數據
{
UpDataFAT(FileSize);//寫FAT表
UpDataRootDir(Name_Buffer,FileSize,0x01);//寫根目錄
WriteFile(WriteData_Addr,FileSize,WriteData);//寫數據
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -