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

📄 bak2nand.c

📁 嵌入式系统中文件系统源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		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 + -