📄 structuremanager.c
字号:
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 + -