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

📄 translationmodule.c

📁 Nand Flash Translation Layer 用于nandflash的操作。 bad block memory map garbage collection average er
💻 C
📖 第 1 页 / 共 3 页
字号:
*				SUCCESS:no problems is occurred 		   			  *
*				FAILURE:the read operation is failed		 		  *
*********************************************************************/

NFTL_Return CallGarbageCollection(UINT16 VirtualBlockNumber, UINT8 Sector)
{
	NFTL_Return result;
	UINT16 *InvalidBlocks = NULL; 
	UINT8 SizeDataStructure;
	UINT16 NewPhysicalBlockNumber;
	UINT8 LastWrite = 0;


	//allocate a new Block
	result = GetBestFreeBlock(&NewPhysicalBlockNumber);
	if (result == NO_FREE_BLOCKS)
	{
		return NO_FREE_BLOCKS;
	}

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

	//Verify the size of data structure that emulate the re-writing operation
	SizeDataStructure = DimensionDataStructure(VirtualToPhysicalMT[VirtualBlockNumber]);

	//allocate the array to cointain the block to erase
	InvalidBlocks = (UINT16 *)OS_DRIVER_Malloc(sizeof(UINT16) * SizeDataStructure);
	if (InvalidBlocks == NULL)
	{
		return FAILURE;
	} 

	//search the physical block that must be erased

	ListInvalidBlock(VirtualToPhysicalMT[VirtualBlockNumber],InvalidBlocks);

	//reduce the full data structure to execute a write operation
	result = MinimizeStructure(InvalidBlocks,SizeDataStructure,
				VirtualToPhysicalMT[VirtualBlockNumber],NewPhysicalBlockNumber,Sector);

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

	//Update VirtualToPhysicalMT and erase the data old structure from RAM

	UpdateVirtualToPhysicalMT(VirtualBlockNumber,NewPhysicalBlockNumber);
	LastWrite = GetGCNumPageWritten();
	if (UpdateLastwrite(VirtualToPhysicalMT[VirtualBlockNumber],LastWrite) != SUCCESS)
	{
		return FAILURE;
	}
	if (InvalidBlocks != NULL)
	{
		OS_DRIVER_Free(InvalidBlocks);
		InvalidBlocks = NULL;
	}
	MMI_PutString((INT8 *) "CallGarbageCollection\n\r");
	return SUCCESS;
}


NFTL_Return IsInTable(UINT16 *tempTable, int len, UINT16 value)
{
	int i;

	if (tempTable == NULL)
	{
		return FAILURE;
	}
	for (i = 0; i < len; i++)
	{
		if (tempTable[i] == value)
		{
			return SUCCESS;
		}
	}
	return FAILURE;
}


NFTL_Return NFTL_Unmount()
{
	int i;

	if (isInitialised == NOT_INITIALISED)
	{
		return SUCCESS;
	}

	Unmount_HAL();

	ResetCache();

	for (i = 0; i < ACCESSIBLE_BLOCKS; i++)
	{
		if (EraseStructure(VirtualToPhysicalMT[i]) != SUCCESS)
		{
			return FAILURE;
		}
		VirtualToPhysicalMT[i] = NULL;
	}

	if (Unmount_BBM() != SUCCESS)
	{
		return FAILURE;
	}

	if (Unmount_WearLeveling() != SUCCESS)
	{
		return FAILURE;
	}

	isInitialised = NOT_INITIALISED;
	return SUCCESS;
}


UINT8 HD_NFlashRead(UINT32 RD_NFlash_Address, UINT32 sramAddress)
{
	UINT32 LBA ;
	UINT8 Errorcode ;
	UINT8 *pReadBufer = (UINT8 *) sramAddress ;

	LBA = RD_NFlash_Address >> 9 ;
	Errorcode = NFTL_ReadSector(LBA,pReadBufer) ;;
	return Errorcode ;
}
UINT8 HD_NFlashWrite(UINT32   sramAddress, UINT32 WR_NFlash_Address)
{
	UINT32 LBA ;
	UINT8 Errorcode ;
	UINT8 *pWriteBuffer = (UINT8 *) sramAddress ;

	LBA = WR_NFlash_Address >> 9 ;
	Errorcode = NFTL_WriteSector(LBA,pWriteBuffer) ;	

	return Errorcode ;
}

UINT8 NandWriteBuffer[512];

extern FATSYS_STRUCT gNandFATSYS ;

UINT16 DevNandWrite(UINT16 clusNumber, UINT16 sectorNumber, UINT32 bufAddr,
	UINT16 length, UINT16 offset)
{
	UINT32 dst_addr = 0 ;
	UINT32 src_addr = 0 ;
	UINT16 i = 0 ;  
	UINT8 error = SUCCESS  ;


	dst_addr = NandClusterToAddr(clusNumber) +
		sectorNumber * gNandFATSYS.Bpb50.bpbBytesPerSec;

	src_addr = (UINT32) NandWriteBuffer ;

	if (length != 512)
	{
		error = HD_NFlashRead(dst_addr,src_addr) ;
		if (error != SUCCESS)
		{
			return error  ;
		}
		for (i = offset ; i < offset + length ; i++)
			NandWriteBuffer[i] = *(UINT8 *) bufAddr++ ;

		error = HD_NFlashWrite(src_addr,dst_addr) ;
		return  error ;
	}
	else
	{
		error = HD_NFlashWrite(bufAddr,dst_addr) ;
		return  error ;
	}
}


UINT16 DevNandRead(UINT16 clusNumber, UINT16 sectorNumber, UINT32  bufAddr)
{
	UINT32 dst_addr = 0 ;
	UINT32 src_addr = 0 ; 
	UINT8 error = SUCCESS  ;

	src_addr = NandClusterToAddr(clusNumber) +
		sectorNumber * gNandFATSYS.Bpb50.bpbBytesPerSec;
	dst_addr = bufAddr ;
	error = HD_NFlashRead(src_addr,dst_addr) ;

	return error ;
}   


NFTL_Return PartialDefrag(UINT16 StartVBIndex, UINT16 EndVBIndex)
{
	UINT16 VBIndex, *InvalidBlocks = NULL; 
	UINT8 SizeDataStructure;
	UINT16 NewPhysicalBlockNumber;
	NFTL_Return result;
	UINT8 LastWrite = 0;


	//Read the all elements of VirtualToPhysicalMappingTable 
	for (VBIndex = StartVBIndex; VBIndex < EndVBIndex; VBIndex++)
	{
		//verify if the VirtualBlock "VBIndex" is used
		if (VirtualToPhysicalMT[VBIndex] != NULL)
		{
			//verify if there is only one block in data structure
			SizeDataStructure = DimensionDataStructure(VirtualToPhysicalMT[VBIndex]);	

			if (SizeDataStructure > 1)
			{
				//the VirtualBlock "VBIndex" is used and the hystory data structure can be erased 			
				//allocate a new Block

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

				//allocate the array to cointain the block to erase
				InvalidBlocks = (UINT16 *)OS_DRIVER_Malloc(sizeof(UINT16) * SizeDataStructure);
				if (InvalidBlocks == NULL)
				{
					return FAILURE;
				} 

				//search the physical block that must be erased

				ListInvalidBlock(VirtualToPhysicalMT[VBIndex],InvalidBlocks);
				//execute the garbage collection
				result = MinimizeStructure(InvalidBlocks,SizeDataStructure,
							VirtualToPhysicalMT[VBIndex],NewPhysicalBlockNumber,
							NOT_VALUE);

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

				//Update VirtualToPhysicalMT and erase the data old structure from RAM

				UpdateVirtualToPhysicalMT(VBIndex,NewPhysicalBlockNumber);

				LastWrite = GetGCNumPageWritten();
				if (UpdateLastwrite(VirtualToPhysicalMT[VBIndex],LastWrite) != SUCCESS)
				{
					return FAILURE;
				}

				if (InvalidBlocks != NULL)
				{
					OS_DRIVER_Free(InvalidBlocks);
					InvalidBlocks = NULL;
				}
			}
		}
	}

	return SUCCESS;
}

UINT32 NAND_MediaCapacity(void)
{
    UINT16 NumberOfBadBlocks=0 ;
    UINT32 MemCapacity;
    UINT32 temp;
	
    GetBadBlocksNumber(&NumberOfBadBlocks);

    temp = ACCESSIBLE_BLOCKS - NumberOfBadBlocks -RESEVED_AREA_BLOCK ; 
    MemCapacity = temp<<14 ; /*valid memory capacity; Uint is byte*/
    return (MemCapacity) ;

}


static NFTL_Return USBWriteSector(UINT32 VirtualAddress, UINT8 *Buffer)
{
	UINT16 VirtualBlockNumber = 0, Sector = 0, PagePerVirtualBlock = 0, VBIndex = 0,
		VBBestDataStructure = 0;
	UINT16 *InvalidBlocks = NULL, NewPhysicalBlockNumber = 0, NumberOfUsedBlocks = 0;
	UINT8 SizeDataStructure = 1, BestSizeDataStructure = 1;
	UINT16 badBlocksNumber;
	static UINT16 StartVBIndex = 0, EndVBIndex = 50;
	NFTL_Return result = SUCCESS;
	void *BestDataStructure = NULL;
	UINT8 LastWrite = 0;
	UINT16 *p =(UINT16 *) (&Buffer[CHUNK_DATA_SIZE]);

	SDAndNandFlag=1;
	
	*p++=0xFFFF;
	*p++=0xFFFF;
	*p++=0xFFFF;
	*p++=0xFFFF;
	*p++=0xFFFF;
	*p++=0xFFFF;
	*p++=0xFFFF;
	*p++=0xFFFF;

	
#ifdef NFTL_DEBUG
{	
	UINT32 NumberOfAddressableSector = 0;
	//Verify if the VirtualAddress in within partition
	NumberOfAddressableSector = ACCESSIBLE_BLOCKS * GetDeviceArchitecture().pagesInBlock ;
	if (VirtualAddress >= NumberOfAddressableSector)
	{
		return WRONG_ADDRESS;
	}
}
#endif /*NFTL_DEBUG*/

	VirtualBlockNumber = VirtualAddress >>5;
	Sector = VirtualAddress & 31;/*PAGES_OF_BLOCK-1*/

	if (gInvalidBlocks > SPACE_TO_FREE)
	{
		FreeDirtySpace();
	}

	if (StartVBIndex >= END_POINT)
	{
		StartVBIndex = 0;
		EndVBIndex = INTERVAL;
	}	
	PartialDefrag(StartVBIndex,EndVBIndex);
	StartVBIndex = EndVBIndex;
	EndVBIndex += INTERVAL;
	if (StartVBIndex == END_POINT)
	{
		EndVBIndex = ACCESSIBLE_BLOCKS;
	}

	//Execute the write in the sector history data structure	
	result = USBWritePage(VirtualBlockNumber,Sector,Buffer,
				&(VirtualToPhysicalMT[VirtualBlockNumber]));

	//if the program operation fail the physical position is bad. The sector must be remapped.
	if (result == FAILURE)
	{
		return FAILURE;
	}

	if (result == DATA_STRUCTURE_FULL)
	{
		result = CallGarbageCollection(VirtualBlockNumber,Sector);
		if (result == FAILURE)
		{
			return result;
		}

		if (result == NO_FREE_BLOCKS)//garbage not performed
		{
			if (FreeDirtySpace() != SUCCESS)
			{
				return FAILURE;
			}
			result = CallGarbageCollection(VirtualBlockNumber,Sector);
			if (result == FAILURE)
			{
				return result;
			}
		}
		//Execute the write in the sector history data structure	
		result = USBWritePage(VirtualBlockNumber,Sector,Buffer,
					&(VirtualToPhysicalMT[VirtualBlockNumber]));

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

		if (InvalidBlocks != NULL)
		{
			OS_DRIVER_Free(InvalidBlocks);
			InvalidBlocks = NULL;
		}
		return SUCCESS;
	}

	if (result == NO_FREE_BLOCKS)
	{
		if (FreeDirtySpace() != SUCCESS)
		{
			return FAILURE;
		}
		result = USBWritePage(VirtualBlockNumber,Sector,Buffer,
					&(VirtualToPhysicalMT[VirtualBlockNumber]));

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


	return SUCCESS;
}
NFTL_Return USB_WriteSector(UINT32 VirtualAddress, UINT8 *Buffer)
{
	NFTL_Return ErrorCode ;
	if (SDAndNandFlag==0)
	{
		EnableSDClock();
		EnableSDControler();
		CardReset();
		DisableSDClock();
		DisableSDControler();

	}
	EnableNAND();
	if(SDAndNandFlag==0)//SD used ever
	{
		HD_NFlashInit();
	}
	ErrorCode=USBWriteSector( VirtualAddress, Buffer);
	DisableNAND();

	return ErrorCode ;
}

/***********************  ReadSector *******************************
* Read a sector from flash searching the last sector update written *
*   													 			*
*-------------------------------------------------------------------*
*   VirtualAddress :is the sector address   						*
*   Buffer  	   :contain the data to read from flash 	  		*
*																	*
*	return values:													*
*				WRONG_ADDRESS: the virtual address is mistaken  	*
*				SUCCESS:no problems is occurred 		   			*
*				FAILURE:the read operation is failed		 		*
*********************************************************************/

static NFTL_Return USBReadSector(UINT32 VirtualAddress, UINT8 *Buffer)
{
	
	UINT16 VirtualBlockNumber, Sector, PagePerVirtualBlock;
	NFTL_Return result;

	SDAndNandFlag=1;

#ifdef NFTL_DEBUG
{	//Verify if the VirtualAddress in within partition
	UINT32 NumberOfAddressableSector;
	NumberOfAddressableSector = ACCESSIBLE_BLOCKS * GetDeviceArchitecture().pagesInBlock * (GetDeviceArchitecture().mainSize /
		CHUNK_DATA_SIZE);
	if (VirtualAddress >= NumberOfAddressableSector)
	{
		return WRONG_ADDRESS;
	}
}
#endif /*NFTL_DEBUG*/
	//Calculate the number of physical page per Virtual Block

	VirtualBlockNumber = VirtualAddress >>5;
	Sector = VirtualAddress &31;/*PAGES_OF_BLOCK-1*/
	
	if (VirtualToPhysicalMT[VirtualBlockNumber] == NULL)
	{
		return UNWRITTEN;
	}
	else
	{
		result = SM_ReadPage(VirtualBlockNumber,Sector,Buffer,
					VirtualToPhysicalMT[VirtualBlockNumber]); 
		if (result == SUCCESS)
		{
			if (Buffer[SECTOR_SIZE + ERASE_STATUS_BYTE] == ERASED)
			{
				result = PAGENOTFOUND;
				return result;
			}	
		}
		return result;
	}

	return SUCCESS;
}

NFTL_Return USB_ReadSector(UINT32 VirtualAddress, UINT8 *Buffer)
{
	NFTL_Return ErrorCode ;

	if (SDAndNandFlag==0)
	{
		EnableSDClock();
		EnableSDControler();
		CardReset();
		DisableSDClock();
		DisableSDControler();
		
	}
	EnableNAND() ;
	if(SDAndNandFlag==0)//SD used ever
	{
		HD_NFlashInit();
	}
	
	ErrorCode = USBReadSector( VirtualAddress, Buffer);
	DisableNAND();

	return ErrorCode;
}

NFTL_Return NFTL_ReadSector(UINT32 VirtualAddress, UINT8 *Buffer)
{
	NFTL_Return ErrorCode ;

	EnableNAND() ;
	ErrorCode = ReadSector( VirtualAddress, Buffer);
	DisableNAND();

	return ErrorCode;
}

NFTL_Return NFTL_WriteSector(UINT32 VirtualAddress, UINT8 *Buffer)
{
	NFTL_Return ErrorCode ;
	EnableNAND();
	ErrorCode=WriteSector( VirtualAddress, Buffer);
	DisableNAND();
	return ErrorCode ;
}

NFTL_Return NFTL_FormatFlash(void)
{
	NFTL_Return ErrorCode ;

	EnableNAND();
	ErrorCode=FormatFlash() ;
	DisableNAND();
	return ErrorCode ;
}

⌨️ 快捷键说明

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