QP/C++  6.9.3
Real-Time Embedded Framework
qep.hpp
Go to the documentation of this file.
1 
39 #ifndef QEP_HPP
40 #define QEP_HPP
41 
42 //****************************************************************************
44 // major version number, Y is a 1-digit minor version number, and Z is
45 // a 1-digit release number.
46 #define QP_VERSION 693U
47 
49 // a 2-digit major version number, Y is a 1-digit minor version number,
50 // and Z is a 1-digit release number.
51 #define QP_VERSION_STR "6.9.3"
52 
54 #define QP_RELEASE 0x8295AA8AU
55 
56 
57 //****************************************************************************
58 #ifndef Q_SIGNAL_SIZE
65  #define Q_SIGNAL_SIZE 2U
66 #endif
67 
68 //****************************************************************************
69 // Aliases for basic numerical types; MISRA-C++ 2008 rule 3-9-2(req).
70 
76 using char_t = char;
77 
79 using int_t = int;
80 
82 using enum_t = int;
83 
91 using float32_t = float;
92 
100 using float64_t = double;
101 
108 #define Q_EVT_CAST(class_) (static_cast<class_ const *>(e))
109 
117 #define Q_UINT2PTR_CAST(type_, uint_) (reinterpret_cast<type_ *>(uint_))
118 
124 #define QEVT_INITIALIZER(sig_) { static_cast<QP::QSignal>(sig_), 0U, 0U }
125 
126 
127 //****************************************************************************
130 namespace QP {
131 
133  constexpr char_t const versionStr[]{QP_VERSION_STR};
134 
135 #if (Q_SIGNAL_SIZE == 1U)
136  using QSignal = std::uint8_t;
137 #elif (Q_SIGNAL_SIZE == 2U)
147 #elif (Q_SIGNAL_SIZE == 4U)
148  using QSignal = std::uint32_t;
149 #else
150  #error "Q_SIGNAL_SIZE defined incorrectly, expected 1U, 2U, or 4U"
151 #endif
152 
153 #ifdef Q_EVT_CTOR // Provide the constructor for the QEvt class?
154 
155  //************************************************************************
156  class QEvt {
157  public:
159  QEvt(QSignal const s) noexcept
160  : sig(s)
161  // poolId_/refCtr_ intentionally uninitialized
162  {}
163 
165  enum StaticEvt : std::uint8_t { STATIC_EVT };
166  constexpr QEvt(QSignal const s, StaticEvt /*dummy*/) noexcept
167  : sig(s),
168  poolId_(0U),
169  refCtr_(0U)
170  {}
171 
172 #ifdef Q_EVT_VIRTUAL
174  virtual ~QEvt() noexcept {}
175 #endif // Q_EVT_VIRTUAL
176 
177  public:
178  QSignal sig;
179 
180  private:
182  std::uint8_t volatile refCtr_;
183 
184  friend class QF;
185  friend class QActive;
186  friend class QMActive;
187  friend class QTimeEvt;
188  friend class QEQueue;
189  friend class QTicker;
190  friend class QXThread;
191  friend std::uint8_t QF_EVT_POOL_ID_ (QEvt const * const e) noexcept;
192  friend std::uint8_t QF_EVT_REF_CTR_ (QEvt const * const e) noexcept;
193  friend void QF_EVT_REF_CTR_INC_(QEvt const * const e) noexcept;
194  friend void QF_EVT_REF_CTR_DEC_(QEvt const * const e) noexcept;
195  };
196 
197 #else // QEvt is a POD (Plain Old Datatype)
198 
199  //************************************************************************
209  struct QEvt {
213  };
214 
215 #endif // Q_EVT_CTOR
216 
217 // forward declarations...
218 struct QMState;
219 struct QMTranActTable;
220 class QXThread;
221 
224 
226 using QStateHandler = QState (*)(void * const me, QEvt const * const e);
227 
229 using QActionHandler = QState (*)(void * const me);
230 
232 using QXThreadHandler = void (*)(QXThread * const me);
233 
238 union QHsmAttr {
242  QMState const *obj;
244 };
245 
246 
247 //****************************************************************************
269 class QHsm {
272 
273 public:
275  virtual ~QHsm();
276 
278  virtual void init(void const * const e,
279  std::uint_fast8_t const qs_id);
280 
282  virtual void init(std::uint_fast8_t const qs_id) {
283  this->init(nullptr, qs_id);
284  }
285 
287  virtual void dispatch(QEvt const * const e,
288  std::uint_fast8_t const qs_id);
289 
292  bool isIn(QStateHandler const s) noexcept;
293 
296  QStateHandler state(void) const noexcept {
297  return m_state.fun;
298  }
299 
302  QStateHandler childState(QStateHandler const parent) noexcept;
303 
305  static QState top(void * const me, QEvt const * const e) noexcept;
306 
307 protected:
309  explicit QHsm(QStateHandler const initial) noexcept;
310 
311 public:
312 // facilities for the QHsm implementation strategy...
314  static constexpr QState Q_RET_SUPER {static_cast<QState>(0)};
315 
317  static constexpr QState Q_RET_SUPER_SUB {static_cast<QState>(1)};
318 
320  static constexpr QState Q_RET_UNHANDLED {static_cast<QState>(2)};
321 
323  static constexpr QState Q_RET_HANDLED {static_cast<QState>(3)};
324 
326  static constexpr QState Q_RET_IGNORED {static_cast<QState>(4)};
327 
329  static constexpr QState Q_RET_ENTRY {static_cast<QState>(5)};
330 
332  static constexpr QState Q_RET_EXIT {static_cast<QState>(6)};
333 
335  static constexpr QState Q_RET_NULL {static_cast<QState>(7)};
336 
338  static constexpr QState Q_RET_TRAN {static_cast<QState>(8)};
339 
341  static constexpr QState Q_RET_TRAN_INIT {static_cast<QState>(9)};
342 
344  static constexpr QState Q_RET_TRAN_EP {static_cast<QState>(10)};
345 
347  static constexpr QState Q_RET_TRAN_HIST {static_cast<QState>(11)};
348 
350  static constexpr QState Q_RET_TRAN_XP {static_cast<QState>(12)};
351 
352 protected:
354  QState tran(QStateHandler const target) noexcept {
355  m_temp.fun = target;
356  return Q_RET_TRAN;
357  }
358 
360  QState tran_hist(QStateHandler const hist) noexcept {
361  m_temp.fun = hist;
362  return Q_RET_TRAN_HIST;
363  }
364 
366  QState super(QStateHandler const superstate) noexcept {
367  m_temp.fun = superstate;
368  return Q_RET_SUPER;
369  }
370 
374  Q_INIT_SIG
375  };
376 
377 // protected facilities for the QMsm implementation strategy...
380  QState qm_tran(void const * const tatbl) noexcept {
381  m_temp.tatbl = static_cast<QP::QMTranActTable const *>(tatbl);
382  return Q_RET_TRAN;
383  }
384 
387  QState qm_tran_hist(QMState const * const hist,
388  void const * const tatbl) noexcept
389  {
390  m_state.obj = hist;
391  m_temp.tatbl = static_cast<QP::QMTranActTable const *>(tatbl);
392  return Q_RET_TRAN_HIST;
393  }
394 
397  QState qm_tran_init(void const * const tatbl) noexcept {
398  m_temp.tatbl = static_cast<QP::QMTranActTable const *>(tatbl);
399  return Q_RET_TRAN_INIT;
400  }
401 
404  QState qm_tran_ep(void const * const tatbl) noexcept {
405  m_temp.tatbl = static_cast<QP::QMTranActTable const *>(tatbl);
406  return Q_RET_TRAN_EP;
407  }
408 
412  void const *const tatbl) noexcept
413  {
414  m_state.act = xp;
415  m_temp.tatbl = static_cast<QP::QMTranActTable const *>(tatbl);
416  return Q_RET_TRAN_XP;
417  }
418 
419 #ifdef Q_SPY
421  QState qm_entry(QMState const * const s) noexcept {
422  m_temp.obj = s;
423  return Q_RET_ENTRY;
424  }
425 
427  QState qm_exit(QMState const * const s) noexcept {
428  m_temp.obj = s;
429  return Q_RET_EXIT;
430  }
431 
433  virtual QStateHandler getStateHandler() noexcept;
434 #else
436  QState qm_entry(QMState const * const s) noexcept {
437  (void)s;
438  return Q_RET_ENTRY;
439  }
440 
442  QState qm_exit(QMState const * const s) noexcept {
443  (void)s;
444  return Q_RET_EXIT;
445  }
446 #endif
447 
449  QState qm_sm_exit(QMState const * const s) noexcept {
450  m_temp.obj = s;
451  return Q_RET_EXIT;
452  }
453 
456  QState qm_super_sub(QMState const * const s) noexcept {
457  m_temp.obj = s;
458  return Q_RET_SUPER_SUB;
459  }
460 
461 private:
463  static constexpr std::int_fast8_t MAX_NEST_DEPTH_{6};
464 
467  std::uint_fast8_t const qs_id);
468 
469  friend class QMsm;
470  friend class QActive;
471  friend class QMActive;
472  friend class QF;
473  friend class QS;
474  friend class QXK;
475  friend class QXThread;
476  friend class QXMutex;
477  friend class QXSemaphore;
478 #ifdef Q_UTEST
479  friend class QActiveDummy;
480 #endif // Q_UTEST
481 };
482 
483 //****************************************************************************
501 class QMsm : public QHsm {
502 public:
505  void init(void const * const e,
506  std::uint_fast8_t const qs_id) override;
507  void init(std::uint_fast8_t const qs_id) override {
508  this->init(nullptr, qs_id);
509  }
510 
512  void dispatch(QEvt const * const e,
513  std::uint_fast8_t const qs_id) override;
514 
516  bool isInState(QMState const * const st) const noexcept;
517 
519  QMState const *stateObj(void) const noexcept {
520  return m_state.obj;
521  }
522 
524  QMState const *childStateObj(QMState const * const parent) const noexcept;
525 
526 protected:
528  explicit QMsm(QStateHandler const initial) noexcept;
529 
530 #ifdef Q_SPY
532  QStateHandler getStateHandler() noexcept override;
533 #endif
534 
535 private:
538  bool isIn(QStateHandler const s) noexcept = delete;
539 
542  QStateHandler state(void) const noexcept = delete;
543 
546  QStateHandler childState(QStateHandler const parent) noexcept = delete;
547 
550  static QState top(void * const me, QEvt const * const e) noexcept = delete;
551 
553  QState execTatbl_(QMTranActTable const * const tatbl,
554  std::uint_fast8_t const qs_id);
555 
557  void exitToTranSource_(QMState const *s,
558  QMState const * const ts,
559  std::uint_fast8_t const qs_id);
560 
562  QState enterHistory_(QMState const * const hist,
563  std::uint_fast8_t const qs_id);
564 
566  static constexpr std::int_fast8_t MAX_ENTRY_DEPTH_ {4};
567 
569  static QMState const msm_top_s;
570 
571  friend class QMActive;
572 };
573 
584 struct QMState {
590 };
591 
594  QMState const *target;
595  QActionHandler const act[1];
596 };
597 
598 
599 //****************************************************************************
601 class QEP {
602 public:
604  static char_t const *getVersion(void) noexcept {
605  return versionStr;
606  }
607 };
608 
610 constexpr enum_t Q_USER_SIG {4};
611 
612 } // namespace QP
613 
614 //****************************************************************************
615 // Macros for coding QHsm-style state machines...
616 
619 #define Q_STATE_DECL(state_) \
620  QP::QState state_ ## _h(QP::QEvt const * const e); \
621  static QP::QState state_(void * const me, QP::QEvt const * const e)
622 
625 #define Q_STATE_DEF(subclass_, state_) \
626  QP::QState subclass_::state_(void * const me, QP::QEvt const * const e) {\
627  return static_cast<subclass_ *>(me)->state_ ## _h(e); } \
628  QP::QState subclass_::state_ ## _h(QP::QEvt const * const e)
629 
631 #define Q_HANDLED() (Q_RET_HANDLED)
632 
635 #define Q_UNHANDLED() (Q_RET_UNHANDLED)
636 
642 #define Q_STATE_CAST(handler_) \
643  (reinterpret_cast<QP::QStateHandler>(handler_))
644 
650 #define Q_ACTION_CAST(act_) (reinterpret_cast<QP::QActionHandler>(act_))
651 
654 #define Q_ACTION_NULL (nullptr)
655 
656 
657 //****************************************************************************
658 // Macros for coding QMsm-style state machines...
659 
662 #define QM_STATE_DECL(state_) \
663  QP::QState state_ ## _h(QP::QEvt const * const e); \
664  static QP::QState state_(void * const me, QP::QEvt const * const e); \
665  static QP::QMState const state_ ## _s
666 
669 #define QM_SM_STATE_DECL(subm_, state_) \
670  QP::QState state_ ## _h(QP::QEvt const * const e); \
671  static QP::QState state_(void * const me, QP::QEvt const * const e); \
672  static SM_ ## subm_ const state_ ## _s
673 
676 #define QM_ACTION_DECL(action_) \
677  QP::QState action_ ## _h(void); \
678  static QP::QState action_(void * const me)
679 
682 #define QM_STATE_DEF(subclass_, state_) \
683  QP::QState subclass_::state_(void * const me, QP::QEvt const * const e) {\
684  return static_cast<subclass_ *>(me)->state_ ## _h(e); } \
685  QP::QState subclass_::state_ ## _h(QP::QEvt const * const e)
686 
689 #define QM_ACTION_DEF(subclass_, action_) \
690  QP::QState subclass_::action_(void * const me) { \
691  return static_cast<subclass_ *>(me)->action_ ## _h(); } \
692  QP::QState subclass_::action_ ## _h(void)
693 
695 #define QM_HANDLED() (Q_RET_HANDLED)
696 
699 #define QM_UNHANDLED() (Q_RET_UNHANDLED)
700 
702 #define QM_SUPER() (Q_RET_SUPER)
703 
706 #define QM_STATE_NULL (nullptr)
707 
708 #endif // QEP_HPP
709 
unsigned int uint16_t
Definition: 16bit/stdint.h:30
unsigned long int uint32_t
Definition: 16bit/stdint.h:31
signed int int_fast8_t
Definition: 16bit/stdint.h:35
unsigned char uint8_t
Definition: 16bit/stdint.h:29
unsigned int uint_fast8_t
Definition: 16bit/stdint.h:36
Provides miscellaneous QEP services.
Definition: qep.hpp:601
static char_t const * getVersion(void) noexcept
get the current QEP version number string of the form "X.Y.Z"
Definition: qep.hpp:604
Definition: qf.hpp:496
static constexpr QState Q_RET_SUPER_SUB
event passed to submachine superstate
Definition: qep.hpp:317
QState qm_tran_init(void const *const tatbl) noexcept
Definition: qep.hpp:397
QState qm_tran_hist(QMState const *const hist, void const *const tatbl) noexcept
Definition: qep.hpp:387
static constexpr QState Q_RET_HANDLED
event handled (internal transition)
Definition: qep.hpp:323
friend class QMsm
Definition: qep.hpp:469
static constexpr QState Q_RET_SUPER
event passed to the superstate to handle
Definition: qep.hpp:314
QState tran_hist(QStateHandler const hist) noexcept
Helper function to specify a transition to history.
Definition: qep.hpp:360
static constexpr QState Q_RET_UNHANDLED
event unhandled due to a guard evaluating to 'false'
Definition: qep.hpp:320
QState qm_entry(QMState const *const s) noexcept
Helper function to specify a state entry in a QM state-handler.
Definition: qep.hpp:421
virtual void dispatch(QEvt const *const e, std::uint_fast8_t const qs_id)
Dispatches an event to QHsm.
Definition: qep_hsm.cpp:242
static constexpr QState Q_RET_IGNORED
event silently ignored (bubbled up to top)
Definition: qep.hpp:326
ReservedHsmSignals
Definition: qep.hpp:371
@ Q_INIT_SIG
signal for nested initial transitions
Definition: qep.hpp:374
@ Q_EXIT_SIG
signal for exit actions
Definition: qep.hpp:373
@ Q_ENTRY_SIG
signal for entry actions
Definition: qep.hpp:372
QState tran(QStateHandler const target) noexcept
Helper function to specify a state transition.
Definition: qep.hpp:354
QState qm_tran_xp(QActionHandler const xp, void const *const tatbl) noexcept
Definition: qep.hpp:411
static QState top(void *const me, QEvt const *const e) noexcept
the top-state.
Definition: qep_hsm.cpp:224
virtual void init(std::uint_fast8_t const qs_id)
overloaded init(qs_id)
Definition: qep.hpp:282
virtual QStateHandler getStateHandler() noexcept
Get the current state handler of the HSM.
Definition: qep_hsm.cpp:539
virtual ~QHsm()
virtual destructor
Definition: qep_hsm.cpp:126
QState qm_tran_ep(void const *const tatbl) noexcept
Definition: qep.hpp:404
virtual void init(void const *const e, std::uint_fast8_t const qs_id)
executes the top-most initial transition in QP::QHsm
Definition: qep_hsm.cpp:139
static constexpr QState Q_RET_TRAN_EP
entry-point transition into a submachine
Definition: qep.hpp:344
QState qm_super_sub(QMState const *const s) noexcept
Definition: qep.hpp:456
static constexpr QState Q_RET_TRAN_INIT
initial transition taken
Definition: qep.hpp:341
static constexpr QState Q_RET_NULL
return value without any effect
Definition: qep.hpp:335
static constexpr QState Q_RET_TRAN
regular transition taken
Definition: qep.hpp:338
QStateHandler childState(QStateHandler const parent) noexcept
Definition: qep_hsm.cpp:600
QHsmAttr m_state
current active state (state-variable)
Definition: qep.hpp:270
static constexpr QState Q_RET_EXIT
state exit action executed
Definition: qep.hpp:332
static constexpr std::int_fast8_t MAX_NEST_DEPTH_
< maximum nesting depth of states in HSM
Definition: qep.hpp:463
QState qm_exit(QMState const *const s) noexcept
Helper function to specify a state exit in a QM state-handler.
Definition: qep.hpp:427
QStateHandler state(void) const noexcept
Definition: qep.hpp:296
QState super(QStateHandler const superstate) noexcept
Helper function to specify the superstate of a given state.
Definition: qep.hpp:366
QState qm_tran(void const *const tatbl) noexcept
Definition: qep.hpp:380
bool isIn(QStateHandler const s) noexcept
Definition: qep_hsm.cpp:557
static constexpr QState Q_RET_TRAN_HIST
transition to history of a given state
Definition: qep.hpp:347
QHsmAttr m_temp
temporary: transition chain, target state, etc.
Definition: qep.hpp:271
static constexpr QState Q_RET_TRAN_XP
exit-point transition out of a submachine
Definition: qep.hpp:350
std::int_fast8_t hsm_tran(QStateHandler(&path)[MAX_NEST_DEPTH_], std::uint_fast8_t const qs_id)
internal helper function to take a transition in QP::QHsm
Definition: qep_hsm.cpp:404
static constexpr QState Q_RET_ENTRY
state entry action executed
Definition: qep.hpp:329
QState qm_sm_exit(QMState const *const s) noexcept
Helper function to specify a submachine exit in a QM state-handler.
Definition: qep.hpp:449
QHsm(QStateHandler const initial) noexcept
Protected constructor of QHsm.
Definition: qep_hsm.cpp:117
void exitToTranSource_(QMState const *s, QMState const *const ts, std::uint_fast8_t const qs_id)
Internal helper function to exit current state to transition source.
Definition: qep_msm.cpp:415
bool isIn(QStateHandler const s) noexcept=delete
static QMState const msm_top_s
the top state object for the QMsm
Definition: qep.hpp:569
QStateHandler getStateHandler() noexcept override
Get the current state handler of the QMsm.
Definition: qep_msm.cpp:321
QStateHandler state(void) const noexcept=delete
static QState top(void *const me, QEvt const *const e) noexcept=delete
QMState const * stateObj(void) const noexcept
Return the current active state object (read only)
Definition: qep.hpp:519
QState execTatbl_(QMTranActTable const *const tatbl, std::uint_fast8_t const qs_id)
Internal helper function to execute a transition-action table.
Definition: qep_msm.cpp:340
void dispatch(QEvt const *const e, std::uint_fast8_t const qs_id) override
Dispatches an event to a HSM.
Definition: qep_msm.cpp:149
static constexpr std::int_fast8_t MAX_ENTRY_DEPTH_
maximum depth of implemented entry levels for transitions to history
Definition: qep.hpp:566
void init(std::uint_fast8_t const qs_id) override
overloaded init(qs_id)
Definition: qep.hpp:507
QMState const * childStateObj(QMState const *const parent) const noexcept
Obtain the current active child state of a given parent (read only)
Definition: qep_msm.cpp:554
QStateHandler childState(QStateHandler const parent) noexcept=delete
QState enterHistory_(QMState const *const hist, std::uint_fast8_t const qs_id)
Internal helper function to enter state history.
Definition: qep_msm.cpp:456
void init(void const *const e, std::uint_fast8_t const qs_id) override
Definition: qep_msm.cpp:101
bool isInState(QMState const *const st) const noexcept
Tests if a given state is part of the active state configuration.
Definition: qep_msm.cpp:524
Definition: qs.hpp:302
Definition: qxk.hpp:144
Definition: struct.dox:1
std::uint_fast8_t QState
Type returned from state-handler functions.
Definition: qep.hpp:223
void(*)(QXThread *const me) QXThreadHandler
Pointer to a thread-handler function.
Definition: qep.hpp:232
QActionHandler const act[1]
Definition: qep.hpp:595
void QF_EVT_REF_CTR_INC_(QEvt const *const e) noexcept
increment the refCtr_ of an event e
Definition: qf_pkg.hpp:150
QMState const * obj
pointer to QMState object
Definition: qep.hpp:242
QMTranActTable const * tatbl
transition-action table
Definition: qep.hpp:243
QActionHandler const entryAction
entry action handler function
Definition: qep.hpp:587
QMState const * superstate
superstate of this state
Definition: qep.hpp:585
constexpr char_t const versionStr[]
the current QP version number string based on QP_VERSION_STR
Definition: qep.hpp:133
QState(*)(void *const me) QActionHandler
Pointer to an action-handler function.
Definition: qep.hpp:229
QMState const * target
Definition: qep.hpp:594
constexpr enum_t Q_USER_SIG
Offset or the user signals.
Definition: qep.hpp:610
std::uint8_t QF_EVT_POOL_ID_(QEvt const *const e) noexcept
return the Pool-ID of an event e
Definition: qf_pkg.hpp:140
QActionHandler const initAction
init action handler function
Definition: qep.hpp:589
QState(*)(void *const me, QEvt const *const e) QStateHandler
Pointer to state-handler function.
Definition: qep.hpp:226
QActionHandler const exitAction
exit action handler function
Definition: qep.hpp:588
QStateHandler const stateHandler
state handler function
Definition: qep.hpp:586
QXThreadHandler thr
pointer to an thread-handler function
Definition: qep.hpp:241
QStateHandler fun
pointer to a state handler function
Definition: qep.hpp:239
std::uint16_t QSignal
Definition: qep.hpp:146
void QF_EVT_REF_CTR_DEC_(QEvt const *const e) noexcept
decrement the refCtr_ of an event e
Definition: qf_pkg.hpp:155
std::uint8_t QF_EVT_REF_CTR_(QEvt const *const e) noexcept
return the Reference Conter of an event e
Definition: qf_pkg.hpp:145
QActionHandler act
pointer to an action-handler function
Definition: qep.hpp:240
Transition-Action Table for the QP::QMsm State Machine.
Definition: qep.hpp:593
char char_t
Definition: qassert.h:77
int int_t
Definition: qassert.h:86
int enum_t
alias for enumerations used for event signals
Definition: qep.hpp:82
float float32_t
Definition: qep.hpp:91
#define QP_VERSION_STR
The current QP version number string of the form XX.Y.Z, where XX is.
Definition: qep.hpp:51
double float64_t
Definition: qep.hpp:100
QSignal sig
signal of the event instance
Definition: qep.hpp:210
std::uint8_t volatile refCtr_
reference counter
Definition: qep.hpp:212
std::uint8_t poolId_
pool ID (0 for static event)
Definition: qep.hpp:211