📄 dbmflash.c
字号:
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 + -