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

📄 sector.c.bak

📁 AMD公司官方版FLASH文件系统。有详细说明文档和Windows仿真测试环境。
💻 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 + -