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.
1 #include <FpConfig.hpp>
3 #include <Fw/Types/Assert.hpp>
4 #include <Os/TaskString.hpp>
5 
6 namespace Fw {
7 
9 
10  public:
12  return sizeof(m_buff);
13  }
14 
16  return m_buff;
17  }
18 
19  const U8* getBuffAddr() const {
20  return m_buff;
21  }
22 
23  private:
24 
26 
27  };
28 
30 
31  }
32 
34  }
35 
37  QueuedComponentBase::init(instance);
38  }
39 
40 #if FW_OBJECT_TO_STRING == 1
41  const char* ActiveComponentBase::getToStringFormatString() {
42  return "ActComp: %s";
43  }
44 #endif
45 
47  Os::TaskString taskName;
48 
49 #if FW_OBJECT_NAMES == 1
50  taskName = this->getObjName();
51 #else
52  (void) taskName.format("ActComp_%" PRI_FwSizeType, Os::Task::getNumTasks());
53 #endif
54  // Cooperative threads tasks externalize the task loop, and as such use the state machine as their task function
55  // Standard multithreading tasks use the task loop to respectively call the state machine
56  Os::Task::taskRoutine routine = (m_task.isCooperative()) ? this->s_taskStateMachine : this->s_taskLoop;
57  Os::Task::Arguments arguments(taskName, routine, this, priority, stackSize, cpuAffinity, static_cast<PlatformUIntType>(identifier));
58  Os::Task::Status status = this->m_task.start(arguments);
59  FW_ASSERT(status == Os::Task::Status::OP_OK,static_cast<FwAssertArgType>(status));
60  }
61 
64  SerializeStatus stat = exitBuff.serialize(static_cast<I32>(ACTIVE_COMPONENT_EXIT));
65  FW_ASSERT(FW_SERIALIZE_OK == stat,static_cast<FwAssertArgType>(stat));
66  (void)this->m_queue.send(exitBuff,0,Os::Queue::BlockingType::NONBLOCKING);
67  }
68 
70  return this->m_task.join();
71  }
72 
74  return this->m_task.join();
75  }
76 
77  void ActiveComponentBase::s_taskStateMachine(void* component_pointer) {
78  FW_ASSERT(component_pointer != nullptr);
79  // cast void* back to active component
80  ActiveComponentBase* component = static_cast<ActiveComponentBase*>(component_pointer);
81 
82  // Each invocation of this function runs a single stage of the thread lifecycle. This has moved the thread
83  // while loop to the top level such that it can be replaced by something else (e.g. cooperative thread
84  // dispatcher) and is not intrinsic to this code.
85  switch (component->m_stage) {
86  // The first stage the active component triggers the "preamble" call before moving into the dispatching
87  // stage of the component thread.
88  case Lifecycle::CREATED:
89  component->preamble();
90  component->m_stage = Lifecycle::DISPATCHING;
91  break;
92  // The second stage of the active component triggers the dispatching loop dispatching messages until an
93  // exit message is received.
94  case Lifecycle::DISPATCHING:
95  if (component->dispatch() == MsgDispatchStatus::MSG_DISPATCH_EXIT) {
96  component->m_stage = Lifecycle::FINALIZING;
97  }
98  break;
99  // The second-to-last stage is where the finalizer is called. This will transition to the final stage
100  // automatically after the finalizer is called
101  case Lifecycle::FINALIZING:
102  component->finalizer();
103  component->m_stage = Lifecycle::DONE;
104  break;
105  // The last stage does nothing, cooperative tasks live here forever, threaded tasks exit on this condition
106  case Lifecycle::DONE:
107  break;
108  default:
109  FW_ASSERT(0);
110  break;
111  }
112  }
113 
114  void ActiveComponentBase::s_taskLoop(void* component_pointer) {
115  FW_ASSERT(component_pointer != nullptr);
116  ActiveComponentBase* component = static_cast<ActiveComponentBase*>(component_pointer);
117  // A non-cooperative task switching implementation is just a while-loop around the active component
118  // state-machine. Here the while loop is at top-level.
119  while (component->m_stage != ActiveComponentBase::Lifecycle::DONE) {
120  ActiveComponentBase::s_taskStateMachine(component);
121  }
122  }
123 
125  // Cooperative tasks should return rather than block when no messages are available
126  if (this->m_task.isCooperative() and m_queue.getMessagesAvailable() == 0) {
127  return MsgDispatchStatus::MSG_DISPATCH_EMPTY;
128  }
129  return this->doDispatch();
130  }
131 
133  }
134 
136  }
137 
138 }
Serialization/Deserialization operation was successful.
Operation succeeded.
Definition: Os.hpp:26
Os::Task m_task
task object for active component
SerializeStatus serialize(U8 val)
serialize 8-bit unsigned int
PlatformSizeType FwSizeType
Definition: FpConfig.h:35
Status start(const Arguments &arguments) override
start the task
Definition: Task.cpp:82
void exit()
exit task in active component
virtual MsgDispatchStatus doDispatch()=0
method to dispatch a single message in the queue.
I32 FwEnumStoreType
Definition: FpConfig.h:64
Os::Queue m_queue
queue object for active component
void init()
Object initializer.
Definition: ObjBase.cpp:26
SerializeStatus
forward declaration for string
message to exit active component task
bool isCooperative() override
determine if the task is cooperative multitasking (implementation specific)
Definition: Task.cpp:164
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:134
static FwSizeType getNumTasks()
get the current number of tasks
Definition: Task.cpp:179
Status send(const U8 *buffer, FwSizeType size, FwQueuePriorityType priority, BlockingType blockType) override
send a message into the queue through delegate
FormatStatus format(const CHAR *formatString,...)
write formatted string to buffer
Definition: StringBase.cpp:55
C++-compatible configuration header for fprime configuration.
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:32
FwSizeType ParamType
backwards-compatible parameter type
Definition: Task.hpp:220
FwSizeType getMessagesAvailable() const override
get number of messages available
Definition: Queue.cpp:77
void start(Os::Task::ParamType priority=Os::Task::TASK_DEFAULT, Os::Task::ParamType stackSize=Os::Task::TASK_DEFAULT, Os::Task::ParamType cpuAffinity=Os::Task::TASK_DEFAULT, Os::Task::ParamType identifier=Os::Task::TASK_DEFAULT)
called by instantiator when task is to be started
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
#define PRI_FwSizeType
Definition: FpConfig.h:36
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:60
#define FW_ASSERT(...)
Definition: Assert.hpp:14