📄 bak2nand.c
字号:
#endif
return -1;
}
// check if the region is large enough to hold the files
i = blocksNeededToBackupDir(dirNO);
if (i == -1 || i > region->blockNum)
{
// region not big enough to hold all files
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, " region too small, needed=%d, available=%d", i, region->blockNum);
SprintStringLn(NANDBackupDebugString);
#endif
ap_free(srcFile);
return -1;
}
clearRegion(region);
// 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++;
}
srcIndex = i;
srcFile[i++] = '*';
srcFile[i] = '\0';
result = 0;
curFrame = region->startingBlock * FramesPerBlock;
if (findfirst(srcFile, &ffresult, 0) == 0)
{
// file found, get the real filename
do
{
// check if the region boundary has been breached
if (curFrame > (region->startingBlock + region->blockNum) * FramesPerBlock)
{
result = -2;
break;
}
// get the complete pathname
for (i = 0; i < strlen(ffresult.ff_name); i++)
srcFile[srcIndex + i] = ffresult.ff_name[i];
srcFile[srcIndex + i] = '\0';
// backup the file
usedFrame = backupFile(srcFile, curFrame);
if (usedFrame == -1)
{
result = -2;
break;
}
curFrame += usedFrame;
} while (findnext(&ffresult) != -1);
}
if (result == -2)
clearRegion(region);
findclose(&ffresult);
ap_free(srcFile);
return result;
}
/*************************************************************
Function: restoreFile
Description:
Restore a file
Input:
entry - the index entry of the file to be restored
Return value:
0 restore ok
-1 function failed - memory allocation error
**************************************************************/
static int restoreFile(struct backupRecord *entry)
{
int i;
unsigned char *srcFile;
int fd;
long bufSize;
long writeSize;
int result;
unsigned char buffer[NFLASH_FRAME_SIZE];
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, "[restoreFile]");
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;
}
// get the filename in ordinary C convention
i = 0;
while (entry->filename[i] != 0xFF && entry->filename[i] != 0x0 && i < NAND_BACKUP_FILENAME_LEN)
{
srcFile[i] = entry->filename[i];
i++;
}
srcFile[i] = '\0';
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, " file: %s", srcFile);
SprintStringLn(NANDBackupDebugString);
#endif
// open (create/truncate) the file
fd = open(srcFile, O_CREATE | O_TRUNC);
if (fd == -1)
{
ap_free(srcFile);
return -2;
}
if (entry->frameNum > 0)
{
result = 0;
for (i = 0; i < entry->frameNum; i++)
{
if (i == (entry->frameNum - 1))
bufSize = NFLASH_FRAME_SIZE - (entry->frameNum * NFLASH_FRAME_SIZE - entry->fsize);
else
bufSize = NFLASH_FRAME_SIZE;
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, " frame %d: size = %d", i, bufSize);
SprintStringLn(NANDBackupDebugString);
#endif
sc_disableInt();
nfshReadFrame((unsigned long)(entry->startingFrame + i) * NFLASH_FRAME_SIZE, buffer);
sc_enableInt();
writeSize = write(fd, buffer, bufSize);
if (writeSize != bufSize)
{
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, " write error: writeSize = %d", writeSize);
SprintStringLn(NANDBackupDebugString);
#endif
result = -1;
break;
}
}
}
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, " done! %d bytes written.", entry->fsize);
SprintStringLn(NANDBackupDebugString);
#endif
close(fd);
ap_free(srcFile);
return 0;
}
/*************************************************************
Function: restoreDir
Description:
Restore the target DIR
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 restoreDir(int dirNO)
{
int i;
struct backupRecord *entry;
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, "[restoreDir] (%d)[%s]", dirNO, TargetDir[dirNO]);
SprintStringLn(NANDBackupDebugString);
#endif
// 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, restore it
if (restoreFile(entry) != 0)
return -1;
}
}
return 0;
}
/*************************************************************
Function: NAND_checkBackup
Description:
Check if the backup contains the most recent file content.
Return value:
1 backup is older, new backup may be needed
0 backup is latest, new backup not necessary
-1 system error
**************************************************************/
int NAND_checkBackup(void)
{
int i;
int result;
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, "[NAND_checkBackup]");
SprintStringLn(NANDBackupDebugString);
#endif
// initialize NAND flash
nfshInit();
// initialize index buffer and get last backup time
if (initBackup() == -1)
return -1;
result = 0;
for (i = 0; i < NAND_BACKUP_DIR_NUM; i++)
{
result = checkNeedBackupDir(i);
if (result != 0)
break;
}
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, " result = %d", result);
SprintStringLn(NANDBackupDebugString);
#endif
// only checking is done here, index block is not changed
endBackup(0);
return result;
}
/*************************************************************
Function: NAND_backup
Description:
Backup the target DIRs to NAND flash.
Input:
forceBackup - unconditional backup
Return value:
0 backup succeeded
-1 failed - parameter error
-2 failed - memory allocation error
-3 failed - backup dir error
Note:
Directories within the specified directory are not backup.
**************************************************************/
int NAND_backup(short forceBackup)
{
int availableBlockNum;
int i;
int result;
struct NAND_region targetRegion[NAND_BACKUP_DIR_NUM];
short indexUpdated = 0;
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, "[NAND_backup] %d", forceBackup);
SprintStringLn(NANDBackupDebugString);
#endif
// initialize NAND flash
nfshInit();
// set parameters
availableBlockNum = (NAND_FLASH_SIZE / NAND_BLOCK_SIZE) - NAND_INDEX_BLOCK_NUM;
// calculate the number of frames assigned to each target DIR according to the given percentages
// also get the starting frame of each region assigned to a target DIR
if (NAND_BACKUP_DIR_NUM == 1)
{
// only one target DIR, all the frames are belong to us
targetRegion[0].startingBlock = NAND_INDEX_BLOCK_NUM;
targetRegion[0].blockNum = availableBlockNum;
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, " region %d: startingBlock=%d, blockNum=%d", 0, targetRegion[0].startingBlock, targetRegion[0].blockNum);
SprintStringLn(NANDBackupDebugString);
#endif
}
else
{
// more than one targets, check percentage
result = 0;
for (i = 0; i < NAND_BACKUP_DIR_NUM; i++)
result += BlockPercentage[i];
if (result > 100)
return -1;
// cut the NAND flash into regions with
for (i = 0; i < NAND_BACKUP_DIR_NUM; i++)
{
if (i == (NAND_BACKUP_DIR_NUM - 1))
{
targetRegion[NAND_BACKUP_DIR_NUM - 1].blockNum = availableBlockNum;
for (i = 0; i < NAND_BACKUP_DIR_NUM - 1; i++)
targetRegion[NAND_BACKUP_DIR_NUM - 1].blockNum -= targetRegion[i].blockNum;
}
else
{
targetRegion[i].blockNum = availableBlockNum * BlockPercentage[i] / 100;
}
if (i == 0)
targetRegion[i].startingBlock = NAND_INDEX_BLOCK_NUM;
else
targetRegion[i].startingBlock = targetRegion[i - 1].startingBlock + targetRegion[i - 1].blockNum;
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, " region %d: startingBlock=%d, blockNum=%d", i, targetRegion[i].startingBlock, targetRegion[i].blockNum);
SprintStringLn(NANDBackupDebugString);
#endif
}
}
// initialize index buffer and get last backup time
if (initBackup() == -1)
return -2;
result = 0;
// backup the target DIR one by one
for (i = 0; i < NAND_BACKUP_DIR_NUM; i++)
{
if (forceBackup == 1 || checkNeedBackupDir(i) == 1)
{
// backup the target DIR
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, " Backup (%d)[%s]", i, TargetDir[i]);
SprintStringLn(NANDBackupDebugString);
#endif
result = backupDir(i, &(targetRegion[i]));
if (result == -2)
{
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, " backupDir(%s) return -2!", TargetDir[i]);
SprintStringLn(NANDBackupDebugString);
#endif
indexUpdated = 1;
result = -3;
}
else if (result == 0)
{
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, " backupDir(%s) succeeded!", TargetDir[i]);
SprintStringLn(NANDBackupDebugString);
#endif
indexUpdated = 1;
}
else
{
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, " backupDir(%s) failed!", TargetDir[i]);
SprintStringLn(NANDBackupDebugString);
#endif
result = -3;
}
}
}
endBackup(indexUpdated);
return result;
}
/*************************************************************
Function: NAND_restore
Description:
Restore the target DIRs with data from NAND flash.
Input:
forceRestore - unconditional restore
Return value:
0 restore succeeded
-1 failed - memory allocation error
-2 failed - restore dir error
Note:
Directories within the specified directory are not backup.
**************************************************************/
int NAND_restore(short forceRestore)
{
int i;
int result;
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, "[NAND_restore] %d", forceRestore);
SprintStringLn(NANDBackupDebugString);
#endif
// initialize NAND flash
nfshInit();
for (i = 0; i < NAND_BACKUP_DIR_NUM; i++)
mkpath(TargetDir[i]);
// initialize index buffer and get last backup time
if (initBackup() == -1)
return -1;
// restore the target DIR one by one
result = 0;
for (i = 0; i < NAND_BACKUP_DIR_NUM; i++)
{
if (forceRestore == 1 || checkNeedRestoreDir(i) == 1)
{
// restore the target DIR
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, " Restore (%d)[%s]", i, TargetDir[i]);
SprintStringLn(NANDBackupDebugString);
#endif
if (restoreDir(i) == -1)
result = -2;
}
}
endBackup(0);
return result;
}
/*************************************************************
Function: NAND_clearBackup
Description:
Clear all backup
**************************************************************/
void NAND_clearBackup(void)
{
unsigned long offset;
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, "[NAND_clearBackup]");
SprintStringLn(NANDBackupDebugString);
#endif
// initialize NAND flash
nfshInit();
offset = 0;
while (offset < NAND_FLASH_SIZE)
{
sc_disableInt();
nfshEraseBlock(offset);
sc_enableInt();
offset += NAND_BLOCK_SIZE;
}
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, " done!");
SprintStringLn(NANDBackupDebugString);
#endif
return;
}
#endif // #ifdef NAND_BACKUP_ON
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -