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

📄 ffs_nand.c

📁 PDA上的CF CARD 文件系统的建立程式
💻 C
📖 第 1 页 / 共 2 页
字号:
/*************************************************************
File Name: FFS_NAND.C
Last Modified Date: 2001/03/20
Programmer: MSC
Compiler:
Platform:
Usage:
	NAND Flash File System

Unfinished functions:
	NAND_FFS_scanDisk()
	NAND_FFS_defrag()
**************************************************************/
#include <sys/syscall.h>
//#include "../../rDebug/rdebug.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/FFS_NAND.h"
#include "../include/NANDfblk.h"
#include "../include/NANDLump.h"

#ifdef NAND_FLASH_DISK_ID

#ifdef NAND_FFS_DEBUG

#ifdef __WIN32__
#include <stdio.h>
#else
#include <ansi_c/stdio.h>
#endif

#endif

// the block map
//	0 = cannot be used by FFS
//	1 = free flash block
//	2 = allocated flash block
char NAND_FFS_Block[NAND_FFS_BLOCK_NUM];

//#ifdef __WIN32__
unsigned char	pNandFSSCacheBaseAddr[16*16384+16*20];
//#endif

/**** added by chilong 01/18/2002 ****/
char NAND_FFS_lumpMapTable[NAND_FFS_BLOCK_NUM * NAND_FLASH_BLOCK_SIZE / NAND_LUMP_SIZE / 8];
int NAND_FFS_rootLumpNo;
int NAND_FFS_curFreeLumpNo = NAND_FLASH_BLOCK_SIZE / NAND_LUMP_SIZE;
/**** added by chilong 01/18/2002 ****/

// read counts for the flash blocks
unsigned long *NAND_FFS_ReadCount;
// erase counts for the flash blocks
// this counter also use to indicate whether a block is full
// if the block full bit of the count is 1, the block is full.
unsigned long *NAND_FFS_EraseCount;
// program counts for the flash blocks
unsigned long *NAND_FFS_ProgramCount;

//int FFS_FreeBegin = NAND_FFS_START_BLOCK;

// semaphore to serialize FFS accesses
int NAND_FFS_SemaphoreID;
int NAND_FFS_Init_OK = FALSE;
int NAND_FFS_Errno;

// marked by chilong 01/14/2002
//unsigned char *NAND_FlashAccessBuffer;

/**** added by chilong 01/14/2002 ****/
unsigned char *NAND_FlashAccessBuffer1;
unsigned char *NAND_FlashAccessBuffer2;
/**** added by chilong 01/14/2002 ****/

#ifdef NAND_FFS_USE_CACHE
  // cache info
//  struct NAND_FFS_cacheInfo *NAND_FFS_CacheStatus[NAND_FFS_CACHE_BLOCK_NUM];
//  unsigned char *NAND_FFS_BlockCache[NAND_FFS_CACHE_BLOCK_NUM];
  struct NAND_FFS_cacheInfo **NAND_FFS_CacheStatus;
  unsigned char **NAND_FFS_BlockCache;
#endif

/*
// location of flash erase and program function in RAM
NAND_readFun NAND_FFS_read;		// function pointer to the flash sector read function in RAM
NAND_eraseFun NAND_FFS_erase;		// function pointer to the flash sector erase function in RAM
NAND_programFun NAND_FFS_program;	// function pointer to the flash sector program function in RAM
*/


// FileSys.c
//extern short *FileSysHandleTable[MAX_OPEN_FILE];
extern short **FileSysHandleTable;

// NANDfile.c
extern struct NAND_FFS_FILE **NAND_FFS_HandleTable;
extern int NAND_FFS_CurrentHandle;


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

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

// jason define
unsigned long real_flash_block_num ;


/*************************************************************
Function: NAND_FFS_init
Description:
	initialize the simple flash storage system
Input:
Output:
	0	SUCCESS
	-1	FAILURE
**************************************************************/
int NAND_FFS_init(void)
{
  int i;
  
  struct NAND_diskLump *rootLump;
  int j;

#ifdef NAND_FFS_CACHE_DEBUG
  long begin, end;
#endif
    
//  unsigned long rdFuncSize, erFuncSize, prFuncSize;
//  int *src;
//  int *des;
//  unsigned short *bootStatus;
  #ifdef NAND_FFS_USE_CACHE
	unsigned long base;
  #endif

  #ifdef NAND_FFS_DEBUG
	sprintf(NAND_FFS_DebugString, "[NAND_FFS_init] NAND_FFS_Init_OK=%d", NAND_FFS_Init_OK);
	SprintStringLn(NAND_FFS_DebugString);
  #endif

  if (NAND_FFS_Init_OK == TRUE)
  {
	#ifdef NAND_FFS_DEBUG
		sprintf(NAND_FFS_DebugString, "    Flash disk already initialized");
		SprintStringLn(NAND_FFS_DebugString);
	#endif

	return 0;
  }

  // set the flash block map
  for (i = 0; i < NAND_FFS_BLOCK_NUM; i++)
	NAND_FFS_Block[i] = NAND_FB_OK;	// all blocks are usable and free


  // set parameters
  NAND_FFS_Init_OK = TRUE;

  // create a semaphore for NAND FFS
  NAND_FFS_SemaphoreID = sc_createSemaphore(1, 1);
  if (NAND_FFS_SemaphoreID == -1)
  {
	NAND_FFS_Init_OK = FALSE;
	NAND_FFS_Errno = ERROR_CREATE_SEMAPHORE;
	return -1;
  }

  // prepare the access counts
  NAND_FFS_ReadCount = (unsigned long *)sc_malloc(NAND_FFS_BLOCK_NUM * sizeof(unsigned long));
  if (NAND_FFS_ReadCount == NULL)
  {
	NAND_FFS_Init_OK = FALSE;
	sc_deleteSemaphore(NAND_FFS_SemaphoreID);
	NAND_FFS_Errno = ERROR_ALLOC_MEM;
	return -1;
  }
  memoryZero(NAND_FFS_ReadCount, NAND_FFS_BLOCK_NUM * sizeof(unsigned long));

  NAND_FFS_EraseCount = (unsigned long *)sc_malloc(NAND_FFS_BLOCK_NUM * sizeof(unsigned long));
  if (NAND_FFS_EraseCount == NULL)
  {
	sc_free(NAND_FFS_ReadCount);
	NAND_FFS_Init_OK = FALSE;
	sc_deleteSemaphore(NAND_FFS_SemaphoreID);
	NAND_FFS_Errno = ERROR_ALLOC_MEM;
	return -1;
  }
  memoryZero(NAND_FFS_EraseCount, NAND_FFS_BLOCK_NUM * sizeof(unsigned long));

  NAND_FFS_ProgramCount = (unsigned long *)sc_malloc(NAND_FFS_BLOCK_NUM * sizeof(unsigned long));
  if (NAND_FFS_ProgramCount == NULL)
  {
	sc_free(NAND_FFS_EraseCount);
	sc_free(NAND_FFS_ReadCount);
	NAND_FFS_Init_OK = FALSE;
	sc_deleteSemaphore(NAND_FFS_SemaphoreID);
	NAND_FFS_Errno = ERROR_ALLOC_MEM;
	return -1;
  }
  memoryZero(NAND_FFS_ProgramCount, NAND_FFS_BLOCK_NUM * sizeof(unsigned long));

  // set the file handle table
  NAND_FFS_HandleTable = (struct NAND_FFS_FILE **)FileSysHandleTable;
  NAND_FFS_CurrentHandle = -1;
	
  // initialize lump parameters
  NAND_initLump();
	
/*
  // load the erase and program functions into RAM
  rdFuncSize = (unsigned long)NAND_FFS_fshBlockErase - (unsigned long)NAND_FFS_fshBlockRead;
  erFuncSize = (unsigned long)NAND_FFS_fshBlockProgram - (unsigned long)NAND_FFS_fshBlockErase;
  prFuncSize = (unsigned long)NAND_FFS_fshDummy - (unsigned long)NAND_FFS_fshBlockProgram;

  #ifdef NAND_FFS_DEBUG
	sprintf(NAND_FFS_DebugString, "    read: %d; erase: %d; program: %d", rdFuncSize, erFuncSize, prFuncSize);
	SprintStringLn(NAND_FFS_DebugString);
  #endif

  rdFuncSize = (((rdFuncSize - 1) >> 2) + 1) << 2;
  erFuncSize = (((erFuncSize - 1) >> 2) + 1) << 2;
  prFuncSize = (((prFuncSize - 1) >> 2) + 1) << 2;

  #ifdef NAND_FFS_DEBUG
	sprintf(NAND_FFS_DebugString, "    read: %d; erase: %d; program: %d", rdFuncSize, erFuncSize, prFuncSize);
	SprintStringLn(NAND_FFS_DebugString);
  #endif

  NAND_FFS_erase = (NAND_eraseFun)sc_malloc(erFuncSize);
  if (NAND_FFS_erase == NULL)
  {
	NAND_FFS_Init_OK = FALSE;
	sc_free(NAND_FFS_EraseCount);
	sc_deleteSemaphore(NAND_FFS_SemaphoreID);

	NAND_FFS_Errno = ERROR_ALLOC_MEM;
	return -1;
  }

  NAND_FFS_program = (NAND_programFun)sc_malloc(prFuncSize);
  if (NAND_FFS_program == NULL)
  {
	NAND_FFS_Init_OK = FALSE;
	sc_free((void *)NAND_FFS_erase);
	sc_free(NAND_FFS_EraseCount);
	sc_deleteSemaphore(NAND_FFS_SemaphoreID);

	NAND_FFS_Errno = ERROR_ALLOC_MEM;
	return -1;
  }

  // copy erase function to RAM
  src = (int *)NOR_FFS_fshSectorErase;
  des = (int *)NAND_FFS_erase;
  for (i = 0; i < erFuncSize; i += sizeof(int))
	*des++ = *src++;

  // copy program function to RAM
  src = (int *)NOR_FFS_fshSectorProgram;
  des = (int *)NAND_FFS_program;
  for (i = 0; i < prFuncSize; i += sizeof(int))
	*des++ = *src++;
*/

  // setup the cache
  #ifdef NAND_FFS_USE_CACHE
	NAND_FFS_CacheStatus = (struct NAND_FFS_cacheInfo **)sc_malloc(NAND_FFS_CACHE_BLOCK_NUM * sizeof(struct NAND_FFS_cacheInfo *));
	if (NAND_FFS_CacheStatus == NULL)
	{
		sc_free(NAND_FFS_ProgramCount);
		sc_free(NAND_FFS_EraseCount);
		sc_free(NAND_FFS_ReadCount);
		NAND_FFS_Init_OK = FALSE;
		sc_deleteSemaphore(NAND_FFS_SemaphoreID);
		NAND_FFS_Errno = ERROR_ALLOC_MEM;
		return -1;
	}

	NAND_FFS_BlockCache = (unsigned char **)sc_malloc(NAND_FFS_CACHE_BLOCK_NUM * sizeof(unsigned char *));
	if (NAND_FFS_BlockCache == NULL)
	{
		sc_free(NAND_FFS_CacheStatus);
		sc_free(NAND_FFS_ProgramCount);
		sc_free(NAND_FFS_EraseCount);
		sc_free(NAND_FFS_ReadCount);
		NAND_FFS_Init_OK = FALSE;
		sc_deleteSemaphore(NAND_FFS_SemaphoreID);
		NAND_FFS_Errno = ERROR_ALLOC_MEM;
		return -1;
	}

	for (i = 0; i < NAND_FFS_CACHE_BLOCK_NUM; i++)
	{
		NAND_FFS_CacheStatus[i] = (struct NAND_FFS_cacheInfo *)(NAND_FFS_CACHE_BASE_ADDRESS + i * sizeof(struct NAND_FFS_cacheInfo));
      	//memset(NAND_FFS_CacheStatus[i], 0xff, sizeof(struct NAND_FFS_cacheInfo));
		memoryZero(NAND_FFS_CacheStatus[i], sizeof(struct NAND_FFS_cacheInfo));
	}                                                                          
                                                                                 
	base = NAND_FFS_CACHE_BASE_ADDRESS + NAND_FFS_CACHE_BLOCK_NUM * sizeof(struct NAND_FFS_cacheInfo);
	for (i = 0; i < NAND_FFS_CACHE_BLOCK_NUM; i++)
	{
		NAND_FFS_BlockCache[i] = (unsigned char *)(base + i * NAND_FLASH_BLOCK_SIZE);
		//memset(NAND_FFS_BlockCache[i], 0xff, NAND_FLASH_BLOCK_SIZE);
		memoryZero(NAND_FFS_BlockCache[i], NAND_FLASH_BLOCK_SIZE);
	}
        
	//memset((void *)NAND_FFS_CACHE_BASE_ADDRESS, 0xff, (16*16*1024+16*20));

	#ifdef NAND_FFS_DEBUG
		NAND_FFS_showCacheStatusAddress();
		NAND_FFS_showCacheAddress();
	#endif

	// vertify the cache if warm boot
	// if (queryHWStatus() == COLD_RESET)
#ifndef __WIN32__           // by zhang xue ping	
	if (queryHWStatus() == COLD_RESET)
#else
	if(1)
#endif
		
	{
		// cold reset, clear the cache
		NAND_FFS_clearAllCache();
	}
	else
	{
		// warm reset, vertify the cache
		for (i = 0; i < NAND_FFS_CACHE_BLOCK_NUM; i++)
		{
//			#ifdef NAND_FFS_DEBUG
//				sprintf(NAND_FFS_DebugString, "    verify cache %d", i);
//				SprintStringLn(NAND_FFS_DebugString);
//			#endif

			if (NAND_FFS_vertifyCache(i) == -1)
			{
				// cache content incorrect, clear the cache
				NAND_FFS_clearCache(i);
			}
			else
			{
				// cache content ok, flush the cache	
				if (NAND_FFS_flushCache(i) == -1)
				{
					// flush failed, clear the cache
					NAND_FFS_clearCache(i);
				}

				// clear the last modification timestamp
				NAND_FFS_CacheStatus[i]->lastModTime = 0;
				NAND_FFS_CacheStatus[i]->handle = -1;
			}
		}
	}
  #endif

  NAND_FlashAccessBuffer1 = (unsigned char *)sc_malloc(NAND_FLASH_BLOCK_SIZE);
  if (NAND_FlashAccessBuffer1 == NULL)
  {
	NAND_FFS_Init_OK = FALSE;
	#ifdef NAND_FFS_USE_CACHE
		sc_free(NAND_FFS_BlockCache);
		sc_free(NAND_FFS_CacheStatus);
	#endif
	sc_free(NAND_FFS_ProgramCount);
	sc_free(NAND_FFS_EraseCount);
	sc_free(NAND_FFS_ReadCount);
	sc_deleteSemaphore(NAND_FFS_SemaphoreID);

	NAND_FFS_Errno = ERROR_ALLOC_MEM;
	return -1;
  }
  
  NAND_FlashAccessBuffer2 = (unsigned char *)sc_malloc(NAND_FLASH_BLOCK_SIZE);
  if (NAND_FlashAccessBuffer2 == NULL)
  {
	NAND_FFS_Init_OK = FALSE;
	#ifdef NAND_FFS_USE_CACHE
		sc_free(NAND_FFS_BlockCache);
		sc_free(NAND_FFS_CacheStatus);
	#endif
	sc_free(NAND_FFS_ProgramCount);
	sc_free(NAND_FFS_EraseCount);
	sc_free(NAND_FFS_ReadCount);
	
	sc_free(NAND_FlashAccessBuffer1);
	sc_deleteSemaphore(NAND_FFS_SemaphoreID);

	NAND_FFS_Errno = ERROR_ALLOC_MEM;
	return -1;
  }
	
/* marked by chilong 01/25/2002 
  NAND_LumpBuf1 = (unsigned char *)sc_malloc(NAND_LUMP_SIZE);
  if (NAND_LumpBuf1 == NULL)
  {
	NAND_FFS_Init_OK = FALSE;

	sc_free(NAND_FlashAccessBuffer1);
	sc_free(NAND_FlashAccessBuffer2);
	
	#ifdef NAND_FFS_USE_CACHE
		sc_free(NAND_FFS_BlockCache);
		sc_free(NAND_FFS_CacheStatus);
	#endif
	sc_free(NAND_FFS_ProgramCount);
	sc_free(NAND_FFS_EraseCount);
	sc_free(NAND_FFS_ReadCount);
	sc_deleteSemaphore(NAND_FFS_SemaphoreID);

	NAND_FFS_Errno = ERROR_ALLOC_MEM;
	return -1;
  }

  NAND_LumpBuf2 = (unsigned char *)sc_malloc(NAND_LUMP_SIZE);
  if (NAND_LumpBuf2 == NULL)
  {
	NAND_FFS_Init_OK = FALSE;
	sc_free(NAND_LumpBuf1);
	
	sc_free(NAND_FlashAccessBuffer1);
	sc_free(NAND_FlashAccessBuffer2);
	
	#ifdef NAND_FFS_USE_CACHE
		sc_free(NAND_FFS_BlockCache);
		sc_free(NAND_FFS_CacheStatus);
	#endif
	sc_free(NAND_FFS_ProgramCount);
	sc_free(NAND_FFS_EraseCount);
	sc_free(NAND_FFS_ReadCount);
	sc_deleteSemaphore(NAND_FFS_SemaphoreID);

	NAND_FFS_Errno = ERROR_ALLOC_MEM;
	return -1;
  }
    marekd by chilong 01/25/2002 */  
/*
  #ifdef NAND_FFS_DEBUG

⌨️ 快捷键说明

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