mirror of
https://github.com/nasa/fprime.git
synced 2025-12-10 00:44:37 -06:00
Add float to int conversion directives, some misc changes (#3847)
* Add fptoi and itofp dirs * Fix F32 literal * Add some file read stage telemetry to err msgs * Update default register count to 128 * Fix NOT directive to behave properly with if * Make fptoi and itofp signed/unsigned * fix warning * Fix another warning * Fix sp
This commit is contained in:
parent
2690e31bff
commit
a91f24cb38
5
.github/actions/spelling/expect.txt
vendored
5
.github/actions/spelling/expect.txt
vendored
@ -244,11 +244,14 @@ fpptest
|
||||
fprime
|
||||
fptr
|
||||
fptrunc
|
||||
fptosi
|
||||
fptoui
|
||||
fputil
|
||||
fpy
|
||||
FPYSEQUENCER
|
||||
freeram
|
||||
Fregoso
|
||||
fres
|
||||
frhs
|
||||
frsize
|
||||
fsblkcnt
|
||||
@ -599,6 +602,7 @@ sideeffect
|
||||
sighandler
|
||||
Signedness
|
||||
Silveira
|
||||
sitofp
|
||||
sle
|
||||
sloc
|
||||
socio
|
||||
@ -696,6 +700,7 @@ typedef
|
||||
uart
|
||||
UDPSOCKET
|
||||
uge
|
||||
uitofp
|
||||
ulhs
|
||||
UML
|
||||
UNEXP
|
||||
|
||||
@ -13,6 +13,12 @@ module Svc {
|
||||
IDLE
|
||||
}
|
||||
|
||||
enum FileReadStage {
|
||||
HEADER
|
||||
BODY
|
||||
FOOTER
|
||||
}
|
||||
|
||||
include "FpySequencerCommands.fppi"
|
||||
include "FpySequencerTelemetry.fppi"
|
||||
include "FpySequencerEvents.fppi"
|
||||
|
||||
@ -23,8 +23,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::NUM_REGISTERS <= std::numeric_limits<U8>::max(),
|
||||
"Register count must be below U8 max");
|
||||
static_assert(Svc::Fpy::NUM_REGISTERS <= std::numeric_limits<U8>::max(), "Register 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_SERIALIZABLE_REGISTER_SIZE <= std::numeric_limits<FwSizeType>::max(),
|
||||
@ -41,8 +40,7 @@ using State = FpySequencer_SequencerStateMachineStateMachineBase::State;
|
||||
using DirectiveError = FpySequencer_DirectiveErrorCode;
|
||||
|
||||
class FpySequencer : public FpySequencerComponentBase {
|
||||
|
||||
friend class FpySequencerTester;
|
||||
friend class FpySequencerTester;
|
||||
|
||||
public:
|
||||
union DirectiveUnion {
|
||||
@ -78,17 +76,15 @@ class FpySequencer : public FpySequencerComponentBase {
|
||||
//!
|
||||
~FpySequencer();
|
||||
|
||||
private:
|
||||
|
||||
//! Handler for command RUN
|
||||
//!
|
||||
//! Loads, validates and runs a sequence
|
||||
void
|
||||
RUN_cmdHandler(FwOpcodeType opCode, //!< The opcode
|
||||
U32 cmdSeq, //!< The command sequence number
|
||||
const Fw::CmdStringArg& fileName, //!< The name of the sequence file
|
||||
FpySequencer_BlockState block //!< Return command status when complete or not
|
||||
) override;
|
||||
private:
|
||||
//! Handler for command RUN
|
||||
//!
|
||||
//! Loads, validates and runs a sequence
|
||||
void RUN_cmdHandler(FwOpcodeType opCode, //!< The opcode
|
||||
U32 cmdSeq, //!< The command sequence number
|
||||
const Fw::CmdStringArg& fileName, //!< The name of the sequence file
|
||||
FpySequencer_BlockState block //!< Return command status when complete or not
|
||||
) override;
|
||||
|
||||
//! Handler for command VALIDATE
|
||||
//!
|
||||
@ -323,32 +319,30 @@ class FpySequencer : public FpySequencerComponentBase {
|
||||
//!
|
||||
//! called when a sequence failed to execute successfully
|
||||
void Svc_FpySequencer_SequencerStateMachine_action_report_seqFailed(
|
||||
SmId smId, //!< The state machine id
|
||||
Svc_FpySequencer_SequencerStateMachine::Signal signal //!< The signal
|
||||
) override;
|
||||
SmId smId, //!< The state machine id
|
||||
Svc_FpySequencer_SequencerStateMachine::Signal signal //!< The signal
|
||||
) override;
|
||||
|
||||
//! Implementation for action report_seqStarted of state machine Svc_FpySequencer_SequencerStateMachine
|
||||
//!
|
||||
//! reports that a sequence was started
|
||||
void Svc_FpySequencer_SequencerStateMachine_action_report_seqStarted(
|
||||
SmId smId, //!< The state machine id
|
||||
Svc_FpySequencer_SequencerStateMachine::Signal signal //!< The signal
|
||||
) override;
|
||||
SmId smId, //!< The state machine id
|
||||
Svc_FpySequencer_SequencerStateMachine::Signal signal //!< The signal
|
||||
) override;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
// ----------------------------------------------------------------------
|
||||
// Functions to implement for internal state machine guards
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Functions to implement for internal state machine guards
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
//! Implementation for guard goalStateIs_RUNNING of state machine Svc_FpySequencer_SequencerStateMachine
|
||||
//!
|
||||
//! return true if the goal state is RUNNING
|
||||
bool
|
||||
Svc_FpySequencer_SequencerStateMachine_guard_goalStateIs_RUNNING(
|
||||
SmId smId, //!< The state machine id
|
||||
Svc_FpySequencer_SequencerStateMachine::Signal signal //!< The signal
|
||||
) const override;
|
||||
//! Implementation for guard goalStateIs_RUNNING of state machine Svc_FpySequencer_SequencerStateMachine
|
||||
//!
|
||||
//! return true if the goal state is RUNNING
|
||||
bool Svc_FpySequencer_SequencerStateMachine_guard_goalStateIs_RUNNING(
|
||||
SmId smId, //!< The state machine id
|
||||
Svc_FpySequencer_SequencerStateMachine::Signal signal //!< The signal
|
||||
) const override;
|
||||
|
||||
//! Implementation for guard shouldDebugBreak of state machine Svc_FpySequencer_SequencerStateMachine
|
||||
//!
|
||||
@ -384,9 +378,7 @@ class FpySequencer : public FpySequencerComponentBase {
|
||||
) override;
|
||||
|
||||
//! Handler for input port seqRunIn
|
||||
void seqRunIn_handler(FwIndexType portNum,
|
||||
const Fw::StringBase& filename
|
||||
) override;
|
||||
void seqRunIn_handler(FwIndexType portNum, const Fw::StringBase& filename) override;
|
||||
|
||||
//! Handler for input port pingIn
|
||||
void pingIn_handler(FwIndexType portNum, //!< The port number
|
||||
@ -426,13 +418,15 @@ class FpySequencer : public FpySequencerComponentBase {
|
||||
void directive_cmd_internalInterfaceHandler(const Svc::FpySequencer_CmdDirective& directive) override;
|
||||
|
||||
//! Internal interface handler for directive_deserSerReg
|
||||
void directive_deserSerReg_internalInterfaceHandler(const Svc::FpySequencer_DeserSerRegDirective& directive) override;
|
||||
void directive_deserSerReg_internalInterfaceHandler(
|
||||
const Svc::FpySequencer_DeserSerRegDirective& directive) override;
|
||||
|
||||
//! Internal interface handler for directive_setReg
|
||||
void directive_setReg_internalInterfaceHandler(const Svc::FpySequencer_SetRegDirective& directive) override;
|
||||
|
||||
//! Internal interface handler for directive_binaryRegOp
|
||||
void directive_binaryRegOp_internalInterfaceHandler(const Svc::FpySequencer_BinaryRegOpDirective& directive) override;
|
||||
void directive_binaryRegOp_internalInterfaceHandler(
|
||||
const Svc::FpySequencer_BinaryRegOpDirective& directive) override;
|
||||
|
||||
//! Internal interface handler for directive_unaryRegOp
|
||||
void directive_unaryRegOp_internalInterfaceHandler(const Svc::FpySequencer_UnaryRegOpDirective& directive) override;
|
||||
@ -447,9 +441,9 @@ class FpySequencer : public FpySequencerComponentBase {
|
||||
void allocateBuffer(FwEnumStoreType identifier, Fw::MemAllocator& allocator, FwSizeType bytes);
|
||||
|
||||
void deallocateBuffer(Fw::MemAllocator& allocator);
|
||||
private :
|
||||
|
||||
static constexpr U32 CRC_INITIAL_VALUE = 0xFFFFFFFFU;
|
||||
private:
|
||||
static constexpr U32 CRC_INITIAL_VALUE = 0xFFFFFFFFU;
|
||||
|
||||
// allocated at startup
|
||||
Fw::ExternalSerializeBuffer m_sequenceBuffer;
|
||||
@ -570,7 +564,10 @@ class FpySequencer : public FpySequencerComponentBase {
|
||||
// updates the CRC by default, but can be turned off if the contents
|
||||
// aren't included in CRC.
|
||||
// return success if successful
|
||||
Fw::Success readBytes(Os::File& file, FwSizeType readLen, bool updateCrc = true);
|
||||
Fw::Success readBytes(Os::File& file,
|
||||
FwSizeType readLen,
|
||||
const FpySequencer_FileReadStage& readStage,
|
||||
bool updateCrc = true);
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Run state
|
||||
@ -648,6 +645,10 @@ class FpySequencer : public FpySequencerComponentBase {
|
||||
I64 unaryRegOp_not(I64 src);
|
||||
I64 unaryRegOp_fpext(I64 src);
|
||||
I64 unaryRegOp_fptrunc(I64 src);
|
||||
I64 unaryRegOp_fptoui(I64 src);
|
||||
I64 unaryRegOp_fptosi(I64 src);
|
||||
I64 unaryRegOp_sitofp(I64 src);
|
||||
I64 unaryRegOp_uitofp(I64 src);
|
||||
|
||||
Signal exit_directiveHandler(const FpySequencer_ExitDirective& directive, DirectiveError& error);
|
||||
};
|
||||
|
||||
@ -111,15 +111,16 @@ void FpySequencer::directive_setReg_internalInterfaceHandler(const Svc::FpySeque
|
||||
}
|
||||
|
||||
//! Internal interface handler for directive_binaryRegOp
|
||||
void FpySequencer::directive_binaryRegOp_internalInterfaceHandler(const Svc::FpySequencer_BinaryRegOpDirective& directive) {
|
||||
void FpySequencer::directive_binaryRegOp_internalInterfaceHandler(
|
||||
const Svc::FpySequencer_BinaryRegOpDirective& directive) {
|
||||
DirectiveError error = DirectiveError::NO_ERROR;
|
||||
this->sendSignal(this->binaryRegOp_directiveHandler(directive, error));
|
||||
this->m_tlm.lastDirectiveError = error;
|
||||
}
|
||||
|
||||
|
||||
//! Internal interface handler for directive_unaryRegOp
|
||||
void FpySequencer::directive_unaryRegOp_internalInterfaceHandler(const Svc::FpySequencer_UnaryRegOpDirective& directive) {
|
||||
void FpySequencer::directive_unaryRegOp_internalInterfaceHandler(
|
||||
const Svc::FpySequencer_UnaryRegOpDirective& directive) {
|
||||
DirectiveError error = DirectiveError::NO_ERROR;
|
||||
this->sendSignal(this->unaryRegOp_directiveHandler(directive, error));
|
||||
this->m_tlm.lastDirectiveError = error;
|
||||
@ -488,7 +489,7 @@ I64 FpySequencer::binaryRegOp_fge(I64 lhs, I64 rhs) {
|
||||
}
|
||||
|
||||
Signal FpySequencer::binaryRegOp_directiveHandler(const FpySequencer_BinaryRegOpDirective& directive,
|
||||
DirectiveError& error) {
|
||||
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::FGE,
|
||||
static_cast<FwAssertArgType>(directive.get_op()));
|
||||
@ -565,7 +566,10 @@ Signal FpySequencer::binaryRegOp_directiveHandler(const FpySequencer_BinaryRegOp
|
||||
return Signal::stmtResponse_success;
|
||||
}
|
||||
I64 FpySequencer::unaryRegOp_not(I64 src) {
|
||||
return ~src;
|
||||
if (src) {
|
||||
return static_cast<I64>(false);
|
||||
}
|
||||
return static_cast<I64>(true);
|
||||
}
|
||||
I64 FpySequencer::unaryRegOp_fpext(I64 src) {
|
||||
// convert F32 to F64
|
||||
@ -594,10 +598,41 @@ I64 FpySequencer::unaryRegOp_fptrunc(I64 src) {
|
||||
// then extend to I64
|
||||
return static_cast<I64>(itrunc);
|
||||
}
|
||||
|
||||
Signal FpySequencer::unaryRegOp_directiveHandler(const FpySequencer_UnaryRegOpDirective& directive, DirectiveError& error) {
|
||||
I64 FpySequencer::unaryRegOp_fptosi(I64 src) {
|
||||
// first interpret as F64
|
||||
F64 fsrc;
|
||||
memcpy(&fsrc, &src, sizeof(fsrc));
|
||||
// then static cast to int
|
||||
return static_cast<I64>(fsrc);
|
||||
}
|
||||
I64 FpySequencer::unaryRegOp_sitofp(I64 src) {
|
||||
// first static cast to float
|
||||
F64 fsrc = static_cast<F64>(src);
|
||||
// then return bits as I64
|
||||
I64 res;
|
||||
memcpy(&res, &fsrc, sizeof(res));
|
||||
return res;
|
||||
}
|
||||
I64 FpySequencer::unaryRegOp_fptoui(I64 src) {
|
||||
// first interpret as F64
|
||||
F64 fsrc;
|
||||
memcpy(&fsrc, &src, sizeof(fsrc));
|
||||
// then static cast to unsigned int
|
||||
// then return as a signed int
|
||||
return static_cast<I64>(static_cast<U64>(fsrc));
|
||||
}
|
||||
I64 FpySequencer::unaryRegOp_uitofp(I64 src) {
|
||||
// first static cast to unsigned, then to float
|
||||
F64 fsrc = static_cast<F64>(static_cast<U64>(src));
|
||||
// then return bits as I64
|
||||
I64 res;
|
||||
memcpy(&res, &fsrc, sizeof(res));
|
||||
return res;
|
||||
}
|
||||
Signal FpySequencer::unaryRegOp_directiveHandler(const FpySequencer_UnaryRegOpDirective& directive,
|
||||
DirectiveError& error) {
|
||||
// coding error, should not have gotten to this unary reg op handler
|
||||
FW_ASSERT(directive.get_op() >= Fpy::DirectiveId::NOT && directive.get_op() <= Fpy::DirectiveId::FPTRUNC,
|
||||
FW_ASSERT(directive.get_op() >= Fpy::DirectiveId::NOT && directive.get_op() <= Fpy::DirectiveId::UITOFP,
|
||||
static_cast<FwAssertArgType>(directive.get_op()));
|
||||
|
||||
if (directive.getsrc() >= Fpy::NUM_REGISTERS || directive.getres() >= Fpy::NUM_REGISTERS) {
|
||||
@ -607,7 +642,7 @@ Signal FpySequencer::unaryRegOp_directiveHandler(const FpySequencer_UnaryRegOpDi
|
||||
|
||||
I64 src = reg(directive.getsrc());
|
||||
I64& res = reg(directive.getres());
|
||||
|
||||
|
||||
switch (directive.get_op()) {
|
||||
case Fpy::DirectiveId::NOT:
|
||||
res = this->unaryRegOp_not(src);
|
||||
@ -618,6 +653,18 @@ Signal FpySequencer::unaryRegOp_directiveHandler(const FpySequencer_UnaryRegOpDi
|
||||
case Fpy::DirectiveId::FPTRUNC:
|
||||
res = this->unaryRegOp_fptrunc(src);
|
||||
break;
|
||||
case Fpy::DirectiveId::FPTOSI:
|
||||
res = this->unaryRegOp_fptosi(src);
|
||||
break;
|
||||
case Fpy::DirectiveId::FPTOUI:
|
||||
res = this->unaryRegOp_fptoui(src);
|
||||
break;
|
||||
case Fpy::DirectiveId::SITOFP:
|
||||
res = this->unaryRegOp_sitofp(src);
|
||||
break;
|
||||
case Fpy::DirectiveId::UITOFP:
|
||||
res = this->unaryRegOp_uitofp(src);
|
||||
break;
|
||||
default:
|
||||
FW_ASSERT(0, directive.get_op());
|
||||
break;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
event InvalidCommand($state: I32) \
|
||||
severity warning high \
|
||||
format "Cannot run command in state {}"
|
||||
format "Cannot execute command in state {}"
|
||||
|
||||
event InvalidSeqRunCall($state: I32) \
|
||||
severity warning high \
|
||||
@ -14,26 +14,29 @@ event FileOpenError(
|
||||
format "File open error encountered while opening {}: {}"
|
||||
|
||||
event FileReadError(
|
||||
readStage: FileReadStage
|
||||
filePath: string
|
||||
errorCode: I32
|
||||
) \
|
||||
severity warning high \
|
||||
format "File read error encountered while reading {}: {}"
|
||||
format "File read error encountered while reading {} of file {}: {}"
|
||||
|
||||
event EndOfFileError(
|
||||
readStage: FileReadStage
|
||||
filePath: string
|
||||
) \
|
||||
severity warning high \
|
||||
format "End of file encountered unexpectedly while reading {}"
|
||||
format "End of file encountered unexpectedly while reading {} of file {}"
|
||||
|
||||
event FileReadDeserializeError(
|
||||
readStage: FileReadStage
|
||||
filePath: string
|
||||
errorCode: I32
|
||||
buffLeft: U64
|
||||
buffLength: U64
|
||||
) \
|
||||
severity warning high \
|
||||
format "Deserialize error encountered while reading {}: {} ({} bytes left out of {})"
|
||||
format "Deserialize error encountered while reading {} of file {}: {} ({} bytes left out of {})"
|
||||
|
||||
event WrongSchemaVersion(
|
||||
expected: U8
|
||||
|
||||
@ -332,7 +332,11 @@ Fw::Success FpySequencer::deserializeDirective(const Fpy::Statement& stmt, Direc
|
||||
// fallthrough on purpose
|
||||
case Fpy::DirectiveId::NOT:
|
||||
case Fpy::DirectiveId::FPEXT:
|
||||
case Fpy::DirectiveId::FPTRUNC: {
|
||||
case Fpy::DirectiveId::FPTRUNC:
|
||||
case Fpy::DirectiveId::FPTOSI:
|
||||
case Fpy::DirectiveId::FPTOUI:
|
||||
case Fpy::DirectiveId::SITOFP:
|
||||
case Fpy::DirectiveId::UITOFP: {
|
||||
new (&deserializedDirective.unaryRegOp) FpySequencer_UnaryRegOpDirective();
|
||||
|
||||
U8 src;
|
||||
@ -456,7 +460,11 @@ void FpySequencer::dispatchDirective(const DirectiveUnion& directive, const Fpy:
|
||||
// fallthrough on purpose
|
||||
case Fpy::DirectiveId::NOT:
|
||||
case Fpy::DirectiveId::FPEXT:
|
||||
case Fpy::DirectiveId::FPTRUNC: {
|
||||
case Fpy::DirectiveId::FPTRUNC:
|
||||
case Fpy::DirectiveId::FPTOSI:
|
||||
case Fpy::DirectiveId::FPTOUI:
|
||||
case Fpy::DirectiveId::SITOFP:
|
||||
case Fpy::DirectiveId::UITOFP: {
|
||||
this->directive_unaryRegOp_internalInterfaceInvoke(directive.unaryRegOp);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -49,11 +49,18 @@ module Svc {
|
||||
|
||||
# unary reg op dirs
|
||||
NOT = 33
|
||||
# floating point extension and truncation
|
||||
FPEXT = 34
|
||||
FPTRUNC = 35
|
||||
# floating point conversion to signed/unsigned integer,
|
||||
# and vice versa
|
||||
FPTOSI = 36
|
||||
FPTOUI = 37
|
||||
SITOFP = 38
|
||||
UITOFP = 39
|
||||
# end unary reg op dirs
|
||||
|
||||
EXIT = 36
|
||||
EXIT = 40
|
||||
}
|
||||
|
||||
struct Header {
|
||||
|
||||
@ -48,7 +48,8 @@ Fw::Success FpySequencer::validate() {
|
||||
return Fw::Success::FAILURE;
|
||||
}
|
||||
|
||||
Fw::Success readStatus = this->readBytes(sequenceFile, Fpy::Header::SERIALIZED_SIZE);
|
||||
Fw::Success readStatus =
|
||||
this->readBytes(sequenceFile, Fpy::Header::SERIALIZED_SIZE, FpySequencer_FileReadStage::HEADER);
|
||||
|
||||
if (readStatus != Fw::Success::SUCCESS) {
|
||||
return Fw::Success::FAILURE;
|
||||
@ -60,7 +61,8 @@ Fw::Success FpySequencer::validate() {
|
||||
return Fw::Success::FAILURE;
|
||||
}
|
||||
|
||||
readStatus = readBytes(sequenceFile, this->m_sequenceObj.getheader().getbodySize());
|
||||
readStatus =
|
||||
readBytes(sequenceFile, this->m_sequenceObj.getheader().getbodySize(), FpySequencer_FileReadStage::BODY);
|
||||
|
||||
if (readStatus != Fw::Success::SUCCESS) {
|
||||
return Fw::Success::FAILURE;
|
||||
@ -73,7 +75,7 @@ Fw::Success FpySequencer::validate() {
|
||||
}
|
||||
|
||||
// read footer bytes but don't include in CRC
|
||||
readStatus = this->readBytes(sequenceFile, Fpy::Footer::SERIALIZED_SIZE, false);
|
||||
readStatus = this->readBytes(sequenceFile, Fpy::Footer::SERIALIZED_SIZE, FpySequencer_FileReadStage::FOOTER, false);
|
||||
|
||||
if (readStatus != Fw::Success::SUCCESS) {
|
||||
return Fw::Success::FAILURE;
|
||||
@ -104,9 +106,9 @@ Fw::Success FpySequencer::readHeader() {
|
||||
// deser header
|
||||
Fw::SerializeStatus deserStatus = this->m_sequenceBuffer.deserialize(this->m_sequenceObj.getheader());
|
||||
if (deserStatus != Fw::SerializeStatus::FW_SERIALIZE_OK) {
|
||||
this->log_WARNING_HI_FileReadDeserializeError(this->m_sequenceFilePath, static_cast<I32>(deserStatus),
|
||||
this->m_sequenceBuffer.getBuffLeft(),
|
||||
this->m_sequenceBuffer.getBuffLength());
|
||||
this->log_WARNING_HI_FileReadDeserializeError(
|
||||
FpySequencer_FileReadStage::HEADER, this->m_sequenceFilePath, static_cast<I32>(deserStatus),
|
||||
this->m_sequenceBuffer.getBuffLeft(), this->m_sequenceBuffer.getBuffLength());
|
||||
return Fw::Success::FAILURE;
|
||||
}
|
||||
|
||||
@ -140,9 +142,9 @@ Fw::Success FpySequencer::readBody() {
|
||||
// TODO should probably check that this serReg is inside range
|
||||
deserStatus = this->m_sequenceBuffer.deserialize(this->m_sequenceObj.getargs()[argMappingIdx]);
|
||||
if (deserStatus != Fw::FW_SERIALIZE_OK) {
|
||||
this->log_WARNING_HI_FileReadDeserializeError(this->m_sequenceFilePath, static_cast<I32>(deserStatus),
|
||||
this->m_sequenceBuffer.getBuffLeft(),
|
||||
this->m_sequenceBuffer.getBuffLength());
|
||||
this->log_WARNING_HI_FileReadDeserializeError(
|
||||
FpySequencer_FileReadStage::BODY, this->m_sequenceFilePath, static_cast<I32>(deserStatus),
|
||||
this->m_sequenceBuffer.getBuffLeft(), this->m_sequenceBuffer.getBuffLength());
|
||||
return Fw::Success::FAILURE;
|
||||
}
|
||||
}
|
||||
@ -152,9 +154,9 @@ Fw::Success FpySequencer::readBody() {
|
||||
// deser statement
|
||||
deserStatus = this->m_sequenceBuffer.deserialize(this->m_sequenceObj.getstatements()[statementIdx]);
|
||||
if (deserStatus != Fw::FW_SERIALIZE_OK) {
|
||||
this->log_WARNING_HI_FileReadDeserializeError(this->m_sequenceFilePath, static_cast<I32>(deserStatus),
|
||||
this->m_sequenceBuffer.getBuffLeft(),
|
||||
this->m_sequenceBuffer.getBuffLength());
|
||||
this->log_WARNING_HI_FileReadDeserializeError(
|
||||
FpySequencer_FileReadStage::BODY, this->m_sequenceFilePath, static_cast<I32>(deserStatus),
|
||||
this->m_sequenceBuffer.getBuffLeft(), this->m_sequenceBuffer.getBuffLength());
|
||||
return Fw::Success::FAILURE;
|
||||
}
|
||||
}
|
||||
@ -164,9 +166,9 @@ Fw::Success FpySequencer::readBody() {
|
||||
Fw::Success FpySequencer::readFooter() {
|
||||
Fw::SerializeStatus deserStatus = this->m_sequenceBuffer.deserialize(this->m_sequenceObj.getfooter());
|
||||
if (deserStatus != Fw::FW_SERIALIZE_OK) {
|
||||
this->log_WARNING_HI_FileReadDeserializeError(this->m_sequenceFilePath, static_cast<I32>(deserStatus),
|
||||
this->m_sequenceBuffer.getBuffLeft(),
|
||||
this->m_sequenceBuffer.getBuffLength());
|
||||
this->log_WARNING_HI_FileReadDeserializeError(
|
||||
FpySequencer_FileReadStage::FOOTER, this->m_sequenceFilePath, static_cast<I32>(deserStatus),
|
||||
this->m_sequenceBuffer.getBuffLeft(), this->m_sequenceBuffer.getBuffLength());
|
||||
return Fw::Success::FAILURE;
|
||||
}
|
||||
|
||||
@ -183,7 +185,10 @@ Fw::Success FpySequencer::readFooter() {
|
||||
|
||||
// reads some bytes from the open file into the m_sequenceBuffer.
|
||||
// return success if successful
|
||||
Fw::Success FpySequencer::readBytes(Os::File& file, FwSizeType expectedReadLen, bool updateCrc) {
|
||||
Fw::Success FpySequencer::readBytes(Os::File& file,
|
||||
FwSizeType expectedReadLen,
|
||||
const FpySequencer_FileReadStage& readStage,
|
||||
bool updateCrc) {
|
||||
FW_ASSERT(file.isOpen());
|
||||
// this has to be declared a var because file.read must take a ref
|
||||
FwSizeType actualReadLen = expectedReadLen;
|
||||
@ -200,12 +205,12 @@ Fw::Success FpySequencer::readBytes(Os::File& file, FwSizeType expectedReadLen,
|
||||
Os::File::Status fileStatus = file.read(this->m_sequenceBuffer.getBuffAddr(), actualReadLen);
|
||||
|
||||
if (fileStatus != Os::File::OP_OK) {
|
||||
this->log_WARNING_HI_FileReadError(this->m_sequenceFilePath, static_cast<I32>(fileStatus));
|
||||
this->log_WARNING_HI_FileReadError(readStage, this->m_sequenceFilePath, static_cast<I32>(fileStatus));
|
||||
return Fw::Success::FAILURE;
|
||||
}
|
||||
|
||||
if (actualReadLen < expectedReadLen) {
|
||||
this->log_WARNING_HI_EndOfFileError(this->m_sequenceFilePath);
|
||||
this->log_WARNING_HI_EndOfFileError(readStage, this->m_sequenceFilePath);
|
||||
return Fw::Success::FAILURE;
|
||||
}
|
||||
|
||||
|
||||
@ -691,12 +691,12 @@ TEST_F(FpySequencerTester, setReg) {
|
||||
TEST_F(FpySequencerTester, unaryRegOp) {
|
||||
// Test NOT
|
||||
FpySequencer_UnaryRegOpDirective directiveNOT(0, 1, Fpy::DirectiveId::NOT);
|
||||
tester_get_m_runtime_ptr()->regs[0] = 10;
|
||||
tester_get_m_runtime_ptr()->regs[0] = true;
|
||||
DirectiveError err = DirectiveError::NO_ERROR;
|
||||
Signal result = tester_unaryRegOp_directiveHandler(directiveNOT, err);
|
||||
ASSERT_EQ(result, Signal::stmtResponse_success);
|
||||
ASSERT_EQ(err, DirectiveError::NO_ERROR);
|
||||
ASSERT_EQ(tester_get_m_runtime_ptr()->regs[1], ~10);
|
||||
ASSERT_EQ(tester_get_m_runtime_ptr()->regs[1], false);
|
||||
|
||||
// Test out-of-bounds register index
|
||||
FpySequencer_UnaryRegOpDirective directiveOOB(Fpy::NUM_REGISTERS, 1, Fpy::DirectiveId::FPEXT);
|
||||
@ -711,7 +711,7 @@ TEST_F(FpySequencerTester, unaryRegOp) {
|
||||
|
||||
|
||||
TEST_F(FpySequencerTester, not) {
|
||||
ASSERT_EQ(tester_unaryRegOp_not(0x123), ~0x123);
|
||||
ASSERT_EQ(tester_unaryRegOp_not(true), false);
|
||||
}
|
||||
|
||||
TEST_F(FpySequencerTester, fptrunc) {
|
||||
@ -739,6 +739,48 @@ TEST_F(FpySequencerTester, fpext) {
|
||||
ASSERT_EQ(res_f, expected);
|
||||
}
|
||||
|
||||
TEST_F(FpySequencerTester, fptosi) {
|
||||
F64 src = 123.123;
|
||||
I64 expected = static_cast<I64>(src);
|
||||
|
||||
I64 isrc;
|
||||
memcpy(&isrc, &src, sizeof(isrc));
|
||||
|
||||
I64 res = tester_unaryRegOp_fptosi(isrc);
|
||||
ASSERT_EQ(res, expected);
|
||||
}
|
||||
|
||||
TEST_F(FpySequencerTester, sitofp) {
|
||||
I64 src = 123;
|
||||
F64 expected = static_cast<F64>(src);
|
||||
|
||||
I64 res = tester_unaryRegOp_sitofp(src);
|
||||
F64 fres;
|
||||
memcpy(&fres, &res, sizeof(res));
|
||||
ASSERT_EQ(fres, expected);
|
||||
}
|
||||
|
||||
TEST_F(FpySequencerTester, fptoui) {
|
||||
F64 src = 123.123;
|
||||
U64 expected = static_cast<U64>(src);
|
||||
|
||||
I64 isrc;
|
||||
memcpy(&isrc, &src, sizeof(isrc));
|
||||
|
||||
I64 res = tester_unaryRegOp_fptoui(isrc);
|
||||
ASSERT_EQ(static_cast<U64>(res), expected);
|
||||
}
|
||||
|
||||
TEST_F(FpySequencerTester, uitofp) {
|
||||
U64 src = std::numeric_limits<U64>::max();
|
||||
F64 expected = static_cast<F64>(src);
|
||||
|
||||
I64 res = tester_unaryRegOp_uitofp(static_cast<I64>(src));
|
||||
F64 fres;
|
||||
memcpy(&fres, &res, sizeof(res));
|
||||
ASSERT_EQ(fres, expected);
|
||||
}
|
||||
|
||||
TEST_F(FpySequencerTester, exit) {
|
||||
FpySequencer_ExitDirective directive(true);
|
||||
DirectiveError err = DirectiveError::NO_ERROR;
|
||||
@ -1193,20 +1235,20 @@ 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, 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, 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, true),
|
||||
ASSERT_EQ(tester_readBytes(seqFile, Fpy::Header::SERIALIZED_SIZE + Fpy::Footer::SERIALIZED_SIZE + 1, FpySequencer_FileReadStage::HEADER, true),
|
||||
Fw::Success::FAILURE);
|
||||
|
||||
seqFile.close();
|
||||
@ -1214,7 +1256,7 @@ TEST_F(FpySequencerTester, readBytes) {
|
||||
|
||||
// read after close
|
||||
ASSERT_DEATH_IF_SUPPORTED(
|
||||
tester_readBytes(seqFile, Fpy::Header::SERIALIZED_SIZE + Fpy::Footer::SERIALIZED_SIZE, true), "Assert: ");
|
||||
tester_readBytes(seqFile, Fpy::Header::SERIALIZED_SIZE + Fpy::Footer::SERIALIZED_SIZE, FpySequencer_FileReadStage::HEADER, true), "Assert: ");
|
||||
}
|
||||
|
||||
TEST_F(FpySequencerTester, validate) {
|
||||
|
||||
@ -113,5 +113,21 @@ TEST_F(FpySequencerTester, CmpIntTlm) {
|
||||
dispatchUntilState(State::IDLE);
|
||||
ASSERT_EQ(tester_get_m_statementsDispatched(), 8);
|
||||
}
|
||||
TEST_F(FpySequencerTester, NotTrueSeq) {
|
||||
// this sequence caught one bug
|
||||
allocMem();
|
||||
|
||||
add_SET_REG(0, 255);
|
||||
add_UNARY_REG_OP(0, 1, Fpy::DirectiveId::NOT);
|
||||
add_IF(1, 4);
|
||||
// should not get here
|
||||
add_EXIT(false);
|
||||
add_EXIT(true);
|
||||
|
||||
writeAndRun();
|
||||
dispatchUntilState(State::IDLE);
|
||||
// not of 255 should be interpreted as false
|
||||
ASSERT_EQ(tester_get_m_tlm_ptr()->lastDirectiveError, DirectiveError::NO_ERROR);
|
||||
}
|
||||
|
||||
}
|
||||
@ -421,8 +421,8 @@ Svc::FpySequencer::Telemetry* FpySequencerTester::tester_get_m_tlm_ptr() {
|
||||
return &this->cmp.m_tlm;
|
||||
}
|
||||
|
||||
Fw::Success FpySequencerTester::tester_readBytes(Os::File& file, FwSizeType readLen, bool updateCrc) {
|
||||
return this->cmp.readBytes(file, readLen, updateCrc);
|
||||
Fw::Success FpySequencerTester::tester_readBytes(Os::File& file, FwSizeType readLen, FpySequencer_FileReadStage readStage, bool updateCrc) {
|
||||
return this->cmp.readBytes(file, readLen, readStage, updateCrc);
|
||||
}
|
||||
|
||||
Fw::Success FpySequencerTester::tester_readFooter() {
|
||||
@ -545,6 +545,18 @@ I64 FpySequencerTester::tester_unaryRegOp_fpext(I64 src) {
|
||||
I64 FpySequencerTester::tester_unaryRegOp_fptrunc(I64 src) {
|
||||
return this->cmp.unaryRegOp_fptrunc(src);
|
||||
}
|
||||
I64 FpySequencerTester::tester_unaryRegOp_fptosi(I64 src) {
|
||||
return this->cmp.unaryRegOp_fptosi(src);
|
||||
}
|
||||
I64 FpySequencerTester::tester_unaryRegOp_sitofp(I64 src) {
|
||||
return this->cmp.unaryRegOp_sitofp(src);
|
||||
}
|
||||
I64 FpySequencerTester::tester_unaryRegOp_fptoui(I64 src) {
|
||||
return this->cmp.unaryRegOp_fptoui(src);
|
||||
}
|
||||
I64 FpySequencerTester::tester_unaryRegOp_uitofp(I64 src) {
|
||||
return this->cmp.unaryRegOp_uitofp(src);
|
||||
}
|
||||
void FpySequencerTester::tester_doDispatch() {
|
||||
this->cmp.doDispatch();
|
||||
}
|
||||
|
||||
@ -167,6 +167,10 @@ class FpySequencerTester : public FpySequencerGTestBase, public ::testing::Test
|
||||
I64 tester_unaryRegOp_not(I64 src);
|
||||
I64 tester_unaryRegOp_fpext(I64 src);
|
||||
I64 tester_unaryRegOp_fptrunc(I64 src);
|
||||
I64 tester_unaryRegOp_fptoui(I64 src);
|
||||
I64 tester_unaryRegOp_uitofp(I64 src);
|
||||
I64 tester_unaryRegOp_fptosi(I64 src);
|
||||
I64 tester_unaryRegOp_sitofp(I64 src);
|
||||
FpySequencer::Runtime* tester_get_m_runtime_ptr();
|
||||
Fw::ExternalSerializeBuffer* tester_get_m_sequenceBuffer_ptr();
|
||||
void tester_set_m_sequencesStarted(U64 val);
|
||||
@ -179,7 +183,7 @@ class FpySequencerTester : public FpySequencerGTestBase, public ::testing::Test
|
||||
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, 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();
|
||||
|
||||
@ -11,6 +11,6 @@ module Svc {
|
||||
constant MAX_SERIALIZABLE_REGISTER_SIZE = 512 - 4 - 4
|
||||
|
||||
@ The number of registers available to a sequence
|
||||
constant NUM_REGISTERS = 4
|
||||
constant NUM_REGISTERS = 128
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user