QP/C++  5.8.2
qf.h
Go to the documentation of this file.
1 
39 #ifndef qf_h
40 #define qf_h
41 
42 //****************************************************************************
43 #ifndef qpset_h
44 #include "qpset.h"
45 #endif
46 
47 #ifdef Q_EVT_CTOR
48 #include <new> // for placement new
49 #endif // Q_EVT_CTOR
50 
51 //****************************************************************************
52 // apply defaults for all undefined configuration parameters
53 //
54 #ifndef QF_EVENT_SIZ_SIZE
55  #define QF_EVENT_SIZ_SIZE 2
57 #endif
58 
59 #ifndef QF_MAX_EPOOL
60  #define QF_MAX_EPOOL 3
62 #endif
63 
64 #ifndef QF_MAX_TICK_RATE
65  #define QF_MAX_TICK_RATE 1
67 #endif
68 
69 #ifndef QF_TIMEEVT_CTR_SIZE
70  #define QF_TIMEEVT_CTR_SIZE 2
73 #endif
74 
75 
76 //****************************************************************************
77 namespace QP {
78 
79 #if (QF_EVENT_SIZ_SIZE == 1)
80  typedef uint8_t QEvtSize;
81 #elif (QF_EVENT_SIZ_SIZE == 2)
82  typedef uint16_t QEvtSize;
88 #elif (QF_EVENT_SIZ_SIZE == 4)
89  typedef uint32_t QEvtSize;
90 #else
91  #error "QF_EVENT_SIZ_SIZE defined incorrectly, expected 1, 2, or 4"
92 #endif
93 
94 //****************************************************************************
95 #if (QF_TIMEEVT_CTR_SIZE == 1)
96  typedef uint8_t QTimeEvtCtr;
97 #elif (QF_TIMEEVT_CTR_SIZE == 2)
98  typedef uint16_t QTimeEvtCtr;
107 #elif (QF_TIMEEVT_CTR_SIZE == 4)
108  typedef uint32_t QTimeEvtCtr;
109 #else
110  #error "QF_TIMEEVT_CTR_SIZE defined incorrectly, expected 1, 2, or 4"
111 #endif
112 
113 class QEQueue; // forward declaration
114 
115 //****************************************************************************
141 class QActive : public QHsm {
142 public: // for access from extern "C" functions
143 #ifdef QF_EQUEUE_TYPE
144  QF_EQUEUE_TYPE m_eQueue;
155 #endif
156 
157 #ifdef QF_OS_OBJECT_TYPE
158  QF_OS_OBJECT_TYPE m_osObject;
165 #endif
166 
167 #ifdef QF_THREAD_TYPE
168  QF_THREAD_TYPE m_thread;
174 #endif
175 
178 
179 protected:
181  QActive(QStateHandler const initial);
182 
183 public:
186  virtual void start(uint_fast8_t const prio,
187  QEvt const *qSto[], uint_fast16_t const qLen,
188  void * const stkSto, uint_fast16_t const stkSize,
189  QEvt const * const ie);
190 
192  virtual void start(uint_fast8_t const prio,
193  QEvt const *qSto[], uint_fast16_t const qLen,
194  void * const stkSto, uint_fast16_t const stkSize)
195  {
196  this->start(prio, qSto, qLen, stkSto, stkSize,
197  static_cast<QEvt const *>(0));
198  }
199 
200 #ifndef Q_SPY
201  virtual bool post_(QEvt const * const e, uint_fast16_t const margin);
204 #else
205  virtual bool post_(QEvt const * const e, uint_fast16_t const margin,
206  void const * const sender);
207 #endif
208 
211  virtual void postLIFO(QEvt const * const e);
212 
214  void unsubscribeAll(void) const;
215 
218  void stop(void);
219 
221  void subscribe(enum_t const sig) const;
222 
224  void unsubscribe(enum_t const sig) const;
225 
227  bool defer(QEQueue * const eq, QEvt const * const e) const;
228 
230  bool recall(QEQueue * const eq);
231 
233  uint_fast16_t flushDeferred(QEQueue * const eq) const;
234 
236  uint_fast8_t getPrio(void) const {
237  return m_prio;
238  }
239 
241  void setPrio(uint_fast8_t const prio) {
242  m_prio = prio;
243  }
244 
245 #ifdef QF_OS_OBJECT_TYPE
246  QF_OS_OBJECT_TYPE &getOsObject(void) { return m_osObject; }
249 #endif
250 
251 #ifdef QF_THREAD_TYPE
252  QF_THREAD_TYPE &getThread(void) { return m_thread; }
255 #endif
256 
258  QEvt const *get_(void);
259 
260  friend class QF;
261  friend class QTimeEvt;
262  friend class QTicker;
263 #ifdef qk_h
264  friend class QMutex;
265 #endif // qk_h
266 #ifdef qxk_h
267  friend class QXK;
268  friend class QXThread;
269  friend class QXMutex;
270  friend class QXSemaphore;
271 #endif // qxk_h
272 };
273 
274 //****************************************************************************
295 class QMActive : public QActive {
296 public:
297  // all the following operations delegate to the QHsm class...
298  virtual void init(QEvt const * const e);
299  virtual void init(void);
300  virtual void dispatch(QEvt const * const e);
301 
303  bool isInState(QMState const * const st) const;
304 
306  QMState const *stateObj(void) const {
307  return m_state.obj;
308  }
309 
311  QMState const *childStateObj(QMState const * const parent) const;
312 
313 protected:
315  QMActive(QStateHandler const initial);
316 
317 private:
319  bool isIn(QStateHandler const s);
320 
322  QStateHandler state(void) const;
323 
325  QStateHandler childState(QStateHandler const parent);
326 };
327 
328 
329 //****************************************************************************
363 class QTimeEvt : public QEvt {
364 private:
365 
367  QTimeEvt * volatile m_next;
368 
373  void * volatile m_act;
374 
380  QTimeEvtCtr volatile m_ctr;
381 
388  QTimeEvtCtr m_interval;
389 
390 public:
391 
393  QTimeEvt(QActive * const act, enum_t const sgnl,
394  uint8_t const tickRate = static_cast<uint8_t>(0));
395 
397  void armX(QTimeEvtCtr const nTicks,
398  QTimeEvtCtr const interval = static_cast<QTimeEvtCtr>(0));
399 
401  bool disarm(void);
402 
404  bool rearm(QTimeEvtCtr const nTicks);
405 
407  QTimeEvtCtr ctr(void) const;
408 
409 #if (!defined QP_IMPL) && (QP_API_VERSION < 500)
410 
412  QTimeEvt(enum_t const sgnl) :
413 #ifdef Q_EVT_CTOR
414  QEvt(static_cast<QSignal>(sgnl)),
415 #endif
416  m_next(static_cast<QTimeEvt *>(0)),
417  m_act(static_cast<void *>(0)),
418  m_ctr(static_cast<QTimeEvtCtr>(0)),
419  m_interval(static_cast<QTimeEvtCtr >(0))
420  {
421 #ifndef Q_EVT_CTOR
422  sig = static_cast<QSignal>(sgnl); // set QEvt::sig of this time event
423 #endif
424  // time event must be static, see NOTE01
425  poolId_ = static_cast<uint8_t>(0); // not from any event pool
426  refCtr_ = static_cast<uint8_t>(0); // default rate 0, see NOTE02
427  }
428 
430  void postIn(QActive * const act, QTimeEvtCtr const nTicks) {
431  m_act = act;
432  armX(nTicks, static_cast<QTimeEvtCtr>(0));
433  }
434 
436  void postEvery(QActive * const act, QTimeEvtCtr const nTicks) {
437  m_act = act;
438  armX(nTicks, nTicks);
439  }
440 #endif // (!defined QP_IMPL) && (QP_API_VERSION < 500)
441 
442 private:
444  QTimeEvt(void);
445 
447  QTimeEvt(QTimeEvt const &);
448 
450  QTimeEvt & operator=(QTimeEvt const &);
451 
453  QActive *toActive(void) { return static_cast<QActive *>(m_act); }
454 
456  QTimeEvt *toTimeEvt(void) { return static_cast<QTimeEvt *>(m_act); }
457 
458  friend class QF;
459 #ifdef qxk_h
460  friend class QXThread;
461  friend void QXK_activate_(void);
462 #endif // qxk_h
463 };
464 
465 
466 //****************************************************************************
473 
474 
475 //****************************************************************************
480 class QF {
481 public:
482 
484  static char_t const *getVersion(void) {
485  return versionStr;
486  }
487 
489  static void init(void);
490 
492  static void psInit(QSubscrList * const subscrSto,
493  enum_t const maxSignal);
494 
496  static void poolInit(void * const poolSto, uint_fast32_t const poolSize,
497  uint_fast16_t const evtSize);
498 
500  static uint_fast16_t poolGetMaxBlockSize(void);
501 
502 
504  static int_t run(void);
505 
507  static void onStartup(void);
508 
510  static void onCleanup(void);
511 
514  static void stop(void);
515 
516 #ifndef Q_SPY
517  static void publish_(QEvt const *e);
518  static void tickX_(uint8_t const tickRate);
519 #else
520 
522  static void publish_(QEvt const *e, void const *sender);
523 
525  static void tickX_(uint8_t const tickRate, void const * const sender);
526 
527 #endif // Q_SPY
528 
531  static bool noTimeEvtsActiveX(uint8_t const tickRate);
532 
533 
536  static uint_fast16_t getPoolMin(uint_fast8_t const poolId);
537 
540  static uint_fast16_t getQueueMin(uint_fast8_t const prio);
541 
543  static QEvt *newX_(uint_fast16_t const evtSize,
544  uint_fast16_t const margin, enum_t const sig);
545 
547  static void gc(QEvt const *e);
548 
550  static QEvt const *newRef_(QEvt const * const e,
551  QEvt const * const evtRef);
552 
554  static void remove_(QActive * const a);
555 
557  static QActive *active_[QF_MAX_ACTIVE + 1];
558 
560  static void thread_(QActive *act);
561 
563  static void add_(QActive * const a);
564 
566  static void bzero(void * const start, uint_fast16_t len);
567 
568 // to be used in QF ports only...
569 private:
570 
572  static QTimeEvt timeEvtHead_[QF_MAX_TICK_RATE];
573 
574  friend class QActive;
575  friend class QTimeEvt;
576 #ifdef qxk_h
577  friend class QXThread;
578 #endif // qxk_h
579 };
580 
581 
582 //****************************************************************************
592 class QTicker : public QActive {
593 public:
594  QTicker(uint8_t const tickRate); // ctor
595 
596  virtual void init(QEvt const * const e);
597  virtual void init(void) { this->init(static_cast<QEvt const *>(0)); }
598  virtual void dispatch(QEvt const * const e);
599 #ifndef Q_SPY
600  virtual bool post_(QEvt const * const e, uint_fast16_t const margin);
601 #else
602  virtual bool post_(QEvt const * const e, uint_fast16_t const margin,
603  void const * const sender);
604 #endif
605  virtual void postLIFO(QEvt const * const e);
606 };
607 
608 } // namespace QP
609 
610 //****************************************************************************
611 #ifndef QF_CRIT_EXIT_NOP
612  #define QF_CRIT_EXIT_NOP() ((void)0)
622 #endif
623 
624 //****************************************************************************
625 // Provide the constructor for the QEvt class?
626 #ifdef Q_EVT_CTOR
627 
628  #define Q_NEW(evtT_, sig_, ...) \
629  (new(QP::QF::newX_(static_cast<uint_fast16_t>(sizeof(evtT_)), \
630  static_cast<uint_fast16_t>(0), static_cast<enum_t>(0))) \
631  evtT_((sig_), ##__VA_ARGS__))
632 
633  #define Q_NEW_X(e_, evtT_, margin_, sig_, ...) do { \
634  (e_) = static_cast<evtT_ *>(QP::QF::newX_(static_cast<uint_fast16_t>(\
635  sizeof(evtT_)), (margin_), static_cast<enum_t>(0))); \
636  if ((e_) != static_cast<evtT_ *>(0)) { \
637  new((e_)) evtT_((sig_), ##__VA_ARGS__); \
638  } \
639  } while (0)
640 
641 #else // QEvt is a POD (Plain Old Datatype)
642 
663  #define Q_NEW(evtT_, sig_) \
664  (static_cast<evtT_ *>(QP::QF::newX_( \
665  static_cast<uint_fast16_t>(sizeof(evtT_)), \
666  static_cast<uint_fast16_t>(0), (sig_))))
667 
690  #define Q_NEW_X(e_, evtT_, margin_, sig_) ((e_) = static_cast<evtT_ *>(\
691  QP::QF::newX_(static_cast<uint_fast16_t>(sizeof(evtT_)),\
692  (margin_), (sig_))))
693 
694 #endif
695 
715 #define Q_NEW_REF(evtRef_, evtT_) \
716  ((evtRef_) = static_cast<evtT_ const *>(QP::QF::newRef_(e, (evtRef_))))
717 
732 #define Q_DELETE_REF(evtRef_) do { \
733  QP::QF::gc((evtRef_)); \
734  (evtRef_) = 0; \
735 } while (false)
736 
737 
738 //****************************************************************************
739 // QS software tracing integration, only if enabled
740 #ifdef Q_SPY
741 
764  #define TICK_X(tickRate_, sender_) tickX_((tickRate_), (sender_))
765 
787  #define PUBLISH(e_, sender_) publish_((e_), (sender_))
788 
809  #define POST(e_, sender_) \
810  post_((e_), static_cast<uint_fast16_t>(0), (sender_))
811 
843  #define POST_X(e_, margin_, sender_) \
844  post_((e_), (margin_), (sender_))
845 
846 #else
847 
848  #define PUBLISH(e_, dummy_) publish_((e_))
849  #define POST(e_, dummy_) post_((e_), static_cast<uint_fast16_t>(0))
850  #define POST_X(e_, margin_, dummy_) post_((e_), (margin_))
851  #define TICK_X(tickRate_, dummy_) tickX_((tickRate_))
852 
853 #endif // Q_SPY
854 
857 #define TICK(sender_) TICK_X(static_cast<uint8_t>(0), (sender_))
858 
859 #endif // qf_h
860 
virtual void dispatch(QEvt const *const e)
Dispatches an event to QHsm.
Definition: qep_hsm.cpp:223
QStateHandler state(void) const
Obtain the current state (state handler function)
Definition: qep.h:333
Priority Set of up to 32 elements */.
Definition: qpset.h:104
QXK services.
Definition: qxk.h:106
QPSet QSubscrList
Subscriber List.
Definition: qf.h:472
uint16_t QSignal
QSignal represents the signal of an event.
Definition: qep.h:151
char char_t
typedef for character strings.
Definition: qep.h:79
QMActive active object (based on QP::QMsm implementation)
Definition: qf.h:295
Ticker Active Object class.
Definition: qf.h:592
bool defer(QEQueue *const eq, QEvt const *const e) const
Defer an event to a given separate event queue.
Definition: qf_defer.cpp:70
Time Event class.
Definition: qf.h:363
void subscribe(enum_t const sig) const
Subscribes for delivery of signal sig to the active object.
Definition: qf_ps.cpp:197
unsigned short uint16_t
exact-width 16-bit unsigned int
Definition: stdint.h:30
void unsubscribeAll(void) const
Un-subscribes from the delivery of all signals to the active object.
Definition: qf_ps.cpp:279
QEvt base class.
Definition: qep.h:212
char_t const versionStr[6]
the current QP version number string based on QP_VERSION_STR
Definition: qep_msm.cpp:60
unsigned char uint8_t
exact-width 8-bit unsigned int
Definition: stdint.h:29
QF services.
Definition: qf.h:480
QEvt const * get_(void)
Get an event from the event queue of an active object.
Definition: qf_actq.cpp:250
#define QF_THREAD_TYPE
This macro defines the type of the thread handle used for the active objects. This macro depends on t...
Definition: macros.h:53
QStateHandler childState(QStateHandler const parent)
Obtain the current active child state of a given parent.
Definition: qep_hsm.cpp:581
static char_t const * getVersion(void)
get the current QF version number string of the form X.Y.Z
Definition: qf.h:484
unsigned int uint_fast8_t
fast at-least 8-bit unsigned int
Definition: stdint.h:36
int enum_t
typedef for enumerations used for event signals
Definition: qep.h:85
unsigned long uint_fast32_t
fast at-least 32-bit unsigned int
Definition: stdint.h:40
bool isIn(QStateHandler const s)
Tests if a given state is part of the current active state configuration.
Definition: qep_hsm.cpp:540
virtual void postLIFO(QEvt const *const e)
Posts an event directly to the event queue of the active object using the Last-In-First-Out (LIFO) po...
Definition: qf_actq.cpp:193
unsigned long uint32_t
exact-width 32-bit unsigned int
Definition: stdint.h:31
State object for the QMsm class (Meta State Machine).
Definition: qep.h:554
QActive active object (based on QP::QHsm implementation)
Definition: qf.h:141
uint_fast8_t m_prio
QF priority associated with the active object.
Definition: qf.h:177
Native QF Event Queue class.
Definition: qequeue.h:123
void unsubscribe(enum_t const sig) const
Un-subscribes from the delivery of signal sig to the active object.
Definition: qf_ps.cpp:238
unsigned int uint_fast16_t
fast at-least 16-bit unsigned int
Definition: stdint.h:38
namespace associated with the QP/C++ framework
Definition: exa_native.dox:1
#define QF_MAX_ACTIVE
The maximum number of active objects in the application.
Definition: qf_port.h:57
Priority-ceiling Mutex the QK preemptive kernel.
Definition: qk.h:118
void setPrio(uint_fast8_t const prio)
Set the priority of the active object.
Definition: qf.h:241
void stop(void)
Stops execution of an active object and removes it from the framework&#39;s supervision.
Definition: qk.cpp:201
uint16_t QEvtSize
The data type to store the block-size defined based on the macro QF_EVENT_SIZ_SIZE.
Definition: qf.h:87
Extended (blocking) thread of the QXK preemptive kernel.
Definition: qxthread.h:68
#define QF_EQUEUE_TYPE
This macro defines the type of the event queue used for active objects.
Definition: qk.h:53
virtual bool post_(QEvt const *const e, uint_fast16_t const margin, void const *const sender)
Definition: qf_actq.cpp:99
#define QF_MAX_TICK_RATE
Default value of the macro configurable value in qf_port.h.
Definition: qf.h:66
uint16_t QTimeEvtCtr
type of the Time Event counter, which determines the dynamic range of the time delays measured in clo...
Definition: qf.h:106
uint_fast8_t getPrio(void) const
Get the priority of the active object.
Definition: qf.h:236
platform-independent priority sets of 8 or 64 elements.
QState(* QStateHandler)(void *const me, QEvt const *const e)
pointer to state-handler function
Definition: qep.h:225
void QXK_activate_(void)
QXK activator activates the next active object. The activated AO preempts.
Definition: qxk.cpp:329
int int_t
typedef for line numbers in assertions and return from QF_run()
Definition: qep.h:82
QActive(QStateHandler const initial)
protected constructor (abstract class)
Definition: qf_qact.cpp:44
QMState const * stateObj(void) const
Return the current active state object (read only)
Definition: qf.h:306
Hierarchical State Machine base class.
Definition: qep.h:309
virtual void start(uint_fast8_t const prio, QEvt const *qSto[], uint_fast16_t const qLen, void *const stkSto, uint_fast16_t const stkSize)
Overloaded start function (no initialization event)
Definition: qf.h:192
virtual void start(uint_fast8_t const prio, QEvt const *qSto[], uint_fast16_t const qLen, void *const stkSto, uint_fast16_t const stkSize, QEvt const *const ie)
Starts execution of an active object and registers the object with the framework. ...
Definition: qk.cpp:169
Counting Semaphore of the QXK preemptive kernel.
Definition: qxthread.h:141
Priority Ceiling Mutex the QXK preemptive kernel.
Definition: qxk.h:136
bool recall(QEQueue *const eq)
Recall a deferred event from a given event queue.
Definition: qf_defer.cpp:92
#define QF_OS_OBJECT_TYPE
This macro defines the type of the OS-Object used for blocking the native QF event queue when the que...
Definition: macros.h:49
uint_fast16_t flushDeferred(QEQueue *const eq) const
Flush the specified deferred queue &#39;eq&#39;.
Definition: qf_defer.cpp:133