mirror of
https://github.com/nasa/fprime.git
synced 2025-12-10 00:44:37 -06:00
* Created new SerialBufferBase as a parent of SerializeBufferBase. Renaming interface functions to be less confusing. * Deprecating copyRawOffset. No direct use-cases in F' core. * Make SerialBufferBase a true pure virtual interface. * Changing Serializable to work with SerialBufferBase parent interface. * Changing copyRaw and copyRawOffset to work with SerialBufferBase * Updating documentation for SerialBufferBase usage * Adding some documentation. Adding missing ASSERT in copyRaw. Fixing some bugs that new ASSERT uncovered. * Renaming SerializeBufferBase to LinearBufferBase. Add a using declaration to maintain backwards compatability. Properly mark LinearBufferBase functions as override. * Filling in the rest of the docstrings for the classes in Serializable * Removing redundant virtual keyword on override function * Applying clang formatting * Incorporating PR comments * Fix compile issues * Bump version to alpha * Format * v --------- Co-authored-by: M Starch <LeStarch@googlemail.com>
129 lines
5.0 KiB
C++
129 lines
5.0 KiB
C++
#include <Fw/Comp/ActiveComponentBase.hpp>
|
|
#include <Fw/FPrimeBasicTypes.hpp>
|
|
#include <Fw/Types/Assert.hpp>
|
|
#include <Os/TaskString.hpp>
|
|
|
|
namespace Fw {
|
|
|
|
class ActiveComponentExitSerializableBuffer : public Fw::SerializeBufferBase {
|
|
public:
|
|
DEPRECATED(FwSizeType getBuffCapacity() const, "Use getCapacity() instead");
|
|
FwSizeType getCapacity() const { return sizeof(m_buff); }
|
|
|
|
U8* getBuffAddr() { return m_buff; }
|
|
|
|
const U8* getBuffAddr() const { return m_buff; }
|
|
|
|
private:
|
|
U8 m_buff[sizeof(ActiveComponentBase::ACTIVE_COMPONENT_EXIT)];
|
|
};
|
|
|
|
ActiveComponentBase::ActiveComponentBase(const char* name) : QueuedComponentBase(name) {}
|
|
|
|
ActiveComponentBase::~ActiveComponentBase() {}
|
|
|
|
void ActiveComponentBase::init(FwEnumStoreType instance) {
|
|
QueuedComponentBase::init(instance);
|
|
}
|
|
|
|
#if FW_OBJECT_TO_STRING == 1
|
|
const char* ActiveComponentBase::getToStringFormatString() {
|
|
return "ActComp: %s";
|
|
}
|
|
#endif
|
|
|
|
void ActiveComponentBase::start(FwTaskPriorityType priority,
|
|
FwSizeType stackSize,
|
|
FwSizeType cpuAffinity,
|
|
FwTaskIdType identifier) {
|
|
Os::TaskString taskName;
|
|
|
|
#if FW_OBJECT_NAMES == 1
|
|
taskName = this->getObjName();
|
|
#else
|
|
(void)taskName.format("ActComp_%" PRI_FwSizeType, Os::Task::getNumTasks());
|
|
#endif
|
|
// Cooperative threads tasks externalize the task loop, and as such use the state machine as their task function
|
|
// Standard multithreading tasks use the task loop to respectively call the state machine
|
|
Os::Task::taskRoutine routine = (m_task.isCooperative()) ? this->s_taskStateMachine : this->s_taskLoop;
|
|
Os::Task::Arguments arguments(taskName, routine, this, priority, stackSize, cpuAffinity, identifier);
|
|
Os::Task::Status status = this->m_task.start(arguments);
|
|
FW_ASSERT(status == Os::Task::Status::OP_OK, static_cast<FwAssertArgType>(status));
|
|
}
|
|
|
|
void ActiveComponentBase::exit() {
|
|
ActiveComponentExitSerializableBuffer exitBuff;
|
|
SerializeStatus stat = exitBuff.serializeFrom(static_cast<I32>(ACTIVE_COMPONENT_EXIT));
|
|
FW_ASSERT(FW_SERIALIZE_OK == stat, static_cast<FwAssertArgType>(stat));
|
|
(void)this->m_queue.send(exitBuff, 0, Os::Queue::BlockingType::NONBLOCKING);
|
|
}
|
|
|
|
Os::Task::Status ActiveComponentBase::join() {
|
|
return this->m_task.join();
|
|
}
|
|
|
|
Os::Task::Status ActiveComponentBase::join(void** pointer) {
|
|
return this->m_task.join();
|
|
}
|
|
|
|
void ActiveComponentBase::s_taskStateMachine(void* component_pointer) {
|
|
FW_ASSERT(component_pointer != nullptr);
|
|
// cast void* back to active component
|
|
ActiveComponentBase* component = static_cast<ActiveComponentBase*>(component_pointer);
|
|
|
|
// Each invocation of this function runs a single stage of the thread lifecycle. This has moved the thread
|
|
// while loop to the top level such that it can be replaced by something else (e.g. cooperative thread
|
|
// dispatcher) and is not intrinsic to this code.
|
|
switch (component->m_stage) {
|
|
// The first stage the active component triggers the "preamble" call before moving into the dispatching
|
|
// stage of the component thread.
|
|
case Lifecycle::CREATED:
|
|
component->preamble();
|
|
component->m_stage = Lifecycle::DISPATCHING;
|
|
break;
|
|
// The second stage of the active component triggers the dispatching loop dispatching messages until an
|
|
// exit message is received.
|
|
case Lifecycle::DISPATCHING:
|
|
if (component->dispatch() == MsgDispatchStatus::MSG_DISPATCH_EXIT) {
|
|
component->m_stage = Lifecycle::FINALIZING;
|
|
}
|
|
break;
|
|
// The second-to-last stage is where the finalizer is called. This will transition to the final stage
|
|
// automatically after the finalizer is called
|
|
case Lifecycle::FINALIZING:
|
|
component->finalizer();
|
|
component->m_stage = Lifecycle::DONE;
|
|
break;
|
|
// The last stage does nothing, cooperative tasks live here forever, threaded tasks exit on this condition
|
|
case Lifecycle::DONE:
|
|
break;
|
|
default:
|
|
FW_ASSERT(0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void ActiveComponentBase::s_taskLoop(void* component_pointer) {
|
|
FW_ASSERT(component_pointer != nullptr);
|
|
ActiveComponentBase* component = static_cast<ActiveComponentBase*>(component_pointer);
|
|
// A non-cooperative task switching implementation is just a while-loop around the active component
|
|
// state-machine. Here the while loop is at top-level.
|
|
while (component->m_stage != ActiveComponentBase::Lifecycle::DONE) {
|
|
ActiveComponentBase::s_taskStateMachine(component);
|
|
}
|
|
}
|
|
|
|
ActiveComponentBase::MsgDispatchStatus ActiveComponentBase::dispatch() {
|
|
// Cooperative tasks should return rather than block when no messages are available
|
|
if (this->m_task.isCooperative() and m_queue.getMessagesAvailable() == 0) {
|
|
return MsgDispatchStatus::MSG_DISPATCH_EMPTY;
|
|
}
|
|
return this->doDispatch();
|
|
}
|
|
|
|
void ActiveComponentBase::preamble() {}
|
|
|
|
void ActiveComponentBase::finalizer() {}
|
|
|
|
} // namespace Fw
|