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

📄 fat16.c

📁 FAT32文件系统的存储机制及其在单片机上的实现,已通过
💻 C
📖 第 1 页 / 共 3 页
字号:
}

//display the content of a foler , 0 as root directory
unsigned char FAT16_DisDir(unsigned char *dir)
{
	//unsigned char *buffer;
	unsigned long sector;
	unsigned int cluster;
	unsigned long tempclust;
	unsigned char cnt;
	unsigned int offset;
	unsigned char i;
	struct direntry *item = 0;
	Printf("Fat16 dis dir..",0);
	cluster = FAT16_OpenDir(dir);
	Printf("open dir of Fat16 dis dir..",0);
	if(cluster == 1)return 1;
	Printf("step 1 of Fat16 dis dir..",0);
	if(cluster==0)// root directory
	{
		//buffer=malloc(512);//apply memory
		//if(buffer==0)return 1;//if failed
		for(cnt=0;cnt<RootDirSectors;cnt++)
		{
			if(FAT16_ReadSector(FirstDirSector+cnt,buffer))
			{
			 free(buffer);
			 return 1;
			}
			for(offset=0;offset<512;offset+=32)
			{
				item=(struct direntry *)(&buffer[offset]);//pointer convert
				//find a valid item and display it
				if((item->deName[0] != '.') & (item->deName[0] != 0x00) & (item->deName[0] != 0xe5) & (item->deAttributes != 0x0f))
				{
					send(0x0d);
					send(0x0a);
					for(i=0;i<8;i++)//name
					{
						send(item->deName[i]);	
					}
					if((item->deAttributes & 0x10)==0)
					 send('.');
					for(i=0;i<3;i++)//extention
					{
						send(item->deExtension[i]);
					}
				}
			}
		}
		free(buffer);//release
	}
	else//other folders
	{
		tempclust=cluster;
		while(1)
		{
			sector=FirstDataSector+(unsigned long)(tempclust-2)*(unsigned long)SectorsPerClust;//calculate the actual sector number
			//buffer=malloc(512);//apply memory
			//if(buffer==0)return 1;//if failed
			for(cnt=0;cnt<SectorsPerClust;cnt++)
			{
				if(FAT16_ReadSector(sector+cnt,buffer)){free(buffer);return 1;}
				for(offset=0;offset<512;offset+=32)
				{
					item=(struct direntry *)(&buffer[offset]);
					if((item->deName[0] != '.') & (item->deName[0] != 0x00) & (item->deName[0] != 0xe5) & (item->deAttributes != 0x0f))
					{
						send(0x0d);
						send(0x0a);
						for(i=0;i<8;i++)
						{
							send(item->deName[i]);	
						}
						if((item->deAttributes & 0x10)==0)send('.');
						for(i=0;i<3;i++)
						{
							send(item->deExtension[i]);
						}
					}
				}
			}
			free(buffer);//release
			tempclust=FAT16_NextCluster(tempclust);//next cluster
			if(tempclust == 0xffff)break;
		}
	}
	return 0;
}



//select the first unsed item in the given cluster
//for delete a foler or a file
unsigned char FAT16_SelectOneItem(unsigned int cluster,struct FileInfoStruct *FileInfo)
{
	//unsigned char *buffer;
	unsigned long tempclust;
	unsigned long sector;
	unsigned char cnt;
	unsigned int offset;
//	unsigned char i;
	struct direntry *item = 0;
	if(cluster==0)// root directory
	{
		//buffer=malloc(512);//apply memory
		//if(buffer==0)return 1;//if failed
		for(cnt=0;cnt<RootDirSectors;cnt++)
		{
			if(FAT16_ReadSector(FirstDirSector+cnt,buffer)){free(buffer);return 1;}
			for(offset=0;offset<512;offset+=32)
			{
				item=(struct direntry *)(&buffer[offset]);
				if((item->deName[0] != 0x00) & (item->deName[0] != 0xe5) & (item->deAttributes != 0x0f))
				{
					//return the parameter of the item
					FileInfo->StartCluster = item->deStartCluster;
					FileInfo->Size         = item->deFileSize;
					FileInfo->Attr         = item->deAttributes;
					FileInfo->Sector       = FirstDirSector+cnt;
					FileInfo->Offset       = offset;
					free(buffer);
					return 0;
				}
			}
		}
		free(buffer);//release
	}
	else//other folders
	{
		tempclust=cluster;
		while(1)
		{
			sector=FirstDataSector+(unsigned long)(tempclust-2)*(unsigned long)SectorsPerClust;//calculate the actual sector number
			//buffer=malloc(512);//apply memory
			//if(buffer==0)return 1;//if failed
			for(cnt=0;cnt<SectorsPerClust;cnt++)
			{
				if(FAT16_ReadSector(sector+cnt,buffer)){free(buffer);return 1;}
				for(offset=0;offset<512;offset+=32)
				{
					item=(struct direntry *)(&buffer[offset]);
					if((item->deName[0] != 0x2e) & (item->deName[0] != 0x00) & (item->deName[0] != 0xe5) & (item->deAttributes != 0x0f))
					{
						FileInfo->StartCluster = item->deStartCluster;
						FileInfo->Size         = item->deFileSize;
						FileInfo->Attr         = item->deAttributes;
						FileInfo->Sector       = sector+cnt;
						FileInfo->Offset       = offset;
						free(buffer);
						return 0;
					}
				}
			}
			free(buffer);//release
			tempclust=FAT16_NextCluster(tempclust);//next cluster
			if(tempclust == 0xffff || tempclust == 0xfff8)break;
		}
	}
	return 1;
}

//modify the fat table item with "val","cluster" specify the location
unsigned char FAT16_ModifyFAT(unsigned int cluster,unsigned int val)
{
	//unsigned char buffer[512];
	unsigned long sector;
	unsigned long offset=cluster/256;

	sector=FirstFATSector+offset;//calculate the actual sector
	if(FAT16_ReadSector(sector,buffer))return 1;//read fat table

	offset=cluster%256;//find the position
	offset<<=1;
	//sector=buffer[offset+1];
//	sector<<=8;
	//sector+=buffer[offset];
	buffer[offset+1] = val>>8;
	buffer[offset]   = val;
	if(FAT16_WriteSector(sector,buffer))return 1;//write the first fat table
	if(FAT16_WriteSector(sector+FATsectors,buffer))return 1;//write the second fat table
	return 0;//return the value
}

// make a dir
unsigned char FAT16_MkDir(unsigned char * dir)
{
	unsigned char name[11];
	unsigned char *p=dir;
	unsigned char deep=0;
	unsigned int i,j;
	unsigned long cluster=0;
	unsigned long lastcluster;//cluster number of last directory
	unsigned char *buffer;
	unsigned int sector;
	struct direntry *item;
	if(*p != '\\')return 1;//invalid path
	while(*p)
	{
		if(*p == '\\')
		{
			deep++;//the deepth of the path
		}
		p++;
	}
	p=dir;
	for(i=0;i<deep-1;i++)
	{
		p++;
		for(j=0;j<11;j++)name[j]=0x20;
		j=0;
		while(*p != '\\')
		{
			if((*p) >= 'a' && (*p) <= 'z')name[j] = (*p++)-0x20;
			else name[j] = *p++;
			j++;
		}
		if(FAT16_FindItem(cluster,name, &FileInfo))return 1;//find the location of each directory
		cluster = FileInfo.StartCluster;//point to next directory
	}
	p++;
	for(j=0;j<11;j++)name[j]=0x20;
	j=0;
	while(*p)
	{
		if(*p>='a' && *p<='z')name[j]=(*p++)-0x20;
		else name[j]=*p++;
		j++;
	}
	lastcluster=cluster;//save as last directory
	cluster=FAT16_FindFreeCluster();//find a unused cluster
	if(cluster==1)return 1;//error
	if(FAT16_FindFreeItem(lastcluster,&FileInfo))return 1;//find a unused item
	//buffer=malloc(512);
	//if(buffer==0)return 1;
	if(FAT16_ReadSector(FileInfo.Sector,buffer)){free(buffer);return 1;}//read the sector which the item is in
	item=(struct direntry *)(&buffer[FileInfo.Offset]);//pointer convert

	for(j=0;j<8;j++)item->deName[j] = name[j];
	for(j=0;j<3;j++)item->deExtension[j] = 0x20;
	item->deAttributes = ATTR_DIRECTORY;
	item->deLowerCase = LCASE_BASE | LCASE_EXT;
	item->deCHundredth = 0;
	item->deCTime[0] = 0;
	item->deCTime[1] = 0;
	item->deCDate[0] = 0;
	item->deCDate[1] = 0;
	item->deADate[0] = 0;
	item->deADate[1] = 0;
	item->deHighClust = 0;
	item->deMTime[0] = 0;
	item->deMTime[1] = 0;
	item->deMDate[0] = 0;
	item->deMDate[1] = 0;
	item->deStartCluster = cluster;
	item->deFileSize = 0;
	if(FAT16_WriteSector(FileInfo.Sector,buffer))
	{
	 free(buffer);
	 return 1;
	}//write the item

	free(buffer);
	sector=FirstDataSector+(unsigned long)(cluster-2)*(unsigned long)SectorsPerClust;
	for(i=0;i<SectorsPerClust;i++)
	{
		if(FAT16_WriteSector(sector+i,buffer))
		 {
		  free(buffer);
		  return 1;
		 }//clear the data in the directory
	}

	//create "." directory
	item=(struct direntry *)(&buffer[0]);
	item->deName[0] = '.';
	for(j=1;j<8;j++)item->deName[j] = 0x20;
	for(j=0;j<3;j++)item->deExtension[j] = 0x20;
	item->deAttributes = ATTR_DIRECTORY;
	item->deLowerCase = LCASE_BASE | LCASE_EXT;
	item->deCHundredth = 0;
	item->deCTime[0] = 0;
	item->deCTime[1] = 0;
	item->deCDate[0] = 0;
	item->deCDate[1] = 0;
	item->deADate[0] = 0;
	item->deADate[1] = 0;
	item->deHighClust = 0;
	item->deMTime[0] = 0;
	item->deMTime[1] = 0;
	item->deMDate[0] = 0;
	item->deMDate[1] = 0;
	item->deStartCluster = cluster;//the directory itself
	item->deFileSize = 0;

	//creat ".." directory
	item=(struct direntry *)(&buffer[32]);
	item->deName[0] = '.';
	item->deName[1] = '.';
	for(j=2;j<8;j++)item->deName[j] = 0x20;
	for(j=0;j<3;j++)item->deExtension[j] = 0x20;//no extention
	item->deAttributes = ATTR_DIRECTORY;//directory
	item->deLowerCase = LCASE_BASE | LCASE_EXT;
	item->deCHundredth = 0;
	item->deCTime[0] = 0;
	item->deCTime[1] = 0;
	item->deCDate[0] = 0;
	item->deCDate[1] = 0;
	item->deADate[0] = 0;
	item->deADate[1] = 0;
	item->deHighClust = 0;
	item->deMTime[0] = 0;
	item->deMTime[1] = 0;
	item->deMDate[0] = 0;
	item->deMDate[1] = 0;
	item->deStartCluster = lastcluster;//last directory
	item->deFileSize = 0;

	if(FAT16_WriteSector(sector,buffer))
	 {
	  free(buffer);
	  return 1;
	 }//write the data
	free(buffer);
	if(FAT16_ModifyFAT(cluster,0xffff))
	 return 1;//modify the fat table to sign that the cluster was used 
	return 0;//done
}

// remove a directory
unsigned char FAT16_RmDir(unsigned char * dir)
{
	if(FAT16_OpenDir(dir)==0)
	 return 1;//find the directory
	if(FAT16_DelItem(&FileInfo))
	 return 1;//delete it
	return 0;
}

// creat a file, for convenience we designate the size
// return the start sector of the new file
unsigned int FAT16_Create(unsigned char * dir,unsigned long size)
{
	unsigned char name[11];
	unsigned char *p=dir;
	unsigned char deep=0;
	unsigned char i,j;
	unsigned long cluster=0;
	unsigned char *buffer;
	//unsigned int sector;
	struct direntry *item;
	if(*p != '\\')return 1;//invalid path
	while(*p)
	{
		if(*p == '\\')
		{
			deep++;
		}
		p++;
	}
	p=dir;
	for(i=0;i<deep-1;i++)
	{
		p++;
		for(j=0;j<11;j++)name[j]=0x20;
		j=0;
		while(*p != '\\')
		{
			if((*p) >= 'a' && (*p) <= 'z')name[j] = (*p++)-0x20;
			else name[j] = *p++;
			j++;
		}
		if(FAT16_FindItem(cluster,name, &FileInfo))
		 return 1;
		cluster = FileInfo.StartCluster;
	}
	p++;
	for(j=0;j<11;j++)
	 name[j]=0x20;
	j=0;
	while(*p != '.')
	{
		if(*p>='a' && *p<='z')name[j]=(*p++)-0x20;
		else name[j]=*p++;
		j++;
	}
	j=8;
	p++;
	while(*p)
	{
		if(*p>='a' && *p<='z')name[j]=(*p++)-0x20;
		else name[j]=*p++;
		j++;
	}


	if(FAT16_FindFreeItem(cluster,&FileInfo))return 1;
	cluster = FAT16_FindFreeCluster();
	if(cluster==1)
	 return 1;
	//buffer=malloc(512);
	//if(buffer==0)return 1;
	if(FAT16_ReadSector(FileInfo.Sector,buffer))
	 {
	  free(buffer);
	  return 1;
	 }
	item=(struct direntry *)(&buffer[FileInfo.Offset]);

	for(j=0;j<8;j++)item->deName[j] = name[j];
	for(j=0;j<3;j++)item->deExtension[j] = name[8+j];
	item->deAttributes = ATTR_ARCHIVE;//file
	item->deLowerCase = LCASE_BASE | LCASE_EXT;
	item->deCHundredth = 0;
	item->deCTime[0] = 0;
	item->deCTime[1] = 0;
	item->deCDate[0] = 0;
	item->deCDate[1] = 0;
	item->deADate[0] = 0;
	item->deADate[1] = 0;
	item->deHighClust = 0;
	item->deMTime[0] = 0;
	item->deMTime[1] = 0;
	item->deMDate[0] = 0;
	item->deMDate[1] = 0;
	item->deStartCluster = cluster;//the cluster number the file was stored
	item->deFileSize = size;//the file size
	if(FAT16_WriteSector(FileInfo.Sector,buffer))
     {
	  free(buffer);
	  return 1;
	 }//write the item
	free(buffer);
	if(FAT16_ModifyFAT(cluster,0xffff))
	 return 1;//modify the fat table
	return cluster;//reutn the first cluster number
}





unsigned int FAT16_Close(unsigned int * p)
{
	*p=1;
	return 0;
}

// Output the data of a file
// size 0 means read all of the file
unsigned char FAT16_Read(unsigned int pointer, unsigned long size)
{
	unsigned long sector;
	unsigned long tempclust=pointer;
	unsigned char *buffer;
	unsigned int i=0,j=0;
	sector=FirstDataSector+(unsigned long)(tempclust-2)*(unsigned long)SectorsPerClust;
	if(size==0)size = FileInfo.Size;//whether need to read all
	send(0x0d);

⌨️ 快捷键说明

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