QP/C  7.4.0-rc.3
Real-Time Embedded Framework
Loading...
Searching...
No Matches
qep_msm.c
Go to the documentation of this file.
1//$file${src::qf::qep_msm.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
2//
3// Model: qpc.qm
4// File: ${src::qf::qep_msm.c}
5//
6// This code has been generated by QM 6.2.0 <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 : 2025-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_msm.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
43#define QP_IMPL // this is QP implementation
44#include "qp_port.h" // QP port
45#include "qp_pkg.h" // 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.h" // QS port
49 #include "qs_pkg.h" // QS facilities for pre-defined trace records
50#else
51 #include "qs_dummy.h" // disable the QS software tracing
52#endif // Q_SPY
53
54//============================================================================
55//! @cond INTERNAL
56
57Q_DEFINE_THIS_MODULE("qep_msm")
58
59// top-state object for QMsm-style state machines
60static struct QMState const l_msm_top_s = {
61 (struct QMState *)0,
62 Q_STATE_CAST(0),
66};
67//! @endcond
68
69enum {
70 // maximum depth of state nesting in a QMsm (including the top level)
72
73 // maximum length of transition-action array
75
76 // maximum depth of entry levels in a MSM for tran. to history
78};
79
80//============================================================================
81
82//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
83// Check for the minimum required QP version
84#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U)%0x2710U))
85#error qpc version 7.3.0 or higher required
86#endif
87//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
88//$define${QEP::QMsm} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
89
90//${QEP::QMsm} ...............................................................
91
92//${QEP::QMsm::ctor} .........................................................
93//! @protected @memberof QMsm
94void QMsm_ctor(QMsm * const me,
95 QStateHandler const initial)
96{
97 static struct QAsmVtable const vtable = { // QAsm virtual table
98 &QMsm_init_,
99 &QMsm_dispatch_,
100 &QMsm_isIn_
101 #ifdef Q_SPY
102 ,&QMsm_getStateHandler_
103 #endif
104 };
105 // do not call the QAsm_ctor() here
106 me->super.vptr = &vtable;
107 me->super.state.obj = &l_msm_top_s; // the current state (top)
108 me->super.temp.fun = initial; // the initial tran. handler
109}
110
111//${QEP::QMsm::init_} ........................................................
112//! @private @memberof QMsm
113void QMsm_init_(
114 QAsm * const me,
115 void const * const e,
116 uint_fast8_t const qsId)
117{
118 #ifndef Q_SPY
119 Q_UNUSED_PAR(qsId);
120 #endif
121
124 Q_REQUIRE_INCRIT(200, (me->vptr != (struct QAsmVtable *)0)
125 && (me->temp.fun != Q_STATE_CAST(0))
126 && (me->state.obj == &l_msm_top_s));
127 QF_CRIT_EXIT();
128
129 // execute the top-most initial tran.
130 QState r = (*me->temp.fun)(me, Q_EVT_CAST(QEvt));
131
133 // the top-most initial tran. must be taken
135
136 QS_MEM_SYS();
137 QS_BEGIN_PRE_(QS_QEP_STATE_INIT, qsId)
138 QS_OBJ_PRE_(me); // this state machine object
139 QS_FUN_PRE_(me->state.obj->stateHandler); // source state
140 QS_FUN_PRE_(me->temp.tatbl->target->stateHandler); // target state
141 QS_END_PRE_()
142 QS_MEM_APP();
143
144 QF_CRIT_EXIT();
145
146 // set state to the last tran. target
147 me->state.obj = me->temp.tatbl->target;
148
149 // drill down into the state hierarchy with initial transitions...
150 int_fast8_t lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound
151 do {
152 // execute the tran. table
153 r = QMsm_execTatbl_(me, me->temp.tatbl, qsId);
154 --lbound;
155 } while ((r >= Q_RET_TRAN_INIT) && (lbound > 0));
156
158 Q_ENSURE_INCRIT(290, lbound > 0);
159
160 QS_MEM_SYS();
161 QS_BEGIN_PRE_(QS_QEP_INIT_TRAN, qsId)
162 QS_TIME_PRE_(); // time stamp
163 QS_OBJ_PRE_(me); // this state machine object
164 QS_FUN_PRE_(me->state.obj->stateHandler); // the new current state
165 QS_END_PRE_()
166 QS_MEM_APP();
167
168 QF_CRIT_EXIT();
169
170 #ifndef Q_UNSAFE
171 me->temp.uint = ~me->state.uint;
172 #endif
173}
174
175//${QEP::QMsm::dispatch_} ....................................................
176//! @private @memberof QMsm
177void QMsm_dispatch_(
178 QAsm * const me,
179 QEvt const * const e,
180 uint_fast8_t const qsId)
181{
182 #ifndef Q_SPY
183 Q_UNUSED_PAR(qsId);
184 #endif
185
186 QMState const *s = me->state.obj; // store the current state
187 QMState const *t = s;
188
191 Q_REQUIRE_INCRIT(300, QEvt_verify_(e));
192 Q_INVARIANT_INCRIT(302, (s != (QMState *)0)
193 && (me->state.uint == (uintptr_t)(~me->temp.uint)));
194
195 QS_MEM_SYS();
196 QS_BEGIN_PRE_(QS_QEP_DISPATCH, qsId)
197 QS_TIME_PRE_(); // time stamp
198 QS_SIG_PRE_(e->sig); // the signal of the event
199 QS_OBJ_PRE_(me); // this state machine object
200 QS_FUN_PRE_(s->stateHandler); // the current state handler
201 QS_END_PRE_()
202 QS_MEM_APP();
203
204 QF_CRIT_EXIT();
205
206 // scan the state hierarchy up to the top state...
207 QState r;
208 int_fast8_t lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound
209 do {
210 r = (*t->stateHandler)(me, e); // call state handler function
211
212 // event handled? (the most frequent case)
213 if (r >= Q_RET_HANDLED) {
214 break; // done scanning the state hierarchy
215 }
216 // event unhandled and passed to the superstate?
217 else if (r == Q_RET_SUPER) {
218 t = t->superstate; // advance to the superstate
219 }
220 // event unhandled and passed to a submachine superstate?
221 else if (r == Q_RET_SUPER_SUB) {
222 t = me->temp.obj; // current host state of the submachine
223 }
224 else { // event unhandled due to a guard?
226 // event must be unhandled due to a guard evaluating to 'false'
228
229 QS_MEM_SYS();
230 QS_BEGIN_PRE_(QS_QEP_UNHANDLED, qsId)
231 QS_SIG_PRE_(e->sig); // the signal of the event
232 QS_OBJ_PRE_(me); // this state machine object
233 QS_FUN_PRE_(t->stateHandler); // the current state
234 QS_END_PRE_()
235 QS_MEM_APP();
236
237 QF_CRIT_EXIT();
238
239 t = t->superstate; // advance to the superstate
240 }
241 --lbound;
242 } while ((t != (QMState *)0) && (lbound > 0));
244 Q_ENSURE_INCRIT(320, lbound > 0);
245 QF_CRIT_EXIT();
246
247 if (r >= Q_RET_TRAN) { // any kind of tran. taken?
248 #ifdef Q_SPY
249 QMState const * const ts = t; // tran. source for QS tracing
250
252 // the tran. source state must not be NULL
253 Q_ASSERT_INCRIT(330, ts != (QMState *)0);
254 QF_CRIT_EXIT();
255 #endif // Q_SPY
256
257 lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound
258 do {
259 // save the tran-action table before it gets clobbered
260 struct QMTranActTable const * const tatbl = me->temp.tatbl;
261 union QAsmAttr tmp; // temporary to save intermediate values
262
263 // was TRAN, TRAN_INIT, or TRAN_EP taken?
264 if (r <= Q_RET_TRAN_EP) {
265 me->temp.obj = (QMState *)0; // clear
266 QMsm_exitToTranSource_(me, s, t, qsId);
267 r = QMsm_execTatbl_(me, tatbl, qsId);
268 s = me->state.obj;
269 }
270 // was a tran. segment to history taken?
271 else if (r == Q_RET_TRAN_HIST) {
272 tmp.obj = me->state.obj; // save history
273 me->state.obj = s; // restore the original state
274 QMsm_exitToTranSource_(me, s, t, qsId);
275 (void)QMsm_execTatbl_(me, tatbl, qsId);
276 r = QMsm_enterHistory_(me, tmp.obj, qsId);
277 s = me->state.obj;
278 }
279 else {
281 // must be tran. to exit point
283 QF_CRIT_EXIT();
284
285 tmp.act = me->state.act; // save XP action
286 me->state.obj = s; // restore the original state
287 r = (*tmp.act)(me); // execute the XP action
288 if (r == Q_RET_TRAN) { // XP -> TRAN ?
289 #ifdef Q_SPY
290 tmp.tatbl = me->temp.tatbl; // save me->temp
291 #endif // Q_SPY
292 QMsm_exitToTranSource_(me, s, t, qsId);
293 // take the tran-to-XP segment inside submachine
294 (void)QMsm_execTatbl_(me, tatbl, qsId);
295 s = me->state.obj;
296 #ifdef Q_SPY
297 me->temp.tatbl = tmp.tatbl; // restore me->temp
298 #endif // Q_SPY
299 }
300 else if (r == Q_RET_TRAN_HIST) { // XP -> HIST ?
301 tmp.obj = me->state.obj; // save the history
302 me->state.obj = s; // restore the original state
303 s = me->temp.obj; // save me->temp
304 QMsm_exitToTranSource_(me, me->state.obj, t, qsId);
305 // take the tran-to-XP segment inside submachine
306 (void)QMsm_execTatbl_(me, tatbl, qsId);
307 #ifdef Q_SPY
308 me->temp.obj = s; // restore me->temp
309 #endif // Q_SPY
310 s = me->state.obj;
311 me->state.obj = tmp.obj; // restore the history
312 }
313 else {
315 // TRAN_XP must NOT be followed by any other tran. type
316 Q_ASSERT_INCRIT(350, r < Q_RET_TRAN);
317 QF_CRIT_EXIT();
318 }
319 }
320
321 t = s; // set target to the current state
322 --lbound;
323 } while ((r >= Q_RET_TRAN) && (lbound > 0));
324
326 Q_ENSURE_INCRIT(360, lbound > 0);
327
328 QS_MEM_SYS();
329 QS_BEGIN_PRE_(QS_QEP_TRAN, qsId)
330 QS_TIME_PRE_(); // time stamp
331 QS_SIG_PRE_(e->sig); // the signal of the event
332 QS_OBJ_PRE_(me); // this state machine object
333 QS_FUN_PRE_(ts->stateHandler); // the tran. source
334 QS_FUN_PRE_(s->stateHandler); // the new active state
335 QS_END_PRE_()
336 QS_MEM_APP();
337
338 QF_CRIT_EXIT();
339 }
340
341 #ifdef Q_SPY
342 // was the event handled?
343 else if (r == Q_RET_HANDLED) {
345 // internal tran. source can't be NULL
346 Q_ASSERT_INCRIT(380, t != (QMState *)0);
347
348 QS_MEM_SYS();
349 QS_BEGIN_PRE_(QS_QEP_INTERN_TRAN, qsId)
350 QS_TIME_PRE_(); // time stamp
351 QS_SIG_PRE_(e->sig); // the signal of the event
352 QS_OBJ_PRE_(me); // this state machine object
353 QS_FUN_PRE_(t->stateHandler); // the source state
354 QS_END_PRE_()
355 QS_MEM_APP();
356
357 QF_CRIT_EXIT();
358 }
359 // event bubbled to the 'top' state?
360 else if (t == (QMState *)0) {
362 // current state can't be NULL
363 Q_ASSERT_INCRIT(390, s != (QMState *)0);
364
365 QS_MEM_SYS();
366 QS_BEGIN_PRE_(QS_QEP_IGNORED, qsId)
367 QS_TIME_PRE_(); // time stamp
368 QS_SIG_PRE_(e->sig); // the signal of the event
369 QS_OBJ_PRE_(me); // this state machine object
370 QS_FUN_PRE_(s->stateHandler); // the current state
371 QS_END_PRE_()
372 QS_MEM_APP();
373 QS_CRIT_EXIT();
374 }
375 #endif // Q_SPY
376 else {
377 // empty
378 }
379
380 #ifndef Q_UNSAFE
381 me->temp.uint = ~me->state.uint;
382 #endif
383}
384
385//${QEP::QMsm::isIn_} ........................................................
386//! @private @memberof QMsm
387bool QMsm_isIn_(
388 QAsm * const me,
389 QStateHandler const state)
390{
391 bool inState = false; // assume that this SM is not in 'state'
392
393 QMState const *s = me->state.obj;
394 int_fast8_t lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound
395 for (; (s != (QMState *)0) && (lbound > 0); --lbound) {
396 if (s->stateHandler == state) { // match found?
397 inState = true;
398 break;
399 }
400 else {
401 s = s->superstate; // advance to the superstate
402 }
403 }
404
407 Q_ENSURE_INCRIT(490, lbound > 0);
408 QF_CRIT_EXIT();
409
410 return inState;
411}
412
413//${QEP::QMsm::isInState} ....................................................
414//! @private @memberof QMsm
415bool QMsm_isInState(QMsm const * const me,
416 QMState const * const stateObj)
417{
418 bool inState = false; // assume that this SM is not in 'state'
419
420 QMState const *s = me->super.state.obj;
421 int_fast8_t lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound
422 for (; (s != (QMState *)0) && (lbound > 0); --lbound) {
423 if (s == stateObj) { // match found?
424 inState = true;
425 break;
426 }
427 else {
428 s = s->superstate; // advance to the superstate
429 }
430 }
431
434 Q_ENSURE_INCRIT(590, lbound > 0);
435 QF_CRIT_EXIT();
436
437 return inState;
438}
439
440//${QEP::QMsm::childStateObj} ................................................
441//! @public @memberof QMsm
442QMState const * QMsm_childStateObj(QMsm const * const me,
443 QMState const * const parent)
444{
445 QMState const *child = me->super.state.obj;
446 bool isFound = false; // start with the child not found
447 QMState const *s;
448
449 int_fast8_t lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound
450 for (s = me->super.state.obj;
451 (s != (QMState *)0) && (lbound > 0);
452 s = s->superstate)
453 {
454 if (s == parent) {
455 isFound = true; // child is found
456 break;
457 }
458 else {
459 child = s;
460 }
461 --lbound;
462 }
465 Q_ENSURE_INCRIT(680, lbound > 0);
466 QF_CRIT_EXIT();
467
468 if (!isFound) { // still not found?
469 lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound
470 for (s = me->super.temp.obj;
471 (s != (QMState *)0) && (lbound > 0);
472 s = s->superstate)
473 {
474 if (s == parent) {
475 isFound = true; // child is found
476 break;
477 }
478 else {
479 child = s;
480 }
481 --lbound;
482 }
483 }
484
486 // NOTE: the following postcondition can only succeed when
487 // (lbound > 0), so no extra check is necessary.
488 Q_ENSURE_INCRIT(690, isFound);
489 QF_CRIT_EXIT();
490
491 return child; // return the child
492}
493
494//${QEP::QMsm::execTatbl_} ...................................................
495//! @private @memberof QMsm
496QState QMsm_execTatbl_(
497 QAsm * const me,
498 QMTranActTable const * const tatbl,
499 uint_fast8_t const qsId)
500{
501 #ifndef Q_SPY
502 Q_UNUSED_PAR(qsId);
503 #endif
504
507 // precondition:
508 // - the tran-action table pointer must not be NULL
509 Q_REQUIRE_INCRIT(700, tatbl != (struct QMTranActTable *)0);
510 QF_CRIT_EXIT();
511
512 QState r = Q_RET_NULL;
513 int_fast8_t lbound = QMSM_MAX_TRAN_LENGTH_; // fixed upper loop bound
514 QActionHandler const *a = &tatbl->act[0];
515 for (; (*a != Q_ACTION_CAST(0)) && (lbound > 0); ++a) {
516 r = (*(*a))(me); // call the action through the 'a' pointer
517 --lbound;
518 #ifdef Q_SPY
520 QS_MEM_SYS();
521 if (r == Q_RET_ENTRY) {
522 QS_BEGIN_PRE_(QS_QEP_STATE_ENTRY, qsId)
523 QS_OBJ_PRE_(me); // this state machine object
524 QS_FUN_PRE_(me->temp.obj->stateHandler); // entered state
525 QS_END_PRE_()
526 }
527 else if (r == Q_RET_EXIT) {
528 QS_BEGIN_PRE_(QS_QEP_STATE_EXIT, qsId)
529 QS_OBJ_PRE_(me); // this state machine object
530 QS_FUN_PRE_(me->temp.obj->stateHandler); // exited state
531 QS_END_PRE_()
532 }
533 else if (r == Q_RET_TRAN_INIT) {
534 QS_BEGIN_PRE_(QS_QEP_STATE_INIT, qsId)
535 QS_OBJ_PRE_(me); // this state machine object
536 QS_FUN_PRE_(tatbl->target->stateHandler); // source
537 QS_FUN_PRE_(me->temp.tatbl->target->stateHandler); // target
538 QS_END_PRE_()
539 }
540 else if (r == Q_RET_TRAN_EP) {
541 QS_BEGIN_PRE_(QS_QEP_TRAN_EP, qsId)
542 QS_OBJ_PRE_(me); // this state machine object
543 QS_FUN_PRE_(tatbl->target->stateHandler); // source
544 QS_FUN_PRE_(me->temp.tatbl->target->stateHandler); // target
545 QS_END_PRE_()
546 }
547 else if (r == Q_RET_TRAN_XP) {
548 QS_BEGIN_PRE_(QS_QEP_TRAN_XP, qsId)
549 QS_OBJ_PRE_(me); // this state machine object
550 QS_FUN_PRE_(tatbl->target->stateHandler); // source
551 QS_FUN_PRE_(me->temp.tatbl->target->stateHandler); // target
552 QS_END_PRE_()
553 }
554 else {
555 // empty
556 }
557 QS_MEM_APP();
558 QS_CRIT_EXIT();
559 #endif // Q_SPY
560 }
562 // NOTE: the following postcondition can only succeed when
563 // (lbound > 0), so no extra check is necessary.
564 Q_ENSURE_INCRIT(790, *a == Q_ACTION_CAST(0));
565 QF_CRIT_EXIT();
566
567 me->state.obj = (r >= Q_RET_TRAN)
568 ? me->temp.tatbl->target
569 : tatbl->target;
570 return r;
571}
572
573//${QEP::QMsm::exitToTranSource_} ............................................
574//! @private @memberof QMsm
575void QMsm_exitToTranSource_(
576 QAsm * const me,
577 QMState const * const cs,
578 QMState const * const ts,
579 uint_fast8_t const qsId)
580{
581 #ifndef Q_SPY
582 Q_UNUSED_PAR(qsId);
583 #endif
584
586
587 // exit states from the current state to the tran. source state
588 QMState const *s = cs;
589 int_fast8_t lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound
590 for (; (s != ts) && (lbound > 0); --lbound) {
591 // exit action provided in state 's'?
592 if (s->exitAction != Q_ACTION_CAST(0)) {
593 // execute the exit action
594 (void)(*s->exitAction)(me);
595
597 QS_MEM_SYS();
598 QS_BEGIN_PRE_(QS_QEP_STATE_EXIT, qsId)
599 QS_OBJ_PRE_(me); // this state machine object
600 QS_FUN_PRE_(s->stateHandler); // the exited state handler
601 QS_END_PRE_()
602 QS_MEM_APP();
603 QS_CRIT_EXIT();
604 }
605
606 s = s->superstate; // advance to the superstate
607
608 if (s == (QMState *)0) { // reached the top of a submachine?
609 s = me->temp.obj; // the superstate from QM_SM_EXIT()
611 Q_ASSERT_INCRIT(880, s != (QMState *)0); // must be valid
612 QF_CRIT_EXIT();
613 }
614 }
616 Q_ENSURE_INCRIT(890, lbound > 0);
617 QF_CRIT_EXIT();
618}
619
620//${QEP::QMsm::enterHistory_} ................................................
621//! @private @memberof QMsm
622QState QMsm_enterHistory_(
623 QAsm * const me,
624 QMState const *const hist,
625 uint_fast8_t const qsId)
626{
627 #ifndef Q_SPY
628 Q_UNUSED_PAR(qsId);
629 #endif
630
631 QMState const *s = hist;
632 QMState const *ts = me->state.obj; // tran. source
633 QMState const *epath[QMSM_MAX_ENTRY_DEPTH_];
634
636
638 QS_MEM_SYS();
639 QS_BEGIN_PRE_(QS_QEP_TRAN_HIST, qsId)
640 QS_OBJ_PRE_(me); // this state machine object
641 QS_FUN_PRE_(ts->stateHandler); // source state handler
642 QS_FUN_PRE_(hist->stateHandler); // target state handler
643 QS_END_PRE_()
644 QS_MEM_APP();
645 QS_CRIT_EXIT();
646
647 int_fast8_t i = 0; // tran. entry path index
648 while ((s != ts) && (i < QMSM_MAX_ENTRY_DEPTH_)) {
649 if (s->entryAction != Q_ACTION_CAST(0)) {
650 epath[i] = s;
651 ++i;
652 }
653 s = s->superstate;
654 if (s == (QMState *)0) {
655 ts = s; // force exit from the for-loop
656 }
657 }
659 Q_ASSERT_INCRIT(910, s == ts);
660 QF_CRIT_EXIT();
661
662 // retrace the entry path in reverse (desired) order...
663 while (i > 0) {
664 --i;
665 (void)(*epath[i]->entryAction)(me); // run entry action in epath[i]
666
668 QS_MEM_SYS();
669 QS_BEGIN_PRE_(QS_QEP_STATE_ENTRY, qsId)
670 QS_OBJ_PRE_(me);
671 QS_FUN_PRE_(epath[i]->stateHandler); // entered state handler
672 QS_END_PRE_()
673 QS_MEM_APP();
674 QS_CRIT_EXIT();
675 }
676
677 me->state.obj = hist; // set current state to the tran. target
678
679 // initial tran. present?
680 QState r;
681 if (hist->initAction != Q_ACTION_CAST(0)) {
682 r = (*hist->initAction)(me); // execute the tran. action
683 }
684 else {
685 r = Q_RET_NULL;
686 }
687
688 return r;
689}
690//$enddef${QEP::QMsm} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ QMSM_MAX_TRAN_LENGTH_
Definition qep_msm.c:74
@ QMSM_MAX_NEST_DEPTH_
Definition qep_msm.c:71
@ QMSM_MAX_ENTRY_DEPTH_
Definition qep_msm.c:77
@ Q_RET_ENTRY
state entry action executed
Definition qp.h:209
@ Q_RET_HANDLED
event handled (internal transition)
Definition qp.h:205
@ Q_RET_TRAN_XP
exit-point transition out of a submachine
Definition qp.h:222
@ Q_RET_TRAN_INIT
initial transition in a state or submachine
Definition qp.h:217
@ Q_RET_TRAN
regular transition
Definition qp.h:216
@ Q_RET_UNHANDLED
event unhandled due to a guard
Definition qp.h:202
@ Q_RET_SUPER
event passed to superstate to handle
Definition qp.h:200
@ Q_RET_NULL
return value without any effect
Definition qp.h:213
@ Q_RET_TRAN_HIST
transition to history of a given state
Definition qp.h:221
@ Q_RET_SUPER_SUB
event passed to submachine superstate
Definition qp.h:201
@ Q_RET_TRAN_EP
entry-point transition into a submachine
Definition qp.h:218
@ Q_RET_EXIT
state exit action executed
Definition qp.h:210
#define Q_UNUSED_PAR(par_)
Helper macro to clearly mark unused parameters of functions.
Definition qp.h:536
#define Q_STATE_CAST(handler_)
Perform cast to QStateHandler.
Definition qp.h:530
QState(* QStateHandler)(void *const me, QEvt const *const e)
Pointer to a state-handler function.
Definition qp.h:229
#define Q_ACTION_CAST(action_)
Perform cast to QActionHandler.
Definition qp.h:533
enum QStateRet QState
Type returned from state-handler functions.
Definition qp.h:226
#define Q_EVT_CAST(class_)
Perform downcast of an event onto a subclass of QEvt class_
Definition qp.h:527
QState(* QActionHandler)(void *const me)
Pointer to an action-handler function.
Definition qp.h:232
Internal (package scope) QP/C interface.
Sample QP/C port.
@ QS_QEP_STATE_INIT
an initial transition was taken in a state
Definition qs.h:84
@ QS_QEP_TRAN_HIST
a tran. to history was taken
Definition qs.h:162
#define QS_TIME_PRE_()
Definition qs.h:450
@ QS_QEP_TRAN_EP
a tran. to entry point into a submachine
Definition qs.h:163
@ QS_QEP_STATE_EXIT
a state was exited
Definition qs.h:83
@ QS_QEP_INIT_TRAN
the top-most initial transition was taken
Definition qs.h:85
#define QS_MEM_APP()
Definition qs.h:588
@ QS_QEP_INTERN_TRAN
an internal transition was taken
Definition qs.h:86
@ QS_QEP_TRAN_XP
a tran. to exit point out of a submachine
Definition qs.h:164
@ QS_QEP_STATE_ENTRY
a state was entered
Definition qs.h:82
@ QS_QEP_UNHANDLED
an event was un-handled due to a guard
Definition qs.h:90
@ QS_QEP_TRAN
a regular transition was taken
Definition qs.h:87
@ QS_QEP_DISPATCH
an event was dispatched (begin of RTC step)
Definition qs.h:89
@ QS_QEP_IGNORED
an event was ignored (silently discarded)
Definition qs.h:88
#define QS_CRIT_EXIT()
Definition qs.h:578
#define QS_MEM_SYS()
Definition qs.h:583
#define QS_CRIT_ENTRY()
Definition qs.h:573
QS/C package-scope interface.
Sample QS/C port.
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
Abstract State Machine class (state machine interface)
Definition qp.h:280
struct QAsmVtable const * vptr
Virtual pointer inherited by all QAsm subclasses (see also Object Orientation)
Definition qp.h:284
union QAsmAttr state
Current state (pointer to the current state-handler function)
Definition qp.h:289
union QAsmAttr temp
Temporary storage for target/act-table etc.
Definition qp.h:292
Virtual table for the QAsm class.
Definition qp.h:301
Event class.
Definition qp.h:145
QSignal sig
Signal of the event (see Event Signal)
Definition qp.h:149
State object for the QMsm class (QM State Machine)
Definition qp.h:242
struct QMState const * superstate
Definition qp.h:243
QActionHandler const entryAction
Definition qp.h:245
QActionHandler const initAction
Definition qp.h:247
QStateHandler const stateHandler
Definition qp.h:244
Transition-Action Table for the QMsm State Machine.
Definition qp.h:251
QActionHandler const act[1]
Definition qp.h:253
QMState const * target
Definition qp.h:252
Hierarchical State Machine class (QMsm-style state machine implementation strategy)
Definition qp.h:379
QAsm super
Definition qp.h:381
Attribute of for the QAsm class (Abstract State Machine)
Definition qp.h:267
uintptr_t uint
Definition qp.h:274
QMTranActTable const * tatbl
Definition qp.h:271
QStateHandler fun
Definition qp.h:268
struct QMState const * obj
Definition qp.h:272
QActionHandler act
Definition qp.h:269