www.pudn.com > flashfs.rar > simpleffs.c
/* * This is a routine to verify my flash file system software. * It opens a disk file and uses that for the flash. It is * a random access file so that I can read anywhere in the * space. Right now it emulates 29F040 which is a 512k byte * devices with 64k sectors which gives the device 8 secotrs * which can be erased individually. * * now support spacial feature: * 1.append bin file * 2.one file max length less than 64kb * 3.when create a file,sffs will check current sector free space, if * this sector not have enough space to create the file,will create * this file at next sector. * 4.seek support three mode:SET,CUR,END * * TODO * 1, change the config information to use image control. * 2, can make file length more than 64kb. * 3, support cache when write and append bin file * 4, don't use KeySRAM to save the file length and data length * */ #include#include #include #include #include #include "../globalconfig.h" #include "../globalerror.h" #include "../vs2000.h" #include "../include/flashAPI.h" #include "../include/KeySRAMDrvAPI.h" #include "../include/imagesctrlAPI.h" #include "../include/syslog.h" #include "../include/misc.h" #include "simpleffs.h" #define ENABLE_LF 1 #define DEBUG_TEST 0 #define DEBUG_FORMAT 0 #define DEBUG_CREATE 0 #define DEBUG_CONSOL 0 #define DEBUG_WRITE 1 #define DEBUG_GC 0 static int fdiskReady = 0; static char sectorerased[MAXSECTORS]; //0-- FFS_START_SECTOR ; 1--FFS_START_SECTOR+1; ... could use bitmap in future static int workingsector=0; static int debug=0; static int delbfrwrite=1; //extern is removed static int system_error; static int system_log; static int ffs_error; //enad changed static int doconsolidate = 0; //could be removed in the future static char cachename[MAXCACHE][INFOENTRY+1]; static unsigned char cacheuse[MAXCACHE]; static int cachesector[MAXCACHE]; static int cachepacket[MAXCACHE]; static unsigned char openedFileList[NUMOPENFILES]; static filedesc fileds[NUMOPENFILES]; //add by bryan for consolidate static int run_gc_time=0; static long swap_packets_addr_map[NUMPACKETS];//the swap memory address map. //add this struct for bin file append #if ENABLE_LF // #define BIN_FILE_INFO_END_OFFSET (BIN_FILE_INFO_BEGIN_OFFSET+BIN_FILE_MAX_NUM*sizeof(BIN_FILE_INFO_INKEYSRAM)) // #define BIN_FILE_INFO_END_ADDR (KEYSRAM_BASE_ADDRESS+BIN_FILE_INFO_END_OFFSET) #define BIN_FILE_TOTAL_NUM_ADDR BIN_FILE_INFO_END_ADDR #else static long KEYSRAM_BASE_ADDRESS; static long BIN_FILE_INFO_BEGIN_ADDR; static long BIN_FILE_INFO_END_OFFSET; static long BIN_FILE_INFO_END_ADDR; static long BIN_FILE_TOTAL_NUM_ADDR; #endif static BIN_FILE_INFO_INKEYSRAM *pbin_file_info[BIN_FILE_MAX_NUM]; static int total_bin_files = 0; /* * Low level FLASH operater API * */ int read_flash(long addr) { return (int)(*(unsigned char*)addr)&0xff; } int evenodd_prog(long addr, char data) { return Program1byte((unsigned char*)addr, (unsigned char)data); } /* * return adaptor * 0: success * 1: failed */ int emb_program(long addr, unsigned char data) { if (evenodd_prog(addr,data)) { return 0; } return 1; } /* * 0: success * 1: failed, or the sector is not available. */ static int format_sect(unsigned char sector_num) { long erased_count; long addr; unsigned char data; long i; int errorcnt; int numtimes; int ffs_sector = sector_num; int flash_sector = sector_num + FFS_START_SECTOR; #if DEBUG_FORMAT printf("\r\n\n\nformat sector %d\r\n",flash_sector); //SysLog(LOG_DEBUG, c256DebugBuff, 0); #endif erased_count = get_erase_count(sector_num); #if DEBUG_FORMAT printf("erase count1 %d\r\n", erased_count); //SysLog(LOG_DEBUG, c256DebugBuff, 0); #endif if ((erased_count & 0xFFFFFF) == 0xDEADFF) { return -1; } // increment erase count if first starting erase count = 0xFFFFFF if ((erased_count & 0xFFFFFF) == 0xFFFFFF || (erased_count & 0xFFFFFF) == 0xF000FF) { erased_count = 1; } else { erased_count++; } #if DEBUG_FORMAT printf("erase count2 %d\r\n", erased_count); //SysLog(LOG_DEBUG, c256DebugBuff, 0); #endif // if erase count greater than 30,000 then mark the sector as dead if (erased_count > MAXERASE) { erased_count = 0xDEADFF; sectorerased[ffs_sector] = 0; return -2; } else { // erase sector in flash errorcnt = 0; numtimes = 0; while(numtimes < 3) { if(atfSectorErase(flash_sector)) { break; } numtimes++; } sectorerased[ffs_sector] = 1; //mark the sector available } #if DEBUG_FORMAT printf("numtimes = %d\r\n",numtimes); #endif //do sector status verified if (numtimes < 3) { do{ if(isBlankBlock(flash_sector)) { break; } else { if(atfSectorErase(flash_sector)) { break; } } } while (numtimes++ < 3); } else { errorcnt = 1; } #if DEBUG_FORMAT printf("errorcnt3 = %d\r\n",errorcnt); #endif //one byte failed, the sector won't be use anyway. //It could be changed in future. if (errorcnt) { erased_count = 0xDEADFF; sectorerased[ffs_sector] = 0; } #if DEBUG_FORMAT printf("erased_count = %d\r\n",erased_count); #endif //printf("sector addr:%06x \r\n",addr&0x00ffffff); //--add by bryan // put erase count errorcnt = 0; addr = sectortoaddress(ffs_sector); #if DEBUG_FORMAT printf("addr = 0X%x\r\n",addr); #endif data = ((erased_count & 0x00ff0000) >> 16) & 0xFF; #if DEBUG_FORMAT printf("data = 0X%x\r\n",data); #endif if (emb_program(addr,data)) errorcnt++; #if DEBUG_FORMAT printf("errorcnt4 = %d \r\n",errorcnt); #endif data = ((erased_count & 0x0000ff00) >> 8) & 0xFF; if (emb_program(addr+1,data)) errorcnt++; #if DEBUG_FORMAT printf("errorcnt5 = %d \r\n",errorcnt); #endif data = ((erased_count & 0x000000ff)) & 0xFF; if (emb_program(addr+2,data)) errorcnt++; #if DEBUG_FORMAT printf(" errorcnt6 = %d \r\n",errorcnt); #endif if (errorcnt) //if have any error in just access,wil be return return -3; // put packet length 0x100=256 if (emb_program(addr+3,PACKETLENGTH / PACKETLENGTH)) errorcnt++; #if DEBUG_FORMAT printf("errorcnt7 = %d \r\n",errorcnt); #endif if (emb_program(addr+4,PACKETLENGTH % PACKETLENGTH)) errorcnt++; #if DEBUG_FORMAT printf("errorcnt8 = %d \r\n",errorcnt); #endif if (emb_program(addr+5,0xFF)) errorcnt++; #if DEBUG_FORMAT printf("errorcnt9 = %d \r\n",errorcnt); #endif //so the first 6 byte is written //next will mark packet info--add by bryan addr += INFOLENGTH; // get past all sector info // //printf("packet addr:%06x \r\n",addr&0x00ffffff); //--add by bryan i = 1; while (i <= 248) { if (emb_program(addr,ffs_sector)) errorcnt++; if (emb_program(addr+1,i)) errorcnt++; addr += PACKETLENGTH; i++; } #if DEBUG_FORMAT printf("set all links %d\r\n",ffs_sector); #endif if (errorcnt) { #if DEBUG_FORMAT printf("mark sector %d bad\r\n",ffs_sector); #endif atfSectorErase(flash_sector); addr = sectortoaddress(ffs_sector); erased_count = 0xDEADFF; sectorerased[sector_num] = 0; data = ((erased_count & 0x00ff0000) >> 16) & 0xFF; emb_program(addr,data); data = ((erased_count & 0x0000ff00) >> 8) & 0xFF; emb_program(addr+1,data); data = ((erased_count & 0x000000ff)) & 0xFF; emb_program(addr+2,data); return -4; } else { return OK; } } static long get_erase_count(int sector_num) { long addr; long ret; long stuff; addr = sectortoaddress(sector_num); #ifndef read_flash_long stuff = read_flash(addr++) & 0xFF; stuff = (stuff << 16) & 0x00FF0000; ret = stuff; stuff = read_flash(addr++) & 0xFF; stuff = (stuff << 8) & 0x0000FF00; ret |= stuff; stuff = read_flash(addr) & 0xFF; ret |= stuff; #else stuff = read_flash_long(addr); ret = (stuff >> 8) & 0x00ffffff; #endif return ret; } static void kill_sect(unsigned char sector_num) { long addr; addr = sectortoaddress(sector_num); emb_program(addr,0xDE); emb_program(addr+1,0xAD); emb_program(addr+2,0xFF); } #ifndef sectortoaddress long sectortoaddress(int sector) { return kSector2Addr(sector+ FFS_START_SECTOR ); //++ FFS_START_SECTOR fixed by minye_li } #endif /* * Write the data to flash * retun 1: success always */ static int write_data(int filed) { long addr; long addr1; int i; int dataptr; dataptr = 0; // get the address of the new data packet addr = sectortoaddress(fileds[filed].sector); addr1 = (INFOLENGTH + ((long)(fileds[filed].packet-1) * PACKETLENGTH)); addr = addr + addr1; // skip past the packet number and link field addr += 4; // here we do the actual writing of the data. // if we have more data than a packet can handle use the // payload value to write else use the length for a // partial packet. emb_program(addr, 0); emb_program(addr+1, PAYLOAD); addr += 2; for (i=0; i NUMPACKETS) //== changed to > by minye_li { sprintf(c256DebugBuff, "find_packet: ERROR - Couldn't find file in sector %s\r\n",filename); SysLog(LOG_EMERG, c256DebugBuff, 0); while (1) ; } return packet; } /* * return sector * MAXSECTORS means did not find the file */ static int find_file(char *filename) { int sector; int found; long addr; int packet; int data; char tmpfile[INFOENTRY+1]; int i; int cacheentry; int done; int smallest; int entry; int numincache; sector = 0; found = 0; i = 0; numincache = 0; cacheentry = 0; //added by minye_li while (i < MAXCACHE && !found) { if (cachename[i][0]) numincache++; if (!strcmp(filename,cachename[i])) { found = 1; sector = cachesector[i]; if (cacheuse[i] < 255) { cacheuse[i]++; } } else { i++; } } // if didn't find the name in the cache go find an empty entry // in the cache if (!found) { #if DEBUG_TEST sprintf(c256DebugBuff, "find_file: Didn't find file %s in the cache\r\n",filename); SysLog(LOG_DEBUG, c256DebugBuff, 0); #endif cacheentry = 0; done = 0; while (cacheentry < MAXCACHE && !done) { if (!cacheuse[cacheentry]) { done = 1; } else { cacheentry++; } } } // if didn't find an empty entry in the cache take the least used if (cacheentry == MAXCACHE && !found) { cacheentry = 0; smallest = 255; entry = 0; while (cacheentry < MAXCACHE) { entry = cacheuse[cacheentry] < smallest ? cacheentry : entry; smallest = cacheuse[cacheentry] < smallest ? cacheuse[cacheentry] : smallest; cacheentry++; } } else { entry = cacheentry; } //printf("Not in cache!\r\n"); while (sector < MAXSECTORS && !found) { packet = 1; while (packet <= NUMPACKETS && !found) //= added by minye_li { addr = sectortoaddress(sector) + ((long)packet * INFOENTRY); data = read_flash(addr); if (data == 0xFF || data == USEDPACKET || data == 0) // data==0 added by minye_li { addr += INFOENTRY; packet++; } else { for (i=0; i NUMPACKETS) { another_packet = 0; } else { packet = nextpacket; tsector = read_flash(addr+2); } } } } /* * get the type of package number in one sector * retchar: RETFREE, RETDELETED,RETUSED * sector: sector id * return number of packet */ static int number_of_packets(int retchar,int sector) { int free,deleted,used; int value; int i; long addr; addr = get_erase_count(sector); if ((addr & 0xFFFFFF) == 0xDEADFF || (addr & 0xFFFFFF) > MAXERASE) { return 0; } free = deleted = used = 0; for (i=1; i<= NUMPACKETS; i++) //= changed by minye_li { addr = (sectortoaddress(sector)) + (i * INFOENTRY); value = read_flash(addr); switch (value) { case 0xFF: free++; break; case 0: deleted++; break; default: used++; break; } } switch (retchar) { case RETFREE: return free; case RETDELETED: return deleted; case RETUSED: return used; } return 0; //added by minye_li } static int m_consolidate(void) { int i,j; int sector; int found; unsigned int sectordatalength[MAXSECTORS]; int sectornum[MAXSECTORS]; int copytosector; long temp; long smallest; long sectorlength; int numconsolidated; int nextdot; int numsectors; unsigned char* pDst; unsigned char* pSrc; unsigned char* p; int offset, copied; copytosector = 0; // stop warning from compiler nextdot = 0; run_gc_time++; #if DEBUG_CONSOL sprintf(c256DebugBuff, "Consolidate sector with least amount of data\r\n"); SysLog(LOG_DEBUG, c256DebugBuff, 0); #endif i = 0; for (sector=0; sector sectordatalength[sectornum[j+1]]) { found = sectornum[j]; sectornum[j] = sectornum[j+1]; sectornum[j+1] = found; } } } numsectors = i; #if DEBUG_CONSOL for (j=0; j sectordatalength[sectornum[j+1]]) { found = sectornum[j]; sectornum[j] = sectornum[j+1]; sectornum[j+1] = found; } } } numsectors = i; leastdatasector = sectornum[0]; // --add by bryan #if DEBUG_GC for (j=0; jbefore = 0; pheadswapcache = pcurswapcache; pbeforeswapcache = pcurswapcache; swap_packets_addr_map[0] = (long)pcurswapcache; numofswapcache = 1; numpacketsinleast = number_of_packets(RETUSED,leastdatasector); for(j=1; j before = (long)pbeforeswapcache; pbeforeswapcache->next = (long)pcurswapcache; pbeforeswapcache = pcurswapcache; swap_packets_addr_map[j] = (long)pcurswapcache; numofswapcache++; } pendswapcache = pcurswapcache; pSrc=(unsigned char*)sectortoaddress(leastdatasector); pcurswapcache = pheadswapcache; copied=0; offset=0; total_files_in_sector = 0; /* * first step copy all valid content from src to dest */ for(i=1;i<=NUMPACKETS;i++) { offset=i*INFOENTRY; p=pSrc+offset; if(p[0]==0xff) { //free package } else { if((p[0]==0x0)/* && (p[1] == 0x0)*/) { //deleted package } else { //copy info first bcopy((char*)pcurswapcache->name, (char*)p, INFOENTRY); if(p[0] != 0xaa) total_files_in_sector++;//remember files in current sector //copy data second offset=INFOLENGTH+(i-1)*PACKETLENGTH; bcopy((char*)pcurswapcache->data, (char*)(pSrc+offset),PACKETLENGTH); //get packet data length #ifndef read_flash_long addr = (long)(pSrc+offset); stuff = read_flash(addr+4) & 0xFF; stuff = (stuff << 8) & 0x0000FF00; ret = stuff; stuff = read_flash(addr+5) & 0xFF; ret |= stuff; #else stuff = read_flash_long(addr+4); ret = stuff & 0x0000ffff; #endif pcurswapcache->length = ret; //save current packet ID; pcurswapcache->packet=i; //get packet next packet ID; #ifndef read_flash_long ret = read_flash(addr+3) & 0xFF; #else stuff = read_flash_long(addr); ret = stuff & 0x000000ff; #endif pcurswapcache->nextpacket = ret; //point to next unit pcurswapcache = (SWAP_CACHE*)pcurswapcache->next; copied++; } } } if(copied != numpacketsinleast){//copy data error return -1; } #if DEBUG_GC sprintf(c256DebugBuff, "consolidate: copied=%d, length=%d, files=%d\r\n",copied, copied*250,total_files_in_sector); SysLog(LOG_DEBUG, c256DebugBuff, 0); #endif i=get_erase_count(leastdatasector); #if DEBUG_GC sprintf(c256DebugBuff, "consolidate: erased times before format %d\r\n",i); SysLog(LOG_DEBUG, c256DebugBuff, 0); #endif /* * erase the sector */ format_sect(leastdatasector); i=get_erase_count(leastdatasector); #if DEBUG_GC sprintf(c256DebugBuff, "consolidate: erased times after format %d\r\n",i); SysLog(LOG_DEBUG, c256DebugBuff, 0); #endif /* * copy the valid content back to the sector * So the sector is clean */ pDst = pSrc; p=pDst+INFOLENGTH; pSectorInfo = pDst+8; found=0; cur_packet_ID = 1; writed_files=0; swap_cache_end=0; #if DEBUG_GC sprintf(c256DebugBuff, "consolidate: param sect addr 0x%x\r\n", pSrc); SysLog(LOG_DEBUG, c256DebugBuff, 0); #endif pcurswapcache = pheadswapcache; while(total_files_in_sector>0) { //search file first swap packet, if((0xaa == pcurswapcache->name[0]) || pcurswapcache->iswrite) { if(!found){ pcurswapcache = (SWAP_CACHE*)pcurswapcache->next; continue; } } found=1; //find it, then Write back file name infor //mark this swap packet is writed pcurswapcache->iswrite = 1; writed_files++; //write back data to packet while(((unsigned char)pcurswapcache->data[2]&0xff) != 0xff){//the next packet also belone this file // if(found){ // len = INFOENTRY; // found=0; // } // else // len = 1; for(i=0;i name[i]); if(temp!=1) { sprintf(c256DebugBuff, "consolidate: Write 1 byte %d failed\r\n", i); SysLog(LOG_EMERG, c256DebugBuff, 0); return -1; } } for(i=4;i data[i]); if(temp!=1) { sprintf(c256DebugBuff, "consolidate: Write 1 byte %d failed\r\n", i); SysLog(LOG_EMERG, c256DebugBuff, 0); return -1; } } //write back next packet ID Program1byte(p+3,cur_packet_ID+1); //write current sector ID Program1byte(p+2,leastdatasector); p += PACKETLENGTH; pcurswapcache = (SWAP_CACHE*)pcurswapcache->next; if(pcurswapcache == NULL) { swap_cache_end=1; break; } cur_packet_ID++; if(cur_packet_ID>NUMPACKETS) { sprintf(c256DebugBuff, "packet number error\r\n"); SysLog(LOG_EMERG, c256DebugBuff, 0); return -1; } } if(swap_cache_end) { total_files_in_sector--; break; } for(i=0;i name[i]); if(temp!=1) { sprintf(c256DebugBuff, "consolidate: Write 1 byte %d failed\r\n", i); SysLog(LOG_EMERG, c256DebugBuff, 0); return -1; } } for(i=4;i data[i]); if(temp!=1) { sprintf(c256DebugBuff, "consolidate: Write 1 byte %d failed\r\n", i); SysLog(LOG_EMERG, c256DebugBuff, 0); return -1; } } p += PACKETLENGTH; total_files_in_sector--; cur_packet_ID++; if(cur_packet_ID>NUMPACKETS) { sprintf(c256DebugBuff, "packet number error\r\n"); SysLog(LOG_EMERG, c256DebugBuff, 0); return -1; } pcurswapcache = (SWAP_CACHE*)pcurswapcache->next; if(pcurswapcache == NULL) { break; } } #if DEBUG_GC sprintf(c256DebugBuff, "consolidate: after write back sector: %d used = %d!!!\r\n",leastdatasector, number_of_packets(RETUSED,leastdatasector)*250); SysLog(LOG_DEBUG, c256DebugBuff, 0); #endif pcurswapcache = pheadswapcache; while(pcurswapcache != NULL) { pbeforeswapcache = (SWAP_CACHE*)pcurswapcache->next; free(pcurswapcache); pcurswapcache = pbeforeswapcache; } #if DEBUG_GC sprintf(c256DebugBuff, "pDst space was freed!"); SysLog(LOG_DEBUG, c256DebugBuff, 0); #endif // fill filename cache again with current changes fillcache(); return leastdatasector; } static void fillcache(void) { int sector; int found; long addr; int packet; int data; char tmpfile[INFOENTRY+1]; int i; int cacheentry; for (i=0; i NUMPACKETS means unhappy things happen */ static int get_unused_packet_from(int sector) { long addr; long offset; addr = sectortoaddress(sector); offset = INFOENTRY; //scan section info block //0x7d0=2000=6(head)+ ( 8*248=1984) while (read_flash(addr+offset) != 0xFF && offset < 0x7D0) { offset += INFOENTRY; } if (offset == 0x7D0) { return NUMPACKETS+2; } else { return (offset / INFOENTRY); } } static int isReadyBinFileInfo=0; int init_bin_file_info_pool(void) { int id,i; //int p=BIN_FILE_INFO_BEGIN_ADDR; long p; void *tp; int len = BIN_FILE_MAX_NUM * sizeof(BIN_FILE_INFO_INKEYSRAM); #if !ENABLE_LF tp = (void*) malloc(len+4); if(tp==NULL) { sprintf(c256DebugBuff, "no memory for key sram\r\n"); SysLog(LOG_EMERG, c256DebugBuff, 0); return ERR_MEM_MALLOC; } p = (long)tp; KEYSRAM_BASE_ADDRESS = p; BIN_FILE_INFO_BEGIN_ADDR = KEYSRAM_BASE_ADDRESS + BIN_FILE_INFO_BEGIN_OFFSET; BIN_FILE_INFO_END_OFFSET = BIN_FILE_INFO_BEGIN_OFFSET+BIN_FILE_MAX_NUM*sizeof(BIN_FILE_INFO_INKEYSRAM); BIN_FILE_INFO_END_ADDR = KEYSRAM_BASE_ADDRESS + BIN_FILE_INFO_END_OFFSET; BIN_FILE_TOTAL_NUM_ADDR = BIN_FILE_INFO_END_ADDR; #else if(OK != checkKeySRAM((long)BIN_FILE_INFO_BEGIN_OFFSET,(BIN_FILE_MAX_NUM*sizeof(BIN_FILE_INFO_INKEYSRAM))/1024 )){ SysLog(LOG_EMERG, "KEYSRAM ERROR FOR SFFS", 0); return ERR_MEM_CHECK; } p = (long)BIN_FILE_INFO_BEGIN_ADDR; #endif memset((void*)p,0,len); //pbin_file_info = (BIN_FILE_INFO_INKEYSRAM**)BIN_FILE_INFO_BEGIN_ADDR; //memset((void*)pbin_file_info,0,BIN_FILE_MAX_NUM*sizeof(BIN_FILE_INFO_INKEYSRAM)); for(id=0;id id = id; pbin_file_info[id]->name[0] = 0; pbin_file_info[id]->name[1] = 0; pbin_file_info[id]->file_length = 0; pbin_file_info[id]->filled_data_length = 0; p += sizeof(BIN_FILE_INFO_INKEYSRAM); } total_bin_files = 0; *(int*)BIN_FILE_TOTAL_NUM_ADDR = 0; isReadyBinFileInfo = 1; return OK; } int pickup_bin_file_info(void) { int id,i; //int p=BIN_FILE_INFO_BEGIN_ADDR; long p; void *tp; int len = BIN_FILE_MAX_NUM * sizeof(BIN_FILE_INFO_INKEYSRAM); if(isReadyBinFileInfo == 1)//this bin file info already be picked up return OK; #if !ENABLE_LF //this is for EVB test tp = (void*) malloc(len+4); if(tp==NULL) { sprintf(c256DebugBuff, "no memory for key sram\r\n"); SysLog(LOG_EMERG, c256DebugBuff, 0); return ERR_MEM_MALLOC; } p = (long)tp; KEYSRAM_BASE_ADDRESS = p; BIN_FILE_INFO_BEGIN_ADDR = KEYSRAM_BASE_ADDRESS + BIN_FILE_INFO_BEGIN_OFFSET; BIN_FILE_INFO_END_OFFSET = BIN_FILE_INFO_BEGIN_OFFSET+BIN_FILE_MAX_NUM*sizeof(BIN_FILE_INFO_INKEYSRAM); BIN_FILE_INFO_END_ADDR = KEYSRAM_BASE_ADDRESS + BIN_FILE_INFO_END_OFFSET; BIN_FILE_TOTAL_NUM_ADDR = BIN_FILE_INFO_END_ADDR; #else p = (long)BIN_FILE_INFO_BEGIN_ADDR; #endif //pbin_file_info = (BIN_FILE_INFO_INKEYSRAM**)BIN_FILE_INFO_BEGIN_ADDR; //memset((void*)pbin_file_info,0,BIN_FILE_MAX_NUM*sizeof(BIN_FILE_INFO_INKEYSRAM)); for(id=0;id 250 one block } if (length >= SECTORLENGTH) { //reserve space at the create time no more than one sector length return ERR_SFFS_LENGTH; } done = 1; for (i=0; i file_length = length; pbin_file_info[id]->filled_data_length = 0; wrapped = (workingsector-1) & (MAXSECTORS-1); //tips!!! addr = (((long)number_of_packets(RETFREE,workingsector) & 0xFF) * ((long)PAYLOAD & 0xFF)) & 0xFFFF; while (addr < length && (workingsector != wrapped)) { //Search for the sector whose free space is enough workingsector++; workingsector %= MAXSECTORS; addr = (((long)number_of_packets(RETFREE,workingsector) & 0xFF) * ((long)PAYLOAD & 0xFF)) & 0xFFFF; } if ((workingsector == wrapped) && (addr < length)) { #if DEBUG_CONSOL sprintf(c256DebugBuff, "consolidate: befor consolidate workingsector=%d,\r\n",workingsector); SysLog(LOG_DEBUG, c256DebugBuff, 0); sprintf(c256DebugBuff, "consolidate: befor consolidate free space=%d,\r\n",get_avaible_space()); SysLog(LOG_DEBUG, c256DebugBuff, 0); #endif workingsector=my_consolidate(); if(workingsector == -1) return -1; //my_consolidate(); //I won't update the working setor. #if DEBUG_CONSOL sprintf(c256DebugBuff, "consolidate: after consolidate free space=%d,\r\n",get_avaible_space()); SysLog(LOG_DEBUG, c256DebugBuff, 0); sprintf(c256DebugBuff, "consolidate: after consolidate workingsector=%d,\r\n",workingsector); SysLog(LOG_DEBUG, c256DebugBuff, 0); #endif wrapped = (workingsector-1) & (MAXSECTORS-1); addr = (((long)number_of_packets(RETFREE,workingsector) & 0xFF) * ((long)PAYLOAD & 0xFF)) & 0xFFFF; while (addr < length && (workingsector != wrapped)) { workingsector++; workingsector %= MAXSECTORS; addr = (((long)number_of_packets(RETFREE,workingsector) & 0xFF) * ((long)PAYLOAD & 0xFF)) & 0xFFFF; } } else { // get number of erased sectors sector = 0; for (i=0; i NUMPACKETS) { sprintf(c256DebugBuff, "Illegal packet\r\n"); SysLog(LOG_EMERG, c256DebugBuff, 0); system_error = ILLEGALPACKET; return ERR_SFFS_ILLEBAL_PACKET; } addr = sectortoaddress(workingsector) + (packet * INFOENTRY); // write file name for (i=0; i PAYLOAD) length -= PAYLOAD; else length = 0; addr = sectortoaddress(workingsector); addr1 = (long)(INFOLENGTH + ((long)(packet-1) * PACKETLENGTH)); addr = addr + addr1; oldpacket = packet; while (length) { if (length > PAYLOAD) { // link old packet in packet = get_unused_packet_from(workingsector); emb_program(addr+2,workingsector & 0xFF); emb_program(addr+3,packet & 0xFF); // set new as used if (packet > NUMPACKETS) { sprintf(c256DebugBuff, "ERROR: no unused packets in sector\r\n"); SysLog(LOG_EMERG, c256DebugBuff, 0); system_error = ILLEGALPACKET; return ERR_SFFS_ILLEBAL_PACKET; } addr = sectortoaddress(workingsector) + (packet * INFOENTRY); emb_program(addr, USEDPACKET); // marked as used emb_program(addr+1, 0xFF); // marked as used length -= PAYLOAD; // set up for next run addr = sectortoaddress(workingsector); addr1 = (long)(INFOLENGTH + ((long)(packet-1) * PACKETLENGTH)); addr = addr + addr1; oldpacket = packet; } else { // link old packet in packet = get_unused_packet_from(workingsector); emb_program(addr+2,workingsector & 0xFF); emb_program(addr+3,packet & 0xFF); packet = get_unused_packet_from(workingsector); if (packet > NUMPACKETS) { sprintf(c256DebugBuff, "ERROR: no unused packets in sector\r\n"); SysLog(LOG_EMERG, c256DebugBuff, 0); system_error = ILLEGALPACKET; return ERR_SFFS_ILLEBAL_PACKET; } addr = sectortoaddress(workingsector) + (packet * INFOENTRY); emb_program(addr, USEDPACKET); // marked as used emb_program(addr+1, 0xFF); // marked as used length = 0; } } break; case 'f': // this deletes an existing file packet = find_file(kname); if (packet != MAXSECTORS && delbfrwrite) { del_file(kname); } id = insert_bin_file_info(kname); if(id == -1) return -1; pbin_file_info[id]->file_length = length; pbin_file_info[id]->filled_data_length = 0; wrapped = (workingsector-1) & (MAXSECTORS-1); //tips!!! addr = (((long)number_of_packets(RETFREE,workingsector) & 0xFF) * ((long)PAYLOAD & 0xFF)) & 0xFFFF; while (addr < length && (workingsector != wrapped)) { //Search for the sector whose free space is enough workingsector++; workingsector %= MAXSECTORS; addr = (((long)number_of_packets(RETFREE,workingsector) & 0xFF) * ((long)PAYLOAD & 0xFF)) & 0xFFFF; } if ((workingsector == wrapped) && (addr < length)) { #if DEBUG_CONSOL sprintf(c256DebugBuff, "consolidate: befor consolidate workingsector=%d,\r\n",workingsector); SysLog(LOG_DEBUG, c256DebugBuff, 0); sprintf(c256DebugBuff, "consolidate: befor consolidate free space=%d,\r\n",get_avaible_space()); SysLog(LOG_DEBUG, c256DebugBuff, 0); #endif workingsector=my_consolidate(); if(workingsector == -1) return -1; //my_consolidate(); //I won't update the working setor. #if DEBUG_CONSOL sprintf(c256DebugBuff, "consolidate: after consolidate free space=%d,\r\n",get_avaible_space()); SysLog(LOG_DEBUG, c256DebugBuff, 0); sprintf(c256DebugBuff, "consolidate: after consolidate workingsector=%d,\r\n",workingsector); SysLog(LOG_DEBUG, c256DebugBuff, 0); #endif wrapped = (workingsector-1) & (MAXSECTORS-1); addr = (((long)number_of_packets(RETFREE,workingsector) & 0xFF) * ((long)PAYLOAD & 0xFF)) & 0xFFFF; while (addr < length && (workingsector != wrapped)) { workingsector++; workingsector %= MAXSECTORS; addr = (((long)number_of_packets(RETFREE,workingsector) & 0xFF) * ((long)PAYLOAD & 0xFF)) & 0xFFFF; } } else { // get number of erased sectors sector = 0; for (i=0; i NUMPACKETS) { sprintf(c256DebugBuff, "Illegal packet\r\n"); SysLog(LOG_EMERG, c256DebugBuff, 0); system_error = ERR_SFFS_ILLEBAL_PACKET; return ERR_SFFS_ILLEBAL_PACKET; } addr = sectortoaddress(workingsector) + (packet * INFOENTRY); // write file name for (i=0; i PAYLOAD) length -= PAYLOAD; else length = 0; addr = sectortoaddress(workingsector); addr1 = (long)(INFOLENGTH + ((long)(packet-1) * PACKETLENGTH)); addr = addr + addr1; oldpacket = packet; while (length) { if (length > PAYLOAD) { // link old packet in packet = get_unused_packet_from(workingsector); emb_program(addr+2,workingsector & 0xFF); emb_program(addr+3,packet & 0xFF); // set new as used if (packet > NUMPACKETS) { sprintf(c256DebugBuff, "ERROR: no unused packets in sector\r\n"); SysLog(LOG_EMERG, c256DebugBuff, 0); system_error = ILLEGALPACKET; return ERR_SFFS_ILLEBAL_PACKET; } addr = sectortoaddress(workingsector) + (packet * INFOENTRY); emb_program(addr, USEDPACKET); // marked as used emb_program(addr+1, 0xFF); // marked as used length -= PAYLOAD; // set up for next run addr = sectortoaddress(workingsector); addr1 = (long)(INFOLENGTH + ((long)(packet-1) * PACKETLENGTH)); addr = addr + addr1; oldpacket = packet; } else { // link old packet in packet = get_unused_packet_from(workingsector); emb_program(addr+2,workingsector & 0xFF); emb_program(addr+3,packet & 0xFF); packet = get_unused_packet_from(workingsector); if (packet > NUMPACKETS) { sprintf(c256DebugBuff, "ERROR: no unused packets in sector\r\n"); SysLog(LOG_EMERG, c256DebugBuff, 0); system_error = ILLEGALPACKET; return ERR_SFFS_ILLEBAL_PACKET; } addr = sectortoaddress(workingsector) + (packet * INFOENTRY); emb_program(addr, USEDPACKET); // marked as used emb_program(addr+1, 0xFF); // marked as used length = 0; } } break; case 'a': // this deletes an existing file packet = find_file(kname); if (packet != MAXSECTORS && delbfrwrite) { //delete_file(kname,packet); del_file(kname); } #if DEBUG_CONSOL sprintf(c256DebugBuff, "Create append file length = %d\r\n",length); SysLog(LOG_DEBUG, c256DebugBuff, 0); #endif wrapped = (workingsector-1) & (MAXSECTORS-1); //tips!!! addr = (((long)number_of_packets(RETFREE,workingsector) & 0xFF) * ((long)PAYLOAD & 0xFF)) & 0xFFFF; while (addr < length && (workingsector != wrapped)) { //Search for the sector whose free space is enough workingsector++; workingsector %= MAXSECTORS; addr = (((long)number_of_packets(RETFREE,workingsector) & 0xFF) * ((long)PAYLOAD & 0xFF)) & 0xFFFF; } if ((workingsector == wrapped) && (addr < length)) { #if DEBUG_CONSOL sprintf(c256DebugBuff, "consolidate: befor consolidate workingsector=%d,\r\n",workingsector); SysLog(LOG_DEBUG, c256DebugBuff, 0); #endif workingsector=my_consolidate(); if(workingsector == -1) return -1; //my_consolidate(); //I won't update the working setor. #if DEBUG_CONSOL sprintf(c256DebugBuff, "consolidate: after consolidate workingsector=%d,\r\n",workingsector); SysLog(LOG_DEBUG, c256DebugBuff, 0); #endif wrapped = (workingsector-1) & (MAXSECTORS-1); addr = (((long)number_of_packets(RETFREE,workingsector) & 0xFF) * ((long)PAYLOAD & 0xFF)) & 0xFFFF; while (addr < length && (workingsector != wrapped)) { workingsector++; workingsector %= MAXSECTORS; addr = (((long)number_of_packets(RETFREE,workingsector) & 0xFF) * ((long)PAYLOAD & 0xFF)) & 0xFFFF; } } else { // get number of erased sectors sector = 0; for (i=0; i NUMPACKETS) { sprintf(c256DebugBuff, "Illegal packet\r\n"); SysLog(LOG_EMERG, c256DebugBuff, 0); system_error = ERR_SFFS_ILLEBAL_PACKET; return ERR_SFFS_ILLEBAL_PACKET; } addr = sectortoaddress(workingsector) + (packet * INFOENTRY); // write file name for (i=0; i PAYLOAD) length -= PAYLOAD; else length = 0; addr = sectortoaddress(workingsector); addr1 = (long)(INFOLENGTH + ((long)(packet-1) * PACKETLENGTH)); addr = addr + addr1; oldpacket = packet; while (length) { if (length > PAYLOAD) { // link old packet in packet = get_unused_packet_from(workingsector); emb_program(addr+2,workingsector & 0xFF); emb_program(addr+3,packet & 0xFF); // set new as used if (packet > NUMPACKETS) { sprintf(c256DebugBuff, "ERROR: no unused packets in sector\r\n"); SysLog(LOG_EMERG, c256DebugBuff, 0); system_error = ILLEGALPACKET; return ERR_SFFS_ILLEBAL_PACKET; } addr = sectortoaddress(workingsector) + (packet * INFOENTRY); emb_program(addr, USEDPACKET); // marked as used emb_program(addr+1, 0xFF); // marked as used length -= PAYLOAD; // set up for next run addr = sectortoaddress(workingsector); addr1 = (long)(INFOLENGTH + ((long)(packet-1) * PACKETLENGTH)); addr = addr + addr1; oldpacket = packet; } else { // link old packet in packet = get_unused_packet_from(workingsector); emb_program(addr+2,workingsector & 0xFF); emb_program(addr+3,packet & 0xFF); packet = get_unused_packet_from(workingsector); if (packet > NUMPACKETS) { sprintf(c256DebugBuff, "ERROR: no unused packets in sector\r\n"); SysLog(LOG_EMERG, c256DebugBuff, 0); system_error = ILLEGALPACKET; return ERR_SFFS_ILLEBAL_PACKET; } addr = sectortoaddress(workingsector) + (packet * INFOENTRY); emb_program(addr, USEDPACKET); // marked as used emb_program(addr+1, 0xFF); // marked as used length = 0; } } break; default: return ERR_PARAM; } #if DEBUG_CREATE printf("Create %s success!\r\n",filename); #endif return OK; } int createfile4java(char *filename, int offset, char attribute,unsigned int length) { return create_file(filename+offset, attribute, length); } /* * filename: valid file name * string: C string, must have \0 * This API is not good, it should be changed to * char* filename, char* pBuff, int bufflength * It could only append the space which had already reserved for the file * return how many bytes is written. * -1 means failed */ int append_to_file(char *filename, char *string) { int j; int sector; int packet; long addr; long addr1; int dataptr; unsigned char data; unsigned char olddata; int packetlen; int done; int link; int eof; if(!fdiskReady){ SysLog(LOG_DEBUG, "flash disk not ready!", 0); return -1; } sector = find_file(filename); if (sector == MAXSECTORS) { return -1; } packet = find_packet(filename,sector); addr = sectortoaddress(sector); addr1 = (long)(INFOLENGTH + ((long)(packet-1) * PACKETLENGTH)); addr = addr + addr1; packetlen = PAYLOAD; dataptr = 6; done = 0; data = 0; eof = 0; //locate the end of the file while (!done && !eof) { olddata = data; data = read_flash(addr+(long)dataptr); if (data == 0xFF) { done = 1; } else { packetlen--; dataptr++; } if (!packetlen) { packetlen = PAYLOAD; dataptr = 6; link = read_flash(addr+2) * PACKETLENGTH + read_flash(addr+3); if (link == 0xFFFF) { eof = 1; } else { packet = link & 0xFF; addr = sectortoaddress(sector); addr1 = (long)(INFOLENGTH + ((long)(packet-1) * PACKETLENGTH)); addr = addr + addr1; } } } //I am at the end of the file j = 0; if ((dataptr & 1) && (string[j]) && !eof) { emb_program(addr+(long)dataptr-1,olddata); emb_program(addr+(long)dataptr++, string[j]); packetlen--; j++; } //we are at the even address now while (string[j] && !eof) { if (packetlen) { emb_program(addr+(long)dataptr++, string[j]); if (string[j+1] == 0) { if (!((addr+((long)dataptr-1)) & 1)) { emb_program(addr+(long)dataptr,0xFF); } } j++; packetlen--; } else { packetlen = PAYLOAD; dataptr = 6; link = read_flash(addr+2) * PACKETLENGTH + read_flash(addr+3); if (link == 0xFFFF) { eof = 1; } else { packet = link & 0xFF; addr = sectortoaddress(sector); addr1 = (long)(INFOLENGTH + ((long)(packet-1) * PACKETLENGTH)); addr = addr + addr1; } } } if (string[j]) { system_error = 1; } return j; } int appendfile4java(char* filename, int nameoffset, char* string, int stringoffset, int datalength) { return append_to_file(filename+nameoffset, string+stringoffset); } /* * return -1: not exists * 1: exists */ int file_exists(char *filename) { if (find_file(filename) == MAXSECTORS) { return -1; } return 1; } int file_exists4java(char *filename, int offset) { return file_exists(filename+offset); } /* * Have not been test yet */ int read_app_file(char *filename, char *data, int start, int length) { long addr; long addr1; int link; int done; int tsector; int dataptr; int packetlen; int packetptr; int packet; if(!fdiskReady){ SysLog(LOG_DEBUG, "flash disk not ready!", 0); return -1; } tsector = find_file(filename); if (tsector == MAXSECTORS) { return -1; } packet = find_packet(filename,tsector); if (packet > NUMPACKETS) { return -1; } addr = sectortoaddress(tsector); addr1 = (long)(INFOLENGTH + ((long)(packet-1) * PACKETLENGTH)); addr = addr + addr1; done = 0; dataptr = 0; packetptr = 6; packetlen = PAYLOAD; while (dataptr < start && !done) { link = read_flash(addr+packetptr); if (link == 0xFF) { done = 1; } else { packetlen--; dataptr++; packetptr++; } if (!packetlen) { packetlen = PAYLOAD; packetptr = 6; link = read_flash(addr+2) * PACKETLENGTH + read_flash(addr+3); if (link == 0xFFFF) { done = 1; } else { packet = link; addr = sectortoaddress(tsector); addr1 = (long)(INFOLENGTH + ((long)(packet-1) * PACKETLENGTH)); addr = addr + addr1; } } } dataptr = 0; packetptr = 6; while (dataptr < length && !done) { link = read_flash(addr+(long)packetptr); if ((link & 0xFF) == 0xFF) { done = 1; } else { data[dataptr++] = link; packetptr++; packetlen--; } if (!packetlen) { packetlen = PAYLOAD; packetptr = 6; link = read_flash(addr+2) * PACKETLENGTH + read_flash(addr+3); if (link == 0xFFFF) { done = 1; } else { packet = link; addr = sectortoaddress(tsector); addr1 = (long)(INFOLENGTH + ((long)(packet-1) * PACKETLENGTH)); addr = addr + addr1; } } } return dataptr; } /* * get currnet free space */ int get_avaible_space(void) { int i; int space; // if(!fdiskReady){ // SysLog(LOG_DEBUG, "flash disk not ready!", 0); // return -1; // } space=0; for(i=0;i name[0]=0; pbin_file_info[id]->name[1]=0; pbin_file_info[id]->file_length = 0; pbin_file_info[id]->filled_data_length = 0; total_bin_files--; *(int*)BIN_FILE_TOTAL_NUM_ADDR = total_bin_files; } /** * 1: success * -1: failed */ int del_file(char *filename) { int i; if(!fdiskReady){ SysLog(LOG_DEBUG, "flash disk not ready!", 0); return -1; } i = find_file(filename); if (i == MAXSECTORS) { return -1; // return not found } else { int id = get_bin_file_info_id(filename); delete_file(filename,i); if(-1 != id){ delete_bin_file_info(id); } } #if DEBUG_CONSOL printf("del_file: %s be deleted success\r\n",filename); #endif return 1; } static int get_bin_file_info_id(char *binfilename) { int id; // printf("binfilename is %s,length = %d\r\n",binfilename,strlen(binfilename)); for(id=0;id name is %s,length = %d\r\n",pbin_file_info[id]->name,strlen(pbin_file_info[id]->name)); if(!strncmp(pbin_file_info[id]->name,binfilename,INFOENTRY)){ return id; } } return -1; } int get_freeID_bin_file_info(void) { int id; for(id=0;id name[0] == 0){ return id; } } return -1; } static int insert_bin_file_info(char *binfilename){ int index,id; id = get_bin_file_info_id(binfilename); if(-1 == id){//this file already exist index = get_freeID_bin_file_info(); if(-1 == index){ sprintf(c256DebugBuff, "insert_bin_file_info: not get bin file info free id!\r\n"); SysLog(LOG_EMERG, c256DebugBuff, 0); return -1; } total_bin_files++; *(int*)BIN_FILE_TOTAL_NUM_ADDR = total_bin_files; strncpy(pbin_file_info[index]->name,binfilename,INFOENTRY); pbin_file_info[index]->file_length = 0; pbin_file_info[index]->filled_data_length = 0; return index; }else{ //pbin_file_info[id]->file_length = 0; return id; } } /** * This will call flash file GC internally. * return int: which section has been cleaned up */ int cleanup_sector(void) { return my_consolidate(); } /* * filename: file name No more than 8 character. * attribute: r, w, not support rw * return: -1 failed * >=0 file handler */ int kopen(char *filename,char *attribute) { int i; int found; int openfileds; long addr; int id; // cursector = FindClearedSector(); if(!fdiskReady){ check_fdisk(); if(!fdiskReady){ SysLog(LOG_DEBUG, "flash disk must be format!", 0); return ERR_SFFS_NOT_READY; } } openfileds = 0; i = 0; found = 0; #if 1 // while (i < NUMOPENFILES && !found) { if (fileds[i].busy == 0) { openfileds = i; found++; } i++; } if (!found) { return ERR_SFFS_MORE_OPENED_FILES; } #endif // workingsector = cursector; if (!strcmp("w",attribute)) { i = find_file(filename); id = get_bin_file_info_id(filename);//get the bin file id in bin file info if(id != -1){//got a bin file id fileds[openfileds].bin_file = 1; fileds[openfileds].bin_file_info_id = id; fileds[openfileds].bin_file_dataptr = 0; }else{//can not got bin file id sprintf(c256DebugBuff,"kopen:get bin file info id failed!id=%d",id); SysLog(LOG_DEBUG, c256DebugBuff, 0); return ERR_SFFS_GET_ID; } if (i != MAXSECTORS) { fileds[openfileds].sector = i; fileds[openfileds].packet = find_packet(filename,i); fileds[openfileds].startsector = i; fileds[openfileds].startpacket = fileds[openfileds].packet; addr = sectortoaddress(fileds[openfileds].sector) + i * INFOENTRY; fileds[openfileds].busy = 1; fileds[openfileds].length = 0; fileds[openfileds].oldsector = 0; fileds[openfileds].oldpacket = 0; fileds[openfileds].firsttime = 1; fileds[openfileds].write = 1; fileds[openfileds].packetdataptr = 6; fileds[openfileds].totallength = 0; fileds[openfileds].append = 1; strcpy(fileds[openfileds].name,filename); kseek(openfileds,0,SEEK_END);//move the file access point to file end for file write } } else{ id = get_bin_file_info_id(filename); if(-1 != id){ fileds[openfileds].bin_file = 1; fileds[openfileds].bin_file_info_id = id; } i = find_file(filename); if (i != MAXSECTORS) { fileds[openfileds].busy = 1; fileds[openfileds].sector = i; fileds[openfileds].packet = find_packet(filename,i); fileds[openfileds].startsector = i; fileds[openfileds].startpacket = fileds[openfileds].packet; fileds[openfileds].write = 0; addr = sectortoaddress(fileds[openfileds].sector) + (INFOLENGTH + ((long)(fileds[openfileds].packet-1) * PACKETLENGTH)); fileds[openfileds].length = read_flash(addr+4) * 256 + read_flash(addr+5); fileds[openfileds].packetdataptr = 6; fileds[openfileds].totallength = 0; fileds[openfileds].append = 0; fileds[openfileds].bin_file_dataptr = 0; strncpy(fileds[openfileds].name,filename,8); //if (debug) { //printf("Open\r\n"); //printf("fileds = %d\r\n",openfileds); //printf("sector = %d\r\n",fileds[openfileds].sector); //printf("packet = %d\r\n",fileds[openfileds].packet); //printf("length = %d\r\n",fileds[openfileds].length); //} } else{// didn't find file //printf("I did not find file %s\r\n", filename); //added by minye_li return ERR_SFFS_ILLEBAL_SECTOR; } } return openfileds; } int kopen4java(char *filename, int nameOffset, char *attribute) { return kopen(filename+nameOffset, attribute); } /* * Must call kopen with read mode before call kread * return how many byte is read. */ int kread(int filed, unsigned char *data, int length) { long addr,addr1; int j; int link; int done; int tsector; //add by bryan if(!fdiskReady){ SysLog(LOG_DEBUG, "flash disk not ready!", 0); return ERR_SFFS_NOT_READY; } if((filed < 0) || (filed >= NUMOPENFILES)){//the filed is not valuable id return ERR_SFFS_ILLEBAL_FILEHANDLE; } if(!fileds[filed].busy){ SysLog(LOG_DEBUG, "file cannot be opened!", 0); return ERR_SFFS_NOT_OPENED; } // if(fileds[filed].write){ // SysLog(LOG_DEBUG, "open for write, cannot be read!", 0); // return ERR_SFFS_OPERAT_MODE; // } j = 0; done = 0; addr = sectortoaddress(fileds[filed].sector); addr1 = (long)(INFOLENGTH + ((long)(fileds[filed].packet-1) * PACKETLENGTH)); addr = addr + addr1; if (fileds[filed].length == 0xFFFF) { fileds[filed].length = PAYLOAD; fileds[filed].append = 1; } // if (debug) { //printf("length = %d read length = %d append = %d\r\n",fileds[filed].length,length, // fileds[filed].append); // } while (length && !done && fileds[filed].length) { data[j] = read_flash(addr+(long)fileds[filed].packetdataptr++); if (fileds[filed].append) { //if (data[j] == 0xFF) { if(fileds[filed].bin_file){ if (pbin_file_info[fileds[filed].bin_file_info_id]->filled_data_length == fileds[filed].bin_file_dataptr) {//add by bryan done = 1; fileds[filed].length = 0; } else { j++; fileds[filed].length--; length--; if(fileds[filed].bin_file){ fileds[filed].bin_file_dataptr++; if(fileds[filed].bin_file_dataptr > pbin_file_info[fileds[filed].bin_file_info_id]->filled_data_length){ sprintf(c256DebugBuff, "kread:file %s read overflow!\r\n",fileds[filed].name); SysLog(LOG_EMERG, c256DebugBuff, 0); return ERR_SFFS_LENGTH; } } } }else{ if (data[j] == 0xFF){//add by bryan done = 1; fileds[filed].length = 0; } else { j++; fileds[filed].length--; length--; } } } else { fileds[filed].length--; length--; j++; if(fileds[filed].bin_file) fileds[filed].bin_file_dataptr++; if(fileds[filed].bin_file_dataptr > pbin_file_info[fileds[filed].bin_file_info_id]->filled_data_length){ sprintf(c256DebugBuff, "kread:file %s read overflow!\r\n",fileds[filed].name); SysLog(LOG_EMERG, c256DebugBuff, 0); return ERR_SFFS_LENGTH; } } if (fileds[filed].length == 0 && !done) { // need to go to next packet in the file link = read_flash(addr+2) * PACKETLENGTH + read_flash(addr+3); if (link == 0xFFFF) { fileds[filed].length = 0; done = 1; // end of file } else { tsector = (link & 0xFF00) >> 8; if (tsector != fileds[filed].sector) { fileds[filed].oldsector = fileds[filed].sector; fileds[filed].sector = tsector; } link &= 0xFF; fileds[filed].oldpacket = fileds[filed].packet; fileds[filed].packet = link; fileds[filed].packetdataptr = 6; addr = sectortoaddress(fileds[filed].sector); addr1 = (long)(INFOLENGTH + ((long)(fileds[filed].packet-1) * PACKETLENGTH)); addr = addr + addr1; fileds[filed].length = read_flash(addr+4) * 256 + read_flash(addr+5); if (fileds[filed].length == 0xFFFF) { fileds[filed].length = PAYLOAD; fileds[filed].append = 1; } } } } return j; } /* * Must call kopen with read mode before call kread * return how many byte is read. */ int kread4java(int filed, unsigned char *data, int offset, int length) { return kread(filed,data+offset, length); } /** * direct write data to bin flash file area * * @param filed the unique opened file id * @param data the buffer store data will be write to file * @param length the length will be write to file * @param flag true means the data will be write into file, * false means only check the space is enough for the write data * * @return int the writed data length if success. * -1 is the flash memory space can not fill the data */ static long tmpcnt=0; //static int bin_file_writecheck_just_length=0; int kwrite2bin(int filed, unsigned char *data, int length, unsigned char flag) { int count; long addr; long addr1; int dataptr; int reCreate=0; int i,j; int realDataLength = pbin_file_info[fileds[filed].bin_file_info_id]->filled_data_length; int realFileLength = pbin_file_info[fileds[filed].bin_file_info_id]->file_length; boolean isModify=FALSE; //printf("enter kwrite2bin,%d\r\n", OSTimeGetInMillisec ()); if(!fdiskReady) { SysLog(LOG_DEBUG, "flash disk not ready!", 0); return ERR_SFFS_NOT_READY; } if((filed < 0) || (filed >= NUMOPENFILES))//the filed is not valuable id { return ERR_SFFS_ILLEBAL_FILEHANDLE; } j = 0; if(!fileds[filed].busy) { SysLog(LOG_DEBUG, "kwrite2bin:file cannot be opened!", 0); return ERR_SFFS_NOT_OPENED; } if(!fileds[filed].bin_file) { SysLog(LOG_DEBUG, "kwrite2bin:file not a bin file!", 0); return ERR_SFFS_FILE_TYPE; } if(!fileds[filed].write) { SysLog(LOG_DEBUG, "open for read,cannot be write!", 0); return ERR_SFFS_OPERAT_MODE; } if(flag){ fileds[filed].bin_file_willflush_datalen = 0; } if((length + fileds[filed].bin_file_willflush_datalen + realDataLength) > realFileLength) { #if DEBUG_WRITE printf("kwrite2bin: file %s already have data %d\r\n",fileds[filed].name, realDataLength); printf("kwrite2bin: just was checked but not be flushed datalength is %d\r\n",fileds[filed].bin_file_willflush_datalen); printf("kwrite2bin: it's create length is %d\r\n",realFileLength); printf("kwrite2bin: and will be writed data length is %d\r\n",length); printf("kwrite2bin: will writed temp file length is %d\r\n",length + realDataLength + fileds[filed].bin_file_willflush_datalen); printf("kwrite2bin: fileds[%d].sector = %x\r\n",filed,fileds[filed].sector); #endif #if 0 addr = sectortoaddress(fileds[filed].sector); addr1 = (INFOLENGTH + ((long)(fileds[filed].packet-1) * PACKETLENGTH)); #if DEBUG_WRITE printf("kwrite2bin: addr = 0x%x\r\n",addr); printf("kwrite2bin: addr1 = 0x%x\r\n",addr1); #endif addr = addr + addr1; if(addr + length + fileds[filed].bin_file_willflush_datalen + realDataLength >= FFS_END_ADDRESS) { sprintf(c256DebugBuff,"kwrite2bin: flash memory overflow,FFS_END_ADDR=0x%x,want write end addr=0x%x\r\n", (long)FFS_END_ADDRESS, addr + length + fileds[filed].bin_file_willflush_datalen); SysLog(LOG_ERR, c256DebugBuff, 0); return ERR_SFFS_LENGTH; } #endif //here fix the bug that is always overflow when read out the file sector is 0xff // if( (length + fileds[filed].bin_file_willflush_datalen > PAYLOAD * get_unused_packet_from(fileds[filed].oldsector)) // && (length + fileds[filed].bin_file_willflush_datalen > get_avaible_space())){ if(length + fileds[filed].bin_file_willflush_datalen > get_avaible_space()){ sprintf(c256DebugBuff,"kwrite2bin: flash memory overflow"); SysLog(LOG_ERR, c256DebugBuff, 0); #if DEBUG_WRITE printf("kwrite2bin: file at sector %d\r\n",fileds[filed].oldsector); printf("kwrite2bin: want save data is %d\r\n",length+fileds[filed].bin_file_willflush_datalen); printf("kwrite2bin: sector available space is %d\r\n", PAYLOAD * get_unused_packet_from(fileds[filed].oldsector)); printf("kwrite2bin: sffs available space is %d\r\n",get_avaible_space()); #endif return ERR_SFFS_LENGTH; } else { int copyDataLen; int newFileLen; char backFileName[8]; char tempFileName[8]; #if DEBUG_WRITE printf("kwrite2bin: realDataLength is %d\r\n",pbin_file_info[fileds[filed].bin_file_info_id]->filled_data_length); #endif strncpy(backFileName,fileds[filed].name,8); //pbin_file_info[fileds[filed].bin_file_info_id]->file_length += length;//expend file length for longer data sprintf(tempFileName,"%d",tmpcnt++); if(tmpcnt>100000000L) tmpcnt = 0; while(create_file(tempFileName,'f',realDataLength) != OK) { if(reCreate > 3) { sprintf(c256DebugBuff,"kwrite2bin: re create TmpInDrv failed for file length expend.\r\n"); SysLog(LOG_ERR, c256DebugBuff, 0); return ERR_SFFS_CREATE; } reCreate++; if(get_avaible_space() <= length) { if(-1 == my_consolidate()) { return -1; } } else { sprintf(c256DebugBuff,"kwrite2bin: create TmpInDrv failed for file length expend.\r\n"); SysLog(LOG_ERR, c256DebugBuff, 0); return ERR_SFFS_SPACE_EMPTY; } } reCreate=0; if(0 != realDataLength) { copyDataLen = copy_file(tempFileName, backFileName); if(realDataLength != copyDataLen) { sprintf(c256DebugBuff,"kwrite2bin: copy file %s to %s failed, copyDatalen = %d\r\n",backFileName,tempFileName,copyDataLen); SysLog(LOG_ERR, c256DebugBuff, 0); del_file(tempFileName); return ERR_SFFS_LENGTH; } #if DEBUG_WRITE printf("kwrite2bin: backup file %s %d bytes success\r\n",backFileName,copyDataLen); #endif } newFileLen = realDataLength + length + fileds[filed].bin_file_willflush_datalen; newFileLen = (newFileLen%PAYLOAD+2)*PAYLOAD; #if DEBUG_WRITE printf("newFileLen= %d,realDataLength = %d,length=%d,fileds[filed].bin_file_willflush_datalen=%d\r\n",newFileLen,realDataLength,length,fileds[filed].bin_file_willflush_datalen); #endif while(create_file(backFileName,'f',newFileLen) == -1) { if(reCreate > 3) { sprintf(c256DebugBuff,"kwrite2bin: re create %s failed for file length expend.\r\n",backFileName); SysLog(LOG_ERR, c256DebugBuff, 0); del_file(tempFileName); return ERR_SFFS_CREATE; } else { sprintf(c256DebugBuff,"kwrite2bin: create %s failed for file length expend.\r\n",tempFileName); SysLog(LOG_ERR, c256DebugBuff, 0); del_file(tempFileName); return ERR_SFFS_SPACE_EMPTY; } } if(0 != realDataLength) { copyDataLen = copy_file(backFileName,tempFileName); if(realDataLength != copyDataLen) { sprintf(c256DebugBuff,"kwrite2bin: restore file failed.copyDatalen = %d\r\n",copyDataLen); SysLog(LOG_ERR, c256DebugBuff, 0); del_file(tempFileName); return ERR_SFFS_LENGTH; } #if DEBUG_WRITE printf("kwrite2bin: restore file %s %d bytes success\r\n",backFileName,copyDataLen); #endif } kclose(filed); filed = kopen(backFileName, "w"); if(filed<0) { del_file(tempFileName); sprintf(c256DebugBuff,"kwrite2bin: open file %s failed.\r\n",fileds[filed].name); SysLog(LOG_ERR, c256DebugBuff, 0); return ERR_SFFS_ILLEBAL_FILEHANDLE; } del_file(tempFileName); } } // else{ // printf("kwrite2bin: file %s will have data total length is %d\r\n",fileds[filed].name, realDataLength+length+fileds[filed].bin_file_willflush_datalen); // printf("kwrite2bin: it's create length is %d\r\n",realFileLength); // // } //then check the file point is point to the file end, if(fileds[filed].bin_file_dataptr != pbin_file_info[fileds[filed].bin_file_info_id]->filled_data_length) {//the file access point not point to the file end, will check this space is empty or not. i=0; dataptr = fileds[filed].packetdataptr; while(i filled_data_length += count; fileds[filed].totallength += count; fileds[filed].bin_file_dataptr += count; fileds[filed].length = dataptr; if(i >= length) { fileds[filed].packetdataptr = dataptr; } if(dataptr >= PACKETLENGTH) { dataptr = 6; fileds[filed].packetdataptr = 6; addr = sectortoaddress(fileds[filed].sector); addr1 = (INFOLENGTH + ((long)(fileds[filed].packet-1) * PACKETLENGTH)); addr = addr + addr1; // emb_program(addr+4, (PAYLOAD >> 8) & 0xff);//write packet length info // emb_program(addr+5, PAYLOAD & 0xff); fileds[filed].oldsector = fileds[filed].sector; fileds[filed].oldpacket = fileds[filed].packet; // get link to next packet fileds[filed].packet = read_flash(addr+3) & 0xff; fileds[filed].sector = read_flash(addr+2) & 0xff; if((fileds[filed].packet == 0xff) && (i filled_data_length += count; fileds[filed].totallength += count; fileds[filed].bin_file_dataptr += count; fileds[filed].length = dataptr; if(i >= length) { fileds[filed].packetdataptr = dataptr; } if(dataptr >= PACKETLENGTH) { dataptr = 6; fileds[filed].packetdataptr = 6; addr = sectortoaddress(fileds[filed].sector); addr1 = (INFOLENGTH + ((long)(fileds[filed].packet-1) * PACKETLENGTH)); addr = addr + addr1; if(!isModify){//if is modify, the packet length info already be writed emb_program(addr+4, (PAYLOAD >> 8) & 0xff);//write packet length info emb_program(addr+5, PAYLOAD & 0xff); } fileds[filed].oldsector = fileds[filed].sector; fileds[filed].oldpacket = fileds[filed].packet; // get link to next packet fileds[filed].packet = read_flash(addr+3) & 0xff; fileds[filed].sector = read_flash(addr+2) & 0xff; if((fileds[filed].packet == 0xff) && (i = NUMOPENFILES)){//the filed is not valuable id return ERR_SFFS_ILLEBAL_FILEHANDLE; } if(!fileds[filed].busy){ return ERR_SFFS_NOT_OPENED; } j = 0; if(fileds[filed].bin_file) return kwrite2bin(filed,data,length,TRUE); while (length) { count = 0; dataptr = fileds[filed].length; while (dataptr < PAYLOAD && count < length) { fileds[filed].data[dataptr++] = data[j++]; count++; } length -= count; fileds[filed].totallength += count; fileds[filed].length = dataptr; // if full data buffer in file descriptor // write it out. if (dataptr == PAYLOAD) { if (!write_data(filed)) { return 0; } } } return fileds[filed].totallength; } int kwrite4java(int filed, unsigned char *data, int offset, int length,unsigned char flag) { return kwrite2bin(filed, data+offset, length,flag); } /* * Must call kopen with read mode before call kseek * return 0 success * -1 failed. */ int kseek(int filed, int length,unsigned char whence) { int ti,tj,len; int rc; long addr; if(!fdiskReady){ SysLog(LOG_DEBUG, "flash disk not ready!", 0); return ERR_SFFS_NOT_READY; } if((filed < 0) || (filed >= NUMOPENFILES)){//the filed is not valuable id return ERR_SFFS_ILLEBAL_FILEHANDLE; } if(length < 0){ return ERR_SFFS_LENGTH; } //printf("fileds[filed].busy = %d\r\n",fileds[filed].busy); if (!fileds[filed].busy) {//file can not be opened return ERR_SFFS_NOT_OPENED; } switch(whence){ case SEEK_SET: len = length; break; case SEEK_CUR: len = fileds[filed].bin_file_dataptr + length; //printf("now file data length %d\r\n",pbin_file_info[fileds[filed].bin_file_info_id]->filled_data_length); if(len > pbin_file_info[fileds[filed].bin_file_info_id]->filled_data_length) return ERR_SFFS_LENGTH; break; case SEEK_END: len = pbin_file_info[fileds[filed].bin_file_info_id]->filled_data_length + length; //printf("now file data length %d\r\n",pbin_file_info[fileds[filed].bin_file_info_id]->filled_data_length); if(len < 0 ) return ERR_SFFS_LENGTH; break; default: SysLog(LOG_DEBUG, "flash disk not ready!", 0); return ERR_PARAM; } // start of new ti = len%250; tj = len/250; fileds[filed].packet = (fileds[filed].startpacket+tj); if ((fileds[filed].startpacket+tj) > 0) fileds[filed].oldpacket = (fileds[filed].startpacket+tj-1); fileds[filed].packetdataptr = 6+ti; addr = sectortoaddress(fileds[filed].sector) + (INFOLENGTH + ((long)(fileds[filed].packet-1) * PACKETLENGTH)); fileds[filed].length = read_flash(addr+4) * PACKETLENGTH + read_flash(addr+5); fileds[filed].length = fileds[filed].length-ti; // end of new fileds[filed].bin_file_dataptr = len; return OK; } int kseek4java(int filed, int length, unsigned char flag) { return kseek(filed, length, flag); } int kclose(int filed) { int i; int dataptr = 0; long addr; if(!fdiskReady){ SysLog(LOG_DEBUG, "flash disk not ready!", 0); return ERR_SFFS_NOT_READY; } if (filed < 0 || filed >= NUMOPENFILES) { return ERR_SFFS_ILLEBAL_FILEHANDLE; } if (!fileds[filed].busy) { return ERR_SFFS_NOT_OPENED; } if(fileds[filed].bin_file) { fileds[filed].bin_file = 0; fileds[filed].busy = 0; fileds[filed].write = 0; return OK;//because bin file now is directly write data to memory , so can not going on to do flush cache } //follow access is for acsii file to flush cache data to memory if (fileds[filed].write) { if (fileds[filed].length > 0) { // get the address of the new data packet addr = sectortoaddress(fileds[filed].sector) + (INFOLENGTH + ((long)(fileds[filed].packet-1) * PACKETLENGTH)); // skip past the packet number and link field addr += 4; // here we do the actual writing of the data. // if we have more data than a packet can handle use the // payload value to write else use the length for a // partial packet. emb_program(addr, 0); emb_program(addr+1, fileds[filed].length); addr += 2; for (i=0; i id != id) return id; } return OK; } int count_bin_files(void) { int id,num=0; for(id=0;id name[0] != 0x00) num++; } return num; } /** *@return 0 - flash file system is OK. * 1 - not OK. */ int check_fdisk(void) { int i,rc; printf("init_file_system: FFS_IMAGE_ADDRESS = 0x%x,FFS_END_ADDR = 0x%x\r\n",FFS_IMAGE_ADDRESS,FFS_END_ADDRESS); for (i=0; i =buflen) return k; } p[k++] = 0x00; } } } return k; } int get_file_len(char *filename) { int id; id = get_bin_file_info_id(filename); if(id == -1) return -1; return pbin_file_info[id]->file_length; } int get_file_data_len(char *filename) { int id; id = get_bin_file_info_id(filename); if(id == -1) return -1; return pbin_file_info[id]->filled_data_length; } int get_file_list_java(char *p,int buflen) { return get_file_list(p, buflen); } int get_file_num_java(void) { return get_file_num(); } int get_file_len_java(char *filename) { return get_file_len(filename); } int get_file_data_len_java(char *filename) { return get_file_data_len(filename); }