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

📄 filesys.c

📁 本人编写的无线电话程序,给予PIC18C801设计,包括了uCOS的移植以及菜单,自己设计的拼音注入法,完整地一级汉字库,希望对大家有所帮助
💻 C
字号:
#include "includes.h"
#include "feeprom.h"
#include "device.h"
#include "filesys.h"

extern OS_EVENT  * rom EepromSem;

//Configurable constances
#define BLOCK_SIZE		64
#define NUM_OF_BLKS		248
#define MAX_FILE_NUM	10		//the F_NODE is 14 bytes long, so the number of files shall not larger than 18

#define FILESYSUW_START	0
#define F_NODE_START	16
#define BLK_INDEX_START	256
#define FAT_TBL_SIZE	512

#define HDL_NULL_FILE 	0
#define EOF				0xff
#define CURFILESYSID	0x5b57

#define OP_READ			0
#define OP_WRITE		1

//The structure of file system
// (ORG 0)
//		filesysinfo[] and some other information, auch as name, size and so on
// (ORG 16)
// 		F_NODE[]
// (ORG 256)
// 		sys_blk_index[]
// (ORG 512)
// 		blocks(currently there are 248 64bytes blocks as defined above)
// Thus, the start address of block "n" in the physical media can be calculated
// like this: address = n*64+512


//16 BYTEs totally
typedef rom struct fnode{
	INT8U name[6];
	INT16U len;
	INT8U num_of_blks;
	INT8U firstblk;
	INT8U lastblk;
	INT8U rom * buffer;	
	INT8U filler[2];			//no function, just make the addresses to be n*16
}F_NODE;

//16 bytes all together
typedef rom struct _FILESYSINFO{
	INT16U 	id;
	INT8U  	ver;
	INT8U  	rev;

	INT16U 	blocksize;
	INT16U 	blocknum;

	INT16U 	fnodestart;
	INT16U 	blkidxstart;
	INT16U	datastart;

	INT8U	fnodenum;
}FILESYSINFO;

INT8U proc_blkindex(INT8U option);
INT8U proc_fnode(INT8U option);
INT8U proc_filesysinfo(INT8U option);

INT8U alloc_blk(INT8U n, INT8U * eb);
INT8U file_open(INT8U rom * pname, INT8U rom * * pbuf);
INT16U file_read(INT8U hdl_file);


#pragma romdata EXTRAM
INT8U rom sys_blk_index[256];
F_NODE sys_file[MAX_FILE_NUM];
FILESYSINFO filesysinfo;


INT8U rom mediahdl;

#pragma code MYCODE
INT8U filesys_init(void){
	INT8U i,result;
	mediahdl = sysdev_open(DEV_ID_SEEPROM);
	proc_filesysinfo(OP_READ);
	if(filesysinfo.id != CURFILESYSID){
		result = FS_UNKNOWN_FILESYS;
	}
	else{
		proc_blkindex(OP_READ);
		proc_fnode(OP_READ);
		result = FS_OK;
	}
	for(i = 0; i<MAX_FILE_NUM; i++){
		sys_file[i].buffer = (INT8U rom *)0xFFFFFF;
	}
	return(result);
}

void filesys_format(void){
	INT8U i;

	filesysinfo.id = CURFILESYSID;
	filesysinfo.ver = 1;
	filesysinfo.rev = 0;
	filesysinfo.blocksize = BLOCK_SIZE;
	filesysinfo.blocknum = NUM_OF_BLKS;
	filesysinfo.fnodestart = F_NODE_START;
	filesysinfo.blkidxstart = BLK_INDEX_START;
	filesysinfo.datastart = FAT_TBL_SIZE;
	filesysinfo.fnodenum = MAX_FILE_NUM;
	
	for(i=0; i<NUM_OF_BLKS-1; i++){
		sys_blk_index[i] = i+1;
	}
	sys_blk_index[NUM_OF_BLKS-1] = EOF;
	
	sys_file[HDL_NULL_FILE].name[0] = 'N';
	sys_file[HDL_NULL_FILE].name[1] = 'U';
	sys_file[HDL_NULL_FILE].name[2] = 'L';
	sys_file[HDL_NULL_FILE].name[3] = 'L';
	sys_file[HDL_NULL_FILE].name[4] = 0x00;
	sys_file[HDL_NULL_FILE].len = BLOCK_SIZE * NUM_OF_BLKS;
	sys_file[HDL_NULL_FILE].num_of_blks = NUM_OF_BLKS;
	sys_file[HDL_NULL_FILE].firstblk = 0;
	sys_file[HDL_NULL_FILE].lastblk = NUM_OF_BLKS-1;
	
	for(i=1; i< MAX_FILE_NUM; i++){
		sys_file[i].name[0] = 0xff;
		sys_file[i].firstblk = EOF;
		sys_file[i].lastblk = EOF;
		sys_file[i].len = 0;
		sys_file[i].num_of_blks = 0;
	}
	proc_filesysinfo(OP_WRITE);
	proc_blkindex(OP_WRITE);
	proc_fnode(OP_WRITE);
}

INT8U file_create(INT8U rom * pname, INT16U len){
	INT8U en,i,n,j;
	
	//find an empty file item
	
	for(i = 1; i< MAX_FILE_NUM; i++){
		if(sys_file[i].name[0] == EOF) break;
	}
	if(i==MAX_FILE_NUM) return(0xff);
	//see if the idle bloks is enough
	if(sys_file[HDL_NULL_FILE].len < len) return(0xff);
	//calculate the block number
	n=len/BLOCK_SIZE +1;
	sys_file[i].num_of_blks = n;
	sys_file[i].len = len;
	
	//link the blocks to the file
	sys_file[i].firstblk = alloc_blk(n, &en);
	sys_file[i].lastblk = en;
	//copy the name
	for(j=0;j<6;j++){
		sys_file[i].name[j] = *pname++;
	}
	proc_blkindex(OP_WRITE);
	proc_fnode(OP_WRITE);
	//
	return(i);
}


INT8U file_delete(INT8U rom * pname){
	INT8U hdl,k;
	hdl = file_open(pname,(INT8U rom **)0xffff);
	k = sys_file[hdl].lastblk;
	sys_blk_index[k] = sys_file[HDL_NULL_FILE].firstblk;
	sys_file[HDL_NULL_FILE].firstblk = sys_file[hdl].firstblk;
	sys_file[HDL_NULL_FILE].num_of_blks += sys_file[hdl].num_of_blks;
	sys_file[HDL_NULL_FILE].len = (INT16U)sys_file[HDL_NULL_FILE].num_of_blks * BLOCK_SIZE;

	sys_file[hdl].name[0] = 0xff;
	sys_file[hdl].lastblk = EOF;
	sys_file[hdl].firstblk = EOF;
	return(0);
}

//return the handle of the file, and get the exchange buffer, read file from EEPROM to the buffer
INT8U file_open(INT8U rom * pname, INT8U rom * * ppbuf){
	INT8U result,i,j;
	INT8U rom * p;
	p = pname;
	result = 1;
	for(i=0; i< MAX_FILE_NUM; i++){
		for(j = 0; j<6; j++){
			if(sys_file[i].name[j] != *p) break;
			if(*p == 0){
				result = 0;
				break;
			}
			p++;
		}
		if(result == 0){	//yes, we find the file...
			if((INT16U)ppbuf != 0xffffff){	//if the caller really want open the file ...
				if((INT24U)sys_file[i].buffer == 0xffffff){//if the file has not been opened ...
					p = rmalloc(sys_file[i].len);
					sys_file[i].buffer = p;
					*ppbuf = p;
					file_read(i);
				}
				else{
					*ppbuf = sys_file[i].buffer;
				}
			}
			return(i);
		}
	}
	return(0xff);
}

//return the length of file, internal function
INT16U file_read(INT8U hdl_file){
	INT8U k,i,n,err;
	INT8U rom * pd;
	INT16U totallen, tmplen, sadd;

	k = sys_file[hdl_file].firstblk;
	sadd = FAT_TBL_SIZE+ (INT16U)k*BLOCK_SIZE;
	totallen = sys_file[hdl_file].len;
	pd = sys_file[hdl_file].buffer;
	//find longest continous block section, and read it
	while(totallen != 0){
		if(k == EOF) return(0xffff);
		n = 1;
		for(;;){
			i = k;
			k = sys_blk_index[k];
			if(k-i == 1){
				n++;
			}
			else break;
		}
		tmplen = (totallen>((INT16U)n*BLOCK_SIZE))? ((INT16U)n*BLOCK_SIZE) : totallen;
		//add read from eeprom function here
		OSSemPend(EepromSem,0,&err);
		if(err == OS_NO_ERR){
			sysdev_ioctl(mediahdl, EEPROM_ADDRESS, sadd);
			sysdev_read(mediahdl, pd, tmplen);
			OSSemPost(EepromSem);
		}
		totallen -= tmplen;
		pd += tmplen;
		sadd = FAT_TBL_SIZE+ (INT16U)k*BLOCK_SIZE;
	}
	return(sys_file[hdl_file].len);
}

INT8U file_save(INT8U hdl_file, INT16U pos, INT16U len){
	INT8U i,k,n,sblk,eblk,err;
	INT8U rom * ps;
	INT16U totallen, tmplen, sadd;
	if(hdl_file >= MAX_FILE_NUM) return(0);
	sblk = pos / BLOCK_SIZE;
	eblk = (pos+len -1)/BLOCK_SIZE;
	k = sys_file[hdl_file].firstblk;
	for(i = 0; i<sblk; i++){
		k=sys_blk_index[k];
	}
	sadd = FAT_TBL_SIZE+ (INT16U)k*BLOCK_SIZE + (pos % BLOCK_SIZE);
	totallen = len;
	ps = sys_file[hdl_file].buffer + pos;
	//find longest continous block section, and read it
	while(totallen != 0){
		if(k == EOF) return(0xffff);
		n = 1;
		for(;;){
			i = k;
			k = sys_blk_index[k];
			if(k-i == 1){
				n++;
			}
			else break;
		}
		tmplen = (totallen>((INT16U)n*BLOCK_SIZE))? ((INT16U)n*BLOCK_SIZE) : totallen;
		//add read from eeprom function here
		OSSemPend(EepromSem,0,&err);
		if(err == OS_NO_ERR){
			sysdev_ioctl(mediahdl, EEPROM_ADDRESS, sadd);
			sysdev_write(mediahdl, ps, tmplen);
			OSSemPost(EepromSem);
		}
		totallen -= tmplen;
		ps += tmplen;
		sadd = FAT_TBL_SIZE+ (INT16U)k*BLOCK_SIZE;
	}
	return(len);
}

INT16U file_getlength(INT8U hdl_file){
	return(sys_file[hdl_file].len);
}

//use this function to trim the file blocks
void filesys_trim(void){
}


//-------------------------------------------------------------------//
//          The functions followed can only be used internally       //
//-------------------------------------------------------------------//

//allocate numbers of blocks and return the head of the block serial
INT8U alloc_blk(INT8U n, INT8U * eb){
	INT8U fb,lb,j;
	if(sys_file[HDL_NULL_FILE].num_of_blks < n) {
		*eb = EOF;
		return(EOF);
	}
	fb = sys_file[HDL_NULL_FILE].firstblk;
	lb = fb;
	for(j = 0; j<n-1; j++){
		lb = sys_blk_index[lb];
	}
	
	sys_file[HDL_NULL_FILE].firstblk = sys_blk_index[lb];
	sys_blk_index[lb] = EOF;

	sys_file[HDL_NULL_FILE].len -= (INT16U)n*BLOCK_SIZE;
	sys_file[HDL_NULL_FILE].num_of_blks -= n;
	*eb = lb;
	return(fb);
}


INT8U proc_blkindex(INT8U option){
	INT8U err;
	OSSemPend(EepromSem, 0, &err);
	if(err == OS_NO_ERR){
		sysdev_ioctl(mediahdl, EEPROM_ADDRESS, BLK_INDEX_START);
		if(option == OP_READ)
			sysdev_read(mediahdl, sys_blk_index, sizeof(sys_blk_index));
		else
			sysdev_write(mediahdl, sys_blk_index, sizeof(sys_blk_index));
		OSSemPost(EepromSem);
	}
}

INT8U proc_fnode(INT8U option){
	INT8U err;
	OSSemPend(EepromSem, 0, &err);
	if(err == OS_NO_ERR){
		sysdev_ioctl(mediahdl, EEPROM_ADDRESS, F_NODE_START);
		if(option == OP_READ)
			sysdev_read(mediahdl, (INT8U rom *)sys_file, sizeof(sys_file));
		else
			sysdev_write(mediahdl, (INT8U rom *)sys_file, sizeof(sys_file));
		OSSemPost(EepromSem);
	}
}

INT8U proc_filesysinfo(INT8U option){
	INT8U err;
	OSSemPend(EepromSem, 0, &err);
	if(err == OS_NO_ERR){
		sysdev_ioctl(mediahdl, EEPROM_ADDRESS, 0);
		if(option == OP_READ)
			sysdev_read(mediahdl, (INT8U rom *)(&filesysinfo), sizeof(filesysinfo));
		else
			sysdev_write(mediahdl, (INT8U rom *)(&filesysinfo), sizeof(filesysinfo));
		OSSemPost(EepromSem);
	}
}

⌨️ 快捷键说明

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