F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
Loading...
Searching...
No Matches
SeqDispatcher.cpp
Go to the documentation of this file.
1// ======================================================================
2// \title SeqDispatcher.cpp
3// \author zimri.leisher
4// \brief cpp file for SeqDispatcher component implementation class
5// ======================================================================
6
8
9namespace Svc {
10
11// ----------------------------------------------------------------------
12// Construction, initialization, and destruction
13// ----------------------------------------------------------------------
14
15SeqDispatcher ::SeqDispatcher(const char* const compName)
16 : SeqDispatcherComponentBase(compName) {}
17
18SeqDispatcher ::~SeqDispatcher() {}
19
20FwIndexType SeqDispatcher::getNextAvailableSequencerIdx() {
21 for (FwIndexType i = 0; i < SeqDispatcherSequencerPorts; i++) {
23 this->m_entryTable[i].state == SeqDispatcher_CmdSequencerState::AVAILABLE) {
24 return i;
25 }
26 }
27 return -1;
28}
29
30void SeqDispatcher::runSequence(FwIndexType sequencerIdx,
31 const Fw::StringBase& fileName,
32 Fw::Wait block) {
33 // this function is only designed for internal usage
34 // we can guarantee it cannot be called with input that would fail
35 FW_ASSERT(sequencerIdx >= 0 && sequencerIdx < SeqDispatcherSequencerPorts,
36 sequencerIdx);
38 FW_ASSERT(this->m_entryTable[sequencerIdx].state ==
40 this->m_entryTable[sequencerIdx].state);
41
42 if (block == Fw::Wait::NO_WAIT) {
43 this->m_entryTable[sequencerIdx].state =
45 } else {
46 this->m_entryTable[sequencerIdx].state =
48 }
49
50 this->m_sequencersAvailable--;
51 this->tlmWrite_sequencersAvailable(this->m_sequencersAvailable);
52 this->m_entryTable[sequencerIdx].sequenceRunning = fileName;
53
54 this->m_dispatchedCount++;
55 this->tlmWrite_dispatchedCount(this->m_dispatchedCount);
56 this->seqRunOut_out(sequencerIdx,
57 this->m_entryTable[sequencerIdx].sequenceRunning);
58}
59
61 NATIVE_INT_TYPE portNum,
62 const Fw::StringBase& fileName
63) {
64 FW_ASSERT(portNum >= 0 && portNum < SeqDispatcherSequencerPorts, portNum);
65 if (this->m_entryTable[portNum].state ==
67 this->m_entryTable[portNum].state ==
69 // we were aware of this sequencer running a sequence
70 if (this->m_entryTable[portNum].sequenceRunning != fileName) {
71 // uh oh. entry table is wrong
72 // let's just update it to be correct. nothing we can do about
73 // it except raise a warning and update our state
74 this->log_WARNING_HI_ConflictingSequenceStarted(static_cast<U16>(portNum), fileName, this->m_entryTable[portNum].sequenceRunning);
75 this->m_entryTable[portNum].sequenceRunning = fileName;
76 }
77 } else {
78 // we were not aware that this sequencer was running. ground must have
79 // directly commanded that specific sequencer
80
81 // warn because this may be unintentional
82 this->log_WARNING_LO_UnexpectedSequenceStarted(static_cast<U16>(portNum), fileName);
83
84 // update the state
85 this->m_entryTable[portNum].state =
87 this->m_entryTable[portNum].sequenceRunning = fileName;
88 this->m_sequencersAvailable--;
89 this->tlmWrite_sequencersAvailable(this->m_sequencersAvailable);
90 }
91}
92
94 NATIVE_INT_TYPE portNum,
95 FwOpcodeType opCode,
96 U32 cmdSeq,
97 const Fw::CmdResponse& response
98) {
99 FW_ASSERT(portNum >= 0 && portNum < SeqDispatcherSequencerPorts, portNum);
100 if (this->m_entryTable[portNum].state !=
102 this->m_entryTable[portNum].state !=
104 // this sequencer was not running a sequence that we were aware of.
105
106 // we should have caught this in seqStartIn and updated the state
107 // accordingly, but somehow we didn't? very sad and shouldn't happen
108
109 // anyways, don't have to do anything cuz now that this seq we didn't know
110 // about is done, the sequencer is available again (which is its current
111 // state in our internal entry table already)
112 this->log_WARNING_LO_UnknownSequenceFinished(static_cast<U16>(portNum));
113 } else {
114 // ok, a sequence has finished that we knew about
115 if (this->m_entryTable[portNum].state ==
117 // we need to give a cmd response cuz some other sequence is being blocked
118 // by this
119 this->cmdResponse_out(this->m_entryTable[portNum].opCode,
120 this->m_entryTable[portNum].cmdSeq, response);
121
122 if (response == Fw::CmdResponse::EXECUTION_ERROR) {
123 // dispatched sequence errored
124 this->m_errorCount++;
125 this->tlmWrite_errorCount(this->m_errorCount);
126 }
127 }
128 }
129
130 // all command responses mean the sequence is no longer running
131 // so component should be available
132 this->m_entryTable[portNum].state = SeqDispatcher_CmdSequencerState::AVAILABLE;
133 this->m_entryTable[portNum].sequenceRunning = "<no seq>";
134 this->m_sequencersAvailable++;
135 this->tlmWrite_sequencersAvailable(this->m_sequencersAvailable);
136}
137
140 const Fw::StringBase& fileName) {
141 FwIndexType idx = this->getNextAvailableSequencerIdx();
142 // no available sequencers
143 if (idx == -1) {
145 return;
146 }
147
148 this->runSequence(idx, fileName, Fw::Wait::NO_WAIT);
149}
150// ----------------------------------------------------------------------
151// Command handler implementations
152// ----------------------------------------------------------------------
153
154void SeqDispatcher ::RUN_cmdHandler(const FwOpcodeType opCode,
155 const U32 cmdSeq,
156 const Fw::CmdStringArg& fileName,
157 Fw::Wait block) {
158 FwIndexType idx = this->getNextAvailableSequencerIdx();
159 // no available sequencers
160 if (idx == -1) {
161 this->log_WARNING_HI_NoAvailableSequencers();
162 this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
163 return;
164 }
165
166 this->runSequence(idx, fileName, block);
167
168 if (block == Fw::Wait::NO_WAIT) {
169 // return instantly
170 this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
171 } else {
172 // otherwise don't return a response yet. just save the opCode and cmdSeq
173 // so we can return a response later
174 this->m_entryTable[idx].opCode = opCode;
175 this->m_entryTable[idx].cmdSeq = cmdSeq;
176 }
177}
178
179void SeqDispatcher::LOG_STATUS_cmdHandler(
180 const FwOpcodeType opCode,
181 const U32 cmdSeq) {
182 for(FwIndexType idx = 0; idx < SeqDispatcherSequencerPorts; idx++) {
183 this->log_ACTIVITY_LO_LogSequencerStatus(static_cast<U16>(idx), this->m_entryTable[idx].state, Fw::LogStringArg(this->m_entryTable[idx].sequenceRunning));
184 }
185}
186} // end namespace components
#define FW_ASSERT(...)
Definition Assert.hpp:14
PlatformIntType NATIVE_INT_TYPE
Definition BasicTypes.h:55
U32 FwOpcodeType
Definition FpConfig.h:91
PlatformIndexType FwIndexType
Definition FpConfig.h:25
@ SeqDispatcherSequencerPorts
Enum representing a command response.
@ EXECUTION_ERROR
Command had execution error.
@ OK
Command successfully executed.
Wait or don't wait for something.
Auto-generated base for SeqDispatcher component.
void log_ACTIVITY_LO_LogSequencerStatus(U16 idx, Svc::SeqDispatcher_CmdSequencerState state, const Fw::StringBase &filename) const
Log event LogSequencerStatus.
void cmdResponse_out(FwOpcodeType opCode, U32 cmdSeq, Fw::CmdResponse response)
Emit command response.
void tlmWrite_errorCount(U32 arg, Fw::Time _tlmTime=Fw::Time()) const
void log_WARNING_HI_ConflictingSequenceStarted(U16 idx, const Fw::StringBase &newSequence, const Fw::StringBase &sequenceInInternalState) const
Log event ConflictingSequenceStarted.
void tlmWrite_dispatchedCount(U32 arg, Fw::Time _tlmTime=Fw::Time()) const
bool isConnected_seqRunOut_OutputPort(FwIndexType portNum)
void seqRunOut_out(FwIndexType portNum, const Fw::StringBase &filename)
Invoke output port seqRunOut.
void log_WARNING_LO_UnexpectedSequenceStarted(U16 idx, const Fw::StringBase &newSequence) const
Log event UnexpectedSequenceStarted.
void log_WARNING_HI_NoAvailableSequencers() const
Log event NoAvailableSequencers.
void tlmWrite_sequencersAvailable(U32 arg, Fw::Time _tlmTime=Fw::Time()) const
void log_WARNING_LO_UnknownSequenceFinished(U16 idx) const
Log event UnknownSequenceFinished.
void seqDoneIn_handler(NATIVE_INT_TYPE portNum, FwOpcodeType opCode, U32 cmdSeq, const Fw::CmdResponse &response)
Handler for input port seqDoneIn.
void seqStartIn_handler(NATIVE_INT_TYPE portNum, const Fw::StringBase &fileName)
Handler for input port seqStartIn.
void seqRunIn_handler(NATIVE_INT_TYPE portNum, const Fw::StringBase &fileName)
Handler for input port seqRunIn.