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; jbefore = (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;iname[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;idata[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;iname[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;idata[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;idid = 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; ifile_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;iname[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;idname 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;idname[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(ifilled_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) && (ifilled_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; iid  != id) 
			return id; 
	} 
	return OK; 
} 
 
int count_bin_files(void) 
{ 
	int id,num=0; 
	for(id=0;idname[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); 
}