⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bak2nand.c

📁 PDA上的CF CARD 文件系统的建立程式
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************************************
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 + -