⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 simpleffs.c

📁 一个简单的flash文件系统
💻 C
📖 第 1 页 / 共 5 页
字号:
	}

	// 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<INFOENTRY; i++) {
					tmpfile[i] = read_flash(addr+i);
				}
				tmpfile[i] = 0;
				if (!strcmp(filename,tmpfile)) {
					found = 1;
#if DEBUG_TEST
	sprintf(c256DebugBuff, "find_file: insert %s into cache entry %d\r\n",filename,entry);
	SysLog(LOG_DEBUG, c256DebugBuff, 0);
#endif
					strcpy(cachename[entry],tmpfile);
					cachename[entry][i] = tmpfile[i] = 0;
					cacheuse[entry] = 1;
					cachesector[entry] = sector;
					cachepacket[entry] = packet;
				} else {
					addr += INFOENTRY;
					packet++;
				}
			}
		}
		
		if (!found)
		{
			//still could not find, next sector
			//the sector could be MAXSECTORS means could not find
			sector++;
		}
	}

	return sector;
}

/*
 * delete file from the file system.
 * The cache is not very useful in this funciton. It could be improved in futrue
 */
static void delete_file(char *filename,int sector) 
{
	long addr;
	int packet;
	int i;
	int data;
	int found;
	char tmpfile[INFOENTRY+1]; //fixed by minye_li
	int another_packet;
	int dataptr;
	int length;
	int nextpacket;
	int tsector;
	int nsector;
	int numincache;

	// remove entry from cache if there
	found = 0;
	i = 0;
	numincache = 0;

	while (i < MAXCACHE && !found) {
		if (cachename[i][0]) numincache++;
		if (!strcmp(filename,cachename[i])) {
			found = 1;
		} else {
			i++;
		}
	}
	// if found in the cache take it out of the cache
	if (found) 
	{
		cachename[i][0] = 0;
		cacheuse[i] = 0;
#if DEBUG_TEST
	sprintf(c256DebugBuff, "delete_file: deleting %s from cache entry %d\r\n",filename,i);
	SysLog(LOG_DEBUG, c256DebugBuff, 0);
#endif
	}

	tsector = sector;
	packet = 1;
	found = 0;
	while (packet <=NUMPACKETS && !found) //=changed by minye_li
	{
		addr = sectortoaddress(tsector) + ((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<INFOENTRY; i++)
				tmpfile[i] = read_flash(addr+i);
			tmpfile[i] = 0;
			if (!strcmp(filename,tmpfile)) {
				found = 1;
			} else {
				addr += INFOENTRY;
				packet++;
			}
		}
	}
	
	if (found) 
	{
		// now delete the file
		another_packet = 1;
		dataptr = 0;
		while (another_packet) {
			addr = sectortoaddress(tsector) + ((long)packet * INFOENTRY);
			emb_program(addr, 0);
			emb_program(addr+1, 0);
			// point to the data packet rather than the info packet
			// The INFOLENGTH gets you past the information part of the sector
			addr = sectortoaddress(tsector) + (INFOLENGTH + (long)(packet-1) * PACKETLENGTH);
			length = read_flash(addr+4) * PACKETLENGTH + read_flash(addr+5);
			nsector = read_flash(addr+2) & 0xFF;
			if (nsector != tsector) {
				tsector = nsector;
			}
			nextpacket = read_flash(addr+3);
			if ((nextpacket & 0xFF) > 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<MAXSECTORS; sector++) 
	{
		sectornum[i] = sector;
		if (!sectorerased[sector])
		{
			
			sectordatalength[sector] = (number_of_packets(RETUSED,sector)+number_of_packets(RETDELETED,sector)) * 250;

//			  sectordatalength[sector] =(NUMPACKETS- number_of_packets(RETFREE,sector) ) * 250;
		}
		else
		{
			//added by minye_li
			sectordatalength[sector] = 0;
		}
		i++;
	}

	// sort the sectors with data from least amount of data to most
					   //i=MAXSECTORS
	for (sector=0; sector<i; sector++)
	{
		for (j=0; j<i-1; j++) 
		{
			if (sectordatalength[sectornum[j]] > 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<i; j++) 
	{
		sprintf(c256DebugBuff, "consolidate: %d %u\r\n",sectornum[j],sectordatalength[sectornum[j]]);
		SysLog(LOG_DEBUG, c256DebugBuff, 0);
	}
#endif

	// format all empty sectors (sectors with deleted packets but no used packets)
	// BUGFIX UNDO
	// uncomment to 
	j = 0;
	found=0;
	while (sectordatalength[sectornum[j]] == 0) 
	{
		if (number_of_packets(RETDELETED,sectornum[j]) && !number_of_packets(RETUSED,sectornum[j])) {
			if (format_sect(sectornum[j])) {
				found=1; //added by minye_li
				sprintf(c256DebugBuff, "consolidate: ERROR formatting sector\r\n",sectornum[j]);
				SysLog(LOG_DEBUG, c256DebugBuff, 0);
			}
#if DEBUG_CONSOL
	sprintf(c256DebugBuff, "consolidate: Format empty sector %d\r\n",sectornum[j]);
	SysLog(LOG_DEBUG, c256DebugBuff, 0);
#endif
		}
		j++;
	}
	// here to fix again

	// get the sector with the least number of erase cycles (be kind to the flash)
#if 0
	smallest = 100000;
	found = 0;
	for (sector = 0; sector<MAXSECTORS; sector++) {
		if (sectorerased[sector]) {
			temp = get_erase_count(sector);
			if (temp < smallest) {
				smallest = temp;
				copytosector = sector;
				found = 1;
#if DEBUG_CONSOL
printf("consolidate: %d free = %d\r\n",sector,number_of_packets(RETFREE,sector));
#endif
			}
		}
	}

	if (!found) {
#if DEBUG_CONSOL
		printf("consolidate: Ereased sectors ");
#endif
		for (sector=0; sector<MAXSECTORS; sector++) {
#if DEBUG_CONSOL
			printf("%d ",sectorerased[sector]); //this print is not very useful
#endif
		}
		printf("\r\n");

	}
#endif

	j = 0;
												//????numsectors=8 now
	while (sectordatalength[sectornum[j]] == 0 && j < numsectors) j++;
	// leave j pointing to the first sector with data in it
	
	// copy files from max deleted packet sector to blank sector.
	numconsolidated = 0;
	sectorlength = sectordatalength[sectornum[j]];

#if DEBUG_CONSOL
	sprintf(c256DebugBuff, "sector= %d, sectorlength = %ld\r\n",j, sectorlength);
	SysLog(LOG_DEBUG, c256DebugBuff, 0);
#endif

	j=sectornum[j];

#ifdef USE_FLASH_AS_SWAP
	pDst=(unsigned char*)getBeginofthePageAddr(FFS_START_SECTOR-1);
#else
	#if DEBUG_CONSOL
		//printf("Allocate 64k memory for swap \r\n");
	#endif
	pDst=(unsigned char*)malloc(SECTORSIZE);
	if(pDst==NULL)
	{	
		sprintf(c256DebugBuff, "no 64k memory return\r\n");
		SysLog(LOG_ERR, c256DebugBuff, 0);	
		//return -1;
		return sectornum[j];
	}
	else
	{
		for(i=0;i<SECTORSIZE;i++)
		{
			pDst[i]=0xff;
		}
	}
#endif

	pSrc=(unsigned char*)sectortoaddress(j);
	copied=0;
	offset=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*)pDst+offset, (char*)p, INFOENTRY);
				offset=INFOLENGTH+(i-1)*PACKETLENGTH;
				//copy data second
				bcopy((char*)(pDst+offset), (char*)(pSrc+offset),PACKETLENGTH);
				copied++;
			}
		}
	}

#if DEBUG_CONSOL
	sprintf(c256DebugBuff, "consolidate: copied=%d, length=%d\r\n",copied, copied*250);
	SysLog(LOG_DEBUG, c256DebugBuff, 0);
#endif

	i=get_erase_count(j);
#if DEBUG_CONSOL
	sprintf(c256DebugBuff, "consolidate: erased times before format %d\r\n",i);
	SysLog(LOG_DEBUG, c256DebugBuff, 0);
#endif
	
	/*
	 * erase the sector
	 */
	format_sect(j);

	i=get_erase_count(j);
#if DEBUG_CONSOL
	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
	 */
	p=pDst+8;
#if DEBUG_CONSOL
	sprintf(c256DebugBuff, "consolidate: param sect addr 0x%x\r\n", pSrc);
	SysLog(LOG_DEBUG, c256DebugBuff, 0);
#endif
	pSrc+=8;

#if BYTE_WRITEBACK
	//Write back section infor first
	for(i=8;i<INFOLENGTH;i++)
	{
		temp=Program1byte(pSrc++,*p++);
		if(temp!=1)
		{		
		sprintf(c256DebugBuff, "consolidate: Write 1 byte %d failed\r\n", i);
		SysLog(LOG_EMERG, c256DebugBuff, 0);
		while(1);
		}
	}
#else
	temp=ProgramBlock(pSrc, INFOLENGTH-8, p);
	if(temp!=1)
	{
		sprintf(c256DebugBuff, "consolidate: Write back 2048 failed\r\n");
		SysLog(LOG_EMERG, c256DebugBuff, 0);
		return -1;
	}
	pSrc+=INFOLENGTH-8;
	p+=INFOLENGTH-8;

#endif

#if BYTE_WRITEBACK
	//pSrc=point to the first package now
	//p is also
	for(i=1;i<=NUMPACKETS;i++)
	{
		pSrc+=2; //these two byte is written in the format process
		p+=2;
		for(offset=2;offset<PACKETLENGTH;offset++)
		{
			temp=Program1byte(pSrc++,*p++);
			if(temp!=1)
			{
			sprintf(c256DebugBuff, "consolidate: Write 1 byte %d failed\r\n", i);
			SysLog(LOG_EMERG, c256DebugBuff, 0);
			return -1;
			}
		}
	}
#else

	pSrc+=2; //these two byte is written in the format process
	p+=2;

	for(i=1;i<=NUMPACKETS;i++) //changed by minye_li
	{
		temp=ProgramBlock(pSrc, PACKETLENGTH-2, p);
		if(temp!=1)
		{
			sprintf(c256DebugBuff, "consolidate: Write block=%d failed\r\n", i);
			SysLog(LOG_EMERG, c256DebugBuff, 0);
			return -1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -