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