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

📄 dbmflash2.c

📁 norflash的文件系统。 用于中低端手机开发的参考
💻 C
📖 第 1 页 / 共 4 页
字号:
/*****************************************************************************
 
  FILE NAME: dbmflash.c

  DESCRIPTION:

    This file contains the Data Base Manager (DBM) Flash routines. 
    The DBM maintains a data base in Flash memory allowing data to 
    survive across power cycles. 

  PROCEDURES IN THIS SOURCE FILE:

    Global Procedures
    -------------------
    DbmInitFlash
    DbmClearFlashDbMsg
    DbmReadFlashDbMsg
    DbmWriteFlashDbMsg
    DbmCacheFlashDbMsg
    DbmFlushFlashDbMsg
    DbmBlkWriteFlashDbMsg 
    DbmBlkReadFlashDbMsg 
    DbmNAMLockUnlockDbMsg

    Local Procedures
    -------------------
    CacheDb
    FlashProgram
    SwapFlashSections

 Copyright (c) 1998 - 2002 LSI Logic. All rights reserved. LSI Confidential information.
 Copyright (c) 2002, VIA Technologies, Inc.
*****************************************************************************/

#include "dbmapi.h"
#include "dbmdefs.h"
#include "dbmerrs.h"
#include "exeapi.h"
#include "hwddefs.h"
#include "hwdapi.h"
#include "monapi.h"
#include "sysdefs.h"
#include "sysapi.h"
#include "hwdflash.h"
#include "pswapi.h"
#include "iopapi.h"

/*----------------------------------------------------------------
* Define Local typedefs and defines
*----------------------------------------------------------------*/

typedef struct 
{
   const   uint16 FlashOffset;          /* Flash offset, in 16-bit words */
   const   uint16 *SegIndexP;           /* Segment index data pointer */
   const   uint16 *SegLengthP;          /* Segment length data pointer */
   uint8  *DataBaseP;                   /* Data base cache pointer */
   uint16  DbTotalSize;                 /* Data base total size */
   uint16  DbMaxSeg;                    /* Data base maximum segment # */
}DbParamsT;

typedef struct 
{
   HwdFlashSectionTypeT FlashSection1;  /* Flash section in use */
   HwdFlashSectionTypeT FlashSection2;  /* Alternate flash section */
   bool                 DbChanged;      /* Data base changed flag */
   bool                 DbCached;       /* Data Base cached flag */
   DbParamsT            Db[2];          /* Data base parameters */
}FlashDbmT;

typedef uint32 BlkDbSizeT;              /* Block data base size */

/* 
   This value is always written by the dbm to the first word location in 
   the non-block dbm flash section. It is later used at power up 
   initialization to determine whether or not the flash section contains 
   valid data.
*/

#define DBM_MARKER_VALUE  0xCD95

/*---------------------------------------------------------------
* Declare data base 1 (CP) local variables
*----------------------------------------------------------------*/
   
/* Define CP data base segment length array */
static const uint16 SegLengthCP[] = {DBM_CP_SEGMENT_SIZES};

/* Define CP data base segment index array */
static const uint16 SegIndexCP[] = {DBM_CP_SEGMENT_INDEXES};

/* CP data base cache */
static uint8 DataBaseCP[DBM_CP_CACHE_SIZE];

/*---------------------------------------------------------------
* Declare data base 2 (RF) local variables
*----------------------------------------------------------------*/
   
/* Define RF data base segment length array */
static const uint16 SegLengthRF[] = {DBM_RF_SEGMENT_SIZES};

/* Define RF data base segment index array */
static const uint16 SegIndexRF[] = {DBM_RF_SEGMENT_INDEXES};

/* RF data base cache */
static uint8 DataBaseRF[DBM_RF_CACHE_SIZE];

/*---------------------------------------------------------------
*  Declare DBM local variables
*----------------------------------------------------------------*/

/* Pointer to flash data base structure */
static FlashDbmT *FlashDbmP; 

/* Flash data base data structure */
static FlashDbmT FlashDbm = 
{
   HWD_FLASH_CP_DATA_BASE_SECTION_1,   /* One of two flash sections used by DBM */
   HWD_FLASH_CP_DATA_BASE_SECTION_2,   /* The other flash section used by DBM */
   FALSE,                              /* Data base changed flag */
   FALSE,                              /* Data base cached flag */

   DBM_CP_FLASH_OFFSET/sizeof(uint16), /* Flash section offset for CP data base */
   &SegIndexCP[0],                     /* CP data base segment index array */
   &SegLengthCP[0],                    /* CP data base segment length array */
   &DataBaseCP[0],                     /* CP data base cache */
   sizeof(DataBaseCP),                 /* CP data base size */
   DBM_MAX_SEG_CP_DB,                  /* Largest segment supported for CP data base */

   DBM_RF_FLASH_OFFSET/sizeof(uint16), /* Flash section offset for RF data base */
   &SegIndexRF[0],                     /* RF data base segment index array */
   &SegLengthRF[0],                    /* RF data base segment length array */
   &DataBaseRF[0],                     /* RF data base cache */
   sizeof(DataBaseRF),                 /* RF data base size */
   DBM_MAX_SEG_RF_DB,                  /* Largest segment supported for RF data base */
};

/* lock DBM Cache NAM & NVM NAM */
static bool NamLock;
   
/*---------------------------------------------------------------
*  Declare function prototypes for local routines in this file
*----------------------------------------------------------------*/

static void CacheDb(void);
static void SwapFlashSections(void);
static void FlashProgram(HwdFlashSectionTypeT FlashSection, uint16 FlashOffset, 
                         uint8 *Source, uint16 ByteCount);

/*****************************************************************************
 
  FUNCTION NAME: DbmInitFlash

  DESCRIPTION:

    This routine handles Flash based DBM initialization.

  PARAMETERS:

    None
    
  RETURNED VALUES:

    None

*****************************************************************************/

void DbmInitFlash(void)
{
   uint16 Section1Marker, Section2Marker;
   uint32 DbSize;

   /* Point to the data base structure of interest */
   FlashDbmP = &FlashDbm;

   /* Calculate size of CP data base sector */
   DbSize = HwdFlashSectionSize(HWD_FLASH_CP_DATA_BASE_SECTION_1);


   /* Compare size of flash sector to the size of the actual data bases (CP & RF)
      and declare an error if flash sector size < data base size */
   if (DbSize < FlashDbmP->Db[0].DbTotalSize + FlashDbmP->Db[1].DbTotalSize)
      MonFault(MON_DBM_FAULT_UNIT, DBM_FLASH_TOO_SMALL_ERR, DbSize, MON_CONTINUE); 

   /* Two flash sections are used to maintain the data base. 

      The two sections are alternately selected between writes to flash
      in order to minimize impact on system performance due to erase times. */

   /* Read the first byte from each of these sections and check if it is
      equal to DBM_MARKER_VALUE. If not then that section doesn't contain 
      valid data and probably should be erased. If it does then the section
      contains valid data and should be used accordingly.  */

   HwdFlashRead(HWD_FLASH_CP_DATA_BASE_SECTION_1, 0, (uint8 *)&Section1Marker, 2);
   HwdFlashRead(HWD_FLASH_CP_DATA_BASE_SECTION_2, 0, (uint8 *)&Section2Marker, 2);

   /* If both sections contain data then something is wrong, 
      only 1 section should contain data while the other section should have
      been in the erased state. */

   if (Section1Marker == DBM_MARKER_VALUE && Section2Marker == DBM_MARKER_VALUE)
      MonFault(MON_DBM_FAULT_UNIT, DBM_FLASH_AMBIGUOUS_ERR, 
               ((Section1Marker << 16) | Section2Marker), MON_CONTINUE); 

   /* Set FlashSection1 to the empty flash sector. FlashSection2
      should be set to the flash sector containing data. */

   if (Section2Marker == DBM_MARKER_VALUE)
   {
      FlashDbmP->FlashSection1 = HWD_FLASH_CP_DATA_BASE_SECTION_1;
      FlashDbmP->FlashSection2 = HWD_FLASH_CP_DATA_BASE_SECTION_2;
   }
   else
   {
      FlashDbmP->FlashSection1 = HWD_FLASH_CP_DATA_BASE_SECTION_2;
      FlashDbmP->FlashSection2 = HWD_FLASH_CP_DATA_BASE_SECTION_1;
   }

   /* Erase flash section 1 since it has been set to empty */
   HwdFlashErase(FlashDbmP->FlashSection1);

   /* Cache the CP RAM data base from Flash */
   CacheDb();

   /* lock DBM Cache NAM & NVM NAM */
   NamLock = TRUE;

}


/*****************************************************************************
 
  FUNCTION NAME: DbmClearFlashDbMsg 

  DESCRIPTION:

    This routine handles the clear data base message. When this message
    is received the entire cache is cleared. The flash section associated
    with the data base is then erased.

  PARAMETERS:

    MsgDataP - Pointer to message structure
    
  RETURNED VALUES:

    None

*****************************************************************************/

void DbmClearFlashDbMsg(void *MsgDataP)
{
   DbmClearMsgT    *RxMsgP;
   DbmClearRspMsgT *RspMsgP;
   uint32           RspMsgSize;

   /* Cast pointer to data base manager clear message structure */
   RxMsgP = (DbmClearMsgT *) MsgDataP;

   /* Get response message size */
   RspMsgSize = sizeof(DbmClearRspMsgT);

   /* Allocate memory for response message */
   RspMsgP = (DbmClearRspMsgT *)(ExeMsgBufferGet(RspMsgSize));

   /* Return data base ID in response message */
   RspMsgP->DataBaseId = RxMsgP->DataBaseId;

   /* Default to returning ACK in response message */
   RspMsgP->AckType = DBM_ACK_TYPE;

   /* If NAM is locked & NAM data base clear request ? */
   if ((NamLock == TRUE) && (RxMsgP->DataBaseId == DBM_CP_DATA_BASE))
   {
      /* NACK response */
      RspMsgP->AckType = DBM_NACK_TYPE;

      /* Send response message back to sender of write message */
      ExeMsgSend(RxMsgP->RspInfo.TaskId, RxMsgP->RspInfo.MailboxId, 
                 RxMsgP->RspInfo.MsgId, (void *) RspMsgP, RspMsgSize);

      
      /* Declare a Mon Fault */
      MonFault(MON_DBM_FAULT_UNIT, DBM_NAM_LOCKED_ERR, 0, MON_CONTINUE); 
      
      /* Don't clear cache or flash */
      return;
   }

   /* Clear the cache */
   SysMemset(FlashDbmP->Db[RxMsgP->DataBaseId].DataBaseP, 0, 
             FlashDbmP->Db[RxMsgP->DataBaseId].DbTotalSize);

   /* Indicate the cache is unchanged */
   FlashDbmP->DbChanged = FALSE;

   /* 
      Write the Marker value to the data base, to be used to indicate
      this flash section is "dirty".
      (Two byte operations are done because DataBaseP is a byte pointer
      and can point to an odd location).
   */
   FlashDbmP->Db[RxMsgP->DataBaseId].DataBaseP[0] = (uint8)(DBM_MARKER_VALUE & 0xff);
   FlashDbmP->Db[RxMsgP->DataBaseId].DataBaseP[1] = (uint8)(DBM_MARKER_VALUE >> 8);

   /* 
      Write the cleared data base and the other data base to flash
   */
   FlashProgram(FlashDbmP->FlashSection1, FlashDbmP->Db[0].FlashOffset+1,
                &FlashDbmP->Db[0].DataBaseP[2], FlashDbmP->Db[0].DbTotalSize-2);
   FlashProgram(FlashDbmP->FlashSection1, FlashDbmP->Db[1].FlashOffset+1,
                &FlashDbmP->Db[1].DataBaseP[2], FlashDbmP->Db[1].DbTotalSize-2);

   /*
      Write the marker value to the flash
   */
   FlashProgram(FlashDbmP->FlashSection1, FlashDbmP->Db[0].FlashOffset,
                &FlashDbmP->Db[0].DataBaseP[0], 2);
   FlashProgram(FlashDbmP->FlashSection1, FlashDbmP->Db[1].FlashOffset,
                &FlashDbmP->Db[1].DataBaseP[0], 2);

   /* Send ACK in response message */
   ExeMsgSend(RxMsgP->RspInfo.TaskId, RxMsgP->RspInfo.MailboxId, 
              RxMsgP->RspInfo.MsgId, (void *)RspMsgP, RspMsgSize);

   /* 
      NOTE: It is important that the flash is erased AFTER the call
      to ExeMsgSend to allow higher priority tasks to run while the
      flash is being erased. This minimizes the impact of the flash
      erasure time on system performance.
   */
   HwdFlashErase(FlashDbmP->FlashSection2);
   SwapFlashSections();
}


/*****************************************************************************
 
  FUNCTION NAME: DbmReadFlashDbMsg 

  DESCRIPTION:

    This routine handles the read data base message. When this message
    is received data are read from the cache. Data is stored in
    segments and this routine creates a data base address from a
    segment and offset. Then the amount of data specified in the

⌨️ 快捷键说明

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