| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // ====================================================================== | ||
| 2 | // \title CmdSequencerImpl.hpp | ||
| 3 | // \author Bocchino/Canham | ||
| 4 | // \brief hpp file for CmdSequencer component implementation class | ||
| 5 | // | ||
| 6 | // Copyright (C) 2009-2018 California Institute of Technology. | ||
| 7 | // ALL RIGHTS RESERVED. United States Government Sponsorship | ||
| 8 | // acknowledged. | ||
| 9 | // ====================================================================== | ||
| 10 | |||
| 11 | #ifndef Svc_CmdSequencerImpl_HPP | ||
| 12 | #define Svc_CmdSequencerImpl_HPP | ||
| 13 | |||
| 14 | #include <Utils/Hash/Hash.hpp> | ||
| 15 | #include "Fw/Com/ComBuffer.hpp" | ||
| 16 | #include "Fw/Types/MemAllocator.hpp" | ||
| 17 | #include "Os/File.hpp" | ||
| 18 | #include "Os/ValidateFile.hpp" | ||
| 19 | #include "Svc/CmdSequencer/CmdSequencerComponentAc.hpp" | ||
| 20 | #include "Svc/Seq/BlockStateEnumAc.hpp" | ||
| 21 | |||
| 22 | namespace Svc { | ||
| 23 | |||
| 24 | // Forward declaration for UTs | ||
| 25 | namespace ImmediateBase { | ||
| 26 | class CmdSequencerTester; | ||
| 27 | } | ||
| 28 | namespace Immediate { | ||
| 29 | class CmdSequencerTester; | ||
| 30 | } | ||
| 31 | namespace ImmediateEOS { | ||
| 32 | class CmdSequencerTester; | ||
| 33 | } | ||
| 34 | namespace Mixed { | ||
| 35 | class CmdSequencerTester; | ||
| 36 | } | ||
| 37 | namespace MixedRelativeBase { | ||
| 38 | class CmdSequencerTester; | ||
| 39 | } | ||
| 40 | namespace Relative { | ||
| 41 | class CmdSequencerTester; | ||
| 42 | } | ||
| 43 | namespace JoinWait { | ||
| 44 | class CmdSequencerTester; | ||
| 45 | } | ||
| 46 | |||
| 47 | class CmdSequencerComponentImpl final : public CmdSequencerComponentBase { | ||
| 48 | friend class CmdSequencerTester; | ||
| 49 | friend class Svc::ImmediateBase::CmdSequencerTester; | ||
| 50 | friend class Svc::Immediate::CmdSequencerTester; | ||
| 51 | friend class Svc::ImmediateEOS::CmdSequencerTester; | ||
| 52 | friend class Svc::Mixed::CmdSequencerTester; | ||
| 53 | friend class Svc::MixedRelativeBase::CmdSequencerTester; | ||
| 54 | friend class Svc::Relative::CmdSequencerTester; | ||
| 55 | friend class Svc::JoinWait::CmdSequencerTester; | ||
| 56 | |||
| 57 | private: | ||
| 58 | // ---------------------------------------------------------------------- | ||
| 59 | // Private enumerations | ||
| 60 | // ---------------------------------------------------------------------- | ||
| 61 | |||
| 62 | //! The run mode | ||
| 63 | enum RunMode { STOPPED, RUNNING }; | ||
| 64 | |||
| 65 | //! The step mode | ||
| 66 | enum StepMode { AUTO, MANUAL }; | ||
| 67 | |||
| 68 | public: | ||
| 69 | // ---------------------------------------------------------------------- | ||
| 70 | // Public classes | ||
| 71 | // ---------------------------------------------------------------------- | ||
| 72 | |||
| 73 | //! \class Sequence | ||
| 74 | //! \brief A sequence with unspecified binary format | ||
| 75 | class Sequence { | ||
| 76 | public: | ||
| 77 | //! \class Events | ||
| 78 | //! \brief Sequence event reporting | ||
| 79 | class Events { | ||
| 80 | public: | ||
| 81 | //! Construct an Events object | ||
| 82 | Events(Sequence& sequence //!< The enclosing sequence | ||
| 83 | ); | ||
| 84 | |||
| 85 | public: | ||
| 86 | //! File CRC failure | ||
| 87 | void fileCRCFailure(const U32 storedCRC, //!< The CRC stored in the file | ||
| 88 | const U32 computedCRC //!< The CRC computed over the file | ||
| 89 | ); | ||
| 90 | |||
| 91 | //! File invalid | ||
| 92 | void fileInvalid(const CmdSequencer_FileReadStage::t stage, //!< The file read stage | ||
| 93 | const I32 error //!< The error | ||
| 94 | ); | ||
| 95 | |||
| 96 | //! File not found | ||
| 97 | void fileNotFound(); | ||
| 98 | |||
| 99 | //! File read error | ||
| 100 | void fileReadError(); | ||
| 101 | |||
| 102 | //! File size error | ||
| 103 | void fileSizeError(const U32 size //!< The size | ||
| 104 | ); | ||
| 105 | |||
| 106 | //! Record invalid | ||
| 107 | void recordInvalid(const U32 recordNumber, //!< The record number | ||
| 108 | const I32 error //!< The error | ||
| 109 | ); | ||
| 110 | |||
| 111 | //! Record mismatch | ||
| 112 | void recordMismatch(const U32 numRecords, //!< The number of records in the header | ||
| 113 | const U32 extraBytes //!< The number of bytes beyond last record | ||
| 114 | ); | ||
| 115 | |||
| 116 | //! Time base mismatch | ||
| 117 | void timeBaseMismatch(const TimeBase currTimeBase, //!< The current time base | ||
| 118 | const TimeBase seqTimeBase //!< The sequence file time base | ||
| 119 | ); | ||
| 120 | |||
| 121 | //! Time context mismatch | ||
| 122 | void timeContextMismatch(const FwTimeContextStoreType currTimeContext, //!< The current time context | ||
| 123 | const FwTimeContextStoreType seqTimeContext //!< The sequence file time context | ||
| 124 | ); | ||
| 125 | |||
| 126 | // No Records | ||
| 127 | void noRecords(); | ||
| 128 | |||
| 129 | private: | ||
| 130 | //! The enclosing component | ||
| 131 | Sequence& m_sequence; | ||
| 132 | }; | ||
| 133 | |||
| 134 | public: | ||
| 135 | //! Construct a Sequence object | ||
| 136 | Sequence(CmdSequencerComponentImpl& component //!< The enclosing component | ||
| 137 | ); | ||
| 138 | |||
| 139 | //! Destroy a Sequence object | ||
| 140 | virtual ~Sequence(); | ||
| 141 | |||
| 142 | public: | ||
| 143 | //! \class Header | ||
| 144 | //! \brief A sequence header | ||
| 145 | class Header { | ||
| 146 | public: | ||
| 147 | enum Constants { | ||
| 148 | //! Serialized size of header | ||
| 149 | SERIALIZED_SIZE = | ||
| 150 | sizeof(U32) + sizeof(U32) + sizeof(FwTimeBaseStoreType) + sizeof(FwTimeContextStoreType) | ||
| 151 | }; | ||
| 152 | |||
| 153 | public: | ||
| 154 | //! Construct a Header object | ||
| 155 | Header(); | ||
| 156 | |||
| 157 | public: | ||
| 158 | //! Validate the time field of the sequence header | ||
| 159 | //! \return Success or failure | ||
| 160 | bool validateTime(CmdSequencerComponentImpl& component //!< Component for time and events | ||
| 161 | ); | ||
| 162 | |||
| 163 | public: | ||
| 164 | //! The file size | ||
| 165 | U32 m_fileSize; | ||
| 166 | |||
| 167 | //! The number of records in the sequence | ||
| 168 | U32 m_numRecords; | ||
| 169 | |||
| 170 | //! The time base of the sequence | ||
| 171 | TimeBase m_timeBase; | ||
| 172 | |||
| 173 | //! The context of the sequence | ||
| 174 | FwTimeContextStoreType m_timeContext; | ||
| 175 | }; | ||
| 176 | |||
| 177 | public: | ||
| 178 | //! \class Record | ||
| 179 | //! \brief A sequence record | ||
| 180 | class Record { | ||
| 181 | public: | ||
| 182 | enum Descriptor { | ||
| 183 | ABSOLUTE, //!< Absolute time | ||
| 184 | RELATIVE, //!< Relative time | ||
| 185 | END_OF_SEQUENCE //!< end of sequence | ||
| 186 | }; | ||
| 187 | |||
| 188 | public: | ||
| 189 | //! Construct a Record object | ||
| 190 |
1/1✓ Branch 9 taken 167 times.
|
167 | Record() : m_descriptor(END_OF_SEQUENCE) {} |
| 191 | |||
| 192 | public: | ||
| 193 | //! The descriptor | ||
| 194 | Descriptor m_descriptor; | ||
| 195 | |||
| 196 | //! The time tag. NOTE: timeBase and context not filled in | ||
| 197 | Fw::Time m_timeTag; | ||
| 198 | |||
| 199 | //! The command | ||
| 200 | Fw::ComBuffer m_command; | ||
| 201 | }; | ||
| 202 | |||
| 203 | public: | ||
| 204 | //! Give the sequence representation a memory buffer | ||
| 205 | void allocateBuffer(FwEnumStoreType identifier, //!< The identifier | ||
| 206 | Fw::MemAllocator& allocator, //!< The allocator | ||
| 207 | FwSizeType bytes //!< The number of bytes | ||
| 208 | ); | ||
| 209 | |||
| 210 | //! Deallocate the buffer | ||
| 211 | void deallocateBuffer(Fw::MemAllocator& allocator //!< The allocator | ||
| 212 | ); | ||
| 213 | |||
| 214 | //! Set the file name. Also sets the log file name. | ||
| 215 | void setFileName(const Fw::ConstStringBase& fileName); | ||
| 216 | |||
| 217 | //! Get the file name | ||
| 218 | //! \return The file name | ||
| 219 | Fw::CmdStringArg& getFileName(); | ||
| 220 | |||
| 221 | //! Get the log file name | ||
| 222 | //! \return The log file name | ||
| 223 | Fw::LogStringArg& getLogFileName(); | ||
| 224 | |||
| 225 | //! Get the normal string file name | ||
| 226 | //! \return The normal string file name | ||
| 227 | Fw::String& getStringFileName(); | ||
| 228 | |||
| 229 | //! Get the sequence header | ||
| 230 | const Header& getHeader() const; | ||
| 231 | |||
| 232 | //! Load a sequence file | ||
| 233 | //! \return Success or failure | ||
| 234 | virtual bool loadFile(const Fw::ConstStringBase& fileName //!< The file name | ||
| 235 | ) = 0; | ||
| 236 | |||
| 237 | //! Query whether the sequence has any more records | ||
| 238 | //! \return Yes or no | ||
| 239 | virtual bool hasMoreRecords() const = 0; | ||
| 240 | |||
| 241 | //! Get the next record in the sequence | ||
| 242 | //! Asserts on failure | ||
| 243 | virtual void nextRecord(Record& record //!< The returned record | ||
| 244 | ) = 0; | ||
| 245 | |||
| 246 | //! Reset the sequence to the beginning. | ||
| 247 | //! After calling this, hasMoreRecords should return true, | ||
| 248 | //! unless the sequence has no records | ||
| 249 | virtual void reset() = 0; | ||
| 250 | |||
| 251 | //! Clear the sequence records. | ||
| 252 | //! After calling this, hasMoreRecords should return false | ||
| 253 | virtual void clear() = 0; | ||
| 254 | |||
| 255 | protected: | ||
| 256 | //! The enclosing component | ||
| 257 | CmdSequencerComponentImpl& m_component; | ||
| 258 | |||
| 259 | //! Event reporting | ||
| 260 | Events m_events; | ||
| 261 | |||
| 262 | //! The sequence file name | ||
| 263 | Fw::CmdStringArg m_fileName; | ||
| 264 | |||
| 265 | //! Copy of file name for events | ||
| 266 | Fw::LogStringArg m_logFileName; | ||
| 267 | |||
| 268 | //! Copy of file name for ports | ||
| 269 | Fw::String m_stringFileName; | ||
| 270 | |||
| 271 | //! Serialize buffer to hold the binary sequence data | ||
| 272 | Fw::ExternalSerializeBuffer m_buffer; | ||
| 273 | |||
| 274 | //! The allocator ID | ||
| 275 | FwEnumStoreType m_allocatorId; | ||
| 276 | |||
| 277 | //! The sequence header | ||
| 278 | Header m_header; | ||
| 279 | }; | ||
| 280 | |||
| 281 | //! \class FPrimeSequence | ||
| 282 | //! \brief A sequence that uses the F Prime binary format | ||
| 283 | class FPrimeSequence : public Sequence { | ||
| 284 | private: | ||
| 285 | enum Constants { INITIAL_COMPUTED_VALUE = 0xFFFFFFFFU }; | ||
| 286 | |||
| 287 | public: | ||
| 288 | //! \class CRC | ||
| 289 | //! \brief Container for computed and stored CRC values | ||
| 290 | struct CRC { | ||
| 291 | //! Construct a CRC | ||
| 292 | CRC(); | ||
| 293 | |||
| 294 | //! Initialize computed CRC | ||
| 295 | void init(); | ||
| 296 | |||
| 297 | //! Update computed CRC | ||
| 298 | void update(const BYTE* buffer, //!< The buffer | ||
| 299 | FwSizeType bufferSize //!< The buffer size | ||
| 300 | ); | ||
| 301 | |||
| 302 | //! Return the finalized CRC | ||
| 303 | U32 finalize(); | ||
| 304 | |||
| 305 | //! Computed CRC | ||
| 306 | Utils::Hash m_computed; | ||
| 307 | |||
| 308 | //! Stored CRC | ||
| 309 | U32 m_stored; | ||
| 310 | }; | ||
| 311 | |||
| 312 | public: | ||
| 313 | //! Construct an FPrimeSequence | ||
| 314 | FPrimeSequence(CmdSequencerComponentImpl& component //!< The enclosing component | ||
| 315 | ); | ||
| 316 | |||
| 317 | public: | ||
| 318 | //! Load a sequence file | ||
| 319 | //! \return Success or failure | ||
| 320 | bool loadFile(const Fw::ConstStringBase& fileName //!< The file name | ||
| 321 | ); | ||
| 322 | |||
| 323 | //! Query whether the sequence has any more records | ||
| 324 | //! \return Yes or no | ||
| 325 | bool hasMoreRecords() const; | ||
| 326 | |||
| 327 | //! Get the next record in the sequence. | ||
| 328 | //! Asserts on failure | ||
| 329 | void nextRecord(Record& record //!< The returned record | ||
| 330 | ); | ||
| 331 | |||
| 332 | //! Reset the sequence to the beginning. | ||
| 333 | //! After calling this, hasMoreRecords should return true, unless | ||
| 334 | //! the sequence has no records. | ||
| 335 | void reset(); | ||
| 336 | |||
| 337 | //! Clear the sequence records. | ||
| 338 | //! After calling this, hasMoreRecords should return false. | ||
| 339 | void clear(); | ||
| 340 | |||
| 341 | private: | ||
| 342 | //! Read a sequence file | ||
| 343 | //! \return Success or failure | ||
| 344 | bool readFile(); | ||
| 345 | |||
| 346 | //! Read an open sequence file | ||
| 347 | //! \return Success or failure | ||
| 348 | bool readOpenFile(); | ||
| 349 | |||
| 350 | //! Read a binary sequence header from the sequence file | ||
| 351 | //! into the buffer | ||
| 352 | //! \return Success or failure | ||
| 353 | bool readHeader(); | ||
| 354 | |||
| 355 | //! Deserialize the binary sequence header from the buffer | ||
| 356 | //! \return Success or failure | ||
| 357 | bool deserializeHeader(); | ||
| 358 | |||
| 359 | //! Read records and CRC into buffer | ||
| 360 | //! \return Success or failure | ||
| 361 | bool readRecordsAndCRC(); | ||
| 362 | |||
| 363 | //! Extract CRC from record data | ||
| 364 | //! \return Success or failure | ||
| 365 | bool extractCRC(); | ||
| 366 | |||
| 367 | //! Validate the CRC | ||
| 368 | //! \return Success or failure | ||
| 369 | bool validateCRC(); | ||
| 370 | |||
| 371 | //! Deserialize a record from a buffer | ||
| 372 | //! \return Serialize status | ||
| 373 | Fw::SerializeStatus deserializeRecord(Record& record //!< The record | ||
| 374 | ); | ||
| 375 | |||
| 376 | //! Deserialize a record descriptor | ||
| 377 | //! \return Serialize status | ||
| 378 | Fw::SerializeStatus deserializeDescriptor(Record::Descriptor& descriptor //!< The descriptor | ||
| 379 | ); | ||
| 380 | |||
| 381 | //! Deserialize a time tag | ||
| 382 | //! \return Serialize status | ||
| 383 | Fw::SerializeStatus deserializeTimeTag(Fw::Time& timeTag //!< The time tag | ||
| 384 | ); | ||
| 385 | |||
| 386 | //! Deserialize the record size | ||
| 387 | //! \return Serialize status | ||
| 388 | Fw::SerializeStatus deserializeRecordSize(U32& recordSize //!< The record size | ||
| 389 | ); | ||
| 390 | |||
| 391 | //! Copy the serialized command into a com buffer | ||
| 392 | //! \return Serialize status | ||
| 393 | Fw::SerializeStatus copyCommand(Fw::ComBuffer& comBuffer, //!< The com buffer | ||
| 394 | const U32 recordSize //!< The record size | ||
| 395 | ); | ||
| 396 | |||
| 397 | //! Validate the sequence records in the buffer | ||
| 398 | //! \return Success or failure | ||
| 399 | bool validateRecords(); | ||
| 400 | |||
| 401 | private: | ||
| 402 | //! The CRC values | ||
| 403 | CRC m_crc; | ||
| 404 | |||
| 405 | //! The sequence file | ||
| 406 | Os::File m_sequenceFile; | ||
| 407 | }; | ||
| 408 | |||
| 409 | private: | ||
| 410 | // ---------------------------------------------------------------------- | ||
| 411 | // Private classes | ||
| 412 | // ---------------------------------------------------------------------- | ||
| 413 | |||
| 414 | //! \class Timer | ||
| 415 | //! \brief A class representing a timer | ||
| 416 | class Timer { | ||
| 417 | friend class CmdSequencerTester; | ||
| 418 | friend class Svc::ImmediateBase::CmdSequencerTester; | ||
| 419 | friend class Svc::Immediate::CmdSequencerTester; | ||
| 420 | friend class Svc::ImmediateEOS::CmdSequencerTester; | ||
| 421 | friend class Svc::Mixed::CmdSequencerTester; | ||
| 422 | friend class Svc::MixedRelativeBase::CmdSequencerTester; | ||
| 423 | friend class Svc::Relative::CmdSequencerTester; | ||
| 424 | friend class Svc::JoinWait::CmdSequencerTester; | ||
| 425 | |||
| 426 | private: | ||
| 427 | //! The timer state | ||
| 428 | typedef enum { SET, CLEAR } State; | ||
| 429 | |||
| 430 | public: | ||
| 431 | //! Construct a Timer object | ||
| 432 | 148 | Timer() : m_state(CLEAR) {} | |
| 433 | |||
| 434 | //! Set the expiration time | ||
| 435 | 127 | void set(Fw::Time time //!< The time | |
| 436 | ) { | ||
| 437 | 127 | this->m_state = SET; | |
| 438 | 127 | this->expirationTime = time; | |
| 439 | 127 | } | |
| 440 | |||
| 441 | //! Clear the timer | ||
| 442 | 148 | void clear() { this->m_state = CLEAR; } | |
| 443 | |||
| 444 | //! Determine whether the timer is expired at a given time | ||
| 445 | //! \return Yes or no | ||
| 446 | 42 | bool isExpiredAt(Fw::Time time //!< The time | |
| 447 | ) { | ||
| 448 |
3/4✗ Branch 1 not taken.
✓ Branch 2 taken 42 times.
✓ Branch 3 taken 20 times.
✓ Branch 4 taken 22 times.
|
42 | if (this->m_state == CLEAR) { |
| 449 | 20 | return false; | |
| 450 |
3/3✓ Branch 5 taken 22 times.
✓ Branch 14 taken 9 times.
✓ Branch 15 taken 13 times.
|
22 | } else if (Fw::Time::compare(this->expirationTime, time) == Fw::TimeComparison::GT) { |
| 451 | 9 | return false; | |
| 452 | } | ||
| 453 | 13 | return true; | |
| 454 | } | ||
| 455 | |||
| 456 | private: | ||
| 457 | //! The timer state | ||
| 458 | State m_state; | ||
| 459 | |||
| 460 | //! The expiration time | ||
| 461 | Fw::Time expirationTime; | ||
| 462 | }; | ||
| 463 | |||
| 464 | public: | ||
| 465 | // ---------------------------------------------------------------------- | ||
| 466 | // Construction, initialization, and destruction | ||
| 467 | // ---------------------------------------------------------------------- | ||
| 468 | |||
| 469 | //! Construct a CmdSequencer | ||
| 470 | CmdSequencerComponentImpl(const char* compName //!< The component name | ||
| 471 | ); | ||
| 472 | |||
| 473 | //! (Optional) Set a timeout. | ||
| 474 | //! Sequence will quit if a command takes longer than the number of | ||
| 475 | //! seconds in the timeout value. | ||
| 476 | void setTimeout(const U32 seconds //!< The number of seconds | ||
| 477 | ); | ||
| 478 | |||
| 479 | //! (Optional) Set the sequence format. | ||
| 480 | //! CmdSequencer will use the sequence object you pass in | ||
| 481 | //! to load and run sequences. By default, it uses an FPrimeSequence | ||
| 482 | //! object. | ||
| 483 | void setSequenceFormat(Sequence& sequence //!< The sequence object | ||
| 484 | ); | ||
| 485 | |||
| 486 | //! Give the sequence a memory buffer. | ||
| 487 | //! Call this after constructor and init, and after setting | ||
| 488 | //! the sequence format, but before task is spawned. | ||
| 489 | void allocateBuffer(const FwEnumStoreType identifier, //!< The identifier | ||
| 490 | Fw::MemAllocator& allocator, //!< The allocator | ||
| 491 | const FwSizeType bytes //!< The number of bytes | ||
| 492 | ); | ||
| 493 | |||
| 494 | //! (Optional) Load a sequence to run later. | ||
| 495 | //! When you call this function, the event ports must be connected. | ||
| 496 | void loadSequence(const Fw::ConstStringBase& fileName //!< The file name | ||
| 497 | ); | ||
| 498 | |||
| 499 | //! Return allocated buffer. Call during shutdown. | ||
| 500 | void deallocateBuffer(Fw::MemAllocator& allocator //!< The allocator | ||
| 501 | ); | ||
| 502 | |||
| 503 | //! Destroy a CmdDispatcherComponentBase | ||
| 504 | ~CmdSequencerComponentImpl(); | ||
| 505 | |||
| 506 | private: | ||
| 507 | // ---------------------------------------------------------------------- | ||
| 508 | // Handler implementations for input ports | ||
| 509 | // ---------------------------------------------------------------------- | ||
| 510 | |||
| 511 | //! Handler for input port cmdResponseIn | ||
| 512 | void cmdResponseIn_handler(FwIndexType portNum, //!< The port number | ||
| 513 | FwOpcodeType opcode, //!< The command opcode | ||
| 514 | U32 cmdSeq, //!< The command sequence number | ||
| 515 | const Fw::CmdResponse& response //!< The command response | ||
| 516 | ) override; | ||
| 517 | |||
| 518 | //! Handler for input port schedIn | ||
| 519 | void schedIn_handler(FwIndexType portNum, //!< The port number | ||
| 520 | U32 order //!< The call order | ||
| 521 | ) override; | ||
| 522 | |||
| 523 | //! Handler for input port seqRunIn | ||
| 524 | void seqRunIn_handler(FwIndexType portNum, //!< The port number | ||
| 525 | const Fw::StringBase& filename, //!< The sequence file | ||
| 526 | const Svc::SeqArgs& args //!< Sequence arguments (not currently used) | ||
| 527 | ) override; | ||
| 528 | |||
| 529 | //! Handler implementation for seqDispatchIn | ||
| 530 | //! | ||
| 531 | //! Port for file dispatches to run sequences | ||
| 532 | void seqDispatchIn_handler(FwIndexType portNum, //!< The port number | ||
| 533 | Fw::StringBase& file_name //!< The file to dispatch | ||
| 534 | ) override; | ||
| 535 | |||
| 536 | //! Handler for ping port | ||
| 537 | void pingIn_handler(FwIndexType portNum, //!< The port number | ||
| 538 | U32 key //!< Value to return to pinger | ||
| 539 | ) override; | ||
| 540 | |||
| 541 | //! Handler implementation for seqCancelIn | ||
| 542 | //! | ||
| 543 | void seqCancelIn_handler(const FwIndexType portNum /*!< The port number*/ | ||
| 544 | ) override; | ||
| 545 | |||
| 546 | private: | ||
| 547 | // ---------------------------------------------------------------------- | ||
| 548 | // Command handler implementations | ||
| 549 | // ---------------------------------------------------------------------- | ||
| 550 | |||
| 551 | //! Handler for command CS_AUTO | ||
| 552 | //! Set the run mode to AUTO. | ||
| 553 | void CS_AUTO_cmdHandler(FwOpcodeType opcode, //!< The opcode | ||
| 554 | U32 cmdSeq //!< The command sequence number | ||
| 555 | ) override; | ||
| 556 | |||
| 557 | //! Handler for command CS_CANCEL | ||
| 558 | //! Validate a command sequence file | ||
| 559 | void CS_CANCEL_cmdHandler(FwOpcodeType opCode, //!< The opcode | ||
| 560 | U32 cmdSeq //!< The command sequence number | ||
| 561 | ) override; | ||
| 562 | |||
| 563 | //! Handler for command CS_MANUAL | ||
| 564 | //! Set the run mode to MANUAL. | ||
| 565 | void CS_MANUAL_cmdHandler(FwOpcodeType opcode, //!< The opcode | ||
| 566 | U32 cmdSeq //!< The command sequence number | ||
| 567 | ) override; | ||
| 568 | |||
| 569 | //! Handler for command CS_RUN | ||
| 570 | void CS_RUN_cmdHandler(FwOpcodeType opCode, //!< The opcode | ||
| 571 | U32 cmdSeq, //!< The command sequence number | ||
| 572 | const Fw::CmdStringArg& fileName, //!< The file name | ||
| 573 | const Svc::BlockState& block /*!< Return command status when complete or not*/ | ||
| 574 | ) override; | ||
| 575 | |||
| 576 | //! Handler for command CS_START | ||
| 577 | //! Start running a command sequence | ||
| 578 | void CS_START_cmdHandler(FwOpcodeType opcode, //!< The opcode | ||
| 579 | U32 cmdSeq //!< The command sequence number | ||
| 580 | ) override; | ||
| 581 | |||
| 582 | //! Handler for command CS_STEP | ||
| 583 | //! Perform one step in a command sequence. | ||
| 584 | //! Valid only if SequenceRunner is in MANUAL run mode. | ||
| 585 | void CS_STEP_cmdHandler(FwOpcodeType opcode, //!< The opcode | ||
| 586 | U32 cmdSeq //!< The command sequence number | ||
| 587 | ) override; | ||
| 588 | |||
| 589 | //! Handler for command CS_VALIDATE | ||
| 590 | //! Run a command sequence file | ||
| 591 | void CS_VALIDATE_cmdHandler(FwOpcodeType opCode, //!< The opcode | ||
| 592 | U32 cmdSeq, //!< The command sequence number | ||
| 593 | const Fw::CmdStringArg& fileName //!< The name of the sequence file | ||
| 594 | ) override; | ||
| 595 | |||
| 596 | //! Implementation for CS_JOIN command handler | ||
| 597 | //! Wait for sequences that are running to finish. | ||
| 598 | //! Allow user to run multiple seq files in SEQ_NO_BLOCK mode | ||
| 599 | //! then wait for them to finish before allowing more seq run request. | ||
| 600 | void CS_JOIN_WAIT_cmdHandler(const FwOpcodeType opCode, /*!< The opcode*/ | ||
| 601 | const U32 cmdSeq /*!< The command sequence number*/ | ||
| 602 | ) override; | ||
| 603 | |||
| 604 | private: | ||
| 605 | // ---------------------------------------------------------------------- | ||
| 606 | // Private helper methods | ||
| 607 | // ---------------------------------------------------------------------- | ||
| 608 | |||
| 609 | //! Load a sequence file | ||
| 610 | //! \return Success or failure | ||
| 611 | bool loadFile(const Fw::ConstStringBase& fileName //!< The file name | ||
| 612 | ); | ||
| 613 | |||
| 614 | //! Perform a Cancel command | ||
| 615 | void performCmd_Cancel(); | ||
| 616 | |||
| 617 | //! Perform a Step command | ||
| 618 | void performCmd_Step(); | ||
| 619 | |||
| 620 | //! Perform a Step command with a relative time | ||
| 621 | void performCmd_Step_RELATIVE(Fw::Time& currentTime //!< The time | ||
| 622 | ); | ||
| 623 | |||
| 624 | //! Perform a Step command with an absolute time | ||
| 625 | void performCmd_Step_ABSOLUTE(Fw::Time& currentTime //!< The time | ||
| 626 | ); | ||
| 627 | |||
| 628 | //! Record a completed command | ||
| 629 | void commandComplete(const FwOpcodeType opCode //!< The opcode | ||
| 630 | ); | ||
| 631 | |||
| 632 | //! Record a sequence complete event | ||
| 633 | void sequenceComplete(); | ||
| 634 | |||
| 635 | //! Record an error | ||
| 636 | void error(); | ||
| 637 | |||
| 638 | //! Record an error in executing a sequence command | ||
| 639 | void commandError(const U32 number, //!< The command number | ||
| 640 | const FwOpcodeType opCode, //!< The command opcode | ||
| 641 | const U32 error //!< The error code | ||
| 642 | ); | ||
| 643 | |||
| 644 | //! Require a run mode | ||
| 645 | //! \return Whether we are in the correct mode | ||
| 646 | bool requireRunMode(RunMode mode //!< The required mode | ||
| 647 | ); | ||
| 648 | |||
| 649 | //! Set command timeout timer | ||
| 650 | void setCmdTimeout(const Fw::Time& currentTime //!< The current time | ||
| 651 | ); | ||
| 652 | |||
| 653 | //! Sequence run helper | ||
| 654 | void doSequenceRun(const Fw::StringBase& fileName); | ||
| 655 | |||
| 656 | private: | ||
| 657 | // ---------------------------------------------------------------------- | ||
| 658 | // Private member variables | ||
| 659 | // ---------------------------------------------------------------------- | ||
| 660 | |||
| 661 | //! The F Prime sequence | ||
| 662 | FPrimeSequence m_FPrimeSequence; | ||
| 663 | |||
| 664 | //! The abstract sequence | ||
| 665 | Sequence* m_sequence; | ||
| 666 | |||
| 667 | //! The number of Load commands executed | ||
| 668 | U32 m_loadCmdCount; | ||
| 669 | |||
| 670 | //! The number of Cancel commands executed | ||
| 671 | U32 m_cancelCmdCount; | ||
| 672 | |||
| 673 | //! The number of errors | ||
| 674 | U32 m_errorCount; | ||
| 675 | |||
| 676 | //! The run mode | ||
| 677 | RunMode m_runMode; | ||
| 678 | |||
| 679 | //! The step mode | ||
| 680 | StepMode m_stepMode; | ||
| 681 | |||
| 682 | //! The sequence record currently being processed | ||
| 683 | Sequence::Record m_record; | ||
| 684 | |||
| 685 | //! The command time timer | ||
| 686 | Timer m_cmdTimer; | ||
| 687 | |||
| 688 | //! The number of commands executed in this sequence | ||
| 689 | U32 m_executedCount; | ||
| 690 | |||
| 691 | //! The total number of commands executed across all sequences | ||
| 692 | U32 m_totalExecutedCount; | ||
| 693 | |||
| 694 | //! The total number of sequences completed | ||
| 695 | U32 m_sequencesCompletedCount; | ||
| 696 | |||
| 697 | //! timeout value | ||
| 698 | U32 m_timeout; | ||
| 699 | |||
| 700 | //! timeout timer | ||
| 701 | Timer m_cmdTimeoutTimer; | ||
| 702 | |||
| 703 | //! Block mode for command status | ||
| 704 | Svc::BlockState::t m_blockState; | ||
| 705 | FwOpcodeType m_opCode; | ||
| 706 | U32 m_cmdSeq; | ||
| 707 | bool m_join_waiting; | ||
| 708 | |||
| 709 | //! Telemetry to update sequence not running | ||
| 710 | const Fw::String NO_SEQ{"<no seq>"}; | ||
| 711 | }; | ||
| 712 | |||
| 713 | } // namespace Svc | ||
| 714 | |||
| 715 | #endif | ||
| 716 |