44* @ingroup qep
55* @cond
66******************************************************************************
7- * Last updated for version 5.8.1
8- * Last updated on 2017-02-19
7+ * Last updated for version 5.8.2
8+ * Last updated on 2017-02-22
99*
1010* Q u a n t u m L e a P s
1111* ---------------------------
1212* innovating embedded systems
1313*
14- * Copyright (C) Quantum Leaps, www.state-machine.com .
14+ * Copyright (C) Quantum Leaps, LLC. All rights reserved .
1515*
1616* This program is open source software: you can redistribute it and/or
1717* modify it under the terms of the GNU General Public License as published
3232* along with this program. If not, see <http://www.gnu.org/licenses/>.
3333*
3434* Contact information:
35- * http:www.state-machine.com
35+ * http:// www.state-machine.com
3636* mailto:info@state-machine.com
3737******************************************************************************
3838* @endcond
@@ -73,14 +73,6 @@ static int_fast8_t QHsm_tran_(QHsm * const me,
7373*
7474* @note Must be called only ONCE before QHSM_INIT().
7575*
76- * @note
77- * QHsm inherits QHsm, so by the @ref oop convention it should call the
78- * constructor of the superclass, i.e., QHsm_ctor(). However, this would pull
79- * in the QHsmVtbl, which in turn will pull in the code for QHsm_init_() and
80- * QHsm_dispatch_() implemetations. To avoid this code size penalty, in case
81- * ::QHsm is not used in a given project, the QHsm_ctor() performs direct
82- * intitialization of the Vtbl, which avoids pulling in the code for QHsm.
83- *
8476* @usage
8577* The following example illustrates how to invoke QHsm_ctor() in the
8678* "constructor" of a derived state machine:
@@ -91,31 +83,11 @@ void QHsm_ctor(QHsm * const me, QStateHandler initial) {
9183 & QHsm_init_ ,
9284 & QHsm_dispatch_
9385 };
94- /* do not call the QHsm_ctor() here */
95- me -> vptr = & vtbl ;
86+ me -> vptr = & vtbl ;
9687 me -> state = Q_STATE_CAST (& QHsm_top );
9788 me -> temp = initial ;
9889}
9990
100- /****************************************************************************/
101- /**
102- * @description
103- * QHsm_top() is the ultimate root of state hierarchy in all HSMs derived
104- * from ::QHsm.
105- *
106- * @param[in] me pointer (see @ref oop)
107- *
108- * @returns Always returns #Q_RET_IGNORED, which means that the top state
109- * ignores all events.
110- *
111- * @note The parameter @p me to this state handler is not used. It is provided
112- * for conformance with the state-handler function signature ::QStateHandler.
113- */
114- QState QHsm_top (void const * const me ) {
115- (void )me ; /* suppress the "unused parameter" compiler warning */
116- return (QState )Q_RET_IGNORED ; /* the top state ignores all events */
117- }
118-
11991/****************************************************************************/
12092/**
12193* @description
@@ -133,14 +105,14 @@ void QHsm_init_(QHsm * const me) {
133105 * transition must be initialized, and the initial transition must not
134106 * be taken yet.
135107 */
136- Q_REQUIRE_ID (600 , (me -> vptr != (QHsmVtbl const * )0 )
108+ Q_REQUIRE_ID (200 , (me -> vptr != (QHsmVtbl const * )0 )
137109 && (me -> temp != Q_STATE_CAST (0 ))
138110 && (t == Q_STATE_CAST (& QHsm_top )));
139111
140112 r = (* me -> temp )(me ); /* execute the top-most initial transition */
141113
142114 /* the top-most initial transition must be taken */
143- Q_ASSERT_ID (610 , r == (QState )Q_RET_TRAN );
115+ Q_ASSERT_ID (210 , r == (QState )Q_RET_TRAN );
144116
145117 /* drill down into the state hierarchy with initial transitions... */
146118 do {
@@ -152,7 +124,7 @@ void QHsm_init_(QHsm * const me) {
152124 (void )(* me -> temp )(me );
153125 while (me -> temp != t ) {
154126 ++ ip ;
155- Q_ASSERT_ID (620 , ip < (int_fast8_t )Q_DIM (path ));
127+ Q_ASSERT_ID (220 , ip < (int_fast8_t )Q_DIM (path ));
156128 path [ip ] = me -> temp ;
157129 (void )(* me -> temp )(me );
158130 }
@@ -175,6 +147,25 @@ void QHsm_init_(QHsm * const me) {
175147 me -> temp = t ; /* mark the configuration as stable */
176148}
177149
150+ /****************************************************************************/
151+ /**
152+ * @description
153+ * QHsm_top() is the ultimate root of state hierarchy in all HSMs derived
154+ * from ::QHsm.
155+ *
156+ * @param[in] me pointer (see @ref oop)
157+ *
158+ * @returns Always returns #Q_RET_IGNORED, which means that the top state
159+ * ignores all events.
160+ *
161+ * @note The parameter @p me to this state handler is not used. It is provided
162+ * for conformance with the state-handler function signature ::QStateHandler.
163+ */
164+ QState QHsm_top (void const * const me ) {
165+ (void )me ; /* suppress the "unused parameter" compiler warning */
166+ return (QState )Q_RET_IGNORED ; /* the top state ignores all events */
167+ }
168+
178169/****************************************************************************/
179170/**
180171* @description
@@ -193,16 +184,18 @@ void QHsm_dispatch_(QHsm * const me) {
193184 QState r ;
194185 int_fast8_t iq ; /* helper transition entry path index */
195186
196- /** @pre the state configuration must be stable */
197- Q_REQUIRE_ID (700 , t == me -> temp );
187+ /** @pre the current state must be initialized and
188+ * the state configuration must be stable
189+ */
190+ Q_REQUIRE_ID (400 , (t != Q_STATE_CAST (0 ))
191+ && (t == me -> temp ));
198192
199193 /* process the event hierarchically... */
200194 do {
201195 s = me -> temp ;
202196 r = (* s )(me ); /* invoke state handler s */
203197
204- /* unhandled due to a guard? */
205- if (r == (QState )Q_RET_UNHANDLED ) {
198+ if (r == (QState )Q_RET_UNHANDLED ) { /* unhandled due to a guard? */
206199 iq = (int_fast8_t )Q_SIG (me ); /* save the original signal */
207200 Q_SIG (me ) = (QSignal )QEP_EMPTY_SIG_ ; /* find the superstate */
208201 r = (* s )(me ); /* invoke state handler s */
@@ -256,7 +249,7 @@ void QHsm_dispatch_(QHsm * const me) {
256249 me -> temp = path [0 ];
257250
258251 /* entry path must not overflow */
259- Q_ASSERT_ID (710 , ip < QHSM_MAX_NEST_DEPTH_ );
252+ Q_ASSERT_ID (410 , ip < QHSM_MAX_NEST_DEPTH_ );
260253
261254 /* retrace the entry path in reverse (correct) order... */
262255 Q_SIG (me ) = (QSignal )Q_ENTRY_SIG ;
@@ -344,7 +337,7 @@ static int_fast8_t QHsm_tran_(QHsm * const me,
344337 iq = (int_fast8_t )1 ; /* indicate that LCA found */
345338
346339 /* entry path must not overflow */
347- Q_ASSERT_ID (810 , ip < QHSM_MAX_NEST_DEPTH_ );
340+ Q_ASSERT_ID (510 , ip < QHSM_MAX_NEST_DEPTH_ );
348341 -- ip ; /* do not enter the source */
349342 r = (QState )Q_RET_HANDLED ; /* terminate loop */
350343 }
@@ -358,7 +351,7 @@ static int_fast8_t QHsm_tran_(QHsm * const me,
358351 if (iq == (int_fast8_t )0 ) {
359352
360353 /* entry path must not overflow */
361- Q_ASSERT_ID (820 , ip < QHSM_MAX_NEST_DEPTH_ );
354+ Q_ASSERT_ID (520 , ip < QHSM_MAX_NEST_DEPTH_ );
362355
363356 Q_SIG (me ) = (QSignal )Q_EXIT_SIG ;
364357 (void )(* s )(me ); /* exit the source */
@@ -369,9 +362,7 @@ static int_fast8_t QHsm_tran_(QHsm * const me,
369362 iq = ip ;
370363 r = (QState )Q_RET_IGNORED ; /* LCA NOT found */
371364 do {
372- s = path [iq ];
373- /* is this the LCA? */
374- if (t == s ) {
365+ if (t == path [iq ]) { /* is this the LCA? */
375366 r = (QState )Q_RET_HANDLED ; /* LCA found */
376367
377368 /* do not enter LCA */
@@ -383,7 +374,7 @@ static int_fast8_t QHsm_tran_(QHsm * const me,
383374 }
384375 } while (iq >= (int_fast8_t )0 );
385376
386- /* LCAnot found? */
377+ /* LCA not found? */
387378 if (r != (QState )Q_RET_HANDLED ) {
388379 /* (g) check each source->super->...
389380 * for each target->super...
@@ -396,12 +387,11 @@ static int_fast8_t QHsm_tran_(QHsm * const me,
396387 Q_SIG (me ) = (QSignal )QEP_EMPTY_SIG_ ;
397388 (void )(* t )(me ); /* find super of t */
398389 }
399- t = me -> temp ; /* set to super of t */
390+ t = me -> temp ; /* set to super of t */
400391 iq = ip ;
401392 do {
402- s = path [iq ];
403393 /* is this LCA? */
404- if (t == s ) {
394+ if (t == path [ iq ] ) {
405395 /* do not enter LCA */
406396 ip = (int_fast8_t )(iq - (int_fast8_t )1 );
407397 /* cause breaking out of inner loop */
@@ -466,7 +456,7 @@ QStateHandler QHsm_childState_(QHsm * const me,
466456 me -> temp = me -> state ; /* establish stable state configuration */
467457
468458 /** @post the child must be confirmed */
469- Q_ENSURE_ID (910 , isConfirmed != false);
459+ Q_ENSURE_ID (710 , isConfirmed != false);
470460
471461 return child ; /* return the child */
472462}
0 commit comments