📄 filesys.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 + -