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

📄 dbmflash.c

📁 norflash的文件系统。 用于中低端手机开发的参考
💻 C
📖 第 1 页 / 共 3 页
字号:
    This routine handles the write data base message. When this
    message is received data from the message is written to the cache 
    and/or the flash if the write thru flag is set. Data is stored 
    in segments and this routine creates a data base address from a 
    segment and offset. Then the amount of data specified is written 
    to the data base address.

  PARAMETERS:

    MsgDataP - Pointer to message structure

  RETURNED VALUES:

    None

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

void DbmWriteFlashDbMsg(void *MsgDataP)
{
	DbmWriteMsgT            *RxMsgP;
	DbmWriteRspMsgT         *RspMsgP;
	uint32                   RspMsgSize;
	PswNamChangedByEtsMsgT  *PswNotifyMsgP;
	PswMsCapDbWriteMsgT     *PswMsCapDbWrite;

	uint16			MaxSeg;
	uint16			Id;
	const uint16 *	pSegLength;
	uint16			type;
	bool			status;
	bool			bNamSeg;
	DbmAckTypeT		AckType;

	RxMsgP = (DbmWriteMsgT *) MsgDataP;

	RspMsgSize = sizeof(DbmWriteRspMsgT);

	RspMsgP = (DbmWriteRspMsgT *)(ExeMsgBufferGet(RspMsgSize));

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

	RspMsgP->DataBaseId = RxMsgP->DataBaseId;

	AckType = DBM_NACK_TYPE;

	bNamSeg = FALSE;

/*	MonPrintf("\n WriteDB: 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];

		if((RxMsgP->Address.Segment == DBM_PSW_NAM1_SEG) || 
		   (RxMsgP->Address.Segment == DBM_PSW_NAM2_SEG))
		{
			bNamSeg = TRUE;
		}
	}
	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 write\n");
		goto exit;
	}

	/* Range check DB segment address for write */
	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 write */
	if ((RxMsgP->Address.Offset + RxMsgP->NumBytes) > pSegLength[RxMsgP->Address.Segment])
	{
		MonFault(MON_DBM_FAULT_UNIT, DBM_SEG_SIZE_ERR, 0, MON_CONTINUE); 
		goto exit;
	}

	/* If NAM write request & NAM is locked ? */
	if ((NamLock == TRUE) && (bNamSeg == TRUE))
	{
		/* NACK response */
		RspMsgP->AckType = DBM_NACK_TYPE;

		/* Send NACK 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 write to flash */
		return;
	}

/*---------------   for debug begin  ------------*/

		if(bNamSeg == TRUE)
		{
			MonPrintf("\n WriteDB: Task Id = %d, Database ID = %x, seg = %x \n", 
					RxMsgP->RspInfo.TaskId, 
					RxMsgP->DataBaseId, 
					RxMsgP->Address.Segment);

			MonPrintf("  NAM->CPCA = %d\n", ((PswIs95NamT *)(&RxMsgP->Data[0]))->CPCA);
		}

/*---------------   for debug end  ------------*/


	/* Notify PSW if ETS is writing to the MS CAP DB data area */
	if ((RxMsgP->DataBaseId == DBM_CP_DATA_BASE) &&
		(RxMsgP->Address.Segment == DBM_PSW_MS_CAP_DB_SEG) &&
		(RxMsgP->RspInfo.MsgId == IOP_CP_DB_WRITE_ETS))
	{
		RspMsgP->AckType = DBM_ACK_TYPE;

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

		PswMsCapDbWrite	= (PswMsCapDbWriteMsgT *)ExeMsgBufferGet(sizeof(PswMsCapDbWriteMsgT));

		*PswMsCapDbWrite = *((PswMsCapDbWriteMsgT *) RxMsgP->Data);

		/* Send MS CAP DB WRITE Notification message to PSW */
		ExeMsgSend(EXE_PSW_ID, PSW_MAILBOX_CMD, PSW_MS_CAP_DB_WRITE_MSG,
				 (void *) PswMsCapDbWrite, sizeof(PswMsCapDbWriteMsgT));

		/* Don't write to flash */
		return;
	}
	
	status = WriteItem(type, Id, RxMsgP->Address.Offset, (void *)&RxMsgP->Data[0], RxMsgP->NumBytes);


	if(!status)
	{
		MonPrintf("\nDBM write failure!\n");
		goto exit;
	}

	AckType = DBM_ACK_TYPE;

exit:

	RspMsgP->AckType = AckType;

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

	if(AckType == DBM_ACK_TYPE)
	{
		/* Notify PSW if ETS is writing to the NAM data area */
		if ((RxMsgP->RspInfo.MailboxId == IOP_MAILBOX_ETS) 
			&& (RxMsgP->RspInfo.TaskId != EXE_PSW_ID) 
			&& (bNamSeg == TRUE))
		{
			/* Allocate memory for Notify message */
			PswNotifyMsgP = (PswNamChangedByEtsMsgT *) ExeMsgBufferGet(sizeof(PswNamChangedByEtsMsgT));

			/* Fill in Notify message fields */
			if (RxMsgP->Address.Segment == DBM_PSW_NAM1_SEG)
				PswNotifyMsgP->namNumber     = NAM_1;
			else /* Assume secondary DBM_PSW_NAM2 segment */
				PswNotifyMsgP->namNumber     = NAM_2;

			PswNotifyMsgP->whatChangedInNam = 0xFFFFFFFF;

			/* Send Notify message to PSW */
			ExeMsgSend(EXE_PSW_ID, PSW_MAILBOX_CMD, PSW_NAM_CHANGED_BY_ETS_MSG,
					 (void *) PswNotifyMsgP, sizeof(PswNamChangedByEtsMsgT));
		}

	}

/*	MonPrintf("Write Done------->>>>>\n");*/
}


/*****************************************************************************
    
  FUNCTION NAME: DbmFlushFlashDbMsg

  DESCRIPTION:

    This routine handles the flush data base message. When this message
    is received the entire cache is written to the flash.

  PARAMETERS:

    MsgDataP - Pointer to message structure

  RETURNED VALUES:

    None

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

void DbmFlushFlashDbMsg(void *MsgDataP)
{
	DbmFlushMsgT *RxMsgP;

	/* Cast pointer to flush command struct */
	RxMsgP = (DbmFlushMsgT *) MsgDataP;

	FsmDataItemFlushAll();

	/* Send response message back to sender of write command */
	ExeMsgSend(RxMsgP->RspInfo.TaskId, RxMsgP->RspInfo.MailboxId, 
			   RxMsgP->RspInfo.MsgId, NULL, 0);

}


/*****************************************************************************
    
  FUNCTION NAME: DbmCacheFlashDbMsg

  DESCRIPTION:

    This routine handles the cache data base message. When this message
    is received the entire data base is read from flash and written to 
    cache.

  PARAMETERS:

    MsgDataP - Pointer to message structure

  RETURNED VALUES:

    None

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

void DbmCacheFlashDbMsg(void *MsgDataP)
{
	DbmCacheMsgT *RxMsgP;

	/* Cast pointer to cache command struct */
	RxMsgP = (DbmCacheMsgT *) MsgDataP;

	/* Send response message back to sender of write command */
	ExeMsgSend(RxMsgP->RspInfo.TaskId, RxMsgP->RspInfo.MailboxId, 
			   RxMsgP->RspInfo.MsgId, NULL, 0);
}


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

  FUNCTION NAME: DbmBlkReadFlashDbMsg 

  DESCRIPTION:

    This routine handles the read block data base message. 
    Since a block data base does not have a cache, when this
    message is received data is read directly from flash. This 
    routine calculates a flash read address from the data base 
    id and the requested offset. Also, since the data base 
    size is stored in the first four bytes of the flash section,
    the flash read address is incremented by four to take the 
    data base size into account. Then the number of bytes to 
    read specified in the message are read from flash.

  PARAMETERS:

    MsgDataP - Pointer to message structure
    
  RETURNED VALUES:

    None

*****************************************************************************/
void DbmBlkReadFlashDbMsg(void *MsgDataP)
{
	DbmBlkReadMsgT *	RxMsgP;
	DbmBlkReadRspMsgT *	RspMsgP;
	uint16				NumBytes = 0;

	char				filename[FILE_NAME_SIZE];

	HFSMFILE			handle = INVALID_FILE_HANDLE;
	uint32				item_length = 0;

	/* Cast pointer to read message struct */
	RxMsgP = (DbmBlkReadMsgT *) MsgDataP;

/*	MonPrintf("\n Read BLOCK DB: Task Id = %d, Database ID = %x \n", 
			RxMsgP->RspInfo.TaskId, 
			RxMsgP->DataBaseId);*/

	/* Allocate memory buffer for response message */
	RspMsgP = (DbmBlkReadRspMsgT *) ExeMsgBufferGet(sizeof(DbmBlkReadRspMsgT));

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

	/* Fill in response message data base id, data base length, offset and num bytes */
	RspMsgP->DataBaseId = RxMsgP->DataBaseId;

	/* Set the offset from the received message */
	RspMsgP->Offset = RxMsgP->Offset;

	NumBytes = 0;

	/* Determine the flash section to be read */
	switch(RxMsgP->DataBaseId)
	{
	case DBM_DS_DATA_BASE:
		break;

	case DBM_PRL1_DATA_BASE:
		break;

	case DBM_PRL2_DATA_BASE:
		break;

	case DBM_VREC1_DATA_BASE:
		break;

	case DBM_VREC2_DATA_BASE:
		break;

	case DBM_VMEM1_DATA_BASE:
		break;

	case DBM_VMEM2_DATA_BASE:
		break;

	default:
		MonFault(MON_DBM_FAULT_UNIT, DBM_BLK_DB_ID_ERR, 
			  RxMsgP->DataBaseId, MON_CONTINUE);
		goto exit;
		break;
	}

	sprintf(filename, "%s/blockdb%04x.dbf", DBM_PATH, RxMsgP->DataBaseId);

	if((handle = FsmOpen(filename, FSM_OPEN_EXISTING | FSM_OPEN_READ)) == INVALID_FILE_HANDLE)
	{
		NumBytes = 0;
		item_length = 0;
		goto exit;
	}

	MonPrintf("\n opened %d\n", RxMsgP->DataBaseId);

	FsmSeek(handle, 0, FSM_FILE_END);

	item_length = (uint32)FsmTell(handle);

	if(RxMsgP->Offset >= item_length)
	{
		NumBytes = 0;
		goto exit;
	}

	/* Set the number of bytes requested */
	NumBytes = RxMsgP->NumBytes;

	if(RxMsgP->Offset + NumBytes > item_length)
	{
		NumBytes = (uint16)(item_length - RxMsgP->Offset);
	}

	if(NumBytes == 0)
	{
		goto exit;
	}

	FsmSeek(handle, RxMsgP->Offset, FSM_FILE_BEGIN);

	NumBytes = FsmRead(handle, (uint8 *)&RxMsgP->DataP[0], NumBytes);

exit:

	if (handle != INVALID_FILE_HANDLE)
	{
		FsmClose(handle);
		handle = INVALID_FILE_HANDLE;

⌨️ 快捷键说明

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