QP/C++  5.9.5
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  uint_fast8_t const tickRate = static_cast<uint_fast8_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  QTimeEvt(enum_t const sgnl) :
412 #ifdef Q_EVT_CTOR
413  QEvt(static_cast<QSignal>(sgnl)),
414 #endif
415  m_next(static_cast<QTimeEvt *>(0)),
416  m_act(static_cast<void *>(0)),
417  m_ctr(static_cast<QTimeEvtCtr>(0)),
418  m_interval(static_cast<QTimeEvtCtr >(0))
419  {
420 #ifndef Q_EVT_CTOR
421  sig = static_cast<QSignal>(sgnl); // set QEvt::sig of this time event
422 #endif
423  // time event must be static, see NOTE01
424  poolId_ = static_cast<uint8_t>(0); // not from any event pool
425  refCtr_ = static_cast<uint8_t>(0); // default rate 0, see NOTE02
426  }
427 
429  void postIn(QActive * const act, QTimeEvtCtr const nTicks) {
430  m_act = act;
431  armX(nTicks, static_cast<QTimeEvtCtr>(0));
432  }
433 
435  void postEvery(QActive * const act, QTimeEvtCtr const nTicks) {
436  m_act = act;
437  armX(nTicks, nTicks);
438  }
439 #endif // (!defined QP_IMPL) && (QP_API_VERSION < 500)
440 
441 private:
443  QTimeEvt(void);
444 
446  QTimeEvt(QTimeEvt const &);
447 
449  QTimeEvt & operator=(QTimeEvt const &);
450 
452  QActive *toActive(void) { return static_cast<QActive *>(m_act); }
453 
455  QTimeEvt *toTimeEvt(void) { return static_cast<QTimeEvt *>(m_act); }
456 
457  friend class QF;
458 #ifdef qxk_h
459  friend class QXThread;
460  friend void QXK_activate_(void);
461 #endif // qxk_h
462 };
463 
464 
465 //****************************************************************************
472 
473 
474 //****************************************************************************
479 class QF {
480 public:
481 
483  static char_t const *getVersion(void) {
484  return versionStr;
485  }
486 
488  static void init(void);
489 
491  static void psInit(QSubscrList * const subscrSto,
492  enum_t const maxSignal);
493 
495  static void poolInit(void * const poolSto, uint_fast32_t const poolSize,
496  uint_fast16_t const evtSize);
497 
499  static uint_fast16_t poolGetMaxBlockSize(void);
500 
501 
503  static int_t run(void);
504 
506  static void onStartup(void);
507 
509  static void onCleanup(void);
510 
513  static void stop(void);
514 
515 #ifndef Q_SPY
516  static void publish_(QEvt const *e);
517  static void tickX_(uint_fast8_t const tickRate);
518 #else
519 
521  static void publish_(QEvt const *e, void const *sender);
522 
524  static void tickX_(uint_fast8_t const tickRate,
525  void const * const sender);
526 
527 #endif // Q_SPY
528 
531  static bool noTimeEvtsActiveX(uint_fast8_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 
583 uint16_t const QF_NO_MARGIN = static_cast<uint16_t>(0xFFFF);
584 
585 
586 //****************************************************************************
596 class QTicker : public QActive {
597 public:
598  QTicker(uint_fast8_t const tickRate); // ctor
599 
600  virtual void init(QEvt const * const e);
601  virtual void init(void) { this->init(static_cast<QEvt const *>(0)); }
602  virtual void dispatch(QEvt const * const e);
603 #ifndef Q_SPY
604  virtual bool post_(QEvt const * const e, uint_fast16_t const margin);
605 #else
606  virtual bool post_(QEvt const * const e, uint_fast16_t const margin,
607  void const * const sender);
608 #endif
609  virtual void postLIFO(QEvt const * const e);
610 };
611 
612 } // namespace QP
613 
614 //****************************************************************************
615 #ifndef QF_CRIT_EXIT_NOP
616  #define QF_CRIT_EXIT_NOP() ((void)0)
626 #endif
627 
628 //****************************************************************************
629 // Provide the constructor for the QEvt class?
630 #ifdef Q_EVT_CTOR
631 
632  #define Q_NEW(evtT_, sig_, ...) \
633  (new(QP::QF::newX_(static_cast<uint_fast16_t>(sizeof(evtT_)), \
634  QP::QF_NO_MARGIN, static_cast<enum_t>(0))) \
635  evtT_((sig_), ##__VA_ARGS__))
636 
637  #define Q_NEW_X(e_, evtT_, margin_, sig_, ...) do { \
638  (e_) = static_cast<evtT_ *>(QP::QF::newX_(static_cast<uint_fast16_t>(\
639  sizeof(evtT_)), (margin_), static_cast<enum_t>(0))); \
640  if ((e_) != static_cast<evtT_ *>(0)) { \
641  new((e_)) evtT_((sig_), ##__VA_ARGS__); \
642  } \
643  } while (0)
644 
645 #else // QEvt is a POD (Plain Old Datatype)
646 
667  #define Q_NEW(evtT_, sig_) \
668  (static_cast<evtT_ *>(QP::QF::newX_( \
669  static_cast<uint_fast16_t>(sizeof(evtT_)), \
670  QP::QF_NO_MARGIN, (sig_))))
671 
696  #define Q_NEW_X(e_, evtT_, margin_, sig_) ((e_) = static_cast<evtT_ *>(\
697  QP::QF::newX_(static_cast<uint_fast16_t>(sizeof(evtT_)),\
698  (margin_), (sig_))))
699 
700 #endif
701 
721 #define Q_NEW_REF(evtRef_, evtT_) \
722  ((evtRef_) = static_cast<evtT_ const *>(QP::QF::newRef_(e, (evtRef_))))
723 
738 #define Q_DELETE_REF(evtRef_) do { \
739  QP::QF::gc((evtRef_)); \
740  (evtRef_) = 0; \
741 } while (false)
742 
743 
744 //****************************************************************************
745 // QS software tracing integration, only if enabled
746 #ifdef Q_SPY
747 
770  #define TICK_X(tickRate_, sender_) tickX_((tickRate_), (sender_))
771 
793  #define PUBLISH(e_, sender_) publish_((e_), (sender_))
794 
815  #define POST(e_, sender_) \
816  post_((e_), QP::QF_NO_MARGIN, (sender_))
817 
851  #define POST_X(e_, margin_, sender_) \
852  post_((e_), (margin_), (sender_))
853 
854 #else
855 
856  #define PUBLISH(e_, dummy_) publish_((e_))
857  #define POST(e_, dummy_) post_((e_), QP::QF_NO_MARGIN)
858  #define POST_X(e_, margin_, dummy_) post_((e_), (margin_))
859  #define TICK_X(tickRate_, dummy_) tickX_((tickRate_))
860 
861 #endif // Q_SPY
862 
865 #define TICK(sender_) TICK_X(static_cast<uint8_t>(0), (sender_))
866 
867 #endif // qf_h
virtual void dispatch(QEvt const *const e)
Dispatches an event to QHsm.
Definition: qep_hsm.cpp:233
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:125
QPSet QSubscrList
Subscriber List.
Definition: qf.h:471
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:596
uint16_t const QF_NO_MARGIN
special value of margin that causes asserting failure in case event allocation or event posting fails...
Definition: qf.h:583
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:281
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:479
QEvt const * get_(void)
Get an event from the event queue of an active object.
Definition: qf_actq.cpp:253
#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:585
static char_t const * getVersion(void)
get the current QF version number string of the form X.Y.Z
Definition: qf.h:483
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:544
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:195
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:239
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:215
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:98
#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:328
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:172
Counting Semaphore of the QXK preemptive kernel.
Definition: qxthread.h:141
Priority Ceiling Mutex the QXK preemptive kernel.
Definition: qxk.h:155
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