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

📄 filelib.c

📁 在Bf533上实现FAT32文件系统
💻 C
字号:
/************************************************************************
* File         : filelib.c
* Processor    : ADSP-BF533  
* IDDE         : VisualDSP++3.5
* Description  : Define standarded file operating functions includes:
*                  
*            fopen();
*            fread();
*            fwrite();
*            fseek();
*            fclose();
*            frename();
*            fdelete();
*            fsearch();
*            fcloselist();
*            fcreatedir();
*
*************************************************************************/

#include "FAT/filesystem.h"
#include "type.h"
//#include <stdlib.h>
#include <string.h>

 /******************************************************************
* Function     : fnSystemInit
* Description : initialize HD
* Input     : none
* Return   : none
*******************************************************************/
void fnSystemInit()
{
	fnIDE_InitDrive();
	fnDetect_Partition();
}

 /******************************************************************
* Function     : flist
* Description : list directory contents with given path
* Input     : BYTE *name - given path
* Return   : FILELIST_t * file list pointer
*******************************************************************/

FILELIST_t* flist(BYTE *name)
{
	BYTE nsize,i;
	BYTE pn;
	BYTE path[256];
	
	BYTE startcluster = 2;
	BYTE* sub_name;
	char char_lib[]="/";
	
	FILE_t *fp;
	FILELIST_t *filelist;
	
	fp=(FILE_t*)malloc(sizeof(FILE_t));
	nsize=strlen((char *)path);
	//path format must be "C:/"
	if(nsize<3)
	{
#ifdef DEBUG
		printf("Error path!");
#endif
		filelist=NULL;
		return filelist;
	}
	memcpy(path,name,strlen((char *)name)+1);
	//partition num
 	pn = path[0]-'C';
	if(partition_table[pn]==NULL)
	{
#ifdef DEBUG
		printf("Error partition!");
#endif
		filelist=NULL;
		return filelist;
	}
	
	current_fs = partition_table[pn]->fs;
	// path valid or not?
	if(strncmp((char *)path+1,":/",2)!=0)
	{
#ifdef DEBUG
		printf("Error path!");
#endif
		filelist=NULL;
		return filelist;
	}

	sub_name=(BYTE*)strtok((char*)path,char_lib);
	sub_name=(BYTE*)strtok(NULL,char_lib);
	
	fp->type=FILE_ATTR_DIRECTORY;
	fp->startcluster=startcluster;
	fp->currentcluster.value=startcluster;
	fp->currentcluster.offset=0;

	// NULL means root directory
	if(sub_name==NULL)
	{
		filelist=fnListDirectory(fp->startcluster);
		return filelist;
	}

	while(1)
	{
		fp = fnFindFile(startcluster,sub_name,FIND_DIR_MODE);
		sub_name=(BYTE*)strtok(NULL,char_lib);
		if(fp==NULL)
		{
#ifdef DEBUG
			printf("There file not exist!");
#endif
			filelist=NULL;
			return filelist;
		}
		else
		{
			if(sub_name==NULL)
			{
				if(fp->type&FILE_ATTR_DIRECTORY)
				{
					filelist=fnListDirectory(fp->startcluster);
					return filelist;
				}
				else
				{
#ifdef DEBUG
					printf("There is a file!");
#endif
					filelist=NULL;
					return filelist;
				}
			}
			else
			{	
				if(fp->type&FILE_ATTR_DIRECTORY)
				{
					continue;
				}
			
				else
				{
#ifdef DEBUG
					printf("Path error!");
#endif	
					filelist=NULL;
					return filelist;
				}
				
			}
		}
	}
}


 /******************************************************************
* Function     : __fopen
* Description : open file with given path and open mode
* Input     : BYTE *name - given path
*                BYTE *mode - open mode
* Return   : FILE_t * file pointer
*******************************************************************/
FILE_t * __fopen(BYTE *name,BYTE *mode)
{
	FILE_t *fp;
	
	BYTE path[256];
	BYTE* sub_name;
	char sub_name_temp[256];
	char char_lib[]="/\\";
	WORD fopen_mode=0;
	WORD open_mode=0;
	
	BYTE pn;
	
	WORD nsize,i;
	DWORD upfolder;
	DWORD startcluster=2;

	//config open mode
	while(*mode)
	{
		switch(*mode)
		{
			case 'r':
				fopen_mode |=MODE_READ;
				break;
			case 'w':
				fopen_mode |=MODE_WRITE;
				open_mode = (O_CREAT|O_TRUNC);
				break;
			case 'a':
				fopen_mode |=MODE_WRITE;
				open_mode = (O_CREAT|O_APPEND);
				break;
			case '+':
				fopen_mode|=MODE_RDWR;
				break;
		}
		mode++;
	}
	
	switch(fopen_mode &(MODE_READ|MODE_WRITE))
	{
		case 0:
			return 0;
		case MODE_READ:
			open_mode|=O_RDONLY;
			break;
		case MODE_WRITE:
			open_mode|=O_WRONLY;
			break;
		default:
			open_mode |=O_RDWR;
			break;
	}
	
	memcpy(path,name,strlen((char*)name)+1);
	
	fp=(FILE_t *)malloc(sizeof(FILE_t));
	
	nsize=strlen((char*)path);

	if(nsize<3)
	{
#ifdef DEBUG
		printf("Error path!\n");
#endif
		fp=NULL;
		return fp;
	}
	
	//check partition
	
	sub_name=(BYTE*)strtok((char*)path,char_lib);
	if(strlen((char*)sub_name)!=2||sub_name[1]!=':')
	{
		fp=NULL;
		return fp;
	}
	pn = sub_name[0]-'C';
	if(partition_table[pn]==0)
	{
#ifdef DEBUG
		printf("Error partition!\n");
#endif
		fp=NULL;
		return fp;
	}
	current_fs = partition_table[pn]->fs;
	
	sub_name=(BYTE*)strtok(NULL,char_lib);
	
	fp->type=FILE_ATTR_DIRECTORY;
	fp->startcluster=startcluster;
	fp->currentcluster.value=startcluster;
	fp->currentcluster.offset=0;

	if(sub_name==NULL)
	{
#ifdef DEBUG
		printf("There is a folder!\n");
#endif
		fp=NULL;
		return fp;
	}
	

	while(1)
	{
		upfolder = fp->startcluster;
		fp = fnFindFile(fp->startcluster,sub_name,FIND_ALL_MODE);
		memcpy(sub_name_temp,sub_name,strlen((char*)sub_name)+1);
		sub_name=(BYTE*)strtok(NULL,char_lib);	
		if(fp==NULL)
		{

			if(sub_name==NULL)
			{

				//create a new file if the file doesn't exist
				if(open_mode&O_CREAT)
				{
					fp=fnCreateFile(upfolder,(BYTE*)sub_name_temp);
					if(fp==NULL)
					{
						return fp;
					}
#ifdef DEBUG
					printf("Create a new file!\n");
#endif
					break;
				}
				else
				{
#ifdef DEBUG
					printf("There file not exist!");
#endif
					fp=NULL;
					return fp;

				}
			}
			else
			{
#ifdef DEBUG
				printf("Error path!\n");
#endif
				return NULL;
			}
		}
		else
		{
			if(sub_name==NULL)
			{
				if(fp->type&FILE_ATTR_DIRECTORY)
				{
#ifdef DEBUG
					printf("There is a folder!\n");
#endif
					return NULL;
				}
				else
				{
					break;
				}
			}
			else
			{
				if(fp->type&FILE_ATTR_DIRECTORY)
				{
					continue;
				}
				else
				{
					return NULL;	
				}
			}
		}
	}

	//find the file, open it
	fp=fnOpenFile(fp,open_mode);
	if(fp!=NULL)
	{
		fp->flag|=fopen_mode;
		return fp;
	}
	
	return NULL;
	
}

 /******************************************************************
* Function     : __fread
* Description : read file to target buffer
* Input     : BYTE *size - file size
*                DWORD count - number of read data
*                FILE_t *fp - file pointer
* Return   : DWORD  size of read data
*******************************************************************/

DWORD __fread(BYTE *buffer, BYTE size, DWORD count, FILE_t *fp )
{
	DWORD read_num;
	//readable or not?
	if(fp==NULL||((fp->flag&MODE_OPEN)==0)||((fp->flag&MODE_READ)==0)||
	   size==0||
	   count==0)
	{
		return 0;
	}
	if(fp->filesize==0||fp->startcluster==0)
	{
		return 0;
	}
	
	read_num=fnReadFile(buffer,size,count,fp);
	
	return read_num;
}

 /******************************************************************
* Function     : __fwrite
* Description : write file to target buffer
* Input     : BYTE *buffer - buffer address
*                BYTE size - size of read data
*                DWORD count - number of read data
*                FILE_t *fp - file pointer
* Return   : DWORD  size of written data
*******************************************************************/	
DWORD __fwrite(BYTE *buffer,BYTE size,DWORD count,FILE_t *fp)
{
	DWORD write_num;
	DWORD cluster_temp;

	if(fp==NULL||((fp->flag&MODE_OPEN)==0)||((fp->flag&MODE_WRITE)==0)||
	   size==0||
	   count==0)
	{
		return 0;
	}

	//set up starting address of store buffer for empty file
	if(fp->filesize==0||fp->startcluster==0)
	{
		cluster_temp=fnFAT32_NextEmptyCluster(fp->startcluster);
		fnFAT32_EditFat(cluster_temp,0x0FFFFFFF);
		fp->currentcluster.value=cluster_temp;
		
		fp->startcluster=cluster_temp;

	}
	
	//create a new cluster if current file operating pointer reach to the end of file
	else if((fp->curp%(current_fs->bpb.byte_per_sector*current_fs->bpb.sector_per_cluster)==0)&&(fp->curp==fp->filesize))
	{
		cluster_temp = fnFAT32_NextEmptyCluster(fp->currentcluster.value);
				//cycles[0]+=read_cycle();
		if(cluster_temp==0xFFFFFFFF)
		{
			return 0;
		}
		fnFAT32_EditFatChain(fp->currentcluster.value,cluster_temp);
		fnFAT32_EditFatChain(cluster_temp,0x0FFFFFFF);
		fp->currentcluster.value=cluster_temp;
		fp->currentcluster.offset++;
		
	}
	
	write_num=fnWriteFile(buffer,size,count,fp);
	return write_num;
}


 /******************************************************************
* Function     : __fseek
* Description : seek a file
* Input     :
*                FILE_t *fp - file pointer
*                long offset - offset
*                in base - base of offset
* Return   : DWORD  offset of file operating pointer to start of file
*******************************************************************/
DWORD __fseek(FILE_t *fp,long offset,int base)
{
	switch(base)
	{
		case 0:
		{
			if(offset<0||offset>=fp->filesize)
			{
				return 0xFFFFFFFF;
			}
			fp->curp=offset;
			break;
		}
		case 1:
		{
			if(offset+fp->curp>=fp->filesize)
			{
				return 0xFFFFFFFF;
			}
			fp->curp=offset+fp->curp;
			break;
		}
		case 2:
		{
			if(offset>0||offset<=fp->filesize)
			{
				return 0xFFFFFFFF;
			}
			fp->curp=fp->filesize+offset-1;
			break;
		}
	}
	fp->currentcluster=fnGetCurrentCluster(fp->curp,fp->startcluster);
	
	return fp->curp;
}
/******************************************************************
			关闭文件函数
用途: 指定文件指针,把它关闭
输入: FILE_t *fp  文件指针
输出: void
******************************************************************/	

 /******************************************************************
* Function     : __fclose
* Description : close a file
* Input     :
*                FILE_t *fp - file pointer
* Return   : void
*******************************************************************/
void __fclose(FILE_t *fp)
{
	free(fp);
	fp=(FILE_t *)0;
}	

 /******************************************************************
* Function     : __frename
* Description : rename a file
* Input     :
*                FILE_t *fp - file pointer
*                BYTE *name - target file name
* Return   : DWORD read data
*******************************************************************/

BYTE __frename(FILE_t* fp,BYTE *name)
{
	FILE_t *fp_temp;
	char name_temp[256];
	char char_lib[]="%/\\:";//
	BYTE *temp;
	if(fp==NULL)
	{
		return 0;
	}
	if(strlen((char*)name)>=255)
	{
		return 0;
	}
	
	memcpy(name_temp,name,strlen((char*)name)+1);
	temp=(BYTE*)strtok(name_temp,char_lib);
	if(strlen(name_temp)<256&&(strtok(NULL,char_lib)==NULL))
	{
		fp_temp=fnFindFile(fp->up_folder,(BYTE*)name_temp,FIND_FILE_MODE);
	}
	else
	{
		return 0;
	}
	if(fp_temp!=NULL||(strlen(strtok(name_temp,char_lib))!=strlen((char*)name)))
	{
		return 0;
	}
	else
	{
		memcpy(fp->filename,name,strlen((char*)name)+1);
		fnUpdateFILE(fp);
	}
	return 1;
}

 /******************************************************************
* Function     : __fdelete
* Description : remove a file
* Input     :
*                FILE_t *fp - file pointer
* Return   : 1 or 0-error
*******************************************************************/
BYTE __fdelete(FILE_t* fp)
{
	if(fp==NULL)
	{
		return 0;
	}

	fnFreeFile(fp);

	fnDeleteFileLabel(fp);
	
	return 1;
}


 /******************************************************************
* Function     : __fsearch
* Description : search a file
* Input     :
*                FBYTE *name - target file name
* Return   : FILELIST_t * file list pointer of target file
*******************************************************************/
FILELIST_t * __fsearch(BYTE *name)
{
	int i;
	FILELIST_t *file_list;
	char name_temp[256];
	char char_lib[]="%/\\:";
	BYTE searchlevel=0;
	BYTE num=0;
	BYTE *temp;
	
	file_list=(FILELIST_t *)malloc(sizeof(FILELIST_t));
	file_list->list=(FILE_t **)malloc(sizeof(FILE_t *)*256);//at most found 256 files
	file_list->num=256;
	
	
	
	memcpy(name_temp,name,strlen((char*)name)+1);
	temp=(BYTE*)strtok(name_temp,char_lib);
	if(strlen(name_temp)<=255&&(strtok(NULL,char_lib)==NULL))
	{	
		//start searching here
		fnSearchFile(2,name,searchlevel,&num,file_list);
	}
	else
	{
		
		return NULL;
	}
	for(i=num;i<file_list->num;i++)
	{
		file_list->list[i]=NULL;
	}
	
	return file_list;
}


 /******************************************************************
* Function     : __fcloselist
* Description : free FILELIST_t and fp
* Input     :
*                FILELIST_t * variable need to be free 
* Return   : NULL
*******************************************************************/
FILELIST_t * __fcloselist(FILELIST_t *filelist)
{
	DWORD i=0;
	if(filelist==NULL)
		return NULL;
	for(i=0;i<filelist->num;i++)
	{
		free(filelist->list[i]);
	}
	free(filelist->list);
	free(filelist);
	return NULL;
	
}

 /******************************************************************
* Function     : __fcreatedir
* Description :create a directory
* Input     :
*                FILELIST_t * path - path of the directory
*                BYTE *dir - name of directory
* Return   : 1 or 0-error
*******************************************************************/

BYTE __fcreatedir(BYTE *path,BYTE* dir)
{
	FILE_t * fp;
	char path_temp[256];
	BYTE* sub_name;
	BYTE* temp;
	char sub_name_temp[256];
	
	BYTE pn;
	DWORD upfolder;
	char char_lib[]="/\\";
	char invalid_char[]="%/\\:";
	
	
	memcpy(path_temp,path,strlen((char*)path)+1);
	
	sub_name=(BYTE*)strtok(path_temp,char_lib);
	if(strlen((char*)sub_name)!=2||sub_name[1]!=':')
	{
		return 0;
	}
	pn = sub_name[0]-'C';
	if(partition_table[pn]==0)
	{
#ifdef DEBUG
		printf("Error partition!\n");
#endif
		return 0;
	}
	current_fs = partition_table[pn]->fs;
      
	
	memcpy(sub_name_temp,dir,strlen((char*)dir)+1);
	temp=(BYTE*)strtok(sub_name_temp,invalid_char);
	if(strlen(sub_name_temp)>=255||(strtok(NULL,invalid_char)!=NULL))
	{
		return 0;
	}
	
	fp=(FILE_t *)malloc(sizeof(FILE_t));
	sub_name=(BYTE*)strtok(NULL,char_lib);
	
	fp->type=FILE_ATTR_DIRECTORY;
	fp->startcluster=2;
	fp->currentcluster.value=2;
	fp->currentcluster.offset=0;
		
	//there is directory with the same name

⌨️ 快捷键说明

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