📄 dbmflash2.c
字号:
command is read from cache.
PARAMETERS:
MsgDataP - Pointer to message structure
RETURNED VALUES:
None
*****************************************************************************/
void DbmReadFlashDbMsg(void *MsgDataP)
{
DbmReadMsgT *RxMsgP;
DbmReadRspMsgT *RspMsgP = NULL;
uint32 Address, Index, MsgSize;
/* Cast pointer to read command struct */
RxMsgP = (DbmReadMsgT *) MsgDataP;
/* Check if the data base is not in cache */
if (FlashDbmP->DbCached == FALSE)
{
MonFault(MON_DBM_FAULT_UNIT, DBM_NOT_CACHED_ERR, 0, MON_CONTINUE);
goto exit;
}
/* Range check DB segment address for read */
if (RxMsgP->Address.Segment >= FlashDbmP->Db[RxMsgP->DataBaseId].DbMaxSeg)
{
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) >
(FlashDbmP->Db[RxMsgP->DataBaseId].SegLengthP[RxMsgP->Address.Segment]))
{
MonFault(MON_DBM_FAULT_UNIT, DBM_SEG_SIZE_ERR, 0, MON_CONTINUE);
goto exit;
}
/* Calculate DB address from segment and offset in Rx message */
Address = FlashDbmP->Db[RxMsgP->DataBaseId].SegIndexP[RxMsgP->Address.Segment] +
RxMsgP->Address.Offset;
/* Calculate response msg size */
MsgSize = sizeof(DbmReadRspMsgT) + RxMsgP->NumBytes - sizeof(RspMsgP->Data);
/* Allocate memory for response message */
RspMsgP = (DbmReadRspMsgT *) ExeMsgBufferGet(MsgSize);
/* Fill in response message length, address and size fields */
RspMsgP->DataBaseId = RxMsgP->DataBaseId;
RspMsgP->Address = RxMsgP->Address;
RspMsgP->NumBytes = RxMsgP->NumBytes;
/* Read DB and fill in response message data */
for (Index = 0; Index < RxMsgP->NumBytes; Index++)
RspMsgP->Data[Index] = FlashDbmP->Db[RxMsgP->DataBaseId].DataBaseP[Index + Address];
/* Send response message back to sender of read command */
ExeMsgSend(RxMsgP->RspInfo.TaskId, RxMsgP->RspInfo.MailboxId,
RxMsgP->RspInfo.MsgId, (void *) RspMsgP, MsgSize);
exit:;
}
/*****************************************************************************
FUNCTION NAME: DbmWriteFlashDbMsg
DESCRIPTION:
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;
uint32 Address, Index;
bool WriteThru;
/* Cast pointer to write command struct */
RxMsgP = (DbmWriteMsgT *) MsgDataP;
/* Check if the RAM data base has been cached */
if (FlashDbmP->DbCached == FALSE)
{
MonFault(MON_DBM_FAULT_UNIT, DBM_NOT_CACHED_ERR, 0, MON_CONTINUE);
goto exit;
}
/* Range check DB segment address for write */
if (RxMsgP->Address.Segment >= FlashDbmP->Db[RxMsgP->DataBaseId].DbMaxSeg)
{
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) >
(FlashDbmP->Db[RxMsgP->DataBaseId].SegLengthP[RxMsgP->Address.Segment]))
{
MonFault(MON_DBM_FAULT_UNIT, DBM_SEG_SIZE_ERR, 0, MON_CONTINUE);
goto exit;
}
/* Get response message size */
RspMsgSize = sizeof(DbmWriteRspMsgT);
/* Allocate memory for response message */
RspMsgP = (DbmWriteRspMsgT *)(ExeMsgBufferGet(RspMsgSize));
/* Respond with data base ID requested to write to */
RspMsgP->DataBaseId = RxMsgP->DataBaseId;
/* Default to ACK response */
RspMsgP->AckType = DBM_ACK_TYPE;
/* If NAM write request & NAM is locked ? */
if ((NamLock == TRUE) &&
(RxMsgP->DataBaseId == DBM_CP_DATA_BASE) &&
(RxMsgP->Address.Segment == DBM_PSW_NAM1_SEG || RxMsgP->Address.Segment == DBM_PSW_NAM2_SEG))
{
/* 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 cache or flash */
return;
}
/* 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) )
{
/* 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 cache or flash */
return;
}
/* Calculate DB address from segment and offset */
Address = FlashDbmP->Db[RxMsgP->DataBaseId].SegIndexP[RxMsgP->Address.Segment] +
RxMsgP->Address.Offset;
/* Indicate the cache has changed */
FlashDbmP->DbChanged = TRUE;
/* Read data from message and write to cache data base */
for (Index = 0; Index < RxMsgP->NumBytes; Index++)
{
/* Update the RAM cache data base */
FlashDbmP->Db[RxMsgP->DataBaseId].DataBaseP[Address + Index] = RxMsgP->Data[Index];
}
WriteThru = RxMsgP->WriteThru;
/* 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);
/* If write through is enabled then write the data base to flash. */
if (WriteThru == TRUE)
{
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 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 response message back to sender of write message */
ExeMsgSend(RxMsgP->RspInfo.TaskId, RxMsgP->RspInfo.MailboxId,
RxMsgP->RspInfo.MsgId, (void *)RspMsgP, RspMsgSize);
/* Notify PSW if ETS is writing to the NAM data area */
if ( (RxMsgP->DataBaseId == DBM_CP_DATA_BASE) &&
((RxMsgP->RspInfo.MailboxId == IOP_MAILBOX_ETS) && (RxMsgP->RspInfo.TaskId != EXE_PSW_ID)) &&
(RxMsgP->Address.Segment == DBM_PSW_NAM1_SEG || RxMsgP->Address.Segment == DBM_PSW_NAM2_SEG) )
{
/* 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));
}
/* If write through is enabled then prepare the alternate flash
section for use by erasing it. Then set the data structure
to point to the alternate flash section.
NOTE: It is important that the alternate flash section is not
erased until 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. */
if (WriteThru == TRUE)
{
HwdFlashErase(FlashDbmP->FlashSection2);
SwapFlashSections();
FlashDbmP->DbChanged = FALSE;
}
exit:;
}
/*****************************************************************************
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;
/* Check if the RAM data base has been cached. If not cached exit */
if (FlashDbmP->DbCached == FALSE)
{
MonFault(MON_DBM_FAULT_UNIT, DBM_NOT_CACHED_ERR, 0, MON_CONTINUE);
goto exit;
}
/* 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[0].DataBaseP[0] = (uint8)(DBM_MARKER_VALUE & 0xFF);
FlashDbmP->Db[0].DataBaseP[1] = (uint8)(DBM_MARKER_VALUE >> 8);
FlashDbmP->Db[1].DataBaseP[0] = (uint8)(DBM_MARKER_VALUE & 0xFF);
FlashDbmP->Db[1].DataBaseP[1] = (uint8)(DBM_MARKER_VALUE >> 8);
/*
If any element in the data base changed then write the
data base to flash.
*/
if (FlashDbmP->DbChanged == TRUE)
{
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 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 response message back to sender of write command */
ExeMsgSend(RxMsgP->RspInfo.TaskId, RxMsgP->RspInfo.MailboxId,
RxMsgP->RspInfo.MsgId, NULL, 0);
/* If the data base has changed then prepare the alternate
flash section for use by erasing it. Then swap the
data structure flash sections.
NOTE: It is important that the alternate flash section is
not erased until 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. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -