diff --git a/fsw/inc/mm_msg.h b/fsw/inc/mm_msg.h index 844baf8..549332c 100644 --- a/fsw/inc/mm_msg.h +++ b/fsw/inc/mm_msg.h @@ -322,7 +322,7 @@ typedef struct uint8 CmdCounter; /**< \brief MM Application Command Counter */ uint8 ErrCounter; /**< \brief MM Application Command Error Counter */ uint8 LastAction; /**< \brief Last command action executed */ - uint8 Padding; /**< \brief Last command action executed */ + uint8 EepromWriteEnabledMask; /**< \brief EEPROM bank write-enable status (bit mask) */ MM_MemType_t MemType; /**< \brief Memory type for last command */ cpuaddr Address; /**< \brief Fully resolved address used for last command */ uint32 DataValue; /**< \brief Last command data (fill pattern or peek/poke value) */ diff --git a/fsw/src/mm_app.c b/fsw/src/mm_app.c index 61659ae..2ce2f72 100644 --- a/fsw/src/mm_app.c +++ b/fsw/src/mm_app.c @@ -147,6 +147,7 @@ CFE_Status_t MM_AppInit(void) */ MM_AppData.HkPacket.Payload.CmdCounter = 0; MM_AppData.HkPacket.Payload.ErrCounter = 0; + MM_AppData.EepromWriteEnabledMask = 0; /* Initialize all EEPROM banks as write-disabled */ /* ** Register for event services @@ -388,6 +389,11 @@ void MM_AppPipe(const CFE_SB_Buffer_t *BufPtr) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void MM_HousekeepingCmd(const CFE_SB_Buffer_t *BufPtr) { + /* + ** Get the latest EEPROM bank write-enable status + */ + MM_AppData.HkPacket.Payload.EepromWriteEnabledMask = MM_AppData.EepromWriteEnabledMask; + /* ** Send housekeeping telemetry packet */ @@ -561,6 +567,12 @@ bool MM_EepromWriteEnaCmd(const CFE_SB_Buffer_t *BufPtr) MM_AppData.HkPacket.Payload.LastAction = MM_EEPROMWRITE_ENA; MM_AppData.HkPacket.Payload.MemType = MM_EEPROM; + /* Update EEPROM write-enable status mask (set the bit for this bank) */ + if (CmdPtr->Payload.Bank < 8) + { + MM_AppData.EepromWriteEnabledMask |= (1 << CmdPtr->Payload.Bank); + } + CFE_EVS_SendEvent(MM_EEPROM_WRITE_ENA_INF_EID, CFE_EVS_EventType_INFORMATION, "EEPROM bank %d write enabled, cFE_Status= 0x%X", (int)CmdPtr->Payload.Bank, (unsigned int)cFE_Status); @@ -599,6 +611,13 @@ bool MM_EepromWriteDisCmd(const CFE_SB_Buffer_t *BufPtr) MM_AppData.HkPacket.Payload.LastAction = MM_EEPROMWRITE_DIS; MM_AppData.HkPacket.Payload.MemType = MM_EEPROM; Result = true; + + /* Update EEPROM write-enable status mask (clear the bit for this bank) */ + if (CmdPtr->Payload.Bank < 8) + { + MM_AppData.EepromWriteEnabledMask &= ~(1 << CmdPtr->Payload.Bank); + } + CFE_EVS_SendEvent(MM_EEPROM_WRITE_DIS_INF_EID, CFE_EVS_EventType_INFORMATION, "EEPROM bank %d write disabled, cFE_Status= 0x%X", (int)CmdPtr->Payload.Bank, (unsigned int)cFE_Status); diff --git a/fsw/src/mm_app.h b/fsw/src/mm_app.h index e6fbeb3..1da55ee 100644 --- a/fsw/src/mm_app.h +++ b/fsw/src/mm_app.h @@ -75,6 +75,9 @@ typedef struct uint32 RunStatus; /**< \brief Application run status */ + uint8 EepromWriteEnabledMask; /**< \brief EEPROM bank write-enable status. Max 8 banks */ + uint8 Padding[3]; /**< \brief Structure padding for clear 32-bit alignment */ + uint32 LoadBuffer[MM_MAX_LOAD_DATA_SEG / 4]; /**< \brief Load file i/o buffer */ uint32 DumpBuffer[MM_MAX_DUMP_DATA_SEG / 4]; /**< \brief Dump file i/o buffer */ uint32 FillBuffer[MM_MAX_FILL_DATA_SEG / 4]; /**< \brief Fill memory buffer */ diff --git a/unit-test/mm_app_tests.c b/unit-test/mm_app_tests.c index 52dfd0a..a9597f0 100644 --- a/unit-test/mm_app_tests.c +++ b/unit-test/mm_app_tests.c @@ -75,7 +75,7 @@ void MM_AppMain_Test_Nominal(void) CFE_MSG_FcnCode_t FcnCode = MM_NOOP_CC; size_t forced_Size = sizeof(UT_CmdBuf.NoArgsCmd); CFE_SB_Buffer_t Buf; - CFE_SB_Buffer_t * BufPtr = &Buf; + CFE_SB_Buffer_t *BufPtr = &Buf; /* Set to exit loop after first run */ UT_SetDeferredRetcode(UT_KEY(CFE_ES_RunLoop), 1, true); @@ -237,6 +237,7 @@ void MM_AppInit_Test_Nominal(void) UtAssert_True(MM_AppData.RunStatus == CFE_ES_RunStatus_APP_RUN, "MM_AppData.RunStatus == CFE_ES_RunStatus_APP_RUN"); UtAssert_INT32_EQ(MM_AppData.HkPacket.Payload.CmdCounter, 0); UtAssert_INT32_EQ(MM_AppData.HkPacket.Payload.ErrCounter, 0); + UtAssert_True(MM_AppData.EepromWriteEnabledMask == 0, "MM_AppData.EepromWriteEnabledMask initialized to 0"); UtAssert_INT32_EQ(context_CFE_EVS_SendEvent[0].EventID, MM_INIT_INF_EID); UtAssert_INT32_EQ(context_CFE_EVS_SendEvent[0].EventType, CFE_EVS_EventType_INFORMATION); @@ -1173,6 +1174,9 @@ void MM_HousekeepingCmd_Test(void) strncpy(MM_AppData.HkPacket.Payload.FileName, "name", sizeof(MM_AppData.HkPacket.Payload.FileName) - 1); + /* Set the EEPROM write-enable mask to test a couple of values */ + MM_AppData.EepromWriteEnabledMask = 0x05; /* Banks 0 and 2 enabled */ + /* Execute the function being tested */ MM_HousekeepingCmd(&UT_CmdBuf.Buf); @@ -1189,6 +1193,10 @@ void MM_HousekeepingCmd_Test(void) strncmp(MM_AppData.HkPacket.Payload.FileName, MM_AppData.HkPacket.Payload.FileName, OS_MAX_PATH_LEN) == 0, "strncmp(MM_AppData.HkPacket.Payload.FileName, MM_AppData.HkPacket.Payload.FileName, OS_MAX_PATH_LEN) == 0"); + /* Verify that the EEPROM write-enable mask was copied to HK packet correctly */ + UtAssert_True(MM_AppData.HkPacket.Payload.EepromWriteEnabledMask == 0x05, + "MM_AppData.HkPacket.Payload.EepromWriteEnabledMask == 0x05"); + call_count_CFE_EVS_SendEvent = UT_GetStubCount(UT_KEY(CFE_EVS_SendEvent)); UtAssert_True(call_count_CFE_EVS_SendEvent == 0, "CFE_EVS_SendEvent was called %u time(s), expected 0", @@ -1485,6 +1493,8 @@ void MM_EepromWriteEnaCmd_Test_Nominal(void) UtAssert_True(MM_AppData.HkPacket.Payload.MemType == MM_EEPROM, "MM_AppData.HkPacket.Payload.MemType == MM_EEPROM"); UtAssert_INT32_EQ(MM_AppData.HkPacket.Payload.CmdCounter, 0); UtAssert_INT32_EQ(MM_AppData.HkPacket.Payload.ErrCounter, 0); + UtAssert_True(MM_AppData.EepromWriteEnabledMask == 0x01, + "MM_AppData.EepromWriteEnabledMask == 0x01 (bank 0 enabled)"); UtAssert_INT32_EQ(context_CFE_EVS_SendEvent[0].EventID, MM_EEPROM_WRITE_ENA_INF_EID); UtAssert_INT32_EQ(context_CFE_EVS_SendEvent[0].EventType, CFE_EVS_EventType_INFORMATION); @@ -1574,6 +1584,8 @@ void MM_EepromWriteDisCmd_Test_Nominal(void) UtAssert_True(MM_AppData.HkPacket.Payload.MemType == MM_EEPROM, "MM_AppData.HkPacket.Payload.MemType == MM_EEPROM"); UtAssert_INT32_EQ(MM_AppData.HkPacket.Payload.CmdCounter, 0); UtAssert_INT32_EQ(MM_AppData.HkPacket.Payload.ErrCounter, 0); + UtAssert_True(MM_AppData.EepromWriteEnabledMask == 0x00, + "MM_AppData.EepromWriteEnabledMask == 0x00 (bank 0 disabled)"); UtAssert_INT32_EQ(context_CFE_EVS_SendEvent[0].EventID, MM_EEPROM_WRITE_DIS_INF_EID); UtAssert_INT32_EQ(context_CFE_EVS_SendEvent[0].EventType, CFE_EVS_EventType_INFORMATION); @@ -1632,6 +1644,73 @@ void MM_EepromWriteDisCmd_Test_Error(void) call_count_CFE_EVS_SendEvent); } +void MM_EepromWriteEnaCmd_Test_MultipleBanks(void) +{ + CFE_SB_MsgId_t TestMsgId = CFE_SB_ValueToMsgId(MM_CMD_MID); + CFE_MSG_FcnCode_t FcnCode = MM_ENABLE_EEPROM_WRITE_CC; + size_t MsgSize = sizeof(UT_CmdBuf.EepromWriteEnaCmd); + + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &MsgSize, sizeof(MsgSize), false); + + UT_SetDefaultReturnValue(UT_KEY(MM_VerifyCmdLength), true); + UT_SetDefaultReturnValue(UT_KEY(CFE_PSP_EepromWriteEnable), CFE_PSP_SUCCESS); + UT_SetDefaultReturnValue(UT_KEY(CFE_PSP_EepromWriteDisable), CFE_PSP_SUCCESS); + + /* Enable bank 3 */ + UT_CmdBuf.EepromWriteEnaCmd.Payload.Bank = 3; + MM_EepromWriteEnaCmd(&UT_CmdBuf.Buf); + UtAssert_True(MM_AppData.EepromWriteEnabledMask == 0x08, + "MM_AppData.EepromWriteEnabledMask == 0x08 (bank 3 enabled)"); + + /* Enable bank 5 (should now have both banks 3 and 5) */ + UT_CmdBuf.EepromWriteEnaCmd.Payload.Bank = 5; + MM_EepromWriteEnaCmd(&UT_CmdBuf.Buf); + UtAssert_True(MM_AppData.EepromWriteEnabledMask == 0x28, + "MM_AppData.EepromWriteEnabledMask == 0x28 (banks 3 and 5 enabled)"); + + /* Disable bank 3 (should now only have bank 5 enabled)*/ + UT_CmdBuf.EepromWriteDisCmd.Payload.Bank = 3; + MM_EepromWriteDisCmd(&UT_CmdBuf.Buf); + UtAssert_True(MM_AppData.EepromWriteEnabledMask == 0x20, + "MM_AppData.EepromWriteEnabledMask == 0x20 (only bank 5 enabled)"); + + /* Test bank above 8 (should not modify mask) */ + UT_CmdBuf.EepromWriteEnaCmd.Payload.Bank = 9; + MM_EepromWriteEnaCmd(&UT_CmdBuf.Buf); + UtAssert_True(MM_AppData.EepromWriteEnabledMask == 0x20, + "MM_AppData.EepromWriteEnabledMask == 0x20 (unchanged for bank >= 8)"); +} + +void MM_EepromWriteDisCmd_Test_BankNumberAboveMaskMax(void) +{ + CFE_SB_MsgId_t TestMsgId = CFE_SB_ValueToMsgId(MM_CMD_MID); + CFE_MSG_FcnCode_t FcnCode = MM_DISABLE_EEPROM_WRITE_CC; + size_t MsgSize = sizeof(UT_CmdBuf.EepromWriteDisCmd); + + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &MsgSize, sizeof(MsgSize), false); + + UT_SetDefaultReturnValue(UT_KEY(MM_VerifyCmdLength), true); + UT_SetDefaultReturnValue(UT_KEY(CFE_PSP_EepromWriteDisable), CFE_PSP_SUCCESS); + + /* Enable banks 0 and 1 */ + MM_AppData.EepromWriteEnabledMask = 0x03; + + /* Test bank above 8 (should not modify mask) */ + UT_CmdBuf.EepromWriteDisCmd.Payload.Bank = 10; + MM_EepromWriteDisCmd(&UT_CmdBuf.Buf); + + UtAssert_True(MM_AppData.EepromWriteEnabledMask == 0x03, + "MM_AppData.EepromWriteEnabledMask == 0x03 (unchanged for bank >= 8)"); + + /* Verify success event */ + UtAssert_INT32_EQ(context_CFE_EVS_SendEvent[0].EventID, MM_EEPROM_WRITE_DIS_INF_EID); + UtAssert_INT32_EQ(context_CFE_EVS_SendEvent[0].EventType, CFE_EVS_EventType_INFORMATION); +} + /* * Register the test cases to execute with the unit test tool */ @@ -1705,7 +1784,11 @@ void UtTest_Setup(void) UtTest_Add(MM_EepromWriteEnaCmd_Test_Nominal, MM_Test_Setup, MM_Test_TearDown, "MM_EepromWriteEnaCmd_Test_Nominal"); UtTest_Add(MM_EepromWriteEnaCmd_Test_Error, MM_Test_Setup, MM_Test_TearDown, "MM_EepromWriteEnaCmd_Test_Error"); + UtTest_Add(MM_EepromWriteEnaCmd_Test_MultipleBanks, MM_Test_Setup, MM_Test_TearDown, + "MM_EepromWriteEnaCmd_Test_MultipleBanks"); UtTest_Add(MM_EepromWriteDisCmd_Test_Nominal, MM_Test_Setup, MM_Test_TearDown, "MM_EepromWriteDisCmd_Test_Nominal"); UtTest_Add(MM_EepromWriteDisCmd_Test_Error, MM_Test_Setup, MM_Test_TearDown, "MM_EepromWriteDisCmd_Test_Error"); + UtTest_Add(MM_EepromWriteDisCmd_Test_BankNumberAboveMaskMax, MM_Test_Setup, MM_Test_TearDown, + "MM_EepromWriteDisCmd_Test_BankNumberAboveMaskMax"); }