📄 bak2nand.c
字号:
/****************************************************************
File Name: BAK2NAND.C *
*****************************************************************
Last Modified Date: 2001/04/13 (Friday)
Compiler : GNU Cross-compiler/SDS
Platform : X86 protection mode, MIPS, Dragonball
Usage :
****************************************************************/
#include <sys/syscall.h>
#include <ansi_c/stdio.h>
//#include "../../rDebug/include/rdebug.h"
//#include "../../nflash/include/nflash.h"
#ifdef __WIN32__
#include "../../diskEmu/include/nfshEmu.h"
#else
#include "nflash/include/nflash.h"
#endif
#include "../include/FileSys.h"
#ifdef NAND_BACKUP_ON
//#define NAND_BACKUP_DEBUG
#define NAND_FLASH_SIZE 524288 // size of the NAND flash
#define NAND_BACKUP_FILENAME_LEN 114 // max length of a complete pathname
#define NAND_BLOCK_SIZE 4096 // block size
#define NAND_INDEX_BLOCK_NUM 1 // the first block is used for storing index
#define NAND_FIRST_INDEX_ENTRY 1 // the 1st index entry is used to keep general backup info
#define NAND_BACKUP_DIR_NUM 2 // there are two target directories
struct backupRecord
{
unsigned char filename[NAND_BACKUP_FILENAME_LEN];
unsigned char attribute;
unsigned char reserved;
// unsigned long timeInSecond;
unsigned long fsize;
int startingFrame;
int frameNum;
};
struct NAND_region
{
int startingBlock;
int blockNum;
};
static unsigned char TargetDir[NAND_BACKUP_DIR_NUM][20] = {
"A:\\PIM\\CONTACT",
"A:\\PIM\\MEMO"
};
static unsigned char BlockPercentage[NAND_BACKUP_DIR_NUM] = { 80, 20 };
static unsigned long LastBackupTime = 0;
//static unsigned int LastBackupFileNum = 0;
//short IndexEntryNum = 0;
static struct backupRecord *IndexBuffer = NULL;
static short FramesPerBlock = 0;
#ifdef NAND_BACKUP_DEBUG
char NANDBackupDebugString[80];
#endif
static void readBlock(int block, unsigned char *buf);
static void writeBlock(int block, unsigned char *buf);
static int compareName(unsigned char *name1, unsigned char *name2);
static int compareDir(unsigned char *filename, unsigned char *dirname);
static int checkNeedBackupFile(unsigned char *filename);
static int checkNeedBackupDir(int dirNO);
static int checkNeedRestoreDir(int dirNO);
static int blocksNeededToBackupDir(int dirNO);
static int initBackup(void);
static void endBackup(short update);
static void clearRegion(struct NAND_region *region);
static int backupFile(unsigned char *filename, int toFrame);
static int backupDir(int dirNO, struct NAND_region *region);
static int restoreFile(struct backupRecord *entry);
static int restoreDir(int dirNO);
/*************************************************************
Function: readEntry
Description:
Read the specified entry in the index block
Input:
entryNO - the specified index (starts from 0)
buf - the buffer to hold the index entry
**************************************************************/
/*
static void readEntry(int entryNO, unsigned char *buf)
{
int i;
int offset;
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, "[readEntry] entryNO=%d", entryNO);
SprintStringLn(NANDBackupDebugString);
#endif
offset = entryNO * sizeof(struct backupRecord);
for (i = 0; i < sizeof(struct backupRecord); i += NFLASH_FRAME_SIZE)
{
sc_disableInt();
nfshReadFrame(offset, buf);
sc_enableInt();
offset += NFLASH_FRAME_SIZE;
buf += NFLASH_FRAME_SIZE;
}
return;
}
*/
/*************************************************************
Function: readBlock
Description:
Read the specified block
Input:
block - the specified block
buf - the buffer to hold the block
**************************************************************/
static void readBlock(int block, unsigned char *buf)
{
int i;
unsigned long offset;
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, "[readBlock] block=%d", block);
SprintStringLn(NANDBackupDebugString);
#endif
offset = block * NAND_BLOCK_SIZE;
for (i = 0; i < NAND_BLOCK_SIZE; i += NFLASH_FRAME_SIZE)
{
sc_disableInt();
nfshReadFrame(offset, buf);
sc_enableInt();
offset += NFLASH_FRAME_SIZE;
buf += NFLASH_FRAME_SIZE;
}
return;
}
/*************************************************************
Function: writeBlock
Description:
Write the specified block
Input:
block - the specified block
buf - the buffer holding the block
**************************************************************/
static void writeBlock(int block, unsigned char *buf)
{
int i;
unsigned long offset;
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, "[writeBlock] block=%d", block);
SprintStringLn(NANDBackupDebugString);
#endif
offset = block * NAND_BLOCK_SIZE;
sc_disableInt();
nfshEraseBlock(offset);
sc_enableInt();
for (i = 0; i < NAND_BLOCK_SIZE; i += NFLASH_FRAME_SIZE)
{
sc_disableInt();
nfshProgramFrame(offset, buf);
sc_enableInt();
offset += NFLASH_FRAME_SIZE;
buf += NFLASH_FRAME_SIZE;
}
return;
}
/*************************************************************
Function: getLastBackupInfo
Description:
Get the last backup info (date, time, and file number)
from the index block.
Input:
idxBuf - the buffer holding the index block
Note:
The last backup info is stored in the first entry (entry
#0) in the index block.
**************************************************************/
/*
static void getLastBackupInfo(struct backupRecord *idxBuf)
{
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, "[getLastBackupInfo]");
SprintStringLn(NANDBackupDebugString);
#endif
LastBackupTime = idxBuf->timeInSecond;
LastBackupFileNum = idxBuf->fsize;
if (LastBackupTime == 0xFFFFFFFF || LastBackupFileNum == 0xFFFFFFFF)
{
// never do backup before, set all to 0
LastBackupTime = 0;
LastBackupFileNum = 0;
}
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, " Last backup time =%d, number of files=%d", LastBackupTime, LastBackupFileNum);
SprintStringLn(NANDBackupDebugString);
#endif
return;
}
*/
/*************************************************************
Function: compareName
Description:
compare names
Input:
name1 - filename 1
name2 - filename 2
Return value:
1 filenames match
0 filenames unmatch
**************************************************************/
static int compareName(unsigned char *name1, unsigned char *name2)
{
int i;
for (i = 0; i < NAND_BACKUP_FILENAME_LEN; i++)
{
if ((name1[i] == 0xFF || name1[i] == 0x0) && (name2[i] == 0xFF || name2[i] == 0x0))
{
// both filenames reach the ends of the strings, they match
return 1;
}
if (iCompareChar(name1[i], name2[i]) == 0)
{
// filenames unmatch
return 0;
}
}
if (name1[i] == '\0')
{
return 1;
}
else
{
return 0;
}
}
/*************************************************************
Function: compareDir
Description:
Check if the file is within a directory
Input:
filename - the filename
dirname - the DIR name
Return value:
1 filename in the dir
0 filename not in the dir
**************************************************************/
static int compareDir(unsigned char *filename, unsigned char *dirname)
{
int i;
for (i = 0; i < NAND_BACKUP_FILENAME_LEN; i++)
{
if ((dirname[i] == 0xFF || dirname[i] == 0x0) || (filename[i] == 0xFF || filename[i] == 0x0))
{
break;
}
if (iCompareChar(filename[i], dirname[i]) == 0)
{
// filenames unmatch
return 0;
}
}
if (dirname[i] == 0x0 || dirname[i] == 0xFF)
{
// the end of string of dirname has been reached,
// there is chance that the filename is within the dir
if (filename[i] == 0x0 || filename[i] == 0xFF)
{
// end of string of filename has been reached, file not in dir
return 0;
}
if (filename[i] != '\\' && filename[i] != '/')
{
// not a dir separator, the names actually mismatch
return 0;
}
i++; // skip the dir separator
while (filename[i] != 0x0 && filename[i] != 0xFF)
{
if (filename[i] == '\\' || filename[i] == '/')
return 0; // there is another dir level, file not in dir
i++;
}
return 1;
}
else
{
// end of string of dirname not yet reached but that of the filename has been reached
// file not in dir
return 0;
}
}
/*************************************************************
Function: checkNeedBackupFile
Description:
Check the backup to see if the specified file needs
backup.
Input:
filename - the specified file
Return value:
1 backup needed
0 backup not needed
-1 system error
**************************************************************/
static int checkNeedBackupFile(unsigned char *filename)
{
struct _stat fileStat;
struct backupRecord *entry;
int result;
int i;
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, "[checkNeedBackupFile] %s", filename);
SprintStringLn(NANDBackupDebugString);
#endif
/*
entry = (struct backupRecord *)ap_malloc(sizeof(struct backupRecord));
if (entry == NULL)
{
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, " memory allocation error!");
SprintStringLn(NANDBackupDebugString);
#endif
return -1;
}
*/
// get the stat of the file
if (stat(filename, &fileStat) == -1)
{
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, " file not found!");
SprintStringLn(NANDBackupDebugString);
#endif
// ap_free(entry);
return -1;
}
result = 1;
// check the entries in the 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 (compareName(filename, entry->filename) == 1)
{
// names are matched
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, " file found!");
SprintStringLn(NANDBackupDebugString);
#endif
// check size and time
if (fileStat.st_size == entry->fsize && fileStat.st_mtime <= LastBackupTime)
{
// size not change and the file time is older than backup time
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, " backup not needed!");
SprintStringLn(NANDBackupDebugString);
#endif
result = 0;
break;
}
else
{
// size changed or the file time is newer
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, " backup needed!");
SprintStringLn(NANDBackupDebugString);
#endif
result = 1;
break;
}
}
}
return result;
}
/*************************************************************
Function: checkNeedBackupDir
Description:
Check if the backup of the specified target DIR contains
the most recent file content.
Input:
dirNO - the target DIR no (index in TargetDir[])
Return value:
1 backup is old, new backup may be needed
0 backup is latest, new backup not necessary
-1 function failed - memory allocation error
**************************************************************/
static int checkNeedBackupDir(int dirNO)
{
unsigned char *srcFile;
int srcIndex;
int i;
int needBackup;
struct ffblk ffresult;
#ifdef NAND_BACKUP_DEBUG
sprintf(NANDBackupDebugString, "[checkNeedBackupDir] (%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++;
}
srcIndex = i;
srcFile[i++] = '*';
srcFile[i] = '\0';
needBackup = 0;
if (findfirst(srcFile, &ffresult, 0) == 0)
{
do
{
// file found, get the real filename
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -