📄 simpleffs.c
字号:
}
// 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 + -