GCC Code Coverage Report


Directory: lib/fprime-samd/fprime-samd/Svc/Seq/
File: Seq.hpp
Date: 2026-10-20 16:49:07
Exec Total Coverage
Lines: 2 2 100.0%
Functions: 2 2 100.0%
Branches: 0 0 -%

Line Branch Exec Source
1 // ======================================================================
2 // \title Seq.hpp
3 // \author tumbar
4 // \brief hpp file for Seq component implementation class
5 // ======================================================================
6
7 #ifndef Samd21_Seq_HPP
8 #define Samd21_Seq_HPP
9
10 #include "Fw/Types/Serializable.hpp"
11 #include "SeqConfig/SeqNamesEnumAc.hpp"
12 #include "fprime-samd/Svc/Seq/SeqComponentAc.hpp"
13
14 namespace Samd21 {
15
16 class Seq final : public SeqComponentBase {
17 public:
18 // ----------------------------------------------------------------------
19 // Component construction and destruction
20 // ----------------------------------------------------------------------
21
22 //! Construct Seq object
23 Seq(const char* const compName //!< The component name
24 );
25
26 //! Destroy Seq object
27 ~Seq();
28
29 //! A single hard-coded sequence: a pointer to its binary blob and the blob length
30 struct Sequence {
31 81 Sequence() : m_data(nullptr), m_len(0) {}
32 81 Sequence(const U8* data, U32 len) : m_data(data), m_len(len) {}
33
34 const U8* m_data; //!< Pointer to the sequence binary (typically in flash)
35 U32 m_len; //!< Length of the sequence binary in bytes
36 };
37
38 //! Configure the sequence list.
39 //! \a sequences must point at an array of exactly SeqNames::NUM_CONSTANTS
40 //! entries, indexed by the SeqNames enum value. The array and the
41 //! binaries it references must remain valid for the lifetime of the component.
42 void configure(const Sequence* sequences);
43
44 //! Pend a sequence to run when the MCU boots into the main loop
45 void run(const Samd21::SeqNames& name);
46
47 private:
48 // ----------------------------------------------------------------------
49 // Handler implementations for typed input ports
50 // ----------------------------------------------------------------------
51
52 //! Handler implementation for activeIn
53 //!
54 //! Active in for dispatching the "next" action in the table or reseting
55 bool activeIn_handler(FwIndexType portNum, //!< The port number
56 U32 context //!< The call order
57 ) override;
58
59 //! Handler implementation for commandResponseIn
60 //!
61 //! Port to receive status of the currently executing action
62 void commandResponseIn_handler(FwIndexType portNum, //!< The port number
63 FwOpcodeType opCode, //!< Command Op Code
64 U32 cmdSeq, //!< Command Sequence
65 const Fw::CmdResponse& response //!< The command response argument
66 ) override;
67
68 //! Handler implementation for schedIn
69 //!
70 //! Check timers for wait/wait_until timeouts
71 void schedIn_handler(FwIndexType portNum, //!< The port number
72 U32 context //!< The call order
73 ) override;
74
75 private:
76 // ----------------------------------------------------------------------
77 // Handler implementations for commands
78 // ----------------------------------------------------------------------
79
80 //! Handler implementation for command RUN
81 //!
82 //! Run an action table after the current execution finishes
83 //! When this component enters idle, it will pick up this pending run
84 void RUN_cmdHandler(FwOpcodeType opCode, //!< The opcode
85 U32 cmdSeq, //!< The command sequence number
86 const Samd21::SeqNames& table) override;
87
88 //! Handler implementation for command RUN_ON_ERROR
89 //!
90 //! Set the table to run if we exit with an error (i.e. command failure).
91 //! The pending `RUN` is cleared.
92 void RUN_ON_ERROR_cmdHandler(FwOpcodeType opCode, //!< The opcode
93 U32 cmdSeq, //!< The command sequence number
94 const Samd21::SeqNames& table) override;
95
96 //! Handler implementation for command CANCEL
97 //!
98 //! Stop any executing or pending action and reset the program counter to the
99 //! start of the sequence without dispatching anything. A command response for
100 //! an already-dispatched action may still arrive afterwards; it is dropped.
101 void CANCEL_cmdHandler(FwOpcodeType opCode, //!< The opcode
102 U32 cmdSeq //!< The command sequence number
103 ) override;
104
105 //! Handler implementation for command WAIT_TICKS
106 //!
107 //! Block for a number of rate groups ticks before continuing
108 //! If n == 0, the sequence will resume on the NEXT rate group tick
109 void WAIT_TICKS_cmdHandler(FwOpcodeType opCode, //!< The opcode
110 U32 cmdSeq, //!< The command sequence number
111 U32 n) override;
112
113 //! Handler implementation for command WAIT_UNTIL
114 //!
115 //! Block the sequence until the given timeBase matches and the time >= seconds.useconds
116 void WAIT_UNTIL_cmdHandler(FwOpcodeType opCode, //!< The opcode
117 U32 cmdSeq, //!< The command sequence number
118 const TimeBase& timeBase, //!< Wait for the FSW to reach this timebase
119 U32 seconds, //!< Wait for FSW time to reach this time in seconds
120 U32 useconds //!< Microsecond offset to wait for FSW
121 ) override;
122
123 private:
124 // ----------------------------------------------------------------------
125 // Helper functions
126 // ----------------------------------------------------------------------
127
128 //! Whether the current action has more command bytes left to deserialize
129 bool hasMoreRecordsInternal() const;
130
131 //! Deserialize the next command from the current action into \a cmd.
132 //! \return the number of bytes consumed, or 0 on a malformed command.
133 U16 deserializeRecord(Fw::ExternalSerializeBuffer& cmd);
134
135 //! Dispatch the command held in \a cmdBuf out the commandOut port.
136 void dispatchRecord(const Fw::ExternalSerializeBuffer& cmdBuf, U32 cmdSeq);
137
138 //! Advance to and dispatch the next command. If the end of the action is
139 //! reached, finish successfully. On a malformed command, finish with failure.
140 void next();
141
142 private:
143 // ----------------------------------------------------------------------
144 // Member state
145 // ----------------------------------------------------------------------
146
147 static_assert(SeqNames::NUM_CONSTANTS < 255, "Samd21::Seq does not support >255 tables");
148
149 enum class State : U8 {
150 IDLE,
151 AWAITING_RESPONSE,
152 PENDING_NEXT,
153 SLEEPING,
154 };
155
156 //! What the component is waiting on while SLEEPING. Set by the WAIT_TICKS /
157 //! WAIT_UNTIL command handlers (which run re-entrantly while the just-issued
158 //! wait command is AWAITING_RESPONSE) and consumed by commandResponseIn to
159 //! move the component into SLEEPING.
160 enum class SleepKind : U8 {
161 NONE, //!< Not waiting; the completed command advances to the next one
162 TICKS, //!< Waiting for a number of rate-group ticks (WAIT_TICKS)
163 UNTIL, //!< Waiting for the FSW clock to reach an absolute time (WAIT_UNTIL)
164 };
165
166 const Sequence* m_sequences; //!< The configured action list (NUM_CONSTANTS long)
167 U16 m_offset; //!< Current offset in bytes from the active action table
168 U8 m_tableIdx; //!< Index of the active table
169 volatile State m_state; //!< Whether an action is currently executing
170 U8 m_pendingTableIdx; //!< NUM_CONSTANTS indicates nothing to run. Otherwise once this component enters idle, start
171 //!< this sequence
172 U8 m_runOnErrorTableIdx; //!< NUM_CONSTANTS indicates none. Otherwise the table to pend when a command fails
173
174 SleepKind m_sleepKind; //!< The kind of wait requested by the last WAIT_* command
175 U32 m_waitTicks; //!< Rate-group ticks remaining before a WAIT_TICKS sleep resumes
176 TimeBase m_waitTimeBase; //!< Time base a WAIT_UNTIL sleep waits on
177 U32 m_waitSeconds; //!< Seconds a WAIT_UNTIL sleep waits for
178 U32 m_waitUseconds; //!< Microsecond offset a WAIT_UNTIL sleep waits for
179 };
180
181 } // namespace Samd21
182
183 #endif
184