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

📄 simpleffs.c

📁 一个简单的flash文件系统
💻 C
📖 第 1 页 / 共 5 页
字号:
		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<BIN_FILE_MAX_NUM;id++){
		pbin_file_info[id] = (BIN_FILE_INFO_INKEYSRAM*)p;
		pbin_file_info[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<BIN_FILE_MAX_NUM;id++){
		pbin_file_info[id] = (BIN_FILE_INFO_INKEYSRAM*)p;//init struct pbin_file_info point to key sram address.
		p += sizeof(BIN_FILE_INFO_INKEYSRAM);
	}	
	total_bin_files = *(int*)BIN_FILE_TOTAL_NUM_ADDR;
	printf("Total bin files=%d\r\n",total_bin_files);
	isReadyBinFileInfo = 1;
	
	return OK;
}


/*
 * format the file system.
 * all data will be lost.
 * format times will be recorded
 * return 0 SUCCESS
 *		  failed;
 */
int init_file_system(void) 
{
	unsigned char i;
	int rc;
		
	//the last 512k is used to as flashfile system
	fdiskReady = 0;
	for (i=0; i<MAXSECTORS; i++) {
		rc=format_sect(i);
		if(rc != OK)
		{
			sprintf(c256DebugBuff, "format sector %d failed,rc = %d\r\n", i , rc );
			SysLog(LOG_DEBUG, c256DebugBuff, 0);
			return rc;
		}
	}

	bzero(fileds[0].name, NUMOPENFILES*sizeof(filedesc));//fileds[0].name - use this only to get the struct first address for memory initial
	
	if(OK != init_bin_file_info_pool()){
		sprintf(c256DebugBuff, "format sector %d failed\r\n", i);
		SysLog(LOG_DEBUG, c256DebugBuff, 0);
		return ERR_SFFS_INIT_BIN_INFO;	
	}
	fdiskReady = 1;
	return 0;
}


/*
 * I think this should be inner function, but it is used as API.
 * Because the kopen is unable to create file, this API must be called
 * befor using kxxx API.
 * filename: valid file name
 * attribute: 'a'-- append
 *		   'f'-- force ,if the special file is exist,it will be delete
		   'b'--bin, if the special file is exist , will return error -3;
 * length: space to be reserve for the file.
 * return o: create success
 *		-1: disk is not ready
 *		-2: failed no space,file length is too long
 *		-3: the file is exit ,if use 'b' mode
 *		
 *		  0: means create_file success
 */
int create_file(char *filename,char attribute,unsigned int length) 
{
	int i;
	long addr;
	long addr1;
	int wrapped;
	int oldpacket;
	int sector;
	int packet;
	int cacheentry;
	int done;
	int entry;
	int smallest;
	char kname[INFOENTRY+1];
	int id;
	
#if DEBUG_CREATE
	sprintf(c256DebugBuff, "create_file: Create file %s with %c of length %d\r\n",filename,attribute,length);
	SysLog(LOG_DEBUG, c256DebugBuff, 0);
#endif

	if(!fdiskReady){
		check_fdisk();
		if(!fdiskReady){
			SysLog(LOG_DEBUG, "flash disk want be format!", 0);
			return ERR_SFFS_NOT_READY;
		}
	}
	if (length == 0) 
	{
		length = 250; //25 ==> 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<INFOENTRY+1; i++) {
		if (done) {
			if (filename[i]) {
				kname[i] = filename[i];
			} else {
				done = 0;
				kname[i] = 0;
			}
		} else {
			kname[i] = 0;
		}
	}
	
#if DEBUG_CREATE
	sprintf(c256DebugBuff, "Create %s,attribute is %c, length is %d\r\n",filename,attribute,length);
	SysLog(LOG_DEBUG, c256DebugBuff, 0);
#endif

	switch(attribute) {
		case 'b':
			// this deletes an existing file
			packet = find_file(kname);
			if (packet != MAXSECTORS && delbfrwrite) {
				return ERR_SFFS_EXIST;
				//delete_file(kname,packet);
			}
			id = insert_bin_file_info(kname);
			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<MAXSECTORS; i++) {
					if (sectorerased[i]) {
						sector++;
					}
				}

				// if need to consolidate sectors do it.
				if (sector < 3) {
					doconsolidate = 1; //??? I think uncomment the following part is better.
				/*
					workingsector = consolidate();
					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;
					}
				*/
				}
			}
			sectorerased[workingsector] = 0;

#if DEBUG_CREATE
	sprintf(c256DebugBuff, "create_file: workingsector = %d\r\n",workingsector);
	SysLog(LOG_DEBUG, c256DebugBuff, 0);
#endif
			// find first unused packet and wr
			packet = get_unused_packet_from(workingsector);
#if DEBUG_CREATE
	sprintf(c256DebugBuff, "create_file: packet = %d\r\n",packet);
	SysLog(LOG_DEBUG, c256DebugBuff, 0);
#endif
			if (packet > 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<INFOENTRY; i++)
				emb_program(addr+i, kname[i]);

			// put name into cache
			// go find an empty entry in the cache
			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) {
				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;
			}

#if DEBUG_CREATE
	sprintf(c256DebugBuff,"create_file: insert %s int cache entry = %d\r\n",kname,entry);
	SysLog(LOG_DEBUG, c256DebugBuff, 0);
#endif
			strcpy(cachename[entry],kname);
			cacheuse[entry] = 1;
			cachepacket[entry] = packet;
			cachesector[entry] = workingsector;

			// need to mark the rest of the file as used
			if (length > 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<MAXSECTORS; i++) {
					if (sectorerased[i]) {
						sector++;
					}
				}

				// if need to consolidate sectors do it.
				if (sector < 3) {
					doconsolidate = 1; //??? I think uncomment the following part is better.
				/*
					workingsector = consolidate();
					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;
					}
				*/
				}
			}
			sectorerased[workingsector] = 0;

#if DEBUG_CREATE
	sprintf(c256DebugBuff, "create_file: workingsector = %d\r\n",workingsector);
	SysLog(LOG_DEBUG, c256DebugBuff, 0);
#endif
			// find first unused packet and wr
			packet = get_unused_packet_from(workingsector);
#if DEBUG_CREATE
	sprintf(c256DebugBuff, "create_file: packet = %d\r\n",packet);
	SysLog(LOG_DEBUG, c256DebugBuff, 0);
#endif
			if (packet > 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<INFOENTRY; i++)
				emb_program(addr+i, kname[i]);

			// put name into cache
			// go find an empty entry in the cache
			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) {
				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;
			}

#if DEBUG_CREATE

⌨️ 快捷键说明

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