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

📄 structuremanager.c

📁 Nand Flash Translation Layer 用于nandflash的操作。 bad block memory map garbage collection average er
💻 C
📖 第 1 页 / 共 4 页
字号:
{
	if (Root == NULL)
	{
		return SUCCESS;
	}
	OS_DRIVER_Free(Root); 
	return SUCCESS;
}




/***********************  ResolveConflict ***************************
*   																*
* Resolve the Conflict, that is two Root with same Virtual Block	 *
*-------------------------------------------------------------------*
*   																*
*   																*
*	PARAMETER:  													* 
*   		   ConflictPhyBlockNum: is the physical Block Number	 *
*   								 of block that has happens the  *   								 
*   								  conflict  					*
*      			Node : Root involving in the Conflict			  	*
*	return values:													*
*																	*
*				SUCCESS:no problems is occurred 		   			*
*				FAILURE:the operation is failed 			 		*
*********************************************************************/


NFTL_Return ResolveConflict(void **Node, UINT16 ConflictPhyBlockNum)
{
	UINT16 ErasePhyBlockNum, PhysicalBlockNumber;
	UINT8 SpareBuffer[BUFFER_SPARE_SIZE], ConfSpareBuffer[BUFFER_SPARE_SIZE];
	UINT16 ConfCouter, Counter, NumPageW, ConfNumPageW, i;
	UINT16 NumOfPagePerPhysicalBlock;
	UINT8 flag = 0;

	//Assign a value at NumberOfPagePerPhysicalBlock necessary to calculate Physical Page Address
	NumOfPagePerPhysicalBlock = (32) * (512 /
		CHUNK_DATA_SIZE);

	if (*Node == NULL)
	{
		return FAILURE;
	}


	//initialize 
	NumPageW = 0;
	ConfNumPageW = 0;
	OS_MemSet(SpareBuffer,0xFF,BUFFER_SPARE_SIZE);
	OS_MemSet(ConfSpareBuffer,0xFF,BUFFER_SPARE_SIZE);
	Counter = 0;
	ConfCouter = 0;


	PhysicalBlockNumber = ((TreeNode *) *Node)->PhysicalBlockNumber1;

	//read first spare area of Root PhysicalBlockNumber
	ReadSpare528(PhysicalBlockNumber,0,SpareBuffer);

	//Counter of Root
	Counter = (SpareBuffer[ROOT_COUNTER_BYTE]);

	//check if the first page is written
	if (SpareBuffer[PAGE_STATUS_BYTE] != ALL_ONE)
	{
		NumPageW++;
	}

	ReadSpare528(ConflictPhyBlockNum,0,ConfSpareBuffer);


	//counter of Root that create an Conflict
	ConfCouter = (ConfSpareBuffer[ROOT_COUNTER_BYTE]);

	//check if the first page is written
	if (ConfSpareBuffer[PAGE_STATUS_BYTE] != ALL_ONE)
	{
		ConfNumPageW++;
	}

	//calculate the number of page written 
	for (i = 1; i < NumOfPagePerPhysicalBlock; i++)
	{
		ReadSpare528(ConflictPhyBlockNum,(unsigned char) i,ConfSpareBuffer) ;


		if (ConfSpareBuffer[PAGE_STATUS_BYTE] != ALL_ONE)
		{
			ConfNumPageW++;
		}
		else
		{
			break;
		}
	}

	//calculate the number of page written 
	for (i = 1; i < NumOfPagePerPhysicalBlock; i++)
	{
		ReadSpare528(PhysicalBlockNumber,(unsigned char) i,SpareBuffer);

		if (SpareBuffer[PAGE_STATUS_BYTE] != ALL_ONE)
		{
			NumPageW++;
		}
		else
		{
			break;
		}
	}


	if ((ConfCouter == 255) && (Counter == 0))
	{
		ConfCouter = 0;
		Counter = 1;
	}   


	if ((ConfCouter == 0) && (Counter == 255))
	{
		ConfCouter = 1;
		Counter = 0;
	}   



	//manage of conflict

	if (ConfCouter > Counter)
	{
		if (ConfNumPageW == NumPageW)
		{
			//erase the leaft Left   
			if (EraseLeafStructure(Node) == FAILURE)
			{
				return FAILURE;
			} 
			flag = 0 ;
			//ErasePhyBlockNum = ((TreeNode *) *Node)->PhysicalBlockNumber1;
			((TreeNode *) *Node)->PhysicalBlockNumber1 = ConflictPhyBlockNum;
		}//end if( ConfNumPageW == NumPageW)  

		else
		{
			//ConfNumPageW < NumPageW
			//erase block of rootConflict
			flag = 1 ;
			ErasePhyBlockNum = ConflictPhyBlockNum;
		}
	} //endif if(ConfCouter > Couter)

	else
	{
		if (ConfNumPageW == NumPageW)
		{
			//erase block of rootConflict
			ErasePhyBlockNum = ConflictPhyBlockNum;
			flag = 1 ;
			//erase the leaft Left  
		} //end if if( ConfNumPageW == NumPageW)	
		else
		{
			//  ConfNumPageW > NumPageW
			if (EraseLeafStructure(Node) == FAILURE)
			{
				return FAILURE;
			} 
			flag = 0 ;
			//ErasePhyBlockNum = ((TreeNode *) *Node)->PhysicalBlockNumber1;   
			((TreeNode *) *Node)->PhysicalBlockNumber1 = ConflictPhyBlockNum;
		}
	} 

	if (flag == 1)
	{
		//erase physical blck   
		if (BlockErase(ErasePhyBlockNum) == FAILURE)
		{
			//mark PhysicalBlock as bad
			if (MarkBadBlock(ErasePhyBlockNum) == FAILURE)
			{
				return FAILURE;
			}
			//add in BBT store in Ram the bad block
			if (AddBadBlock(ErasePhyBlockNum) == FAILURE)
			{
				return FAILURE;
			}
		}
		else
		{
			//add block in FreeBlockChain

			if (AddFreeBlock(ErasePhyBlockNum,1) == FAILURE)
			{
				return FAILURE;
			}
		}
	}

	return SUCCESS;
}


/********************** GetNodeByPosition ***************************
*   																*
* Retrieve the node of tree referred by Position					*
*-------------------------------------------------------------------*
*   																*
*   																*
*	PARAMETER:  													* 
*   		   Root: is the Root of tree							*
*   																*   								 
*   		   Position: indicate the position on Node in the Tree  *
*      			Node : is the node foundede 					  	*
*	return values:													*
*																	*
*				SUCCESS:no problems is occurred 		   			*
*				NODENOTFOUND:the node is not founded				*
*********************************************************************/


NFTL_Return GetNodeByPosition(void *Root, UINT16 *blockNumber)
{
	if (((TreeNode *) Root)->Info == 0x01)//root
	{
		*blockNumber = ((TreeNode *) Root)->PhysicalBlockNumber1;
		return SUCCESS;
	}

	if (((TreeNode *) Root)->Info == 0x02)//leaf
	{
		*blockNumber = ((TreeNode *) Root)->PhysicalBlockNumber2;
		return SUCCESS;
	}
	return NODENOTFOUND;
}







/********************** GetSectorOffset  ****************************
*   																*
* Retrieve the offset value relative by Sector, 					*
*   	this information is contained into SectorMap				*
*-------------------------------------------------------------------*
*   																*
*   																*
*	PARAMETER:  													* 
*   		 PhyBlockNumber: Physical block Number  				*
*   																*   								 
*   		  LastWrite   : indicate the last sector written		*
*      		  PhyBlockNum :Physical Block Number associated by Node *
*	return values:													*
*																	*
*				SUCCESS:no problems is occurred 		   			*
*				FAILURE: the operation is failed					*
*   			PAGENOTFOUND: the sector is not written 			*
*********************************************************************/


NFTL_Return GetSectorOffset(SectorMap Map, UINT8 Sector, UINT8 *OffSet)
{
	UINT8 CurrentOffset = 0;	
	INT16 Validation; 

	CurrentOffset = Map.Sector[Sector];
	Validation = Map.OffsetValidation;

	*OffSet = CurrentOffset;
	if (CurrentOffset != 0)
	{
		return SUCCESS;
	}

	if ((CurrentOffset == 0) && (Validation == Sector))
	{
		return SUCCESS;
	}   

	if ((CurrentOffset == 0) && (Validation != Sector))
	{
		return PAGENOTFOUND;
	}

	return FAILURE;
}



/********************** SetSectorOffset  ****************************
*   																*
* Set the offset value relative by Sector,  						*
*   	this information is contained into SectorMap				*
*-------------------------------------------------------------------*
*   																*
*   																*
*	PARAMETER:  													* 
*   		 PhyBlockNumber: Physical block Number  				*
*   																*   								 
*   		  LastWrite   : indicate the last sector written		*
*      		  PhyBlockNum :Physical Block Number associated by Node *
*	return values:													*
*																	*
*				SUCCESS:no problems is occurred 		   			*
*				FAILURE: the operation is failed					*
*   			PAGENOTFOUND: the sector is not written 			*
*********************************************************************/


NFTL_Return SetSectorOffset(INT32 Map, UINT8 Sector, UINT8 OffSet)
{
	SetSMSectorElement(Map,Sector,OffSet);
	if (OffSet == 0x00)
	{
		SetSMOffsetValidation(Map,Sector);
	} //Map.OffsetValidation=Sector;

	return SUCCESS;
}



/********************** CreateSectorMap  ****************************
*   																*
* Read the spare area of physical block referred					*
*  by PhysicalBlockNumber and build SecrorMap   					*
*   																*
*-------------------------------------------------------------------*
*   																*
*	PARAMETER:  													* 
*   		 PhyBlockNumber: Physical block Number  				*
*   																*   								 
*   		  Map   : SectorMap 									*
*      																*
*	return values:													*
*																	*
*				SUCCESS:no problems is occurred 		   			*
*				FAILURE: the operation is failed					*
*********************************************************************/

NFTL_Return CreateSectorMap(UINT16 PhysicalBlockNumber, SectorMap *Map, UINT8 *LastWrite)
{
	UINT8 SectorNumber;
	UINT8 SpareBuffer[BUFFER_SPARE_SIZE];
	UINT8 lastPage = 0;
	INT8 i;  	




	//OS_MemSet(Map->Sector,0x00,MAX_SECTOR_NUMBER);
	{
	  UINT8 *pSector = Map->Sector ;
	  for (i =0 ;i<32 ;i+=16)
	{
	   	*pSector++=0 ;
		*pSector++=0 ;
		*pSector++=0 ;
		*pSector++=0 ;
		*pSector++=0 ;
		*pSector++=0 ;
		*pSector++=0 ;
		*pSector++=0 ;
		*pSector++=0 ;
		*pSector++=0 ;
		*pSector++=0 ;
		*pSector++=0 ;
		*pSector++=0 ;
		*pSector++=0 ;
		*pSector++=0 ;
		*pSector++=0 ;
	}
	}
		
	Map->OffsetValidation = -1;
	Map->PhysicalBlockNumber = PhysicalBlockNumber; 	
//	EnableNAND();
	for (i = 0; i < 32; i++)
	{     
		UINT32 returnAddress;
		
	returnAddress =mCalculateAddress(PhysicalBlockNumber,i);
	NAND_SpareReadRandom(returnAddress,SpareBuffer,CHUNK_SPARE_SIZE) ;
		
		if (SpareBuffer[PAGE_STATUS_BYTE] == WRITTEN)
		{  
			SectorNumber = SpareBuffer[SECTOR_NUMBER] | SpareBuffer[COPY_SECTOR_NUMBER];
			
			if (i == 0)
			{
				Map->OffsetValidation = SectorNumber;
			}
			Map->Sector[SectorNumber] = i;
			lastPage++;
		}
		else
		{
			break;
		}
	}
	//DisableNAND();

	if (lastPage == 0)
	{
		*LastWrite = 255;
	}
	else
	{
		*LastWrite = lastPage - 1;
	}

	return SUCCESS;
}

/********************** CopySectorMap  *****************************
*   																*
* Copy Origin SectorMap in Destination SectorMap					*
*   																*
*-------------------------------------------------------------------*
*   																*
*	PARAMETER:  													* 
*   		 PhyBlockNumber: Physical block Number  				*
*   																*   								 
*   		  Origin   	  : SectorMap   							*
*   		  Destination : SectorMap   							*
*      																*
*	return values:													*
*																	*
*				SUCCESS:no problems is occurred 		   			*
*				FAILURE: the operation is failed					*
*********************************************************************/ 
#if 0
NFTL_Return CopySectorMap(SectorMap Origin, INT32 Destination)
{
	UINT8 i;

	SetSMCachePhysicalBlockNumber(Destination,Origin.PhysicalBlockNumber);
	SetSMOffsetValidation(Destination,Origin.OffsetValidation);
for (i = 0; i < MAX_SECTOR_NUMBER; i+=16)
	{	
      	   Cache[Destination].Sector[i] = Origin.Sector[i];
	   Cache[Destination].Sector[i+1] = Origin.Sector[i+1];
	   Cache[Destination].Sector[i+2] = Origin.Sector[i+2];
	   Cache[Destination].Sector[i+3] = Origin.Sector[i+3];
	   Cache[Destination].Sector[i+4] = Origin.Sector[i+4];
	   Cache[Destination].Sector[i+5] = Origin.Sector[i+5];
	   Cache[Destination].Sector[i+6] = Origin.Sector[i+6];
	   Cache[Destination].Sector[i+7] = Origin.Sector[i+7];
	   Cache[Destination].Sector[i+8] = Origin.Sector[i+8];
	   Cache[Destination].Sector[i+9] = Origin.Sector[i+9];
	   Cache[Destination].Sector[i+10] = Origin.Sector[i+10];
	   Cache[Destination].Sector[i+11] = Origin.Sector[i+11];
	   Cache[Destination].Sector[i+12] = Origin.Sector[i+12];
	   Cache[Destination].Sector[i+13] = Origin.Sector[i+13];
	   Cache[Destination].Sector[i+14] = Origin.Sector[i+14];
	   Cache[Destination].Sector[i+15] = Origin.Sector[i+15];
	}
	return SUCCESS;
}  
#endif

NFTL_Return CopySectorMap(SectorMap Origin, INT32 Destination)
{
	UINT8 i;
	UINT8 *pDst, *pSrc ;
	
	SetSMCachePhysicalBlockNumber(Destination,Origin.PhysicalBlockNumber);
	SetSMOffsetValidation(Destination,Origin.OffsetValidation);

	pDst=&(Cache[Destination].Sector[0]); 
	pSrc=&(Origin.Sector[0]);

⌨️ 快捷键说明

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