mirror of
https://github.com/nasa/fprime.git
synced 2025-12-10 00:44:37 -06:00
Add PUSH_TIME directive (#4275)
* Add push_time dir * Add docs and UT * format
This commit is contained in:
parent
35840d549d
commit
896803ad20
@ -61,6 +61,7 @@ class FpySequencer : public FpySequencerComponentBase {
|
||||
FpySequencer_DiscardDirective discard;
|
||||
FpySequencer_MemCmpDirective memCmp;
|
||||
FpySequencer_StackCmdDirective stackCmd;
|
||||
FpySequencer_PushTimeDirective pushTime;
|
||||
|
||||
DirectiveUnion() {}
|
||||
~DirectiveUnion() {}
|
||||
@ -473,6 +474,9 @@ class FpySequencer : public FpySequencerComponentBase {
|
||||
//! Internal interface handler for directive_stackCmd
|
||||
void directive_stackCmd_internalInterfaceHandler(const Svc::FpySequencer_StackCmdDirective& directive) override;
|
||||
|
||||
//! Internal interface handler for directive_pushTime
|
||||
void directive_pushTime_internalInterfaceHandler(const Svc::FpySequencer_PushTimeDirective& directive) override;
|
||||
|
||||
void parametersLoaded() override;
|
||||
void parameterUpdated(FwPrmIdType id) override;
|
||||
|
||||
@ -747,6 +751,7 @@ class FpySequencer : public FpySequencerComponentBase {
|
||||
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);
|
||||
Signal pushTime_directiveHandler(const FpySequencer_PushTimeDirective& directive, DirectiveError& error);
|
||||
};
|
||||
|
||||
} // namespace Svc
|
||||
|
||||
@ -322,6 +322,13 @@ void FpySequencer::directive_stackCmd_internalInterfaceHandler(const Svc::FpySeq
|
||||
handleDirectiveErrorCode(Fpy::DirectiveId::STACK_CMD, error);
|
||||
}
|
||||
|
||||
//! Internal interface handler for directive_pushTime
|
||||
void FpySequencer::directive_pushTime_internalInterfaceHandler(const Svc::FpySequencer_PushTimeDirective& directive) {
|
||||
DirectiveError error = DirectiveError::NO_ERROR;
|
||||
this->sendSignal(this->pushTime_directiveHandler(directive, error));
|
||||
handleDirectiveErrorCode(Fpy::DirectiveId::PUSH_TIME, error);
|
||||
}
|
||||
|
||||
//! Internal interface handler for directive_waitRel
|
||||
Signal FpySequencer::waitRel_directiveHandler(const FpySequencer_WaitRelDirective& directive, DirectiveError& error) {
|
||||
if (this->m_runtime.stackSize < 8) {
|
||||
@ -443,7 +450,7 @@ Signal FpySequencer::pushTlmValAndTime_directiveHandler(const FpySequencer_PushT
|
||||
return Signal::stmtResponse_failure;
|
||||
}
|
||||
|
||||
U8 tlmTimeBuf[Fw::Time::SERIALIZED_SIZE];
|
||||
U8 tlmTimeBuf[Fw::Time::SERIALIZED_SIZE] = {};
|
||||
Fw::ExternalSerializeBuffer timeEsb(tlmTimeBuf, Fw::Time::SERIALIZED_SIZE);
|
||||
Fw::SerializeStatus stat = timeEsb.serializeFrom(tlmTime);
|
||||
|
||||
@ -1240,4 +1247,25 @@ Signal FpySequencer::stackCmd_directiveHandler(const FpySequencer_StackCmdDirect
|
||||
|
||||
return Signal::stmtResponse_success;
|
||||
}
|
||||
|
||||
Signal FpySequencer::pushTime_directiveHandler(const FpySequencer_PushTimeDirective& directive, DirectiveError& error) {
|
||||
if (Fpy::MAX_STACK_SIZE - Fw::Time::SERIALIZED_SIZE < this->m_runtime.stackSize) {
|
||||
error = DirectiveError::STACK_OVERFLOW;
|
||||
return Signal::stmtResponse_failure;
|
||||
}
|
||||
|
||||
Fw::Time currentTime = this->getTime();
|
||||
|
||||
U8 currentTimeBuf[Fw::Time::SERIALIZED_SIZE] = {};
|
||||
Fw::ExternalSerializeBuffer timeEsb(currentTimeBuf, Fw::Time::SERIALIZED_SIZE);
|
||||
Fw::SerializeStatus stat = timeEsb.serializeFrom(currentTime);
|
||||
|
||||
// coding error if this failed, we should have enough space
|
||||
FW_ASSERT(stat == Fw::SerializeStatus::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(stat));
|
||||
|
||||
// push time to end of stack
|
||||
memcpy(this->m_runtime.stack + this->m_runtime.stackSize, timeEsb.getBuffAddr(), timeEsb.getBuffLength());
|
||||
this->m_runtime.stackSize += static_cast<Fpy::StackSizeType>(timeEsb.getBuffLength());
|
||||
return Signal::stmtResponse_success;
|
||||
}
|
||||
} // namespace Svc
|
||||
|
||||
@ -113,6 +113,11 @@ struct StackCmdDirective {
|
||||
argsSize: Fpy.StackSizeType
|
||||
}
|
||||
|
||||
@ pushes the current Fw.Time struct to the stack
|
||||
struct PushTimeDirective {
|
||||
_empty: U8
|
||||
}
|
||||
|
||||
internal port directive_waitRel(directive: WaitRelDirective) priority 6 assert
|
||||
|
||||
internal port directive_waitAbs(directive: WaitAbsDirective) priority 6 assert
|
||||
@ -149,6 +154,8 @@ internal port directive_memCmp(directive: MemCmpDirective) priority 6 assert
|
||||
|
||||
internal port directive_stackCmd(directive: StackCmdDirective) priority 6 assert
|
||||
|
||||
internal port directive_pushTime(directive: PushTimeDirective) priority 6 assert
|
||||
|
||||
enum DirectiveErrorCode {
|
||||
NO_ERROR
|
||||
STMT_OUT_OF_BOUNDS
|
||||
|
||||
@ -348,6 +348,16 @@ Fw::Success FpySequencer::deserializeDirective(const Fpy::Statement& stmt, Direc
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Fpy::DirectiveId::PUSH_TIME: {
|
||||
new (&deserializedDirective.pushTime) FpySequencer_PushTimeDirective();
|
||||
if (argBuf.getBuffLeft() != 0) {
|
||||
this->log_WARNING_HI_DirectiveDeserializeError(stmt.get_opCode(), this->currentStatementIdx(),
|
||||
Fw::SerializeStatus::FW_DESERIALIZE_SIZE_MISMATCH,
|
||||
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->currentStatementIdx(),
|
||||
@ -487,6 +497,10 @@ void FpySequencer::dispatchDirective(const DirectiveUnion& directive, const Fpy:
|
||||
this->directive_stackCmd_internalInterfaceInvoke(directive.stackCmd);
|
||||
return;
|
||||
}
|
||||
case Fpy::DirectiveId::PUSH_TIME: {
|
||||
this->directive_pushTime_internalInterfaceInvoke(directive.pushTime);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// coding err
|
||||
FW_ASSERT(0, static_cast<FwAssertArgType>(id));
|
||||
|
||||
@ -94,6 +94,7 @@ module Svc {
|
||||
MEMCMP = 65
|
||||
STACK_CMD = 66
|
||||
PUSH_TLM_VAL_AND_TIME = 67
|
||||
PUSH_TIME = 68
|
||||
}
|
||||
|
||||
struct Header {
|
||||
|
||||
@ -95,4 +95,5 @@ The FpySequencer has a set of debugging commands which can be used to pause and
|
||||
| 64 | DISCARD | Discards bytes from the top of the stack |
|
||||
| 65 | MEMCMP | Compares two memory regions on the stack |
|
||||
| 66 | STACK_CMD | Dispatches a command with arguments from the stack |
|
||||
| 67 | PUSH_TLM_VAL_AND_TIME | Gets a telemetry channel and pushes its value, and then its time, onto the stack |
|
||||
| 67 | PUSH_TLM_VAL_AND_TIME | Gets a telemetry channel and pushes its value, and then its time, onto the stack |
|
||||
| 68 | PUSH_TIME | Pushes the current time, from the `timeCaller` port, to the stack |
|
||||
@ -996,6 +996,39 @@ TEST_F(FpySequencerTester, memCmp) {
|
||||
ASSERT_EQ(err, DirectiveError::STACK_ACCESS_OUT_OF_BOUNDS);
|
||||
}
|
||||
|
||||
TEST_F(FpySequencerTester, pushTime) {
|
||||
FpySequencer_PushTimeDirective directive;
|
||||
DirectiveError err = DirectiveError::NO_ERROR;
|
||||
Fw::Time testTime(TimeBase::TB_WORKSTATION_TIME, 0, 100, 100);
|
||||
setTestTime(testTime);
|
||||
tester_get_m_runtime_ptr()->stackSize = 0;
|
||||
Signal result = tester_pushTime_directiveHandler(directive, err);
|
||||
ASSERT_EQ(tester_get_m_runtime_ptr()->stackSize, Fw::Time::SERIALIZED_SIZE);
|
||||
ASSERT_EQ(result, Signal::stmtResponse_success);
|
||||
ASSERT_EQ(err, DirectiveError::NO_ERROR);
|
||||
|
||||
// make sure deser'd time is same as input time
|
||||
Fw::Time deserTime;
|
||||
Fw::ExternalSerializeBuffer esb(tester_get_m_runtime_ptr()->stack, Fw::Time::SERIALIZED_SIZE);
|
||||
esb.setBuffLen(Fw::Time::SERIALIZED_SIZE);
|
||||
ASSERT_EQ(esb.deserializeTo(deserTime), Fw::SerializeStatus::FW_SERIALIZE_OK);
|
||||
ASSERT_EQ(deserTime, testTime);
|
||||
clearHistory();
|
||||
|
||||
// check almost overflow
|
||||
tester_get_m_runtime_ptr()->stackSize = Fpy::MAX_STACK_SIZE - Fw::Time::SERIALIZED_SIZE;
|
||||
result = tester_pushTime_directiveHandler(directive, err);
|
||||
ASSERT_EQ(result, Signal::stmtResponse_success);
|
||||
ASSERT_EQ(tester_get_m_runtime_ptr()->stackSize, Fpy::MAX_STACK_SIZE);
|
||||
ASSERT_EQ(err, DirectiveError::NO_ERROR);
|
||||
|
||||
// check overflow
|
||||
tester_get_m_runtime_ptr()->stackSize = Fpy::MAX_STACK_SIZE - Fw::Time::SERIALIZED_SIZE + 1;
|
||||
result = tester_pushTime_directiveHandler(directive, err);
|
||||
ASSERT_EQ(result, Signal::stmtResponse_failure);
|
||||
ASSERT_EQ(err, DirectiveError::STACK_OVERFLOW);
|
||||
}
|
||||
|
||||
TEST_F(FpySequencerTester, checkShouldWakeMismatchBase) {
|
||||
Fw::Time testTime(TimeBase::TB_WORKSTATION_TIME, 0, 100, 100);
|
||||
setTestTime(testTime);
|
||||
|
||||
@ -276,6 +276,10 @@ void FpySequencerTester::add_MEMCMP(FpySequencer_MemCmpDirective dir) {
|
||||
FW_ASSERT(buf.serializeFrom(dir) == Fw::SerializeStatus::FW_SERIALIZE_OK);
|
||||
addDirective(Fpy::DirectiveId::MEMCMP, buf);
|
||||
}
|
||||
void FpySequencerTester::add_PUSH_TIME() {
|
||||
Fw::StatementArgBuffer buf;
|
||||
addDirective(Fpy::DirectiveId::PUSH_TIME, buf);
|
||||
}
|
||||
//! Handle a text event
|
||||
void FpySequencerTester::textLogIn(FwEventIdType id, //!< The event ID
|
||||
const Fw::Time& timeTag, //!< The time
|
||||
@ -406,6 +410,11 @@ Fw::Success FpySequencerTester::tester_deserializeDirective(const Fpy::Statement
|
||||
return this->cmp.deserializeDirective(stmt, deserializedDirective);
|
||||
}
|
||||
|
||||
Signal FpySequencerTester::tester_pushTime_directiveHandler(const FpySequencer_PushTimeDirective& directive,
|
||||
DirectiveError& err) {
|
||||
return this->cmp.pushTime_directiveHandler(directive, err);
|
||||
}
|
||||
|
||||
Svc::Signal FpySequencerTester::tester_dispatchStatement() {
|
||||
return this->cmp.dispatchStatement();
|
||||
}
|
||||
|
||||
@ -111,6 +111,7 @@ class FpySequencerTester : public FpySequencerGTestBase, public ::testing::Test
|
||||
void add_STACK_CMD(FpySequencer_StackCmdDirective dir);
|
||||
void add_MEMCMP(Fpy::StackSizeType size);
|
||||
void add_MEMCMP(FpySequencer_MemCmpDirective dir);
|
||||
void add_PUSH_TIME();
|
||||
template <typename T>
|
||||
void add_PUSH_VAL(T val);
|
||||
//! Handle a text event
|
||||
@ -153,6 +154,7 @@ class FpySequencerTester : public FpySequencerGTestBase, public ::testing::Test
|
||||
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);
|
||||
Signal tester_pushTime_directiveHandler(const FpySequencer_PushTimeDirective& directive, DirectiveError& err);
|
||||
DirectiveError tester_op_or();
|
||||
DirectiveError tester_op_and();
|
||||
DirectiveError tester_op_ieq();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user