QP/C++  7.3.3
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 6.1.1 <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 : 2024-12-31
14// License scope:
15//
16// Copyright (C) 2005 Quantum Leaps, LLC <state-machine.com>.
17//
18// Q u a n t u m L e a P s
19// ------------------------
20// Modern Embedded Software
21//
22// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
23//
24// This software is dual-licensed under the terms of the open source GNU
25// General Public License version 3 (or any later version), or alternatively,
26// under the terms of one of the closed source Quantum Leaps commercial
27// licenses.
28//
29// The terms of the open source GNU General Public License version 3
30// can be found at: <www.gnu.org/licenses/gpl-3.0>
31//
32// The terms of the closed source Quantum Leaps commercial licenses
33// can be found at: <www.state-machine.com/licensing>
34//
35// Redistributions in source code must retain this top-level comment block.
36// Plagiarizing this software to sidestep the license obligations is illegal.
37//
38// Contact information:
39// <www.state-machine.com/licensing>
40// <info@state-machine.com>
41//
42//$endhead${src::qf::qep_hsm.cpp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
43#define QP_IMPL // this is QP implementation
44#include "qp_port.hpp" // QP port
45#include "qp_pkg.hpp" // QP package-scope interface
46#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem
47#ifdef Q_SPY // QS software tracing enabled?
48 #include "qs_port.hpp" // QS port
49 #include "qs_pkg.hpp" // QS facilities for pre-defined trace records
50#else
51 #include "qs_dummy.hpp" // disable the QS software tracing
52#endif // Q_SPY
53
54//============================================================================
55//! @cond INTERNAL
56
57// unnamed namespace for local definitions with internal linkage
58namespace {
59Q_DEFINE_THIS_MODULE("qep_hsm")
60
61// immutable events corresponding to the reserved signals.
62static QP::QEvt const l_reservedEvt_[4] {
67};
68
69} // unnamed namespace
70
71// helper macro to handle reserved event in an QHsm
72#define QHSM_RESERVED_EVT_(state_, sig_) \
73 ((*(state_))(this, &l_reservedEvt_[(sig_)]))
74
75// helper macro to trace state entry
76#define QS_STATE_ENTRY_(state_, qsId_) \
77 QS_CRIT_ENTRY(); \
78 QS_MEM_SYS(); \
79 QS_BEGIN_PRE_(QS_QEP_STATE_ENTRY, (qsId_)) \
80 QS_OBJ_PRE_(this); \
81 QS_FUN_PRE_(state_); \
82 QS_END_PRE_() \
83 QS_MEM_APP(); \
84 QS_CRIT_EXIT()
85
86// helper macro to trace state exit
87#define QS_STATE_EXIT_(state_, qsId_) \
88 QS_CRIT_ENTRY(); \
89 QS_MEM_SYS(); \
90 QS_BEGIN_PRE_(QS_QEP_STATE_EXIT, (qsId_)) \
91 QS_OBJ_PRE_(this); \
92 QS_FUN_PRE_(state_); \
93 QS_END_PRE_() \
94 QS_MEM_APP(); \
95 QS_CRIT_EXIT()
96
97//! @endcond
98//============================================================================
99
100//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
101// Check for the minimum required QP version
102#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8U))
103#error qpcpp version 7.3.0 or higher required
104#endif
105//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
106
107//$define${QEP::versionStr[]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
108namespace QP {
109
110} // namespace QP
111//$enddef${QEP::versionStr[]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
112
113//$define${QEP::QHsm} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
114namespace QP {
115
116//${QEP::QHsm} ...............................................................
117
118//${QEP::QHsm::QHsm} .........................................................
119QHsm::QHsm(QStateHandler const initial) noexcept
120: QAsm()
121{
122 m_state.fun = Q_STATE_CAST(&top);
123 m_temp.fun = initial;
124}
125
126//${QEP::QHsm::init} .........................................................
128 void const * const e,
129 std::uint_fast8_t const qsId)
130{
132
133 #ifdef Q_SPY
135 QS_MEM_SYS();
136 if ((QS::priv_.flags & 0x01U) == 0U) {
137 QS::priv_.flags |= 0x01U;
138 QS_MEM_APP();
139 QS_CRIT_EXIT();
141 }
142 else {
143 QS_MEM_APP();
144 QS_CRIT_EXIT();
145 }
146 #else
147 Q_UNUSED_PAR(qsId);
148 #endif
149
151
153 Q_REQUIRE_INCRIT(200, (m_temp.fun != nullptr)
154 && (t == Q_STATE_CAST(&top)));
155 QF_CRIT_EXIT();
156
157 // execute the top-most initial tran.
158 QState r = (*m_temp.fun)(this, Q_EVT_CAST(QEvt));
159
161 // the top-most initial tran. must be taken
162 Q_ASSERT_INCRIT(210, r == Q_RET_TRAN);
163
164 QS_MEM_SYS();
165 QS_BEGIN_PRE_(QS_QEP_STATE_INIT, qsId)
166 QS_OBJ_PRE_(this); // this state machine object
167 QS_FUN_PRE_(t); // the source state
168 QS_FUN_PRE_(m_temp.fun); // the target of the initial tran.
169 QS_END_PRE_()
170 QS_MEM_APP();
171
172 QF_CRIT_EXIT();
173
174 // drill down into the state hierarchy with initial transitions...
175 std::int_fast8_t limit = MAX_NEST_DEPTH_; // loop hard limit
176 do {
177 QStateHandler path[MAX_NEST_DEPTH_]; // tran entry path array
178 std::int_fast8_t ip = 0; // tran entry path index
179
180 path[0] = m_temp.fun;
181 static_cast<void>(QHSM_RESERVED_EVT_(m_temp.fun, Q_EMPTY_SIG));
182 while (m_temp.fun != t) {
183 ++ip;
184 path[ip] = m_temp.fun;
185 static_cast<void>(QHSM_RESERVED_EVT_(m_temp.fun, Q_EMPTY_SIG));
186 }
188 // The initial transition source state must be reached
189 // Too many state nesting levels or "malformed" HSM.
190 Q_ASSERT_INCRIT(220, m_temp.fun == t);
191 QF_CRIT_EXIT();
192
193 m_temp.fun = path[0];
194
195 // retrace the entry path in reverse (desired) order...
196 do {
197 // enter path[ip]
198 if (QHSM_RESERVED_EVT_(path[ip], Q_ENTRY_SIG)
199 == Q_RET_HANDLED)
200 {
201 QS_STATE_ENTRY_(path[ip], qsId);
202 }
203 --ip;
204 } while (ip >= 0);
205
206 t = path[0]; // current state becomes the new source
207
208 r = QHSM_RESERVED_EVT_(t, Q_INIT_SIG); // execute initial tran.
209
210 #ifdef Q_SPY
211 if (r == Q_RET_TRAN) {
213 QS_MEM_SYS();
214 QS_BEGIN_PRE_(QS_QEP_STATE_INIT, qsId)
215 QS_OBJ_PRE_(this); // this state machine object
216 QS_FUN_PRE_(t); // the source state
217 QS_FUN_PRE_(m_temp.fun); // the target of the initial tran.
218 QS_END_PRE_()
219 QS_MEM_APP();
220 QS_CRIT_EXIT();
221 }
222 #endif // Q_SPY
223
224 --limit;
225 } while ((r == Q_RET_TRAN) && (limit > 0));
226
228 // Loop limit must not be reached.
229 // Too many state nesting levels or likely "malformed" HSM
230 Q_ENSURE_INCRIT(290, limit > 0);
231
232 QS_MEM_SYS();
233 QS_BEGIN_PRE_(QS_QEP_INIT_TRAN, qsId)
234 QS_TIME_PRE_(); // time stamp
235 QS_OBJ_PRE_(this); // this state machine object
236 QS_FUN_PRE_(t); // the new active state
237 QS_END_PRE_()
238 QS_MEM_APP();
239
240 QF_CRIT_EXIT();
241
242 m_state.fun = t; // change the current active state
243 #ifndef Q_UNSAFE
244 m_temp.uint = ~m_state.uint;
245 #endif
246}
247
248//${QEP::QHsm::dispatch} .....................................................
250 QEvt const * const e,
251 std::uint_fast8_t const qsId)
252{
253 #ifndef Q_SPY
254 Q_UNUSED_PAR(qsId);
255 #endif
256
258 QStateHandler t = s;
260
262 Q_REQUIRE_INCRIT(300, (s != Q_STATE_CAST(0))
263 && (m_state.uint == static_cast<std::uintptr_t>(~m_temp.uint)));
265
266 QS_MEM_SYS();
267 QS_BEGIN_PRE_(QS_QEP_DISPATCH, qsId)
268 QS_TIME_PRE_(); // time stamp
269 QS_SIG_PRE_(e->sig); // the signal of the event
270 QS_OBJ_PRE_(this); // this state machine object
271 QS_FUN_PRE_(s); // the current state
272 QS_END_PRE_()
273 QS_MEM_APP();
274
275 QF_CRIT_EXIT();
276
277 // process the event hierarchically...
278 QState r;
279 m_temp.fun = s;
280 std::int_fast8_t limit = MAX_NEST_DEPTH_; // loop hard limit
281 do {
282 s = m_temp.fun;
283 r = (*s)(this, e); // invoke state handler s
284
285 if (r == Q_RET_UNHANDLED) { // unhandled due to a guard?
286
288 QS_MEM_SYS();
289 QS_BEGIN_PRE_(QS_QEP_UNHANDLED, qsId)
290 QS_SIG_PRE_(e->sig); // the signal of the event
291 QS_OBJ_PRE_(this); // this state machine object
292 QS_FUN_PRE_(s); // the current state
293 QS_END_PRE_()
294 QS_MEM_APP();
295 QS_CRIT_EXIT();
296
297 r = QHSM_RESERVED_EVT_(s, Q_EMPTY_SIG); // superstate of s
298 }
299
300 --limit;
301 } while ((r == Q_RET_SUPER) && (limit > 0));
302
304 Q_ASSERT_INCRIT(310, limit > 0);
305 QF_CRIT_EXIT();
306
307 if (r >= Q_RET_TRAN) { // regular tran. taken?
309
310 path[0] = m_temp.fun; // tran. target
311 path[1] = t; // current state
312 path[2] = s; // tran. source
313
314 // exit current state to tran. source s...
315 limit = MAX_NEST_DEPTH_; // loop hard limit
316 for (; (t != s) && (limit > 0); t = m_temp.fun) {
317 // exit from t
318 if (QHSM_RESERVED_EVT_(t, Q_EXIT_SIG) == Q_RET_HANDLED) {
319 QS_STATE_EXIT_(t, qsId);
320 // find superstate of t
321 static_cast<void>(QHSM_RESERVED_EVT_(t, Q_EMPTY_SIG));
322 }
323 --limit;
324 }
326 Q_ASSERT_INCRIT(320, limit > 0);
327 QF_CRIT_EXIT();
328
329 std::int_fast8_t ip = hsm_tran(path, qsId); // take the tran.
330
331 #ifdef Q_SPY
332 if (r == Q_RET_TRAN_HIST) {
334 QS_MEM_SYS();
335 QS_BEGIN_PRE_(QS_QEP_TRAN_HIST, qsId)
336 QS_OBJ_PRE_(this); // this state machine object
337 QS_FUN_PRE_(t); // the source of the transition
338 QS_FUN_PRE_(path[0]); // the target of the tran. to history
339 QS_END_PRE_()
340 QS_MEM_APP();
341 QS_CRIT_EXIT();
342 }
343 #endif // Q_SPY
344
345 // execute state entry actions in the desired order...
346 for (; ip >= 0; --ip) {
347 // enter path[ip]
348 if (QHSM_RESERVED_EVT_(path[ip], Q_ENTRY_SIG)
349 == Q_RET_HANDLED)
350 {
351 QS_STATE_ENTRY_(path[ip], qsId);
352 }
353 }
354 t = path[0]; // stick the target into register
355 m_temp.fun = t; // update the next state
356
357 // drill into the target hierarchy...
358 while (QHSM_RESERVED_EVT_(t, Q_INIT_SIG) == Q_RET_TRAN) {
359
361 QS_MEM_SYS();
362 QS_BEGIN_PRE_(QS_QEP_STATE_INIT, qsId)
363 QS_OBJ_PRE_(this); // this state machine object
364 QS_FUN_PRE_(t); // the source (pseudo)state
365 QS_FUN_PRE_(m_temp.fun); // the target of the tran.
366 QS_END_PRE_()
367 QS_MEM_APP();
368 QS_CRIT_EXIT();
369
370 ip = 0;
371 path[0] = m_temp.fun;
372
373 // find superstate
374 static_cast<void>(QHSM_RESERVED_EVT_(m_temp.fun, Q_EMPTY_SIG));
375
376 while ((m_temp.fun != t) && (ip < (MAX_NEST_DEPTH_ - 1))) {
377 ++ip;
378 path[ip] = m_temp.fun;
379 // find superstate
380 static_cast<void>(
381 QHSM_RESERVED_EVT_(m_temp.fun, Q_EMPTY_SIG));
382 }
384 // The initial transition source state must be reached.
385 // Too many state nesting levels or "malformed" HSM.
386 Q_ASSERT_INCRIT(330, m_temp.fun == t);
387 QF_CRIT_EXIT();
388
389 m_temp.fun = path[0];
390
391 // retrace the entry path in reverse (correct) order...
392 do {
393 // enter path[ip]
394 if (QHSM_RESERVED_EVT_(path[ip], Q_ENTRY_SIG)
395 == Q_RET_HANDLED)
396 {
397 QS_STATE_ENTRY_(path[ip], qsId);
398 }
399 --ip;
400 } while (ip >= 0);
401
402 t = path[0]; // current state becomes the new source
403 }
404
406 QS_MEM_SYS();
407 QS_BEGIN_PRE_(QS_QEP_TRAN, qsId)
408 QS_TIME_PRE_(); // time stamp
409 QS_SIG_PRE_(e->sig); // the signal of the event
410 QS_OBJ_PRE_(this); // this state machine object
411 QS_FUN_PRE_(s); // the source of the tran.
412 QS_FUN_PRE_(t); // the new active state
413 QS_END_PRE_()
414 QS_MEM_APP();
415 QS_CRIT_EXIT();
416 }
417
418 #ifdef Q_SPY
419 else if (r == Q_RET_HANDLED) {
421 QS_MEM_SYS();
422 QS_BEGIN_PRE_(QS_QEP_INTERN_TRAN, qsId)
423 QS_TIME_PRE_(); // time stamp
424 QS_SIG_PRE_(e->sig); // the signal of the event
425 QS_OBJ_PRE_(this); // this state machine object
426 QS_FUN_PRE_(s); // the source state
427 QS_END_PRE_()
428 QS_MEM_APP();
429 QS_CRIT_EXIT();
430 }
431 else {
433 QS_MEM_SYS();
434 QS_BEGIN_PRE_(QS_QEP_IGNORED, qsId)
435 QS_TIME_PRE_(); // time stamp
436 QS_SIG_PRE_(e->sig); // the signal of the event
437 QS_OBJ_PRE_(this); // this state machine object
438 QS_FUN_PRE_(m_state.fun); // the current state
439 QS_END_PRE_()
440 QS_MEM_APP();
441 QS_CRIT_EXIT();
442 }
443 #endif // Q_SPY
444
445 m_state.fun = t; // change the current active state
446 #ifndef Q_UNSAFE
447 m_temp.uint = ~m_state.uint;
448 #endif
449}
450
451//${QEP::QHsm::isIn} .........................................................
452bool QHsm::isIn(QStateHandler const state) noexcept {
455 Q_REQUIRE_INCRIT(602, m_state.uint
456 == static_cast<std::uintptr_t>(~m_temp.uint));
457 QF_CRIT_EXIT();
458
459 bool inState = false; // assume that this HSM is not in 'state'
460
461 // scan the state hierarchy bottom-up
462 QStateHandler s = m_state.fun;
463 std::int_fast8_t limit = MAX_NEST_DEPTH_ + 1; // loop hard limit
464 QState r = Q_RET_SUPER;
465 for (; (r != Q_RET_IGNORED) && (limit > 0); --limit) {
466 if (s == state) { // do the states match?
467 inState = true; // 'true' means that match found
468 break; // break out of the for-loop
469 }
470 else {
471 r = QHSM_RESERVED_EVT_(s, Q_EMPTY_SIG);
472 s = m_temp.fun;
473 }
474 }
475
477 Q_ENSURE_INCRIT(690, limit > 0);
478 QF_CRIT_EXIT();
479
480 #ifndef Q_UNSAFE
481 m_temp.uint = ~m_state.uint;
482 #endif
483
484 return inState; // return the status
485}
486
487//${QEP::QHsm::childState} ...................................................
489 QStateHandler child = m_state.fun; // start with the current state
490 bool isFound = false; // start with the child not found
491
492 // establish stable state configuration
493 m_temp.fun = child;
494 QState r;
495 do {
496 // is this the parent of the current child?
497 if (m_temp.fun == parent) {
498 isFound = true; // child is found
499 r = Q_RET_IGNORED; // break out of the loop
500 }
501 else {
502 child = m_temp.fun;
503 r = QHSM_RESERVED_EVT_(m_temp.fun, Q_EMPTY_SIG);
504 }
505 } while (r != Q_RET_IGNORED); // QHsm::top() state not reached
506
507 #ifndef Q_UNSAFE
508 m_temp.uint = ~m_state.uint;
509 #endif
510
513 Q_ASSERT_INCRIT(890, isFound);
514 QF_CRIT_EXIT();
515
516 return child; // return the child
517}
518
519//${QEP::QHsm::hsm_tran} .....................................................
520std::int_fast8_t QHsm::hsm_tran(
521 QStateHandler (&path)[MAX_NEST_DEPTH_],
522 std::uint_fast8_t const qsId)
523{
524 #ifndef Q_SPY
525 Q_UNUSED_PAR(qsId);
526 #endif
527
528 std::int_fast8_t ip = -1; // tran. entry path index
529 QStateHandler t = path[0];
530 QStateHandler const s = path[2];
532
533 // (a) check source==target (tran. to self)...
534 if (s == t) {
535 // exit source s
536 if (QHSM_RESERVED_EVT_(s, Q_EXIT_SIG) == Q_RET_HANDLED) {
537 QS_STATE_EXIT_(s, qsId);
538 }
539 ip = 0; // enter the target
540 }
541 else {
542 // find superstate of target
543 static_cast<void>(QHSM_RESERVED_EVT_(t, Q_EMPTY_SIG));
544
545 t = m_temp.fun;
546
547 // (b) check source==target->super...
548 if (s == t) {
549 ip = 0; // enter the target
550 }
551 else {
552 // find superstate of src
553 static_cast<void>(QHSM_RESERVED_EVT_(s, Q_EMPTY_SIG));
554
555 // (c) check source->super==target->super...
556 if (m_temp.fun == t) {
557 // exit source s
558 if (QHSM_RESERVED_EVT_(s, Q_EXIT_SIG) == Q_RET_HANDLED) {
559 QS_STATE_EXIT_(s, qsId);
560 }
561 ip = 0; // enter the target
562 }
563 else {
564 // (d) check source->super==target...
565 if (m_temp.fun == path[0]) {
566 // exit source s
567 if (QHSM_RESERVED_EVT_(s, Q_EXIT_SIG) == Q_RET_HANDLED) {
568 QS_STATE_EXIT_(s, qsId);
569 }
570 }
571 else {
572 // (e) check rest of source==target->super->super..
573 // and store the entry path along the way
574 std::int_fast8_t iq = 0; // indicate that LCA was found
575 ip = 1; // enter target and its superstate
576 path[1] = t; // save the superstate of target
577 t = m_temp.fun; // save source->super
578
579 // find target->super->super...
580 QState r = QHSM_RESERVED_EVT_(path[1], Q_EMPTY_SIG);
581 while ((r == Q_RET_SUPER)
582 && (ip < (MAX_NEST_DEPTH_ - 1)))
583 {
584 ++ip;
585 path[ip] = m_temp.fun; // store the entry path
586 if (m_temp.fun == s) { // is it the source?
587 iq = 1; // indicate that the LCA found
588 --ip; // do not enter the source
589 r = Q_RET_HANDLED; // terminate the loop
590 }
591 else { // it is not the source, keep going up
592 r = QHSM_RESERVED_EVT_(m_temp.fun, Q_EMPTY_SIG);
593 }
594 }
596 // Tran. source must be found within the nesting depth
597 // Too many state nesting levels or "malformed" HSM.
598 Q_ASSERT_INCRIT(510, r != Q_RET_SUPER);
599 QF_CRIT_EXIT();
600
601 // the LCA not found yet?
602 if (iq == 0) {
603 // exit source s
604 if (QHSM_RESERVED_EVT_(s, Q_EXIT_SIG)
605 == Q_RET_HANDLED)
606 {
607 QS_STATE_EXIT_(s, qsId);
608 }
609
610 // (f) check the rest of source->super
611 // == target->super->super...
612 iq = ip;
613 r = Q_RET_IGNORED; // indicate that the LCA NOT found
614 do {
615 if (t == path[iq]) { // is this the LCA?
616 r = Q_RET_HANDLED; // indicate the LCA found
617 ip = iq - 1; // do not enter the LCA
618 iq = -1; // cause termination of the loop
619 }
620 else {
621 --iq; // try lower superstate of target
622 }
623 } while (iq >= 0);
624
625 // the LCA not found yet?
626 if (r != Q_RET_HANDLED) {
627 // (g) check each source->super->...
628 // for each target->super...
629 r = Q_RET_IGNORED; // keep looping
630 std::int_fast8_t limit = MAX_NEST_DEPTH_;
631 do {
632 // exit from t
633 if (QHSM_RESERVED_EVT_(t, Q_EXIT_SIG)
634 == Q_RET_HANDLED)
635 {
636 QS_STATE_EXIT_(t, qsId);
637 // find superstate of t
638 static_cast<void>(
639 QHSM_RESERVED_EVT_(t, Q_EMPTY_SIG));
640 }
641 t = m_temp.fun; // set to super of t
642 iq = ip;
643 do {
644 // is this the LCA?
645 if (t == path[iq]) {
646 ip = iq - 1; // do not enter the LCA
647 iq = -1; // break out of inner loop
648 r = Q_RET_HANDLED; // break outer loop
649 }
650 else {
651 --iq;
652 }
653 } while (iq >= 0);
654
655 --limit;
656 } while ((r != Q_RET_HANDLED) && (limit > 0));
658 Q_ASSERT_INCRIT(530, limit > 0);
659 QF_CRIT_EXIT();
660 }
661 }
662 }
663 }
664 }
665 }
668 QF_CRIT_EXIT();
669 return ip;
670}
671
672} // namespace QP
673//$enddef${QEP::QHsm} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Abstract State Machine class (state machine interface)
Definition qp.hpp:220
QAsmAttr m_state
Definition qp.hpp:222
@ Q_RET_HANDLED
event handled (internal transition)
Definition qp.hpp:237
@ Q_RET_IGNORED
event silently ignored (bubbled up to top)
Definition qp.hpp:238
@ Q_RET_UNHANDLED
event unhandled due to a guard
Definition qp.hpp:234
@ Q_RET_TRAN
regular transition
Definition qp.hpp:248
@ Q_RET_TRAN_HIST
transition to history of a given state
Definition qp.hpp:253
@ Q_RET_SUPER
event passed to superstate to handle
Definition qp.hpp:232
static QState top(void *const me, QEvt const *const e) noexcept
Definition qp.hpp:303
@ Q_EXIT_SIG
signal for exit actions
Definition qp.hpp:261
@ Q_INIT_SIG
signal for nested initial transitions
Definition qp.hpp:262
@ Q_ENTRY_SIG
signal for entry actions
Definition qp.hpp:260
@ Q_EMPTY_SIG
signal to execute the default case
Definition qp.hpp:259
QAsmAttr m_temp
Definition qp.hpp:223
Event class.
Definition qp.hpp:139
static bool verify_(QEvt const *const e) noexcept
Definition qp.hpp:163
QSignal sig
Definition qp.hpp:141
static constexpr std::int_fast8_t MAX_NEST_DEPTH_
Definition qp.hpp:394
QStateHandler childState(QStateHandler const parent) noexcept
Definition qep_hsm.cpp:488
void dispatch(QEvt const *const e, std::uint_fast8_t const qsId) override
Definition qep_hsm.cpp:249
bool isIn(QStateHandler const state) noexcept override
Definition qep_hsm.cpp:452
std::int_fast8_t hsm_tran(QStateHandler(&path)[MAX_NEST_DEPTH_], std::uint_fast8_t const qsId)
Definition qep_hsm.cpp:520
void init(void const *const e, std::uint_fast8_t const qsId) override
Definition qep_hsm.cpp:127
QHsm(QStateHandler const initial) noexcept
Definition qep_hsm.cpp:119
QP/C++ framework.
Definition qequeue.hpp:50
std::uint16_t QSignal
Definition qp.hpp:130
QState(*)(void *const me, QEvt const *const e) QStateHandler
Definition qp.hpp:176
std::uint_fast8_t QState
Definition qp.hpp:173
@ QS_QEP_DISPATCH
an event was dispatched (begin of RTC step)
Definition qs.hpp:81
@ QS_QEP_TRAN_HIST
a tran to history was taken
Definition qs.hpp:154
@ QS_QEP_IGNORED
an event was ignored (silently discarded)
Definition qs.hpp:80
@ QS_QEP_UNHANDLED
an event was un-handled due to a guard
Definition qs.hpp:82
@ QS_QEP_STATE_INIT
an initial transition was taken in a state
Definition qs.hpp:76
@ QS_QEP_TRAN
a regular transition was taken
Definition qs.hpp:79
@ QS_QEP_INIT_TRAN
the top-most initial transition was taken
Definition qs.hpp:77
@ QS_QEP_INTERN_TRAN
an internal transition was taken
Definition qs.hpp:78
#define Q_EVT_CAST(subclass_)
Definition qp.hpp:490
#define Q_UNUSED_PAR(par_)
Definition qp.hpp:541
#define Q_STATE_CAST(handler_)
Definition qp.hpp:493
Internal (package scope) QP/C++ interface.
Sample QP/C++ port.
#define QS_TIME_PRE_()
Definition qs.hpp:473
#define QS_FUN_DICTIONARY(fun_)
Definition qs.hpp:546
#define QS_MEM_APP()
Definition qs.hpp:610
#define QS_CRIT_EXIT()
Definition qs.hpp:600
#define QS_MEM_SYS()
Definition qs.hpp:605
#define QS_CRIT_ENTRY()
Definition qs.hpp:595
QS/C++ package-scope interface.
QS/C++ port to a 32-bit CPU, generic C++ compiler.
QP Functional Safety (FuSa) Subsystem.
#define QF_CRIT_ENTRY()
Definition qsafe.h:58
#define Q_ASSERT_INCRIT(id_, expr_)
Definition qsafe.h:72
#define Q_ENSURE_INCRIT(id_, expr_)
Definition qsafe.h:145
#define QF_CRIT_EXIT()
Definition qsafe.h:62
#define Q_REQUIRE_INCRIT(id_, expr_)
Definition qsafe.h:136
#define QF_CRIT_STAT
Definition qsafe.h:54
std::uintptr_t uint
Definition qp.hpp:211
QStateHandler fun
Definition qp.hpp:205