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