mirror of
https://github.com/nasa/fprime.git
synced 2025-12-10 00:44:37 -06:00
FpySequencer arithmetic (#4025)
* Some work towards stack based arch * Bring fp/int conv up to date * Get compiling with stack based arch * Start trying to fix UTs * Start adding store/load dirs * Add push val dir * UTs are running * UTs passing * Make exit stack based * Fix more uts * Fix final UTs * sp * Fix overflow potential err * Fix another overflow * same error fix * Format * Also add to format checker * Add math directives * Add integer extension and truncation * Also check correct size on stack * Fix comment * Push cmd response to stack * Cast cmd response code to i32 * Add stack cmd, memcmp, discard dirs * Fix some bugs with stack cmd * Fix lil bug in sgtack cmd * same bug * Fix another bug sry * Update sdd * sp * Fix undefined behavior with bitshift of signed integer * sp * Fix lil bug in timeout detection of stack cmd * Switch format check to do all Svc dirs * Reformat, and fix packet descriptor serialize bug * Add UTs for all of arith ops * Add tests for disc, memcmp, stack cmd * Add deser tests for those three dirs * sp * Format * Replace magic numbers with sizeofs * Add currentStatementIdx helper function * Format * Split imod into smod and umod * sp * Add fmod, copy python behavior for fmod and smod --------- Co-authored-by: Zimri Leisher <zimri.leisher@fireflyspace.com>
This commit is contained in:
parent
bdade025d0
commit
f4439a8cc9
9
.github/actions/spelling/expect.txt
vendored
9
.github/actions/spelling/expect.txt
vendored
@ -37,6 +37,7 @@ Bies
|
||||
BINDIR
|
||||
bitmaps
|
||||
bitshifts
|
||||
bitwidth
|
||||
bocchino
|
||||
boolt
|
||||
bsd
|
||||
@ -234,6 +235,7 @@ foodoodie
|
||||
foodoodiehoo
|
||||
FPCONFIG
|
||||
fpext
|
||||
fpow
|
||||
fpp
|
||||
fppi
|
||||
fpptest
|
||||
@ -331,6 +333,7 @@ isr
|
||||
isunordered
|
||||
itimerspec
|
||||
itr
|
||||
itrunc
|
||||
itval
|
||||
janamian
|
||||
jawest
|
||||
@ -559,6 +562,7 @@ sbom
|
||||
scid
|
||||
scm
|
||||
sdd
|
||||
sdiv
|
||||
searchdata
|
||||
SENDPARTIAL
|
||||
seqgen
|
||||
@ -580,11 +584,13 @@ SHAREDSTATEDIR
|
||||
SHELLCOMMAND
|
||||
showinitializer
|
||||
sideeffect
|
||||
siext
|
||||
Signedness
|
||||
Silveira
|
||||
sitofp
|
||||
sle
|
||||
sloc
|
||||
smod
|
||||
socio
|
||||
SOCKETHELPER
|
||||
SOCKETIPDRIVER
|
||||
@ -678,10 +684,12 @@ tts
|
||||
typedef'ed
|
||||
typedef
|
||||
uart
|
||||
udiv
|
||||
UDPSOCKET
|
||||
uge
|
||||
uitofp
|
||||
UML
|
||||
umod
|
||||
UNEXP
|
||||
unistd
|
||||
UNITTESTASSERT
|
||||
@ -713,4 +721,5 @@ xdffe
|
||||
xsltproc
|
||||
xxxx
|
||||
XXYY
|
||||
ziext
|
||||
zimri
|
||||
|
||||
59
.github/workflows/format-check.yml
vendored
59
.github/workflows/format-check.yml
vendored
@ -35,64 +35,7 @@ jobs:
|
||||
FppTestProject
|
||||
Fw
|
||||
Os
|
||||
Svc/ActiveRateGroup
|
||||
Svc/ActiveTextLogger
|
||||
Svc/AssertFatalAdapter
|
||||
Svc/BufferAccumulator
|
||||
Svc/BufferLogger
|
||||
Svc/BufferManager
|
||||
Svc/BufferRepeater
|
||||
Svc/Ccsds
|
||||
Svc/ChronoTime
|
||||
Svc/CmdDispatcher
|
||||
Svc/CmdSequencer
|
||||
Svc/CmdSplitter
|
||||
Svc/ComLogger
|
||||
Svc/ComQueue
|
||||
Svc/ComSplitter
|
||||
Svc/ComStub
|
||||
Svc/Cycle
|
||||
Svc/DpCatalog
|
||||
Svc/DpManager
|
||||
Svc/DpPorts
|
||||
Svc/DpWriter
|
||||
Svc/EventManager
|
||||
Svc/Fatal
|
||||
Svc/FatalHandler
|
||||
Svc/FileDownlink
|
||||
Svc/FileDownlinkPorts
|
||||
Svc/FileManager
|
||||
Svc/FileUplink
|
||||
Svc/FprimeDeframer
|
||||
Svc/FprimeFramer
|
||||
Svc/FprimeProtocol
|
||||
Svc/FprimeRouter
|
||||
Svc/FrameAccumulator
|
||||
Svc/FramingProtocol
|
||||
Svc/GenericHub
|
||||
Svc/Health
|
||||
Svc/Interfaces
|
||||
Svc/LinuxTimer
|
||||
Svc/OsTime
|
||||
Svc/PassiveConsoleTextLogger
|
||||
Svc/PassiveRateGroup
|
||||
Svc/Ping
|
||||
Svc/PolyDb
|
||||
Svc/PolyIf
|
||||
Svc/Ports
|
||||
Svc/PosixTime
|
||||
Svc/PrmDb
|
||||
Svc/RateGroupDriver
|
||||
Svc/Sched
|
||||
Svc/Seq
|
||||
Svc/SeqDispatcher
|
||||
Svc/StaticMemory
|
||||
Svc/Subtopologies
|
||||
Svc/SystemResources
|
||||
Svc/TlmChan
|
||||
Svc/TlmPacketizer
|
||||
Svc/Version
|
||||
Svc/WatchDog
|
||||
Svc
|
||||
|
||||
run: |
|
||||
fprime-util format --check --dirs $CHECKED_DIRS
|
||||
|
||||
@ -261,9 +261,11 @@ void FpySequencer::cmdResponseIn_handler(FwIndexType portNum, //!< T
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->m_runtime.currentStatementOpcode != Fpy::DirectiveId::CONST_CMD) {
|
||||
if (this->m_runtime.currentStatementOpcode != Fpy::DirectiveId::CONST_CMD &&
|
||||
this->m_runtime.currentStatementOpcode != Fpy::DirectiveId::STACK_CMD) {
|
||||
// we were not awaiting a cmd response, we were waiting for a directive
|
||||
this->log_WARNING_HI_CmdResponseWhileAwaitingDirective(opCode, response, this->m_runtime.currentStatementOpcode);
|
||||
this->log_WARNING_HI_CmdResponseWhileAwaitingDirective(opCode, response,
|
||||
this->m_runtime.currentStatementOpcode);
|
||||
this->sequencer_sendSignal_stmtResponse_unexpected();
|
||||
return;
|
||||
}
|
||||
@ -303,17 +305,15 @@ void FpySequencer::cmdResponseIn_handler(FwIndexType portNum, //!< T
|
||||
if (response == Fw::CmdResponse::OK) {
|
||||
this->sequencer_sendSignal_stmtResponse_success();
|
||||
} else {
|
||||
this->log_WARNING_HI_CommandFailed(opCode,
|
||||
this->m_runtime.nextStatementIndex - 1, this->m_sequenceFilePath,
|
||||
response);
|
||||
this->log_WARNING_HI_CommandFailed(opCode, this->currentStatementIdx(), this->m_sequenceFilePath, response);
|
||||
this->sequencer_sendSignal_stmtResponse_failure();
|
||||
}
|
||||
// push the cmd response to the stack so we can branch off of it
|
||||
this->push(static_cast<I32>(response.e));
|
||||
}
|
||||
|
||||
//! Handler for input port seqRunIn
|
||||
void FpySequencer::seqRunIn_handler(FwIndexType portNum,
|
||||
const Fw::StringBase& filename
|
||||
) {
|
||||
void FpySequencer::seqRunIn_handler(FwIndexType portNum, const Fw::StringBase& filename) {
|
||||
// can only run a seq while in idle
|
||||
if (sequencer_getState() != State::IDLE) {
|
||||
this->log_WARNING_HI_InvalidSeqRunCall(static_cast<I32>(sequencer_getState()));
|
||||
@ -356,7 +356,8 @@ FpySequencer_DebugTelemetry FpySequencer::getDebugTelemetry() {
|
||||
}
|
||||
if (nextStmt.get_opCode() == Fpy::DirectiveId::CONST_CMD) {
|
||||
// send opcode of the cmd to the ground
|
||||
return FpySequencer_DebugTelemetry(false, true, nextStmt.get_opCode(), directiveUnion.constCmd.get_opCode());
|
||||
return FpySequencer_DebugTelemetry(false, true, nextStmt.get_opCode(),
|
||||
directiveUnion.constCmd.get_opCode());
|
||||
}
|
||||
|
||||
return FpySequencer_DebugTelemetry(false, true, nextStmt.get_opCode(), 0);
|
||||
|
||||
@ -25,8 +25,7 @@ static_assert(Svc::Fpy::MAX_SEQUENCE_ARG_COUNT <= std::numeric_limits<U8>::max()
|
||||
"Sequence arg count must be below U8 max");
|
||||
static_assert(Svc::Fpy::MAX_SEQUENCE_STATEMENT_COUNT <= std::numeric_limits<U16>::max(),
|
||||
"Sequence statement count must be below U16 max");
|
||||
static_assert(Svc::Fpy::MAX_STACK_SIZE <= std::numeric_limits<U16>::max(),
|
||||
"Max stack size must be below U16 max");
|
||||
static_assert(Svc::Fpy::MAX_STACK_SIZE <= std::numeric_limits<U16>::max(), "Max stack size must be below U16 max");
|
||||
static_assert(Svc::Fpy::MAX_STACK_SIZE >= FW_TLM_BUFFER_MAX_SIZE,
|
||||
"Max stack size must be greater than max tlm buffer size");
|
||||
static_assert(Svc::Fpy::MAX_STACK_SIZE >= FW_PARAM_BUFFER_MAX_SIZE,
|
||||
@ -57,6 +56,9 @@ class FpySequencer : public FpySequencerComponentBase {
|
||||
FpySequencer_StoreDirective store;
|
||||
FpySequencer_LoadDirective load;
|
||||
FpySequencer_PushValDirective pushVal;
|
||||
FpySequencer_DiscardDirective discard;
|
||||
FpySequencer_MemCmpDirective memCmp;
|
||||
FpySequencer_StackCmdDirective stackCmd;
|
||||
|
||||
DirectiveUnion() {}
|
||||
~DirectiveUnion() {}
|
||||
@ -405,7 +407,8 @@ class FpySequencer : public FpySequencerComponentBase {
|
||||
void directive_noOp_internalInterfaceHandler(const Svc::FpySequencer_NoOpDirective& directive) override;
|
||||
|
||||
//! Internal interface handler for directive_storeTlmVal
|
||||
void directive_storeTlmVal_internalInterfaceHandler(const Svc::FpySequencer_StoreTlmValDirective& directive) override;
|
||||
void directive_storeTlmVal_internalInterfaceHandler(
|
||||
const Svc::FpySequencer_StoreTlmValDirective& directive) override;
|
||||
|
||||
//! Internal interface handler for directive_storePrm
|
||||
void directive_storePrm_internalInterfaceHandler(const Svc::FpySequencer_StorePrmDirective& directive) override;
|
||||
@ -431,6 +434,15 @@ class FpySequencer : public FpySequencerComponentBase {
|
||||
//! Internal interface handler for directive_pushVal
|
||||
void directive_pushVal_internalInterfaceHandler(const Svc::FpySequencer_PushValDirective& directive) override;
|
||||
|
||||
//! Internal interface handler for directive_discard
|
||||
void directive_discard_internalInterfaceHandler(const Svc::FpySequencer_DiscardDirective& directive) override;
|
||||
|
||||
//! Internal interface handler for directive_memCmp
|
||||
void directive_memCmp_internalInterfaceHandler(const Svc::FpySequencer_MemCmpDirective& directive) override;
|
||||
|
||||
//! Internal interface handler for directive_stackCmd
|
||||
void directive_stackCmd_internalInterfaceHandler(const Svc::FpySequencer_StackCmdDirective& directive) override;
|
||||
|
||||
void parametersLoaded() override;
|
||||
void parameterUpdated(FwPrmIdType id) override;
|
||||
|
||||
@ -589,6 +601,7 @@ class FpySequencer : public FpySequencerComponentBase {
|
||||
|
||||
// sends a signal based on a signal id
|
||||
void sendSignal(Signal signal);
|
||||
Fw::Success sendCmd(FwOpcodeType opcode, const U8* argBuf, FwSizeType argBufSize);
|
||||
|
||||
// pops a value off of the top of the stack
|
||||
// converts it from big endian
|
||||
@ -606,6 +619,8 @@ class FpySequencer : public FpySequencerComponentBase {
|
||||
U8* lvars();
|
||||
// returns the stack height at which the lvar array begins
|
||||
U16 lvarOffset();
|
||||
// returns the index of the current statement
|
||||
U32 currentStatementIdx();
|
||||
|
||||
// we split these functions up into the internalInterfaceInvoke and these custom member funcs
|
||||
// so that we can unit test them easier
|
||||
@ -644,12 +659,39 @@ class FpySequencer : public FpySequencerComponentBase {
|
||||
DirectiveError op_fptosi();
|
||||
DirectiveError op_sitofp();
|
||||
DirectiveError op_uitofp();
|
||||
DirectiveError op_iadd();
|
||||
DirectiveError op_isub();
|
||||
DirectiveError op_imul();
|
||||
DirectiveError op_udiv();
|
||||
DirectiveError op_sdiv();
|
||||
DirectiveError op_umod();
|
||||
DirectiveError op_smod();
|
||||
DirectiveError op_fadd();
|
||||
DirectiveError op_fsub();
|
||||
DirectiveError op_fmul();
|
||||
DirectiveError op_fdiv();
|
||||
DirectiveError op_float_floor_div();
|
||||
DirectiveError op_fpow();
|
||||
DirectiveError op_flog();
|
||||
DirectiveError op_fmod();
|
||||
DirectiveError op_siext_8_64();
|
||||
DirectiveError op_siext_16_64();
|
||||
DirectiveError op_siext_32_64();
|
||||
DirectiveError op_ziext_8_64();
|
||||
DirectiveError op_ziext_16_64();
|
||||
DirectiveError op_ziext_32_64();
|
||||
DirectiveError op_itrunc_64_8();
|
||||
DirectiveError op_itrunc_64_16();
|
||||
DirectiveError op_itrunc_64_32();
|
||||
|
||||
Signal exit_directiveHandler(const FpySequencer_ExitDirective& directive, DirectiveError& error);
|
||||
Signal allocate_directiveHandler(const FpySequencer_AllocateDirective& directive, DirectiveError& error);
|
||||
Signal store_directiveHandler(const FpySequencer_StoreDirective& directive, DirectiveError& error);
|
||||
Signal load_directiveHandler(const FpySequencer_LoadDirective& directive, DirectiveError& error);
|
||||
Signal pushVal_directiveHandler(const FpySequencer_PushValDirective& directive, DirectiveError& error);
|
||||
Signal discard_directiveHandler(const FpySequencer_DiscardDirective& directive, DirectiveError& error);
|
||||
Signal memCmp_directiveHandler(const FpySequencer_MemCmpDirective& directive, DirectiveError& error);
|
||||
Signal stackCmd_directiveHandler(const FpySequencer_StackCmdDirective& directive, DirectiveError& error);
|
||||
};
|
||||
|
||||
} // namespace Svc
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#include <type_traits>
|
||||
#include <cmath>
|
||||
#include <type_traits>
|
||||
#include "Fw/Com/ComPacket.hpp"
|
||||
#include "Svc/FpySequencer/FpySequencer.hpp"
|
||||
|
||||
@ -29,10 +29,44 @@ void FpySequencer::sendSignal(Signal signal) {
|
||||
}
|
||||
}
|
||||
|
||||
Fw::Success FpySequencer::sendCmd(FwOpcodeType opcode, const U8* argBuf, FwSizeType argBufSize) {
|
||||
Fw::ComBuffer cmdBuf;
|
||||
Fw::SerializeStatus stat =
|
||||
cmdBuf.serialize(static_cast<FwPacketDescriptorType>(Fw::ComPacketType::FW_PACKET_COMMAND));
|
||||
// TODO should I assert here? this really shouldn't fail, I should just add a static assert
|
||||
// on com buf size and then assert here
|
||||
if (stat != Fw::SerializeStatus::FW_SERIALIZE_OK) {
|
||||
return Fw::Success::FAILURE;
|
||||
}
|
||||
stat = cmdBuf.serialize(opcode);
|
||||
if (stat != Fw::SerializeStatus::FW_SERIALIZE_OK) {
|
||||
return Fw::Success::FAILURE;
|
||||
}
|
||||
stat = cmdBuf.serialize(argBuf, argBufSize, Fw::Serialization::OMIT_LENGTH);
|
||||
if (stat != Fw::SerializeStatus::FW_SERIALIZE_OK) {
|
||||
return Fw::Success::FAILURE;
|
||||
}
|
||||
|
||||
// calculate the unique command identifier:
|
||||
// cmd UID is formatted like XXYY, where XX are the first two bytes of the m_sequencesStarted counter
|
||||
// and YY are the first two bytes of the m_statementsDispatched counter.
|
||||
// this way, we know when we get a cmd back A) whether or not it's from this sequence (modulo 2^16) and B)
|
||||
// whether or not it's this specific instance of the cmd in the sequence, and not another one with the same opcode
|
||||
// somewhere else in the file.
|
||||
// if we put this uid in the context we send to the cmdDisp, we will get it back when the cmd returns
|
||||
U32 cmdUid =
|
||||
static_cast<U32>(((this->m_sequencesStarted & 0xFFFF) << 16) | (this->m_statementsDispatched & 0xFFFF));
|
||||
|
||||
this->cmdOut_out(0, cmdBuf, cmdUid);
|
||||
|
||||
return Fw::Success::SUCCESS;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T FpySequencer::pop() {
|
||||
static_assert(sizeof(T) == 8 || sizeof(T) == 4 || sizeof(T) == 2 || sizeof(T) == 1, "size must be 1, 2, 4, 8");
|
||||
FW_ASSERT(this->m_runtime.stackSize >= sizeof(T), static_cast<FwAssertArgType>(this->m_runtime.stackSize), static_cast<FwAssertArgType>(sizeof(T)));
|
||||
FW_ASSERT(this->m_runtime.stackSize >= sizeof(T), static_cast<FwAssertArgType>(this->m_runtime.stackSize),
|
||||
static_cast<FwAssertArgType>(sizeof(T)));
|
||||
// first make a byte array which can definitely store our val
|
||||
U8 valBytes[8] = {0};
|
||||
// now move top of stack into byte array and shrink stack
|
||||
@ -41,25 +75,15 @@ T FpySequencer::pop() {
|
||||
|
||||
// now do appropriate byteswap on byte array
|
||||
if (sizeof(T) == 8) {
|
||||
return static_cast<T>(
|
||||
(static_cast<T>(valBytes[7]) << 0) |
|
||||
(static_cast<T>(valBytes[6]) << 8) |
|
||||
(static_cast<T>(valBytes[5]) << 16) |
|
||||
(static_cast<T>(valBytes[4]) << 24) |
|
||||
(static_cast<T>(valBytes[3]) << 32) |
|
||||
(static_cast<T>(valBytes[2]) << 40) |
|
||||
(static_cast<T>(valBytes[1]) << 48) |
|
||||
(static_cast<T>(valBytes[0]) << 56));
|
||||
return static_cast<T>((static_cast<T>(valBytes[7]) << 0) | (static_cast<T>(valBytes[6]) << 8) |
|
||||
(static_cast<T>(valBytes[5]) << 16) | (static_cast<T>(valBytes[4]) << 24) |
|
||||
(static_cast<T>(valBytes[3]) << 32) | (static_cast<T>(valBytes[2]) << 40) |
|
||||
(static_cast<T>(valBytes[1]) << 48) | (static_cast<T>(valBytes[0]) << 56));
|
||||
} else if (sizeof(T) == 4) {
|
||||
return static_cast<T>(
|
||||
(static_cast<T>(valBytes[3]) << 0) |
|
||||
(static_cast<T>(valBytes[2]) << 8) |
|
||||
(static_cast<T>(valBytes[1]) << 16) |
|
||||
(static_cast<T>(valBytes[0]) << 24));
|
||||
return static_cast<T>((static_cast<T>(valBytes[3]) << 0) | (static_cast<T>(valBytes[2]) << 8) |
|
||||
(static_cast<T>(valBytes[1]) << 16) | (static_cast<T>(valBytes[0]) << 24));
|
||||
} else if (sizeof(T) == 2) {
|
||||
return static_cast<T>(
|
||||
(static_cast<T>(valBytes[1]) << 0) |
|
||||
(static_cast<T>(valBytes[0]) << 8));
|
||||
return static_cast<T>((static_cast<T>(valBytes[1]) << 0) | (static_cast<T>(valBytes[0]) << 8));
|
||||
} else {
|
||||
return static_cast<T>(valBytes[0]);
|
||||
}
|
||||
@ -74,14 +98,16 @@ template I16 FpySequencer::pop();
|
||||
template I32 FpySequencer::pop();
|
||||
template I64 FpySequencer::pop();
|
||||
|
||||
template <> F32 FpySequencer::pop<F32>() {
|
||||
template <>
|
||||
F32 FpySequencer::pop<F32>() {
|
||||
U32 endianness = this->pop<U32>();
|
||||
F32 val;
|
||||
memcpy(&val, &endianness, sizeof(val));
|
||||
return val;
|
||||
}
|
||||
|
||||
template <> F64 FpySequencer::pop<F64>() {
|
||||
template <>
|
||||
F64 FpySequencer::pop<F64>() {
|
||||
U64 endianness = this->pop<U64>();
|
||||
F64 val;
|
||||
memcpy(&val, &endianness, sizeof(val));
|
||||
@ -91,7 +117,8 @@ template <> F64 FpySequencer::pop<F64>() {
|
||||
template <typename T>
|
||||
void FpySequencer::push(T val) {
|
||||
static_assert(sizeof(T) == 8 || sizeof(T) == 4 || sizeof(T) == 2 || sizeof(T) == 1, "size must be 1, 2, 4, 8");
|
||||
FW_ASSERT(this->m_runtime.stackSize + sizeof(val) < Fpy::MAX_STACK_SIZE, static_cast<FwAssertArgType>(this->m_runtime.stackSize), static_cast<FwAssertArgType>(sizeof(T)));
|
||||
FW_ASSERT(this->m_runtime.stackSize + sizeof(val) < Fpy::MAX_STACK_SIZE,
|
||||
static_cast<FwAssertArgType>(this->m_runtime.stackSize), static_cast<FwAssertArgType>(sizeof(T)));
|
||||
// first make a byte array which can definitely store our val
|
||||
U8 valBytes[8] = {0};
|
||||
// convert val to unsigned to avoid undefined behavior for bitshifts of signed types
|
||||
@ -130,13 +157,15 @@ template void FpySequencer::push(I16);
|
||||
template void FpySequencer::push(I32);
|
||||
template void FpySequencer::push(I64);
|
||||
|
||||
template <> void FpySequencer::push<F32>(F32 val) {
|
||||
template <>
|
||||
void FpySequencer::push<F32>(F32 val) {
|
||||
U32 endianness;
|
||||
memcpy(&endianness, &val, sizeof(val));
|
||||
this->push(endianness);
|
||||
}
|
||||
|
||||
template <> void FpySequencer::push<F64>(F64 val) {
|
||||
template <>
|
||||
void FpySequencer::push<F64>(F64 val) {
|
||||
U64 endianness;
|
||||
memcpy(&endianness, &val, sizeof(val));
|
||||
this->push(endianness);
|
||||
@ -192,7 +221,8 @@ void FpySequencer::directive_noOp_internalInterfaceHandler(const Svc::FpySequenc
|
||||
}
|
||||
|
||||
//! Internal interface handler for directive_storeTlmVal
|
||||
void FpySequencer::directive_storeTlmVal_internalInterfaceHandler(const Svc::FpySequencer_StoreTlmValDirective& directive) {
|
||||
void FpySequencer::directive_storeTlmVal_internalInterfaceHandler(
|
||||
const Svc::FpySequencer_StoreTlmValDirective& directive) {
|
||||
DirectiveError error = DirectiveError::NO_ERROR;
|
||||
this->sendSignal(this->storeTlmVal_directiveHandler(directive, error));
|
||||
this->m_tlm.lastDirectiveError = error;
|
||||
@ -254,6 +284,27 @@ void FpySequencer::directive_load_internalInterfaceHandler(const Svc::FpySequenc
|
||||
this->m_tlm.lastDirectiveError = error;
|
||||
}
|
||||
|
||||
//! Internal interface handler for directive_discard
|
||||
void FpySequencer::directive_discard_internalInterfaceHandler(const Svc::FpySequencer_DiscardDirective& directive) {
|
||||
DirectiveError error = DirectiveError::NO_ERROR;
|
||||
this->sendSignal(this->discard_directiveHandler(directive, error));
|
||||
this->m_tlm.lastDirectiveError = error;
|
||||
}
|
||||
|
||||
//! Internal interface handler for directive_memCmp
|
||||
void FpySequencer::directive_memCmp_internalInterfaceHandler(const Svc::FpySequencer_MemCmpDirective& directive) {
|
||||
DirectiveError error = DirectiveError::NO_ERROR;
|
||||
this->sendSignal(this->memCmp_directiveHandler(directive, error));
|
||||
this->m_tlm.lastDirectiveError = error;
|
||||
}
|
||||
|
||||
//! Internal interface handler for directive_stackCmd
|
||||
void FpySequencer::directive_stackCmd_internalInterfaceHandler(const Svc::FpySequencer_StackCmdDirective& directive) {
|
||||
DirectiveError error = DirectiveError::NO_ERROR;
|
||||
this->sendSignal(this->stackCmd_directiveHandler(directive, error));
|
||||
this->m_tlm.lastDirectiveError = error;
|
||||
}
|
||||
|
||||
//! Internal interface handler for directive_waitRel
|
||||
Signal FpySequencer::waitRel_directiveHandler(const FpySequencer_WaitRelDirective& directive, DirectiveError& error) {
|
||||
if (this->m_runtime.stackSize < 8) {
|
||||
@ -324,7 +375,8 @@ Signal FpySequencer::noOp_directiveHandler(const FpySequencer_NoOpDirective& dir
|
||||
return Signal::stmtResponse_success;
|
||||
}
|
||||
|
||||
Signal FpySequencer::storeTlmVal_directiveHandler(const FpySequencer_StoreTlmValDirective& directive, DirectiveError& error) {
|
||||
Signal FpySequencer::storeTlmVal_directiveHandler(const FpySequencer_StoreTlmValDirective& directive,
|
||||
DirectiveError& error) {
|
||||
if (!this->isConnected_getTlmChan_OutputPort(0)) {
|
||||
error = DirectiveError::TLM_GET_NOT_CONNECTED;
|
||||
return Signal::stmtResponse_failure;
|
||||
@ -390,40 +442,14 @@ Signal FpySequencer::storePrm_directiveHandler(const FpySequencer_StorePrmDirect
|
||||
}
|
||||
|
||||
Signal FpySequencer::constCmd_directiveHandler(const FpySequencer_ConstCmdDirective& directive, DirectiveError& error) {
|
||||
Fw::ComBuffer cmdBuf;
|
||||
Fw::SerializeStatus stat = cmdBuf.serialize(static_cast<FwPacketDescriptorType>(Fw::ComPacketType::FW_PACKET_COMMAND));
|
||||
// TODO should I assert here? this really shouldn't fail, I should just add a static assert
|
||||
// on com buf size and then assert here
|
||||
if (stat != Fw::SerializeStatus::FW_SERIALIZE_OK) {
|
||||
error = DirectiveError::CMD_SERIALIZE_FAILURE;
|
||||
if (this->sendCmd(directive.get_opCode(), directive.get_argBuf(), directive.get__argBufSize()) ==
|
||||
Fw::Success::FAILURE) {
|
||||
return Signal::stmtResponse_failure;
|
||||
} else {
|
||||
// now tell the SM to wait some more until we get the cmd response back
|
||||
// if we've already got the response back this should be harmless
|
||||
return Signal::stmtResponse_keepWaiting;
|
||||
}
|
||||
stat = cmdBuf.serialize(directive.get_opCode());
|
||||
if (stat != Fw::SerializeStatus::FW_SERIALIZE_OK) {
|
||||
error = DirectiveError::CMD_SERIALIZE_FAILURE;
|
||||
return Signal::stmtResponse_failure;
|
||||
}
|
||||
stat = cmdBuf.serialize(directive.get_argBuf(), directive.get__argBufSize(), Fw::Serialization::OMIT_LENGTH);
|
||||
if (stat != Fw::SerializeStatus::FW_SERIALIZE_OK) {
|
||||
error = DirectiveError::CMD_SERIALIZE_FAILURE;
|
||||
return Signal::stmtResponse_failure;
|
||||
}
|
||||
|
||||
// calculate the unique command identifier:
|
||||
// cmd UID is formatted like XXYY, where XX are the first two bytes of the m_sequencesStarted counter
|
||||
// and YY are the first two bytes of the m_statementsDispatched counter.
|
||||
// this way, we know when we get a cmd back A) whether or not it's from this sequence (modulo 2^16) and B)
|
||||
// whether or not it's this specific instance of the cmd in the sequence, and not another one with the same opcode
|
||||
// somewhere else in the file.
|
||||
// if we put this uid in the context we send to the cmdDisp, we will get it back when the cmd returns
|
||||
U32 cmdUid =
|
||||
static_cast<U32>(((this->m_sequencesStarted & 0xFFFF) << 16) | (this->m_statementsDispatched & 0xFFFF));
|
||||
|
||||
this->cmdOut_out(0, cmdBuf, cmdUid);
|
||||
|
||||
// now tell the SM to wait some more until we get the cmd response back
|
||||
// if we've already got the response back this should be harmless
|
||||
return Signal::stmtResponse_keepWaiting;
|
||||
}
|
||||
|
||||
I8 floatCmp(F64 lhs, F64 rhs) {
|
||||
@ -440,35 +466,35 @@ I8 floatCmp(F64 lhs, F64 rhs) {
|
||||
}
|
||||
|
||||
DirectiveError FpySequencer::op_or() {
|
||||
if (this->m_runtime.stackSize < 2) {
|
||||
if (this->m_runtime.stackSize < sizeof(U8) * 2) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
this->push(static_cast<U8>(this->pop<U8>() | this->pop<U8>()));
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_and() {
|
||||
if (this->m_runtime.stackSize < 2) {
|
||||
if (this->m_runtime.stackSize < sizeof(U8) * 2) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
this->push(static_cast<U8>(this->pop<U8>() & this->pop<U8>()));
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_ieq() {
|
||||
if (this->m_runtime.stackSize < 16) {
|
||||
if (this->m_runtime.stackSize < sizeof(I64) * 2) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
this->push(static_cast<U8>(this->pop<I64>() == this->pop<I64>()));
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_ine() {
|
||||
if (this->m_runtime.stackSize < 16) {
|
||||
if (this->m_runtime.stackSize < sizeof(I64) * 2) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
this->push(static_cast<U8>(this->pop<I64>() != this->pop<I64>()));
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_ult() {
|
||||
if (this->m_runtime.stackSize < 16) {
|
||||
if (this->m_runtime.stackSize < sizeof(U64) * 2) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
U64 rhs = this->pop<U64>();
|
||||
@ -477,7 +503,7 @@ DirectiveError FpySequencer::op_ult() {
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_ule() {
|
||||
if (this->m_runtime.stackSize < 16) {
|
||||
if (this->m_runtime.stackSize < sizeof(U64) * 2) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
U64 rhs = this->pop<U64>();
|
||||
@ -486,7 +512,7 @@ DirectiveError FpySequencer::op_ule() {
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_ugt() {
|
||||
if (this->m_runtime.stackSize < 16) {
|
||||
if (this->m_runtime.stackSize < sizeof(U64) * 2) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
U64 rhs = this->pop<U64>();
|
||||
@ -495,7 +521,7 @@ DirectiveError FpySequencer::op_ugt() {
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_uge() {
|
||||
if (this->m_runtime.stackSize < 16) {
|
||||
if (this->m_runtime.stackSize < sizeof(U64) * 2) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
U64 rhs = this->pop<U64>();
|
||||
@ -504,7 +530,7 @@ DirectiveError FpySequencer::op_uge() {
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_slt() {
|
||||
if (this->m_runtime.stackSize < 16) {
|
||||
if (this->m_runtime.stackSize < sizeof(I64) * 2) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
I64 rhs = this->pop<I64>();
|
||||
@ -513,7 +539,7 @@ DirectiveError FpySequencer::op_slt() {
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_sle() {
|
||||
if (this->m_runtime.stackSize < 16) {
|
||||
if (this->m_runtime.stackSize < sizeof(I64) * 2) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
I64 rhs = this->pop<I64>();
|
||||
@ -522,7 +548,7 @@ DirectiveError FpySequencer::op_sle() {
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_sgt() {
|
||||
if (this->m_runtime.stackSize < 16) {
|
||||
if (this->m_runtime.stackSize < sizeof(I64) * 2) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
I64 rhs = this->pop<I64>();
|
||||
@ -531,7 +557,7 @@ DirectiveError FpySequencer::op_sgt() {
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_sge() {
|
||||
if (this->m_runtime.stackSize < 16) {
|
||||
if (this->m_runtime.stackSize < sizeof(I64) * 2) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
I64 rhs = this->pop<I64>();
|
||||
@ -540,7 +566,7 @@ DirectiveError FpySequencer::op_sge() {
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_feq() {
|
||||
if (this->m_runtime.stackSize < 16) {
|
||||
if (this->m_runtime.stackSize < sizeof(F64) * 2) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
F64 rhs = this->pop<F64>();
|
||||
@ -550,7 +576,7 @@ DirectiveError FpySequencer::op_feq() {
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_fne() {
|
||||
if (this->m_runtime.stackSize < 16) {
|
||||
if (this->m_runtime.stackSize < sizeof(F64) * 2) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
F64 rhs = this->pop<F64>();
|
||||
@ -561,7 +587,7 @@ DirectiveError FpySequencer::op_fne() {
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_flt() {
|
||||
if (this->m_runtime.stackSize < 16) {
|
||||
if (this->m_runtime.stackSize < sizeof(F64) * 2) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
F64 rhs = this->pop<F64>();
|
||||
@ -570,7 +596,7 @@ DirectiveError FpySequencer::op_flt() {
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_fle() {
|
||||
if (this->m_runtime.stackSize < 16) {
|
||||
if (this->m_runtime.stackSize < sizeof(F64) * 2) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
F64 rhs = this->pop<F64>();
|
||||
@ -580,7 +606,7 @@ DirectiveError FpySequencer::op_fle() {
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_fgt() {
|
||||
if (this->m_runtime.stackSize < 16) {
|
||||
if (this->m_runtime.stackSize < sizeof(F64) * 2) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
F64 rhs = this->pop<F64>();
|
||||
@ -589,7 +615,7 @@ DirectiveError FpySequencer::op_fgt() {
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_fge() {
|
||||
if (this->m_runtime.stackSize < 16) {
|
||||
if (this->m_runtime.stackSize < sizeof(F64) * 2) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
F64 rhs = this->pop<F64>();
|
||||
@ -599,7 +625,7 @@ DirectiveError FpySequencer::op_fge() {
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_not() {
|
||||
if (this->m_runtime.stackSize < 1) {
|
||||
if (this->m_runtime.stackSize < sizeof(U8)) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
this->push(static_cast<U8>(this->pop<U8>() == 0));
|
||||
@ -607,7 +633,7 @@ DirectiveError FpySequencer::op_not() {
|
||||
}
|
||||
DirectiveError FpySequencer::op_fpext() {
|
||||
// convert F32 to F64
|
||||
if (this->m_runtime.stackSize < 4) {
|
||||
if (this->m_runtime.stackSize < sizeof(F32)) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
this->push(static_cast<F64>(this->pop<F32>()));
|
||||
@ -615,44 +641,266 @@ DirectiveError FpySequencer::op_fpext() {
|
||||
}
|
||||
DirectiveError FpySequencer::op_fptrunc() {
|
||||
// convert F64 to F32
|
||||
if (this->m_runtime.stackSize < 8) {
|
||||
if (this->m_runtime.stackSize < sizeof(F64)) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
this->push(static_cast<F32>(this->pop<F64>()));
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_fptosi() {
|
||||
if (this->m_runtime.stackSize < 8) {
|
||||
if (this->m_runtime.stackSize < sizeof(F64)) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
this->push(static_cast<I64>(this->pop<F64>()));
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_sitofp() {
|
||||
if (this->m_runtime.stackSize < 8) {
|
||||
if (this->m_runtime.stackSize < sizeof(I64)) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
this->push(static_cast<F64>(this->pop<I64>()));
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_fptoui() {
|
||||
if (this->m_runtime.stackSize < 8) {
|
||||
if (this->m_runtime.stackSize < sizeof(F64)) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
this->push(static_cast<U64>(this->pop<F64>()));
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_uitofp() {
|
||||
if (this->m_runtime.stackSize < 8) {
|
||||
if (this->m_runtime.stackSize < sizeof(U64)) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
this->push(static_cast<F64>(this->pop<U64>()));
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
Signal FpySequencer::stackOp_directiveHandler(const FpySequencer_StackOpDirective& directive,
|
||||
DirectiveError& error) {
|
||||
// coding error, should not have gotten to this binary reg op handler
|
||||
FW_ASSERT(directive.get__op() >= Fpy::DirectiveId::OR && directive.get__op() <= Fpy::DirectiveId::UITOFP,
|
||||
DirectiveError FpySequencer::op_iadd() {
|
||||
if (this->m_runtime.stackSize < sizeof(I64) * 2) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
I64 rhs = this->pop<I64>();
|
||||
I64 lhs = this->pop<I64>();
|
||||
this->push(static_cast<I64>(lhs + rhs));
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_isub() {
|
||||
if (this->m_runtime.stackSize < sizeof(I64) * 2) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
I64 rhs = this->pop<I64>();
|
||||
I64 lhs = this->pop<I64>();
|
||||
this->push(static_cast<I64>(lhs - rhs));
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_imul() {
|
||||
if (this->m_runtime.stackSize < sizeof(I64) * 2) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
I64 rhs = this->pop<I64>();
|
||||
I64 lhs = this->pop<I64>();
|
||||
this->push(static_cast<I64>(lhs * rhs));
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_udiv() {
|
||||
if (this->m_runtime.stackSize < sizeof(U64) * 2) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
U64 rhs = this->pop<U64>();
|
||||
U64 lhs = this->pop<U64>();
|
||||
this->push(static_cast<U64>(lhs / rhs));
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_sdiv() {
|
||||
if (this->m_runtime.stackSize < sizeof(I64) * 2) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
I64 rhs = this->pop<I64>();
|
||||
I64 lhs = this->pop<I64>();
|
||||
this->push(static_cast<I64>(lhs / rhs));
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_umod() {
|
||||
if (this->m_runtime.stackSize < sizeof(U64) * 2) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
U64 rhs = this->pop<U64>();
|
||||
if (rhs == 0) {
|
||||
return DirectiveError::DOMAIN_ERROR;
|
||||
}
|
||||
U64 lhs = this->pop<U64>();
|
||||
this->push(static_cast<U64>(lhs % rhs));
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_smod() {
|
||||
if (this->m_runtime.stackSize < sizeof(I64) * 2) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
I64 rhs = this->pop<I64>();
|
||||
if (rhs == 0) {
|
||||
return DirectiveError::DOMAIN_ERROR;
|
||||
}
|
||||
I64 lhs = this->pop<I64>();
|
||||
I64 res = static_cast<I64>(lhs % rhs);
|
||||
// in order to match Python's behavior,
|
||||
// if the signs of the remainder and divisor differ, adjust the result.
|
||||
// this happens when the result should be positive but is negative, or vice-versa.
|
||||
// credit Gemini 2.5 pro
|
||||
if ((res > 0 && rhs < 0) || (res < 0 && rhs > 0)) {
|
||||
res += rhs;
|
||||
}
|
||||
this->push(res);
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_fadd() {
|
||||
if (this->m_runtime.stackSize < sizeof(F64) * 2) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
F64 rhs = this->pop<F64>();
|
||||
F64 lhs = this->pop<F64>();
|
||||
this->push(static_cast<F64>(lhs + rhs));
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_fsub() {
|
||||
if (this->m_runtime.stackSize < sizeof(F64) * 2) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
F64 rhs = this->pop<F64>();
|
||||
F64 lhs = this->pop<F64>();
|
||||
this->push(static_cast<F64>(lhs - rhs));
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_fmul() {
|
||||
if (this->m_runtime.stackSize < sizeof(F64) * 2) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
F64 rhs = this->pop<F64>();
|
||||
F64 lhs = this->pop<F64>();
|
||||
this->push(static_cast<F64>(lhs * rhs));
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_fdiv() {
|
||||
if (this->m_runtime.stackSize < sizeof(F64) * 2) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
F64 rhs = this->pop<F64>();
|
||||
F64 lhs = this->pop<F64>();
|
||||
this->push(static_cast<F64>(lhs / rhs));
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_float_floor_div() {
|
||||
if (this->m_runtime.stackSize < sizeof(F64) * 2) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
F64 rhs = this->pop<F64>();
|
||||
F64 lhs = this->pop<F64>();
|
||||
this->push(static_cast<F64>(floor(lhs / rhs)));
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_fpow() {
|
||||
if (this->m_runtime.stackSize < sizeof(F64) * 2) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
F64 rhs = this->pop<F64>();
|
||||
F64 lhs = this->pop<F64>();
|
||||
this->push(static_cast<F64>(pow(lhs, rhs)));
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_flog() {
|
||||
if (this->m_runtime.stackSize < sizeof(F64)) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
F64 val = this->pop<F64>();
|
||||
this->push(static_cast<F64>(log(val)));
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_fmod() {
|
||||
if (this->m_runtime.stackSize < sizeof(F64) * 2) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
F64 rhs = this->pop<F64>();
|
||||
if (rhs == 0.0) {
|
||||
return DirectiveError::DOMAIN_ERROR;
|
||||
}
|
||||
F64 lhs = this->pop<F64>();
|
||||
this->push(static_cast<F64>(lhs - rhs * std::floor(lhs / rhs)));
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_siext_8_64() {
|
||||
if (this->m_runtime.stackSize < sizeof(I8)) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
I8 src = this->pop<I8>();
|
||||
this->push(static_cast<I64>(src));
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_siext_16_64() {
|
||||
if (this->m_runtime.stackSize < sizeof(I16)) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
I16 src = this->pop<I16>();
|
||||
this->push(static_cast<I64>(src));
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_siext_32_64() {
|
||||
if (this->m_runtime.stackSize < sizeof(I32)) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
I32 src = this->pop<I32>();
|
||||
this->push(static_cast<I64>(src));
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_ziext_8_64() {
|
||||
if (this->m_runtime.stackSize < sizeof(U8)) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
U8 src = this->pop<U8>();
|
||||
this->push(static_cast<U64>(src));
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_ziext_16_64() {
|
||||
if (this->m_runtime.stackSize < sizeof(U16)) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
U16 src = this->pop<U16>();
|
||||
this->push(static_cast<U64>(src));
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_ziext_32_64() {
|
||||
if (this->m_runtime.stackSize < sizeof(U32)) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
U32 src = this->pop<U32>();
|
||||
this->push(static_cast<U64>(src));
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_itrunc_64_8() {
|
||||
if (this->m_runtime.stackSize < sizeof(U64)) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
U64 src = this->pop<U64>();
|
||||
this->push(static_cast<U8>(src));
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_itrunc_64_16() {
|
||||
if (this->m_runtime.stackSize < sizeof(U64)) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
U64 src = this->pop<U64>();
|
||||
this->push(static_cast<U16>(src));
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
DirectiveError FpySequencer::op_itrunc_64_32() {
|
||||
if (this->m_runtime.stackSize < sizeof(U64)) {
|
||||
return DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
}
|
||||
U64 src = this->pop<U64>();
|
||||
this->push(static_cast<U32>(src));
|
||||
return DirectiveError::NO_ERROR;
|
||||
}
|
||||
Signal FpySequencer::stackOp_directiveHandler(const FpySequencer_StackOpDirective& directive, DirectiveError& error) {
|
||||
// coding error, should not have gotten to this stack op handler
|
||||
FW_ASSERT(directive.get__op() >= Fpy::DirectiveId::OR && directive.get__op() <= Fpy::DirectiveId::ITRUNC_64_32,
|
||||
static_cast<FwAssertArgType>(directive.get__op()));
|
||||
|
||||
switch (directive.get__op()) {
|
||||
@ -731,6 +979,78 @@ Signal FpySequencer::stackOp_directiveHandler(const FpySequencer_StackOpDirectiv
|
||||
case Fpy::DirectiveId::UITOFP:
|
||||
error = this->op_uitofp();
|
||||
break;
|
||||
case Fpy::DirectiveId::IADD:
|
||||
error = this->op_iadd();
|
||||
break;
|
||||
case Fpy::DirectiveId::ISUB:
|
||||
error = this->op_isub();
|
||||
break;
|
||||
case Fpy::DirectiveId::IMUL:
|
||||
error = this->op_imul();
|
||||
break;
|
||||
case Fpy::DirectiveId::UDIV:
|
||||
error = this->op_udiv();
|
||||
break;
|
||||
case Fpy::DirectiveId::SDIV:
|
||||
error = this->op_sdiv();
|
||||
break;
|
||||
case Fpy::DirectiveId::UMOD:
|
||||
error = this->op_umod();
|
||||
break;
|
||||
case Fpy::DirectiveId::SMOD:
|
||||
error = this->op_smod();
|
||||
break;
|
||||
case Fpy::DirectiveId::FADD:
|
||||
error = this->op_fadd();
|
||||
break;
|
||||
case Fpy::DirectiveId::FSUB:
|
||||
error = this->op_fsub();
|
||||
break;
|
||||
case Fpy::DirectiveId::FMUL:
|
||||
error = this->op_fmul();
|
||||
break;
|
||||
case Fpy::DirectiveId::FDIV:
|
||||
error = this->op_fdiv();
|
||||
break;
|
||||
case Fpy::DirectiveId::FLOAT_FLOOR_DIV:
|
||||
error = this->op_float_floor_div();
|
||||
break;
|
||||
case Fpy::DirectiveId::FPOW:
|
||||
error = this->op_fpow();
|
||||
break;
|
||||
case Fpy::DirectiveId::FLOG:
|
||||
error = this->op_flog();
|
||||
break;
|
||||
case Fpy::DirectiveId::FMOD:
|
||||
error = this->op_fmod();
|
||||
break;
|
||||
case Fpy::DirectiveId::SIEXT_8_64:
|
||||
error = this->op_siext_8_64();
|
||||
break;
|
||||
case Fpy::DirectiveId::SIEXT_16_64:
|
||||
error = this->op_siext_16_64();
|
||||
break;
|
||||
case Fpy::DirectiveId::SIEXT_32_64:
|
||||
error = this->op_siext_32_64();
|
||||
break;
|
||||
case Fpy::DirectiveId::ZIEXT_8_64:
|
||||
error = this->op_ziext_8_64();
|
||||
break;
|
||||
case Fpy::DirectiveId::ZIEXT_16_64:
|
||||
error = this->op_ziext_16_64();
|
||||
break;
|
||||
case Fpy::DirectiveId::ZIEXT_32_64:
|
||||
error = this->op_ziext_32_64();
|
||||
break;
|
||||
case Fpy::DirectiveId::ITRUNC_64_8:
|
||||
error = this->op_itrunc_64_8();
|
||||
break;
|
||||
case Fpy::DirectiveId::ITRUNC_64_16:
|
||||
error = this->op_itrunc_64_16();
|
||||
break;
|
||||
case Fpy::DirectiveId::ITRUNC_64_32:
|
||||
error = this->op_itrunc_64_32();
|
||||
break;
|
||||
default:
|
||||
FW_ASSERT(0, directive.get__op());
|
||||
break;
|
||||
@ -811,4 +1131,57 @@ Signal FpySequencer::pushVal_directiveHandler(const FpySequencer_PushValDirectiv
|
||||
this->m_runtime.stackSize += directive.get__valSize();
|
||||
return Signal::stmtResponse_success;
|
||||
}
|
||||
|
||||
Signal FpySequencer::discard_directiveHandler(const FpySequencer_DiscardDirective& directive, DirectiveError& error) {
|
||||
if (this->m_runtime.stackSize < directive.get_size()) {
|
||||
error = DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
return Signal::stmtResponse_failure;
|
||||
}
|
||||
this->m_runtime.stackSize -= directive.get_size();
|
||||
return Signal::stmtResponse_success;
|
||||
}
|
||||
|
||||
Signal FpySequencer::memCmp_directiveHandler(const FpySequencer_MemCmpDirective& directive, DirectiveError& error) {
|
||||
if (this->m_runtime.stackSize < directive.get_size() * 2) {
|
||||
error = DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
return Signal::stmtResponse_failure;
|
||||
}
|
||||
|
||||
U64 lhsOffset = this->m_runtime.stackSize - directive.get_size() * 2;
|
||||
U64 rhsOffset = this->m_runtime.stackSize - directive.get_size();
|
||||
this->m_runtime.stackSize -= directive.get_size() * 2;
|
||||
|
||||
if (memcmp(this->m_runtime.stack + lhsOffset, this->m_runtime.stack + rhsOffset, directive.get_size()) == 0) {
|
||||
this->push<U8>(1);
|
||||
} else {
|
||||
this->push<U8>(0);
|
||||
}
|
||||
return Signal::stmtResponse_success;
|
||||
}
|
||||
|
||||
Signal FpySequencer::stackCmd_directiveHandler(const FpySequencer_StackCmdDirective& directive, DirectiveError& error) {
|
||||
if (this->m_runtime.stackSize < static_cast<U64>(directive.get_argsSize() + sizeof(FwOpcodeType))) {
|
||||
error = DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS;
|
||||
return Signal::stmtResponse_failure;
|
||||
}
|
||||
|
||||
FwOpcodeType opcode = this->pop<FwOpcodeType>();
|
||||
U64 argBufOffset = this->m_runtime.stackSize - directive.get_argsSize();
|
||||
|
||||
// update the opcode of the cmd we will await
|
||||
this->m_runtime.currentCmdOpcode = opcode;
|
||||
|
||||
// also pop the args off the stack
|
||||
this->m_runtime.stackSize -= directive.get_argsSize();
|
||||
|
||||
if (this->sendCmd(opcode, this->m_runtime.stack + argBufOffset, directive.get_argsSize()) == Fw::Success::FAILURE) {
|
||||
return Signal::stmtResponse_failure;
|
||||
} else {
|
||||
// now tell the SM to wait some more until we get the cmd response back
|
||||
// if we've already got the response back this should be harmless
|
||||
return Signal::stmtResponse_keepWaiting;
|
||||
}
|
||||
|
||||
return Signal::stmtResponse_success;
|
||||
}
|
||||
} // namespace Svc
|
||||
|
||||
@ -94,6 +94,18 @@ struct PushValDirective {
|
||||
_valSize: FwSizeType
|
||||
}
|
||||
|
||||
struct DiscardDirective {
|
||||
$size: U16
|
||||
}
|
||||
|
||||
struct MemCmpDirective {
|
||||
$size: U16
|
||||
}
|
||||
|
||||
struct StackCmdDirective {
|
||||
argsSize: U16
|
||||
}
|
||||
|
||||
internal port directive_waitRel(directive: WaitRelDirective) priority 6 assert
|
||||
|
||||
internal port directive_waitAbs(directive: WaitAbsDirective) priority 6 assert
|
||||
@ -122,6 +134,12 @@ internal port directive_load(directive: LoadDirective) priority 6 assert
|
||||
|
||||
internal port directive_pushVal(directive: PushValDirective) priority 6 assert
|
||||
|
||||
internal port directive_discard(directive: DiscardDirective) priority 6 assert
|
||||
|
||||
internal port directive_memCmp(directive: MemCmpDirective) priority 6 assert
|
||||
|
||||
internal port directive_stackCmd(directive: StackCmdDirective) priority 6 assert
|
||||
|
||||
enum DirectiveErrorCode {
|
||||
NO_ERROR
|
||||
STMT_OUT_OF_BOUNDS
|
||||
@ -133,4 +151,5 @@ enum DirectiveErrorCode {
|
||||
DELIBERATE_FAILURE
|
||||
STACK_ACCESS_OUT_OF_BOUNDS
|
||||
STACK_OVERFLOW
|
||||
DOMAIN_ERROR
|
||||
}
|
||||
@ -4,6 +4,15 @@
|
||||
#include "Svc/FpySequencer/FpySequencer.hpp"
|
||||
namespace Svc {
|
||||
|
||||
// returns the index of the current statement
|
||||
U32 FpySequencer::currentStatementIdx() {
|
||||
if (this->m_runtime.nextStatementIndex == 0) {
|
||||
// haven't started executing the sequence yet
|
||||
return 0;
|
||||
}
|
||||
return this->m_runtime.nextStatementIndex - 1;
|
||||
}
|
||||
|
||||
Signal FpySequencer::dispatchStatement() {
|
||||
// check to make sure no array out of bounds, or if it is out of bounds it's only 1 out of bound
|
||||
// as that indicates eof
|
||||
@ -16,7 +25,7 @@ Signal FpySequencer::dispatchStatement() {
|
||||
const Fpy::Statement& nextStatement = this->m_sequenceObj.get_statements()[this->m_runtime.nextStatementIndex];
|
||||
this->m_runtime.nextStatementIndex++;
|
||||
this->m_runtime.currentStatementOpcode = nextStatement.get_opCode();
|
||||
this->m_runtime.currentCmdOpcode = 0; // we haven't deserialized the directive yet, so we don't know if it's a cmd
|
||||
this->m_runtime.currentCmdOpcode = 0; // we haven't deserialized the directive yet, so we don't know if it's a cmd
|
||||
|
||||
Fw::Success result;
|
||||
DirectiveUnion directiveUnion;
|
||||
@ -34,7 +43,8 @@ Signal FpySequencer::dispatchStatement() {
|
||||
|
||||
this->dispatchDirective(directiveUnion,
|
||||
Fpy::DirectiveId(static_cast<Fpy::DirectiveId::T>(nextStatement.get_opCode())));
|
||||
this->m_runtime.currentStatementDispatchTime = getTime(); // set dispatch time right after we have successfully dispatched
|
||||
this->m_runtime.currentStatementDispatchTime =
|
||||
getTime(); // set dispatch time right after we have successfully dispatched
|
||||
|
||||
this->m_statementsDispatched++;
|
||||
|
||||
@ -57,7 +67,7 @@ Fw::Success FpySequencer::deserializeDirective(const Fpy::Statement& stmt, Direc
|
||||
new (&deserializedDirective.waitRel) FpySequencer_WaitRelDirective();
|
||||
// wait rel does not need deser
|
||||
if (argBuf.getBuffLeft() != 0) {
|
||||
this->log_WARNING_HI_DirectiveDeserializeError(stmt.get_opCode(), this->m_runtime.nextStatementIndex - 1,
|
||||
this->log_WARNING_HI_DirectiveDeserializeError(stmt.get_opCode(), this->currentStatementIdx(),
|
||||
Fw::SerializeStatus::FW_DESERIALIZE_SIZE_MISMATCH,
|
||||
argBuf.getBuffLeft(), argBuf.getBuffLength());
|
||||
return Fw::Success::FAILURE;
|
||||
@ -68,7 +78,7 @@ Fw::Success FpySequencer::deserializeDirective(const Fpy::Statement& stmt, Direc
|
||||
new (&deserializedDirective.waitAbs) FpySequencer_WaitAbsDirective();
|
||||
// wait abs does not need deser
|
||||
if (argBuf.getBuffLeft() != 0) {
|
||||
this->log_WARNING_HI_DirectiveDeserializeError(stmt.get_opCode(), this->m_runtime.nextStatementIndex - 1,
|
||||
this->log_WARNING_HI_DirectiveDeserializeError(stmt.get_opCode(), this->currentStatementIdx(),
|
||||
Fw::SerializeStatus::FW_DESERIALIZE_SIZE_MISMATCH,
|
||||
argBuf.getBuffLeft(), argBuf.getBuffLength());
|
||||
return Fw::Success::FAILURE;
|
||||
@ -79,8 +89,8 @@ Fw::Success FpySequencer::deserializeDirective(const Fpy::Statement& stmt, Direc
|
||||
new (&deserializedDirective.gotoDirective) FpySequencer_GotoDirective();
|
||||
status = argBuf.deserialize(deserializedDirective.gotoDirective);
|
||||
if (status != Fw::SerializeStatus::FW_SERIALIZE_OK || argBuf.getBuffLeft() != 0) {
|
||||
this->log_WARNING_HI_DirectiveDeserializeError(stmt.get_opCode(), this->m_runtime.nextStatementIndex - 1,
|
||||
status, argBuf.getBuffLeft(), argBuf.getBuffLength());
|
||||
this->log_WARNING_HI_DirectiveDeserializeError(stmt.get_opCode(), this->currentStatementIdx(), status,
|
||||
argBuf.getBuffLeft(), argBuf.getBuffLength());
|
||||
return Fw::Success::FAILURE;
|
||||
}
|
||||
break;
|
||||
@ -89,8 +99,8 @@ Fw::Success FpySequencer::deserializeDirective(const Fpy::Statement& stmt, Direc
|
||||
new (&deserializedDirective.ifDirective) FpySequencer_IfDirective();
|
||||
status = argBuf.deserialize(deserializedDirective.ifDirective);
|
||||
if (status != Fw::SerializeStatus::FW_SERIALIZE_OK || argBuf.getBuffLeft() != 0) {
|
||||
this->log_WARNING_HI_DirectiveDeserializeError(stmt.get_opCode(), this->m_runtime.nextStatementIndex - 1,
|
||||
status, argBuf.getBuffLeft(), argBuf.getBuffLength());
|
||||
this->log_WARNING_HI_DirectiveDeserializeError(stmt.get_opCode(), this->currentStatementIdx(), status,
|
||||
argBuf.getBuffLeft(), argBuf.getBuffLength());
|
||||
return Fw::Success::FAILURE;
|
||||
}
|
||||
break;
|
||||
@ -99,7 +109,7 @@ Fw::Success FpySequencer::deserializeDirective(const Fpy::Statement& stmt, Direc
|
||||
new (&deserializedDirective.noOp) FpySequencer_NoOpDirective();
|
||||
// no op does not need deser
|
||||
if (argBuf.getBuffLeft() != 0) {
|
||||
this->log_WARNING_HI_DirectiveDeserializeError(stmt.get_opCode(), this->m_runtime.nextStatementIndex - 1,
|
||||
this->log_WARNING_HI_DirectiveDeserializeError(stmt.get_opCode(), this->currentStatementIdx(),
|
||||
Fw::SerializeStatus::FW_DESERIALIZE_SIZE_MISMATCH,
|
||||
argBuf.getBuffLeft(), argBuf.getBuffLength());
|
||||
return Fw::Success::FAILURE;
|
||||
@ -110,8 +120,8 @@ Fw::Success FpySequencer::deserializeDirective(const Fpy::Statement& stmt, Direc
|
||||
new (&deserializedDirective.storeTlmVal) FpySequencer_StoreTlmValDirective();
|
||||
status = argBuf.deserialize(deserializedDirective.storeTlmVal);
|
||||
if (status != Fw::SerializeStatus::FW_SERIALIZE_OK || argBuf.getBuffLeft() != 0) {
|
||||
this->log_WARNING_HI_DirectiveDeserializeError(stmt.get_opCode(), this->m_runtime.nextStatementIndex - 1,
|
||||
status, argBuf.getBuffLeft(), argBuf.getBuffLength());
|
||||
this->log_WARNING_HI_DirectiveDeserializeError(stmt.get_opCode(), this->currentStatementIdx(), status,
|
||||
argBuf.getBuffLeft(), argBuf.getBuffLength());
|
||||
return Fw::Success::FAILURE;
|
||||
}
|
||||
break;
|
||||
@ -120,8 +130,8 @@ Fw::Success FpySequencer::deserializeDirective(const Fpy::Statement& stmt, Direc
|
||||
new (&deserializedDirective.storePrm) FpySequencer_StorePrmDirective();
|
||||
status = argBuf.deserialize(deserializedDirective.storePrm);
|
||||
if (status != Fw::SerializeStatus::FW_SERIALIZE_OK || argBuf.getBuffLeft() != 0) {
|
||||
this->log_WARNING_HI_DirectiveDeserializeError(stmt.get_opCode(), this->m_runtime.nextStatementIndex - 1,
|
||||
status, argBuf.getBuffLeft(), argBuf.getBuffLength());
|
||||
this->log_WARNING_HI_DirectiveDeserializeError(stmt.get_opCode(), this->currentStatementIdx(), status,
|
||||
argBuf.getBuffLeft(), argBuf.getBuffLength());
|
||||
return Fw::Success::FAILURE;
|
||||
}
|
||||
break;
|
||||
@ -133,8 +143,8 @@ Fw::Success FpySequencer::deserializeDirective(const Fpy::Statement& stmt, Direc
|
||||
FwOpcodeType opcode;
|
||||
status = argBuf.deserialize(opcode);
|
||||
if (status != Fw::SerializeStatus::FW_SERIALIZE_OK) {
|
||||
this->log_WARNING_HI_DirectiveDeserializeError(stmt.get_opCode(), this->m_runtime.nextStatementIndex - 1,
|
||||
status, argBuf.getBuffLeft(), argBuf.getBuffLength());
|
||||
this->log_WARNING_HI_DirectiveDeserializeError(stmt.get_opCode(), this->currentStatementIdx(), status,
|
||||
argBuf.getBuffLeft(), argBuf.getBuffLength());
|
||||
return Fw::Success::FAILURE;
|
||||
}
|
||||
|
||||
@ -144,18 +154,19 @@ Fw::Success FpySequencer::deserializeDirective(const Fpy::Statement& stmt, Direc
|
||||
|
||||
// check to make sure the value will fit in the FpySequencer_ConstCmdDirective::argBuf
|
||||
if (cmdArgBufSize > Fpy::MAX_DIRECTIVE_SIZE) {
|
||||
this->log_WARNING_HI_DirectiveDeserializeError(stmt.get_opCode(), this->m_runtime.nextStatementIndex - 1,
|
||||
this->log_WARNING_HI_DirectiveDeserializeError(stmt.get_opCode(), this->currentStatementIdx(),
|
||||
Fw::SerializeStatus::FW_DESERIALIZE_FORMAT_ERROR,
|
||||
argBuf.getBuffLeft(), argBuf.getBuffLength());
|
||||
return Fw::Success::FAILURE;
|
||||
}
|
||||
|
||||
// okay, it will fit. put it in
|
||||
status = argBuf.deserialize(deserializedDirective.constCmd.get_argBuf(), cmdArgBufSize, Fw::Serialization::OMIT_LENGTH);
|
||||
status = argBuf.deserialize(deserializedDirective.constCmd.get_argBuf(), cmdArgBufSize,
|
||||
Fw::Serialization::OMIT_LENGTH);
|
||||
|
||||
if (status != Fw::SerializeStatus::FW_SERIALIZE_OK) {
|
||||
this->log_WARNING_HI_DirectiveDeserializeError(stmt.get_opCode(), this->m_runtime.nextStatementIndex - 1,
|
||||
status, argBuf.getBuffLeft(), argBuf.getBuffLength());
|
||||
this->log_WARNING_HI_DirectiveDeserializeError(stmt.get_opCode(), this->currentStatementIdx(), status,
|
||||
argBuf.getBuffLeft(), argBuf.getBuffLength());
|
||||
return Fw::Success::FAILURE;
|
||||
}
|
||||
|
||||
@ -174,11 +185,11 @@ Fw::Success FpySequencer::deserializeDirective(const Fpy::Statement& stmt, Direc
|
||||
case Fpy::DirectiveId::UGT:
|
||||
case Fpy::DirectiveId::ULT:
|
||||
case Fpy::DirectiveId::ULE:
|
||||
case Fpy::DirectiveId::UGE:
|
||||
case Fpy::DirectiveId::UGE:
|
||||
case Fpy::DirectiveId::SGT:
|
||||
case Fpy::DirectiveId::SLT:
|
||||
case Fpy::DirectiveId::SLE:
|
||||
case Fpy::DirectiveId::SGE:
|
||||
case Fpy::DirectiveId::SGE:
|
||||
case Fpy::DirectiveId::FEQ:
|
||||
case Fpy::DirectiveId::FNE:
|
||||
case Fpy::DirectiveId::FLT:
|
||||
@ -191,10 +202,34 @@ Fw::Success FpySequencer::deserializeDirective(const Fpy::Statement& stmt, Direc
|
||||
case Fpy::DirectiveId::FPTOSI:
|
||||
case Fpy::DirectiveId::FPTOUI:
|
||||
case Fpy::DirectiveId::SITOFP:
|
||||
case Fpy::DirectiveId::UITOFP: {
|
||||
case Fpy::DirectiveId::UITOFP:
|
||||
case Fpy::DirectiveId::IADD:
|
||||
case Fpy::DirectiveId::ISUB:
|
||||
case Fpy::DirectiveId::IMUL:
|
||||
case Fpy::DirectiveId::UDIV:
|
||||
case Fpy::DirectiveId::SDIV:
|
||||
case Fpy::DirectiveId::UMOD:
|
||||
case Fpy::DirectiveId::SMOD:
|
||||
case Fpy::DirectiveId::FADD:
|
||||
case Fpy::DirectiveId::FSUB:
|
||||
case Fpy::DirectiveId::FMUL:
|
||||
case Fpy::DirectiveId::FDIV:
|
||||
case Fpy::DirectiveId::FLOAT_FLOOR_DIV:
|
||||
case Fpy::DirectiveId::FPOW:
|
||||
case Fpy::DirectiveId::FLOG:
|
||||
case Fpy::DirectiveId::FMOD:
|
||||
case Fpy::DirectiveId::SIEXT_8_64:
|
||||
case Fpy::DirectiveId::SIEXT_16_64:
|
||||
case Fpy::DirectiveId::SIEXT_32_64:
|
||||
case Fpy::DirectiveId::ZIEXT_8_64:
|
||||
case Fpy::DirectiveId::ZIEXT_16_64:
|
||||
case Fpy::DirectiveId::ZIEXT_32_64:
|
||||
case Fpy::DirectiveId::ITRUNC_64_8:
|
||||
case Fpy::DirectiveId::ITRUNC_64_16:
|
||||
case Fpy::DirectiveId::ITRUNC_64_32: {
|
||||
new (&deserializedDirective.stackOp) FpySequencer_StackOpDirective();
|
||||
if (argBuf.getBuffLeft() != 0) {
|
||||
this->log_WARNING_HI_DirectiveDeserializeError(stmt.get_opCode(), this->m_runtime.nextStatementIndex - 1,
|
||||
this->log_WARNING_HI_DirectiveDeserializeError(stmt.get_opCode(), this->currentStatementIdx(),
|
||||
Fw::SerializeStatus::FW_DESERIALIZE_SIZE_MISMATCH,
|
||||
argBuf.getBuffLeft(), argBuf.getBuffLength());
|
||||
return Fw::Success::FAILURE;
|
||||
@ -205,7 +240,7 @@ Fw::Success FpySequencer::deserializeDirective(const Fpy::Statement& stmt, Direc
|
||||
case Fpy::DirectiveId::EXIT: {
|
||||
new (&deserializedDirective.exit) FpySequencer_ExitDirective();
|
||||
if (argBuf.getBuffLeft() != 0) {
|
||||
this->log_WARNING_HI_DirectiveDeserializeError(stmt.get_opCode(), this->m_runtime.nextStatementIndex - 1,
|
||||
this->log_WARNING_HI_DirectiveDeserializeError(stmt.get_opCode(), this->currentStatementIdx(),
|
||||
Fw::SerializeStatus::FW_DESERIALIZE_SIZE_MISMATCH,
|
||||
argBuf.getBuffLeft(), argBuf.getBuffLength());
|
||||
return Fw::Success::FAILURE;
|
||||
@ -216,8 +251,8 @@ Fw::Success FpySequencer::deserializeDirective(const Fpy::Statement& stmt, Direc
|
||||
new (&deserializedDirective.allocate) FpySequencer_AllocateDirective();
|
||||
status = argBuf.deserialize(deserializedDirective.allocate);
|
||||
if (status != Fw::SerializeStatus::FW_SERIALIZE_OK || argBuf.getBuffLeft() != 0) {
|
||||
this->log_WARNING_HI_DirectiveDeserializeError(stmt.get_opCode(), this->m_runtime.nextStatementIndex - 1,
|
||||
status, argBuf.getBuffLeft(), argBuf.getBuffLength());
|
||||
this->log_WARNING_HI_DirectiveDeserializeError(stmt.get_opCode(), this->currentStatementIdx(), status,
|
||||
argBuf.getBuffLeft(), argBuf.getBuffLength());
|
||||
return Fw::Success::FAILURE;
|
||||
}
|
||||
break;
|
||||
@ -226,8 +261,8 @@ Fw::Success FpySequencer::deserializeDirective(const Fpy::Statement& stmt, Direc
|
||||
new (&deserializedDirective.store) FpySequencer_StoreDirective();
|
||||
status = argBuf.deserialize(deserializedDirective.store);
|
||||
if (status != Fw::SerializeStatus::FW_SERIALIZE_OK || argBuf.getBuffLeft() != 0) {
|
||||
this->log_WARNING_HI_DirectiveDeserializeError(stmt.get_opCode(), this->m_runtime.nextStatementIndex - 1,
|
||||
status, argBuf.getBuffLeft(), argBuf.getBuffLength());
|
||||
this->log_WARNING_HI_DirectiveDeserializeError(stmt.get_opCode(), this->currentStatementIdx(), status,
|
||||
argBuf.getBuffLeft(), argBuf.getBuffLength());
|
||||
return Fw::Success::FAILURE;
|
||||
}
|
||||
break;
|
||||
@ -236,8 +271,8 @@ Fw::Success FpySequencer::deserializeDirective(const Fpy::Statement& stmt, Direc
|
||||
new (&deserializedDirective.load) FpySequencer_LoadDirective();
|
||||
status = argBuf.deserialize(deserializedDirective.load);
|
||||
if (status != Fw::SerializeStatus::FW_SERIALIZE_OK || argBuf.getBuffLeft() != 0) {
|
||||
this->log_WARNING_HI_DirectiveDeserializeError(stmt.get_opCode(), this->m_runtime.nextStatementIndex - 1,
|
||||
status, argBuf.getBuffLeft(), argBuf.getBuffLength());
|
||||
this->log_WARNING_HI_DirectiveDeserializeError(stmt.get_opCode(), this->currentStatementIdx(), status,
|
||||
argBuf.getBuffLeft(), argBuf.getBuffLength());
|
||||
return Fw::Success::FAILURE;
|
||||
}
|
||||
break;
|
||||
@ -250,18 +285,19 @@ Fw::Success FpySequencer::deserializeDirective(const Fpy::Statement& stmt, Direc
|
||||
|
||||
// check to make sure the value will fit in the FpySequencer_PushValDirective::val buf
|
||||
if (bufSize > Fpy::MAX_DIRECTIVE_SIZE) {
|
||||
this->log_WARNING_HI_DirectiveDeserializeError(stmt.get_opCode(), this->m_runtime.nextStatementIndex - 1,
|
||||
this->log_WARNING_HI_DirectiveDeserializeError(stmt.get_opCode(), this->currentStatementIdx(),
|
||||
Fw::SerializeStatus::FW_DESERIALIZE_FORMAT_ERROR,
|
||||
argBuf.getBuffLeft(), argBuf.getBuffLength());
|
||||
return Fw::Success::FAILURE;
|
||||
}
|
||||
|
||||
// okay, it will fit. put it in
|
||||
status = argBuf.deserialize(deserializedDirective.pushVal.get_val(), bufSize, Fw::Serialization::OMIT_LENGTH);
|
||||
status =
|
||||
argBuf.deserialize(deserializedDirective.pushVal.get_val(), bufSize, Fw::Serialization::OMIT_LENGTH);
|
||||
|
||||
if (status != Fw::SerializeStatus::FW_SERIALIZE_OK) {
|
||||
this->log_WARNING_HI_DirectiveDeserializeError(stmt.get_opCode(), this->m_runtime.nextStatementIndex - 1,
|
||||
status, argBuf.getBuffLeft(), argBuf.getBuffLength());
|
||||
this->log_WARNING_HI_DirectiveDeserializeError(stmt.get_opCode(), this->currentStatementIdx(), status,
|
||||
argBuf.getBuffLeft(), argBuf.getBuffLength());
|
||||
return Fw::Success::FAILURE;
|
||||
}
|
||||
|
||||
@ -272,9 +308,39 @@ Fw::Success FpySequencer::deserializeDirective(const Fpy::Statement& stmt, Direc
|
||||
deserializedDirective.pushVal.set__valSize(bufSize);
|
||||
break;
|
||||
}
|
||||
case Fpy::DirectiveId::DISCARD: {
|
||||
new (&deserializedDirective.discard) FpySequencer_DiscardDirective();
|
||||
status = argBuf.deserialize(deserializedDirective.discard);
|
||||
if (status != Fw::SerializeStatus::FW_SERIALIZE_OK || argBuf.getBuffLeft() != 0) {
|
||||
this->log_WARNING_HI_DirectiveDeserializeError(stmt.get_opCode(), this->currentStatementIdx(), status,
|
||||
argBuf.getBuffLeft(), argBuf.getBuffLength());
|
||||
return Fw::Success::FAILURE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Fpy::DirectiveId::MEMCMP: {
|
||||
new (&deserializedDirective.memCmp) FpySequencer_MemCmpDirective();
|
||||
status = argBuf.deserialize(deserializedDirective.memCmp);
|
||||
if (status != Fw::SerializeStatus::FW_SERIALIZE_OK || argBuf.getBuffLeft() != 0) {
|
||||
this->log_WARNING_HI_DirectiveDeserializeError(stmt.get_opCode(), this->currentStatementIdx(), status,
|
||||
argBuf.getBuffLeft(), argBuf.getBuffLength());
|
||||
return Fw::Success::FAILURE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Fpy::DirectiveId::STACK_CMD: {
|
||||
new (&deserializedDirective.stackCmd) FpySequencer_StackCmdDirective();
|
||||
status = argBuf.deserialize(deserializedDirective.stackCmd);
|
||||
if (status != Fw::SerializeStatus::FW_SERIALIZE_OK || argBuf.getBuffLeft() != 0) {
|
||||
this->log_WARNING_HI_DirectiveDeserializeError(stmt.get_opCode(), this->currentStatementIdx(), status,
|
||||
argBuf.getBuffLeft(), argBuf.getBuffLength());
|
||||
return Fw::Success::FAILURE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
// unsure what this opcode is. check compiler version matches sequencer
|
||||
this->log_WARNING_HI_UnknownSequencerDirective(stmt.get_opCode(), this->m_runtime.nextStatementIndex - 1,
|
||||
this->log_WARNING_HI_UnknownSequencerDirective(stmt.get_opCode(), this->currentStatementIdx(),
|
||||
this->m_sequenceFilePath);
|
||||
return Fw::Success::FAILURE;
|
||||
}
|
||||
@ -330,7 +396,7 @@ void FpySequencer::dispatchDirective(const DirectiveUnion& directive, const Fpy:
|
||||
case Fpy::DirectiveId::UGT:
|
||||
case Fpy::DirectiveId::ULT:
|
||||
case Fpy::DirectiveId::ULE:
|
||||
case Fpy::DirectiveId::UGE:
|
||||
case Fpy::DirectiveId::UGE:
|
||||
case Fpy::DirectiveId::SGT:
|
||||
case Fpy::DirectiveId::SLT:
|
||||
case Fpy::DirectiveId::SLE:
|
||||
@ -347,7 +413,31 @@ void FpySequencer::dispatchDirective(const DirectiveUnion& directive, const Fpy:
|
||||
case Fpy::DirectiveId::FPTOSI:
|
||||
case Fpy::DirectiveId::FPTOUI:
|
||||
case Fpy::DirectiveId::SITOFP:
|
||||
case Fpy::DirectiveId::UITOFP: {
|
||||
case Fpy::DirectiveId::UITOFP:
|
||||
case Fpy::DirectiveId::IADD:
|
||||
case Fpy::DirectiveId::ISUB:
|
||||
case Fpy::DirectiveId::IMUL:
|
||||
case Fpy::DirectiveId::UDIV:
|
||||
case Fpy::DirectiveId::SDIV:
|
||||
case Fpy::DirectiveId::UMOD:
|
||||
case Fpy::DirectiveId::SMOD:
|
||||
case Fpy::DirectiveId::FADD:
|
||||
case Fpy::DirectiveId::FSUB:
|
||||
case Fpy::DirectiveId::FMUL:
|
||||
case Fpy::DirectiveId::FDIV:
|
||||
case Fpy::DirectiveId::FLOAT_FLOOR_DIV:
|
||||
case Fpy::DirectiveId::FPOW:
|
||||
case Fpy::DirectiveId::FLOG:
|
||||
case Fpy::DirectiveId::FMOD:
|
||||
case Fpy::DirectiveId::SIEXT_8_64:
|
||||
case Fpy::DirectiveId::SIEXT_16_64:
|
||||
case Fpy::DirectiveId::SIEXT_32_64:
|
||||
case Fpy::DirectiveId::ZIEXT_8_64:
|
||||
case Fpy::DirectiveId::ZIEXT_16_64:
|
||||
case Fpy::DirectiveId::ZIEXT_32_64:
|
||||
case Fpy::DirectiveId::ITRUNC_64_8:
|
||||
case Fpy::DirectiveId::ITRUNC_64_16:
|
||||
case Fpy::DirectiveId::ITRUNC_64_32: {
|
||||
this->directive_stackOp_internalInterfaceInvoke(directive.stackOp);
|
||||
return;
|
||||
}
|
||||
@ -371,6 +461,18 @@ void FpySequencer::dispatchDirective(const DirectiveUnion& directive, const Fpy:
|
||||
this->directive_pushVal_internalInterfaceInvoke(directive.pushVal);
|
||||
return;
|
||||
}
|
||||
case Fpy::DirectiveId::DISCARD: {
|
||||
this->directive_discard_internalInterfaceInvoke(directive.discard);
|
||||
return;
|
||||
}
|
||||
case Fpy::DirectiveId::MEMCMP: {
|
||||
this->directive_memCmp_internalInterfaceInvoke(directive.memCmp);
|
||||
return;
|
||||
}
|
||||
case Fpy::DirectiveId::STACK_CMD: {
|
||||
this->directive_stackCmd_internalInterfaceInvoke(directive.stackCmd);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// coding err
|
||||
FW_ASSERT(0, static_cast<FwAssertArgType>(id));
|
||||
@ -441,13 +543,14 @@ Signal FpySequencer::checkStatementTimeout() {
|
||||
}
|
||||
|
||||
// we timed out
|
||||
if (this->m_runtime.currentStatementOpcode == Fpy::DirectiveId::CONST_CMD) {
|
||||
if (this->m_runtime.currentStatementOpcode == Fpy::DirectiveId::CONST_CMD ||
|
||||
this->m_runtime.currentStatementOpcode == Fpy::DirectiveId::STACK_CMD) {
|
||||
// if we were executing a command, warn that the cmd timed out with its opcode
|
||||
this->log_WARNING_HI_CommandTimedOut(this->m_runtime.currentCmdOpcode,
|
||||
this->m_runtime.nextStatementIndex - 1, this->m_sequenceFilePath);
|
||||
this->log_WARNING_HI_CommandTimedOut(this->m_runtime.currentCmdOpcode, this->currentStatementIdx(),
|
||||
this->m_sequenceFilePath);
|
||||
} else {
|
||||
this->log_WARNING_HI_DirectiveTimedOut(this->m_runtime.currentStatementOpcode,
|
||||
this->m_runtime.nextStatementIndex - 1, this->m_sequenceFilePath);
|
||||
this->log_WARNING_HI_DirectiveTimedOut(this->m_runtime.currentStatementOpcode, this->currentStatementIdx(),
|
||||
this->m_sequenceFilePath);
|
||||
}
|
||||
|
||||
return Signal::result_checkStatementTimeout_statementTimeout;
|
||||
|
||||
@ -305,8 +305,8 @@ void FpySequencer::Svc_FpySequencer_SequencerStateMachine_action_setDebugBreakpo
|
||||
//!
|
||||
//! called when a sequence failed to execute successfully
|
||||
void FpySequencer::Svc_FpySequencer_SequencerStateMachine_action_report_seqFailed(
|
||||
SmId smId, //!< The state machine id
|
||||
Svc_FpySequencer_SequencerStateMachine::Signal signal //!< The signal
|
||||
SmId smId, //!< The state machine id
|
||||
Svc_FpySequencer_SequencerStateMachine::Signal signal //!< The signal
|
||||
) {
|
||||
if (this->isConnected_seqDoneOut_OutputPort(0)) {
|
||||
// report that the sequence failed to internal callers
|
||||
@ -318,8 +318,8 @@ void FpySequencer::Svc_FpySequencer_SequencerStateMachine_action_report_seqFaile
|
||||
//!
|
||||
//! reports that a sequence was started
|
||||
void FpySequencer::Svc_FpySequencer_SequencerStateMachine_action_report_seqStarted(
|
||||
SmId smId, //!< The state machine id
|
||||
Svc_FpySequencer_SequencerStateMachine::Signal signal //!< The signal
|
||||
SmId smId, //!< The state machine id
|
||||
Svc_FpySequencer_SequencerStateMachine::Signal signal //!< The signal
|
||||
) {
|
||||
if (this->isConnected_seqDoneOut_OutputPort(0)) {
|
||||
// report that the sequence started to internal callers
|
||||
|
||||
@ -16,46 +16,79 @@ module Svc {
|
||||
# stack op directives
|
||||
# all of these are handled at the CPP level by one StackOpDirective
|
||||
# boolean ops
|
||||
OR = 15
|
||||
AND = 16
|
||||
OR = 10
|
||||
AND = 11
|
||||
# integer equalities
|
||||
IEQ = 17
|
||||
INE = 18
|
||||
IEQ = 12
|
||||
INE = 13
|
||||
# unsigned integer inequalities
|
||||
ULT = 19
|
||||
ULE = 20
|
||||
UGT = 21
|
||||
UGE = 22
|
||||
ULT = 14
|
||||
ULE = 15
|
||||
UGT = 16
|
||||
UGE = 17
|
||||
# signed integer inequalities
|
||||
SLT = 23
|
||||
SLE = 24
|
||||
SGT = 25
|
||||
SGE = 26
|
||||
SLT = 18
|
||||
SLE = 19
|
||||
SGT = 20
|
||||
SGE = 21
|
||||
# floating point equalities
|
||||
FEQ = 27
|
||||
FNE = 28
|
||||
FEQ = 22
|
||||
FNE = 23
|
||||
# floating point inequalities
|
||||
FLT = 29
|
||||
FLE = 30
|
||||
FGT = 31
|
||||
FGE = 32
|
||||
NOT = 33
|
||||
# floating point extension and truncation
|
||||
FPEXT = 34
|
||||
FPTRUNC = 35
|
||||
FLT = 24
|
||||
FLE = 25
|
||||
FGT = 26
|
||||
FGE = 27
|
||||
NOT = 28
|
||||
# floating point conversion to signed/unsigned integer,
|
||||
# and vice versa
|
||||
FPTOSI = 36
|
||||
FPTOUI = 37
|
||||
SITOFP = 38
|
||||
UITOFP = 39
|
||||
FPTOSI = 29
|
||||
FPTOUI = 30
|
||||
SITOFP = 31
|
||||
UITOFP = 32
|
||||
# integer arithmetic
|
||||
IADD = 33
|
||||
ISUB = 34
|
||||
IMUL = 35
|
||||
UDIV = 36
|
||||
SDIV = 37
|
||||
UMOD = 38
|
||||
SMOD = 39
|
||||
# float arithmetic
|
||||
FADD = 40
|
||||
FSUB = 41
|
||||
FMUL = 42
|
||||
FDIV = 43
|
||||
FLOAT_FLOOR_DIV = 44
|
||||
FPOW = 45
|
||||
FLOG = 46
|
||||
FMOD = 47
|
||||
# floating point bitwidth conversions
|
||||
FPEXT = 48
|
||||
FPTRUNC = 49
|
||||
# integer bitwidth conversions
|
||||
# signed integer extend
|
||||
SIEXT_8_64 = 50
|
||||
SIEXT_16_64 = 51
|
||||
SIEXT_32_64 = 52
|
||||
# zero (unsigned) integer extend
|
||||
ZIEXT_8_64 = 53
|
||||
ZIEXT_16_64 = 54
|
||||
ZIEXT_32_64 = 55
|
||||
# integer truncate
|
||||
ITRUNC_64_8 = 56
|
||||
ITRUNC_64_16 = 57
|
||||
ITRUNC_64_32 = 58
|
||||
# end stack op dirs
|
||||
|
||||
EXIT = 40
|
||||
ALLOCATE = 41
|
||||
STORE = 42
|
||||
LOAD = 43
|
||||
PUSH_VAL = 44
|
||||
EXIT = 59
|
||||
ALLOCATE = 60
|
||||
STORE = 61
|
||||
LOAD = 62
|
||||
PUSH_VAL = 63
|
||||
DISCARD = 64
|
||||
MEMCMP = 65
|
||||
STACK_CMD = 66
|
||||
}
|
||||
|
||||
struct Header {
|
||||
|
||||
@ -203,7 +203,8 @@ TEST_F(FpySequencerTester, cmd) {
|
||||
Fw::ComBuffer expected;
|
||||
ASSERT_EQ(expected.serialize(Fw::ComPacketType::FW_PACKET_COMMAND), Fw::SerializeStatus::FW_SERIALIZE_OK);
|
||||
ASSERT_EQ(expected.serialize(directive.get_opCode()), Fw::SerializeStatus::FW_SERIALIZE_OK);
|
||||
ASSERT_EQ(expected.serialize(data, sizeof(data), Fw::Serialization::OMIT_LENGTH), Fw::SerializeStatus::FW_SERIALIZE_OK);
|
||||
ASSERT_EQ(expected.serialize(data, sizeof(data), Fw::Serialization::OMIT_LENGTH),
|
||||
Fw::SerializeStatus::FW_SERIALIZE_OK);
|
||||
ASSERT_from_cmdOut_SIZE(1);
|
||||
ASSERT_from_cmdOut(0, expected, 0);
|
||||
this->clearHistory();
|
||||
@ -268,7 +269,7 @@ TEST_F(FpySequencerTester, stackOp) {
|
||||
result = tester_stackOp_directiveHandler(directiveAND, err);
|
||||
ASSERT_EQ(result, Signal::stmtResponse_success);
|
||||
ASSERT_EQ(err, DirectiveError::NO_ERROR);
|
||||
ASSERT_EQ(tester_get_m_runtime_ptr()->stack[0], 8); // 0b1111
|
||||
ASSERT_EQ(tester_get_m_runtime_ptr()->stack[0], 8); // 0b1111
|
||||
ASSERT_EQ(tester_get_m_runtime_ptr()->stackSize, 1); // 0b1111
|
||||
tester_get_m_runtime_ptr()->stackSize = 0;
|
||||
|
||||
@ -710,7 +711,6 @@ TEST_F(FpySequencerTester, fne) {
|
||||
ASSERT_EQ(tester_get_m_runtime_ptr()->stack[0], 0);
|
||||
}
|
||||
|
||||
|
||||
TEST_F(FpySequencerTester, not) {
|
||||
tester_push<U8>(true);
|
||||
ASSERT_EQ(tester_op_not(), DirectiveError::NO_ERROR);
|
||||
@ -771,6 +771,108 @@ TEST_F(FpySequencerTester, uitofp) {
|
||||
ASSERT_EQ(expected, tester_pop<F64>());
|
||||
}
|
||||
|
||||
TEST_F(FpySequencerTester, iadd) {
|
||||
tester_push<I64>(100);
|
||||
tester_push<I64>(23);
|
||||
ASSERT_EQ(tester_op_iadd(), DirectiveError::NO_ERROR);
|
||||
ASSERT_EQ(tester_pop<I64>(), 123);
|
||||
}
|
||||
|
||||
TEST_F(FpySequencerTester, isub) {
|
||||
tester_push<I64>(150);
|
||||
tester_push<I64>(27);
|
||||
ASSERT_EQ(tester_op_isub(), DirectiveError::NO_ERROR);
|
||||
ASSERT_EQ(tester_pop<I64>(), 123);
|
||||
}
|
||||
|
||||
TEST_F(FpySequencerTester, imul) {
|
||||
tester_push<I64>(41);
|
||||
tester_push<I64>(3);
|
||||
ASSERT_EQ(tester_op_imul(), DirectiveError::NO_ERROR);
|
||||
ASSERT_EQ(tester_pop<I64>(), 123);
|
||||
}
|
||||
|
||||
TEST_F(FpySequencerTester, udiv) {
|
||||
tester_push<U64>(246);
|
||||
tester_push<U64>(2);
|
||||
ASSERT_EQ(tester_op_udiv(), DirectiveError::NO_ERROR);
|
||||
ASSERT_EQ(tester_pop<U64>(), 123);
|
||||
}
|
||||
|
||||
TEST_F(FpySequencerTester, sdiv) {
|
||||
tester_push<I64>(-246);
|
||||
tester_push<I64>(-2);
|
||||
ASSERT_EQ(tester_op_sdiv(), DirectiveError::NO_ERROR);
|
||||
ASSERT_EQ(tester_pop<I64>(), 123);
|
||||
}
|
||||
|
||||
TEST_F(FpySequencerTester, umod) {
|
||||
tester_push<U64>(123);
|
||||
tester_push<U64>(10);
|
||||
ASSERT_EQ(tester_op_umod(), DirectiveError::NO_ERROR);
|
||||
ASSERT_EQ(tester_pop<U64>(), 3);
|
||||
}
|
||||
|
||||
TEST_F(FpySequencerTester, smod) {
|
||||
tester_push<I64>(-7);
|
||||
tester_push<I64>(-3);
|
||||
ASSERT_EQ(tester_op_smod(), DirectiveError::NO_ERROR);
|
||||
ASSERT_EQ(tester_pop<I64>(), -1);
|
||||
}
|
||||
|
||||
TEST_F(FpySequencerTester, fadd) {
|
||||
tester_push<F64>(100.5);
|
||||
tester_push<F64>(22.5);
|
||||
ASSERT_EQ(tester_op_fadd(), DirectiveError::NO_ERROR);
|
||||
ASSERT_EQ(tester_pop<F64>(), 123.0);
|
||||
}
|
||||
|
||||
TEST_F(FpySequencerTester, fsub) {
|
||||
tester_push<F64>(150.5);
|
||||
tester_push<F64>(27.5);
|
||||
ASSERT_EQ(tester_op_fsub(), DirectiveError::NO_ERROR);
|
||||
ASSERT_EQ(tester_pop<F64>(), 123.0);
|
||||
}
|
||||
|
||||
TEST_F(FpySequencerTester, fmul) {
|
||||
tester_push<F64>(41.0);
|
||||
tester_push<F64>(3.0);
|
||||
ASSERT_EQ(tester_op_fmul(), DirectiveError::NO_ERROR);
|
||||
ASSERT_EQ(tester_pop<F64>(), 123.0);
|
||||
}
|
||||
|
||||
TEST_F(FpySequencerTester, fdiv) {
|
||||
tester_push<F64>(246.0);
|
||||
tester_push<F64>(2.0);
|
||||
ASSERT_EQ(tester_op_fdiv(), DirectiveError::NO_ERROR);
|
||||
ASSERT_EQ(tester_pop<F64>(), 123.0);
|
||||
}
|
||||
|
||||
TEST_F(FpySequencerTester, float_floor_div) {
|
||||
tester_push<F64>(246.8);
|
||||
tester_push<F64>(2.0);
|
||||
ASSERT_EQ(tester_op_float_floor_div(), DirectiveError::NO_ERROR);
|
||||
ASSERT_EQ(tester_pop<F64>(), 123.0);
|
||||
}
|
||||
|
||||
TEST_F(FpySequencerTester, fpow) {
|
||||
tester_push<F64>(3.0);
|
||||
tester_push<F64>(2.0);
|
||||
ASSERT_EQ(tester_op_fpow(), DirectiveError::NO_ERROR);
|
||||
ASSERT_EQ(tester_pop<F64>(), 9.0);
|
||||
}
|
||||
|
||||
TEST_F(FpySequencerTester, flog) {
|
||||
tester_push<F64>(2.718281828459045); // e
|
||||
ASSERT_EQ(tester_op_flog(), DirectiveError::NO_ERROR);
|
||||
ASSERT_EQ(tester_pop<F64>(), 1.0);
|
||||
}
|
||||
TEST_F(FpySequencerTester, fmod) {
|
||||
tester_push<F64>(-8.5);
|
||||
tester_push<F64>(-2.5);
|
||||
ASSERT_EQ(tester_op_fmod(), DirectiveError::NO_ERROR);
|
||||
ASSERT_EQ(tester_pop<F64>(), -1.0);
|
||||
}
|
||||
TEST_F(FpySequencerTester, exit) {
|
||||
FpySequencer_ExitDirective directive;
|
||||
DirectiveError err = DirectiveError::NO_ERROR;
|
||||
@ -787,6 +889,73 @@ TEST_F(FpySequencerTester, exit) {
|
||||
ASSERT_EQ(err, DirectiveError::DELIBERATE_FAILURE);
|
||||
}
|
||||
|
||||
TEST_F(FpySequencerTester, discard) {
|
||||
// Test discarding 4 bytes
|
||||
tester_push<U32>(0x12345678);
|
||||
FpySequencer_DiscardDirective directive(4);
|
||||
DirectiveError err = DirectiveError::NO_ERROR;
|
||||
Signal result = tester_discard_directiveHandler(directive, err);
|
||||
ASSERT_EQ(result, Signal::stmtResponse_success);
|
||||
ASSERT_EQ(err, DirectiveError::NO_ERROR);
|
||||
ASSERT_EQ(tester_get_m_runtime_ptr()->stackSize, 0);
|
||||
|
||||
// Test error case - try to discard more bytes than available
|
||||
tester_push<U8>(0x12);
|
||||
directive.set_size(2);
|
||||
result = tester_discard_directiveHandler(directive, err);
|
||||
ASSERT_EQ(result, Signal::stmtResponse_failure);
|
||||
ASSERT_EQ(err, DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS);
|
||||
}
|
||||
|
||||
TEST_F(FpySequencerTester, stackCmd) {
|
||||
// Test valid command
|
||||
tester_push<U32>(0x12345678); // Args
|
||||
tester_push<FwOpcodeType>(123); // Opcode
|
||||
|
||||
FpySequencer_StackCmdDirective directive(4); // 4 bytes of args
|
||||
DirectiveError err = DirectiveError::NO_ERROR;
|
||||
Signal result = tester_stackCmd_directiveHandler(directive, err);
|
||||
ASSERT_EQ(result, Signal::stmtResponse_keepWaiting);
|
||||
ASSERT_EQ(err, DirectiveError::NO_ERROR);
|
||||
ASSERT_from_cmdOut_SIZE(1);
|
||||
ASSERT_EQ(tester_get_m_runtime_ptr()->stackSize, 0);
|
||||
|
||||
// Test error case - not enough bytes on stack
|
||||
tester_push<U8>(0x12);
|
||||
result = tester_stackCmd_directiveHandler(directive, err);
|
||||
ASSERT_EQ(result, Signal::stmtResponse_failure);
|
||||
ASSERT_EQ(err, DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS);
|
||||
}
|
||||
|
||||
TEST_F(FpySequencerTester, memCmp) {
|
||||
// Test equal memory blocks
|
||||
tester_push<U32>(0x12345678);
|
||||
tester_push<U32>(0x12345678);
|
||||
|
||||
FpySequencer_MemCmpDirective directive(4);
|
||||
DirectiveError err = DirectiveError::NO_ERROR;
|
||||
Signal result = tester_memCmp_directiveHandler(directive, err);
|
||||
ASSERT_EQ(result, Signal::stmtResponse_success);
|
||||
ASSERT_EQ(err, DirectiveError::NO_ERROR);
|
||||
ASSERT_EQ(tester_pop<U8>(), 1); // Should be true
|
||||
|
||||
// Test unequal memory blocks
|
||||
tester_push<U32>(0x12345678);
|
||||
tester_push<U32>(0x87654321);
|
||||
result = tester_memCmp_directiveHandler(directive, err);
|
||||
ASSERT_EQ(result, Signal::stmtResponse_success);
|
||||
ASSERT_EQ(err, DirectiveError::NO_ERROR);
|
||||
ASSERT_EQ(tester_pop<U8>(), 0); // Should be false
|
||||
|
||||
// test not enough bytes on stack
|
||||
tester_push<U32>(0x12345678);
|
||||
tester_push<U8>(0x11);
|
||||
directive.set_size(3);
|
||||
result = tester_memCmp_directiveHandler(directive, err);
|
||||
ASSERT_EQ(result, Signal::stmtResponse_failure);
|
||||
ASSERT_EQ(err, DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS);
|
||||
}
|
||||
|
||||
TEST_F(FpySequencerTester, checkShouldWakeMismatchBase) {
|
||||
Fw::Time testTime(TimeBase::TB_WORKSTATION_TIME, 0, 100, 100);
|
||||
setTestTime(testTime);
|
||||
@ -1226,28 +1395,32 @@ TEST_F(FpySequencerTester, readBytes) {
|
||||
tester_get_m_sequenceBuffer_ptr()->setExtBuffer(data, sizeof(data));
|
||||
Os::File seqFile;
|
||||
ASSERT_EQ(seqFile.open("test.bin", Os::File::OPEN_READ), Os::File::OP_OK);
|
||||
ASSERT_EQ(tester_readBytes(seqFile, Fpy::Header::SERIALIZED_SIZE, FpySequencer_FileReadStage::HEADER, true), Fw::Success::SUCCESS);
|
||||
ASSERT_EQ(tester_readBytes(seqFile, Fpy::Header::SERIALIZED_SIZE, FpySequencer_FileReadStage::HEADER, true),
|
||||
Fw::Success::SUCCESS);
|
||||
seqFile.close();
|
||||
|
||||
// check capacity too low
|
||||
tester_get_m_sequenceBuffer_ptr()->setExtBuffer(data, Fpy::Header::SERIALIZED_SIZE - 1);
|
||||
ASSERT_EQ(seqFile.open("test.bin", Os::File::OPEN_READ), Os::File::OP_OK);
|
||||
ASSERT_EQ(tester_readBytes(seqFile, Fpy::Header::SERIALIZED_SIZE, FpySequencer_FileReadStage::HEADER, true), Fw::Success::FAILURE);
|
||||
ASSERT_EQ(tester_readBytes(seqFile, Fpy::Header::SERIALIZED_SIZE, FpySequencer_FileReadStage::HEADER, true),
|
||||
Fw::Success::FAILURE);
|
||||
seqFile.close();
|
||||
|
||||
// check not enough bytes
|
||||
tester_get_m_sequenceBuffer_ptr()->setExtBuffer(data,
|
||||
Fpy::Header::SERIALIZED_SIZE + Fpy::Footer::SERIALIZED_SIZE + 1);
|
||||
ASSERT_EQ(seqFile.open("test.bin", Os::File::OPEN_READ), Os::File::OP_OK);
|
||||
ASSERT_EQ(tester_readBytes(seqFile, Fpy::Header::SERIALIZED_SIZE + Fpy::Footer::SERIALIZED_SIZE + 1, FpySequencer_FileReadStage::HEADER, true),
|
||||
ASSERT_EQ(tester_readBytes(seqFile, Fpy::Header::SERIALIZED_SIZE + Fpy::Footer::SERIALIZED_SIZE + 1,
|
||||
FpySequencer_FileReadStage::HEADER, true),
|
||||
Fw::Success::FAILURE);
|
||||
|
||||
seqFile.close();
|
||||
removeFile("test.bin");
|
||||
|
||||
// read after close
|
||||
ASSERT_DEATH_IF_SUPPORTED(
|
||||
tester_readBytes(seqFile, Fpy::Header::SERIALIZED_SIZE + Fpy::Footer::SERIALIZED_SIZE, FpySequencer_FileReadStage::HEADER, true), "Assert: ");
|
||||
ASSERT_DEATH_IF_SUPPORTED(tester_readBytes(seqFile, Fpy::Header::SERIALIZED_SIZE + Fpy::Footer::SERIALIZED_SIZE,
|
||||
FpySequencer_FileReadStage::HEADER, true),
|
||||
"Assert: ");
|
||||
}
|
||||
|
||||
TEST_F(FpySequencerTester, validate) {
|
||||
@ -1543,6 +1716,65 @@ TEST_F(FpySequencerTester, deserialize_exit) {
|
||||
ASSERT_EVENTS_DirectiveDeserializeError_SIZE(0);
|
||||
}
|
||||
|
||||
TEST_F(FpySequencerTester, deserialize_discard) {
|
||||
FpySequencer::DirectiveUnion actual;
|
||||
FpySequencer_DiscardDirective dir(123);
|
||||
add_DISCARD(dir);
|
||||
Fw::Success result = tester_deserializeDirective(seq.get_statements()[0], actual);
|
||||
ASSERT_EQ(result, Fw::Success::SUCCESS);
|
||||
ASSERT_EQ(actual.discard, dir);
|
||||
// write some junk after buf, make sure it fails
|
||||
seq.get_statements()[0].get_argBuf().serialize(123);
|
||||
result = tester_deserializeDirective(seq.get_statements()[0], actual);
|
||||
ASSERT_EQ(result, Fw::Success::FAILURE);
|
||||
ASSERT_EVENTS_DirectiveDeserializeError_SIZE(1);
|
||||
this->clearHistory();
|
||||
// clear args, make sure it fails
|
||||
seq.get_statements()[0].get_argBuf().resetSer();
|
||||
result = tester_deserializeDirective(seq.get_statements()[0], actual);
|
||||
ASSERT_EQ(result, Fw::Success::FAILURE);
|
||||
ASSERT_EVENTS_DirectiveDeserializeError_SIZE(1);
|
||||
}
|
||||
|
||||
TEST_F(FpySequencerTester, deserialize_stackCmd) {
|
||||
FpySequencer::DirectiveUnion actual;
|
||||
FpySequencer_StackCmdDirective dir(123);
|
||||
add_STACK_CMD(dir);
|
||||
Fw::Success result = tester_deserializeDirective(seq.get_statements()[0], actual);
|
||||
ASSERT_EQ(result, Fw::Success::SUCCESS);
|
||||
ASSERT_EQ(actual.stackCmd, dir);
|
||||
// write some junk after buf, make sure it fails
|
||||
seq.get_statements()[0].get_argBuf().serialize(123);
|
||||
result = tester_deserializeDirective(seq.get_statements()[0], actual);
|
||||
ASSERT_EQ(result, Fw::Success::FAILURE);
|
||||
ASSERT_EVENTS_DirectiveDeserializeError_SIZE(1);
|
||||
this->clearHistory();
|
||||
// clear args, make sure it fails
|
||||
seq.get_statements()[0].get_argBuf().resetSer();
|
||||
result = tester_deserializeDirective(seq.get_statements()[0], actual);
|
||||
ASSERT_EQ(result, Fw::Success::FAILURE);
|
||||
ASSERT_EVENTS_DirectiveDeserializeError_SIZE(1);
|
||||
}
|
||||
|
||||
TEST_F(FpySequencerTester, deserialize_memCmp) {
|
||||
FpySequencer::DirectiveUnion actual;
|
||||
FpySequencer_MemCmpDirective dir(123);
|
||||
add_MEMCMP(dir);
|
||||
Fw::Success result = tester_deserializeDirective(seq.get_statements()[0], actual);
|
||||
ASSERT_EQ(result, Fw::Success::SUCCESS);
|
||||
ASSERT_EQ(actual.memCmp, dir);
|
||||
// write some junk after buf, make sure it fails
|
||||
seq.get_statements()[0].get_argBuf().serialize(123);
|
||||
result = tester_deserializeDirective(seq.get_statements()[0], actual);
|
||||
ASSERT_EQ(result, Fw::Success::FAILURE);
|
||||
ASSERT_EVENTS_DirectiveDeserializeError_SIZE(1);
|
||||
this->clearHistory();
|
||||
// clear args, make sure it fails
|
||||
seq.get_statements()[0].get_argBuf().resetSer();
|
||||
result = tester_deserializeDirective(seq.get_statements()[0], actual);
|
||||
ASSERT_EQ(result, Fw::Success::FAILURE);
|
||||
ASSERT_EVENTS_DirectiveDeserializeError_SIZE(1);
|
||||
}
|
||||
// caught a bug
|
||||
TEST_F(FpySequencerTester, checkTimers) {
|
||||
allocMem();
|
||||
|
||||
@ -32,13 +32,12 @@ TEST_F(FpySequencerTester, ComplexControlFlow) {
|
||||
add_IF(6);
|
||||
// if true
|
||||
add_NO_OP();
|
||||
add_GOTO(9); // goto end
|
||||
add_GOTO(9); // goto end
|
||||
// else
|
||||
add_NO_OP();
|
||||
add_NO_OP();
|
||||
add_NO_OP();
|
||||
|
||||
|
||||
writeAndRun();
|
||||
dispatchUntilState(State::IDLE);
|
||||
ASSERT_EQ(tester_get_m_tlm_ptr()->lastDirectiveError, DirectiveError::NO_ERROR);
|
||||
@ -65,7 +64,7 @@ TEST_F(FpySequencerTester, OrOfTlmAndReg) {
|
||||
add_IF(8);
|
||||
// if true
|
||||
add_NO_OP();
|
||||
add_GOTO(11); // goto end
|
||||
add_GOTO(11); // goto end
|
||||
// else
|
||||
add_NO_OP();
|
||||
add_NO_OP();
|
||||
@ -97,7 +96,7 @@ TEST_F(FpySequencerTester, CmpIntTlm) {
|
||||
add_IF(8);
|
||||
// if true
|
||||
add_NO_OP();
|
||||
add_GOTO(11); // goto end
|
||||
add_GOTO(11); // goto end
|
||||
// else
|
||||
add_NO_OP();
|
||||
add_NO_OP();
|
||||
@ -135,4 +134,4 @@ TEST_F(FpySequencerTester, NotTrueSeq) {
|
||||
ASSERT_EQ(tester_get_m_tlm_ptr()->lastDirectiveError, DirectiveError::NO_ERROR);
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace Svc
|
||||
@ -189,7 +189,8 @@ void FpySequencerTester::add_CONST_CMD(FwOpcodeType opcode) {
|
||||
void FpySequencerTester::add_CONST_CMD(FpySequencer_ConstCmdDirective dir) {
|
||||
Fw::StatementArgBuffer buf;
|
||||
FW_ASSERT(buf.serialize(dir.get_opCode()) == Fw::SerializeStatus::FW_SERIALIZE_OK);
|
||||
FW_ASSERT(buf.serialize(dir.get_argBuf(), dir.get__argBufSize(), Fw::Serialization::OMIT_LENGTH) == Fw::SerializeStatus::FW_SERIALIZE_OK);
|
||||
FW_ASSERT(buf.serialize(dir.get_argBuf(), dir.get__argBufSize(), Fw::Serialization::OMIT_LENGTH) ==
|
||||
Fw::SerializeStatus::FW_SERIALIZE_OK);
|
||||
addDirective(Fpy::DirectiveId::CONST_CMD, buf);
|
||||
}
|
||||
|
||||
@ -226,7 +227,8 @@ void FpySequencerTester::add_LOAD(FpySequencer_LoadDirective dir) {
|
||||
FW_ASSERT(buf.serialize(dir) == Fw::SerializeStatus::FW_SERIALIZE_OK);
|
||||
addDirective(Fpy::DirectiveId::LOAD, buf);
|
||||
}
|
||||
template <typename T> void FpySequencerTester::add_PUSH_VAL(T val) {
|
||||
template <typename T>
|
||||
void FpySequencerTester::add_PUSH_VAL(T val) {
|
||||
Fw::StatementArgBuffer buf;
|
||||
FW_ASSERT(buf.serializeFrom(val) == Fw::SerializeStatus::FW_SERIALIZE_OK);
|
||||
addDirective(Fpy::DirectiveId::PUSH_VAL, buf);
|
||||
@ -240,7 +242,30 @@ template void FpySequencerTester::add_PUSH_VAL(I8);
|
||||
template void FpySequencerTester::add_PUSH_VAL(I16);
|
||||
template void FpySequencerTester::add_PUSH_VAL(I32);
|
||||
template void FpySequencerTester::add_PUSH_VAL(I64);
|
||||
|
||||
void FpySequencerTester::add_DISCARD(U16 size) {
|
||||
add_DISCARD(FpySequencer_DiscardDirective(size));
|
||||
}
|
||||
void FpySequencerTester::add_DISCARD(FpySequencer_DiscardDirective dir) {
|
||||
Fw::StatementArgBuffer buf;
|
||||
FW_ASSERT(buf.serialize(dir) == Fw::SerializeStatus::FW_SERIALIZE_OK);
|
||||
addDirective(Fpy::DirectiveId::DISCARD, buf);
|
||||
}
|
||||
void FpySequencerTester::add_STACK_CMD(U16 size) {
|
||||
add_STACK_CMD(FpySequencer_StackCmdDirective(size));
|
||||
}
|
||||
void FpySequencerTester::add_STACK_CMD(FpySequencer_StackCmdDirective dir) {
|
||||
Fw::StatementArgBuffer buf;
|
||||
FW_ASSERT(buf.serialize(dir) == Fw::SerializeStatus::FW_SERIALIZE_OK);
|
||||
addDirective(Fpy::DirectiveId::STACK_CMD, buf);
|
||||
}
|
||||
void FpySequencerTester::add_MEMCMP(U16 size) {
|
||||
add_MEMCMP(FpySequencer_MemCmpDirective(size));
|
||||
}
|
||||
void FpySequencerTester::add_MEMCMP(FpySequencer_MemCmpDirective dir) {
|
||||
Fw::StatementArgBuffer buf;
|
||||
FW_ASSERT(buf.serialize(dir) == Fw::SerializeStatus::FW_SERIALIZE_OK);
|
||||
addDirective(Fpy::DirectiveId::MEMCMP, buf);
|
||||
}
|
||||
//! Handle a text event
|
||||
void FpySequencerTester::textLogIn(FwEventIdType id, //!< The event ID
|
||||
const Fw::Time& timeTag, //!< The time
|
||||
@ -321,12 +346,12 @@ Signal FpySequencerTester::tester_if_directiveHandler(const FpySequencer_IfDirec
|
||||
}
|
||||
|
||||
Signal FpySequencerTester::tester_storePrm_directiveHandler(const FpySequencer_StorePrmDirective& directive,
|
||||
DirectiveError& err) {
|
||||
DirectiveError& err) {
|
||||
return this->cmp.storePrm_directiveHandler(directive, err);
|
||||
}
|
||||
|
||||
Signal FpySequencerTester::tester_storeTlmVal_directiveHandler(const FpySequencer_StoreTlmValDirective& directive,
|
||||
DirectiveError& err) {
|
||||
DirectiveError& err) {
|
||||
return this->cmp.storeTlmVal_directiveHandler(directive, err);
|
||||
}
|
||||
|
||||
@ -336,15 +361,30 @@ Signal FpySequencerTester::tester_exit_directiveHandler(const FpySequencer_ExitD
|
||||
}
|
||||
|
||||
Signal FpySequencerTester::tester_constCmd_directiveHandler(const FpySequencer_ConstCmdDirective& directive,
|
||||
DirectiveError& err) {
|
||||
DirectiveError& err) {
|
||||
return this->cmp.constCmd_directiveHandler(directive, err);
|
||||
}
|
||||
|
||||
Signal FpySequencerTester::tester_stackOp_directiveHandler(const FpySequencer_StackOpDirective& directive,
|
||||
DirectiveError& err) {
|
||||
DirectiveError& err) {
|
||||
return this->cmp.stackOp_directiveHandler(directive, err);
|
||||
}
|
||||
|
||||
Signal FpySequencerTester::tester_discard_directiveHandler(const FpySequencer_DiscardDirective& directive,
|
||||
DirectiveError& err) {
|
||||
return this->cmp.discard_directiveHandler(directive, err);
|
||||
}
|
||||
|
||||
Signal FpySequencerTester::tester_stackCmd_directiveHandler(const FpySequencer_StackCmdDirective& directive,
|
||||
DirectiveError& err) {
|
||||
return this->cmp.stackCmd_directiveHandler(directive, err);
|
||||
}
|
||||
|
||||
Signal FpySequencerTester::tester_memCmp_directiveHandler(const FpySequencer_MemCmpDirective& directive,
|
||||
DirectiveError& err) {
|
||||
return this->cmp.memCmp_directiveHandler(directive, err);
|
||||
}
|
||||
|
||||
Fw::Success FpySequencerTester::tester_deserializeDirective(const Fpy::Statement& stmt,
|
||||
Svc::FpySequencer::DirectiveUnion& deserializedDirective) {
|
||||
return this->cmp.deserializeDirective(stmt, deserializedDirective);
|
||||
@ -370,7 +410,10 @@ Svc::FpySequencer::Telemetry* FpySequencerTester::tester_get_m_tlm_ptr() {
|
||||
return &this->cmp.m_tlm;
|
||||
}
|
||||
|
||||
Fw::Success FpySequencerTester::tester_readBytes(Os::File& file, FwSizeType readLen, FpySequencer_FileReadStage readStage, bool updateCrc) {
|
||||
Fw::Success FpySequencerTester::tester_readBytes(Os::File& file,
|
||||
FwSizeType readLen,
|
||||
FpySequencer_FileReadStage readStage,
|
||||
bool updateCrc) {
|
||||
return this->cmp.readBytes(file, readLen, readStage, updateCrc);
|
||||
}
|
||||
|
||||
@ -506,6 +549,78 @@ DirectiveError FpySequencerTester::tester_op_sitofp() {
|
||||
DirectiveError FpySequencerTester::tester_op_uitofp() {
|
||||
return this->cmp.op_uitofp();
|
||||
}
|
||||
DirectiveError FpySequencerTester::tester_op_iadd() {
|
||||
return this->cmp.op_iadd();
|
||||
}
|
||||
DirectiveError FpySequencerTester::tester_op_isub() {
|
||||
return this->cmp.op_isub();
|
||||
}
|
||||
DirectiveError FpySequencerTester::tester_op_imul() {
|
||||
return this->cmp.op_imul();
|
||||
}
|
||||
DirectiveError FpySequencerTester::tester_op_udiv() {
|
||||
return this->cmp.op_udiv();
|
||||
}
|
||||
DirectiveError FpySequencerTester::tester_op_sdiv() {
|
||||
return this->cmp.op_sdiv();
|
||||
}
|
||||
DirectiveError FpySequencerTester::tester_op_umod() {
|
||||
return this->cmp.op_umod();
|
||||
}
|
||||
DirectiveError FpySequencerTester::tester_op_smod() {
|
||||
return this->cmp.op_smod();
|
||||
}
|
||||
DirectiveError FpySequencerTester::tester_op_fadd() {
|
||||
return this->cmp.op_fadd();
|
||||
}
|
||||
DirectiveError FpySequencerTester::tester_op_fsub() {
|
||||
return this->cmp.op_fsub();
|
||||
}
|
||||
DirectiveError FpySequencerTester::tester_op_fmul() {
|
||||
return this->cmp.op_fmul();
|
||||
}
|
||||
DirectiveError FpySequencerTester::tester_op_fdiv() {
|
||||
return this->cmp.op_fdiv();
|
||||
}
|
||||
DirectiveError FpySequencerTester::tester_op_float_floor_div() {
|
||||
return this->cmp.op_float_floor_div();
|
||||
}
|
||||
DirectiveError FpySequencerTester::tester_op_fpow() {
|
||||
return this->cmp.op_fpow();
|
||||
}
|
||||
DirectiveError FpySequencerTester::tester_op_flog() {
|
||||
return this->cmp.op_flog();
|
||||
}
|
||||
DirectiveError FpySequencerTester::tester_op_fmod() {
|
||||
return this->cmp.op_fmod();
|
||||
}
|
||||
DirectiveError FpySequencerTester::tester_op_siext_8_64() {
|
||||
return this->cmp.op_siext_8_64();
|
||||
}
|
||||
DirectiveError FpySequencerTester::tester_op_siext_16_64() {
|
||||
return this->cmp.op_siext_16_64();
|
||||
}
|
||||
DirectiveError FpySequencerTester::tester_op_siext_32_64() {
|
||||
return this->cmp.op_siext_32_64();
|
||||
}
|
||||
DirectiveError FpySequencerTester::tester_op_ziext_8_64() {
|
||||
return this->cmp.op_ziext_8_64();
|
||||
}
|
||||
DirectiveError FpySequencerTester::tester_op_ziext_16_64() {
|
||||
return this->cmp.op_ziext_16_64();
|
||||
}
|
||||
DirectiveError FpySequencerTester::tester_op_ziext_32_64() {
|
||||
return this->cmp.op_ziext_32_64();
|
||||
}
|
||||
DirectiveError FpySequencerTester::tester_op_itrunc_64_8() {
|
||||
return this->cmp.op_itrunc_64_8();
|
||||
}
|
||||
DirectiveError FpySequencerTester::tester_op_itrunc_64_16() {
|
||||
return this->cmp.op_itrunc_64_16();
|
||||
}
|
||||
DirectiveError FpySequencerTester::tester_op_itrunc_64_32() {
|
||||
return this->cmp.op_itrunc_64_32();
|
||||
}
|
||||
void FpySequencerTester::tester_doDispatch() {
|
||||
this->cmp.doDispatch();
|
||||
}
|
||||
@ -518,11 +633,13 @@ void FpySequencerTester::tester_setState(Svc::FpySequencer_SequencerStateMachine
|
||||
FpySequencer_SequencerStateMachineTester::setState(this->cmp.m_stateMachine_sequencer, state);
|
||||
}
|
||||
|
||||
void FpySequencerTester::tester_dispatchDirective(const FpySequencer::DirectiveUnion& directive, const Fpy::DirectiveId& id) {
|
||||
void FpySequencerTester::tester_dispatchDirective(const FpySequencer::DirectiveUnion& directive,
|
||||
const Fpy::DirectiveId& id) {
|
||||
this->cmp.dispatchDirective(directive, id);
|
||||
}
|
||||
|
||||
template <typename T> void FpySequencerTester::tester_push(T val) {
|
||||
template <typename T>
|
||||
void FpySequencerTester::tester_push(T val) {
|
||||
cmp.push<T>(val);
|
||||
}
|
||||
template void FpySequencerTester::tester_push(U8);
|
||||
@ -535,7 +652,8 @@ template void FpySequencerTester::tester_push(I32);
|
||||
template void FpySequencerTester::tester_push(I64);
|
||||
template void FpySequencerTester::tester_push(F32);
|
||||
template void FpySequencerTester::tester_push(F64);
|
||||
template <typename T> T FpySequencerTester::tester_pop() {
|
||||
template <typename T>
|
||||
T FpySequencerTester::tester_pop() {
|
||||
return cmp.pop<T>();
|
||||
}
|
||||
template U8 FpySequencerTester::tester_pop();
|
||||
|
||||
@ -103,7 +103,14 @@ class FpySequencerTester : public FpySequencerGTestBase, public ::testing::Test
|
||||
void add_STORE(FpySequencer_StoreDirective dir);
|
||||
void add_LOAD(U16 lvarOffset, U16 size);
|
||||
void add_LOAD(FpySequencer_LoadDirective dir);
|
||||
template <typename T> void add_PUSH_VAL(T val);
|
||||
void add_DISCARD(U16 size);
|
||||
void add_DISCARD(FpySequencer_DiscardDirective dir);
|
||||
void add_STACK_CMD(U16 size);
|
||||
void add_STACK_CMD(FpySequencer_StackCmdDirective dir);
|
||||
void add_MEMCMP(U16 size);
|
||||
void add_MEMCMP(FpySequencer_MemCmpDirective dir);
|
||||
template <typename T>
|
||||
void add_PUSH_VAL(T val);
|
||||
//! Handle a text event
|
||||
void textLogIn(FwEventIdType id, //!< The event ID
|
||||
const Fw::Time& timeTag, //!< The time
|
||||
@ -132,13 +139,16 @@ class FpySequencerTester : public FpySequencerGTestBase, public ::testing::Test
|
||||
Signal tester_noOp_directiveHandler(const FpySequencer_NoOpDirective& directive, DirectiveError& err);
|
||||
Signal tester_waitRel_directiveHandler(const FpySequencer_WaitRelDirective& directive, DirectiveError& err);
|
||||
Signal tester_waitAbs_directiveHandler(const FpySequencer_WaitAbsDirective& directive, DirectiveError& err);
|
||||
Signal tester_goto_directiveHandler(const Svc::FpySequencer_GotoDirective &directive, DirectiveError& err);
|
||||
Signal tester_goto_directiveHandler(const Svc::FpySequencer_GotoDirective& directive, DirectiveError& err);
|
||||
Signal tester_if_directiveHandler(const FpySequencer_IfDirective& directive, DirectiveError& err);
|
||||
Signal tester_storePrm_directiveHandler(const FpySequencer_StorePrmDirective& directive, DirectiveError& err);
|
||||
Signal tester_storeTlmVal_directiveHandler(const FpySequencer_StoreTlmValDirective& directive, DirectiveError& err);
|
||||
Signal tester_exit_directiveHandler(const FpySequencer_ExitDirective& directive, DirectiveError& err);
|
||||
Signal tester_constCmd_directiveHandler(const FpySequencer_ConstCmdDirective& directive, DirectiveError& err);
|
||||
Signal tester_stackOp_directiveHandler(const FpySequencer_StackOpDirective& directive, DirectiveError& err);
|
||||
Signal tester_discard_directiveHandler(const FpySequencer_DiscardDirective& directive, DirectiveError& err);
|
||||
Signal tester_stackCmd_directiveHandler(const FpySequencer_StackCmdDirective& directive, DirectiveError& err);
|
||||
Signal tester_memCmp_directiveHandler(const FpySequencer_MemCmpDirective& directive, DirectiveError& err);
|
||||
DirectiveError tester_op_or();
|
||||
DirectiveError tester_op_and();
|
||||
DirectiveError tester_op_ieq();
|
||||
@ -164,19 +174,47 @@ class FpySequencerTester : public FpySequencerGTestBase, public ::testing::Test
|
||||
DirectiveError tester_op_fptosi();
|
||||
DirectiveError tester_op_sitofp();
|
||||
DirectiveError tester_op_uitofp();
|
||||
DirectiveError tester_op_iadd();
|
||||
DirectiveError tester_op_isub();
|
||||
DirectiveError tester_op_imul();
|
||||
DirectiveError tester_op_udiv();
|
||||
DirectiveError tester_op_sdiv();
|
||||
DirectiveError tester_op_umod();
|
||||
DirectiveError tester_op_smod();
|
||||
DirectiveError tester_op_fadd();
|
||||
DirectiveError tester_op_fsub();
|
||||
DirectiveError tester_op_fmul();
|
||||
DirectiveError tester_op_fdiv();
|
||||
DirectiveError tester_op_float_floor_div();
|
||||
DirectiveError tester_op_fpow();
|
||||
DirectiveError tester_op_flog();
|
||||
DirectiveError tester_op_fmod();
|
||||
DirectiveError tester_op_siext_8_64();
|
||||
DirectiveError tester_op_siext_16_64();
|
||||
DirectiveError tester_op_siext_32_64();
|
||||
DirectiveError tester_op_ziext_8_64();
|
||||
DirectiveError tester_op_ziext_16_64();
|
||||
DirectiveError tester_op_ziext_32_64();
|
||||
DirectiveError tester_op_itrunc_64_8();
|
||||
DirectiveError tester_op_itrunc_64_16();
|
||||
DirectiveError tester_op_itrunc_64_32();
|
||||
FpySequencer::Runtime* tester_get_m_runtime_ptr();
|
||||
Fw::ExternalSerializeBuffer* tester_get_m_sequenceBuffer_ptr();
|
||||
void tester_set_m_sequencesStarted(U64 val);
|
||||
void tester_set_m_statementsDispatched(U64 val);
|
||||
U64 tester_get_m_sequencesStarted();
|
||||
U64 tester_get_m_statementsDispatched();
|
||||
Fw::Success tester_deserializeDirective(const Fpy::Statement& stmt, Svc::FpySequencer::DirectiveUnion& deserializedDirective);
|
||||
Fw::Success tester_deserializeDirective(const Fpy::Statement& stmt,
|
||||
Svc::FpySequencer::DirectiveUnion& deserializedDirective);
|
||||
Fpy::Sequence* tester_get_m_sequenceObj_ptr();
|
||||
Svc::Signal tester_dispatchStatement();
|
||||
Fw::Success tester_validate();
|
||||
Fw::String tester_get_m_sequenceFilePath();
|
||||
void tester_set_m_sequenceFilePath(Fw::String str);
|
||||
Fw::Success tester_readBytes(Os::File& file, FwSizeType readLen, FpySequencer_FileReadStage readStage, bool updateCrc = true);
|
||||
Fw::Success tester_readBytes(Os::File& file,
|
||||
FwSizeType readLen,
|
||||
FpySequencer_FileReadStage readStage,
|
||||
bool updateCrc = true);
|
||||
Fw::Success tester_readFooter();
|
||||
Fw::Success tester_readBody();
|
||||
Fw::Success tester_readHeader();
|
||||
@ -189,8 +227,10 @@ class FpySequencerTester : public FpySequencerGTestBase, public ::testing::Test
|
||||
void tester_setState(Svc::FpySequencer_SequencerStateMachineStateMachineBase::State state);
|
||||
Svc::FpySequencer_SequencerStateMachineStateMachineBase::State tester_getState();
|
||||
void tester_dispatchDirective(const FpySequencer::DirectiveUnion& directive, const Fpy::DirectiveId& id);
|
||||
template <typename T> void tester_push(T val);
|
||||
template <typename T> T tester_pop();
|
||||
template <typename T>
|
||||
void tester_push(T val);
|
||||
template <typename T>
|
||||
T tester_pop();
|
||||
|
||||
public:
|
||||
// ----------------------------------------------------------------------
|
||||
@ -198,24 +238,16 @@ class FpySequencerTester : public FpySequencerGTestBase, public ::testing::Test
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
//! Get the OPCODE_RUN value
|
||||
static FwOpcodeType get_OPCODE_RUN() {
|
||||
return FpySequencerComponentBase::OPCODE_RUN;
|
||||
}
|
||||
static FwOpcodeType get_OPCODE_RUN() { return FpySequencerComponentBase::OPCODE_RUN; }
|
||||
|
||||
//! Get the OPCODE_VALIDATE value
|
||||
static FwOpcodeType get_OPCODE_VALIDATE() {
|
||||
return FpySequencerComponentBase::OPCODE_VALIDATE;
|
||||
}
|
||||
static FwOpcodeType get_OPCODE_VALIDATE() { return FpySequencerComponentBase::OPCODE_VALIDATE; }
|
||||
|
||||
//! Get the OPCODE_RUN_VALIDATED value
|
||||
static FwOpcodeType get_OPCODE_RUN_VALIDATED() {
|
||||
return FpySequencerComponentBase::OPCODE_RUN_VALIDATED;
|
||||
}
|
||||
static FwOpcodeType get_OPCODE_RUN_VALIDATED() { return FpySequencerComponentBase::OPCODE_RUN_VALIDATED; }
|
||||
|
||||
//! Get the OPCODE_CANCEL value
|
||||
static FwOpcodeType get_OPCODE_CANCEL() {
|
||||
return FpySequencerComponentBase::OPCODE_CANCEL;
|
||||
}
|
||||
static FwOpcodeType get_OPCODE_CANCEL() { return FpySequencerComponentBase::OPCODE_CANCEL; }
|
||||
|
||||
//! Get the OPCODE_DEBUG_CLEAR_BREAKPOINT value
|
||||
static FwOpcodeType get_OPCODE_DEBUG_CLEAR_BREAKPOINT() {
|
||||
@ -228,16 +260,10 @@ class FpySequencerTester : public FpySequencerGTestBase, public ::testing::Test
|
||||
}
|
||||
|
||||
//! Get the OPCODE_DEBUG_BREAK value
|
||||
static FwOpcodeType get_OPCODE_DEBUG_BREAK() {
|
||||
return FpySequencerComponentBase::OPCODE_DEBUG_BREAK;
|
||||
}
|
||||
static FwOpcodeType get_OPCODE_DEBUG_BREAK() { return FpySequencerComponentBase::OPCODE_DEBUG_BREAK; }
|
||||
|
||||
//! Get the OPCODE_DEBUG_CONTINUE value
|
||||
static FwOpcodeType get_OPCODE_DEBUG_CONTINUE() {
|
||||
return FpySequencerComponentBase::OPCODE_DEBUG_CONTINUE;
|
||||
}
|
||||
|
||||
|
||||
static FwOpcodeType get_OPCODE_DEBUG_CONTINUE() { return FpySequencerComponentBase::OPCODE_DEBUG_CONTINUE; }
|
||||
};
|
||||
|
||||
class FpySequencer_SequencerStateMachineTester {
|
||||
@ -257,10 +283,7 @@ class FpySequencer_SequencerStateMachineTester {
|
||||
// ----------------------------------------------------------------------
|
||||
// Test access to private and protected methods and members
|
||||
// ----------------------------------------------------------------------
|
||||
static void setState(FpySequencer_SequencerStateMachineStateMachineBase& sm, State s){
|
||||
sm.m_state = s;
|
||||
}
|
||||
|
||||
static void setState(FpySequencer_SequencerStateMachineStateMachineBase& sm, State s) { sm.m_state = s; }
|
||||
};
|
||||
|
||||
} // namespace Svc
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user