QP/C++  5.9.8
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 #ifdef qxk_h // QXK kernel used?
180  uint_fast8_t m_startPrio;
182 #endif
183 
184 
185 protected:
187  QActive(QStateHandler const initial);
188 
189 public:
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  QEvt const * const ie);
196 
198  virtual void start(uint_fast8_t const prio,
199  QEvt const *qSto[], uint_fast16_t const qLen,
200  void * const stkSto, uint_fast16_t const stkSize)
201  {
202  this->start(prio, qSto, qLen, stkSto, stkSize,
203  static_cast<QEvt const *>(0));
204  }
205 
206 #ifndef Q_SPY
207  virtual bool post_(QEvt const * const e, uint_fast16_t const margin);
210 #else
211  virtual bool post_(QEvt const * const e, uint_fast16_t const margin,
212  void const * const sender);
213 #endif
214 
217  virtual void postLIFO(QEvt const * const e);
218 
220  void unsubscribeAll(void) const;
221 
224  void stop(void);
225 
227  void subscribe(enum_t const sig) const;
228 
230  void unsubscribe(enum_t const sig) const;
231 
233  bool defer(QEQueue * const eq, QEvt const * const e) const;
234 
236  bool recall(QEQueue * const eq);
237 
239  uint_fast16_t flushDeferred(QEQueue * const eq) const;
240 
242  uint_fast8_t getPrio(void) const {
243  return m_prio;
244  }
245 
247  void setPrio(uint_fast8_t const prio) {
248  m_prio = prio;
249  }
250 
251 #ifdef QF_OS_OBJECT_TYPE
252  QF_OS_OBJECT_TYPE &getOsObject(void) { return m_osObject; }
255 #endif
256 
257 #ifdef QF_THREAD_TYPE
258  QF_THREAD_TYPE &getThread(void) { return m_thread; }
261 #endif
262 
264  QEvt const *get_(void);
265 
266  friend class QF;
267  friend class QTimeEvt;
268  friend class QTicker;
269 #ifdef qk_h
270  friend class QMutex;
271 #endif // qk_h
272 #ifdef qxk_h
273  friend class QXK;
274  friend class QXThread;
275  friend class QXMutex;
276  friend class QXSemaphore;
277 #endif // qxk_h
278 };
279 
280 //****************************************************************************
301 class QMActive : public QActive {
302 public:
303  // all the following operations delegate to the QHsm class...
304  virtual void init(QEvt const * const e);
305  virtual void init(void);
306  virtual void dispatch(QEvt const * const e);
307 
309  bool isInState(QMState const * const st) const;
310 
312  QMState const *stateObj(void) const {
313  return m_state.obj;
314  }
315 
317  QMState const *childStateObj(QMState const * const parent) const;
318 
319 protected:
321  QMActive(QStateHandler const initial);
322 
323 private:
325  bool isIn(QStateHandler const s);
326 
328  QStateHandler state(void) const;
329 
331  QStateHandler childState(QStateHandler const parent);
332 };
333 
334 
335 //****************************************************************************
372 class QTimeEvt : public QEvt {
373 private:
374 
376  QTimeEvt * volatile m_next;
377 
382  void * volatile m_act;
383 
389  QTimeEvtCtr volatile m_ctr;
390 
397  QTimeEvtCtr m_interval;
398 
399 public:
400 
402  QTimeEvt(QActive * const act, enum_t const sgnl,
403  uint_fast8_t const tickRate = static_cast<uint_fast8_t>(0));
404 
406  void armX(QTimeEvtCtr const nTicks,
407  QTimeEvtCtr const interval = static_cast<QTimeEvtCtr>(0));
408 
410  bool disarm(void);
411 
413  bool rearm(QTimeEvtCtr const nTicks);
414 
416  QTimeEvtCtr ctr(void) const;
417 
418 #if (!defined QP_IMPL) && (QP_API_VERSION < 500)
419  QTimeEvt(enum_t const sgnl) :
423 #ifdef Q_EVT_CTOR
424  QEvt(static_cast<QSignal>(sgnl)),
425 #endif
426  m_next(static_cast<QTimeEvt *>(0)),
427  m_act(static_cast<void *>(0)),
428  m_ctr(static_cast<QTimeEvtCtr>(0)),
429  m_interval(static_cast<QTimeEvtCtr >(0))
430  {
431 #ifndef Q_EVT_CTOR
432  sig = static_cast<QSignal>(sgnl); // set QEvt::sig of this time event
433 #endif
434  // time event must be static, see NOTE01
435  poolId_ = static_cast<uint8_t>(0); // not from any event pool
436  refCtr_ = static_cast<uint8_t>(0); // default rate 0, see NOTE02
437  }
438 
440  void postIn(QActive * const act, QTimeEvtCtr const nTicks) {
441  m_act = act;
442  armX(nTicks, static_cast<QTimeEvtCtr>(0));
443  }
444 
446  void postEvery(QActive * const act, QTimeEvtCtr const nTicks) {
447  m_act = act;
448  armX(nTicks, nTicks);
449  }
450 #endif // (!defined QP_IMPL) && (QP_API_VERSION < 500)
451 
452 private:
454  QTimeEvt(void);
455 
457  QTimeEvt(QTimeEvt const &);
458 
460  QTimeEvt & operator=(QTimeEvt const &);
461 
463  QActive *toActive(void) { return static_cast<QActive *>(m_act); }
464 
466  QTimeEvt *toTimeEvt(void) { return static_cast<QTimeEvt *>(m_act); }
467 
468  friend class QF;
469 #ifdef qxk_h
470  friend class QXThread;
471  friend void QXK_activate_(void);
472 #endif // qxk_h
473 };
474 
475 
476 //****************************************************************************
483 
484 
485 //****************************************************************************
490 class QF {
491 public:
492 
494  static char_t const *getVersion(void) {
495  return versionStr;
496  }
497 
499  static void init(void);
500 
502  static void psInit(QSubscrList * const subscrSto,
503  enum_t const maxSignal);
504 
506  static void poolInit(void * const poolSto, uint_fast32_t const poolSize,
507  uint_fast16_t const evtSize);
508 
510  static uint_fast16_t poolGetMaxBlockSize(void);
511 
512 
514  static int_t run(void);
515 
517  static void onStartup(void);
518 
520  static void onCleanup(void);
521 
524  static void stop(void);
525 
526 #ifndef Q_SPY
527  static void publish_(QEvt const *e);
528  static void tickX_(uint_fast8_t const tickRate);
529 #else
530 
532  static void publish_(QEvt const *e, void const *sender);
533 
535  static void tickX_(uint_fast8_t const tickRate,
536  void const * const sender);
537 
538 #endif // Q_SPY
539 
542  static bool noTimeEvtsActiveX(uint_fast8_t const tickRate);
543 
544 
547  static uint_fast16_t getPoolMin(uint_fast8_t const poolId);
548 
551  static uint_fast16_t getQueueMin(uint_fast8_t const prio);
552 
554  static QEvt *newX_(uint_fast16_t const evtSize,
555  uint_fast16_t const margin, enum_t const sig);
556 
558  static void gc(QEvt const *e);
559 
561  static QEvt const *newRef_(QEvt const * const e,
562  QEvt const * const evtRef);
563 
565  static void remove_(QActive * const a);
566 
568  static QActive *active_[QF_MAX_ACTIVE + 1];
569 
571  static void thread_(QActive *act);
572 
574  static void add_(QActive * const a);
575 
577  static void bzero(void * const start, uint_fast16_t len);
578 
579 // to be used in QF ports only...
580 private:
581 
583  static QTimeEvt timeEvtHead_[QF_MAX_TICK_RATE];
584 
585  friend class QActive;
586  friend class QTimeEvt;
587 #ifdef qxk_h
588  friend class QXThread;
589 #endif // qxk_h
590 };
591 
594 uint_fast16_t const QF_NO_MARGIN = static_cast<uint_fast16_t>(0xFFFF);
595 
596 
597 //****************************************************************************
607 class QTicker : public QActive {
608 public:
609  QTicker(uint_fast8_t const tickRate); // ctor
610 
611  virtual void init(QEvt const * const e);
612  virtual void init(void) { this->init(static_cast<QEvt const *>(0)); }
613  virtual void dispatch(QEvt const * const e);
614 #ifndef Q_SPY
615  virtual bool post_(QEvt const * const e, uint_fast16_t const margin);
616 #else
617  virtual bool post_(QEvt const * const e, uint_fast16_t const margin,
618  void const * const sender);
619 #endif
620  virtual void postLIFO(QEvt const * const e);
621 };
622 
623 } // namespace QP
624 
625 //****************************************************************************
626 #ifndef QF_CRIT_EXIT_NOP
627  #define QF_CRIT_EXIT_NOP() ((void)0)
637 #endif
638 
639 //****************************************************************************
640 // Provide the constructor for the QEvt class?
641 #ifdef Q_EVT_CTOR
642 
643  #define Q_NEW(evtT_, sig_, ...) \
644  (new(QP::QF::newX_(static_cast<uint_fast16_t>(sizeof(evtT_)), \
645  QP::QF_NO_MARGIN, static_cast<enum_t>(0))) \
646  evtT_((sig_), ##__VA_ARGS__))
647 
648  #define Q_NEW_X(e_, evtT_, margin_, sig_, ...) do { \
649  (e_) = static_cast<evtT_ *>(QP::QF::newX_(static_cast<uint_fast16_t>(\
650  sizeof(evtT_)), (margin_), static_cast<enum_t>(0))); \
651  if ((e_) != static_cast<evtT_ *>(0)) { \
652  new((e_)) evtT_((sig_), ##__VA_ARGS__); \
653  } \
654  } while (0)
655 
656 #else // QEvt is a POD (Plain Old Datatype)
657 
678  #define Q_NEW(evtT_, sig_) \
679  (static_cast<evtT_ *>(QP::QF::newX_( \
680  static_cast<uint_fast16_t>(sizeof(evtT_)), \
681  QP::QF_NO_MARGIN, (sig_))))
682 
707  #define Q_NEW_X(e_, evtT_, margin_, sig_) ((e_) = static_cast<evtT_ *>(\
708  QP::QF::newX_(static_cast<uint_fast16_t>(sizeof(evtT_)),\
709  (margin_), (sig_))))
710 
711 #endif
712 
732 #define Q_NEW_REF(evtRef_, evtT_) \
733  ((evtRef_) = static_cast<evtT_ const *>(QP::QF::newRef_(e, (evtRef_))))
734 
749 #define Q_DELETE_REF(evtRef_) do { \
750  QP::QF::gc((evtRef_)); \
751  (evtRef_) = 0; \
752 } while (false)
753 
754 
755 //****************************************************************************
756 // QS software tracing integration, only if enabled
757 #ifdef Q_SPY
758 
781  #define TICK_X(tickRate_, sender_) tickX_((tickRate_), (sender_))
782 
804  #define PUBLISH(e_, sender_) publish_((e_), (sender_))
805 
826  #define POST(e_, sender_) \
827  post_((e_), QP::QF_NO_MARGIN, (sender_))
828 
862  #define POST_X(e_, margin_, sender_) \
863  post_((e_), (margin_), (sender_))
864 
865 #else
866 
867  #define PUBLISH(e_, dummy_) publish_((e_))
868  #define POST(e_, dummy_) post_((e_), QP::QF_NO_MARGIN)
869  #define POST_X(e_, margin_, dummy_) post_((e_), (margin_))
870  #define TICK_X(tickRate_, dummy_) tickX_((tickRate_))
871 
872 #endif // Q_SPY
873 
876 #define TICK(sender_) TICK_X(static_cast<uint8_t>(0), (sender_))
877 
878 #endif // qf_h
Priority Set of up to 32 elements */.
Definition: qpset.h:104
QXK services.
Definition: qxk.h:128
virtual void init(void)
Executes the top-most initial transition in QP::QHsm.
Definition: qf.h:612
char char_t
typedef for character strings.
Definition: qep.h:79
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
QMActive active object (based on QP::QMsm implementation)
Definition: qf.h:301
Ticker Active Object class.
Definition: qf.h:607
static char_t const * getVersion(void)
get the current QF version number string of the form X.Y.Z
Definition: qf.h:494
char_t const versionStr[6]
the current QP version number string based on QP_VERSION_STR
Definition: qep_msm.cpp:60
Time Event class.
Definition: qf.h:372
unsigned short uint16_t
exact-width 16-bit unsigned int
Definition: stdint.h:30
uint_fast16_t const QF_NO_MARGIN
special value of margin that causes asserting failure in case event allocation or event posting fails...
Definition: qf.h:594
QEvt base class.
Definition: qep.h:212
unsigned char uint8_t
exact-width 8-bit unsigned int
Definition: stdint.h:29
QMState const * stateObj(void) const
Return the current active state object (read only)
Definition: qf.h:312
QF services.
Definition: qf.h:490
QEvt const * get_(void)
Get an event from the event queue of an active object.
Definition: qf_actq.cpp:257
#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
void subscribe(enum_t const sig) const
Subscribes for delivery of signal sig to the active object.
Definition: qf_ps.cpp:197
virtual void dispatch(QEvt const *const e)
Dispatches an event to QHsm.
Definition: qep_hsm.cpp:233
bool recall(QEQueue *const eq)
Recall a deferred event from a given event queue.
Definition: qf_defer.cpp:92
unsigned int uint_fast8_t
fast at-least 8-bit unsigned int
Definition: stdint.h:36
void stop(void)
Stops execution of an active object and removes it from the framework&#39;s supervision.
Definition: qk.cpp:206
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
unsigned long uint32_t
exact-width 32-bit unsigned int
Definition: stdint.h:31
QStateHandler childState(QStateHandler const parent)
Obtain the current active child state of a given parent.
Definition: qep_hsm.cpp:585
State object for the QMsm class (Meta State Machine).
Definition: qep.h:556
virtual void init(void)
Executes the top-most initial transition in QP::QHsm.
Definition: qep.h:318
QActive active object (based on QP::QHsm implementation)
Definition: qf.h:141
QStateHandler state(void) const
Obtain the current state (state handler function)
Definition: qep.h:335
Native QF Event Queue class.
Definition: qequeue.h:123
void setPrio(uint_fast8_t const prio)
Set the priority of the active object.
Definition: qf.h:247
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:189
unsigned int uint_fast16_t
fast at-least 16-bit unsigned int
Definition: stdint.h:38
QPSet QSubscrList
Subscriber List.
Definition: qf.h:482
namespace associated with the QP/C++ framework
Definition: api.dox:1
uint16_t QSignal
QSignal represents the signal of an event.
Definition: qep.h:151
#define QF_MAX_ACTIVE
The maximum number of active objects in the application.
Definition: qf_port.h:57
uint_fast8_t m_prio
QF priority (1..QF_MAX_ACTIVE) of this active object.
Definition: qf.h:177
QState(* QStateHandler)(void *const me, QEvt const *const e)
pointer to state-handler function
Definition: qep.h:225
Extended (blocking) thread of the QXK preemptive kernel.
Definition: qxthread.h:71
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:165
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:198
QActive(QStateHandler const initial)
protected constructor (abstract class)
Definition: qf_qact.cpp:44
uint_fast8_t getPrio(void) const
Get the priority of the active object.
Definition: qf.h:242
#define QF_EQUEUE_TYPE
This macro defines the type of the event queue used for active objects.
Definition: qk.h:53
uint_fast16_t flushDeferred(QEQueue *const eq) const
Flush the specified deferred queue &#39;eq&#39;.
Definition: qf_defer.cpp:133
void unsubscribeAll(void) const
Un-subscribes from the delivery of all signals to the active object.
Definition: qf_ps.cpp:281
#define QF_MAX_TICK_RATE
Default value of the macro configurable value in qf_port.h.
Definition: qf.h:66
platform-independent priority sets of 8 or 64 elements.
bool defer(QEQueue *const eq, QEvt const *const e) const
Defer an event to a given separate event queue.
Definition: qf_defer.cpp:70
void QXK_activate_(void)
QXK activator activates the next active object. The activated AO preempts.
Definition: qxk.cpp:435
int int_t
typedef for line numbers in assertions and return from QF_run()
Definition: qep.h:82
void unsubscribe(enum_t const sig) const
Un-subscribes from the delivery of signal sig to the active object.
Definition: qf_ps.cpp:239
Hierarchical State Machine base class.
Definition: qep.h:309
uint16_t QEvtSize
The data type to store the block-size defined based on the macro QF_EVENT_SIZ_SIZE.
Definition: qf.h:87
Counting Semaphore of the QXK preemptive kernel.
Definition: qxthread.h:141
bool isIn(QStateHandler const s)
Tests if a given state is part of the current active state configuration.
Definition: qep_hsm.cpp:544
Priority Ceiling Mutex the QXK preemptive kernel */.
Definition: qxthread.h:189
#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
virtual bool post_(QEvt const *const e, uint_fast16_t const margin, void const *const sender)
Definition: qf_actq.cpp:90