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 + -
显示快捷键?