fileio.c

来自「在VC6环境下开发」· C语言 代码 · 共 609 行

C
609
字号
#include "..\ucos-ii\includes.h"
#include "K9F2808.h"
#include "FileIO.h"
#include <stdarg.h>

typedef struct FileHdr FileHdr;
typedef struct PageBuf PageBuf;

#define ROOT_BLOCK			0
#define START_BLOCK			1
#define NONE_BLOCK			0xffff

#define BLOCK_SIZE			0x4000
#define PAGE_SIZE			528
#define SECTION_SIZE		512
#define PAGE_PER_BLOCK		32
#define MAX_FILE_NUM		512
#define MAX_FILENAME_LEN	11

#define FILE_BUF_NUM	9

#define BLOCK_ATTR_NOUSED		0xffffffff
#define BLOCK_ATTR_USED		0x01ffffff
#define RESERVED				0xffffffff

#define UPDATE_ROOT_BLOCK	_write_block(ROOT_BLOCK,(u8 *)root_buf)

static u8 Page_Buf[PAGE_SIZE];

static U8 FileMemPart[(36+0x4000) * 10];
static OS_MEM *pFileMem;
static U8 root_buf[SECTION_SIZE][PAGE_PER_BLOCK];

extern void Uart_Printf(char *fmt,...);
extern int vsprintf(char *str,const char *format,...);
void Uart_SendString(char *pt);

struct PageBuf{
	u8 section[SECTION_SIZE];	
	u32 attr;	
	u32 resvd;
	u32 prevBlk;
	u32 nextBlk;
};
struct FileHdr{
	char name[8];
	char ext[3];
	char attr;
	char rsv[10];
	u16 lasttime;
	u16 lastdate;
	u16 firstblk;
	u32 size;
};
struct FILE {
	FileHdr *hdr;
	u8 Buffer[BLOCK_SIZE];		/* file buffer */
	u32 curBlk;					/* current block number of the Buffer*/
	u32 prevBlk;
	u32 nextBlk;				/* the next block */
	u32 filemode;				/* file mode */
	u32 filebufnum;				/* the pointer to Buffer */
	u32 fileCurpos;				/* the pointer to file */
	u32 filesize;				/* file size */
	u32 filechanged;		
};

u32 _swab32(u32 x){
  return ((x & 0xff)<<24) | ((x & 0xff00)<<8) |
         ((x>>8) & 0xff00) | ((x>>24)&0xff);
}

int _write_block(int blkNum,u8 *buf){
	int i,rc;
	PageBuf *pBuf = (PageBuf *)Page_Buf;
	rc = Erase_Cluster(blkNum);
	pBuf->attr = _swab32(BLOCK_ATTR_USED);		
	pBuf->resvd = _swab32(RESERVED);
	pBuf->prevBlk = _swab32(blkNum);
	pBuf->nextBlk = _swab32(NONE_BLOCK);
	for(i=0;i<PAGE_PER_BLOCK;i++){
		memcpy(Page_Buf,&buf[i*SECTION_SIZE],SECTION_SIZE);
		WritePage(blkNum,i,Page_Buf);
	}	
	return 0;
}

int _read_block(int blkNum,u8 *buf){
	int i;	
	for(i=0;i<PAGE_PER_BLOCK;i++){		
		//memset(Page_Buf,0,SECTION_SIZE);
		ReadPage(blkNum,i,Page_Buf);
		memcpy(&buf[i*SECTION_SIZE],Page_Buf,SECTION_SIZE);
	}	
	return 0;
}

int _seek_blank_blk(u32 base){
	int attr;
	PageBuf *pBuf = (PageBuf *)Page_Buf;
	do{				
		ReadPage(base,0,pBuf->section);
		attr = (_swab32(pBuf->attr) >> 24) & 0xff;
	}while( attr != 0xff && ++base != NONE_BLOCK);
	return base;
}

int _write_file(FILE *pFile){
	int i;
	int blkNum;
	PageBuf *pBuf;
	if(pFile->filechanged == 0){
		return 0;
	}
	pBuf = (PageBuf *)Page_Buf;;
	blkNum = pFile->curBlk;
	Erase_Cluster(blkNum);
		
	pBuf->attr = _swab32(BLOCK_ATTR_USED);
	pBuf->resvd = RESERVED;	
	pBuf->prevBlk = _swab32(pFile->prevBlk);			
	pBuf->nextBlk = _swab32(pFile->nextBlk);
	
	for(i=0;i<PAGE_PER_BLOCK;i++){
		memcpy(pBuf->section,&pFile->Buffer[i*SECTION_SIZE],SECTION_SIZE);
		WritePage(blkNum,i,Page_Buf);
	}	
	pFile->filechanged = 0;
	return 0;
}

int _read_file(FILE *pFile){
	int i;
	int blkNum;
	PageBuf *pBuf;
	
	if((pFile->filemode & FILEMODE_READ) != FILEMODE_READ){
		return 1;
	}
	blkNum = pFile->nextBlk;		
	if(blkNum == NONE_BLOCK || blkNum == 0){

		return 1;
	} 
	pBuf = (PageBuf *)Page_Buf;	
	for(i=0;i<PAGE_PER_BLOCK;i++){		
		ReadPage(blkNum,i,Page_Buf);
		memcpy(&pFile->Buffer[i*SECTION_SIZE],pBuf->section,SECTION_SIZE);
	}
	pFile->filebufnum = 0;
	pFile->curBlk = blkNum;
	pFile->prevBlk = _swab32(pBuf->prevBlk) & NONE_BLOCK;
	pFile->nextBlk = _swab32(pBuf->nextBlk) & NONE_BLOCK;	
	pFile->filechanged = 0;
	return 0;
}

int _read_file_1stBlk(FILE *pFile){
	int i;
	int blkNum;
	PageBuf *pBuf;
	
	if((pFile->filemode & FILEMODE_READ) != FILEMODE_READ){
		return 1;
	}
	blkNum = pFile->hdr->firstblk;
	if(blkNum == NONE_BLOCK || blkNum == 0){
		return 1;
	} 
	pBuf = (PageBuf *)Page_Buf;	
	for(i=0;i<PAGE_PER_BLOCK;i++){		
		ReadPage(blkNum,i,pBuf->section);
		memcpy(&pFile->Buffer[i*SECTION_SIZE],pBuf->section,SECTION_SIZE);
	}
	pFile->filebufnum = 0;
	pFile->fileCurpos = 0;
	pFile->curBlk = blkNum;
	pFile->prevBlk = blkNum;
	pFile->nextBlk = _swab32(pBuf->nextBlk) & NONE_BLOCK;	
	pFile->filechanged = 0;
	return 0;
}

FileHdr *_find_file(char *name,int empty){
	int i,k;
	FileHdr *filehdr;
	for(i=0;i<MAX_FILE_NUM;i++){
		filehdr = (FileHdr *)root_buf[i];
		if(filehdr->name[0] == 0 || filehdr->name[0] == 0xe5 || 
			filehdr->name[0] == 0xff){
			if(empty == 1){
				 return filehdr;
			}
		}else{
			if(empty == 1) continue;
			for(k=0;k<MAX_FILENAME_LEN;k++){
				if(name[k] != filehdr->name[k]) break;
			}
			if(k >= 11){
				return filehdr;
			}
		}
	}
	return 0;
}

int _zero_file(FILE *pFile){	
	int nextBlk;
	int blkNum = pFile->hdr->firstblk;
	PageBuf *pBuf = (PageBuf *)Page_Buf;		
	while(blkNum != NONE_BLOCK){		
		ReadPage(blkNum,0,Page_Buf);
		nextBlk = _swab32(pBuf->nextBlk) & NONE_BLOCK;
		Erase_Cluster(blkNum);
		blkNum = nextBlk;		
	}
	memset(pFile->Buffer,0xff,BLOCK_SIZE);	
	pFile->curBlk = pFile->hdr->firstblk;
	pFile->prevBlk = pFile->curBlk;
	pFile->nextBlk = NONE_BLOCK;
	pFile->filebufnum = 0;
	pFile->fileCurpos = 0;
	pFile->filesize = 0;		
	pFile->filechanged = 0;
	pFile->hdr->size = 0;
	return 0;
}

int initFileSys(){
	u8 err;
	pFileMem = OSMemCreate(FileMemPart,FILE_BUF_NUM,sizeof(FILE),&err);
	if(pFileMem == 0){
		Uart_Printf("Failed to Initiate File System!\n");
		return 1;
	}else{	
		_read_block(ROOT_BLOCK,(u8 *)root_buf);
		return 0;
	}
}

FILE *OpenFile(char *name,int mode){
	FileHdr *hdr;
	FILE *pFile;
	u8 err;
	hdr = _find_file(name,0);
	if(hdr == 0) return 0;
		
	pFile = OSMemGet(pFileMem,&err);
	if(pFile == 0) return 0;
	
	pFile->hdr = hdr;
	pFile->filemode = mode;		
	pFile->filesize = hdr->size;
	
	if(pFile->filemode == FILEMODE_WRITE){
		_zero_file(pFile);
	}else{
		_read_file_1stBlk(pFile);
	}	
	return pFile;
}
int CreateFile(char *name){
	int blkNum;
	FileHdr *hdr;	
	hdr = _find_file(name,0);
	/*
	** file exists
	*/
	if(hdr != 0) return 0;

	hdr = _find_file(name,1);
	/*
	** no space for file header 
	*/
	if(hdr == 0) return 1;
	
	blkNum = _seek_blank_blk(START_BLOCK);
	if(blkNum == NONE_BLOCK) return 1;	
	memcpy(hdr->name,name,MAX_FILENAME_LEN);
	memset(hdr+MAX_FILENAME_LEN,0,sizeof(FileHdr)-MAX_FILENAME_LEN);
	hdr->firstblk = blkNum;	
	//UPDATE_ROOT_BLOCK;
	return 0;
}
int DeleteFile(char *name){
	int blkNum,nextBlk;
	FileHdr *hdr;
	PageBuf *pBuf;	
	hdr = _find_file(name,0);
	if(hdr == 0) return 1;	
	blkNum = hdr->firstblk;
	pBuf = (PageBuf *)Page_Buf;		
	while(blkNum != NONE_BLOCK){		
		ReadPage(blkNum,0,Page_Buf);
		nextBlk = _swab32(pBuf->nextBlk) & NONE_BLOCK;
		Erase_Cluster(blkNum);
		blkNum = nextBlk;
	}
	memset(hdr,0,sizeof(FileHdr));	
	UPDATE_ROOT_BLOCK;
	return 0;
	
}
int FlushFile(FILE *pFile){
	_write_file(pFile);
	return 0;
}
int CloseFile(FILE *pFile){	
	if((pFile->filemode & FILEMODE_WRITE) == FILEMODE_WRITE){
		pFile->hdr->size = pFile->filesize;
		UPDATE_ROOT_BLOCK;
							
		_write_file(pFile);
		OSMemPut(pFileMem,pFile);
		return 0;
	}else{		
		OSMemPut(pFileMem,pFile);
		return 0;
	}
}
u32 FileSize(FILE *pFile){
	return pFile->filesize;
}
int FileExist(char *name){
	FileHdr *hdr = _find_file(name,0);
	if(hdr == 0) return 0;
	return 1;
}
int SeekFile(FILE *pFile,long offset,int origin){
	int err = 0;
	switch(origin){
		case FILESEEK_SET:{
			if(pFile->curBlk != pFile->hdr->firstblk){
				_write_file(pFile);
				err = _read_file_1stBlk(pFile);
				if(err) break;
			}else{
				pFile->filebufnum = 0;
				pFile->fileCurpos = 0;
			}
		}
		case FILESEEK_CUR:{			
			if(pFile->fileCurpos + offset > pFile->filesize){				
				err = 1;
				break;
			}
			if(pFile->filebufnum + offset < BLOCK_SIZE){				
				pFile->fileCurpos += offset;
				pFile->filebufnum += offset;
			}else{
				int n1,n2;
								
				_write_file(pFile);

				n1 = BLOCK_SIZE - pFile->filebufnum;				
				n2 = offset - n1;
				pFile->filebufnum += n1;
				pFile->fileCurpos += n1;
				
				while(n2 >= 0){					
					err = _read_file(pFile);
					if(err) break;
										
					if(pFile->filebufnum + n2 < BLOCK_SIZE){						
						pFile->fileCurpos += n2;
						pFile->filebufnum += n2;
					}else{
						pFile->filebufnum += BLOCK_SIZE;
						pFile->fileCurpos += BLOCK_SIZE;							
					}
					n2 -= BLOCK_SIZE;
				}
			}
			break;
		}		
		case FILESEEK_END:{	
			err = 1;
			break;
		}
		default:{
			err = 1;
		}
	}
	return err;
}
int ReadFile(FILE *pFile, u8 *rBuf, u32 nByte){
	int amt,err;	
	if((nByte == 0 || pFile->filemode & FILEMODE_READ) != FILEMODE_READ){
		return 0;
	}
	if(pFile->fileCurpos  >= pFile->filesize){
		return 0;
	}
	if(pFile->fileCurpos + nByte > pFile->filesize){
		amt = pFile->filesize - pFile->fileCurpos;
	}else{
		amt = nByte;
	}
	if(pFile->filebufnum + amt <= BLOCK_SIZE){
		memcpy(rBuf,&pFile->Buffer[pFile->filebufnum],amt);
		pFile->fileCurpos += amt;
		pFile->filebufnum += amt;
	}else{
		int n1,n2,k;
		k = 0;
		n1 = BLOCK_SIZE - pFile->filebufnum;
		memcpy(&rBuf[k],&pFile->Buffer[pFile->filebufnum],n1);
		pFile->filebufnum += n1;
		pFile->fileCurpos += n1;
		k += n1;
		n2 = amt - n1;
		while(n2 > 0){
			err = _read_file(pFile);
			if(err){
				amt = k;
				break;
			}
			if(pFile->filebufnum + n2 <= BLOCK_SIZE){
				memcpy(&rBuf[k],&pFile->Buffer[pFile->filebufnum],n2);
				pFile->fileCurpos += n2;
				pFile->filebufnum += n2;
			}else{
				memcpy(&rBuf[k],&pFile->Buffer[pFile->filebufnum],BLOCK_SIZE);				
				pFile->filebufnum += BLOCK_SIZE;
				pFile->fileCurpos += BLOCK_SIZE;	
				k += BLOCK_SIZE;
			}
			n2 -= BLOCK_SIZE;
		}
	}
	return  amt;
}

int WriteFile(FILE *pFile, u8 *wrBuf, u32 nByte){
	int amt;
	if(nByte == 0 || (pFile->filemode & FILEMODE_WRITE) != FILEMODE_WRITE){
		return 0;
	}		
	
	if(pFile->filebufnum + nByte <= BLOCK_SIZE){
		memcpy(&pFile->Buffer[pFile->filebufnum],wrBuf,nByte);
		pFile->fileCurpos += nByte;
		pFile->filebufnum += nByte;	
		amt = nByte;
	}else{
		int n1,n2;
		amt = 0;
		n1 = BLOCK_SIZE - pFile->filebufnum;
		memcpy(&pFile->Buffer[pFile->filebufnum],&wrBuf[amt],n1);
		pFile->filebufnum += n1;
		pFile->fileCurpos += n1;
		amt += n1;
		n2 = nByte - n1;
	
		while(n2 > 0){
			if(pFile->nextBlk == NONE_BLOCK){
				pFile->nextBlk = _seek_blank_blk(pFile->curBlk+1);
				if(pFile->nextBlk == NONE_BLOCK){
					pFile->nextBlk = _seek_blank_blk(START_BLOCK);
					if(pFile->nextBlk == NONE_BLOCK || pFile->nextBlk == pFile->curBlk){
						pFile->nextBlk = NONE_BLOCK;
					}
				}
				_write_file(pFile);
				if(pFile->nextBlk == NONE_BLOCK) break;				
				pFile->prevBlk = pFile->curBlk;
				pFile->curBlk = pFile->nextBlk;
				pFile->nextBlk = NONE_BLOCK;				
				pFile->filebufnum = 0;
				memset(pFile->Buffer,0xff,BLOCK_SIZE);
				
			}else{
				_write_file(pFile);
				_read_file(pFile);
			}			
			if(pFile->filebufnum + n2 <= BLOCK_SIZE){
				memcpy(&pFile->Buffer[pFile->filebufnum],&wrBuf[amt],n2);
				pFile->fileCurpos += n2;
				pFile->filebufnum += n2;				
			}else{
				memcpy(&pFile->Buffer[pFile->filebufnum],&wrBuf[amt],BLOCK_SIZE);
				pFile->filebufnum += BLOCK_SIZE;
				pFile->fileCurpos += BLOCK_SIZE;	
				amt += BLOCK_SIZE;
			}
			n2 -= BLOCK_SIZE;
		}
	}
	if(pFile->fileCurpos > pFile->filesize){
		pFile->filesize = pFile->fileCurpos;
	}	
	pFile->filechanged = 1;
	return amt;
}

int sprintf(char *str , const char *format , ...){
	va_list ap;   
    
    va_start(ap,format);
    if(str == 0){ 
    	char string[256];   	
    	vsprintf(string,format,ap); 
    	Uart_SendString(string);
    }else{
    	vsprintf(str,format,ap);    	
    }       
    va_end(ap); 
	return 0;
}

int fprintf(FILE *pFile, const char *format, ...){
	
	va_list ap;
	char string[256]; 
	
	va_start(ap,format);
    if(pFile == 0){
    	vsprintf(string,format,ap); 
    	Uart_SendString(string);
    }else{    	    	   	
    	vsprintf(string,format,ap);    	
    	WriteFile(pFile,(u8 *)string,strlen(string));
    }    
    va_end(ap);    
	return 0;
}
int fflush(FILE *pFile ){
	FlushFile(pFile);
	return 0;
}
char *fgets(char *str, int n, FILE *pFile){
	extern void Uart_GetString(char *string);
	int k;
	if(pFile == 0){
		Uart_GetString(str);
		k = strlen(str);
		if(str[0]==0 || k >= n)	return 0;
		str[k] = '\n';
		
	}else{
		k = ReadFile(pFile,(u8 *)str,n);
		str[k] = 0;
	}
	return str;
}

void listAllFile(){
	int i,k;
	char name[15];	
	FileHdr *fhdr;
	PageBuf *pBuf = (PageBuf *)Page_Buf;
	name[8] = '.';
	name[12] = 0;
	Uart_Printf("\nfile list: \n");
	k = 0;
	for(i=0;i<512;i++){
		fhdr = (FileHdr *)root_buf[i];
		if(fhdr->name[0] != 0){
			int blknum;
			k++;
			memcpy(name,fhdr->name,8);
			memcpy(&name[9],fhdr->ext,3);
			Uart_Printf("%s\t",name);
			Uart_Printf("size: %x\t",fhdr->size);
			Uart_Printf("first block: : %x\n",fhdr->firstblk);
			/*			
			blknum = fhdr->firstblk;
			do{
				ReadPage(blknum,0,Page_Buf);
				Uart_Printf("cur: %x\t",blknum);
				Uart_Printf("attr: %x\t",_swab32(pBuf->attr));
				Uart_Printf("reserve: %x\t",_swab32(pBuf->resvd));
				Uart_Printf("prev: %x\t",_swab32(pBuf->prevBlk));
				Uart_Printf("next: %x\n",_swab32(pBuf->nextBlk));

				blknum = _swab32(pBuf->nextBlk) & NONE_BLOCK;
			}while(blknum != 0xffff);	
			//OSTimeDly(10);
			*/
		}
	}
	Uart_Printf("total files: %d\n",k);	
}
void disp_fileInfo(char *name){
	
	int blknum;
	FileHdr *fhdr;
	PageBuf *pBuf = (PageBuf *)Page_Buf;	
	Uart_Printf("\n%s file information: ",name);
	fhdr = _find_file(name,0);
	if(fhdr == 0){
		 Uart_Printf("\nnot found!");
		 return;
	}
	
	Uart_Printf("\nsize: %x\t",fhdr->size);
	Uart_Printf("first block: : %x",fhdr->firstblk);
	blknum = fhdr->firstblk;
	do{
		ReadPage(blknum,0,Page_Buf);
		Uart_Printf("\ncur: %x\t",blknum);
		Uart_Printf("attr: %x\t",_swab32(pBuf->attr));
		Uart_Printf("reserve: %x\t",_swab32(pBuf->resvd));
		Uart_Printf("prev: %x\t",_swab32(pBuf->prevBlk));
		Uart_Printf("next: %x\n",_swab32(pBuf->nextBlk));
		blknum = _swab32(pBuf->nextBlk) & NONE_BLOCK;
		//OSTimeDly(10);
	}while(blknum != NONE_BLOCK);	
	return;
}

⌨️ 快捷键说明

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