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:
10  DEPRECATED(FwSizeType getBuffCapacity() const, "Use getCapacity() instead");
11  FwSizeType getCapacity() const { return sizeof(m_buff); }
12 
13  U8* getBuffAddr() { return m_buff; }
14 
15  const U8* getBuffAddr() const { return m_buff; }
16 
17  private:
19 };
20 
22 
24 
26  QueuedComponentBase::init(instance);
27 }
28 
29 #if FW_OBJECT_TO_STRING == 1
30 const char* ActiveComponentBase::getToStringFormatString() {
31  return "ActComp: %s";
32 }
33 #endif
34 
36  FwSizeType stackSize,
37  FwSizeType cpuAffinity,
38  FwTaskIdType identifier) {
39  Os::TaskString taskName;
40 
41 #if FW_OBJECT_NAMES == 1
42  taskName = this->getObjName();
43 #else
44  (void)taskName.format("ActComp_%" PRI_FwSizeType, Os::Task::getNumTasks());
45 #endif
46  // Cooperative threads tasks externalize the task loop, and as such use the state machine as their task function
47  // Standard multithreading tasks use the task loop to respectively call the state machine
48  Os::Task::taskRoutine routine = (m_task.isCooperative()) ? this->s_taskStateMachine : this->s_taskLoop;
49  Os::Task::Arguments arguments(taskName, routine, this, priority, stackSize, cpuAffinity, identifier);
50  Os::Task::Status status = this->m_task.start(arguments);
51  FW_ASSERT(status == Os::Task::Status::OP_OK, static_cast<FwAssertArgType>(status));
52 }
53 
56  SerializeStatus stat = exitBuff.serializeFrom(static_cast<I32>(ACTIVE_COMPONENT_EXIT));
57  FW_ASSERT(FW_SERIALIZE_OK == stat, static_cast<FwAssertArgType>(stat));
58  (void)this->m_queue.send(exitBuff, 0, Os::Queue::BlockingType::NONBLOCKING);
59 }
60 
62  return this->m_task.join();
63 }
64 
66  return this->m_task.join();
67 }
68 
69 void ActiveComponentBase::s_taskStateMachine(void* component_pointer) {
70  FW_ASSERT(component_pointer != nullptr);
71  // cast void* back to active component
72  ActiveComponentBase* component = static_cast<ActiveComponentBase*>(component_pointer);
73 
74  // Each invocation of this function runs a single stage of the thread lifecycle. This has moved the thread
75  // while loop to the top level such that it can be replaced by something else (e.g. cooperative thread
76  // dispatcher) and is not intrinsic to this code.
77  switch (component->m_stage) {
78  // The first stage the active component triggers the "preamble" call before moving into the dispatching
79  // stage of the component thread.
80  case Lifecycle::CREATED:
81  component->preamble();
82  component->m_stage = Lifecycle::DISPATCHING;
83  break;
84  // The second stage of the active component triggers the dispatching loop dispatching messages until an
85  // exit message is received.
86  case Lifecycle::DISPATCHING:
87  if (component->dispatch() == MsgDispatchStatus::MSG_DISPATCH_EXIT) {
88  component->m_stage = Lifecycle::FINALIZING;
89  }
90  break;
91  // The second-to-last stage is where the finalizer is called. This will transition to the final stage
92  // automatically after the finalizer is called
93  case Lifecycle::FINALIZING:
94  component->finalizer();
95  component->m_stage = Lifecycle::DONE;
96  break;
97  // The last stage does nothing, cooperative tasks live here forever, threaded tasks exit on this condition
98  case Lifecycle::DONE:
99  break;
100  default:
101  FW_ASSERT(0);
102  break;
103  }
104 }
105 
106 void ActiveComponentBase::s_taskLoop(void* component_pointer) {
107  FW_ASSERT(component_pointer != nullptr);
108  ActiveComponentBase* component = static_cast<ActiveComponentBase*>(component_pointer);
109  // A non-cooperative task switching implementation is just a while-loop around the active component
110  // state-machine. Here the while loop is at top-level.
111  while (component->m_stage != ActiveComponentBase::Lifecycle::DONE) {
112  ActiveComponentBase::s_taskStateMachine(component);
113  }
114 }
115 
117  // Cooperative tasks should return rather than block when no messages are available
118  if (this->m_task.isCooperative() and m_queue.getMessagesAvailable() == 0) {
119  return MsgDispatchStatus::MSG_DISPATCH_EMPTY;
120  }
121  return this->doDispatch();
122 }
123 
125 
127 
128 } // namespace Fw
Serialization/Deserialization operation was successful.
PlatformTaskIdType FwTaskIdType
The type of task priorities used.
Operation succeeded.
Definition: Os.hpp:26
SerializeStatus serializeFrom(U8 val, Endianness mode=Endianness::BIG) override
Serialize an 8-bit unsigned integer value.
Os::Task m_task
task object for active component
PlatformSizeType FwSizeType
I32 FwEnumStoreType
#define PRI_FwSizeType
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.
FwSizeType getCapacity() const
Get buffer capacity.
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
DEPRECATED(FwSizeType getBuffCapacity() const, "Use getCapacity() instead")
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:46
FormatStatus format(const CHAR *formatString,...)
write formatted string to buffer
Definition: StringBase.cpp:39
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:53
FwSizeType getMessagesAvailable() const override
get number of messages available
Definition: Queue.cpp:81
MsgDispatchStatus dispatch()
The function that will dispatching messages.
virtual ~ActiveComponentBase()
Destructor.
Os::Task::Status join()
Join the thread.
U8 * getBuffAddr()
Get buffer address for data filling (non-const version)
message to exit active component task
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.
const U8 * getBuffAddr() const
Get buffer address for data reading (const version)
void(* taskRoutine)(void *ptr)
Prototype for task routine started in task context.
Definition: Task.hpp:69
#define FW_ASSERT(...)
Definition: Assert.hpp:14