📄 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 <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 + -