From 476b73692511eeed9602d71e773da5ab24831b74 Mon Sep 17 00:00:00 2001 From: hackbard Date: Tue, 11 Sep 2007 01:23:21 +0200 Subject: [PATCH] some more pffs code (structures become identifiable ;) --- betty/Makefile | 3 +- betty/pffs.c | 196 ++++++++++++++++++++++++++++++++++--------------- betty/pffs.h | 54 ++++++++++---- 3 files changed, 180 insertions(+), 73 deletions(-) diff --git a/betty/Makefile b/betty/Makefile index 0a35586..ad7c7d4 100644 --- a/betty/Makefile +++ b/betty/Makefile @@ -19,7 +19,8 @@ HOST_TARGET = lpcload fwdump CROSS_TARGET = fwbc.hex fwflash.hex betty.hex # betty deps -BETTY_DEPS = system.o uart.o buttons.o spi.o display.o flash.o functions.o #pffs.o +BETTY_DEPS = system.o uart.o buttons.o spi.o display.o flash.o functions.o +#BETTY_DEPS += pffs.o # all projects all: $(HOST_TARGET) $(CROSS_TARGET) diff --git a/betty/pffs.c b/betty/pffs.c index 1257d18..f1fe3f4 100644 --- a/betty/pffs.c +++ b/betty/pffs.c @@ -11,37 +11,23 @@ * functions */ -u32 pffs_get_ptr(t_pffs *pffs,u8 sector) { - - u16 data[3]; - u32 iaddr; - u32 daddr; - u8 fnlen; - u8 found; +#define pffs_check_magic(data) (((data)&PFFS_INDEX_MAGIC_MASK)==PFFS_INDEX_MAGIC) +#define pffs_fnlen(data) (((data)&PFFS_FNLEN_MASK)>>4) +#define pffs_daddr_msb(data) (((data)&PFFS_LEN_MSB_MASK)) +#define pffs_sec_erase(pffs,sec) pffs->fe(pffs->base_addr|pffs->sec_addr[sec]) - iaddr=0; - daddr=0; - found=0; +u32 pffs_find_index(t_pffs *pffs,u8 sector) { - while(1) { - pffs->fr(pffs->base_addr+pffs->sec_addr[sector]+iaddr,data,6); - if(!((data[0]&0xff00)==PFFS_INDEX_MAGIC)) - break; - found=1; - fnlen=(data[0]&0x00f0)>>4; - iaddr+=(6+fnlen+fnlen); - daddr=((data[0]&0x000f)<<16)|data[1]; - } + u16 data; - pffs->data_ptr=daddr; + pffs->fr(pffs->base_addr+pffs->sec_addr[sector],&data,2); - if(found) { - pffs->index_ptr[0]=pffs->sec_addr[sector]; - pffs->index_ptr[1]=pffs->sec_addr[sector]+iaddr; - return 0; + if((data&0xf000)==PFFS_INDEX_MAGIC) { + pffs->index_sec=sector; + return PFFS_INDEX_FOUND; } - else - return -1; + + return PFFS_NO_INDEX_FOUND; } int pffs_sec_empty(t_pffs *pffs,u8 sec) { @@ -52,26 +38,71 @@ int pffs_sec_empty(t_pffs *pffs,u8 sec) { addr=pffs->base_addr|pffs->sec_addr[sec]; while(addr<(pffs->base_addr|pffs->sec_addr[sec+1])) { - data=*((u16 *)(addr)); + pffs->fr(addr,&data,2); if(data!=0xffff) - return 0; + return PFFS_SEC_NOT_EMPTY; addr+=2; } - return 1; + return PFFS_SEC_EMPTY; } -#define pffs_sec_erase(pffs,sec) pffs->fe(pffs->base_addr|pffs->sec_addr[sec]) +int pffs_find_data_tmp(t_pffs *pffs,u8 sector) { + + u32 iaddr,daddr,dend,dstart; + u16 data[3]; + u8 fnlen; + + iaddr=pffs->base_addr|pffs->sec_addr[pffs->index_sec]; + dstart=pffs->sec_addr[sector]; + dend=pffs->sec_addr[sector+1]; + + while(iaddr<(pffs->base_addr|pffs->sec_addr[sector+1])) { + pffs->fr(iaddr,data,6); + if(pffs_check_magic(data[0])) + break; + daddr=pffs_daddr_msb(data[0])|data[1]; + if((daddr+data[2]=dend)) { + fnlen=pffs_fnlen(data[0]); + iaddr+=(6+fnlen+fnlen); + continue; + } + else + return PFFS_NO_DATA_TMP; + } + + pffs->data_tmp_sec=sector; + if(pffs_sec_empty(pffs,sector)!=PFFS_SEC_EMPTY) + pffs->fe(pffs->base_addr|dstart); + + return PFFS_DATA_TMP_FOUND;; +} int pffs_orientate(t_pffs *pffs) { - u8 sec,sec0,sec1; + u8 sec,sec0,sec1,found; - /* check index sectors */ sec0=pffs->sec_num_index[0]; sec1=pffs->sec_num_index[1]; - if(!(pffs_get_ptr(pffs,sec0)&pffs_get_ptr(pffs,sec1))) - return 0; + + found=0; + + /* check index sectors */ + if(pffs_find_index(pffs,sec0)==PFFS_INDEX_FOUND) + found=1; + else if(pffs_find_index(pffs,sec1)==PFFS_INDEX_FOUND) + found=1; + + /* chose temp data sector */ + if(found) { + sec0=pffs->sec_num_data[0]; + sec1=pffs->sec_num_data[1]; + for(sec=sec1;sec>=sec0;sec--) + if(pffs_find_data_tmp(pffs,sec)==PFFS_DATA_TMP_FOUND) + break; + + return PFFS_INDEX_FOUND; + } /* initial run => no data + no index assumed => check whether erased! */ // erase index sectors @@ -79,9 +110,11 @@ int pffs_orientate(t_pffs *pffs) { pffs_sec_erase(pffs,sec0); if(!pffs_sec_empty(pffs,sec1)) pffs_sec_erase(pffs,sec1); + pffs->index_sec=sec0; // erase data sectors sec0=pffs->sec_num_data[0]; sec1=pffs->sec_num_data[1]; + pffs->data_tmp_sec=sec1; for(sec=sec0;sec<=sec1;sec++) if(!pffs_sec_empty(pffs,sec)) pffs_sec_erase(pffs,sec); @@ -128,77 +161,124 @@ int pffs_init(t_pffs *pffs) { return 0; } -#define pffs_check_magic(data) (((data)&PFFS_INDEX_MAGIC_MASK)==PFFS_INDEX_MAGIC) -#define pffs_fnlen(data) (((data)&PFFS_FNLEN_MASK)>>4) -#define pffs_daddr_msb(data) (((data)&)) - int pffs_find_file(t_pffs *pffs,char *file,u32 *iaddr,u32 *daddr,u16 *len) { u8 fnl; u16 data[PFFS_MAX_FILENAME_SIZE+PFFS_HEADER_SIZE]; - pffs->index_ptr[2]=pffs->base_addr|pffs->index_ptr[0]; + *iaddr=pffs->base_addr|pffs->sec_addr[pffs->index_sec]; - while(pffs->index_ptr[2]index_ptr[1]) - pffs->fr(iaddr,data,3); + while(*iaddrsec_addr[pffs->index_sec]) { + pffs->fr(*iaddr,data,3); if(!pffs_check_magic(data[0])) break; fnl=pffs_fnlen(data[0]); - pffs->fr(iaddr+6,data+3,fnl+fnl); + pffs->fr(*iaddr+6,data+3,fnl+fnl); - if(!strncmp(fd->file,(char *)(data+3),fnl+fnl)) { - *daddr=((data[0]&0x000f)<<16)|data[1]; + if(!strncmp(file,(char *)(data+3),fnl+fnl)) { + *daddr=pffs->base_addr|((data[0]&0x000f)<<16)|data[1]; *len=data[2]; - pffs->index_ptr[2]=*iaddr; - return PFFS_FILE_EXISTS; + return PFFS_FILE_FOUND; } - pffs->fr(iaddr,data,3); + + *iaddr+=(6+fnl+fnl); } return PFFS_FILE_NOT_FOUND; } -int pffs_open_read(t_pffs *pffs,t_pffs_fd *fd) { +int pffs_open_read(t_pffs_fd *fd) { - u32 iaddr; - u32 daddr; - u16 data[PFFS_MAX_FILENAME+PFFS_HEADER_SIZE]; + int ret; - iaddr=pffs->base_addr|pffs->index_ptr[0]; + ret=pffs_find_file(fd->pffs,fd->file, + &(fd->iaddr),&(fd->daddr),&(fd->len)); + + if(ret==PFFS_FILE_FOUND) { + fd->dptr=fd->daddr; + fd->mode=PFFS_READ; + } - return 0x23; + return ret; } +int pffs_open_write(t_pffs_fd *fd) { + + int ret; + + ret=pffs_find_file(fd->pffs,fd->file, + &(fd->iaddr),&(fd->daddr),&(fd->len)); + + switch(ret) { + case PFFS_FILE_NOT_FOUND: + fd->mode=PFFS_WRITE; + pffs_write_index_init(); + fd->dptr=fd->daddr; + break; + case PFFS_FILE_FOUND: + default: + break; + } + + return ret; +} + int pffs_open(t_pffs *pffs,t_pffs_fd *fd,char *file,u8 mode) { + int ret; + /* the pffs struct */ fd->pffs=pffs; /* filename */ fd->fn_size=strlen(file); - if(fd->fn_size>30) + if(fd->fn_size>PFFS_MAX_FILENAME_SIZE+PFFS_MAX_FILENAME_SIZE) return PFFS_FILENAME_TOO_LONG; strncpy(fd->file,file,fd->fn_size); if(fd->fn_size&1) fd->file[fd->fn_size++]='\0'; - /* mode */ - fd->mode=mode; + /* clear fd mode */ + fd->mode=0; /* action */ switch(mode) { case PFFS_READ: - pffs_open_read(pffs,fd); + ret=pffs_open_read(fd); break; case PFFS_WRITE: + ret=pffs_open_write(fd); break; case PFFS_RDWR: default: return PFFS_MODE_UNSUPPORTED; } - return 0; + return ret; +} + +int pffs_read(t_pffs_fd *fd,u8 *buf,int len) { + + int missing; + + /* check whether valid */ + if(!(fd->mode&PFFS_READ)) + return PFFS_EINVAL; + + /* checl len */ + if(len&1) + return PFFS_INVALID_LEN; + + missing=fd->len-(fd->dptr-fd->daddr); + if(len>missing) + len=missing; + + /* read */ + fd->pffs->fr(fd->dptr,(u16 *)buf,len); + fd->dptr+=len;; + + return len; } diff --git a/betty/pffs.h b/betty/pffs.h index faf0d38..a37876e 100644 --- a/betty/pffs.h +++ b/betty/pffs.h @@ -16,25 +16,46 @@ #define PFFS_MAX_FILENAME_SIZE 15 // in words #define PFFS_HEADER_SIZE 3 // in words -#define PFFS_REGISTERED (1<<0) +/* general pffs system */ +#define PFFS_INDEX_FOUND 0x00 +#define PFFS_NO_INDEX_FOUND 0x01 -#define PFFS_INDEX_MAGIC 0x7000 +#define PFFS_DATA_TMP_FOUND 0x00 +#define PFFS_NO_DATA_TMP 0x01 + +#define PFFS_SEC_NOT_EMPTY 0x00 +#define PFFS_SEC_EMPTY 0x01 +#define PFFS_REGISTERED (1<<0) + +/* pffs index format */ #define PFFS_INDEX_MAGIC_MASK 0xf000 -#define PFFS_RESERVED_MASK 0x0f00 +#define PFFS_STATE_MASK 0x0f00 #define PFFS_FNLEN_MASK 0x00f0 #define PFFS_LEN_MSB_MASK 0x000f +#define PFFS_INDEX_MAGIC 0x7000 +#define PFFS_INDEX_REMOVED 0x0700 + /* file modes */ #define PFFS_READ 0x01 #define PFFS_WRITE 0x02 #define PFFS_RDWR 0x03 -/* pffs write / read return codes */ -#define PFFS_FILE_EXISTS 0x01 +/* lseek offsets */ +#define PFFS_SEEK_SET 0x01 +#define PFFS_SEEK_CUR 0x02 +#define PFFS_SEEK_END 0x03 + +/* pffs open / write / read return codes */ +#define PFFS_FILE_FOUND 0x01 #define PFFS_FILE_NOT_FOUND 0x02 #define PFFS_NO_SPACE_LEFT 0x04 #define PFFS_FILENAME_TOO_LONG 0x08 +#define PFFS_MODE_UNSUPPORTED 0x10 + +#define PFFS_INVALID_LEN 0x01 +#define PFFS_EINVAL 0x02 /* type definitions */ @@ -42,21 +63,25 @@ typedef struct s_pffs { /* flash specs */ u32 base_addr; u32 *sec_addr; + u8 sec_num_data[2]; // first/last sector used for data + u8 sec_num_index[2]; // 2 sectors used as an index + /* flash write, read and sector erase function pointers */ int (*fw)(u32 addr,u16 *buf,int len); int (*fr)(u32 addr,u16 *buf,int len); int (*fe)(u32 addr); + /* pffs internal variables */ u8 state; - u32 data_ptr; // pointer where new data goes - u32 index_ptr[3]; // 0: start, 1: new, 2: current - u8 sec_num_data[2]; // data start/end sectors - u8 sec_num_index[2]; // 2 index sectors + u8 index_sec; // current index sector + u8 data_tmp_sec; // current temp data sector } t_pffs; typedef struct s_pffs_fd { u32 daddr; + u32 dptr; u32 iaddr; + u16 len; char file[PFFS_MAX_FILENAME_SIZE+PFFS_MAX_FILENAME_SIZE]; u8 fn_size; u8 mode; @@ -64,10 +89,11 @@ typedef struct s_pffs_fd { } t_pffs_fd; /* function prototypes */ -int pffs_open(t_pffs *pffs,char *file,u8 mode); -int pffs_write(t_pffs *pffs,int fd,u8 *buf,int len); -int pffs_read(t_pffs *pffs,int fd,u8 *buf,int len); -int pffs_close(t_pffs *pffs,int fd); -int pffs_unlink(t_pffs *pffs,char *file); +int pffs_open(t_pffs *pffs,t_pffs_fd *fd,char *file,u8 mode); +int pffs_write(t_pffs_fd *fd,u8 *buf,int len); +int pffs_read(t_pffs_fd *fd,u8 *buf,int len); +int pffs_lseek(t_pffs_fd *fd,u8 offset,int len); +int pffs_close(t_pffs_fd *fd); +int pffs_unlink(t_pffs_fd *fd,char *file); #endif -- 2.20.1