📄 bak2nand.c
字号:
for (i = 0; i < strlen(ffresult.ff_name); i++)
srcFile[srcIndex + i] = ffresult.ff_name[i];
srcFile[srcIndex + i] = '\0';
needBackup = checkNeedBackupFile(srcFile);
if (needBackup != 0)
break;
} while (findnext(&ffresult) != -1);
}
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, " needBackup = %d", needBackup);
SprintStringLn(NANDBackupDebugString);
#endif
findclose(&ffresult);
ap_free(srcFile);
return needBackup;
}
/*************************************************************
Function: checkNeedRestoreDir
Description:
Check if the backup of the specified target DIR has
the most recent file content.
Input:
dirNO - the target DIR no (index in TargetDir[])
Return value:
1 backup is newer, restore is recommended
0 backup is old, restore is not recommended
-1 function failed - memory allocation error
**************************************************************/
static int checkNeedRestoreDir(int dirNO)
{
int i, j;
struct backupRecord *entry;
unsigned char *srcFile;
int backupLatest;
struct _stat fileStat;
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, "[checkNeedRestoreDir] (%d)[%s]", dirNO, TargetDir[dirNO]);
SprintStringLn(NANDBackupDebugString);
#endif
srcFile = (unsigned char *)ap_malloc(NAND_BACKUP_FILENAME_LEN);
if (srcFile == NULL)
{
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, " memory allocation failed");
SprintStringLn(NANDBackupDebugString);
#endif
return -1;
}
backupLatest = 0;
// loop through the index entry to compare status of the related files
for (i = NAND_FIRST_INDEX_ENTRY * sizeof(struct backupRecord); i < NAND_BLOCK_SIZE; i += sizeof(struct backupRecord))
{
entry = (struct backupRecord *)((unsigned long)IndexBuffer + i);
if (compareDir(entry->filename, TargetDir[dirNO]) == 1)
{
// the file in this entry is within the target DIR, check status
j = 0;
while (entry->filename[j] != 0xFF && entry->filename[j] != 0x0)
{
srcFile[j] = entry->filename[j];
j++;
}
srcFile[j] = '\0';
if (stat(srcFile, &fileStat) == -1)
{
// file not found, backup of course is good
backupLatest = 1;
break;
}
if (fileStat.st_mtime < LastBackupTime)
{
// file in backup is newer
backupLatest = 1;
break;
}
}
}
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, " backupLatest = %d", backupLatest);
SprintStringLn(NANDBackupDebugString);
#endif
ap_free(srcFile);
return backupLatest;
}
/*************************************************************
Function: blocksNeededToBackupDir
Description:
Get the total size of the files in the specified directory
in terms of blocks (NAND_BLOCK_SIZE).
Input:
dirNO - the specified DIR no (index in TargetDir[])
Return value:
Number of blocks required to hold the files in the
specified directory.
-1 if error.
**************************************************************/
static int blocksNeededToBackupDir(int dirNO)
{
unsigned char *srcFile;
int totalFrames;
int totalBlocks;
struct ffblk ffresult;
int i;
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, "[blocksNeededToBackupDir] (%d)[%s]", dirNO, TargetDir[dirNO]);
SprintStringLn(NANDBackupDebugString);
#endif
srcFile = (unsigned char *)ap_malloc(NAND_BACKUP_FILENAME_LEN);
if (srcFile == NULL)
{
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, " memory allocation failed");
SprintStringLn(NANDBackupDebugString);
#endif
return -1;
}
// copy the target DIR name to srcFile and add a "\*" at its end for findX()
for (i = 0; i < strlen(TargetDir[dirNO]); i++)
srcFile[i] = TargetDir[dirNO][i];
if (srcFile[i - 1] != '\\' && srcFile[i - 1] != '/')
{
srcFile[i] = '\\';
i++;
}
srcFile[i++] = '*';
srcFile[i] = '\0';
totalFrames = 0;
if (findfirst(srcFile, &ffresult, 0) == 0)
{
do
{
// file found, get the file size
if (ffresult.ff_fsize > 0)
totalFrames += ((ffresult.ff_fsize - 1) / NFLASH_FRAME_SIZE + 1);
} while (findnext(&ffresult) != -1);
}
totalBlocks = ((totalFrames - 1) / FramesPerBlock) + 1;
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, " total frames = %d, total blocks = %d", totalFrames, totalBlocks);
SprintStringLn(NANDBackupDebugString);
#endif
findclose(&ffresult);
ap_free(srcFile);
return totalBlocks;
}
/*************************************************************
Function: initBackup
Description:
Allocate memory for index buffer, read index block,
and get the last backup time.
Return value:
0 succeeded
-1 memory allocation error
**************************************************************/
static int initBackup(void)
{
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, "[initBackup]");
SprintStringLn(NANDBackupDebugString);
sprintf(NANDBackupDebugString, " sizeof(struct backupRecord) = %d", sizeof(struct backupRecord));
SprintStringLn(NANDBackupDebugString);
#endif
FramesPerBlock = NAND_BLOCK_SIZE / NFLASH_FRAME_SIZE;
IndexBuffer = (struct backupRecord *)ap_malloc(NAND_BLOCK_SIZE);
if (IndexBuffer == NULL)
{
return -1;
}
// read index block
readBlock(0, (unsigned char *)IndexBuffer);
// read last backup info
LastBackupTime = IndexBuffer->fsize;
if (LastBackupTime == 0xFFFFFFFF)
LastBackupTime = 0;
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, " last backup time = %d", LastBackupTime);
SprintStringLn(NANDBackupDebugString);
#endif
return 0;
}
/*************************************************************
Function: endBackup
Description:
Terminate the backup system.
Input:
update - 1 = update the index block
0 = kept index block intact
**************************************************************/
static void endBackup(short update)
{
unsigned short cDate;
unsigned short cTime;
unsigned long cTimeInSecond;
sysTime now;
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, "[endBackup]");
SprintStringLn(NANDBackupDebugString);
#endif
if (update == 1 && IndexBuffer != NULL)
{
// backup has been done, set the backup time
sc_getTime(&now);
cDate = (now.year << 9) + (now.month << 5) + now.day;
cTime = (now.hour << 11) + (now.minute << 5) + (now.second >> 1);
timeConvert(cDate, cTime, &cTimeInSecond);
IndexBuffer->fsize = cTimeInSecond;
writeBlock(0, (unsigned char *)IndexBuffer);
}
ap_free(IndexBuffer);
IndexBuffer = NULL;
return;
}
/*************************************************************
Function: clearRegion
Description:
Clear a region
Input:
region - the region information
**************************************************************/
static void clearRegion(struct NAND_region *region)
{
int i, j;
struct backupRecord *entry;
int startingFrame;
int endingFrame;
int *target;
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, "[clearRegion]");
SprintStringLn(NANDBackupDebugString);
#endif
// get the starting frame and the ending frame of the region
startingFrame = region->startingBlock * FramesPerBlock;
endingFrame = startingFrame + region->blockNum * FramesPerBlock - 1;
// clear the index entry related to the region
for (i = NAND_FIRST_INDEX_ENTRY * sizeof(struct backupRecord); i < NAND_BLOCK_SIZE; i += sizeof(struct backupRecord))
{
entry = (struct backupRecord *)((unsigned long)IndexBuffer + i);
if (entry->startingFrame >= startingFrame && entry->startingFrame <= endingFrame)
{
// the index entry of the file is within the region
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, " kill entry %d", i / sizeof(struct backupRecord));
SprintStringLn(NANDBackupDebugString);
#endif
target = (int *)entry;
for (j = 0; j < sizeof(struct backupRecord); j += sizeof(int))
{
*target = 0xFFFFFFFF;
target++;
}
}
}
// erase the block in the region
for (i = 0; i < region->blockNum; i++)
{
sc_disableInt();
nfshEraseBlock((unsigned long)(region->startingBlock + i) * NAND_BLOCK_SIZE);
sc_enableInt();
}
return;
}
/*************************************************************
Function: backupFile
Description:
Backup a file
Input:
filename - the file
toFrame - backup starts from this frame
Return value:
If succeeded, the value is the number of frame used.
If failed, the value is -1.
Note:
The index block should be already in index buffer before
calling this function.
**************************************************************/
static int backupFile(unsigned char *filename, int toFrame)
{
int frames = 0;
struct _stat fileStat;
int i;
long j;
struct backupRecord *entry;
int fd;
long bufSize;
long readSize;
unsigned char buffer[NFLASH_FRAME_SIZE];
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, "[backupFile] %s to frame %d", filename, toFrame);
SprintStringLn(NANDBackupDebugString);
#endif
// get the stat of the file
if (stat(filename, &fileStat) == -1)
return -1;
// number of frames needed by the file
if (fileStat.st_size > 0)
frames = (fileStat.st_size - 1) / NFLASH_FRAME_SIZE + 1;
else
frames = 0;
// find an free entry in index block
for (i = NAND_FIRST_INDEX_ENTRY * sizeof(struct backupRecord); i < NAND_BLOCK_SIZE; i += sizeof(struct backupRecord))
{
entry = (struct backupRecord *)((unsigned long)IndexBuffer + i);
if (entry->filename[0] == 0xFF)
{
// this entry is free, fill in the info
for (j = 0; j < NAND_BACKUP_FILENAME_LEN; j++)
{
if (filename[j] == '\0')
break;
entry->filename[j] = filename[j];
}
for (; j < NAND_BACKUP_FILENAME_LEN; j++)
entry->filename[j] = 0xFF;
entry->attribute = fileStat.st_mode;
// entry->timeInSecond = fileStat.st_mtime;
entry->fsize = fileStat.st_size;
entry->startingFrame = toFrame;
entry->frameNum = frames;
break;
}
}
if (i >= NAND_BLOCK_SIZE)
return -1; // no free index entry
// index entry done, start filling in the content to the NAND flash frames
if (frames == 0)
{
// filesize is zero, no need to copy data
return 0;
}
// open the file
fd = open(filename, 0);
if (fd == -1)
return -1;
for (i = 0; i < frames; i++)
{
if (i == (frames - 1))
bufSize = NFLASH_FRAME_SIZE - (frames * NFLASH_FRAME_SIZE - filelength(fd));
else
bufSize = NFLASH_FRAME_SIZE;
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, " frame %d: size = %d", i, bufSize);
SprintStringLn(NANDBackupDebugString);
#endif
readSize = read(fd, buffer, bufSize);
if (readSize != bufSize)
{
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, " read error: readSize = %d", readSize);
SprintStringLn(NANDBackupDebugString);
#endif
frames = -1;
break;
}
if (bufSize < NFLASH_FRAME_SIZE)
{
for (j = bufSize; j < NFLASH_FRAME_SIZE; j++)
buffer[j] = 0xFF;
}
sc_disableInt();
nfshProgramFrame((unsigned long)(toFrame + i) * NFLASH_FRAME_SIZE, buffer);
sc_enableInt();
}
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, " done! %d frames programmed.", frames);
SprintStringLn(NANDBackupDebugString);
#endif
close(fd);
return frames;
}
/*************************************************************
Function: backupDir
Description:
Backup a target directory.
Input:
dirNO - the specified DIR no (index in TargetDir[])
region - the region information
Return value:
0 - backup succeeded
-1 - backup failed and the index buffer intact
-2 - backup failed and the content in region has been destroyed
Note:
The index block should be already in index buffer before
calling this function.
**************************************************************/
static int backupDir(int dirNO, struct NAND_region *region)
{
unsigned char *srcFile;
int srcIndex;
int i;
struct ffblk ffresult;
int curFrame;
int usedFrame;
int result;
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, "[backupDir] (%d)[%s]", dirNO, TargetDir[dirNO]);
SprintStringLn(NANDBackupDebugString);
sprintf(NANDBackupDebugString, " starting block = %d, number of blocks = %d", region->startingBlock, region->blockNum);
SprintStringLn(NANDBackupDebugString);
#endif
srcFile = (unsigned char *)ap_malloc(NAND_BACKUP_FILENAME_LEN);
if (srcFile == NULL)
{
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, " memory allocation failed");
SprintStringLn(NANDBackupDebugString);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -