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

📄 bak2nand.c

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