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

📄 structuremanager.c

📁 Nand Flash Translation Layer 用于nandflash的操作。 bad block memory map garbage collection average er
💻 C
📖 第 1 页 / 共 4 页
字号:
NFTL_Return SM_WritePage(UINT16 VirtualBlock, UINT8 Sector, UINT8 *Buffer_data,
	void **Node)
{
	NFTL_Return result, result1;
	UINT16 PhysicalBlockNumber, NewPhysicalBlockNumber, CPhyBlockNumber;
	UINT8 SpareBuffer[BUFFER_SPARE_SIZE], InvalidPage;
	UINT8 Buffer[SECTOR_SIZE + BUFFER_SPARE_SIZE];
	UINT16 NewPhysicalPage ;
	UINT16 j=0;

	UINT8 Position = 0, Conflict, Level;

	//MMI_PutString((INT8 *) "SM_WritePage\n");
	OS_MemSet(SpareBuffer,0xFF,BUFFER_SPARE_SIZE);

	//nodo non presente
	if (*Node == NULL)
	{
		SpareBuffer[TREE_POSITION_BYTE] = ROOT_POSITION;
		SpareBuffer[COPY_TREE_POSITION_BYTE] = ROOT_POSITION;

		SpareBuffer[ROOT_COUNTER_BYTE] = 0;

		if ((result = GetBestFreeBlock(&NewPhysicalBlockNumber)) != SUCCESS)
		{
			return result;
		}

		if (AddBlock(NewPhysicalBlockNumber,SpareBuffer,Node,&Conflict,&CPhyBlockNumber,
				1) == FAILURE)
		{
			return FAILURE;
		}
		NewPhysicalPage = 0;
		Position = ROOT_POSITION;
	}
	else
	{
		//nodo presente, vedo se root o foglia	
		result = GetValidPagePosition((TreeNode *) *Node,&PhysicalBlockNumber,
					&NewPhysicalPage,Sector,&Position,WRITE_OPERATION);

		if (result == FAILURE)
		{
			return result;
		}

		if (result == DATA_STRUCTURE_FULL)
		{
			return result;
		}

		if (result == PAGENOTFOUND)
		{
			SpareBuffer[TREE_POSITION_BYTE] = 0x01;
			SpareBuffer[COPY_TREE_POSITION_BYTE] = 0x01;


			SpareBuffer[ROOT_COUNTER_BYTE] = 0;


			if ((result = GetBestFreeBlock(&NewPhysicalBlockNumber)) != SUCCESS)
			{
				return result;
			}

			if (AddBlock(NewPhysicalBlockNumber,SpareBuffer,Node,&Conflict,
					&CPhyBlockNumber,1) == FAILURE)
			{
				return FAILURE;
			}
			NewPhysicalPage = 0;
		}
		else
		{
			if (Position == 0x01)
			{
				SpareBuffer[TREE_POSITION_BYTE] = ROOT_POSITION;;
				SpareBuffer[COPY_TREE_POSITION_BYTE] = ROOT_POSITION;
				SpareBuffer[ROOT_COUNTER_BYTE] = 0;
			}
			if (Position == 0x02)
			{
				SpareBuffer[TREE_POSITION_BYTE] = 0x01;;
				SpareBuffer[COPY_TREE_POSITION_BYTE] = 0x01;
				SpareBuffer[ROOT_COUNTER_BYTE] = 0;
			}
			NewPhysicalBlockNumber = PhysicalBlockNumber;
		}
	}


	SpareBuffer[PAGE_STATUS_BYTE] = WRITTEN;
	SpareBuffer[SECTOR_NUMBER] = Sector;
	SpareBuffer[COPY_SECTOR_NUMBER] = Sector;



	SpareBuffer[VIRTUAL_BLOCK_NUMBER_BYTE] = (unsigned char) (VirtualBlock >> 8);
	SpareBuffer[COPY_VIRTUAL_BLOCK_NUMBER_BYTE] = (unsigned char) (VirtualBlock >> 8);
	SpareBuffer[VIRTUAL_BLOCK_NUMBER_BYTE + 1] = (unsigned char) VirtualBlock;
	SpareBuffer[COPY_VIRTUAL_BLOCK_NUMBER_BYTE + 1] = (unsigned char) VirtualBlock;			


	OS_MemCopy(Buffer,Buffer_data,SECTOR_SIZE);
	OS_MemCopy(Buffer + SECTOR_SIZE,SpareBuffer,BUFFER_SPARE_SIZE);

	for (j = 0; j < MAX_ENTRY_CACHE; j++)
	{
		if ((GetSMCachePhysicalBlockNumber(j) == NewPhysicalBlockNumber) &&
			(GetSMFreeCache(j)))
		{
			SetSMSectorElement(j,Sector,NewPhysicalPage);

			if (NewPhysicalPage == 0x00)
			{
				(SetSMOffsetValidation(j,Sector));
			}
			break;
		}
	}




	((TreeNode *) (*Node))->LastWrite = NewPhysicalPage ;  

	result = Write528(NewPhysicalBlockNumber,NewPhysicalPage,Buffer);

	if (result == FAILURE)
	{
		InvalidPage = NewPhysicalPage;
		result = FAILURE;
		while (result != SUCCESS)
		{
			result1 = IncrementWriteAddress(*Node,Sector,InvalidPage,SpareBuffer,
						&NewPhysicalBlockNumber,&NewPhysicalPage);
			if (result1 == DATA_STRUCTURE_FULL)
			{
				return result1;
			}
			
			result = Write528(NewPhysicalBlockNumber,NewPhysicalPage,Buffer);
			if (result == SUCCESS)
			{
				Level = SpareBuffer[TREE_POSITION_BYTE];
				((TreeNode *) (*Node))->LastWrite = NewPhysicalPage ;

				for (j = 0; j < MAX_ENTRY_CACHE; j++)
				{
					if ((GetSMCachePhysicalBlockNumber(j) == NewPhysicalBlockNumber) &&
						(GetSMFreeCache(j)))
					{
						SetSectorOffset(j,Sector,NewPhysicalPage);
					}
					break;
				}
			}
		}
	}			

	return SUCCESS;
}


/***********************  SM_ReadPage  **********************************************
* Calculate the correct position in flash where the sector must be read 			*
*   																				*
*-------------------------------------------------------------------------------	*
*   Node : is the pointer to the root node of tree data structure   				*
*	Buffer: indicate the data buffer read from flash					 			*
*	VirtualBlock: is the Virtual Block number of sector is written  				*  
*	Sector: is the sector number to read											*
*   			 																	*
*	return values:  																*
*				UNWRITTEN: the sector is never written  							*
*				SUCCESS:the write operation is executed with success			 	*
*				FAILURE:the fail is occured 								 		*
*************************************************************************************/

NFTL_Return SM_ReadPage(UINT16 VirtualBlock, UINT8 Sector, UINT8 *Buffer, void *Node)
{
	NFTL_Return result;
	UINT16 PhysicalBlockNumber;
	UINT16 PhysicalPage;
	UINT8 Position;
	//MMI_PutString((INT8 *) "SM_ReadPage\n");
	if (Node == NULL)
	{
		return UNWRITTEN;
	}

	result = GetValidPagePosition(Node,&PhysicalBlockNumber,&PhysicalPage,Sector,
				&Position,READ_OPERATION);

	if (result == PAGENOTFOUND)
	{
		return UNWRITTEN;
	}

	if (result == FAILURE)
	{
		return FAILURE;
	}

	result = Read(PhysicalBlockNumber,PhysicalPage,Buffer);
	return result;
}


/***********************  IncrementWriteAddress  **********************************
* Increment of one position the address in the treee data structure 			  *
*   												 							  *
*------------------------------------------------------------------------------   *
*   Node : is the pointer to the root node of tree data structure   			  *
*   Sector: is the sector number to write   		 							  *
*	PhysicalPage:is the physical page where the last update of sector is written  * 
*	SpareBuffer: indicate the position the tree of the last update of sector	  *
*	NewPhysicalBlockNumber: is new phisical block number calculated 			  *
*	NewPhysicalPage: is new phisical page number calculated 					  *
*   																			  *
*	return values:  															  *
*   			DATA_STRUCTURE_FULL: the increment is no possible because the tree*
*   								  data structure is full					  *
*				SUCCESS:the sector is founded   		 					 	  *
*				FAILURE:the fail is occured 								 	  *
*********************************************************************************/

NFTL_Return IncrementWriteAddress(void *Node, UINT8 Sector, UINT8 PhysicalPage,
	UINT8 *SpareBuffer, UINT16 *NewPhysicalBlockNumber, UINT16 *NewPhysicalPage)
{
	UINT8 Level, Conflict;
	UINT16 CPhyBlockNum;

	Level = SpareBuffer[TREE_POSITION_BYTE]; 

	if ((Level == 0x01) && (PhysicalPage >= MAX_SECTOR_NUMBER))
	{
		return DATA_STRUCTURE_FULL;
	} 

	if (Level == ROOT_POSITION)
	{
		if (PhysicalPage >= MAX_SECTOR_NUMBER)
		{
			if (GetBestFreeBlock(NewPhysicalBlockNumber) != SUCCESS)
			{
				return FAILURE;
			}
			SpareBuffer[TREE_POSITION_BYTE] = 0x1; 
			if (AddBlock((*NewPhysicalBlockNumber),SpareBuffer,&Node,&Conflict,
					&CPhyBlockNum,1) == FAILURE)
			{
				return FAILURE;
			}
			*NewPhysicalPage = 0;
		}
		else
		{
			((TreeNode *) (Node))->LastWrite = PhysicalPage;
			GetNodeByPosition(Node,NewPhysicalBlockNumber); 
			*NewPhysicalPage = PhysicalPage + 1;
		}
	}

	return SUCCESS;
}




/***********************  DimensionDataStructure  ***********************************
* Return the number of leaf that compose the tree data structure of specific Virtual*
* Block 												  							*
*-------------------------------------------------------------------------------	*
*   Node : is the pointer to the root node of tree data structure   				*
*   			 																	*
*	return values:  																*
*				NumberLeafperRoot: is a number of leaves of the tree data structure *
*   							   plus the node root   							*
*************************************************************************************/

UINT8 DimensionDataStructure(void *Node)
{
	return((TreeNode *) Node)->Info;
}


/***********************  ListInvalidBlock  *****************************************
* Return the number of physical block that compose the tree data structure  		*
* Block 												  							*
*-------------------------------------------------------------------------------	*
*   Root : is the pointer to the root node of tree data structure   				*
*   InvalidBlocks: return the physical block number of leaves that compose the tree *   		 																	*
*************************************************************************************/

void ListInvalidBlock(void *Root, UINT16 *InvalidBlocks)
{
	if (((TreeNode *) (Root))->Info == 0x01)
	{
		InvalidBlocks[0] = ((TreeNode *) Root)->PhysicalBlockNumber1;
		return;
	}

	if (((TreeNode *) (Root))->Info == 0x02)
	{
		InvalidBlocks[0] = ((TreeNode *) Root)->PhysicalBlockNumber1;
		InvalidBlocks[1] = ((TreeNode *) Root)->PhysicalBlockNumber2;
		return;
	}
	return;
}



/***********************  UpdatePhysicalBlock  *********************************
* Update in a node the phisical block number								   *
*   													 					   *
*------------------------------------------------------------------------------*
*   Node : is the pointer to the root node of tree data structure   		   *
*   NewPhysicalBlockNumber:physical block number to update in node  		   *																				*
*******************************************************************************/

void UpdatePhysicalBlock(void *Node, UINT16 NewPhysicalBlockNumber)
{
	((TreeNode *) Node)->PhysicalBlockNumber1 = NewPhysicalBlockNumber;
	return;
}


/***********************  UpdateLastWrite  *********************************
* Update in a node the phisical block number							   *
*   													 				   *
*--------------------------------------------------------------------------*
*   Node : is the pointer to the root node of tree data structure   	   *
*   LastWrite: indicate the last sector writtten in the block   		   *																				*
***************************************************************************/

NFTL_Return UpdateLastwrite(void *Node, UINT8 LastWrite)
{
	((TreeNode *) Node)->LastWrite = LastWrite;
	return SUCCESS;
}


/***********************  EraseRAMStructure  ***********************************
* Free in RAM the node that compose the tree data structure of a specific      *
* Virtual Block 										   					   *
*------------------------------------------------------------------------------*
*   Node : is the pointer to the root node of tree data structure to OS_Free	  *
*******************************************************************************/

NFTL_Return EraseRAMStructure(void *Root)
{
	((TreeNode *) (Root))->PhysicalBlockNumber2 = 0;
	((TreeNode *) (Root))->Info = 1; 
	
	return SUCCESS;
}


/***********************  EraseLeafStructure  **********************************
* Free in RAM the node that compose the tree data structure of a specific      *
* Virtual Block, and the corrispondent phisical block   					   *
*------------------------------------------------------------------------------*
*   Node : is the pointer to the root node of tree data structure to OS_Free	  *
*   NFTL_Return:															   *
*   		   SUCCESS:the erase Leaf operation is executed with success	   *
*				FAILURE:the fail is occured 								   *
*******************************************************************************/ 

NFTL_Return EraseLeafStructure(void **Root)
{
	UINT16 NodeNumber = 0, i;
	UINT16 *InvalidBlocks;

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

	//retrieve the number of Node less the Root 
	NodeNumber = ((TreeNode *) (*Root))->Info;
	InvalidBlocks = (UINT16 *) OS_DRIVER_Malloc(sizeof(UINT16) * NodeNumber);



	ListInvalidBlock((*Root),InvalidBlocks);

	((TreeNode *) (*Root))->Info = 1; 

	EraseRAMStructure(Root);

	for (i = 1; i < NodeNumber; i++)
	{
		if (BlockErase(InvalidBlocks[i]) == FAILURE)
		{
			//mark PhysicalBlock as bad
			if (MarkBadBlock(InvalidBlocks[i]) == FAILURE)
			{
				return FAILURE;
			}
			//add in BBT store in Ram the bad block
			if (AddBadBlock(InvalidBlocks[i]) == FAILURE)
			{
				return FAILURE;
			}
		}
		else
		{
			//add block in FreeBlockChain   	
			if (AddFreeBlock(InvalidBlocks[i],1) == FAILURE)
			{
				return FAILURE;
			}
		}				
		SetSMUsedBlocks(GetSMUsedBlocks() - 1);
	}

	OS_DRIVER_Free(InvalidBlocks);
	return SUCCESS;
}




/***********************  GetSectorNumber  *****************************************
* Return the number of sector exstract to physical page in the tree data structure  *
*   													 							*
*-------------------------------------------------------------------------------	*
*   PhysicalPage : is the physical page in tree data structure  					*
*   Sector: is the number of sector calculated from physical page   				*
*	SpareBuffer: indicate the position of physical page in tree data structure  	*
************************************************************************************/

void GetSectorNumber(UINT8 *SpareBuffer, UINT8 PhysicalPage, UINT8 *Sector)
{
	*Sector = (SpareBuffer[SECTOR_NUMBER] | SpareBuffer[COPY_SECTOR_NUMBER]);

	return;
}


/***********************  GetRootCounter  *****************************************
* Return the Root Counter refered by node   									  *
*   													 						  *
*-----------------------------------------------------------------------------    *
*   Node : is the root of tree data structure   								  *
*   																			  *
***********************************************************************************/


NFTL_Return GetRootCounter(void *Node, UINT8 *RootCounter)
{
	UINT8 SpareBuffer[BUFFER_SPARE_SIZE];

	ReadSpare528(((TreeNode *) Node)->PhysicalBlockNumber1,SECTOR_ZERO,SpareBuffer);


	*RootCounter = (SpareBuffer[ROOT_COUNTER_BYTE]);

	if (SpareBuffer[PAGE_STATUS_BYTE] == 0xFF)
	{
		*RootCounter = 0;
	}

	return SUCCESS;
}

/***********************  EraseStructure  *****************************************
* Erase in Ram the tree structure included the Root 							  *
*   													 						  *
*-----------------------------------------------------------------------------    *
*   Root: is the root of tree data structure									 *
*   																			  *
***********************************************************************************/


NFTL_Return EraseStructure(void *Root)

⌨️ 快捷键说明

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