📄 fat16.c
字号:
#include <string.h>
#include "..\inc\44b.h"
#include "..\inc\def.h"
#include "..\inc\config.h"
#include "..\inc\fat16.h"
#include "..\inc\flash.h"
#include "..\inc\utils.h"
#ifdef NAND_FLASH_SUPPORT
#define Uart_Printf printf
//#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
#define DISK_32M 32
#define DISK_16M 16
//#define DEBUG_FAT 0 //0不显示信息,为1时显示有关FAT16信息
#define FAT_SIZEOFWORD 8*256
//请注意每个扇区实际为528个字节,最后还有16个字节
BYTE SectorBuffer[512]; //SectorBuffer
BYTE SectorSpare[16]; //Nandflash的备用区,一定要与sectorBuffer连在一起,防止sectorbuffer与clusterbuffer冲突
BYTE ClusterBuffer[32][512]; //ClusterBuffer
WORD FatCache[FAT_SIZEOFWORD];
//extern U8 NFEraseBlock(U32 block);
//extern void NFReadPage(U32 block,U32 page,U8 *pPage);
//extern int WritePage(U32 block,U32 page,U8 *pPage);
//--------------该函数用于将磁盘格式化----------------------------//
//参数说明:
//........Media: Now only for Nandflash
//........Sizeofdisk_M:
//........FilesysType:Now only for fat16
//05-5-10: add invalid block detection and record in spare field of Page1 of the block;
int Fat_Format(U8 Media,U8 Sizeofdisk_M,U8 FilesysType)
{
//PARTSECTOR *partsector;
//PARTRECORD *partrecord;
int i,j,k,fatsec,temp,blocknum;
BOOTSECTOR50 *bootsector;
BPB50 *bpb;
EXTBOOT *ext;
unsigned short badblk_num[20];//最多20个坏簇
const CHAR *litai_str ="LiYuTai ";
const CHAR *armsys_str="ARMSys2005 ";
const CHAR *fat16_str ="FAT16 ";
blocknum=((Sizeofdisk_M<<20)>>9)>>5;
Uart_Printf("\n开始Nand-flash格式化...\n");
for(i=0;i<20;i++)
{
badblk_num[i]=0;
}
for(i=0;i<512;i++)
SectorBuffer[i]=0xff;
j=0;
for(i=0;i<blocknum;i++)
{
if(!(NFEraseBlock(i)))
{
SectorSpare[5]=0x00;
WritePage(i,0,SectorBuffer); //先是512个字节,接着就会读SectorSpare的16个字节
badblk_num[j++]=i;
Uart_Printf("\n第 %d 块为坏块,被标记,可忽略.",i);//Erase Nand-flash NULLed!");
//return 0;
}
}
//Uart_Printf("擦除Nand-flash完成!");
for(i=0;i<512;i++)
SectorBuffer[i]=0xff;
if(Media==NAND_FLASH_Drv) //对Nand-flash进行格式化
{
//Samsung promise block0 is a vaild block
//第0个扇区为DBR
bootsector = (BOOTSECTOR50 *)SectorBuffer;
bpb = (BPB50 *)(bootsector->bsBPB);
ext = (EXTBOOT *)(bootsector->bsExt);
bootsector->bsJump[0] = 0xeb;
bootsector->bsJump[1] = 0x03;
bootsector->bsJump[2] = 0x90;
for(i=0;i<7;i++)
bootsector->bsOemName[i] = *litai_str++;
bootsector->bsOemName[7]='\0';
bootsector->bsBootSectSig0 = BOOTSIG0;
bootsector->bsBootSectSig1 = BOOTSIG1;
bpb->bpbBytesPerSec = 512;
bpb->bpbSecPerClust = 32;
if(FilesysType==PART_TYPE_FAT12||FilesysType==PART_TYPE_DOSFAT16
||FilesysType==PART_TYPE_FAT16||FilesysType==PART_TYPE_FAT16LBA)
bpb->bpbResSectors = 1;
else if(FilesysType==PART_TYPE_FAT32||FilesysType==PART_TYPE_FAT32LBA)
bpb->bpbResSectors = 32;
bpb->bpbFATs = 2;
bpb->bpbRootDirEnts = ((bpb->bpbSecPerClust)-1-(Sizeofdisk_M >> 1)) << 4;
bpb->bpbSectors = Sizeofdisk_M << 11;
bpb->bpbMedia = 0xf0; //必须与FAT[0]一致。
fatsec = bpb->bpbFATsecs = Sizeofdisk_M >> 2;
bpb->bpbSecPerTrack = 0;
bpb->bpbHeads = 0;
bpb->bpbHiddenSecs = 0;
bpb->bpbHugeSectors = Sizeofdisk_M << 11;
ext->exDriveNumber = 0x80;
ext->exReserved1 = 0;
ext->exBootSignature = EXBOOTSIG;
ext->exVolumeID = 0x88331446;
for(i=0;i<10;i++)
ext->exVolumeLabel[i] = *armsys_str++;
ext->exVolumeLabel[10]='\0';
for(i=0;i<7;i++)
ext->exFileSysType[i] = *fat16_str++;
ext->exFileSysType[7]='\0';
memcpy(ClusterBuffer[0],SectorBuffer,512);
//第1个扇区开始是FAT及FAT备份区
for(i=0;i<512;i++)
SectorBuffer[i]=0x00;
for(i=1;i<(fatsec*2+1);i++)
memcpy(ClusterBuffer[i],SectorBuffer,512);
ClusterBuffer[1][0]=0xf0; //0xf8
ClusterBuffer[1][1]=0xff;
ClusterBuffer[1][2]=0xff;
ClusterBuffer[1][3]=0xff;
ClusterBuffer[fatsec+1][0]=0xf0; //0xf8
ClusterBuffer[fatsec+1][1]=0xff;
ClusterBuffer[fatsec+1][2]=0xff;
ClusterBuffer[fatsec+1][3]=0xff;
for(i=0;i<20;i++)
{
if(badblk_num[i]!=0)
{
j=(badblk_num[i]>>8)+1;
k=((badblk_num[i])&0xff)<<1;
ClusterBuffer[j][k]=0xf7;
ClusterBuffer[j][k+1]=0xff;
ClusterBuffer[fatsec+j][k]=0xf7;
ClusterBuffer[fatsec+j][k+1]=0xff;
}
}
//从第fatsec*2+1个扇区开始,是根目录区,到簇的最后,应该清零
for(i=fatsec*2+1;i<32;i++)
memcpy(ClusterBuffer[i],SectorBuffer,512);
for(i=0;i<32;i++) //一扇区接一扇区写入
{
for(j=0;j<255;j++); //延时
temp=WritePage(0,i,ClusterBuffer[i]);
if(temp==0)
{
Uart_Printf("\n格式化Nand-flash失败!");
return 0;
}
}
FatInit(1);
i=Fat_mkdir("\\code");
if(i!=0)
Uart_Printf("\n文件夹'code'未建立。");
Uart_Printf("\n格式化Nand-flash完成!\n");
return 1;
}
return 0;
}
//PARTRECORD PartInfo;
unsigned char Fat32Enabled;
unsigned int FirstDataSector;
unsigned int BytesPerSector;
unsigned int FATsectors;
unsigned int SectorsPerCluster;
unsigned int FirstFATSector;
unsigned int FirstDirSector;
unsigned int FileSize;
unsigned int FatInCache = 0;
DWORD RootDirSectors; // Numbers of sectors occupied by Root Directory.
DWORD RootDirCount;
//--------------该函数主要用于从已有的存储介质中获得文件系统信息------------------//
unsigned char FatInit(int show)
{
BOOTSECTOR50 *bootsector;
BPB50 *bpb;
EXTBOOT *ext;
int i,j;
//Uart_Printf("\n Nandflash 读取信息。");
for(j=0;j<255;j++);
NFReadPage(0,0,SectorBuffer);
bootsector = (BOOTSECTOR50 *)SectorBuffer;
bpb = (BPB50 *)(bootsector->bsBPB);
ext = (EXTBOOT *)(bootsector->bsExt);
// setup global disk constants
FirstDataSector = 0; //PartInfo.prStartLBA;
if(bpb->bpbFATsecs)
{
// bpbFATsecs is non-zero and is therefore valid
FirstDirSector += bpb->bpbResSectors + bpb->bpbFATs * bpb->bpbFATsecs;
//FAT12,16 =1 =2(2份FAT,其中1份为备份)×每一份FAT所占用的sector数
}
SectorsPerCluster = bpb->bpbSecPerClust;//每cluster的sector数目
BytesPerSector = bpb->bpbBytesPerSec;//每sector的字节数
FirstFATSector = bpb->bpbResSectors + 0;//PartInfo.prStartLBA;//FAT区的起始地址
FATsectors = bpb->bpbFATsecs;
FirstDataSector = FirstDirSector+((bpb->bpbRootDirEnts)>>4);
RootDirCount = bpb->bpbRootDirEnts;
RootDirSectors = (RootDirCount*32)>>9;
if((SectorsPerCluster==0x00)||(SectorsPerCluster==0xff)||(BytesPerSector==0x00)||(BytesPerSector==0xff)
||(SectorBuffer[510]!=0x55)||(SectorBuffer[511]!=0xaa))
{
Uart_Printf("\n Nandflash没有被格式化,运行NFormat工具可对其进行格式化。\n");
return 1;
}
//#if DEBUG_FAT
if(show==1)
{
Uart_Printf("\nOEM name : %s",(char *)(bootsector->bsOemName));
//Uart_Printf("\nFirst sector : %4x",PartInfo.prStartLBA);
//Uart_Printf("\nSize : %4x",PartInfo.prSize);
Uart_Printf("\nbytes per sector : %4d",bpb->bpbBytesPerSec);
Uart_Printf("\nsectors per cluster : %4d",bpb->bpbSecPerClust);
Uart_Printf("\nreserved sectors : %4d",bpb->bpbResSectors);
Uart_Printf("\nRootDir Entrys : %4d",bpb->bpbRootDirEnts);
Uart_Printf("\nTolSectors : %4d",bpb->bpbSectors);
Uart_Printf("\nFatSectors : %4d",bpb->bpbFATsecs);
//Uart_Printf("\nBigFatSectors : %4x",bpb->bpbBigFATsecs);
Uart_Printf("\nNumber of Fats : %4d",bpb->bpbFATs);
Uart_Printf("\nFirst Fat Sector : %4d",FirstFATSector);
Uart_Printf("\nFirst Dir sector : %4d",FirstDirSector);
Uart_Printf("\nFirst Data Sect : %4d",FirstDataSector);
Uart_Printf("\nVolNumber : %x",(unsigned int)(ext->exVolumeID));
Uart_Printf("\nVolumeLabel : %s\n",(char *)(ext->exVolumeLabel));
}
//#endif
for(i=0;i<FATsectors;i++)
{
NFReadPage(0,i+1,SectorBuffer);
for(j=0;j<256;j++)
{
FatCache[i*256+j] = SectorBuffer[j*2] + (SectorBuffer[j*2+1] << 8);
}
}
return 0;
}
//一个测试程序
void Fat16_Nandflash_test(void)
{
int x,result,i;
char buff[]="fangajfdklsafjasfa;lfs;l";
if(1)///Fat_Format(NAND_FLASH_Drv,DISK_16M,PART_TYPE_FAT16))
{
//FatInit();
result=Fat_mkdir("\\abcde");
Uart_Printf("\nfat_mkdir's result=%d",result);
Fat_mkdir("\\code");
x = Fat_creat("\\code\\fang123.txt", 0x27);//0x27:txt file?
Uart_Printf("\nfat_creat's file handle=%d",x);
Fat_write(x, buff, 20);//将buff中10个字节内容写入文件x
Fat_lseek(x, 0, SEEK_SET);
memset(buff, 0, sizeof(buff));
Uart_Printf("\nfat_read buff=");
Fat_read(x, buff, 20);
for(i=0;i<20;i++)
Uart_Printf("%c",buff[i]);
Fat_close(x);
x=Fat_open("\\code\\fang123.txt");
Uart_Printf("\nfat_open's result=%d",x);
Uart_Printf("\nfat_read buff=");
Fat_read(x, buff, 15);
for(i=0;i<15;i++)
Uart_Printf("%c",buff[i]);
Fat_close(x);
result=Fat_rename("\\code\\fang123.txt", "fang321.txt");
Uart_Printf("\nfat_rename's result=%d",x);
x=Fat_open("\\code\\fang321.txt");
Uart_Printf("\nfat_open's result=%d",result);
Uart_Printf("\nfat_read buff=");
Fat_read(x, buff, 20);
for(i=0;i<20;i++)
Uart_Printf("%c",buff[i]);
result=Fat_remove("\\code\\fang321.txt");
Uart_Printf("\nfat_remove's result=%d",result);
x=Fat_open("\\code\\fang321.txt");
Uart_Printf("\nfat_open's result=%d",x);
//result=Fat_rename("\\abcde\\", "abcd12");
//Uart_Printf("\nfat_rename's result=%d",result);
result=Fat_rmdir("\\abcde");
Uart_Printf("\nfat_rmdir's result=%d\n",result);
}
}
void FlushFAT() //更新fat表
{
int i,j;
NFReadPage(0,0,SectorBuffer);
memcpy(ClusterBuffer[0], SectorBuffer, BytesPerSector); //backup Sector0
for(i=FirstDirSector;i<SectorsPerCluster;i++)
{
NFReadPage(0,i,SectorBuffer);
memcpy(ClusterBuffer[i],SectorBuffer,BytesPerSector);
}
for(i=0;i<FATsectors;i++)
{
for(j=0;j<256;j++)
{
SectorBuffer[j*2]=(FatCache[i*256+j])%256;
SectorBuffer[j*2+1]=(FatCache[i*256+j])>>8;
}
memcpy(ClusterBuffer[i+FirstFATSector],SectorBuffer,BytesPerSector);
}
for(i=0;i<FATsectors;i++)//backup FAT field
{
for(j=0;j<256;j++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -