Skip to content

Commit

Permalink
Fix #108, dispatch pattern for SC
Browse files Browse the repository at this point in the history
Move switch statements to a separate dispatch source file, and update
all unit tests accordingly.

All business logic of commands is put into separate command handler
functions in sc_cmds.c.  No logic is inside the switch statement,
outside of message validation.
  • Loading branch information
jphickey committed Sep 29, 2023
1 parent 67c885c commit e904d4b
Show file tree
Hide file tree
Showing 15 changed files with 1,619 additions and 1,550 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ set(APP_SRC_FILES
fsw/src/sc_state.c
fsw/src/sc_loads.c
fsw/src/sc_cmds.c
fsw/src/sc_dispatch.c
)

# Create the app module
Expand Down
2 changes: 1 addition & 1 deletion fsw/src/sc_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
#include "cfe.h"
#include "sc_app.h"
#include "sc_rts.h"
#include "sc_cmds.h"
#include "sc_dispatch.h"
#include "sc_loads.h"
#include "sc_events.h"
#include "sc_msgids.h"
Expand Down
316 changes: 72 additions & 244 deletions fsw/src/sc_cmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,33 @@ void SC_SendHkPacket(void)
CFE_SB_TransmitMsg(&SC_OperData.HkPacket.TlmHeader.Msg, true);
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* Send HK Command */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void SC_SendHkCmd(const CFE_SB_Buffer_t *BufPtr)

Check notice

Code scanning / CodeQL-coding-standard

Long function without assertion Note

All functions of more than 10 lines should have at least one assertion.
{
/* set during init to power on or processor reset auto-exec RTS */
if (SC_AppData.AutoStartRTS != 0)
{
/* make sure the selected auto-exec RTS is enabled */
if (SC_OperData.RtsInfoTblAddr[SC_RTS_NUM_TO_INDEX(SC_AppData.AutoStartRTS)].RtsStatus == SC_LOADED)
{
SC_OperData.RtsInfoTblAddr[SC_RTS_NUM_TO_INDEX(SC_AppData.AutoStartRTS)].DisabledFlag = false;
}

/* send ground cmd to have SC start the RTS */
SC_AutoStartRts(SC_AppData.AutoStartRTS);

/* only start it once */
SC_AppData.AutoStartRTS = 0;
}

/* request from health and safety for housekeeping status */
SC_SendHkPacket();
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* Reset Counters Command */
Expand All @@ -500,269 +527,70 @@ void SC_ResetCountersCmd(const CFE_SB_Buffer_t *BufPtr)

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* No Op Command */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void SC_NoOpCmd(const CFE_SB_Buffer_t *BufPtr)
{
SC_OperData.HkPacket.Payload.CmdCtr++;
CFE_EVS_SendEvent(SC_NOOP_INF_EID, CFE_EVS_EventType_INFORMATION, "No-op command. Version %d.%d.%d.%d",
SC_MAJOR_VERSION, SC_MINOR_VERSION, SC_REVISION, SC_MISSION_REV);
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* Process Requests */
/* 1Hz Wakeup Command */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void SC_ProcessRequest(const CFE_SB_Buffer_t *BufPtr)
void SC_OneHzWakeupCmd(const CFE_SB_Buffer_t *BufPtr)

Check notice

Code scanning / CodeQL-coding-standard

Long function without assertion Note

All functions of more than 10 lines should have at least one assertion.
{
CFE_SB_MsgId_t MessageID = CFE_SB_INVALID_MSG_ID;
int8 IsThereAnotherCommandToExecute = false;

/* cast the packet header pointer on the packet buffer */
CFE_MSG_GetMsgId(&BufPtr->Msg, &MessageID);
bool IsThereAnotherCommandToExecute = false;

/*
** Get the current system time in the global SC_AppData.CurrentTime
* Time to execute a command in the SC memory
*/
SC_GetCurrentTime();

switch (CFE_SB_MsgIdToValue(MessageID))
do
{
case SC_CMD_MID:
/* request from the ground */
SC_ProcessCommand(BufPtr);
break;
/*
* Check to see if there is an ATS switch Pending, if so service it.
*/
if (SC_OperData.AtsCtrlBlckAddr->SwitchPendFlag == true)
{
SC_ServiceSwitchPend();
}

case SC_SEND_HK_MID:
if (SC_VerifyCmdLength(&BufPtr->Msg, sizeof(SC_NoArgsCmd_t)))
if (SC_AppData.NextProcNumber == SC_ATP)
{
SC_ProcessAtpCmd();
}
else
{
if (SC_AppData.NextProcNumber == SC_RTP)
{
/* set during init to power on or processor reset auto-exec RTS */
if (SC_AppData.AutoStartRTS != 0)
{
/* make sure the selected auto-exec RTS is enabled */
if (SC_OperData.RtsInfoTblAddr[SC_RTS_NUM_TO_INDEX(SC_AppData.AutoStartRTS)].RtsStatus == SC_LOADED)
{
SC_OperData.RtsInfoTblAddr[SC_RTS_NUM_TO_INDEX(SC_AppData.AutoStartRTS)].DisabledFlag = false;
}

/* send ground cmd to have SC start the RTS */
SC_AutoStartRts(SC_AppData.AutoStartRTS);

/* only start it once */
SC_AppData.AutoStartRTS = 0;
}

/* request from health and safety for housekeeping status */
SC_SendHkPacket();
SC_ProcessRtpCommand();
}
break;
}

case SC_1HZ_WAKEUP_MID:
/*
** Time to execute a command in the SC memory
*/
do
SC_UpdateNextTime();
if ((SC_AppData.NextProcNumber == SC_NONE) ||
(SC_AppData.NextCmdTime[SC_AppData.NextProcNumber] > SC_AppData.CurrentTime))
{
SC_OperData.NumCmdsSec = 0;
IsThereAnotherCommandToExecute = false;
}
else /* Command needs to run immediately */
{
if (SC_OperData.NumCmdsSec >= SC_MAX_CMDS_PER_SEC)
{
/*
** Check to see if there is an ATS switch Pending, if so service it.
*/
if (SC_OperData.AtsCtrlBlckAddr->SwitchPendFlag == true)
{
SC_ServiceSwitchPend();
}

if (SC_AppData.NextProcNumber == SC_ATP)
{
SC_ProcessAtpCmd();
}
else
{
if (SC_AppData.NextProcNumber == SC_RTP)
{
SC_ProcessRtpCommand();
}
}

SC_UpdateNextTime();
if ((SC_AppData.NextProcNumber == SC_NONE) ||
(SC_AppData.NextCmdTime[SC_AppData.NextProcNumber] > SC_AppData.CurrentTime))
{
SC_OperData.NumCmdsSec = 0;
IsThereAnotherCommandToExecute = false;
}
else /* Command needs to run immediately */
{
if (SC_OperData.NumCmdsSec >= SC_MAX_CMDS_PER_SEC)
{
SC_OperData.NumCmdsSec = 0;
IsThereAnotherCommandToExecute = false;
}
else
{
IsThereAnotherCommandToExecute = true;
}
}
} while (IsThereAnotherCommandToExecute);

break;

default:
CFE_EVS_SendEvent(SC_MID_ERR_EID, CFE_EVS_EventType_ERROR, "Invalid command pipe message ID: 0x%08lX",
(unsigned long)CFE_SB_MsgIdToValue(MessageID));

SC_OperData.HkPacket.Payload.CmdErrCtr++;
break;
} /* end switch */
SC_OperData.NumCmdsSec = 0;
IsThereAnotherCommandToExecute = false;
}
else
{
IsThereAnotherCommandToExecute = true;
}
}
} while (IsThereAnotherCommandToExecute);

Check warning

Code scanning / CodeQL-coding-standard

Unbounded loop Warning

This loop does not have a fixed bound.
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* Process a command */
/* No Op Command */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void SC_ProcessCommand(const CFE_SB_Buffer_t *BufPtr)
void SC_NoOpCmd(const CFE_SB_Buffer_t *BufPtr)
{
CFE_MSG_FcnCode_t CommandCode = 0;
CFE_SB_MsgId_t MessageID = CFE_SB_INVALID_MSG_ID;

CFE_MSG_GetMsgId(&BufPtr->Msg, &MessageID);
CFE_MSG_GetFcnCode(&BufPtr->Msg, &CommandCode);

switch (CommandCode)
{
case SC_NOOP_CC:
if (SC_VerifyCmdLength(&BufPtr->Msg, sizeof(SC_NoArgsCmd_t)))
{
SC_NoOpCmd(BufPtr);
}
break;


case SC_RESET_COUNTERS_CC:
if (SC_VerifyCmdLength(&BufPtr->Msg, sizeof(SC_NoArgsCmd_t)))
{
SC_ResetCountersCmd(BufPtr);
}
break;

case SC_START_ATS_CC:
if (SC_VerifyCmdLength(&BufPtr->Msg, sizeof(SC_StartAtsCmd_t)))
{
SC_StartAtsCmd(BufPtr);
}
break;

case SC_STOP_ATS_CC:
if (SC_VerifyCmdLength(&BufPtr->Msg, sizeof(SC_NoArgsCmd_t)))
{
SC_StopAtsCmd(BufPtr);
}
break;

case SC_START_RTS_CC:
if (SC_VerifyCmdLength(&BufPtr->Msg, sizeof(SC_RtsCmd_t)))
{
SC_StartRtsCmd(BufPtr);
}
else
{
SC_OperData.HkPacket.Payload.RtsActiveErrCtr++;
}
break;

case SC_STOP_RTS_CC:
if (SC_VerifyCmdLength(&BufPtr->Msg, sizeof(SC_RtsCmd_t)))
{
SC_StopRtsCmd(BufPtr);
}
break;

case SC_DISABLE_RTS_CC:
if (SC_VerifyCmdLength(&BufPtr->Msg, sizeof(SC_RtsCmd_t)))
{
SC_DisableRtsCmd(BufPtr);
}
break;

case SC_ENABLE_RTS_CC:
if (SC_VerifyCmdLength(&BufPtr->Msg, sizeof(SC_RtsCmd_t)))
{
SC_EnableRtsCmd(BufPtr);
}
break;

case SC_SWITCH_ATS_CC:
if (SC_VerifyCmdLength(&BufPtr->Msg, sizeof(SC_NoArgsCmd_t)))
{
SC_GroundSwitchCmd(BufPtr);
}
break;

case SC_JUMP_ATS_CC:
if (SC_VerifyCmdLength(&BufPtr->Msg, sizeof(SC_JumpAtsCmd_t)))
{
SC_JumpAtsCmd(BufPtr);
}
break;

case SC_CONTINUE_ATS_ON_FAILURE_CC:
if (SC_VerifyCmdLength(&BufPtr->Msg, sizeof(SC_SetContinueAtsOnFailureCmd_t)))
{
SC_ContinueAtsOnFailureCmd(BufPtr);
}
break;

case SC_APPEND_ATS_CC:
if (SC_VerifyCmdLength(&BufPtr->Msg, sizeof(SC_AppendAtsCmd_t)))
{
SC_AppendAtsCmd(BufPtr);
}
break;

case SC_MANAGE_TABLE_CC:
if (SC_VerifyCmdLength(&BufPtr->Msg, sizeof(SC_NoArgsCmd_t)))
{
SC_TableManageCmd(BufPtr);
}
break;

case SC_START_RTS_GRP_CC:
if (SC_VerifyCmdLength(&BufPtr->Msg, sizeof(SC_RtsGrpCmd_t)))
{
SC_StartRtsGrpCmd(BufPtr);
}
break;

case SC_STOP_RTS_GRP_CC:
if (SC_VerifyCmdLength(&BufPtr->Msg, sizeof(SC_RtsGrpCmd_t)))
{
SC_StopRtsGrpCmd(BufPtr);
}
break;

case SC_DISABLE_RTS_GRP_CC:
if (SC_VerifyCmdLength(&BufPtr->Msg, sizeof(SC_RtsGrpCmd_t)))
{
SC_DisableRtsGrpCmd(BufPtr);
}
break;

case SC_ENABLE_RTS_GRP_CC:
if (SC_VerifyCmdLength(&BufPtr->Msg, sizeof(SC_RtsGrpCmd_t)))
{
SC_EnableRtsGrpCmd(BufPtr);
}
break;

default:
CFE_EVS_SendEvent(SC_INVLD_CMD_ERR_EID, CFE_EVS_EventType_ERROR,
"Invalid Command Code: MID = 0x%08lX CC = %d",
(unsigned long)CFE_SB_MsgIdToValue(MessageID), CommandCode);
SC_OperData.HkPacket.Payload.CmdErrCtr++;
break;
} /* end switch */
SC_OperData.HkPacket.Payload.CmdCtr++;
CFE_EVS_SendEvent(SC_NOOP_INF_EID, CFE_EVS_EventType_INFORMATION, "No-op command. Version %d.%d.%d.%d",
SC_MAJOR_VERSION, SC_MINOR_VERSION, SC_REVISION, SC_MISSION_REV);
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
Expand Down
Loading

0 comments on commit e904d4b

Please sign in to comment.