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

📄 nandfile.424

📁 PDA上的CF CARD 文件系统的建立程式
💻 424
📖 第 1 页 / 共 4 页
字号:
/*************************************************************
File Name: NANDFILE.C
Last Modified Date: 2001/03/21
Programmer: MSC
Compiler:
Platform:
Usage:
	File API for NAND FFS

Other Information:
**************************************************************/
#include <sys/syscall.h>
#include <ansi_c/stdio.h>

/**** added by chilong 01/19/2002 ****/
//#include "nflash/include/nflash.h"
#ifdef __WIN32__
#include "../../diskEmu/include/nfshEmu.h"
#else
#include "nflash/include/nflash.h"
#endif

/**** added by chilong 01/19/2002 ****/

//#include "../../rDebug/rdebug.h"
//#include "../../rDebug/include/rdebug.h"
#include "ffs_nand/include/FFS_NAND.h"
#include "ffs_nand/include/NANDfblk.h"
#include "ffs_nand/include/NANDlump.h"

//**************************** jason
#define FILE_COU 30
#define FILE_LEN 30
extern unsigned char dir_file[FILE_COU][FILE_LEN] ;
extern unsigned short file_index ;
extern unsigned short file_end ;

//********************************************* jason
#define ERROR_FILE_SYSTEM_NOT_INIT  	 0x90
#define ERROR_ALLOC_MEM			 0x91
#define ERROR_NO_HANDLE_AVAIL		 0x92
#define ERROR_DIR_ALREADY_EXIST		 0x93
#define ERROR_FILE_SYSTEM_NOT_INIT	 0x94
#define ERROR_INVALID_HANDLE		 0x95
#define ERROR_DIR_NOT_EXIST		 0x96
#define ERROR_FILE_NOT_EXIST		 0x97
#define ERROR_DIR_NOT_EMPTY		 0x98
#define ERROR_PATHNAME_TOO_LONG		 0x99
#define ERROR_WAIT_SEMAPHORE		 0xa0
#define ERROR_ALLOC_LUMP		 0xa1
#define ERROR_FILE_FLAG			 0xa2



//*********************************************

#ifdef NAND_FLASH_DISK_ID

struct NAND_FFS_FILE **NAND_FFS_HandleTable;
int NAND_FFS_CurrentHandle;

/* marked by chilong 01/25/2002
unsigned char *NAND_LumpBuf1;
unsigned char *NAND_LumpBuf2;
   marked by chilong 01/25/2002 */
   
extern unsigned long real_flash_block_num ;

// FFS_NAND.c
extern char NAND_FFS_Block[NAND_FFS_BLOCK_NUM];
extern int NAND_FFS_SemaphoreID;
extern int NAND_FFS_Init_OK;

/**** added by chilong 01/18/2002 ****/
extern int NAND_FFS_rootLumpNo;
/**** added by chilong 01/18/2002 ****/

/**** added by chilong 01/19/2002 ****/
extern char NAND_FFS_lumpMapTable[NAND_FFS_BLOCK_NUM * NAND_FLASH_BLOCK_SIZE / NAND_LUMP_SIZE / 8];
/**** added by chilong 01/19/2002 ****/

#ifdef NAND_FFS_USE_CACHE
  extern unsigned char *NAND_FFS_BlockCache[NAND_FFS_CACHE_BLOCK_NUM];
#endif

// NANDlump.c
extern unsigned long NAND_LumpNum;
extern unsigned long NAND_TotalLumpNum;

/**** added by chilong 12/24/2001 ****/
//char NAND_FFS_DebugString[80];
/**** added by chilong 12/24/2001 ****/

/*************************************************************
	External functions
 *************************************************************/
#ifndef __WIN32__
extern void memoryZero(void *source, unsigned int size);
#endif

extern struct dLinkList *tcbSearch(threadID searchID);



/*************************************************************
Function: NAND_FFS_open
Description:
	open an existing file in the simple flash storage system
Input:
	name	the target file
	flag	open flags
Output:
	file handle
	-1	failure
**************************************************************/
int NAND_FFS_open(unsigned char *name, int flag)
{

  int returnValue;

  if (NAND_FFS_Init_OK == FALSE)
  {
	NAND_FFS_Errno = ERROR_FILE_SYSTEM_NOT_INIT;
	return -1;
  }

  NAND_FFS_Errno = 0;

  sc_waitSemaphore(NAND_FFS_SemaphoreID);

  returnValue = NAND_FFS_open_r(name, flag);

  sc_signalSemaphore(NAND_FFS_SemaphoreID);

  return returnValue;
}

int NAND_FFS_open_r(unsigned char *string, int flag)
{
  struct NAND_FFS_FILE 	*pfile;
  int 			result;
  int 			availHandler;
  unsigned char		attrib;

/*  
#ifdef NAND_FFS_DEBUG
  struct NAND_diskLump *curLump;
  unsigned char *pData;
  int i;
#endif
*/
  // initialize the file's structure
  pfile = (struct NAND_FFS_FILE *)ap_malloc(sizeof(struct NAND_FFS_FILE));
  if (pfile == NULL)
  {
	NAND_FFS_Errno = ERROR_ALLOC_MEM;
	return -1;
  }
  memoryZero((void *)pfile, (unsigned int)sizeof(struct NAND_FFS_FILE));

  availHandler				= findFreeHandle();
  pfile->handle				= availHandler;
  NAND_FFS_HandleTable[availHandler] 	= pfile;

  if (availHandler == -1)
  {
	ap_free(pfile);

	NAND_FFS_Errno = ERROR_NO_HANDLE_AVAIL;

	return -1;
  }

  // initialize some values before searching the file
  pfile->subDirLumpNo = NAND_END_LUMP;
  pfile->nThDirEntry = NAND_END_LUMP;
  
  result = NAND_FFS_fileSearch(pfile, string);

  pfile->fileFlag = flag;
  
  // If the file does not exist, create it if O_CREATE is set
  if (result == -1)
  {
	if ((flag & O_CREATE) != O_CREATE)
	{
		// file not found and the O_CREATE flag is off
		ap_free(pfile);
		NAND_FFS_HandleTable[availHandler] = NULL;
		return -1;
	}
	else
	{
		attrib = DA_ARCHIVE;

		result = NAND_FFS_fileCreate(pfile, string, attrib);
		
		if (result == -1)
		{
			ap_free(pfile);
			NAND_FFS_HandleTable[availHandler] = NULL;
			return -1;
		}
	}
  }
  else
  {
	// name found, check if it is a file
	if (((pfile->dirEntry).attribute & DA_DIR) == DA_DIR)
	{
		// this is a directory, cannot open
		NAND_FFS_Errno = ERROR_DIR_ALREADY_EXIST;

		ap_free(pfile);
		NAND_FFS_HandleTable[availHandler] = NULL;
		return -1;
	}

	// file found, open it
	if ((flag & O_TRUNC) == O_TRUNC)
	{
		// truncate the file
		(pfile->dirEntry).fsize = 0;

		NAND_FFS_freeCurrentLumps(pfile->dirEntry.startLump);

		NAND_FFS_freeLumpLink(pfile->dirEntry.startLump);

		pfile->dirEntry.startLump = NAND_END_LUMP;
	}
	else if ((flag & O_APPEND) == O_APPEND)
		pfile->fpos = (pfile->dirEntry).fsize;
  }

  pfile->deviceID = NAND_FLASH_DISK_ID;
  pfile->currentLump = NAND_END_LUMP;
  pfile->ownerID = sc_getThreadID();
  pfile->fDupFromHandle = -1;
  
  return(availHandler);
}



/*************************************************************
Function: NAND_FFS_close
Description:
	close a file in the simple flash storage system
Input:
	handle	the target file handle
Output:
	0	no error
	-1	error
**************************************************************/
int NAND_FFS_close(int handle)
{
  if (NAND_FFS_Init_OK == FALSE)
  {
	NAND_FFS_Errno = ERROR_FILE_SYSTEM_NOT_INIT;
	return -1;
  }

  #ifdef NAND_FFS_DEBUG
	sprintf(NAND_FFS_DebugString, "[NAND_FFS_close] handle=%d, *handle=%d", handle, *((int *)NAND_FFS_HandleTable[handle]));
	SprintStringLn(NAND_FFS_DebugString);
  #endif

  if ((handle < 0) || (handle >= MAX_OPEN_FILE) || (NAND_FFS_HandleTable[handle] == NULL))
  {
	NAND_FFS_Errno = ERROR_INVALID_HANDLE;
	return -1;
  }

  if (NAND_FFS_HandleTable[handle]->deviceID != NAND_FLASH_DISK_ID)
  {
	NAND_FFS_Errno = ERROR_INVALID_DEVICE;
	return -1;
  }

  NAND_FFS_Errno = 0;

  sc_waitSemaphore(NAND_FFS_SemaphoreID);

  NAND_FFS_close_r(NAND_FFS_HandleTable[handle]);

  NAND_FFS_HandleTable[handle] = NULL;

  sc_signalSemaphore(NAND_FFS_SemaphoreID);

  return 0;
}


void NAND_FFS_close_r(struct NAND_FFS_FILE *pfile)
{
  #ifdef NAND_FFS_DEBUG
	#ifdef NAND_FFS_USE_CACHE
		NAND_FFS_showCacheStatus();
	#endif
  #endif

  #ifdef NAND_FFS_USE_CACHE
	#ifdef NAND_FFS_DEBUG
//		if (NAND_FFS_flushCacheByHandle(pfile->handle) == -1)
		if (NAND_FFS_flushAllCache() == -1)
		{
			sprintf(NAND_FFS_DebugString, "    flush failed! NAND_FFS_Errno=0x%x", NAND_FFS_Errno);
			SprintStringLn(NAND_FFS_DebugString);
		}
	#else
//		NAND_FFS_flushCacheByHandle(pfile->handle);
		NAND_FFS_flushAllCache();
	#endif
  #endif
	
  sc_free(pfile);

  return;
}

/*************************************************************
Function: NAND_FFS_remove
Description:
	delete an existing file
Input:
	dirname - full path name
Output:
	0:  Success
	-1: Failure
**************************************************************/
int NAND_FFS_remove(unsigned char *dirname)
{
  int status;

  if (NAND_FFS_Init_OK == FALSE)
  {
	NAND_FFS_Errno = ERROR_FILE_SYSTEM_NOT_INIT;
	return -1;
  }

  NAND_FFS_Errno = 0;
  
  sc_waitSemaphore(NAND_FFS_SemaphoreID);

  status = NAND_FFS_killEntry(dirname, 0);

  sc_signalSemaphore(NAND_FFS_SemaphoreID);

  return status;
}

int NAND_FFS_killEntry(unsigned char *dirname, unsigned char attribute)
{
  struct NAND_FFS_FILE *pfile;
  struct NAND_diskLump *curLump;
  struct NAND_directory *curEntry;
  int result;

#ifdef NAND_FFS_DEBUG
  sprintf(NAND_FFS_DebugString, "[NAND_FFS_killEntry] dirname: %s, attribute: %x", 
  	dirname, attribute);
  SprintString(NAND_FFS_DebugString);
#endif

  // initialize the file's structure
  pfile = (struct NAND_FFS_FILE *)ap_malloc(sizeof(struct NAND_FFS_FILE));
  if (pfile == NULL)
  {
	NAND_FFS_Errno = ERROR_ALLOC_MEM;
	return -1;
  }
  memoryZero((void *)pfile, (unsigned int)sizeof(struct NAND_FFS_FILE));

  // initialize some values before searching the file
  pfile->subDirLumpNo = NAND_END_LUMP;
  pfile->nThDirEntry = NAND_END_LUMP;
  
  result = NAND_FFS_fileSearch(pfile, dirname);

  if (result == 0)
  {
	// name found, check attribute (file or directory)
	if (attribute == DA_DIR)
	{
		// trying to rmdir, check the attribute of the entry
		if (((pfile->dirEntry).attribute & DA_DIR) == DA_DIR)
		{
			// the entry is actually a directory, check if it is empty
			if (NAND_FFS_isDirEmpty((pfile->dirEntry).startLump) != 0)
			{
			#ifdef NAND_FFS_DEBUG
				SprintStringLn("[NAND_FFS_killEntry]: pfile->Entry is not empty");
			#endif
				// not empty, can't remove
				NAND_FFS_Errno = ERROR_DIR_NOT_EMPTY;
				ap_free(pfile);
				result = -1;
			}
		}
		else
		{
		#ifdef NAND_FFS_DEBUG
			SprintStringLn("[NAND_FFS_killEntry]: pfile->Entry is not a dir");
		#endif
			// the entry is a file, it is not a directory!
			NAND_FFS_Errno = ERROR_DIR_NOT_EXIST;
			ap_free(pfile);
			result = -1;
		}
	}
	else
	{
		// trying to remove a file, check the attribute of the entry
		if (((pfile->dirEntry).attribute & DA_DIR) == DA_DIR)
		{
			// the entry is a directory, it is not a file!
			NAND_FFS_Errno = ERROR_FILE_NOT_EXIST;
			ap_free(pfile);
			result = -1;
		}

		// we can't remove the file if it's being open by another user
		if (NAND_FFS_isFileOpened(pfile) == 1)
		{
			// NAND_FFS_Errno = ERROR_FILE_NOT_EXIST;
			ap_free(pfile);
			result = -1;
			
		}
	}

	if (result == 0)
	{
		// no problem found, delete the entry
		printf("{Free Lump=%d}",(pfile->dirEntry).startLump);	// jason
		NAND_FFS_freeLumpLink((pfile->dirEntry).startLump);
		
		if (NAND_FFS_readLump(pfile->subDirLumpNo, (unsigned char**)&curLump) == -1)
		{
			ap_free(pfile);
			return -1;
		}
		curEntry = (struct NAND_directory *) ((unsigned long) curLump +
			sizeof(struct NAND_diskLump) + 
			pfile->nThDirEntry * sizeof(struct NAND_directory));
			
		curEntry->name[0] = DELETED_ENTRY;
		printf("{Sub Lump=%d}", pfile->subDirLumpNo);
		if (NAND_FFS_writeLump(pfile->subDirLumpNo, (unsigned char*)curLump) == -1)
		{
			ap_free(pfile);
			return -1;
		}
		
		NAND_FFS_Errno = 0;
	}
  }
  else
  {
	if (attribute == DA_DIR)
		NAND_FFS_Errno = ERROR_DIR_NOT_EXIST;
	else
		NAND_FFS_Errno = ERROR_FILE_NOT_EXIST;
  }

  ap_free(pfile);
  
  return result;
}

/*************************************************************
Function: NAND_FFS_isDirEmpty
Description:
	check if a directory is empty
Input:
	startBlock - the starting block of the directory
Output:
	0:  empty
	-1: not empty
**************************************************************/
int NAND_FFS_isDirEmpty(int startLumpNo)
{
  struct NAND_diskLump *curLump;
  struct NAND_directory *curEntry;
  long i;
  int curLumpNo;

#ifdef NAND_FFS_DEBUG
  sprintf(NAND_FFS_DebugString, "[NAND_FFS_isDirEmpty] startLumpNo: %d", startLumpNo);
  SprintStringLn(NAND_FFS_DebugString);
#endif

  curLumpNo = startLumpNo;
  
  if (NAND_checkLump(curLumpNo) == -1)
  {
	// invalid block location
	NAND_FFS_Errno = ERROR_FILE_SYSTEM;
	return -1;
  }

  if (NAND_FFS_readLump(curLumpNo, (unsigned char**)&curLump) == -1)
  	return -1;
  	
  for (;;)
  {
	curEntry = (struct NAND_directory *)((unsigned long)curLump + sizeof(struct NAND_diskLump));
	
	// compare the entries in this cluster
	for (i = 0; i < NAND_LUMP_SIZE; i += sizeof(struct NAND_directory))
	{
		if (curEntry->name[0] == NAND_FREE_ENTRY)
		{
			// it is a free entry, the end has been reached and nothing in this dir
			return 0;
		}

		if ((unsigned char)(curEntry->name[0]) != (unsigned char)DELETED_ENTRY)
		{
			// not deleted entry nor free entry ==> not empty
			return -1;
		}

	#ifdef NAND_FFS_DEBUG
		sprintf(NAND_FFS_DebugString, "[NAND_FFS_isDirEmtry] curEntry->name: %s", curEntry->name);
		SprintStringLn(NAND_FFS_DebugString);
	#endif
	
		curEntry = (struct NAND_directory *)((unsigned long)curEntry + sizeof(struct NAND_directory));
	}

	curLumpNo = curLump->nextLump;
	if (curLumpNo == NAND_END_LUMP)
		return 0;
		
	if (NAND_checkLump(curLumpNo) == -1)
	{
		// invalid block location
		NAND_FFS_Errno = ERROR_FILE_SYSTEM;
		return -1;
	}

  	if (NAND_FFS_readLump(curLumpNo, (unsigned char**)&curLump) == -1)
  		return -1;
  }

  return 0;
}

/*************************************************************
Function: NAND_FFS_isFileOpened
Description:
	check if the file is being opened above twice
Input:
	pfile
Output:
	1: open
	0: not open
**************************************************************/
int NAND_FFS_isFileOpened(struct NAND_FFS_FILE *pfile)
{
  int i;
  
  if (pfile == NULL)
  	return 0;
  	
  if (pfile->deviceID != NAND_FLASH_DISK_ID)
  	return 0;
  	
  for (i = 0; i < MAX_OPEN_FILE; i++)
  {
  	if (NAND_FFS_HandleTable[i] != NULL)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -