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

📄 dbmflash.c

📁 norflash的文件系统。 用于中低端手机开发的参考
💻 C
📖 第 1 页 / 共 3 页
字号:
/*****************************************************************************
 
  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
    -------------------
    ReadItem
    WriteItem

 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"

#include "fsmapi.h"
#include "fsmdataitem.h"
#include "sidbdefs.h"

static bool	ReadItem(uint16 type, uint16 id, uint32 offset, void *data, uint32 length);
static bool	WriteItem(uint16 type, uint16 id, uint32 offset, void *data, uint32 length);

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

#define DBM_PATH	"vt/dbmfile"

#define DBM_ITEM_CP_TYPE		ITEM_DBM_CP_TYPE
#define DBM_ITEM_RF_TYPE		ITEM_DBM_RF_TYPE

#define DBM_MAX_WRITE_TRY	3
#define DBM_SLEEP_TICKS		20

#define MAKE_LONG(a,b)		((((long)(a)) << 16) | ((long)(b)))

#define FILE_NAME_SIZE		128

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

/*---------------------------------------------------------------
* Declare data base 2 (RF) local variables
*----------------------------------------------------------------*/

/* Define RF data base segment length array */
static const uint16 SegLengthRF[] = {DBM_RF_SEGMENT_SIZES};
static uint16		MaxRFSegLength;

/*---------------------------------------------------------------*/

/* lock DBM Cache NAM & NVM NAM */
static bool NamLock;
   
/*****************************************************************************
 
  FUNCTION NAME: DbmInitFlash

  DESCRIPTION:

    This routine handles Flash based DBM initialization.

  PARAMETERS:

    None
    
  RETURNED VALUES:

    None

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

void DbmInitFlash(void)
{
	HFSMFILE		handle;
	uint16			max_len;
	uint32			i;

	max_len = 0;

	for( i = 0; i < DBM_MAX_SEG_CP_DB; i++)
	{
		if(SegLengthCP[i] > max_len)
			max_len = SegLengthCP[i];
	}

	MaxCPSegLength = max_len + 4;

	max_len = 0;

	for(i = 0; i < DBM_MAX_SEG_RF_DB; i++)
	{
		if(SegLengthRF[i] > max_len)
			max_len = SegLengthRF[i];
	}

	MaxRFSegLength = max_len + 4;

	handle = FsmOpenDir(DBM_PATH);

	if(handle == INVALID_FILE_HANDLE)
	{
		FsmMakeDir(DBM_PATH);
	}
	else
	{
		FsmCloseDir(handle);
	}

	/* 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;


   uint16			i;
   uint16			type;
   uint32			maxsize;
   bool				status;
   uint8			*pBuffer;


   /* 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 all data.
 */


   maxsize = MaxCPSegLength > MaxRFSegLength ? MaxCPSegLength : MaxRFSegLength;

   pBuffer = (uint8 *)ExeMsgBufferGet(maxsize);

   if(pBuffer == NULL)
   {
      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, 0x55AA, MON_CONTINUE); 

      /* Don't clear cache or flash */
      return;
   }

   memset(pBuffer, 0, maxsize);

   if(RxMsgP->DataBaseId == DBM_CP_DATA_BASE)
   {
/*	   MonPrintf("\n\n clear CP.........\n\n");*/
     type = DBM_ITEM_CP_TYPE;

	   for(i = 0; i < DBM_MAX_SEG_CP_DB; i++)
	   {
		   status = WriteItem(type, i, 0, pBuffer, SegLengthCP[i]);

		   if(!status)
			   MonFault(MON_DBM_FAULT_UNIT, DBM_WRITE_ERR, MAKE_LONG(type, i), MON_CONTINUE);
	   }
   }
   else if(RxMsgP->DataBaseId == DBM_RF_DATA_BASE)
   {
/*	   MonPrintf("\n\n clear RF.........\n\n");*/
     type = DBM_ITEM_RF_TYPE;

	   for(i = 0; i < DBM_MAX_SEG_RF_DB; i++)
	   {
		   status = WriteItem(type, i, 0, pBuffer, SegLengthRF[i]);

		   if(!status)
			   MonFault(MON_DBM_FAULT_UNIT, DBM_WRITE_ERR, MAKE_LONG(type, i), MON_CONTINUE);
	   }
   }

   ExeMsgBufferFree(pBuffer);

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

}


/*****************************************************************************
 
  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
    command is read from cache.

  PARAMETERS:

    MsgDataP - Pointer to message structure
    
  RETURNED VALUES:

    None

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

void DbmReadFlashDbMsg(void *MsgDataP)
{
	DbmReadMsgT    *RxMsgP;
	DbmReadRspMsgT *RspMsgP = NULL;
	uint32          MsgSize;

	uint16			MaxSeg;
	uint16			type;
	uint16			Id;
	bool			status;
	uint16			NumBytes;
	const uint16 *	pSegLength;

	/* Cast pointer to read command struct */
	RxMsgP = (DbmReadMsgT *) MsgDataP;

	MsgSize = sizeof(DbmReadRspMsgT) + RxMsgP->NumBytes - sizeof(RspMsgP->Data);

	RspMsgP = (DbmReadRspMsgT *) ExeMsgBufferGet(MsgSize);

	if(RspMsgP == NULL)
	{
		MonPrintf("\nBuffer get failure in DBM read!\n");
		return;
	}

	RspMsgP->DataBaseId = RxMsgP->DataBaseId;
	RspMsgP->Address    = RxMsgP->Address;

	NumBytes = 0;

/*	MonPrintf("\n ReadDB: Task Id = %d, Database ID = %x, seg = %x \n", 
			RxMsgP->RspInfo.TaskId, 
			RxMsgP->DataBaseId, 
			RxMsgP->Address.Segment);*/

	Id = RxMsgP->Address.Segment;

	if(RxMsgP->DataBaseId == DBM_CP_DATA_BASE)
	{
    type = DBM_ITEM_CP_TYPE;
		MaxSeg = DBM_MAX_SEG_CP_DB;

		pSegLength = &SegLengthCP[0];
	}
	else if(RxMsgP->DataBaseId == DBM_RF_DATA_BASE)
	{
    type = DBM_ITEM_RF_TYPE;
		MaxSeg = DBM_MAX_SEG_RF_DB;

		pSegLength = &SegLengthRF[0];
	}
	else
	{
		MonPrintf("\nDataBaseId error in DBM read\n");
		goto exit;
	}

	/* Range check DB segment address for read */
	if (RxMsgP->Address.Segment >= MaxSeg)
	{
		MonFault(MON_DBM_FAULT_UNIT, DBM_SEG_NUM_ERR, RxMsgP->Address.Segment, 
			MON_CONTINUE); 
		goto exit;
	}

	/* Range check DB segment size for read */
	if ((RxMsgP->Address.Offset + RxMsgP->NumBytes) > pSegLength[RxMsgP->Address.Segment])
	{
		MonFault(MON_DBM_FAULT_UNIT, DBM_SEG_SIZE_ERR, 0, MON_CONTINUE); 
		goto exit;
	}

	RspMsgP->NumBytes   = RxMsgP->NumBytes;
   	status = ReadItem(type, Id, RxMsgP->Address.Offset, (void *)(&(RspMsgP->Data[0])), RxMsgP->NumBytes);

	if(!status)
	{
		MonPrintf("\nDBM read failure!\n");
		NumBytes = 0;
		goto exit;
	}

	NumBytes = RxMsgP->NumBytes;

exit:

	RspMsgP->NumBytes = NumBytes;

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

/*	MonPrintf("Read Done-------<<<<<<<\n");*/
}


/*****************************************************************************
 
  FUNCTION NAME: DbmWriteFlashDbMsg 

  DESCRIPTION:

⌨️ 快捷键说明

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