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_DiscardDirective discard;
|
||||||
FpySequencer_MemCmpDirective memCmp;
|
FpySequencer_MemCmpDirective memCmp;
|
||||||
FpySequencer_StackCmdDirective stackCmd;
|
FpySequencer_StackCmdDirective stackCmd;
|
||||||
|
FpySequencer_PushTimeDirective pushTime;
|
||||||
|
|
||||||
DirectiveUnion() {}
|
DirectiveUnion() {}
|
||||||
~DirectiveUnion() {}
|
~DirectiveUnion() {}
|
||||||
@ -473,6 +474,9 @@ class FpySequencer : public FpySequencerComponentBase {
|
|||||||
//! Internal interface handler for directive_stackCmd
|
//! Internal interface handler for directive_stackCmd
|
||||||
void directive_stackCmd_internalInterfaceHandler(const Svc::FpySequencer_StackCmdDirective& directive) override;
|
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 parametersLoaded() override;
|
||||||
void parameterUpdated(FwPrmIdType id) override;
|
void parameterUpdated(FwPrmIdType id) override;
|
||||||
|
|
||||||
@ -747,6 +751,7 @@ class FpySequencer : public FpySequencerComponentBase {
|
|||||||
Signal discard_directiveHandler(const FpySequencer_DiscardDirective& directive, DirectiveError& error);
|
Signal discard_directiveHandler(const FpySequencer_DiscardDirective& directive, DirectiveError& error);
|
||||||
Signal memCmp_directiveHandler(const FpySequencer_MemCmpDirective& directive, DirectiveError& error);
|
Signal memCmp_directiveHandler(const FpySequencer_MemCmpDirective& directive, DirectiveError& error);
|
||||||
Signal stackCmd_directiveHandler(const FpySequencer_StackCmdDirective& directive, DirectiveError& error);
|
Signal stackCmd_directiveHandler(const FpySequencer_StackCmdDirective& directive, DirectiveError& error);
|
||||||
|
Signal pushTime_directiveHandler(const FpySequencer_PushTimeDirective& directive, DirectiveError& error);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Svc
|
} // namespace Svc
|
||||||
|
|||||||
@ -322,6 +322,13 @@ void FpySequencer::directive_stackCmd_internalInterfaceHandler(const Svc::FpySeq
|
|||||||
handleDirectiveErrorCode(Fpy::DirectiveId::STACK_CMD, error);
|
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
|
//! Internal interface handler for directive_waitRel
|
||||||
Signal FpySequencer::waitRel_directiveHandler(const FpySequencer_WaitRelDirective& directive, DirectiveError& error) {
|
Signal FpySequencer::waitRel_directiveHandler(const FpySequencer_WaitRelDirective& directive, DirectiveError& error) {
|
||||||
if (this->m_runtime.stackSize < 8) {
|
if (this->m_runtime.stackSize < 8) {
|
||||||
@ -443,7 +450,7 @@ Signal FpySequencer::pushTlmValAndTime_directiveHandler(const FpySequencer_PushT
|
|||||||
return Signal::stmtResponse_failure;
|
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::ExternalSerializeBuffer timeEsb(tlmTimeBuf, Fw::Time::SERIALIZED_SIZE);
|
||||||
Fw::SerializeStatus stat = timeEsb.serializeFrom(tlmTime);
|
Fw::SerializeStatus stat = timeEsb.serializeFrom(tlmTime);
|
||||||
|
|
||||||
@ -1240,4 +1247,25 @@ Signal FpySequencer::stackCmd_directiveHandler(const FpySequencer_StackCmdDirect
|
|||||||
|
|
||||||
return Signal::stmtResponse_success;
|
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
|
} // namespace Svc
|
||||||
|
|||||||
@ -113,6 +113,11 @@ struct StackCmdDirective {
|
|||||||
argsSize: Fpy.StackSizeType
|
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_waitRel(directive: WaitRelDirective) priority 6 assert
|
||||||
|
|
||||||
internal port directive_waitAbs(directive: WaitAbsDirective) 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_stackCmd(directive: StackCmdDirective) priority 6 assert
|
||||||
|
|
||||||
|
internal port directive_pushTime(directive: PushTimeDirective) priority 6 assert
|
||||||
|
|
||||||
enum DirectiveErrorCode {
|
enum DirectiveErrorCode {
|
||||||
NO_ERROR
|
NO_ERROR
|
||||||
STMT_OUT_OF_BOUNDS
|
STMT_OUT_OF_BOUNDS
|
||||||
|
|||||||
@ -348,6 +348,16 @@ Fw::Success FpySequencer::deserializeDirective(const Fpy::Statement& stmt, Direc
|
|||||||
}
|
}
|
||||||
break;
|
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: {
|
default: {
|
||||||
// unsure what this opcode is. check compiler version matches sequencer
|
// unsure what this opcode is. check compiler version matches sequencer
|
||||||
this->log_WARNING_HI_UnknownSequencerDirective(stmt.get_opCode(), this->currentStatementIdx(),
|
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);
|
this->directive_stackCmd_internalInterfaceInvoke(directive.stackCmd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
case Fpy::DirectiveId::PUSH_TIME: {
|
||||||
|
this->directive_pushTime_internalInterfaceInvoke(directive.pushTime);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// coding err
|
// coding err
|
||||||
FW_ASSERT(0, static_cast<FwAssertArgType>(id));
|
FW_ASSERT(0, static_cast<FwAssertArgType>(id));
|
||||||
|
|||||||
@ -94,6 +94,7 @@ module Svc {
|
|||||||
MEMCMP = 65
|
MEMCMP = 65
|
||||||
STACK_CMD = 66
|
STACK_CMD = 66
|
||||||
PUSH_TLM_VAL_AND_TIME = 67
|
PUSH_TLM_VAL_AND_TIME = 67
|
||||||
|
PUSH_TIME = 68
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Header {
|
struct Header {
|
||||||
|
|||||||
@ -96,3 +96,4 @@ The FpySequencer has a set of debugging commands which can be used to pause and
|
|||||||
| 65 | MEMCMP | Compares two memory regions on the stack |
|
| 65 | MEMCMP | Compares two memory regions on the stack |
|
||||||
| 66 | STACK_CMD | Dispatches a command with arguments from 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);
|
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) {
|
TEST_F(FpySequencerTester, checkShouldWakeMismatchBase) {
|
||||||
Fw::Time testTime(TimeBase::TB_WORKSTATION_TIME, 0, 100, 100);
|
Fw::Time testTime(TimeBase::TB_WORKSTATION_TIME, 0, 100, 100);
|
||||||
setTestTime(testTime);
|
setTestTime(testTime);
|
||||||
|
|||||||
@ -276,6 +276,10 @@ void FpySequencerTester::add_MEMCMP(FpySequencer_MemCmpDirective dir) {
|
|||||||
FW_ASSERT(buf.serializeFrom(dir) == Fw::SerializeStatus::FW_SERIALIZE_OK);
|
FW_ASSERT(buf.serializeFrom(dir) == Fw::SerializeStatus::FW_SERIALIZE_OK);
|
||||||
addDirective(Fpy::DirectiveId::MEMCMP, buf);
|
addDirective(Fpy::DirectiveId::MEMCMP, buf);
|
||||||
}
|
}
|
||||||
|
void FpySequencerTester::add_PUSH_TIME() {
|
||||||
|
Fw::StatementArgBuffer buf;
|
||||||
|
addDirective(Fpy::DirectiveId::PUSH_TIME, buf);
|
||||||
|
}
|
||||||
//! Handle a text event
|
//! Handle a text event
|
||||||
void FpySequencerTester::textLogIn(FwEventIdType id, //!< The event ID
|
void FpySequencerTester::textLogIn(FwEventIdType id, //!< The event ID
|
||||||
const Fw::Time& timeTag, //!< The time
|
const Fw::Time& timeTag, //!< The time
|
||||||
@ -406,6 +410,11 @@ Fw::Success FpySequencerTester::tester_deserializeDirective(const Fpy::Statement
|
|||||||
return this->cmp.deserializeDirective(stmt, deserializedDirective);
|
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() {
|
Svc::Signal FpySequencerTester::tester_dispatchStatement() {
|
||||||
return this->cmp.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_STACK_CMD(FpySequencer_StackCmdDirective dir);
|
||||||
void add_MEMCMP(Fpy::StackSizeType size);
|
void add_MEMCMP(Fpy::StackSizeType size);
|
||||||
void add_MEMCMP(FpySequencer_MemCmpDirective dir);
|
void add_MEMCMP(FpySequencer_MemCmpDirective dir);
|
||||||
|
void add_PUSH_TIME();
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void add_PUSH_VAL(T val);
|
void add_PUSH_VAL(T val);
|
||||||
//! Handle a text event
|
//! 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_discard_directiveHandler(const FpySequencer_DiscardDirective& directive, DirectiveError& err);
|
||||||
Signal tester_stackCmd_directiveHandler(const FpySequencer_StackCmdDirective& 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_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_or();
|
||||||
DirectiveError tester_op_and();
|
DirectiveError tester_op_and();
|
||||||
DirectiveError tester_op_ieq();
|
DirectiveError tester_op_ieq();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user