QP/C++  7.2.2
Real-Time Embedded Framework
Loading...
Searching...
No Matches
qep_hsm.cpp
Go to the documentation of this file.
1//$file${src::qf::qep_hsm.cpp} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
2//
3// Model: qpcpp.qm
4// File: ${src::qf::qep_hsm.cpp}
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) : qpcpp
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${src::qf::qep_hsm.cpp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
39//! @file
40//! @brief QP::QHsm implementation
41//!
42//! @tr{RQP103} @tr{RQP104} @tr{RQP120} @tr{RQP130}
43
44#define QP_IMPL // this is QP implementation
45#include "qep_port.hpp" // QEP port
46#ifdef Q_SPY // QS software tracing enabled?
47 #include "qs_port.hpp" // QS port
48 #include "qs_pkg.hpp" // QS facilities for pre-defined trace records
49#else
50 #include "qs_dummy.hpp" // disable the QS software tracing
51#endif // Q_SPY
52#include "qassert.h" // QP embedded systems-friendly assertions
53
54//============================================================================
55//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
56// Check for the minimum required QP version
57#if (QP_VERSION < 700U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U))
58#error qpcpp version 7.0.0 or higher required
59#endif
60//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
61
62//$define${QEP::versionStr[]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
63namespace QP {
64
65} // namespace QP
66//$enddef${QEP::versionStr[]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
67
68//============================================================================
69// unnamed namespace for local definitions with internal linkage
70namespace {
71Q_DEFINE_THIS_MODULE("qep_hsm")
72
73//----------------------------------------------------------------------------
74//! Immutable events corresponding to the reserved signals.
75//!
76//! @details
77//! Static, immutable reserved events that the QEP event processor sends
78//! to state handler functions of QHsm-style state machine to execute entry
79//! actions, exit actions, and initial transitions.
80//!
81static QP::QEvt const l_reservedEvt_[4] {
82#ifdef Q_EVT_CTOR // Is the QEvt constructor provided?
85 QP::QEvt(static_cast<QP::QSignal>(QP::QHsm::Q_EXIT_SIG), 0U),
87#else // QEvt is a POD (Plain Old Datatype)
88 { static_cast<QP::QSignal>(QP::QHsm::Q_EMPTY_SIG), 0U, 0U },
89 { static_cast<QP::QSignal>(QP::QHsm::Q_ENTRY_SIG), 0U, 0U },
90 { static_cast<QP::QSignal>(QP::QHsm::Q_EXIT_SIG), 0U, 0U },
91 { static_cast<QP::QSignal>(QP::QHsm::Q_INIT_SIG), 0U, 0U }
92#endif
93};
94
95//----------------------------------------------------------------------------
96// inline helper functions
97
98//............................................................................
99//! helper function to trigger reserved event in an QHsm
100//!
101//! @param[in] state state handler function
102//! @param[in] sig reserved signal to trigger
103static inline QP::QState hsm_reservedEvt_(
104 QP::QHsm * const me,
105 QP::QStateHandler const state,
106 enum QP::QHsm::ReservedSig const sig)
107{
108 return (*state)(me, &l_reservedEvt_[sig]);
109}
110
111//............................................................................
112//! Helper function to execute entry into a given state in a
113//! hierarchical state machine (HSM).
114//!
115//! @param[in] state state handler function
116//! @param[in] qs_id QS-id of this state machine (for QS local filter)
117static inline void hsm_state_entry_(
118 QP::QHsm * const me,
119 QP::QStateHandler const state,
120 std::uint_fast8_t const qs_id)
121{
122#ifdef Q_SPY
123 if ((*state)(me, &l_reservedEvt_[QP::QHsm::Q_ENTRY_SIG])
125 {
128 QS_OBJ_PRE_(me);
129 QS_FUN_PRE_(state);
131 }
132#else
133 Q_UNUSED_PAR(qs_id);
134 static_cast<void>((*state)(me, &l_reservedEvt_[QP::QHsm::Q_ENTRY_SIG]));
135#endif // Q_SPY
136}
137
138//............................................................................
139//! Helper function to execute exit from a given state in a
140//! hierarchical state machine (HSM).
141//!
142//! @param[in] state state handler function
143//! @param[in] qs_id QS-id of this state machine (for QS local filter)
144//!
145//! @returns
146//! 'true' if the exit action has been found in the state and
147//! 'flase' otherwise.
148static inline bool hsm_state_exit_(
149 QP::QHsm * const me,
150 QP::QStateHandler const state,
151 std::uint_fast8_t const qs_id)
152{
153#ifdef Q_SPY
154 bool isHandled;
155 if ((*state)(me, &l_reservedEvt_[QP::QHsm::Q_EXIT_SIG])
157 {
160 QS_OBJ_PRE_(me);
161 QS_FUN_PRE_(state);
163 isHandled = true;
164 }
165 else {
166 isHandled = false;
167 }
168 return isHandled;
169#else
170 Q_UNUSED_PAR(qs_id);
171 return (*state)(me, &l_reservedEvt_[QP::QHsm::Q_EXIT_SIG]);
172#endif // Q_SPY
173}
174
175} // unnamed namespace
176
177//$define${QEP::QHsm} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
178namespace QP {
179
180//${QEP::QHsm} ...............................................................
181
182//${QEP::QHsm::QHsm} .........................................................
183QHsm::QHsm(QStateHandler const initial) noexcept{
184 m_state.fun = Q_STATE_CAST(&top);
185 m_temp.fun = initial;
186}
187
188//${QEP::QHsm::init} .........................................................
190 void const * const e,
191 std::uint_fast8_t const qs_id)
192{
193 #ifdef Q_SPY
194 if ((QS::priv_.flags & 0x01U) == 0U) {
195 QS::priv_.flags |= 0x01U;
197 }
198 #else
199 Q_UNUSED_PAR(qs_id);
200 #endif
201
203
204 //! @pre ctor must have been executed and initial tran NOT taken
205 Q_REQUIRE_ID(200, (m_temp.fun != nullptr)
206 && (t == Q_STATE_CAST(&top)));
207
208 // execute the top-most initial transition
209 QState r = (*m_temp.fun)(this, Q_EVT_CAST(QEvt));
210
211 // the top-most initial transition must be taken
212 Q_ASSERT_ID(210, r == Q_RET_TRAN);
213
216 QS_OBJ_PRE_(this); // this state machine object
217 QS_FUN_PRE_(t); // the source state
218 QS_FUN_PRE_(m_temp.fun); // the target of the initial transition
220
221 // drill down into the state hierarchy with initial transitions...
222 do {
223 QStateHandler path[MAX_NEST_DEPTH_]; // tran entry path array
224 std::int_fast8_t ip = 0; // entry path index
225
226 path[0] = m_temp.fun;
227 static_cast<void>(hsm_reservedEvt_(this, m_temp.fun, Q_EMPTY_SIG));
228 while (m_temp.fun != t) {
229 ++ip;
230 Q_ASSERT_ID(220, ip < MAX_NEST_DEPTH_);
231 path[ip] = m_temp.fun;
232 static_cast<void>(hsm_reservedEvt_(this, m_temp.fun, Q_EMPTY_SIG));
233 }
234 m_temp.fun = path[0];
235
236 // retrace the entry path in reverse (desired) order...
237 do {
238 hsm_state_entry_(this, path[ip], qs_id); // enter path[ip]
239 --ip;
240 } while (ip >= 0);
241
242 t = path[0]; // current state becomes the new source
243
244 r = hsm_reservedEvt_(this, t, Q_INIT_SIG); // execute initial tran.
245
246 #ifdef Q_SPY
247 if (r == Q_RET_TRAN) {
249 QS_OBJ_PRE_(this); // this state machine object
250 QS_FUN_PRE_(t); // the source state
251 QS_FUN_PRE_(m_temp.fun); // the target of the initial tran.
253 }
254 #endif // Q_SPY
255
256 } while (r == Q_RET_TRAN);
257
259 QS_TIME_PRE_(); // time stamp
260 QS_OBJ_PRE_(this); // this state machine object
261 QS_FUN_PRE_(t); // the new active state
263
264 m_state.fun = t; // change the current active state
265 m_temp.fun = t; // mark the configuration as stable
266}
267
268//${QEP::QHsm::dispatch} .....................................................
270 QEvt const * const e,
271 std::uint_fast8_t const qs_id)
272{
273 #ifndef Q_SPY
274 Q_UNUSED_PAR(qs_id);
275 #endif
276
279
280 //! @pre the current state must be initialized and
281 //! the state configuration must be stable
282 Q_REQUIRE_ID(400, (t != nullptr)
283 && (t == m_temp.fun));
284
286 QS_TIME_PRE_(); // time stamp
287 QS_SIG_PRE_(e->sig); // the signal of the event
288 QS_OBJ_PRE_(this); // this state machine object
289 QS_FUN_PRE_(t); // the current state
291
293 QState r;
294 // process the event hierarchically...
295 //! @tr{RQP120A}
296 do {
297 s = m_temp.fun;
298 r = (*s)(this, e); // invoke state handler s
299
300 if (r == Q_RET_UNHANDLED) { // unhandled due to a guard?
301
303 QS_SIG_PRE_(e->sig); // the signal of the event
304 QS_OBJ_PRE_(this); // this state machine object
305 QS_FUN_PRE_(s); // the current state
307
308 r = hsm_reservedEvt_(this, s, Q_EMPTY_SIG); // find superstate of s
309 }
310 } while (r == Q_RET_SUPER);
311
312 // regular transition taken?
313 //! @tr{RQP120E}
314 if (r >= Q_RET_TRAN) {
316
317 path[0] = m_temp.fun; // save the target of the transition
318 path[1] = t;
319 path[2] = s;
320
321 // exit current state to transition source s...
322 //! @tr{RQP120C}
323 for (; t != s; t = m_temp.fun) {
324 // exit handled?
325 if (hsm_state_exit_(this, t, qs_id)) {
326 // find superstate of t
327 static_cast<void>(hsm_reservedEvt_(this, t, Q_EMPTY_SIG));
328 }
329 }
330
331 std::int_fast8_t ip = hsm_tran(path, qs_id); // the HSM transition
332
333 #ifdef Q_SPY
334 if (r == Q_RET_TRAN_HIST) {
335
337 QS_OBJ_PRE_(this); // this state machine object
338 QS_FUN_PRE_(t); // the source of the transition
339 QS_FUN_PRE_(path[0]); // the target of the tran. to history
341
342 }
343 #endif // Q_SPY
344
345 // execute state entry actions in the desired order...
346 //! @tr{RQP120B}
347 for (; ip >= 0; --ip) {
348 hsm_state_entry_(this, path[ip], qs_id); // enter path[ip]
349 }
350 t = path[0]; // stick the target into register
351 m_temp.fun = t; // update the next state
352
353 // drill into the target hierarchy...
354 //! @tr{RQP120I}
355 while (hsm_reservedEvt_(this, t, Q_INIT_SIG) == Q_RET_TRAN) {
356
358 QS_OBJ_PRE_(this); // this state machine object
359 QS_FUN_PRE_(t); // the source (pseudo)state
360 QS_FUN_PRE_(m_temp.fun); // the target of the transition
362
363 ip = 0;
364 path[0] = m_temp.fun;
365
366 // find superstate
367 static_cast<void>(hsm_reservedEvt_(this, m_temp.fun, Q_EMPTY_SIG));
368
369 while (m_temp.fun != t) {
370 ++ip;
371 path[ip] = m_temp.fun;
372 // find superstate
373 static_cast<void>(
374 hsm_reservedEvt_(this, m_temp.fun, Q_EMPTY_SIG));
375 }
376 m_temp.fun = path[0];
377
378 // entry path must not overflow
379 Q_ASSERT_ID(410, ip < MAX_NEST_DEPTH_);
380
381 // retrace the entry path in reverse (correct) order...
382 do {
383 hsm_state_entry_(this, path[ip], qs_id); // enter path[ip]
384 --ip;
385 } while (ip >= 0);
386
387 t = path[0];
388 }
389
391 QS_TIME_PRE_(); // time stamp
392 QS_SIG_PRE_(e->sig); // the signal of the event
393 QS_OBJ_PRE_(this); // this state machine object
394 QS_FUN_PRE_(s); // the source of the transition
395 QS_FUN_PRE_(t); // the new active state
397 }
398
399 #ifdef Q_SPY
400 else if (r == Q_RET_HANDLED) {
401
403 QS_TIME_PRE_(); // time stamp
404 QS_SIG_PRE_(e->sig); // the signal of the event
405 QS_OBJ_PRE_(this); // this state machine object
406 QS_FUN_PRE_(s); // the source state
408
409 }
410 else {
411
413 QS_TIME_PRE_(); // time stamp
414 QS_SIG_PRE_(e->sig); // the signal of the event
415 QS_OBJ_PRE_(this); // this state machine object
416 QS_FUN_PRE_(m_state.fun);// the current state
418
419 }
420 #else
421 Q_UNUSED_PAR(qs_id); // when Q_SPY not defined
422 #endif // Q_SPY
423
424 m_state.fun = t; // change the current active state
425 m_temp.fun = t; // mark the configuration as stable
426}
427
428//${QEP::QHsm::top} ..........................................................
430 void * const me,
431 QEvt const * const e) noexcept
432{
433 Q_UNUSED_PAR(me);
434 Q_UNUSED_PAR(e);
435 return Q_RET_IGNORED; // the top state ignores all events
436}
437
438//${QEP::QHsm::isIn} .........................................................
439bool QHsm::isIn(QStateHandler const s) noexcept {
440 //! @pre state configuration must be stable
441 Q_REQUIRE_ID(600, m_temp.fun == m_state.fun);
442
443 bool inState = false; // assume that this HSM is not in 'state'
444
445 // scan the state hierarchy bottom-up
446 QState r;
447 do {
448 // do the states match?
449 if (m_temp.fun == s) {
450 inState = true; // 'true' means that match found
451 r = Q_RET_IGNORED; // cause breaking out of the loop
452 }
453 else {
454 r = hsm_reservedEvt_(this, m_temp.fun, Q_EMPTY_SIG);
455 }
456 } while (r != Q_RET_IGNORED); // QHsm::top() state not reached
457 m_temp.fun = m_state.fun; // restore the stable state configuration
458
459 return inState; // return the status
460}
461
462//${QEP::QHsm::childState} ...................................................
464 QStateHandler child = m_state.fun; // start with the current state
465 bool isFound = false; // start with the child not found
466
467 // establish stable state configuration
468 m_temp.fun = m_state.fun;
469 QState r;
470 do {
471 // is this the parent of the current child?
472 if (m_temp.fun == parent) {
473 isFound = true; // child is found
474 r = Q_RET_IGNORED; // cause breaking out of the loop
475 }
476 else {
477 child = m_temp.fun;
478 r = hsm_reservedEvt_(this, m_temp.fun, Q_EMPTY_SIG);
479 }
480 } while (r != Q_RET_IGNORED); // QHsm::top() state not reached
481 m_temp.fun = m_state.fun; // establish stable state configuration
482
483 //! @post the child must be confirmed
484 Q_ENSURE_ID(810, isFound);
485
486 #ifdef Q_NASSERT
487 Q_UNUSED_PAR(isFound);
488 #endif
489
490 return child; // return the child
491}
492
493//${QEP::QHsm::hsm_tran} .....................................................
494std::int_fast8_t QHsm::hsm_tran(
495 QStateHandler (&path)[MAX_NEST_DEPTH_],
496 std::uint_fast8_t const qs_id)
497{
498 #ifndef Q_SPY
499 Q_UNUSED_PAR(qs_id);
500 #endif
501
502 std::int_fast8_t ip = -1; // transition entry path index
503 QStateHandler t = path[0];
504 QStateHandler const s = path[2];
505
506 // (a) check source==target (transition to self)
507 if (s == t) {
508 // exit the source
509 static_cast<void>(hsm_state_exit_(this, s, qs_id));
510 ip = 0; // enter the target
511 }
512 else {
513 // superstate of target
514 static_cast<void>(hsm_reservedEvt_(this, t, Q_EMPTY_SIG));
515 t = m_temp.fun;
516
517 // (b) check source==target->super
518 if (s == t) {
519 ip = 0; // enter the target
520 }
521 else {
522 // superstate of src
523 static_cast<void>(hsm_reservedEvt_(this, s, Q_EMPTY_SIG));
524
525 // (c) check source->super==target->super
526 if (m_temp.fun == t) {
527 // exit the source
528 static_cast<void>(hsm_state_exit_(this, s, qs_id));
529 ip = 0; // enter the target
530 }
531 else {
532 // (d) check source->super==target
533 if (m_temp.fun == path[0]) {
534 // exit the source
535 static_cast<void>(hsm_state_exit_(this, s, qs_id));
536 }
537 else {
538 // (e) check rest of source==target->super->super..
539 // and store the entry path along the way
540 std::int_fast8_t iq = 0; // indicate that LCA was found
541 ip = 1; // enter target and its superstate
542 path[1] = t; // save the superstate of target
543 t = m_temp.fun; // save source->super
544
545 // find target->super->super
546 QState r = hsm_reservedEvt_(this, path[1], Q_EMPTY_SIG);
547 while (r == Q_RET_SUPER) {
548 ++ip;
549 path[ip] = m_temp.fun; // store the entry path
550 if (m_temp.fun == s) { // is it the source?
551 // indicate that the LCA was found
552 iq = 1;
553
554 // entry path must not overflow
555 Q_ASSERT_ID(510, ip < MAX_NEST_DEPTH_);
556 --ip; // do not enter the source
557 r = Q_RET_HANDLED; // terminate the loop
558 }
559 // it is not the source, keep going up
560 else {
561 r = hsm_reservedEvt_(this, m_temp.fun, Q_EMPTY_SIG);
562 }
563 }
564
565 // the LCA not found yet?
566 if (iq == 0) {
567 // entry path must not overflow
568 Q_ASSERT_ID(520, ip < MAX_NEST_DEPTH_);
569
570 // exit the source
571 static_cast<void>(hsm_state_exit_(this, s, qs_id));
572
573 // (f) check the rest of source->super
574 // == target->super->super...
575 //
576 iq = ip;
577 r = Q_RET_IGNORED; // indicate LCA NOT found
578 do {
579 // is this the LCA?
580 if (t == path[iq]) {
581 r = Q_RET_HANDLED; // indicate LCA found
582 ip = iq - 1; // do not enter LCA
583 iq = -1; // cause termination of the loop
584 }
585 else {
586 --iq; // try lower superstate of target
587 }
588 } while (iq >= 0);
589
590 // LCA not found yet?
591 if (r != Q_RET_HANDLED) {
592 // (g) check each source->super->...
593 // for each target->super...
594 //
595 r = Q_RET_IGNORED; // keep looping
596 do {
597 // exit from t handled?
598 if (hsm_state_exit_(this, t, qs_id)) {
599 // find superstate of t
600 static_cast<void>(
601 hsm_reservedEvt_(this, t, Q_EMPTY_SIG));
602 }
603 t = m_temp.fun; // set to super of t
604 iq = ip;
605 do {
606 // is this LCA?
607 if (t == path[iq]) {
608 ip = iq - 1; // do not enter LCA
609 iq = -1; // break out of inner loop
610 r = Q_RET_HANDLED; // break outer loop
611 }
612 else {
613 --iq;
614 }
615 } while (iq >= 0);
616 } while (r != Q_RET_HANDLED);
617 }
618 }
619 }
620 }
621 }
622 }
623 return ip;
624
625}
626
627} // namespace QP
628//$enddef${QEP::QHsm} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Event class.
Definition: qep.hpp:163
QSignal sig
signal of the event instance RQP002
Definition: qep.hpp:168
Hierarchical State Machine abstract base class (ABC)
Definition: qep.hpp:293
static constexpr std::int_fast8_t MAX_NEST_DEPTH_
Maximum nesting depth of states in HSM.
Definition: qep.hpp:305
bool isIn(QStateHandler const s) noexcept
Tests if a given state is part of the current active state configuration.
Definition: qep_hsm.cpp:439
QStateHandler childState(QStateHandler const parent) noexcept
Obtain the current active child state of a given parent.
Definition: qep_hsm.cpp:463
ReservedSig
Reserved signals by the HSM-style state machine implementation strategy.
Definition: qep.hpp:329
@ Q_EXIT_SIG
signal for exit actions
Definition: qep.hpp:332
@ Q_ENTRY_SIG
signal for entry actions
Definition: qep.hpp:331
@ Q_INIT_SIG
signal for nested initial transitions
Definition: qep.hpp:333
@ Q_EMPTY_SIG
signal to execute the default case
Definition: qep.hpp:330
std::int_fast8_t hsm_tran(QStateHandler(&path)[MAX_NEST_DEPTH_], std::uint_fast8_t const qs_id)
Definition: qep_hsm.cpp:494
QHsmAttr m_temp
temporary: transition chain, target state, etc.
Definition: qep.hpp:300
static QState top(void *const me, QEvt const *const e) noexcept
The top-state handler.
Definition: qep_hsm.cpp:429
QHsm(QStateHandler const initial) noexcept
protected constructor of QHsm
Definition: qep_hsm.cpp:183
QHsmAttr m_state
current active state (the state-variable)
Definition: qep.hpp:297
virtual void dispatch(QEvt const *const e, std::uint_fast8_t const qs_id)
Dispatches an event to QP::QHsm.
Definition: qep_hsm.cpp:269
@ Q_RET_IGNORED
event silently ignored (bubbled up to top)
Definition: qep.hpp:345
@ Q_RET_TRAN
regular transition
Definition: qep.hpp:355
@ Q_RET_TRAN_HIST
transition to history of a given state
Definition: qep.hpp:360
@ Q_RET_SUPER
event passed to superstate to handle
Definition: qep.hpp:339
@ Q_RET_HANDLED
event handled (internal transition)
Definition: qep.hpp:344
@ Q_RET_UNHANDLED
event unhandled due to a guard
Definition: qep.hpp:341
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:189
QStx priv_
the only instance of the QS-TX object (Singleton)
Definition: qs.cpp:65
std::uint8_t flags
flags for internal use
Definition: qs.hpp:381
QP/C++ framework.
QState(*)(void *const me, QEvt const *const e) QStateHandler
Pointer to state-handler function.
Definition: qep.hpp:213
QStateHandler fun
pointer to a state handler function
Definition: qep.hpp:261
std::uint16_t QSignal
QSignal represents the signal of an event.
Definition: qep.hpp:134
std::uint_fast8_t QState
Type returned from state-handler functions.
Definition: qep.hpp:209
@ QS_QEP_DISPATCH
an event was dispatched (begin of RTC step)
Definition: qs.hpp:164
@ QS_QEP_STATE_ENTRY
a state was entered
Definition: qs.hpp:157
@ QS_QEP_STATE_EXIT
a state was exited
Definition: qs.hpp:158
@ QS_QEP_TRAN_HIST
a tran to history was taken
Definition: qs.hpp:237
@ QS_QEP_IGNORED
an event was ignored (silently discarded)
Definition: qs.hpp:163
@ QS_QEP_UNHANDLED
an event was unhandled due to a guard
Definition: qs.hpp:165
@ QS_QEP_STATE_INIT
an initial transition was taken in a state
Definition: qs.hpp:159
@ QS_QEP_TRAN
a regular transition was taken
Definition: qs.hpp:162
@ QS_QEP_INIT_TRAN
the top-most initial transition was taken
Definition: qs.hpp:160
@ QS_QEP_INTERN_TRAN
an internal transition was taken
Definition: qs.hpp:161
Customizable and memory-efficient Design by Contract (DbC) for embedded systems.
#define Q_ENSURE_ID(id_, expr_)
Definition: qassert.h:243
#define Q_REQUIRE_ID(id_, expr_)
Definition: qassert.h:220
#define Q_ASSERT_ID(id_, expr_)
Definition: qassert.h:97
#define Q_EVT_CAST(subclass_)
Perform downcast of an event onto a subclass of QEvt class_
Definition: qep.hpp:867
#define Q_UNUSED_PAR(par_)
Helper macro to clearly mark unused parameters of functions.
Definition: qep.hpp:953
#define Q_STATE_CAST(handler_)
Macro to perform casting to QStateHandler.
Definition: qep.hpp:876
QEP/C++ sample port with all configurable options.
#define QS_CRIT_STAT_
This is an internal macro for defining the critical section status type.
Definition: qs.hpp:1398
#define QS_TIME_PRE_()
Output time stamp to a QS record (used in predefined and application-specific trace records)
Definition: qs.hpp:1137
#define QS_FUN_DICTIONARY(fun_)
Output function dictionary record.
Definition: qs.hpp:1303
Internal (package scope) QS/C++ interface.
#define QS_BEGIN_PRE_(rec_, qs_id_)
Internal QS macro to begin a predefined QS record with critical section.
Definition: qs_pkg.hpp:119
#define QS_OBJ_PRE_(obj_)
Internal QS macro to output object pointer data element.
Definition: qs_pkg.hpp:190
#define QS_FUN_PRE_(fun_)
Internal QS macro to output an unformatted function pointer data element.
Definition: qs_pkg.hpp:212
#define QS_END_PRE_()
Internal QS macro to end a predefined QS record with critical section.
Definition: qs_pkg.hpp:130
QS/C++ sample port with all configurable options.