qep.h 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204
  1. /*$file${include::qep.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
  2. /*
  3. * Model: qpc.qm
  4. * File: ${include::qep.h}
  5. *
  6. * This code has been generated by QM 5.2.5 <www.state-machine.com/qm>.
  7. * DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
  8. *
  9. * This code is covered by the following QP license:
  10. * License # : LicenseRef-QL-dual
  11. * Issued to : Any user of the QP/C real-time embedded framework
  12. * Framework(s) : qpc
  13. * Support ends : 2023-12-31
  14. * License scope:
  15. *
  16. * Copyright (C) 2005 Quantum Leaps, LLC <state-machine.com>.
  17. *
  18. * SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
  19. *
  20. * This software is dual-licensed under the terms of the open source GNU
  21. * General Public License version 3 (or any later version), or alternatively,
  22. * under the terms of one of the closed source Quantum Leaps commercial
  23. * licenses.
  24. *
  25. * The terms of the open source GNU General Public License version 3
  26. * can be found at: <www.gnu.org/licenses/gpl-3.0>
  27. *
  28. * The terms of the closed source Quantum Leaps commercial licenses
  29. * can be found at: <www.state-machine.com/licensing>
  30. *
  31. * Redistributions in source code must retain this top-level comment block.
  32. * Plagiarizing this software to sidestep the license obligations is illegal.
  33. *
  34. * Contact information:
  35. * <www.state-machine.com/licensing>
  36. * <info@state-machine.com>
  37. */
  38. /*$endhead${include::qep.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  39. /*! @file
  40. * @brief QEP/C platform-independent public interface.
  41. *
  42. * @trace
  43. * @tr{RQP001}, @tr{RQP101}
  44. */
  45. #ifndef QEP_H_
  46. #define QEP_H_
  47. /*==========================================================================*/
  48. /*! The current QP version as an unsigned number
  49. *
  50. * @details
  51. * ::QP_VERSION is a decimal constant, where XX is a 1-digit or 2-digit
  52. * major version number, Y is a 1-digit minor version number, and Z is
  53. * a 1-digit release number.
  54. */
  55. #define QP_VERSION 722U
  56. /*! The current QP version as a zero terminated string literal.
  57. *
  58. * @details
  59. * ::QP_VERSION_STR is of the form "XX.Y.Z", where XX is a 1-or 2-digit
  60. * major version number, Y is a 1-digit minor version number, and Z is
  61. * a 1-digit release number.
  62. */
  63. #define QP_VERSION_STR "7.2.2"
  64. /*! Encrypted current QP release (7.2.2) and date (2023-03-01) */
  65. #define QP_RELEASE 0x76BAD85DU
  66. /*==========================================================================*/
  67. /*$declare${glob-types} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
  68. /*${glob-types::int_t} .....................................................*/
  69. /*! alias for line numbers in assertions and return from QF_run() */
  70. typedef int int_t;
  71. /*${glob-types::enum_t} ....................................................*/
  72. /*! alias for enumerations used for event signals */
  73. typedef int enum_t;
  74. /*${glob-types::float32_t} .................................................*/
  75. /*! alias for IEEE 754 32-bit floating point number,
  76. * MISRA-C 2012 Dir 4.6(A)
  77. *
  78. * @note
  79. * QP does not use floating-point types anywhere in the internal
  80. * implementation, except in QS software tracing, where utilities for
  81. * output of floating-point numbers are provided for application-specific
  82. * trace records.
  83. */
  84. typedef float float32_t;
  85. /*${glob-types::float64_t} .................................................*/
  86. /*! alias for IEEE 754 64-bit floating point number,
  87. * MISRA-C 2012 Dir 4.6(A)
  88. *
  89. * @note
  90. * QP does not use floating-point types anywhere in the internal
  91. * implementation, except in QS software tracing, where utilities for
  92. * output of floating-point numbers are provided for application-specific
  93. * trace records.
  94. */
  95. typedef double float64_t;
  96. /*$enddecl${glob-types} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  97. /*$declare${QEP-config} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
  98. /*${QEP-config::Q_SIGNAL_SIZE} .............................................*/
  99. #ifndef Q_SIGNAL_SIZE
  100. /*! The size (in bytes) of the signal of an event. Valid values:
  101. * 1U, 2U, or 4U; default 2U
  102. *
  103. * @details
  104. * This macro can be defined in the QEP port file (qep_port.h) to
  105. * configure the ::QSignal type. When the macro is not defined, the
  106. * default of 2 bytes is applied.
  107. */
  108. #define Q_SIGNAL_SIZE 2U
  109. #endif /* ndef Q_SIGNAL_SIZE */
  110. /*$enddecl${QEP-config} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  111. /*==========================================================================*/
  112. /*$declare${QEP} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
  113. /*${QEP::QP_versionStr[8]} .................................................*/
  114. /*! the current QP version number string in ROM, based on #QP_VERSION_STR */
  115. extern char const QP_versionStr[8];
  116. /*${QEP::QSignal} ..........................................................*/
  117. #if (Q_SIGNAL_SIZE == 2U)
  118. /*! ::QSignal represents the signal of an event
  119. *
  120. * @details
  121. * The relationship between an event and a signal is as follows. A signal
  122. * in UML is the specification of an asynchronous stimulus that triggers
  123. * reactions, and as such is an essential part of an event. (The signal
  124. * conveys the type of the occurrence--what happened?) However, an event
  125. * can also contain additional quantitative information about the
  126. * occurrence in form of event parameters.
  127. */
  128. typedef uint16_t QSignal;
  129. #endif /* (Q_SIGNAL_SIZE == 2U) */
  130. /*${QEP::QSignal} ..........................................................*/
  131. #if (Q_SIGNAL_SIZE == 1U)
  132. typedef uint8_t QSignal;
  133. #endif /* (Q_SIGNAL_SIZE == 1U) */
  134. /*${QEP::QSignal} ..........................................................*/
  135. #if (Q_SIGNAL_SIZE == 4U)
  136. typedef uint32_t QSignal;
  137. #endif /* (Q_SIGNAL_SIZE == 4U) */
  138. /*${QEP::QEvt} .............................................................*/
  139. /*! @brief Event class
  140. * @class QEvt
  141. *
  142. * @details
  143. * ::QEvt represents events without parameters and serves as the base class
  144. * for derivation of events with parameters.
  145. *
  146. * @trace
  147. * @tr{RQP001}, @tr{RQP004}, @tr{AQP210}
  148. *
  149. * @usage
  150. * The following example illustrates how to add an event parameter by
  151. * derivation of the ::QEvt class. Please note that the ::QEvt member
  152. * super is defined as the FIRST member of the derived struct.
  153. * @include qep_qevt.c
  154. */
  155. typedef struct {
  156. /* public: */
  157. /*! Signal of the event.
  158. * @public @memberof QEvt
  159. *
  160. * @trace
  161. * @tr{RQP002}
  162. */
  163. QSignal sig;
  164. /* private: */
  165. /*! Pool ID (==0 for immutable event)
  166. * @private @memberof QEvt
  167. *
  168. * @trace
  169. * @tr{RQP003}
  170. */
  171. uint8_t poolId_;
  172. /*! Reference counter (for mutable events)
  173. * @private @memberof QEvt
  174. *
  175. * @trace
  176. * @tr{RQP003}
  177. */
  178. uint8_t volatile refCtr_;
  179. } QEvt;
  180. /* public: */
  181. #ifdef Q_EVT_CTOR
  182. /*! Custom event constructor
  183. * @public @memberof QEvt
  184. *
  185. * @note
  186. * Available only when the macro #Q_EVT_CTOR is defined
  187. *
  188. * @trace
  189. * @tr{RQP005}
  190. */
  191. void QEvt_ctor(QEvt * const me,
  192. enum_t const sig);
  193. #endif /* def Q_EVT_CTOR */
  194. /*${QEP::QStateRet} ........................................................*/
  195. /*! All possible values returned from state/action handlers
  196. *
  197. * @note
  198. * The order matters for algorithmic correctness.
  199. */
  200. enum QStateRet {
  201. /* unhandled and need to "bubble up" */
  202. Q_RET_SUPER, /*!< event passed to superstate to handle */
  203. Q_RET_SUPER_SUB, /*!< event passed to submachine superstate */
  204. Q_RET_UNHANDLED, /*!< event unhandled due to a guard */
  205. /* handled and do not need to "bubble up" */
  206. Q_RET_HANDLED, /*!< event handled (internal transition) */
  207. Q_RET_IGNORED, /*!< event silently ignored (bubbled up to top) */
  208. /* entry/exit */
  209. Q_RET_ENTRY, /*!< state entry action executed */
  210. Q_RET_EXIT, /*!< state exit action executed */
  211. /* no side effects */
  212. Q_RET_NULL, /*!< return value without any effect */
  213. /* transitions need to execute transition-action table in ::QMsm */
  214. Q_RET_TRAN, /*!< regular transition */
  215. Q_RET_TRAN_INIT, /*!< initial transition in a state or submachine */
  216. Q_RET_TRAN_EP, /*!< entry-point transition into a submachine */
  217. /* transitions that additionally clobber me->state */
  218. Q_RET_TRAN_HIST, /*!< transition to history of a given state */
  219. Q_RET_TRAN_XP /*!< exit-point transition out of a submachine */
  220. };
  221. /*${QEP::QState} ...........................................................*/
  222. /*! Type returned from state-handler functions */
  223. typedef enum QStateRet QState;
  224. /*${QEP::QStateHandler} ....................................................*/
  225. /*! Pointer to a state-handler function. */
  226. typedef QState (* QStateHandler )(void * const me, QEvt const * const e);
  227. /*${QEP::QActionHandler} ...................................................*/
  228. /*! Pointer to an action-handler function. */
  229. typedef QState (* QActionHandler )(void * const me);
  230. /*${QEP::QXThread} .........................................................*/
  231. /* forward declaration */
  232. struct QXThread;
  233. /*${QEP::QXThreadHandler} ..................................................*/
  234. /*! Pointer to an eXthended thread handler function */
  235. typedef void (* QXThreadHandler )(struct QXThread * const me);
  236. /*${QEP::QMState} ..........................................................*/
  237. /*! @brief State object for the ::QMsm class (QM State Machine).
  238. *
  239. * @details
  240. * This class groups together the attributes of a ::QMsm state, such as the
  241. * parent state (state nesting), the associated state handler function and
  242. * the exit action handler function. These attributes are used inside the
  243. * QMsm_dispatch() and QMsm_init() functions.
  244. *
  245. * @trace
  246. * @tr{RQP104}
  247. *
  248. * @attention
  249. * The ::QMState class is only intended for the QM code generator and should
  250. * not be used in hand-crafted code.
  251. */
  252. typedef struct QMState {
  253. struct QMState const *superstate; /*!< superstate of this state */
  254. QStateHandler const stateHandler; /*!< state handler function */
  255. QActionHandler const entryAction; /*!< entry action handler function */
  256. QActionHandler const exitAction; /*!< exit action handler function */
  257. QActionHandler const initAction; /*!< init action handler function */
  258. } QMState;
  259. /*${QEP::QMTranActTable} ...................................................*/
  260. /*! @brief Transition-Action Table for the ::QMsm State Machine. */
  261. typedef struct QMTranActTable {
  262. QMState const *target; /*!< target of the transition */
  263. QActionHandler const act[1]; /*!< array of actions */
  264. } QMTranActTable;
  265. /*${QEP::QHsmAttr} .........................................................*/
  266. /*! @brief Attribute of for the ::QHsm class (Hierarchical State Machine).
  267. *
  268. * @details
  269. * This union represents possible values stored in the 'state' and 'temp'
  270. * attributes of the ::QHsm class.
  271. */
  272. union QHsmAttr {
  273. QStateHandler fun; /*!< @private pointer to a state-handler */
  274. QActionHandler act; /*!< @private pointer to an action-handler */
  275. QXThreadHandler thr; /*!< @private pointer to an thread-handler */
  276. QMTranActTable const *tatbl; /*!< @private transition-action table */
  277. struct QMState const *obj; /*!< @private pointer to QMState object */
  278. };
  279. /*${QEP::QReservedSig} .....................................................*/
  280. /*! Reserved signals by the HSM-style state machine
  281. * implementation strategy.
  282. */
  283. enum QReservedSig {
  284. Q_EMPTY_SIG, /*!< signal to execute the default case */
  285. Q_ENTRY_SIG, /*!< signal for coding entry actions */
  286. Q_EXIT_SIG, /*!< signal for coding exit actions */
  287. Q_INIT_SIG, /*!< signal for coding initial transitions */
  288. Q_USER_SIG /*!< offset for the user signals (QP Application) */
  289. };
  290. /*${QEP::QHsm} .............................................................*/
  291. /*! @brief Hierarchical State Machine class
  292. * @class QHsm
  293. *
  294. * @details
  295. * ::QHsm represents a Hierarchical State Machine (HSM) with full support for
  296. * hierarchical nesting of states, entry/exit actions, initial transitions,
  297. * and transitions to history in any composite state. This class is designed
  298. * for ease of manual coding of HSMs in C, but it is also supported by the
  299. * QM modeling tool.<br>
  300. *
  301. * ::QHsm is also the base class for the QMsm state machine, which provides
  302. * a superior efficiency, but requires the use of the QM modeling tool to
  303. * generate code.
  304. *
  305. * @note
  306. * ::QHsm is not intended to be instantiated directly, but rather serves as the
  307. * abstract base class for derivation of state machines in the QP application.
  308. *
  309. * @trace
  310. * @tr{RQP103}, @tr{AQP211}
  311. *
  312. * @usage
  313. * The following example illustrates how to derive a state machine class
  314. * from QHsm. Please note that the QHsm member `super` is defined as the
  315. * FIRST member of the derived class.
  316. * @include qep_qhsm.c
  317. */
  318. typedef struct {
  319. /* private: */
  320. /*! Virtual pointer
  321. * @private @memberof QHsm
  322. *
  323. * @trace
  324. * @tr{RQP102}
  325. */
  326. struct QHsmVtable const * vptr;
  327. /* protected: */
  328. /*! Current active state (state-variable).
  329. * @private @memberof QHsm
  330. */
  331. union QHsmAttr state;
  332. /*! Temporary: target/act-table, etc.
  333. * @private @memberof QHsm
  334. */
  335. union QHsmAttr temp;
  336. } QHsm;
  337. /* public: */
  338. /*! Tests if a given state is part of the current active state
  339. * configuration in ::QHsm subclasses.
  340. * @public @memberof QHsm
  341. *
  342. * @details
  343. * Tests if a state machine derived from QHsm is-in a given state.
  344. *
  345. * @note For a HSM, to "be in a state" means also to be in a superstate of
  346. * of the state.
  347. *
  348. * @param[in] me current instance pointer (see @ref oop)
  349. * @param[in] state pointer to the state-handler function to be tested
  350. *
  351. * @returns
  352. *'true' if the HSM "is in" the `state` and 'false' otherwise
  353. *
  354. * @precondition{qep_hsm,600}
  355. * - the state configuration must be stable
  356. *
  357. * @trace
  358. * @tr{RQP103}, @tr{RQP120S}
  359. */
  360. bool QHsm_isIn(QHsm * const me,
  361. QStateHandler const state);
  362. /*! Obtain the current active state from a HSM (read only).
  363. * @public @memberof QHsm
  364. *
  365. * @param[in] me current instance pointer (see @ref oop)
  366. *
  367. * @returns the current active state of the QHsm class
  368. *
  369. * @note
  370. * This function is used in QM for auto-generating code for state history.
  371. */
  372. static inline QStateHandler QHsm_state(QHsm * const me) {
  373. return me->state.fun;
  374. }
  375. /*! Obtain the current active child state of a given parent in ::QHsm
  376. * @public @memberof QHsm
  377. *
  378. * @details
  379. * Finds the child state of the given `parent`, such that this child state
  380. * is an ancestor of the currently active state. The main purpose of this
  381. * function is to support **shallow history** transitions in state machines
  382. * derived from QHsm.
  383. *
  384. * @param[in] me current instance pointer (see @ref oop)
  385. * @param[in] parent pointer to the state-handler function
  386. *
  387. * @returns
  388. * the child of a given `parent` state, which is an ancestor of the current
  389. * active state. For the corner case when the currently active state is the
  390. * given `parent` state, function returns the `parent` state.
  391. *
  392. * @postcondition{qep_hsm,890}
  393. * - the child must be found
  394. *
  395. * @note
  396. * this function is designed to be called during state transitions, so it
  397. * does not necessarily start in a stable state configuration.
  398. * However, the function establishes stable state configuration upon exit.
  399. *
  400. * @trace
  401. * @tr{RQP103}, @tr{RQP120H}
  402. */
  403. QStateHandler QHsm_childState(QHsm * const me,
  404. QStateHandler const parent);
  405. /* protected: */
  406. /*! Protected "constructor" of ::QHsm
  407. * @protected @memberof QHsm
  408. *
  409. * @details
  410. * Performs the first step of HSM initialization by assigning the initial
  411. * pseudostate to the currently active state of the state machine.
  412. *
  413. * @param[in,out] me current instance pointer (see @ref oop)
  414. * @param[in] initial pointer to the top-most initial state-handler
  415. * function in the derived state machine
  416. *
  417. * @note Must be called only by the constructors of the derived state
  418. * machines.
  419. *
  420. * @note Must be called only ONCE before QHSM_INIT().
  421. *
  422. * @usage
  423. * The following example illustrates how to invoke QHsm_ctor() in the
  424. * "constructor" of a derived state machine:
  425. * @include qep_qhsm_ctor.c
  426. *
  427. * @trace
  428. * @tr{RQP103}
  429. */
  430. void QHsm_ctor(QHsm * const me,
  431. QStateHandler const initial);
  432. /*! The top-state of QHsm.
  433. * @protected @memberof QHsm
  434. *
  435. * @details
  436. * QHsm_top() is the ultimate root of state hierarchy in all HSMs derived
  437. * from ::QHsm.
  438. *
  439. * @param[in] me current instance pointer (see @ref oop)
  440. * @param[in] e pointer to the event to be dispatched to the FSM
  441. *
  442. * @returns
  443. * Always returns ::Q_RET_IGNORED, which means that the top state ignores
  444. * all events.
  445. *
  446. * @note The parameters to this state handler are not used. They are provided
  447. * for conformance with the state-handler function signature ::QStateHandler.
  448. *
  449. * @trace
  450. * @tr{RQP103}, @tr{RQP120T}
  451. */
  452. QState QHsm_top(QHsm const * const me,
  453. QEvt const * const e);
  454. /*! Implementation of the top-most initial tran. in ::QHsm.
  455. * @protected @memberof QHsm
  456. *
  457. * @details
  458. * Executes the top-most initial transition in a HSM.
  459. *
  460. * @param[in,out] me current instance pointer (see @ref oop)
  461. * @param[in] e pointer to an extra parameter (might be NULL)
  462. * @param[in] qs_id QS-id of this state machine (for QS local filter)
  463. *
  464. * @precondition{qep_hsm,200}
  465. * - the virtual pointer must be initialized,
  466. * - the top-most initial transition must be initialized,
  467. * - the initial transition must not be taken yet.
  468. *
  469. * @note Must be called only ONCE after the QHsm_ctor().
  470. *
  471. * @trace
  472. * @tr{RQP103}, @tr{RQP120I}, @tr{RQP120D}
  473. */
  474. void QHsm_init_(QHsm * const me,
  475. void const * const e,
  476. uint_fast8_t const qs_id);
  477. /*! Implementation of dispatching events to a ::QHsm
  478. * @protected @memberof QHsm
  479. *
  480. * @details
  481. * Dispatches an event for processing to a hierarchical state machine (HSM).
  482. * The processing of an event represents one run-to-completion (RTC) step.
  483. *
  484. * @param[in,out] me current instance pointer (see @ref oop)
  485. * @param[in] e pointer to the event to be dispatched to the HSM
  486. * @param[in] qs_id QS-id of this state machine (for QS local filter)
  487. *
  488. * @precondition{qep_hsm,400}
  489. * - the current state must be initialized and
  490. * - the state configuration must be stable
  491. *
  492. * @note
  493. * This function should be called only via the virtual table (see
  494. * QHSM_DISPATCH()) and should NOT be called directly in the applications.
  495. *
  496. * @trace
  497. * @tr{RQP103}, @tr{RQP120A}, @tr{RQP120B}, @tr{RQP120C},
  498. * @tr{RQP120D}, @tr{RQP120E}, @tr{RQP120E}, @tr{RQP120C},
  499. * @tr{RQP120B}
  500. */
  501. void QHsm_dispatch_(QHsm * const me,
  502. QEvt const * const e,
  503. uint_fast8_t const qs_id);
  504. /* private: */
  505. #ifdef Q_SPY
  506. /*! Implementation of getting the state handler in a ::QHsm subclass
  507. * @private @memberof QHsm
  508. */
  509. QStateHandler QHsm_getStateHandler_(QHsm * const me);
  510. #endif /* def Q_SPY */
  511. /*! Helper function to execute transition sequence in a hierarchical state
  512. * machine (HSM).
  513. *
  514. * @param[in,out] path array of pointers to state-handler functions
  515. * to execute the entry actions
  516. * @param[in] qs_id QS-id of this state machine (for QS local filter)
  517. *
  518. * @returns
  519. * the depth of the entry path stored in the `path` parameter.
  520. *
  521. * @trace
  522. * @tr{RQP103}, @tr{RQP120E}, @tr{RQP120F}
  523. */
  524. int_fast8_t QHsm_tran_(QHsm * const me,
  525. QStateHandler * const path,
  526. uint_fast8_t const qs_id);
  527. /*! Helper function to execute entry into a given state in a
  528. * hierarchical state machine (HSM).
  529. * @private @memberof QHsm
  530. *
  531. * @param[in] state state handler function
  532. * @param[in] qs_id QS-id of this state machine (for QS local filter)
  533. */
  534. void QHsm_state_entry_(QHsm * const me,
  535. QStateHandler const state,
  536. uint_fast8_t const qs_id);
  537. /*! Helper function to execute exit from a given state in a
  538. * hierarchical state machine (HSM).
  539. * @private @memberof QHsm
  540. *
  541. * @param[in] state state handler function
  542. * @param[in] qs_id QS-id of this state machine (for QS local filter)
  543. *
  544. * @returns
  545. * 'true' if the exit action has been found in the state and
  546. * 'flase' otherwise.
  547. */
  548. bool QHsm_state_exit_(QHsm * const me,
  549. QStateHandler const state,
  550. uint_fast8_t const qs_id);
  551. /*${QEP::QHsmVtable} .......................................................*/
  552. /*! @brief Virtual table for the ::QHsm class.
  553. *
  554. * @trace
  555. * @tr{RQP102}
  556. */
  557. struct QHsmVtable {
  558. /*! Triggers the top-most initial transition in the HSM. */
  559. void (*init)(QHsm * const me, void const * const e,
  560. uint_fast8_t const qs_id);
  561. /*! Dispatches an event to the HSM. */
  562. void (*dispatch)(QHsm * const me, QEvt const * const e,
  563. uint_fast8_t const qs_id);
  564. #ifdef Q_SPY
  565. /*! Get the current state handler of the HSM. */
  566. QStateHandler (*getStateHandler)(QHsm * const me);
  567. #endif /* Q_SPY */
  568. };
  569. /*${QEP::QMsm} .............................................................*/
  570. /*! @brief QM state machine implementation strategy
  571. * @class QMsm
  572. * @extends QHsm
  573. *
  574. * @details
  575. * QMsm (QM State Machine) provides a more efficient state machine
  576. * implementation strategy than ::QHsm, but requires the use of the QM
  577. * modeling tool, but are the fastest and need the least run-time
  578. * support (the smallest event-processor taking up the least code space).
  579. *
  580. * @note
  581. * QMsm is not intended to be instantiated directly, but rather serves
  582. * as the abstrace base class for derivation of state machines in the
  583. * application code.
  584. *
  585. * @trace
  586. * @tr{RQP104}
  587. *
  588. * @usage
  589. * The following example illustrates how to derive a state machine class
  590. * from QMsm. Please note that the QMsm member `super` is defined
  591. * as the *first* member of the derived struct.
  592. * @include qep_qmsm.c
  593. */
  594. typedef struct {
  595. /* protected: */
  596. QHsm super;
  597. } QMsm;
  598. /* public: */
  599. /*! Tests if a given state is part of the current active state
  600. * configuration in a MSM.
  601. * @public @memberof QMsm
  602. *
  603. * @details
  604. * Tests if a state machine derived from QMsm is-in a given state.
  605. *
  606. * @note
  607. * For a MSM, to "be-in" a state means also to "be-in" a superstate of
  608. * of the state.
  609. *
  610. * @param[in] me current instance pointer (see @ref oop)
  611. * @param[in] state pointer to the QMState object that corresponds to the
  612. * tested state.
  613. * @returns
  614. * 'true' if the MSM "is in" the `state` and 'false' otherwise
  615. */
  616. bool QMsm_isInState(QMsm const * const me,
  617. QMState const * const state);
  618. /*! Obtain the current active state from a MSM (read only)
  619. * @public @memberof QMsm
  620. *
  621. * @param[in] me current instance pointer (see @ref oop)
  622. *
  623. * @returns the current active state-object
  624. *
  625. * @note
  626. * This function is used in QM for auto-generating code for state history
  627. */
  628. QMState const * QMsm_stateObj(QHsm const * const me);
  629. /*! Obtain the current active child state of a given parent in ::QMsm
  630. * @public @memberof QMsm
  631. *
  632. * @details
  633. * Finds the child state of the given @c parent, such that this child state
  634. * is an ancestor of the currently active state. The main purpose of this
  635. * function is to support **shallow history** transitions in state machines
  636. * derived from QMsm.
  637. *
  638. * @param[in] me current instance pointer (see @ref oop)
  639. * @param[in] parent pointer to the state-handler object
  640. *
  641. * @returns
  642. * the child of a given @c parent state, which is an ancestor of
  643. * the currently active state. For the corner case when the currently active
  644. * state is the given @c parent state, function returns the @c parent state.
  645. *
  646. * @postcondition{qep_msm,890}
  647. * - the child must be found
  648. *
  649. * @sa QMsm_childStateObj()
  650. */
  651. QMState const * QMsm_childStateObj(
  652. QHsm const * const me,
  653. QMState const * const parent);
  654. /* protected: */
  655. /*! Constructor of ::QMsm
  656. * @protected @memberof QMsm
  657. *
  658. * @details
  659. * Performs the first step of QMsm initialization by assigning the initial
  660. * pseudostate to the currently active state of the state machine.
  661. *
  662. * @param[in,out] me current instance pointer (see @ref oop)
  663. * @param[in] initial the top-most initial transition for the MSM.
  664. *
  665. * @note
  666. * Must be called only ONCE before QHSM_INIT().
  667. *
  668. * @note
  669. * QMsm inherits QHsm, so by the @ref oop convention it should call the
  670. * constructor of the superclass, i.e., QHsm_ctor(). However, this would pull
  671. * in the QHsmVtable, which in turn will pull in the code for QHsm_init_() and
  672. * QHsm_dispatch_() implemetations. To avoid this code size penalty, in case
  673. * ::QHsm is not used in a given project, the QMsm_ctor() performs direct
  674. * intitialization of the Vtable, which avoids pulling in the code for QMsm.
  675. *
  676. * @usage
  677. * The following example illustrates how to invoke QMsm_ctor() in the
  678. * "constructor" of a derived state machine:
  679. * @include qep_qmsm_ctor.c
  680. */
  681. void QMsm_ctor(QMsm * const me,
  682. QStateHandler const initial);
  683. /* public: */
  684. /*! Implementation of the top-most initial tran. in ::QMsm.
  685. * @private @memberof QMsm
  686. *
  687. * @details
  688. * Executes the top-most initial transition in a MSM.
  689. *
  690. * @param[in,out] me current instance pointer (see @ref oop)
  691. * @param[in] e pointer to an extra parameter (might be NULL)
  692. * @param[in] qs_id QS-id of this state machine (for QS local filter)
  693. *
  694. * @precondition{qep_msm,200}
  695. * - the virtual pointer must be initialized,
  696. * - the top-most initial transition must be initialized,
  697. * - the initial transition must not be taken yet.
  698. *
  699. * @note
  700. * This function should be called only via the virtual table (see
  701. * QHSM_INIT()) and should NOT be called directly in the applications.
  702. */
  703. void QMsm_init_(
  704. QHsm * const me,
  705. void const * const e,
  706. uint_fast8_t const qs_id);
  707. /* private: */
  708. /*! Implementation of dispatching events to a ::QMsm
  709. * @private @memberof QMsm
  710. *
  711. * @details
  712. * Dispatches an event for processing to a meta state machine (MSM).
  713. * The processing of an event represents one run-to-completion (RTC) step.
  714. *
  715. * @param[in,out] me current instance pointer (see @ref oop)
  716. * @param[in] e pointer to the event to be dispatched to the MSM
  717. * @param[in] qs_id QS-id of this state machine (for QS local filter)
  718. *
  719. * @precondition{qep_msm,300}
  720. * - current state must be initialized
  721. *
  722. * @note
  723. * This function should be called only via the virtual table (see
  724. * QHSM_DISPATCH()) and should NOT be called directly in the applications.
  725. */
  726. void QMsm_dispatch_(
  727. QHsm * const me,
  728. QEvt const * const e,
  729. uint_fast8_t const qs_id);
  730. /* public: */
  731. #ifdef Q_SPY
  732. /*! Implementation of getting the state handler in a ::QMsm subclass
  733. * @public @memberof QMsm
  734. */
  735. QStateHandler QMsm_getStateHandler_(QHsm * const me);
  736. #endif /* def Q_SPY */
  737. /* private: */
  738. /*! Execute transition-action table
  739. * @private @memberof QMsm
  740. *
  741. * @details
  742. * Helper function to execute transition sequence in a transition-action table.
  743. *
  744. * @param[in,out] me current instance pointer (see @ref oop)
  745. * @param[in] tatbl pointer to the transition-action table
  746. * @param[in] qs_id QS-id of this state machine (for QS local filter)
  747. *
  748. * @returns
  749. * status of the last action from the transition-action table.
  750. *
  751. * @note
  752. * This function is for internal use inside the QEP event processor and
  753. * should **not** be called directly from the applications.
  754. */
  755. QState QMsm_execTatbl_(
  756. QHsm * const me,
  757. QMTranActTable const * const tatbl,
  758. uint_fast8_t const qs_id);
  759. /*! Exit the current state up to the explicit transition source
  760. * @private @memberof QMsm
  761. *
  762. * @details
  763. * Static helper function to exit the current state configuration to the
  764. * transition source, which in a hierarchical state machine might be a
  765. * superstate of the current state.
  766. *
  767. * @param[in,out] me current instance pointer (see @ref oop)
  768. * @param[in] cs pointer to the current state
  769. * @param[in] ts pointer to the transition source state
  770. * @param[in] qs_id QS-id of this state machine (for QS local filter)
  771. */
  772. void QMsm_exitToTranSource_(
  773. QHsm * const me,
  774. QMState const * const cs,
  775. QMState const * const ts,
  776. uint_fast8_t const qs_id);
  777. /*! Enter history of a composite state
  778. * @private @memberof QMsm
  779. *
  780. * @details
  781. * Static helper function to execute the segment of transition to history
  782. * after entering the composite state and
  783. *
  784. * @param[in,out] me current instance pointer (see @ref oop)
  785. * @param[in] hist pointer to the history substate
  786. * @param[in] qs_id QS-id of this state machine (for QS local filter)
  787. *
  788. * @returns
  789. * #Q_RET_TRAN_INIT, if an initial transition has been executed in the last
  790. * entered state or #Q_RET_NULL if no such transition was taken.
  791. */
  792. QState QMsm_enterHistory_(
  793. QHsm * const me,
  794. QMState const *const hist,
  795. uint_fast8_t const qs_id);
  796. /*$enddecl${QEP} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  797. /*==========================================================================*/
  798. /*$declare${QEP-macros} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
  799. /*${QEP-macros::QHSM_INIT} .................................................*/
  800. #ifdef Q_SPY
  801. /*! Virtual call to the top-most initial transition in a HSM.
  802. *
  803. * @param[in,out] me_ current instance pointer (see @ref oop)
  804. * @param[in] par_ pointer the optional initialization parameter
  805. * @param[in] qs_id_ QS local filter ID (used only when Q_SPY is defined)
  806. *
  807. * @note Must be called only ONCE after the SM "constructor".
  808. *
  809. * @trace
  810. * @tr{RQP102}
  811. *
  812. * @usage
  813. * The following example illustrates how to initialize a SM, and dispatch
  814. * events to it:
  815. * @include qep_qhsm_use.c
  816. */
  817. #define QHSM_INIT(me_, par_, qs_id_) do { \
  818. Q_ASSERT((me_)->vptr); \
  819. (*(me_)->vptr->init)((me_), (par_), (qs_id_)); \
  820. } while (false)
  821. #endif /* def Q_SPY */
  822. /*${QEP-macros::QHSM_INIT} .................................................*/
  823. #ifndef Q_SPY
  824. #define QHSM_INIT(me_, par_, dummy) do { \
  825. Q_ASSERT((me_)->vptr); \
  826. (*(me_)->vptr->init)((me_), (par_), 0U); \
  827. } while (false)
  828. #endif /* ndef Q_SPY */
  829. /*${QEP-macros::QHSM_DISPATCH} .............................................*/
  830. #ifdef Q_SPY
  831. /*! Virtual call to dispatch an event to a HSM
  832. *
  833. * @details
  834. * Processes one event at a time in Run-to-Completion fashion.
  835. *
  836. * @param[in,out] me_ current instance pointer (see @ref oop)
  837. * @param[in] e_ constant pointer the ::QEvt or a class
  838. * derived from ::QEvt (see @ref oop)
  839. * @param[in] qs_id_ QS local filter ID (used only when Q_SPY is defined)
  840. *
  841. * @note Must be called after the "constructor" and after QHSM_INIT().
  842. *
  843. * @trace
  844. * @tr{RQP102}
  845. */
  846. #define QHSM_DISPATCH(me_, e_, qs_id_) \
  847. ((*(me_)->vptr->dispatch)((me_), (e_), (qs_id_)))
  848. #endif /* def Q_SPY */
  849. /*${QEP-macros::QHSM_DISPATCH} .............................................*/
  850. #ifndef Q_SPY
  851. #define QHSM_DISPATCH(me_, e_, dummy) \
  852. ((*(me_)->vptr->dispatch)((me_), (e_), 0U))
  853. #endif /* ndef Q_SPY */
  854. /*${QEP-macros::Q_HSM_UPCAST} ..............................................*/
  855. /*! Perform upcast from a subclass of ::QHsm to the base class ::QHsm
  856. *
  857. * @details
  858. * Upcasting from a subclass to superclass is a very frequent and **safe**
  859. * operation in object-oriented programming and object-oriented languages
  860. * (such as C++) perform such upcasting automatically. However, OOP is
  861. * implemented in C just as a set of coding conventions (see @ref oop),
  862. * and the C compiler does not "know" that certain types are related by
  863. * inheritance. Therefore for C, the upcast must be performed explicitly.
  864. * Unfortunately, pointer casting violates the advisory MISRA-C 2012
  865. * Rule 11.3(req) "A cast shall not be performed between a pointer to object
  866. * type and a pointer to a different object type". This macro encapsulates
  867. * this deviation and provides a descriptive name for the reason of this cast.
  868. */
  869. #define Q_HSM_UPCAST(ptr_) ((QHsm *)(ptr_))
  870. /*${QEP-macros::Q_TRAN} ....................................................*/
  871. /*! Perform upcast from a subclass of ::QHsm to the base class ::QHsm
  872. *
  873. * @details
  874. * Upcasting from a subclass to superclass is a very frequent and **safe**
  875. * operation in object-oriented programming and object-oriented languages
  876. * (such as C++) perform such upcasting automatically. However, OOP is
  877. * implemented in C just as a set of coding conventions (see @ref oop),
  878. * and the C compiler does not "know" that certain types are related by
  879. * inheritance. Therefore for C, the upcast must be performed explicitly.
  880. * Unfortunately, pointer casting violates the advisory MISRA-C 2012
  881. * Rule 11.3(req) "A cast shall not be performed between a pointer to object
  882. * type and a pointer to a different object type". This macro encapsulates
  883. * this deviation and provides a descriptive name for the reason of this cast.
  884. */
  885. #define Q_TRAN(target_) \
  886. ((Q_HSM_UPCAST(me))->temp.fun = Q_STATE_CAST(target_), Q_RET_TRAN)
  887. /*${QEP-macros::Q_TRAN_HIST} ...............................................*/
  888. /*! Macro to call in a state-handler when it executes a transition
  889. * to history. Applicable only to HSMs.
  890. *
  891. * @trace
  892. * @tr{RQP103}, @tr{RQP120H}
  893. *
  894. * @usage
  895. * @include qep_qhist.c
  896. */
  897. #define Q_TRAN_HIST(hist_) \
  898. ((Q_HSM_UPCAST(me))->temp.fun = (hist_), Q_RET_TRAN_HIST)
  899. /*${QEP-macros::Q_SUPER} ...................................................*/
  900. /*! Macro to call in a state-handler when it designates the superstate
  901. * of a given state. Applicable only to ::QHsm subclasses.
  902. *
  903. * @trace
  904. * @tr{RQP103}
  905. *
  906. * @usage
  907. * @include qep_qsuper.c
  908. */
  909. #define Q_SUPER(super_) \
  910. ((Q_HSM_UPCAST(me))->temp.fun = Q_STATE_CAST(super_), Q_RET_SUPER)
  911. /*${QEP-macros::Q_HANDLED} .................................................*/
  912. /*! Macro to call in a state-handler when it handles an event.
  913. *
  914. * @trace
  915. * @tr{RQP103}, @tr{RQP120B}, @tr{RQP120C}
  916. */
  917. #define Q_HANDLED() (Q_RET_HANDLED)
  918. /*${QEP-macros::Q_UNHANDLED} ...............................................*/
  919. /*! Macro to call in a state-handler when it attempts to handle
  920. * an event but a guard condition evaluates to 'false' and there is no other
  921. * explicit way of handling the event. Applicable only to ::QHsm subclasses.
  922. */
  923. #define Q_UNHANDLED() (Q_RET_UNHANDLED)
  924. /*${QEP-macros::Q_ACTION_NULL} .............................................*/
  925. /*! Macro to provide strictly-typed zero-action to terminate action lists
  926. *! in the transition-action-tables
  927. */
  928. #define Q_ACTION_NULL ((QActionHandler)0)
  929. /*${QEP-macros::Q_EVT_CAST} ................................................*/
  930. /*! Perform downcast of an event onto a subclass of ::QEvt `class_`
  931. *
  932. * @details
  933. * This macro encapsulates the downcast of ::QEvt pointers, which violates
  934. * MISRA-C 2012 Rule 11.3(R) "A cast shall not be performed between a
  935. * pointer to object type and a pointer to a different object type". This
  936. * macro helps to localize this deviation.
  937. *
  938. * @param class_ a subclass of ::QEvt
  939. *
  940. * @trace
  941. * @tr{RQP003}, @tr{PQA11_3}
  942. */
  943. #define Q_EVT_CAST(class_) ((class_ const *)(e))
  944. /*${QEP-macros::Q_STATE_CAST} ..............................................*/
  945. /*! Perform cast to ::QStateHandler.
  946. * @details
  947. * This macro encapsulates the cast of a specific state handler function
  948. * pointer to ::QStateHandler, which violates MISRA:C-2012 Rule 11.1(req)
  949. * "Conversions shall not be performed between a pointer to function and
  950. * any other type". This macro helps to localize this deviation.
  951. *
  952. * @trace
  953. * @tr{PQP11_1}, @tr{PQA11_1}
  954. *
  955. * @usage
  956. * @include qep_qhsm_ctor.c
  957. */
  958. #define Q_STATE_CAST(handler_) ((QStateHandler)(handler_))
  959. /*${QEP-macros::Q_ACTION_CAST} .............................................*/
  960. /*! Perform cast to ::QActionHandler.
  961. * @details
  962. * This macro encapsulates the cast of a specific action handler function
  963. * pointer to ::QActionHandler, which violates MISRA:C-2012 Rule 11.1(R)
  964. * "Conversions shall not be performed between a pointer to function and
  965. * any other type". This macro helps to localize this deviation.
  966. *
  967. * @trace
  968. * @tr{PQP11_1}, @tr{PQA11_1}
  969. */
  970. #define Q_ACTION_CAST(action_) ((QActionHandler)(action_))
  971. /*${QEP-macros::Q_UNUSED_PAR} ..............................................*/
  972. /*! Helper macro to clearly mark unused parameters of functions. */
  973. #define Q_UNUSED_PAR(par_) ((void)(par_))
  974. /*${QEP-macros::Q_DIM} .....................................................*/
  975. /*! Helper macro to calculate static dimension of a 1-dim `array_`
  976. *
  977. * @param array_ 1-dimensional array
  978. * @returns the length of the array (number of elements it can hold)
  979. */
  980. #define Q_DIM(array_) (sizeof(array_) / sizeof((array_)[0U]))
  981. /*${QEP-macros::Q_UINT2PTR_CAST} ...........................................*/
  982. /*! Perform cast from unsigned integer `uint_` to pointer of type `type_`
  983. *
  984. * @details
  985. * This macro encapsulates the cast to (type_ *), which QP ports or
  986. * application might use to access embedded hardware registers.
  987. * Such uses can trigger PC-Lint "Note 923: cast from int to pointer"
  988. * and this macro helps to encapsulate this deviation.
  989. */
  990. #define Q_UINT2PTR_CAST(type_, uint_) ((type_ *)(uint_))
  991. /*${QEP-macros::QEVT_INITIALIZER} ..........................................*/
  992. /*! Initializer of static constant QEvt instances
  993. *
  994. * @details
  995. * This macro encapsulates the ugly casting of enumerated signals
  996. * to QSignal and constants for QEvt.poolID and QEvt.refCtr_.
  997. */
  998. #define QEVT_INITIALIZER(sig_) { (QSignal)(sig_), 0U, 0U }
  999. /*${QEP-macros::QM_ENTRY} ..................................................*/
  1000. #ifdef Q_SPY
  1001. /*! Macro to call in a QM action-handler when it executes
  1002. * an entry action. Applicable only to ::QMsm subclasses.
  1003. */
  1004. #define QM_ENTRY(state_) \
  1005. ((Q_HSM_UPCAST(me))->temp.obj = (state_), Q_RET_ENTRY)
  1006. #endif /* def Q_SPY */
  1007. /*${QEP-macros::QM_ENTRY} ..................................................*/
  1008. #ifndef Q_SPY
  1009. #define QM_ENTRY(dummy) (Q_RET_ENTRY)
  1010. #endif /* ndef Q_SPY */
  1011. /*${QEP-macros::QM_EXIT} ...................................................*/
  1012. #ifdef Q_SPY
  1013. /*! Macro to call in a QM action-handler when it executes
  1014. * an exit action. Applicable only to ::QMsm subclasses.
  1015. */
  1016. #define QM_EXIT(state_) \
  1017. ((Q_HSM_UPCAST(me))->temp.obj = (state_), Q_RET_EXIT)
  1018. #endif /* def Q_SPY */
  1019. /*${QEP-macros::QM_EXIT} ...................................................*/
  1020. #ifndef Q_SPY
  1021. #define QM_EXIT(dummy) (Q_RET_EXIT)
  1022. #endif /* ndef Q_SPY */
  1023. /*${QEP-macros::QM_SM_EXIT} ................................................*/
  1024. /*! Macro to call in a QM submachine exit-handler.
  1025. * Applicable only to subclasses of ::QMsm.
  1026. */
  1027. #define QM_SM_EXIT(state_) \
  1028. ((Q_HSM_UPCAST(me))->temp.obj = (state_), Q_RET_EXIT)
  1029. /*${QEP-macros::QM_TRAN} ...................................................*/
  1030. /*! Macro to call in a QM state-handler when it executes a regular
  1031. * transition. Applicable only to ::QMsm subclasses.
  1032. */
  1033. #define QM_TRAN(tatbl_) ((Q_HSM_UPCAST(me))->temp.tatbl \
  1034. = (struct QMTranActTable const *)(tatbl_), Q_RET_TRAN)
  1035. /*${QEP-macros::QM_TRAN_INIT} ..............................................*/
  1036. /*! Macro to call in a QM state-handler when it executes an initial
  1037. * transition. Applicable only to ::QMsm subclasses.
  1038. */
  1039. #define QM_TRAN_INIT(tatbl_) ((Q_HSM_UPCAST(me))->temp.tatbl \
  1040. = (struct QMTranActTable const *)(tatbl_), Q_RET_TRAN_INIT)
  1041. /*${QEP-macros::QM_TRAN_HIST} ..............................................*/
  1042. /*! Macro to call in a QM state-handler when it executes a transition
  1043. * to history. Applicable only to ::QMsm subclasses.
  1044. */
  1045. #define QM_TRAN_HIST(history_, tatbl_) \
  1046. ((((Q_HSM_UPCAST(me))->state.obj = (history_)), \
  1047. ((Q_HSM_UPCAST(me))->temp.tatbl = \
  1048. (struct QMTranActTable const *)(tatbl_))), \
  1049. Q_RET_TRAN_HIST)
  1050. /*${QEP-macros::QM_TRAN_EP} ................................................*/
  1051. /*! Macro to call in a QM state-handler when it executes a transition
  1052. * to the submachine via an entry point.
  1053. */
  1054. #define QM_TRAN_EP(tatbl_) ((Q_HSM_UPCAST(me))->temp.tatbl \
  1055. = (struct QMTranActTable const *)(tatbl_), Q_RET_TRAN_EP)
  1056. /*${QEP-macros::QM_TRAN_XP} ................................................*/
  1057. /*! Macro to call in a QM state-handler when it executes a transition
  1058. * to exit point. Applicable only to ::QMsm subclasses.
  1059. */
  1060. #define QM_TRAN_XP(xp_, tatbl_) \
  1061. ((((Q_HSM_UPCAST(me))->state.act = (xp_)), \
  1062. ((Q_HSM_UPCAST(me))->temp.tatbl = \
  1063. (struct QMTranActTable const *)(tatbl_))), \
  1064. Q_RET_TRAN_XP)
  1065. /*${QEP-macros::QM_HANDLED} ................................................*/
  1066. /*! Macro to call in a QM state-handler when it handled an event.
  1067. * Applicable only to ::QMsm subclasses.
  1068. */
  1069. #define QM_HANDLED() (Q_RET_HANDLED)
  1070. /*${QEP-macros::QM_UNHANDLED} ..............................................*/
  1071. /*! Macro to call in a QM state-handler when when it attempts to
  1072. * handle an event but a guard condition evaluates to 'false' and there is
  1073. * no other explicit way of handling the event. Applicable only to
  1074. * ::QMsm subclasses.
  1075. */
  1076. #define QM_UNHANDLED() (Q_RET_UNHANDLED)
  1077. /*${QEP-macros::QM_SUPER} ..................................................*/
  1078. /*! Macro to call in a QM state-handler when it designates the
  1079. * superstate to handle an event. Applicable only to QMSMs.
  1080. */
  1081. #define QM_SUPER() (Q_RET_SUPER)
  1082. /*${QEP-macros::QM_SUPER_SUB} ..............................................*/
  1083. /*! Macro to call in a QM submachine-handler when it designates the
  1084. * host state to handle an event. Applicable only to subclasses of ::QMsm.
  1085. */
  1086. #define QM_SUPER_SUB(host_) \
  1087. ((Q_HSM_UPCAST(me))->temp.obj = (host_), Q_RET_SUPER_SUB)
  1088. /*${QEP-macros::QM_STATE_NULL} .............................................*/
  1089. /*! Macro to provide strictly-typed zero-state to use for submachines.
  1090. *! Applicable to subclasses of ::QMsm.
  1091. */
  1092. #define QM_STATE_NULL ((QMState *)0)
  1093. /*$enddecl${QEP-macros} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  1094. #endif /* QEP_H_ */