some more pffs code (structures become identifiable ;)
authorhackbard <hackbard@staubsauger.localdomain>
Mon, 10 Sep 2007 23:23:21 +0000 (01:23 +0200)
committerhackbard <hackbard@staubsauger.localdomain>
Mon, 10 Sep 2007 23:23:21 +0000 (01:23 +0200)
betty/Makefile
betty/pffs.c
betty/pffs.h

index 0a35586..ad7c7d4 100644 (file)
@@ -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)
index 1257d18..f1fe3f4 100644 (file)
  * 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]<dstart)|(daddr>=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]<pffs->index_ptr[1])
-               pffs->fr(iaddr,data,3);
+       while(*iaddr<pffs->sec_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;
 }
 
index faf0d38..a37876e 100644 (file)
 #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