F´ Flight Software - C/C++ Documentation  devel
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 #include <cstdio>
6 
7 //#define DEBUG_PRINT(...) printf(##__VA_ARGS__); fflush(stdout)
8 #define DEBUG_PRINT(...)
9 
10 namespace Fw {
11 
13 
14  public:
16  return sizeof(m_buff);
17  }
18 
20  return m_buff;
21  }
22 
23  const U8* getBuffAddr() const {
24  return m_buff;
25  }
26 
27  private:
28 
30 
31  };
32 
34 
35  }
36 
38  DEBUG_PRINT("ActiveComponent %s destructor.\n",this->getObjName());
39  }
40 
42  QueuedComponentBase::init(instance);
43  }
44 
45 #if FW_OBJECT_TO_STRING == 1 && FW_OBJECT_NAMES == 1
46  void ActiveComponentBase::toString(char* buffer, NATIVE_INT_TYPE size) {
47  FW_ASSERT(size > 0);
48  if (snprintf(buffer, size, "ActComp: %s", this->m_objName) < 0) {
49  buffer[0] = 0;
50  }
51  }
52 #endif
53 
54  void ActiveComponentBase::start(NATIVE_INT_TYPE identifier, NATIVE_INT_TYPE priority, NATIVE_INT_TYPE stackSize, NATIVE_INT_TYPE cpuAffinity) {
55  this->start(static_cast<NATIVE_UINT_TYPE>(priority), static_cast<NATIVE_UINT_TYPE>(stackSize),
56  ((cpuAffinity == -1) ? Os::Task::TASK_DEFAULT : static_cast<NATIVE_UINT_TYPE>(cpuAffinity)),
57  static_cast<NATIVE_UINT_TYPE>(identifier));
58  }
59 
60  void ActiveComponentBase::start(NATIVE_UINT_TYPE priority, NATIVE_UINT_TYPE stackSize, NATIVE_UINT_TYPE cpuAffinity, NATIVE_UINT_TYPE identifier) {
61  Os::TaskString taskName;
62 
63 #if FW_OBJECT_NAMES == 1
64  taskName = this->getObjName();
65 #else
66  char taskNameChar[FW_TASK_NAME_MAX_SIZE];
67  (void)snprintf(taskNameChar,sizeof(taskNameChar),"ActComp_%d",Os::Task::getNumTasks());
68  taskName = taskNameChar;
69 #endif
70 // If running with the baremetal scheduler, use a variant of the task-loop that
71 // does not loop internal, but waits for an external iteration call.
72 #if FW_BAREMETAL_SCHEDULER == 1
73  Os::Task::taskRoutine routine = this->s_baseBareTask;
74 #else
75  Os::Task::taskRoutine routine = this->s_baseTask;
76 #endif
77  Os::Task::TaskStatus status = this->m_task.start(taskName, routine, this, priority, stackSize, cpuAffinity, identifier);
78  FW_ASSERT(status == Os::Task::TASK_OK,static_cast<NATIVE_INT_TYPE>(status));
79  }
80 
83  SerializeStatus stat = exitBuff.serialize(static_cast<I32>(ACTIVE_COMPONENT_EXIT));
84  FW_ASSERT(FW_SERIALIZE_OK == stat,static_cast<NATIVE_INT_TYPE>(stat));
85  (void)this->m_queue.send(exitBuff,0,Os::Queue::QUEUE_NONBLOCKING);
86  DEBUG_PRINT("exit %s\n", this->getObjName());
87  }
88 
90  DEBUG_PRINT("join %s\n", this->getObjName());
91  return this->m_task.join(value_ptr);
92  }
93 
94  void ActiveComponentBase::s_baseBareTask(void* ptr) {
95  FW_ASSERT(ptr != nullptr);
96  ActiveComponentBase* comp = reinterpret_cast<ActiveComponentBase*>(ptr);
97  //Start if not started
98  if (!comp->m_task.isStarted()) {
99  comp->m_task.setStarted(true);
100  comp->preamble();
101  }
102  //Bare components cannot block, so return to the scheduler
103  if (comp->m_queue.getNumMsgs() == 0) {
104  return;
105  }
107  switch (loopStatus) {
108  case ActiveComponentBase::MSG_DISPATCH_OK: // if normal message processing, continue
109  break;
111  comp->finalizer();
112  comp->m_task.setStarted(false);
113  break;
114  default:
115  FW_ASSERT(0,static_cast<NATIVE_INT_TYPE>(loopStatus));
116  }
117  }
118  void ActiveComponentBase::s_baseTask(void* ptr) {
119  // cast void* back to active component
120  ActiveComponentBase* comp = static_cast<ActiveComponentBase*> (ptr);
121  // indicated that task is started
122  comp->m_task.setStarted(true);
123  // print out message when task is started
124  // printf("Active Component %s task started.\n",comp->getObjName());
125  // call preamble
126  comp->preamble();
127  // call main task loop until exit or error
128  comp->loop();
129  // if main loop exits, call finalizer
130  comp->finalizer();
131  }
132 
134 
135  bool quitLoop = false;
136  while (!quitLoop) {
137  MsgDispatchStatus loopStatus = this->doDispatch();
138  switch (loopStatus) {
139  case MSG_DISPATCH_OK: // if normal message processing, continue
140  break;
141  case MSG_DISPATCH_EXIT:
142  quitLoop = true;
143  break;
144  default:
145  FW_ASSERT(0,static_cast<NATIVE_INT_TYPE>(loopStatus));
146  }
147  }
148 
149  }
150 
152  }
153 
155  }
156 
157 }
#define DEBUG_PRINT(...)
#define FW_ASSERT(...)
Definition: Assert.hpp:14
PlatformIntType NATIVE_INT_TYPE
Definition: BasicTypes.h:51
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.h:26
PlatformUIntType NATIVE_UINT_TYPE
Definition: BasicTypes.h:52
#define FW_TASK_NAME_MAX_SIZE
Max size of task name.
Definition: FpConfig.h:223
C++-compatible configuration header for fprime configuration.
@ ACTIVE_COMPONENT_EXIT
message to exit active component task
Os::Task m_task
task object for active component
ActiveComponentBase(const char *name)
Constructor.
void exit()
exit task in active component
virtual ~ActiveComponentBase()
Destructor.
void start(NATIVE_UINT_TYPE priority=Os::Task::TASK_DEFAULT, NATIVE_UINT_TYPE stackSize=Os::Task::TASK_DEFAULT, NATIVE_UINT_TYPE cpuAffinity=Os::Task::TASK_DEFAULT, NATIVE_UINT_TYPE identifier=Os::Task::TASK_DEFAULT)
called by instantiator when task is to be started
Os::Task::TaskStatus join(void **value_ptr)
provide return value of thread if value_ptr is not NULL
virtual void loop()
The function that will loop dispatching messages.
virtual void finalizer()
A function that will be called after exiting the loop.
virtual void preamble()
A function that will be called before the event loop is entered.
const U8 * getBuffAddr() const
gets buffer address for data reading, const version
NATIVE_UINT_TYPE getBuffCapacity() const
returns capacity, not current size, of buffer
U8 * getBuffAddr()
gets buffer address for data filling
void init()
Object initializer.
Definition: ObjBase.cpp:27
virtual MsgDispatchStatus doDispatch()=0
method to dispatch a single message in the queue.
Os::Queue m_queue
queue object for active component
@ MSG_DISPATCH_OK
Dispatch was normal.
@ MSG_DISPATCH_EXIT
A message was sent requesting an exit of the loop.
SerializeStatus serialize(U8 val)
serialize 8-bit unsigned int
QueueStatus send(const Fw::SerializeBufferBase &buffer, NATIVE_INT_TYPE priority, QueueBlocking block)
send a message
Definition: QueueCommon.cpp:13
@ QUEUE_NONBLOCKING
Queue receive always returns even if there is no message.
Definition: Queue.hpp:42
NATIVE_INT_TYPE getNumMsgs() const
get the number of messages in the queue
Definition: Queue.cpp:211
static const NATIVE_UINT_TYPE TASK_DEFAULT
Definition: Task.hpp:17
void(* taskRoutine)(void *ptr)
prototype for task routine started in task context
Definition: Task.hpp:30
TaskStatus join(void **value_ptr)
Wait for task to finish.
Definition: Task.cpp:74
TaskStatus
Definition: Task.hpp:18
@ TASK_OK
message sent/received okay
Definition: Task.hpp:19
bool isStarted()
check to see if task is started
Definition: TaskCommon.cpp:21
void setStarted(bool started)
set task to started when thread is fully up. Avoids a VxWorks race condition.
Definition: TaskCommon.cpp:25
TaskStatus start(const Fw::StringBase &name, taskRoutine routine, void *arg, NATIVE_UINT_TYPE priority=TASK_DEFAULT, NATIVE_UINT_TYPE stackSize=TASK_DEFAULT, NATIVE_UINT_TYPE cpuAffinity=TASK_DEFAULT, NATIVE_UINT_TYPE identifier=TASK_DEFAULT)
start the task
Definition: Task.cpp:18
static NATIVE_INT_TYPE getNumTasks()
Definition: TaskCommon.cpp:12
SerializeStatus
forward declaration for string
@ FW_SERIALIZE_OK
Serialization/Deserialization operation was successful.