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

📄 kfs.c

📁 kfs嵌入式文件系统1.0.1release版 作者:Eagle 来源:http://www.embseek.com 由embseek开发
💻 C
字号:
/*

filename : kfs.c

version : 1.0.1 release

author : eagle

web : www.embseek.com

*/
#include "kfs.h"

#include "kfsdev.h"

#include "str.h"

/*Data=========================================*/

/*file systen start address*/
u8 * fs_start_add;

/*file system length*/
u16  fs_len;

/*current head in the file system*/
u8 * fs_head_add;

/*table of the file head informations*/
struct fhead 			fheadtable[MAX_FILE_NUM];

/*totle file number in the file system*/
u16 					f_num;	

/*Operations===================================*/


/****************************************
function : r_fsinit
_fs_start_add : file systen start address
_fs_end_add : file system end address
description : init the file system
****************************************/
void r_fsinit(u8 *_fs_start_add,u8 *_fs_end_add){
	u8 * pf;
	u16 i;
	u8	state;//是否被格式化的标记,文件系统第一个字节	
		
	fs_start_add=_fs_start_add+sizeof(u8)+sizeof(u8 *);
		
	fs_len=_fs_end_add-fs_start_add+1;
	f_num=0;
	
	kfsdev_read(_fs_start_add,&state,sizeof(u8));
	if(state==0x55){//file system has formated	
		
		kfsdev_read(_fs_start_add+sizeof(u8),(u8 *)&(fs_head_add),sizeof(u8 *));
		
		pf=fs_head_add;
			
		for(i=0;i<MAX_FILE_NUM;i++){
			kfsdev_read(pf,(u8 *)&(fheadtable[i]._status),sizeof(u16));
			if(!fheadtable[i]._status&FHS_FSEND){
				kfsdev_read(pf+sizeof(u16),(u8 *)&(fheadtable[i]._size),sizeof(u16));
				kfsdev_read(pf+sizeof(u16)*2,fheadtable[i].filename,MAX_FLIE_NAME_LEN);
				
				fheadtable[i]._f_sadd=pf+sizeof(struct fshead);
				
				pf+=sizeof(struct fshead)+fheadtable[i]._size;
				f_num++;
			}
		}
	}
	else{
		fs_head_add=fs_start_add;
		
		kfsdev_write(_fs_start_add+sizeof(u8),(u8 *)&(fs_head_add),sizeof(u8 *));
		
		state=0x55;
		
		kfsdev_write(_fs_start_add,&state,sizeof(u8));
	}
}

/****************************************
function : r_fopen
filename : file name less than 12byte
mode : Type of access permitted.
return : point to the opened file
description : open a file
****************************************/
r_FILE * r_fopen(u8 * filename, const u8 mode){
	u8 i;
	
	if(es_strlen(filename)>MAX_FLIE_NAME_LEN){
		
		
		return NULL;
	}
	
	
	for(i=0;i<f_num;i++){		
		if(es_strcmp(filename,fheadtable[i].filename))/*if file exist*/
		{			
			if(!(fheadtable[i]._status&FHS_DELETED)&&!(fheadtable[i]._status&FHS_OPENED))
			{
				fheadtable[i]._p=fheadtable[i]._f_sadd;
				return &fheadtable[i];				
			}
		}
	}
		
	/*file not exist , create a file*/
	if(mode&O_CREAT){
		if(f_num<MAX_FILE_NUM){
				
			fheadtable[f_num]._status=FHS_FSEND;
			es_strcpy(filename,fheadtable[f_num].filename,MAX_FLIE_NAME_LEN);
			fheadtable[f_num]._status|=FHS_NAMEMODIFIED;
			fheadtable[f_num]._status|=FHS_STATUEMODIFIED;
			
			if(f_num>=1){
				fheadtable[f_num]._f_sadd=fheadtable[f_num-1]._f_sadd+fheadtable[f_num-1]._size+sizeof(struct fshead);
			}else{
				fheadtable[f_num]._f_sadd=fs_head_add+sizeof(struct fshead);
			}
			
			
			fheadtable[f_num]._p=fheadtable[f_num]._f_sadd;
			
			fheadtable[f_num]._status|=FHS_OPENED;
			fheadtable[f_num]._size=0;
			fheadtable[f_num]._status|=FHS_SIZEMODIFIED;
			
			f_num++;
			
			return &fheadtable[f_num-1];
		}
	}		
	return NULL;
}

/****************************************
function : r_fdelete
fp : point to the FILE structure
return : if file was deleted return 1,else return 0;
description : delete a file ,please make sure that there are not any other file opened
****************************************/
void r_fdelete(r_FILE * *_fp){
	
	u8 i,j;
	
	r_FILE * fp,* fpt;
	fp=*_fp;
	
	if(fp==&fheadtable[0]){//file is the first file in the file system
		fp->_status=FHS_DELETED|FHS_STATUEMODIFIED;
		r_fsavehead(fp);		
		r_frmhead(fp);
		
		fs_head_add=fheadtable[0]._f_sadd-sizeof(struct fshead);
		
		kfsdev_write(fs_start_add-sizeof(u8*),(u8 *)&(fs_head_add),sizeof(u8 *));
		
	}else if(fp->_status&FHS_FSEND){	//file is in the end of the file system
		fp->_status=FHS_DELETED|FHS_STATUEMODIFIED|FHS_FSEND;
		r_fsavehead(fp);
	}else{		//file is not in the end of the file system
		j=0;
		
		fp->_status=FHS_DELETED|FHS_STATUEMODIFIED;
		for(i=0;i<f_num;i++){
			if(!(fheadtable[i]._status&FHS_DELETED)){
				j++;
			}
			if(fp==&fheadtable[i]){
				if(j>0){//file is in the middle of the file system
					//彻底删除文件,移动后面的文件
					//请确保当前文件之后的文件未被打开
					f_num--;
					for(j=i;j<f_num;j++){
						fpt=&fheadtable[j+1];
						fp->_size=fpt->_size;
						es_strcpy(fpt->filename,fp->filename,MAX_FLIE_NAME_LEN);
						fp->_status=fpt->_status;
						fp->_status|=FHS_SIZEMODIFIED|FHS_STATUEMODIFIED|FHS_NAMEMODIFIED;
						
						r_rewind(fp);
						r_rewind(fpt);
						
						for(i=0;i<fp->_size;i++){
							r_fputc(fp,r_fgetc(fpt));
						}
						r_fsavehead(fp);
						fpt->_f_sadd=fp->_f_sadd+fp->_size+sizeof(struct fshead);
						fp=fpt;						
					}
					*_fp=NULL;
				}
				else{
					r_fsavehead(fp);
					return;
				}
			}
		}
	}
}


/****************************************
function : r_rewind
fp : point to the FILE structure
description : rewind a file to head
****************************************/
void r_rewind(r_FILE *fp){
	fp->_p=fp->_f_sadd;
}


//从fp指向的用户操作文件中取出当前文件指针指向的数据(u8类型),并将文件指针的当前文件指针地址加1;
/****************************************
function : r_fgetc
fp : point to the FILE structure
return : the character read from the file
description : get a character from the file
****************************************/
u8 r_fgetc(r_FILE * fp){
	u8 ret=0;	
	if(r_feof(fp)){
		return ret;
	}else{
		if(fp->_p>fs_start_add+fs_len-1){
			kfsdev_read(fp->_p-fs_len,&ret,1);
		}else{			
			kfsdev_read(fp->_p,&ret,1);
		}
		fp->_p++;	
	}
	return ret;
}


//向fp指向的用户操作文件中文件指针指向的数据(u8类型)地址写入一个字符,并将文件指针的当前文件指针地址加1;
/****************************************
function : r_fputc
fp : point to the FILE structure
ch : character to put to file
return : if success return 1,else return 0
description : put a character to file
****************************************/
u8 r_fputc(r_FILE * fp ,u8 ch){
	u8 ret=0;
	if(fp->_p-(fs_len)>=fs_head_add){
		/*超出文件系统长度*/
		return 0;
	}
	if(r_feof(fp)){
		if(fp->_status&FHS_FSEND){
			fp->_size+=0x01;			
			if(fp->_p>fs_start_add+fs_len-1){
				kfsdev_write(fp->_p-fs_len,&ch,1);
			}else{			
				kfsdev_write(fp->_p,&ch,1);
			}
			fp->_p+=1;
			ret=1;
			fp->_status|=FHS_SIZEMODIFIED;
		}
	}else{
		if(fp->_p>fs_start_add+fs_len-1){
			kfsdev_write(fp->_p-fs_len,&ch,1);
		}else{			
			kfsdev_write(fp->_p,&ch,1);
		}
		fp->_p+=1;	
		ret=1;
	}
	return ret;
}


//判断是否到达文件末尾;是则返回1
/****************************************
function : r_feof
fp : point to the FILE structure
return : if end return 1,else return 0
description : check if got the end of file
****************************************/
u8 r_feof(r_FILE * fp){
	u8 ret=0;
	if(fp->_p==fp->_f_sadd+fp->_size)
		ret=1;	
	return ret;
}



//关闭fp指向的文件
/****************************************
function : r_fclose
fp : point to the FILE structure
description : close the file
****************************************/
void r_fclose(r_FILE * * fp){
	if(*fp==NULL)
		return;
	(*fp)->_status&=~FHS_OPENED;
		
	r_rewind(*fp);
	
	if((*fp)->_size==0){
		r_frmhead(*fp);
	}else{
		r_fsavehead(*fp);
	}
	*fp=NULL;
}

/****************************************
function : r_frmhead
fp : point to the FILE structure
description : remove the file head from 
				the head table
****************************************/
void r_frmhead(r_FILE * fp){
	u8 i,j;
	for(i=0;i<f_num;i++){
		if(fp==&fheadtable[i]){
			for(j=i;j<f_num-1;j++){
				fheadtable[j]._status=fheadtable[j+1]._status;
				fheadtable[j]._size=fheadtable[j+1]._size;
				fheadtable[j]._f_sadd=fheadtable[j+1]._f_sadd;
				fheadtable[j]._p=fheadtable[j+1]._p;
				es_strcpy(fheadtable[j+1].filename,fheadtable[j].filename,MAX_FLIE_NAME_LEN);				
			}
			f_num-=1;
			return;
		}
	}
}

/****************************************
function : r_fsavehead
fp : point to the FILE structure
description : save the file head
****************************************/
void r_fsavehead(r_FILE * fp){
	if(fp==NULL)
		return;
	if(fp->_status&FHS_SIZEMODIFIED){
		fp->_status&=~FHS_SIZEMODIFIED;		
		kfsdev_write(fp->_f_sadd-sizeof(struct fshead)+sizeof(u16),(u8 *)&(fp->_size),sizeof(u16));	
	}
	if(fp->_status&FHS_NAMEMODIFIED){
		fp->_status&=~FHS_NAMEMODIFIED;		
		kfsdev_write(fp->_f_sadd-sizeof(struct fshead)+sizeof(u16)*2,fp->filename,MAX_FLIE_NAME_LEN);	
	}
	if(fp->_status&FHS_STATUEMODIFIED){
		fp->_status&=~FHS_STATUEMODIFIED;	
		kfsdev_write(fp->_f_sadd-sizeof(struct fshead),(u8 *)&(fp->_status),sizeof(u16));		
	}
	
	if(fp->_status&FHS_FSEND&&f_num>=2){
		if(fheadtable[f_num-2]._status&FHS_FSEND){
			fheadtable[f_num-2]._status&=!FHS_FSEND;
			kfsdev_write(fheadtable[f_num-2]._f_sadd-sizeof(struct fshead),(u8 *)&(fheadtable[f_num-2]._status),sizeof(u16));			
		}
	}	
}


/****************************************
function : r_format
_fs_start_add : file systen start address
_fs_end_add : file system end address
description : format the file system
****************************************/
void r_format(u8 *_fs_start_add,u8 *_fs_end_add){
	
	u8	state;//是否被格式化的标记,文件系统第一个字节	
	
	fs_start_add=_fs_start_add+sizeof(u8)+sizeof(u8 *);
		
	fs_len=_fs_end_add-fs_start_add+1;
	f_num=0;
	
	fs_head_add=fs_start_add;
		
	kfsdev_write(_fs_start_add+sizeof(u8),(u8 *)&(fs_head_add),sizeof(u8 *));
		
	state=0x55;
		
	kfsdev_write(_fs_start_add,&state,sizeof(u8));
}

⌨️ 快捷键说明

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