F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
ActiveComponentBase.cpp
Go to the documentation of this file.
3 #include <Fw/Types/Assert.hpp>
4 #include <Os/TaskString.hpp>
5 
6 namespace Fw {
7 
9  public:
11 
12  private:
14 };
15 
16 ActiveComponentBase::ActiveComponentBase(const char* name) : QueuedComponentBase(name), m_stage(Lifecycle::CREATED) {}
17 
19 
21  QueuedComponentBase::init(instance);
22 }
23 
24 #if FW_OBJECT_TO_STRING == 1
25 const char* ActiveComponentBase::getToStringFormatString() {
26  return "ActComp: %s";
27 }
28 #endif
29 
31  FwSizeType stackSize,
32  FwSizeType cpuAffinity,
33  FwTaskIdType identifier) {
34  Os::TaskString taskName;
35 
36 #if FW_OBJECT_NAMES == 1
37  taskName = this->getObjName();
38 #else
39  (void)taskName.format("ActComp_%" PRI_FwSizeType, Os::Task::getNumTasks());
40 #endif
41  // Cooperative threads tasks externalize the task loop, and as such use the state machine as their task function
42  // Standard multithreading tasks use the task loop to respectively call the state machine
43  Os::Task::taskRoutine routine = (m_task.isCooperative()) ? this->s_taskStateMachine : this->s_taskLoop;
44  Os::Task::Arguments arguments(taskName, routine, this, priority, stackSize, cpuAffinity, identifier);
45  Os::Task::Status status = this->m_task.start(arguments);
46  FW_ASSERT(status == Os::Task::Status::OP_OK, static_cast<FwAssertArgType>(status));
47 }
48 
51  SerializeStatus stat = exitBuff.serializeFrom(static_cast<I32>(ACTIVE_COMPONENT_EXIT));
52  FW_ASSERT(FW_SERIALIZE_OK == stat, static_cast<FwAssertArgType>(stat));
53  (void)this->m_queue.send(exitBuff, 0, Os::Queue::BlockingType::NONBLOCKING);
54 }
55 
57  return this->m_task.join();
58 }
59 
61  return this->m_task.join();
62 }
63 
64 void ActiveComponentBase::s_taskStateMachine(void* component_pointer) {
65  FW_ASSERT(component_pointer != nullptr);
66  // cast void* back to active component
67  ActiveComponentBase* component = static_cast<ActiveComponentBase*>(component_pointer);
68 
69  // Each invocation of this function runs a single stage of the thread lifecycle. This has moved the thread
70  // while loop to the top level such that it can be replaced by something else (e.g. cooperative thread
71  // dispatcher) and is not intrinsic to this code.
72  switch (component->m_stage) {
73  // The first stage the active component triggers the "preamble" call before moving into the dispatching
74  // stage of the component thread.
75  case Lifecycle::CREATED:
76  component->preamble();
77  component->m_stage = Lifecycle::DISPATCHING;
78  break;
79  // The second stage of the active component triggers the dispatching loop dispatching messages until an
80  // exit message is received.
81  case Lifecycle::DISPATCHING:
82  if (component->dispatch() == MsgDispatchStatus::MSG_DISPATCH_EXIT) {
83  component->m_stage = Lifecycle::FINALIZING;
84  }
85  break;
86  // The second-to-last stage is where the finalizer is called. This will transition to the final stage
87  // automatically after the finalizer is called
88  case Lifecycle::FINALIZING:
89  component->finalizer();
90  component->m_stage = Lifecycle::DONE;
91  break;
92  // The last stage does nothing, cooperative tasks live here forever, threaded tasks exit on this condition
93  case Lifecycle::DONE:
94  break;
95  default:
96  FW_ASSERT(false);
97  break;
98  }
99 }
100 
101 void ActiveComponentBase::s_taskLoop(void* component_pointer) {
102  FW_ASSERT(component_pointer != nullptr);
103  ActiveComponentBase* component = static_cast<ActiveComponentBase*>(component_pointer);
104  // A non-cooperative task switching implementation is just a while-loop around the active component
105  // state-machine. Here the while loop is at top-level.
106  // @non-terminating@: component lifecycle loop runs until DONE
107  while (component->m_stage != ActiveComponentBase::Lifecycle::DONE) {
108  ActiveComponentBase::s_taskStateMachine(component);
109  }
110 }
111 
113  // Cooperative tasks should return rather than block when no messages are available
114  if (this->m_task.isCooperative() and m_queue.getMessagesAvailable() == 0) {
115  return MsgDispatchStatus::MSG_DISPATCH_EMPTY;
116  }
117  return this->doDispatch();
118 }
119 
121 
123 
124 } // namespace Fw
Serialization/Deserialization operation was successful.
PlatformTaskIdType FwTaskIdType
The type of task priorities used.
Lifecycle
Tracks the lifecycle of the component.
Operation succeeded.
Definition: Os.hpp:27
Os::Task m_task
task object for active component
PlatformSizeType FwSizeType
I32 FwEnumStoreType
#define PRI_FwSizeType
message to exit active component task
Status start(const Arguments &arguments) override
start the task
Definition: Task.cpp:84
void exit()
exit task in active component
virtual MsgDispatchStatus doDispatch()=0
method to dispatch a single message in the queue.
SerializeStatus serializeFrom(U8 val, Endianness mode=Endianness::BIG) override
Serialize an 8-bit unsigned integer value.
Os::Queue m_queue
queue object for active component
void init()
Object initializer.
Definition: ObjBase.cpp:24
SerializeStatus
forward declaration for string
bool isCooperative() override
determine if the task is cooperative multitasking (implementation specific)
Definition: Task.cpp:172
virtual void finalizer()
A function that will be called after exiting the loop.
ActiveComponentBase(const char *name)
Constructor.
Status join() override
block until the task has ended
Definition: Task.cpp:141
static FwSizeType getNumTasks()
get the current number of tasks
Definition: Task.cpp:192
Status send(const U8 *buffer, FwSizeType size, FwQueuePriorityType priority, BlockingType blockType) override
send a message into the queue through delegate
Definition: Queue.cpp:54
FormatStatus format(const CHAR *formatString,...)
write formatted string to buffer
Definition: StringBase.cpp:58
PlatformTaskPriorityType FwTaskPriorityType
The type of task priorities used.
virtual void preamble()
A function that will be called before the event loop is entered.
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.h:54
FwSizeType getMessagesAvailable() const override
get number of messages available
Definition: Queue.cpp:89
MsgDispatchStatus dispatch()
The function that will dispatching messages.
virtual ~ActiveComponentBase()
Destructor.
Os::Task::Status join()
Join the thread.
void start(FwTaskPriorityType priority=Os::Task::TASK_PRIORITY_DEFAULT, FwSizeType stackSize=Os::Task::TASK_DEFAULT, FwSizeType cpuAffinity=Os::Task::TASK_DEFAULT, FwTaskIdType identifier=static_cast< FwTaskIdType >(Os::Task::TASK_DEFAULT))
called by instantiator when task is to be started
Implementation of malloc based allocator.
void(* taskRoutine)(void *ptr)
Prototype for task routine started in task context.
Definition: Task.hpp:70
#define FW_ASSERT(...)
Definition: Assert.hpp:14