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

📄 file.c

📁 实现了fat16文件系统的读写控制
💻 C
📖 第 1 页 / 共 2 页
字号:
/*-----------------------------------------------------------
*文 件 名: file.c
*功能描述: 完成文件系统的基本操作,创建文件,打开文件,读写文件等操作
*作    者:
*----------------------------------------------------------*/

//--------------------------------------------------------
//INCLUDES
//--------------------------------------------------------
#include "file.h"

//------------------------------------------------------------
//*函数名称:init_FileSystem()
//*功能描述:读取文件系统的BPB,获得磁盘的基本参数
			
//*形式参数:void  
//*返 回 值:unsigned char,若为FAT16则返回1,若不是则返回其他值
//-------------------------------------------------------------
unsigned char init_FileSystem()
{
	unsigned char file_type=0;

	read_partition();		//读取分区表中的信息
	BootStartSector = partitionTable1.SectorsPrecedingPartition;
	//喂狗
WDTCN=0xa5;	
	read_BPB();				//获取BPB中的基本参数
	compute_BPB();			//计算BPB中的基本参数

	if(RootDirSectors == 0)
		file_type = 2;		//文件系统为FAT32
	if((CountofClusters>0) && (CountofClusters<=4085))
		file_type = 3;		//文件系统为FAT12
	if((CountofClusters>4085) && (CountofClusters<=65525))
		file_type = 1;		//文件系统为FAT16

	return file_type;
} 

/*------------------------------------------------------------
*函数名称:create_file()
*功能描述:创建新文件
*形式参数:unsigned char * name;要创建的文件的名称
*返 回 值:void
*---------------------------------------------------------------*/
void create_file(unsigned char * file_name,unsigned char * type)
{
	unsigned char flag=0;
	unsigned int xdata i;
	unsigned int xdata j;
	unsigned int xdata k;
	unsigned char xdata *p;
	unsigned int xdata *pcluster;
	unsigned char xdata name[8];
	unsigned char xdata file_type[3];

	//对文件名的整理
	for(i=0;i<strlen(file_name);i++)
		name[i]=*(file_name+i);
	for(i=strlen(file_name);i<8;i++)
		name[i]=0x20;
	//对文件类型的整理
	for(i=0;i<strlen(type);i++)
		file_type[i]=*(type+i);
	for(i=strlen(type);i<3;i++)
		file_type[i]=0x20;
	//喂狗
WDTCN=0xa5;	
//*********在FAT1中查找是否有闲置的单元存在,有则分配给所要创建的文件。FAT1占BPB.BPB_FATSz16
	for(i=0;i<BPB.BPB_FATSz16;i++)	//BPB.BPB_FATSz16:一个FAT表所占的扇区数
	{
		mmc_readblock(FAT1_FirstSector+i,buffer);	//读出FAT表中第i个扇区的内容
		
		pcluster=(unsigned int xdata *)buffer;	//转换为整型指针给pcluster

		for(j=0;j<256;j++)			//在FAT表的第i个扇区找是否有空闲的簇存在,16位表示一个扇区是否被占用
			if(*(pcluster+j) == 0)
			{
				flag =1;
				break;
			}
		if(flag ==1)
		{
			flag =0;
			break;
		}

	}
	//喂狗
WDTCN=0xa5;	
	if(i<BPB.BPB_FATSz16)		//有空闲的簇分配给新文件
	{
		
				
		strcpy(FileIndex.FileName.NAME,name);		//将要创建的文件名放入文件索引中
		strcpy(FileIndex.FileName.TYPE,file_type);		//要要创建的文件的类型放入文件索引中
		FileIndex.FileAttrib=0x20;			//文件属性值


		FileIndex.FilePosit.Size=0x00;		//新创建的为空文件
		fileSize=0x00000000;				//更新文件大小,新建文件大小为0
		FileIndex.FilePosit.Start=0x0000;	//文件的起始簇号

		FAT_writeFlag =1;		//允许在写时将FAT表对应的项写入值

		//文件位置信息
		filePosition.ClusID	= (i*256)+j;			//文件地址的基本信息
		filePosition.SecOfClus = 0;
		filePosition.ByteOfSec = 0;
	//喂狗
WDTCN=0xa5;		
	//**************************文件时间值的填充************
		file_time(0);					//填充文件的创建时间值
		
		//在root 中寻找空的目录项
		for(i=0;i<RootDirSectors;i++)
		{
			mmc_readblock(FDT_FirstSector+i,buffer);	//读出root中第i个扇区的内容
			
		//	if(i==0)				//当为根目录的第一个扇区时,从offset =64开始查找
		//		j=64;		
		//	else
				j=0;
			while(j<512)
			{
				//喂狗
WDTCN=0xa5;	
				if((buffer[j]==0x00)||(buffer[j]==0xe5))
				{
					flag=1;
					break;
				}
				j +=32;
			}
			if(flag==1)
			{
				flag=0;
				break;
			}
		}
	
		p=(unsigned char xdata *)(FileIndex.FileName.NAME);
		mmc_readblock(FDT_FirstSector+i,buffer);
		
		for(k=j;k<j+32;k++)
			buffer[k]=*(p++);
		mmc_writeblock(FDT_FirstSector,buffer);	//写入将要创建的文件索引

		FileIndex.FilePosit.Start=filePosition.ClusID;	//文件的起始簇号
			//转换为大端模式,unsigned int
		p=(unsigned char xdata *)(&FileIndex.FilePosit.Start);
		{
			unsigned char temp;
			temp=*p;
			*p=*(p+1);
			*(p+1)=temp;
		}

		fileIndexPosition.secotor =FDT_FirstSector+i;
		fileIndexPosition.ByteOfSec=j;
	}
} 

/*------------------------------------------------------------
*函数名称:write_file(unsigned char xdata *buffer)
*功能描述:向打开的文件中写入数据
*形式参数:void  
*返 回 值:void
*---------------------------------------------------------------*/
void write_file(unsigned char xdata *dataBuffer)
{
	unsigned char xdata *p;
	unsigned int xdata *pcluster;
 
	unsigned int xdata offset;
	
	unsigned long  xdata currentCluster;			//当前要写入的簇号
	unsigned int xdata nextCluster;			//下一个簇号
 
	unsigned long xdata currentSector;			//当前要写入的扇区数
	
	currentCluster = filePosition.ClusID;

		//喂狗
WDTCN=0xa5;	
	
	if(FAT_writeFlag == 1)
	{
		FAT_writeFlag = 0;		
		//初始化FAT表
		offset = currentCluster/256;
		mmc_readblock(FAT1_FirstSector+offset,buffer);
		pcluster=(unsigned int xdata *)buffer;	//转换为整型指针给pcluster
	
		*(pcluster+currentCluster%256)=0xffff;
		mmc_writeblock(FAT1_FirstSector+offset,buffer);	//更新FAT表

		mmc_readblock(FAT2_FirstSector+offset,buffer);
		pcluster=(unsigned int xdata *)buffer;	//转换为整型指针给pcluster
	
		*(pcluster+currentCluster%256)=0xffff;
		mmc_writeblock(FAT2_FirstSector+offset,buffer);	//更新FAT表
	}
	//--------------------------------------------------------------------------------
	currentSector = FirstDataSector + (currentCluster -2)*BPB.BPB_SecPerClus + filePosition.SecOfClus;

	mmc_writeblock(currentSector,dataBuffer);			//将数据写入相应的扇区

	fileSize +=BPB.BPB_BytsPerSec;					//更新文件大小

	filePosition.SecOfClus++;

	//还需要考虑簇数要符合要求
	if(filePosition.SecOfClus>BPB.BPB_SecPerClus-1)
	{
		filePosition.SecOfClus=0;

		nextCluster=get_freeClusterID(currentCluster);  //或许下一个簇号
		
		if(nextCluster>0)
		{
			filePosition.ClusID =nextCluster;	//将当前指向的簇号更新
						
			FAT_writeFlag = 1;
			//转换为大端模式,unsigned int
			p=(unsigned char xdata *)(&nextCluster);
			{
				unsigned char temp;
				temp=*p;
				*p=*(p+1);
				*(p+1)=temp;
			}
				//喂狗
WDTCN=0xa5;	
			offset = currentCluster/256;
			mmc_readblock(FAT1_FirstSector+offset,buffer);
			pcluster=(unsigned int xdata *)buffer;	//转换为整型指针给pcluster
	
			*(pcluster+currentCluster%256)=nextCluster;		//大小端可能会需要变化
			mmc_writeblock(FAT1_FirstSector+offset,buffer);	//更新FAT表
			
			mmc_readblock(FAT2_FirstSector+offset,buffer);
			pcluster=(unsigned int xdata *)buffer;	//转换为整型指针给pcluster
	
			*(pcluster+currentCluster%256)=nextCluster;		//大小端可能会需要变化
			mmc_writeblock(FAT2_FirstSector+offset,buffer);	//更新FAT表
			//保存文件
			close_file();
		}
	}
}  

/*------------------------------------------------------------
*函数名称:close_file()
*功能描述:保存文件,更新文件索引表
*形式参数:void  
*返 回 值:void
*---------------------------------------------------------------*/
void close_file()
{
	unsigned int i;
	unsigned char xdata *p;
	//更新文件索引表

	//更新文件大小
	FileIndex.FilePosit.Size = fileSize;				//注意大端小端的问题
	
	//转换为大端模式 ,unsigned long 
	p=(unsigned char xdata *)(&FileIndex.FilePosit.Size);
	for(i=0;i<2;i++)
	{
		unsigned char temp;

		temp=*(p+(3-i));
		*(p+(3-i))=*(p+i);
		*(p+i)=temp;
	}
		//喂狗
WDTCN=0xa5;	
	mmc_readblock(fileIndexPosition.secotor,buffer);

	file_time(1);				//填充文件的更新时间值

	p=(unsigned char xdata *)(FileIndex.FileName.NAME);
	
	for(i=fileIndexPosition.ByteOfSec;i<fileIndexPosition.ByteOfSec+32;i++)
		buffer[i]=*(p++);

	mmc_writeblock(fileIndexPosition.secotor,buffer);	//更新文件索引
}
/*------------------------------------------------------------
*函数名称:unsigned int get_clusterID(unsigned int currentCluster)
*功能描述: 从形式参数开始,找一个未用的簇,然后返回簇号
*形式参数:unsigned int
*返 回 值:unsigned int :簇号
*---------------------------------------------------------------*/
unsigned int get_freeClusterID(unsigned int currentCluster)
{
	unsigned char xdata flag=0;
	unsigned int  xdata i;
	unsigned int  xdata j;
	unsigned int xdata offset;
	unsigned int xdata *pcluster;
	unsigned int clusterID=0;


	offset = currentCluster/256;

	for(i=offset;i< BPB.BPB_FATSz16;i++)
	{
		//喂狗
WDTCN=0xa5;	
		mmc_readblock(FAT1_FirstSector+i,buffer);
		
		pcluster=(unsigned int xdata *)buffer;	//转换为整型指针给pcluster

		if(i== offset)
			j=currentCluster%256;
		else
			j=0;
		while(j<256)
		{
				//喂狗
WDTCN=0xa5;	
			if(*(pcluster+j) == 0)
			{
				flag=1;
				break;
			}
			else			
				j++;
		}
		if(flag==1)
		{
			flag=0;
			break;
		}
	}
	clusterID=256*i+j;

	return clusterID;
}

/*------------------------------------------------------------
*函数名称:unsigned int get_freeRom()
*功能描述:由基本参数,计算MMC卡中剩余的空间,返回值以M为单位
*形式参数:void  
*返 回 值:空闲的空间,单位为M
*---------------------------------------------------------------*/
unsigned int get_freeRom()
{
	unsigned int rom=0;      //空闲的空间
	unsigned long value=0;						//注意数值间的转换运算

		//喂狗
WDTCN=0xa5;	
	value =get_freeCluster();
	//喂狗
WDTCN=0xa5;	
	value *= (BPB.BPB_SecPerClus*BPB.BPB_BytsPerSec);
	//喂狗
WDTCN=0xa5;	
	rom = (int)(value/1000000);	

	return rom;
} 
/*------------------------------------------------------------
*函数名称:unsigned int get_freeCluster()
*功能描述:在FAT1表中查找空闲的簇,并返回空闲簇的簇数
*形式参数:void  
*返 回 值:空闲簇的簇数
*---------------------------------------------------------------*/ 
unsigned int get_freeCluster()
{
	unsigned int xdata i;
	unsigned int xdata j;
	unsigned int freeClusterNum = 0;	//空闲簇计数
	unsigned int value = 0;				//提取FAT中对应簇的值

	for(i=0;i<BPB.BPB_FATSz16;i++)
	{
		mmc_readblock(FAT1_FirstSector+i,buffer);
	
	//喂狗
		WDTCN=0xa5;	
		for(j=0;j<256;j++)
		{
				//喂狗
			WDTCN=0xa5;	
			value = *(int *)(buffer+2*j);

			if(value == 0)
				freeClusterNum++;
		}
	}
	return freeClusterNum;
}

/*------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -