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

📄 structuremanager.c

📁 Nand Flash Translation Layer 用于nandflash的操作。 bad block memory map garbage collection average er
💻 C
📖 第 1 页 / 共 4 页
字号:
for (i = 0; i < MAX_SECTOR_NUMBER; i+=16)
	{	
		*pDst++=*pSrc++;
		*pDst++=*pSrc++;
		*pDst++=*pSrc++;
		*pDst++=*pSrc++;
		*pDst++=*pSrc++;
		*pDst++=*pSrc++;
		*pDst++=*pSrc++;
		*pDst++=*pSrc++;
		*pDst++=*pSrc++;
		*pDst++=*pSrc++;
		*pDst++=*pSrc++;
		*pDst++=*pSrc++;
		*pDst++=*pSrc++;
		*pDst++=*pSrc++;
		*pDst++=*pSrc++;
		*pDst++=*pSrc++;
	   
	}
	return SUCCESS;
}  


#if 0
NFTL_Return CopySectorMapFromCache(SectorMap *Origin, INT32 Destination)
{
	UINT8 i;
	
	Origin->PhysicalBlockNumber = GetSMCachePhysicalBlockNumber(Destination);
	Origin->OffsetValidation = GetSMOffsetValidation(Destination);
	for (i = 0; i < MAX_SECTOR_NUMBER; i+=16)
	{
		Origin->Sector[i] = Cache[Destination].Sector[i];
		Origin->Sector[i+1] = Cache[Destination].Sector[i+1];
		Origin->Sector[i+2] = Cache[Destination].Sector[i+2];
		Origin->Sector[i+3] = Cache[Destination].Sector[i+3];
		Origin->Sector[i+4] = Cache[Destination].Sector[i+4];
		Origin->Sector[i+5] = Cache[Destination].Sector[i+5];
		Origin->Sector[i+6] = Cache[Destination].Sector[i+6];
		Origin->Sector[i+7] = Cache[Destination].Sector[i+7];
		Origin->Sector[i+8] = Cache[Destination].Sector[i+8];
		Origin->Sector[i+9] = Cache[Destination].Sector[i+9];
		Origin->Sector[i+10] = Cache[Destination].Sector[i+10];
		Origin->Sector[i+11] = Cache[Destination].Sector[i+11];
		Origin->Sector[i+12] = Cache[Destination].Sector[i+12];
		Origin->Sector[i+13] = Cache[Destination].Sector[i+13];
		Origin->Sector[i+14] = Cache[Destination].Sector[i+14];
		Origin->Sector[i+15] = Cache[Destination].Sector[i+15];
	}
	
	return SUCCESS;
}
#endif
NFTL_Return CopySectorMapFromCache(SectorMap *Origin, INT32 Destination)
{
	UINT8 i;
	UINT8 *pDst, *pSrc ;
	
	Origin->PhysicalBlockNumber = GetSMCachePhysicalBlockNumber(Destination);
	Origin->OffsetValidation = GetSMOffsetValidation(Destination);
	
	pSrc=Cache[Destination].Sector; 
	pDst=&(Origin->Sector[0]);
	
	for (i = 0; i < MAX_SECTOR_NUMBER; i+=16)
	{
		*pDst++=*pSrc++;
		*pDst++=*pSrc++;
		*pDst++=*pSrc++;
		*pDst++=*pSrc++;
		*pDst++=*pSrc++;
		*pDst++=*pSrc++;
		*pDst++=*pSrc++;
		*pDst++=*pSrc++;
		*pDst++=*pSrc++;
		*pDst++=*pSrc++;
		*pDst++=*pSrc++;
		*pDst++=*pSrc++;
		*pDst++=*pSrc++;
		*pDst++=*pSrc++;
		*pDst++=*pSrc++;
		*pDst++=*pSrc++;
	   
	}
	
	return SUCCESS;
}

/********************** IncrementIndexCache  ***********************
*   																*
* Increment the index of cache  									*
*   																*
*-------------------------------------------------------------------*
*********************************************************************/ 


void IncrementIndexCache()
{
	//SetSMIndexCache((GetSMIndexCache() + 1) % MAX_ENTRY_CACHE);
	SetSMIndexCache((GetSMIndexCache() + 1) & (MAX_ENTRY_CACHE-1));
}  




/**********************FindSectorMap  *****************************
*   																*
* Calculate the page valid in the phsical block referred			*
*  by  PhyBlockNumber   											*
*   																*
*-------------------------------------------------------------------*
*   																*
*	PARAMETER:  													* 
*   		 PhyBlockNumber: Physical block Number  				*
*   																*   								 
*   		  V_Page   	  : Valid Page  							*
*   																*
*      																*
*	return values:													*
*																	*
*				SUCCESS:no problems is occurred 		   			*
*				FAILURE: the operation is failed					*
*********************************************************************/ 

NFTL_Return FindSectorMap(UINT16 PhyBlockNum, SectorMap *SectorM)
{
	UINT8 j=0, IsinCache = 1;


	for (j = 0; j < MAX_ENTRY_CACHE; j++)
	{
		if ((GetSMCachePhysicalBlockNumber(j) == PhyBlockNum) && (GetSMFreeCache(j)))
		{
			if (CopySectorMapFromCache(SectorM,j) != SUCCESS)
			{
				return FAILURE;
			}
			IsinCache = 0;	
			break;
		}
	}  	 

	if (IsinCache == 1)
	{
		UINT8 LastWrite;
		CreateSectorMap(PhyBlockNum,SectorM,&LastWrite) ;
	
	}	 
	return SUCCESS;
}	 




/**********************EraseSectorMapToCache  **********************
*   																*
* delete SectorMap referred by PhyBlockNumber to cache  			*
*  by  PhyBlockNumber   											*
*   																*
*-------------------------------------------------------------------*
*   																*
*	PARAMETER:  													* 
*   		 PhyBlockNumber: Physical block Number  				*
*   																*   								 
*      																*
*	return values:													*
*																	*
*				SUCCESS:no problems is occurred 		   			*
*				FAILURE: the operation is failed					*
*********************************************************************/ 

NFTL_Return EraseSectorMapToCache(UINT16 PhyBlockNum)
{
	UINT8 j=0;
	UINT8 inCache = 0;


	for (j = 0; j < MAX_ENTRY_CACHE; j++)
	{
		if ((GetSMCachePhysicalBlockNumber(j) == PhyBlockNum) && (GetSMFreeCache(j)))
		{
			SetSMCachePhysicalBlockNumber(j,0);

			SetSMFreeCache(j,0);
			inCache = 1;
			break;
		}
	}  	 

	if (inCache == 1)
	{
		return FAILURE;
	}
	else
	{
		return SUCCESS;
	}
}	 



NFTL_Return CopyAndEraseSectorMapToCache(UINT16 PhyBlockNumToBeErased,
	SectorMap *NewSectorMap)
{
	UINT8 j=0;
	UINT8 inCache = 0;
	UINT16 i;

	for (j = 0; j < MAX_ENTRY_CACHE; j++)
	{
		if ((GetSMCachePhysicalBlockNumber(j) == PhyBlockNumToBeErased) &&
			(GetSMFreeCache(j)))
		{
			SetSMCachePhysicalBlockNumber(j,0);
			SetSMFreeCache(j,0);
			inCache = 1;
			break;
		}
	}  

	if (inCache == 1)
	{
		SetSMCachePhysicalBlockNumber(j,NewSectorMap->PhysicalBlockNumber);
		SetSMOffsetValidation(j,NewSectorMap->OffsetValidation);

		for (i = 0; i < MAX_SECTOR_NUMBER; i++)
			SetSMSectorElement(j,i,NewSectorMap->Sector[i]);
		return SUCCESS;
	}
	else
	{
		return FAILURE;
	}
}	 


void SetSMFreeCache(INT32 j, UINT8 FC)
{
	FreeCache[j] = FC;
}

UINT8 GetSMFreeCache(INT32 j)
{
	return FreeCache[j];
}

INT32 Get_SM_IndexCache()
{
	return IndexCache;
}

void Set_SM_IndexCache(INT32 j)
{
	IndexCache = j;
}


UINT16 GetSMCachePhysicalBlockNumber(INT32 j)
{
	return Cache[j].PhysicalBlockNumber;
}

void SetSMCachePhysicalBlockNumber(INT32 j, UINT16 BN)
{
	Cache[j].PhysicalBlockNumber = BN;
}

void ResetCache()
{
	UINT16 g=0, k;
	IndexCache = -1;

	for (g = 0; g < MAX_ENTRY_CACHE; g++)
	{
		Cache[g].PhysicalBlockNumber = 0;
		for (k = 0; k < MAX_SECTOR_NUMBER; k++)
		{
			Cache[g].Sector[k] = 0;
		}
		Cache[g].OffsetValidation = -1;
		FreeCache[g] = 0;
	}
}

UINT16 GetSMUsedBlocks()
{
	return UsedBlocks;
}

void SetSMUsedBlocks(UINT16 value)
{
	UsedBlocks = value;
}

UINT8 GetSMSectorElement(INT32 i, INT32 j)
{
	return Cache[i].Sector[j];
}

void SetSMSectorElement(INT32 i, INT32 j, INT16 Elem)
{
	Cache[i].Sector[j] = Elem;
}

INT16 GetSMOffsetValidation(INT32 i)
{
	return Cache[i].OffsetValidation;
}

void SetSMOffsetValidation(INT32 i, INT16 OV)
{
	Cache[i].OffsetValidation = OV;
}

INT32 GetSMIndexCache()
{
	return IndexCache;
}

void SetSMIndexCache(INT32 j)
{
	IndexCache = j;
}

NFTL_Return USBWritePage(UINT16 VirtualBlock, UINT8 Sector, UINT8 *Buffer_data,
	void **Node)
{
	NFTL_Return result, result1;
	UINT16 PhysicalBlockNumber, NewPhysicalBlockNumber, CPhyBlockNumber;
	UINT8 InvalidPage;
	UINT16 NewPhysicalPage ;
	UINT8 j=0;
	UINT8 Position = 0, Conflict, Level;

	if (*Node == NULL)
	{
		Buffer_data[SECTOR_SIZE + TREE_POSITION_BYTE] = ROOT_POSITION;
		Buffer_data[SECTOR_SIZE + COPY_TREE_POSITION_BYTE] = ROOT_POSITION;

		Buffer_data[SECTOR_SIZE +ROOT_COUNTER_BYTE] = 0;

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

		if (AddBlock(NewPhysicalBlockNumber,(UINT8 *)&(Buffer_data[SECTOR_SIZE]),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)
		{
			Buffer_data[SECTOR_SIZE +TREE_POSITION_BYTE] = 0x01;
			Buffer_data[SECTOR_SIZE +COPY_TREE_POSITION_BYTE] = 0x01;
			Buffer_data[SECTOR_SIZE+ROOT_COUNTER_BYTE] = 0;


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

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


	Buffer_data[SECTOR_SIZE +PAGE_STATUS_BYTE] = WRITTEN;
	Buffer_data[SECTOR_SIZE +SECTOR_NUMBER] = Sector;
	Buffer_data[SECTOR_SIZE +COPY_SECTOR_NUMBER] = Sector;



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


	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_data);

	if (result == FAILURE)
	{
		InvalidPage = NewPhysicalPage;
		result = FAILURE;
		while (result != SUCCESS)
		{
			result1 = IncrementWriteAddress(*Node,Sector,InvalidPage,(UINT8 *)(&Buffer_data[SECTOR_SIZE]),
						&NewPhysicalBlockNumber,&NewPhysicalPage);
			if (result1 == DATA_STRUCTURE_FULL)
			{
				return result1;
			}
	
			result = Write528(NewPhysicalBlockNumber,NewPhysicalPage,Buffer_data);
			if (result == SUCCESS)
			{
				Level = Buffer_data[SECTOR_SIZE+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;
}

⌨️ 快捷键说明

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