📄 sector.c.bak
字号:
/**
* Sector.c
*/
#include "Sector.h"
#include "SectorHeader.h"
#include "SectorInfo.h"
#include "BlockTable.h"
#include "CellInfo.h"
#include "CellTable.h"
#include "Block.h"
#include "Device.h"
#include <malloc.h>
/**
* dms_SectorFormat
* Erases sector by calling dms_DeviceErase and
* then initializes the sector header information.
* wCellCount is needed as part of the data written in
* the sector header. The rest of the header information
* comes from dms_SectorInfo.
*
* Prerequisites:
* dms_SectorInfoDefineArchitecture()
* Uses:
* dms_SectorHeaderWriteHeaderStatus()
* dms_DeviceErase()
* dms_SectorInfoGetAddress()
* dms_SectorHeaderWriteInfo()
* Used By:
* dms_SectorFormatAll()
* dms_SectorInitialize()
*/
DMS_STATUS dms_SectorFormat(WORD awSectorIndex, WORD awCellCount){
DMS_STATUS eStatus;
/*
* Write HeaderErase in the header status.
* If power is lost durring a sector erase and some of
* the old data is left in the sector then maybe the
* HeaderErase will still be there and Initialization will
* know to do another erase.
*/
eStatus = dms_SectorHeaderWriteHeaderStatus(awSectorIndex, HeaderErase);
if (eStatus != No_Error){
return eStatus;
}
/* Erase the sector */
eStatus = dms_DeviceErase(dms_SectorInfoGetAddress(awSectorIndex));
if (eStatus != No_Error){
return eStatus;
}
/* Write Sector Header Info */
eStatus = dms_SectorHeaderWriteInfo(awSectorIndex, awCellCount);
if (eStatus != No_Error){
return eStatus;
}
return No_Error;
}
/**
* dms_SectorFormatAll
* Formats all sectors by calling dms_SectorFormat for each sector.
* wCellCount is required by dms_SectorFromat which is used as part of
* the data stored in the sector header.
*
* Prerequisites:
* dms_SectorInfoDefineArchitecture()
* Uses:
* dms_SectorInfoGetCount()
* dms_SectorFormat()
* Used By:
* dms_CellFormat()
*/
DMS_STATUS dms_SectorFormatAll(WORD awCellCount){
DMS_STATUS eStatus;
WORD wSectorIndex;
for (wSectorIndex = 0; wSectorIndex < dms_SectorInfoGetCount(); wSectorIndex++){
eStatus = dms_SectorFormat(wSectorIndex,awCellCount);
if (eStatus != No_Error){
return eStatus;
}
}
return No_Error;
}
/**
* dms_SectorInitialize(WORD wSectorIndex){
* Requires dms_CellInfo to be initialized.
* Requires dms_SectorInfo to be initialized.
* This function is to be called durring Initialization
* and cleanup.
*
* Prerequisites:
* dms_SectorInfoDefineArchitecture()
* dms_CellInfoDefineCellCount()
* Uses:
* dms_SectorHeaderReadHeaderStatus()
* dms_SectorFormat()
* dms_CellInfoGetCount()
* dms_SectorHeaderReadHeaderStatus()
* dms_SectorInfoGetBlockCount()
* dms_BlockTableReadEntry()
* dms_CellTableAddBlock()
* dms_CellTableAddAvailableBlock()
* dms_CellTableAddGarbageBlock()
* dms_BlockTableWriteBlockStatus()
* Used By:
* dms_CellInitialize()
*/
DMS_STATUS dms_SectorInitialize(WORD awSectorIndex){
DMS_STATUS eStatus;
DMS_HEADER_STATUS eHeaderStatus;
BLOCK_TABLE_ENTRY Bte;
WORD wSectorBlockIndex;
WORD wSectorBlockCount;
eStatus = dms_SectorHeaderReadHeaderStatus(awSectorIndex,&eHeaderStatus);
if (eStatus != No_Error){
return eStatus;
}
if (eHeaderStatus != HeaderValid){
/* If header is not valid then format it. */
eStatus = dms_SectorFormat(awSectorIndex,dms_CellInfoGetCount());
if (eStatus != No_Error){
return eStatus;
}
/* Re-check header status */
eStatus = dms_SectorHeaderReadHeaderStatus(awSectorIndex,&eHeaderStatus);
if (eStatus != No_Error){
return eStatus;
}
/* if header is not valid after the format then something is wrong */
if (eHeaderStatus != HeaderValid){
return Sector_Initialization_Failed;
}
}
/*
* foreach block in sector add block to cell table, available table,
* or garbage table depending on its block status.
*/
wSectorBlockCount = dms_SectorInfoGetBlockCount(awSectorIndex);
for (wSectorBlockIndex = 0; wSectorBlockIndex < wSectorBlockCount; wSectorBlockIndex++){
eStatus = dms_BlockTableReadEntry(awSectorIndex,wSectorBlockIndex,&Bte);
if (eStatus != No_Error){
return eStatus;
}
if (Bte.bBlockStatus == BlockValid){
eStatus = dms_CellTableAddBlock(Bte.wCellIndex,Bte.wBlockIndex,Bte.bCellStatus,awSectorIndex,wSectorBlockIndex);
if (eStatus != No_Error){
return eStatus;
}
} else if (Bte.bBlockStatus == BlockAvailable) {
eStatus = dms_CellTableAddAvailableBlock(awSectorIndex,wSectorBlockIndex);
if (eStatus != No_Error){
return eStatus;
}
} else if (Bte.bBlockStatus == BlockErase){
dms_CellTableAddGarbageBlock(awSectorIndex,wSectorBlockIndex);
} else {
eStatus = dms_BlockTableWriteBlockStatus(awSectorIndex,wSectorBlockIndex,BlockErase);
if (eStatus != No_Error){
return eStatus;
}
dms_CellTableAddGarbageBlock(awSectorIndex,wSectorBlockIndex);
}
}
return No_Error;
}
/**
* dms_SectorCleanup()
* Calls dms_CellTableGetBestSectorToErase() to select the best
* sector to erase. If there are no garbage blocks then
* dms_SectorCleanup returns No_Garbage_Blocks. Otherwise it
* cleans one sector and returns No_Error if it was successful.
* The Block Move Process:
* Get new block.
* Write BlockBeingWritten.
* Write block number.
* Write cell number.
* Copy cell status.
* Write block data.
* Write BlockValid.
* Write BlockErase in old block.
* Add old block to garbage count.
*
* Prerequisites:
* dms_SectorInfoDefineArchitecture()
* dms_CellTableInitialize()
* dms_CellTableCheckValidity()
* Uses:
* dms_CellTableGetBestSectorToErase()
* dms_SectorInfoGetBlockCount()
* dms_BlockTableReadTable()
* dms_CellTableMoveBlock()
* dms_BlockRead()
* dms_BlockWrite()
* dms_BlockTableWriteBlockStatus()
* dms_SectorFormat()
* dms_SectorInitialize()
* Used By:
* dms_CellWrite()
* dms_CellInitialize()
* dms_Cleanup()
*/
DMS_STATUS dms_SectorCleanup(void){
DMS_STATUS eStatus;
WORD wSectorIndex;
WORD wSectorBlockIndex;
WORD wSectorBlockCount;
WORD wNewSectorIndex;
WORD wNewSectorBlockIndex;
BLOCK_TABLE_ENTRY *pBlockTable;
DATABLOCK bData;
eStatus = dms_CellTableGetBestSectorToErase(&wSectorIndex);
/* Could return No_Garbage_Blocks */
if (eStatus != No_Error) {
return eStatus;
}
wSectorBlockCount = dms_SectorInfoGetBlockCount(wSectorIndex);
pBlockTable = (BLOCK_TABLE_ENTRY*) malloc(sizeof(BLOCK_TABLE_ENTRY) * wSectorBlockCount);
if (pBlockTable == NULL) {
return Out_Of_Memory_Error;
}
eStatus = dms_BlockTableReadTable(wSectorIndex,pBlockTable,wSectorBlockCount);
if (eStatus != No_Error) {
free(pBlockTable);
return eStatus;
}
for (wSectorBlockIndex = 0; wSectorBlockIndex < wSectorBlockCount; wSectorBlockIndex++){
if (pBlockTable[wSectorBlockIndex].bBlockStatus == BlockValid){
eStatus = dms_CellTableMoveBlock(wSectorIndex,wSectorBlockIndex,pBlockTable[wSectorBlockIndex].wCellIndex,
&wNewSectorIndex, &wNewSectorBlockIndex);
if (eStatus != No_Error) {
free(pBlockTable);
return eStatus;
}
eStatus = dms_BlockRead(wSectorIndex,wSectorBlockIndex,(BYTE*)&bData);
if (eStatus != No_Error) {
free(pBlockTable);
return eStatus;
}
eStatus = dms_BlockWrite(pBlockTable[wSectorBlockIndex].wCellIndex,pBlockTable[wSectorBlockIndex].wBlockIndex,
pBlockTable[wSectorBlockIndex].bCellStatus,
wNewSectorIndex,wNewSectorBlockIndex,(BYTE*)&bData);
if (eStatus != No_Error) {
free(pBlockTable);
return eStatus;
}
/* Write Block Status */
eStatus = dms_BlockTableWriteBlockStatus(wSectorIndex,wSectorBlockIndex,BlockErase);
if (eStatus != No_Error) {
free(pBlockTable);
return eStatus;
}
} else {
eStatus = dms_BlockTableWriteBlockStatus(wSectorIndex,wSectorBlockIndex,BlockErase);
if (eStatus != No_Error) {
free(pBlockTable);
return eStatus;
}
}
}
free(pBlockTable);
/* Erases sector and formats the Sector Header */
eStatus = dms_SectorFormat(wSectorIndex, dms_CellInfoGetCount());
if (eStatus != No_Error) {
return eStatus;
}
/* Adds new blocks to available table */
eStatus = dms_SectorInitialize(wSectorIndex);
if (eStatus != No_Error) {
return eStatus;
}
return No_Error;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -