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

📄 nandlump.c

📁 PDA上的CF CARD 文件系统的建立程式
💻 C
📖 第 1 页 / 共 3 页
字号:

/**** added by chilong 01/18/2002 ****/
int NAND_findFreeLump(void)
{
  int i;
  int result;

  #ifdef NAND_FFS_DEBUG
	sprintf(NAND_FFS_DebugString, "[NAND_findFreeLump]");
	SprintStringLn(NAND_FFS_DebugString);
  #endif

  for (i = 0; i < NAND_TotalLumpNum; i++)
  {
  	if( ((NAND_FFS_lumpMapTable[NAND_FFS_curFreeLumpNo/8] >> ((NAND_FFS_curFreeLumpNo)%8)) & 0x01) == 0x01)
  	{
  		/*
  		if ( (NAND_FFS_curFreeLumpNo+NAND_LumpNum) < NAND_TotalLumpNum)
  			NAND_FFS_curFreeLumpNo += NAND_LumpNum;
  		else
  			NAND_FFS_curFreeLumpNo = (NAND_FFS_curFreeLumpNo+1) % NAND_LumpNum;
  		*/  			

  		if ( (NAND_FFS_curFreeLumpNo+1) < NAND_TotalLumpNum)
  			NAND_FFS_curFreeLumpNo += 1;
  		else
  			NAND_FFS_curFreeLumpNo = 1;
  			
  		continue;
  	}
  	else
  	{
		if (NAND_readLumpStructure(NAND_FFS_curFreeLumpNo, 2) != NULL)
		{
			/* marked
			// set this lump "USED" in lumpMapTable
			result = NAND_FFS_curFreeLumpNo;
			NAND_FFS_lumpMapTable[NAND_FFS_curFreeLumpNo/8] |= (1 << (NAND_FFS_curFreeLumpNo%8));

	  		if ( (NAND_FFS_curFreeLumpNo+NAND_LumpNum) < NAND_TotalLumpNum)
  				NAND_FFS_curFreeLumpNo += NAND_LumpNum;
  			else
  				NAND_FFS_curFreeLumpNo = (NAND_FFS_curFreeLumpNo+1) % NAND_LumpNum;

			break;
  			*/
			// set this lump "USED" in lumpMapTable
			result = NAND_FFS_curFreeLumpNo;
			NAND_FFS_lumpMapTable[NAND_FFS_curFreeLumpNo/8] |= (1 << (NAND_FFS_curFreeLumpNo%8));

	  		if ( (NAND_FFS_curFreeLumpNo+1) < NAND_TotalLumpNum)
  				NAND_FFS_curFreeLumpNo += 1;
  			else
  				NAND_FFS_curFreeLumpNo = 1;
  				
			break;
		}
		else
		{
			/*
	  		if ( (NAND_FFS_curFreeLumpNo+NAND_LumpNum) < NAND_TotalLumpNum)
  				NAND_FFS_curFreeLumpNo += NAND_LumpNum;
  			else
  				NAND_FFS_curFreeLumpNo = (NAND_FFS_curFreeLumpNo+1) % NAND_LumpNum;
  			*/
	  		if ( (NAND_FFS_curFreeLumpNo+1) < NAND_TotalLumpNum)
  				NAND_FFS_curFreeLumpNo += 1;
  			else
  				NAND_FFS_curFreeLumpNo = 1;
		}
  	}
  }
  
  if (i == NAND_TotalLumpNum)
  {
  	NAND_FFS_Errno = ERROR_DISK_FULL;
  	return NAND_END_LUMP;
  }
  
  return result;
}
/**** added by chilong 01/18/2002 ****/


/* marked by chilong 01/18/2002
int NAND_findFreeLump(void)
{
  struct NAND_diskLump *lumpPtr = NULL;
  int block;
  int i;
  int result;
  int nthLumpEntry;

  #ifdef NAND_FFS_DEBUG
	sprintf(NAND_FFS_DebugString, "[NAND_findFreeLump]");
	SprintStringLn(NAND_FFS_DebugString);
  #endif

  block = NAND_FFS_findLeastErasedNonFullBlock(&nthLumpEntry);
  if (block != -1)
  {
	// this block has the least erase count and unoccupied lumps
	if (nthLumpEntry == NAND_LumpNum - 1)
		NAND_FFS_Block[block] = NAND_FB_FULL;

	// added by chilong 01/18/2002
	NAND_FFS_lumpMapTable[(block*NAND_LumpNum+nthLumpEntry)/8] |=
		1 << ((block*NAND_LumpNum+nthLumpEntry)%8);
		
	// added by chilong 01/18/2002
	
	return (NAND_LumpNum * block + nthLumpEntry);	// first free lump in the block
  }

  // no empty lump found
  // the block is full
//  NAND_FFS_EraseCount[block] = NAND_FFS_EraseCount[block] | NAND_BLOCK_FULL_BIT_MASK;
  NAND_FFS_Block[block] = NAND_FB_FULL;

  #ifdef NAND_FFS_DEBUG
	sprintf(NAND_FFS_DebugString, "    no free lump!");
	SprintStringLn(NAND_FFS_DebugString);
  #endif

  NAND_FFS_Errno = ERROR_DISK_FULL;
  return NAND_END_LUMP;
}
   marked by chilong 01/18/2002 */

/*************************************************************
Function: NAND_findFreeLumpByAdjLump
Description:
	find a free lump in the same block as the specific lump
Input:
	lump - the specific lump
Output:
	the lump number
	NAND_END_LUMP if not found
**************************************************************/
/* marked by chilong 12/20/2001 temporarily

int NAND_findFreeLumpByAdjLump(int lump)
{
  int block;
  int nThEntry;
  struct NAND_diskLump *lumpPtr;
  int i;
  int result;

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

  // if a block can only hold one lump, there is no adjacent lump
  if (NAND_LumpNum <= 1)
	return NAND_END_LUMP;

  // find the flash block in which the specific lump resides
  NAND_lump2Block(lump, &block, &nThEntry);
  if (block == -1 || nThEntry == -1)
  {
	// errno set by NAND_lump2Block()
	return NAND_END_LUMP;
  }

  // read the block into buffer
  if (NAND_FFS_readBlock(block, (unsigned char **)&lumpPtr) == -1)
  {
	#ifdef NAND_FFS_DEBUG
		sprintf(NAND_FFS_DebugString, "    block invalid");
		SprintStringLn(NAND_FFS_DebugString);
	#endif

	// errno set by NAND_FFS_readBlock()
	return NAND_END_LUMP;
  }

  if (lumpPtr == NULL)
  {
	NAND_FFS_Errno = ERROR_FLASH_BLOCK_READ;
	return NAND_END_LUMP;
  }

  // check the lumps in the block
  for (i = 0; i < NAND_LumpNum; i++)
  {
	if (lumpPtr->type == NAND_LUMP_TYPE_FREE)
	{
		result = block * NAND_LumpNum + i;

		#ifdef NAND_FFS_DEBUG
			sprintf(NAND_FFS_DebugString, "    free lump = %d", result);
			SprintStringLn(NAND_FFS_DebugString);
		#endif

		if (i >= (NAND_LumpNum - 1))
		{
			// the last lump in the block => block will be full
//			NAND_FFS_EraseCount[block] = NAND_FFS_EraseCount[block] | NAND_BLOCK_FULL_BIT_MASK;
			NAND_FFS_Block[block] = NAND_FB_FULL;
		}

		return result;
	}

	lumpPtr = (struct NAND_diskLump *)((unsigned long)lumpPtr + NAND_LUMP_SIZE);
  }

  // the block is full
//  NAND_FFS_EraseCount[block] = NAND_FFS_EraseCount[block] | NAND_BLOCK_FULL_BIT_MASK;
  NAND_FFS_Block[block] = NAND_FB_FULL;

  #ifdef NAND_FFS_DEBUG
	sprintf(NAND_FFS_DebugString, "    no adjacent free lump");
	SprintStringLn(NAND_FFS_DebugString);
  #endif

  return NAND_END_LUMP;
}
   marked by chilong 12/20/2001 temporarily */



/*************************************************************
Function: NAND_checkLumpNum
Description:
	check if the lump address is valid
Input:
	lump - the specific lump
Output:
	0	lump ok
	-1	lump invalid
**************************************************************/
/* marked by chilong 12/20/2001 temporarily

int NAND_checkLumpNum(int lump)
{
  int block;

  if (lump == -1)
	return -1;

  // find the block holding this lump and the entry number of this lump in the block
  block = lump / NAND_LumpNum;

  // check if the block is valid
  // if there is error, errno will be set by NAND_FFS_checkBlock()
  return (NAND_FFS_checkBlock(block));
}
   marked by chilong 12/20/2001 temporarily */



/*************************************************************
Function: NAND_lump2Block
Description:
	convert lump to block and entry
Input:
	lump - the specific lump
Output:
	block		the block number
	nthEntry	the entry number in the block
	both equal to -1 if error
**************************************************************/

void NAND_lump2Block(int lump, int *block, int *nthEntry)
{
  *block = lump / NAND_LumpNum;
  *nthEntry = lump % NAND_LumpNum;

  // check if the block is valid
  if (NAND_FFS_checkBlock(*block) == -1)
  {
	*block = -1;
	*nthEntry = -1;
	// errno set by NAND_FFS_checkBlock()
	return;
  }

  return;
}



/*************************************************************
Function: NAND_readLumpStructure
Description:
	read the data structure of a lump
Input:
	lump - the specific lump
	lumpType - 0 = get any lump
		   1 = get only the starting lump
		   2 = get only the free lump
Output:
	the pointer to the lump structure
Note:
	If the lump is in cache, the cache content is used.
	If the lump is not in cache, the corresponding frames
	are read from flash and the cache is kept inact.
**************************************************************/
struct NAND_diskLump *NAND_readLumpStructure(int lump, int lumpType)
{
  int frameNum;
  int i;
  int block;
  int nthEntry;
  struct NAND_diskLump *base = NULL;
  unsigned char *status;
  int frame;
  #ifdef NAND_FFS_USE_CACHE
	int cacheNum;
  #endif

  /**** added by chilong 01/18/2002 ****/
  if (NAND_checkLump(lump) == -1)
	return NULL;
  /**** added by chilong 01/18/2002 ****/
  
  NAND_lump2Block(lump, &block, &nthEntry);
  if (block == -1 || nthEntry == -1)
  {
	// errno set by NAND_lump2Block()
	return NULL;
  }

  #ifdef NAND_FFS_USE_CACHE
  	///* marked by chilong 01/25/2002
	cacheNum = NAND_FFS_searchBlockInCache(block);
	if (cacheNum != -1)
	{
		base = (struct NAND_diskLump *)((unsigned long)NAND_FFS_BlockCache[cacheNum] + nthEntry * NAND_LUMP_SIZE);
		// check lump type
		switch (lumpType)
		{
			//
			//case 1:
			//	if (base->type != NAND_LUMP_TYPE_START)
			//		return NULL;
			//	break;
			//
			case 2:
				if (base->type != NAND_LUMP_TYPE_FREE)
					return NULL;
				break;
			default:
				break;
		}

		return base;
	}
	//   marked by chilong 01/25/2002 */
	   
	/* marked by chilong 01/25/2002
  	#ifdef NAND_FFS_CACHE_DEBUG
		cacheNum = NAND_FFS_putBlockInCache(block, 1, 1);
	#else
		cacheNum = NAND_FFS_putBlockInCache(block, 1);
	#endif
	if (cacheNum != -1)
	{
		base = (struct NAND_diskLump *)((unsigned long)NAND_FFS_BlockCache[cacheNum] + nthEntry * NAND_LUMP_SIZE);
		// check lump type
		switch (lumpType)
		{
			//
			//case 1:
			//	if (base->type != NAND_LUMP_TYPE_START)
			//		return NULL;
			//	break;
			//
			case 2:
				if (base->type != NAND_LUMP_TYPE_FREE)
					return NULL;
				break;
			default:
				break;
		}

		return base;
	}
	else
	{
		// unknown error
		return NULL;
	}
	   marked by chilong 01/25/2002 */
  #endif

  frameNum = ( (sizeof(struct NAND_diskLump) - 1) / NFLASH_FRAME_SIZE) + 1;
  //frame = lump * NAND_LUMP_SIZE / NFLASH_FRAME_SIZE;
  
  frame = (NAND_FFS_START_BLOCK*NAND_FLASH_BLOCK_SIZE + lump*NAND_LUMP_SIZE) / NFLASH_FRAME_SIZE;
  
  /**** modified by chilong 01/15/2002 ****/  
  // chilong: we point "base" to NAND_FlashAccessBuffer2 because
  // 	we collaborate this function with NAND_findfreeLump()
  //	in NAND_FFS_write_r()
  status = NAND_FlashAccessBuffer2;
  base = (struct NAND_diskLump *)NAND_FlashAccessBuffer2;
  /**** modified by chilong 01/15/2002 ****/  
  for (i = 0; i < frameNum; i++)
  {
	#ifdef NAND_FFS_DEBUG
		sprintf(NAND_FFS_DebugString, "Read frame %d", frame);
		SprintStringLn(NAND_FFS_DebugString);
	#endif

	if (NAND_FFS_fshFrameRead(frame, status) == -1)
	{
		#ifdef NAND_FFS_DEBUG
			sprintf(NAND_FFS_DebugString, "Read frame %d failed!", frame);
			SprintStringLn(NAND_FFS_DebugString);
		#endif
		NAND_FFS_Errno = ERROR_FRAME_READ;
		return NULL;
	}

	// check lump type
	switch (lumpType)
	{
		/* marked by chilong 12/24/2001 
		case 1:
			if (base->type != NAND_LUMP_TYPE_START)
				return NULL;
			break;
		   marked by chilong 12/24/2001 */
		case 2:
			if (base->type != NAND_LUMP_TYPE_FREE)
				return NULL;
			else
				return base;
			break;
		default:
			break;
	}

	frame++;
	status += NFLASH_FRAME_SIZE;
  }

  return base;
}

/**** added by chilong 01/12/2002 ****/
/*************************************************************
Function: NAND_checkLump
Description:
	check if the lump address is valid
Input:
	lump - the specific lump
Output:
	1	lump address ok
	0	lump address out of bound
**************************************************************/
int NAND_checkLump(int lumpNo)
{
  int block, nThEntry;
  
  /**** added by chilong 01/18/2002 ****/
  if (NAND_checkBadLump(lumpNo) == -1)
  {
  	/**** added by chilong 01/19/2002 ****/
  	NAND_FFS_lumpMapTable[lumpNo/8] |= (1 << (lumpNo % 8));
  	/**** added by chilong 01/19/2002 ****/
	return -1;
  }
  /**** added by chilong 01/18/2002 ****/

  // chilong: NAND_FFS_checkBlock is invoked insided NAND_lump2Block
  NAND_lump2Block(lumpNo, &block, &nThEntry);
  if (block == -1 || nThEntry == -1)
  {
	// errno set by NAND_lump2Block()
	return -1;
  }

  return 0;	
}

/**** added by chilong 01/12/2002 ****/

#endif	// #ifdef NAND_FLASH_DISK_ID


⌨️ 快捷键说明

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