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

📄 simpleffs.c

📁 一个简单的flash文件系统
💻 C
📖 第 1 页 / 共 5 页
字号:
		}
		pSrc+=PACKETLENGTH;
		p+=PACKETLENGTH;
	}
#endif
	
#if DEBUG_CONSOL
  sprintf(c256DebugBuff, "consolidate: after write back sector: %d used = %d!!!\r\n",j, number_of_packets(RETUSED,j)*250);
  SysLog(LOG_DEBUG, c256DebugBuff, 0);
#endif

#ifdef USE_FLASH_AS_SWAP
	EraseSector(FFS_START_SECTOR-1);
#else
	free(pDst);
#if DEBUG_CONSOL
	sprintf(c256DebugBuff, "pDst space was freed!");
	SysLog(LOG_DEBUG, c256DebugBuff, 0);
#endif

#endif
	// fill filename cache again with current changes
	fillcache();
	return j;
}

static int my_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;
	int total_files_in_sector;
	int writed_files;

	//--add by bryan
	long addr;
	int ret,stuff;
	int leastdatasector;
	int numpacketsinleast;
	int mostdatasector;
	int cur_packet_ID;
	int len;
	int swap_cache_end;

	int numofswapcache=0;
	SWAP_CACHE *pbeforeswapcache;
	SWAP_CACHE *pcurswapcache;
	SWAP_CACHE *pheadswapcache;
	SWAP_CACHE *pendswapcache;
	//add end

	unsigned char* pDst;
	unsigned char* pSrc;
	unsigned char* p;
	unsigned char* pSectorInfo;
	int offset, copied;
	
	copytosector = 0;			// stop warning from compiler
	nextdot = 0;
	run_gc_time++;

	sprintf(c256DebugBuff, "GC%d.\r\n",run_gc_time);
	SysLog(LOG_DEBUG, c256DebugBuff);
	
	i = 0;
	for (sector=0; sector<MAXSECTORS; sector++) 
	{
		sectornum[i] = sector;
		if (!sectorerased[sector])
		{
			sectordatalength[sector] = number_of_packets(RETUSED,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;
	leastdatasector = sectornum[0]; // --add by bryan
#if DEBUG_GC
	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_GC
	sprintf(c256DebugBuff, "consolidate: Format empty sector %d\r\n",sectornum[j]);
	SysLog(LOG_DEBUG, c256DebugBuff, 0);
#endif
		}
		j++;
	}
	// here to fix again


 //in this will malloc least memory for file system GC -- add by bryan
		pcurswapcache = (SWAP_CACHE*)malloc(sizeof(SWAP_CACHE));
		if(pcurswapcache == NULL){
			sprintf(c256DebugBuff, "malloc error for GC\r\n");
			SysLog(LOG_EMERG, c256DebugBuff, 0);
			return -1;
		}
		bzero(pcurswapcache,sizeof(SWAP_CACHE));
		pcurswapcache->before = 0;
		pheadswapcache = pcurswapcache;		
		pbeforeswapcache = pcurswapcache;
		swap_packets_addr_map[0] = (long)pcurswapcache;
		numofswapcache = 1;
		numpacketsinleast = number_of_packets(RETUSED,leastdatasector);
		for(j=1; j<numpacketsinleast; j++){
			pcurswapcache = (SWAP_CACHE*)malloc(sizeof(SWAP_CACHE));
			if(pcurswapcache == NULL)
			{
				sprintf(c256DebugBuff, "malloc error for GC\r\n");
				SysLog(LOG_EMERG, c256DebugBuff, 0);
				return -1;
			}
			bzero(pcurswapcache,sizeof(SWAP_CACHE));
			pcurswapcache->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<INFOENTRY;i++)
			{
				temp=Program1byte(pDst + 8*cur_packet_ID + i, pcurswapcache->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<PACKETLENGTH;i++)
			{
					temp=Program1byte(p+i,pcurswapcache->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<INFOENTRY;i++)
			{
				temp=Program1byte(pDst + 8*cur_packet_ID + i, pcurswapcache->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<PACKETLENGTH;i++)
		{
			temp=Program1byte(p+i,pcurswapcache->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<MAXCACHE; i++) {
		cachename[i][0] = 0;
		cacheuse[i] = 0;
		cachesector[i] = 0;
		cachepacket[i] = 0;
	}

	cacheentry = 0;
	sector = 0;
	found = 0;
#if DEBUG_CONSOL
	sprintf(c256DebugBuff, "cache list:\r\ncacheentry  |  cachename  |	cacheuse  |  cachesector  |  cachepacket\r\n");
	SysLog(LOG_DEBUG, c256DebugBuff, 0);
#endif
	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) {
				addr += INFOENTRY;
				packet++;
			} else {
				for (i=0; i<INFOENTRY; i++) {
					tmpfile[i] = read_flash(addr+i);
					cachename[cacheentry][i] = tmpfile[i];
				}
				cachename[cacheentry][i] = tmpfile[i] = 0;
				cacheuse[cacheentry] = 1;
				cachesector[cacheentry] = sector;
				cachepacket[cacheentry] = packet;
#if DEBUG_CONSOL
sprintf(c256DebugBuff, "%10d	 %6s	  %6d        %04x        %04x",cacheentry,cachename[cacheentry],
			cacheuse[cacheentry],cachesector[cacheentry],cachepacket[cacheentry]);
printf("%s\r\n", c256DebugBuff);
#endif
				if (cacheentry < MAXCACHE)
					cacheentry++;
				// if we are done filling the cache
				if (cacheentry == MAXCACHE) {
					found++;
				}
				addr += INFOENTRY;
				packet++;
			}
		}
		sector++;
	}
}

/*
 * return the number of the unused packet in the section.
 *		  value > 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);

⌨️ 快捷键说明

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