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

📄 simpleffs.c

📁 一个简单的flash文件系统
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
 * 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 <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ucos.h>
#include <types.h>

#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<fileds[filed].length; i++)
		emb_program(addr+i,fileds[filed].data[dataptr++]);

	addr = sectortoaddress(fileds[filed].sector);
	addr1 = (INFOLENGTH + ((long)(fileds[filed].packet-1) * PACKETLENGTH));
	addr = addr + addr1;

	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;

	// kill the length
	fileds[filed].length = 0;
	return 1;
}

/*
 * filename: valid file name
 * sector: the sector contains file
 * return: packet id(from 1, ..)
 * this function could not be failed now
 * packet id=MAXPACKETS+1 means failed to find
 */
static int find_packet(char *filename,int sector) 
{
	int packet;
	long addr;
	int found;
	int i;
	int data;
	char tmpfile[INFOENTRY+1];

	packet = 1;
	found = 0;
	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);
			tmpfile[i] = 0;
			if (!strcmp(filename,tmpfile)) {
				found = 1;
			} else {
				addr += INFOENTRY;
				packet++;
			}
		}
	}
	if (packet > 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++;
		}

⌨️ 快捷键说明

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