⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fat16.c

📁 杭州立宇泰ARMsys-P型ARM开发板BIOS代码
💻 C
📖 第 1 页 / 共 3 页
字号:
#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 + -