This commit is contained in:
Quantum Leaps 2017-11-12 21:35:04 -05:00
parent fc9e78a100
commit b96369996d
46 changed files with 2619 additions and 799 deletions

View File

@ -5,7 +5,7 @@
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = "QP/C++"
PROJECT_NUMBER = "6.0.0"
PROJECT_NUMBER = "6.0.1"
PROJECT_BRIEF =
PROJECT_LOGO = images/header_logo_ql.png
OUTPUT_DIRECTORY =

View File

@ -5,7 +5,7 @@
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = "QP/C++"
PROJECT_NUMBER = "6.0.0"
PROJECT_NUMBER = "6.0.1"
PROJECT_BRIEF =
PROJECT_LOGO = images/header_logo_ql.png
OUTPUT_DIRECTORY =

View File

@ -2,6 +2,27 @@ namespace QP {
/** @page history Revision History
@section qpcpp_6_0_1 Version 6.0.1, 2017-11-10
The main focus of this release is to fix the remaining problems with transitions out of eXit-Points in sub-machines. Specifically, this release modifies the QMsm-based state machine implementation strategy (file src/qf/qep_msm.cpp to properly handle transitions from eXit-Points to Entry-Points and to History connectors in sub-machines. These changes are part of fixing the following bugs reported for QM:
- [bug#190 "Exit-Point segment targeting History doesn't work](https://sourceforge.net/p/qpc/bugs/190/)
- [bug#189 "Exit-Point segment targeting an Entry-Point to sub-machine state doesn't work"](https://sourceforge.net/p/qpc/bugs/189/)
Additionally, this release fixes the following bug in transitions to "shallow history":
- [bug#191 "Transition to shallow history in QMsm causes assertion qep_msm#810"](https://sourceforge.net/p/qpc/bugs/191/)
The bug#191 is fixed by modifying the function QMsm::childStateObj() in qep_msm.cpp to return the parent state in the corner case when the current state is the parent state.
@note
This QP/C++ 6.0.1 release is the minium version required in the upcoming QM 4.1.0. This is because QM 4.1.0 assumes the modified QMsm-state machine implementation strategy in order to properly handle the various transitions out of eXit-Points in sub-machine states.
Additionally, this release changes the QXK implementation still related to the [bug#186 "QXK: Extended thread context switch causes assertion in PendSV_Handler"](https://sourceforge.net/p/qpc/bugs/186/). Specifically, the case of context switching away and back to the same thread (which can arise under specific interrupt preemption scenarios) is now handled as a simple return from PendSV. The QXK scheduler has been modified to set the "next" thread pointer to NULL when it detects switching back to the "current" thread.
------------------------------------------------------------------------------
@section qpcpp_6_0_0 Version 6.0.0, 2017-10-13
This release fixes two bugs found in the QXK kernel:
- [bug#185](https://sourceforge.net/p/qpc/bugs/185/) "QXK: PendSV_Handler uses inconsistent stack frames for saving and restoring AO for Cortex-M0(+)"

View File

@ -1,8 +1,8 @@
@echo off
:: ==========================================================================
:: Product: QP/C++ script for generating Doxygen documentation
:: Last Updated for Version: 6.0.0
:: Date of the Last Update: 2017-10-13
:: Last Updated for Version: 6.0.1
:: Date of the Last Update: 2017-11-12
::
:: Q u a n t u m L e a P s
:: ---------------------------
@ -38,7 +38,7 @@ echo usage:
echo make
echo make -CHM
set VERSION=6.0.0
set VERSION=6.0.1
:: Generate Resource Standard Metrics for QP/C++ .............................
set DOXHOME="C:\tools\doxygen\bin"

View File

@ -1,7 +1,7 @@
/** @page metrics Code Metrics
@code
Standard Code Metrics for QP/C++ 6.0.0
Standard Code Metrics for QP/C++ 6.0.1
Resource Standard Metrics (TM) for C, C++, C# and Java
Version 7.75 - mSquaredTechnologies.com
@ -9,7 +9,7 @@
License Type: Windows Single User License
Licensed To : Quantum Leaps, LLC
License No. : WS2975 License Date: Dec 15, 2013
Build Date : Sep 2 2009 Run Date: Oct 18, 2017
Build Date : Sep 2 2009 Run Date: Nov 12, 2017
(C)1996-2009 M Squared Technologies LLC
________________________________________________________________________
@ -827,12 +827,12 @@
Conditional if / else if: 1
Logical and ( && ) : 1
Complexity Param 1 Return 1 Cyclo Vg 6 Total 8
LOC 49 eLOC 46 lLOC 30 Comment 30 Lines 67
LOC 49 eLOC 46 lLOC 30 Comment 31 Lines 67
Function: QP::QHsm::top
Parameters: (void * const, QEvt const * const)
Complexity Param 2 Return 1 Cyclo Vg 1 Total 4
LOC 3 eLOC 2 lLOC 1 Comment 15 Lines 3
LOC 3 eLOC 2 lLOC 1 Comment 16 Lines 3
Function: QP::QHsm::dispatch
Parameters: (QEvt const * const e)
@ -852,7 +852,7 @@
Loops while / do : 4
Conditional if / else if: 10
Complexity Param 1 Return 1 Cyclo Vg 15 Total 17
LOC 99 eLOC 79 lLOC 48 Comment 61 Lines 140
LOC 99 eLOC 79 lLOC 48 Comment 62 Lines 140
Function: QP::QHsm::isIn
Parameters: (QStateHandler const s)
@ -861,7 +861,7 @@
Loops while / do : 1
Conditional if / else if: 1
Complexity Param 1 Return 1 Cyclo Vg 3 Total 5
LOC 16 eLOC 13 lLOC 9 Comment 21 Lines 23
LOC 16 eLOC 13 lLOC 9 Comment 22 Lines 23
Function: QP::QHsm::childState
Parameters: (QStateHandler const parent)
@ -870,13 +870,13 @@
Loops while / do : 1
Conditional if / else if: 1
Complexity Param 1 Return 1 Cyclo Vg 3 Total 5
LOC 19 eLOC 16 lLOC 12 Comment 27 Lines 25
LOC 19 eLOC 16 lLOC 12 Comment 29 Lines 25
------------------------------------------------------------------------
~~ Total File Summary ~~
LOC 348 eLOC 302 lLOC 169 Comment 289 Lines 611
LOC 348 eLOC 302 lLOC 169 Comment 295 Lines 617
------------------------------------------------------------------------
~~ File Functional Summary ~~
@ -907,7 +907,7 @@
Function: QP::QMsm::QMsm
Parameters: (QStateHandler const initial)
Complexity Param 1 Return 1 Cyclo Vg 1 Total 3
LOC 4 eLOC 2 lLOC 2 Comment 13 Lines 4
LOC 4 eLOC 2 lLOC 2 Comment 15 Lines 4
Function: QP::QMsm::init
Parameters: (QEvt const * const e)
@ -923,18 +923,19 @@
Cyclomatic Complexity Vg Detail
Function Base : 1
Loops while / do : 2
Conditional if / else if: 13
Complexity Param 1 Return 1 Cyclo Vg 16 Total 18
LOC 117 eLOC 100 lLOC 61 Comment 73 Lines 159
Conditional if / else if: 12
Complexity Param 1 Return 1 Cyclo Vg 15 Total 17
LOC 112 eLOC 95 lLOC 61 Comment 72 Lines 153
Function: QP::QMsm::execTatbl_
Parameters: (QMTranActTable const * const tatbl)
Cyclomatic Complexity Vg Detail
Function Base : 1
Loops for / foreach : 1
Conditional if / else if: 6
Conditional if / else if: 5
Inlined if-else ( ? : ) : 1
Complexity Param 1 Return 1 Cyclo Vg 8 Total 10
LOC 56 eLOC 46 lLOC 21 Comment 31 Lines 67
LOC 53 eLOC 45 lLOC 20 Comment 30 Lines 63
Function: QP::QMsm::exitToTranSource_
Parameters: (QMState const *s, QMState const * const ts)
@ -952,7 +953,7 @@
Loops while / do : 2
Conditional if / else if: 3
Complexity Param 1 Return 1 Cyclo Vg 6 Total 8
LOC 40 eLOC 33 lLOC 21 Comment 22 Lines 48
LOC 40 eLOC 33 lLOC 21 Comment 23 Lines 48
Function: QP::QMsm::isInState
Parameters: (QMState const * const st)
@ -970,33 +971,33 @@
Loops for / foreach : 1
Conditional if / else if: 1
Complexity Param 1 Return 1 Cyclo Vg 3 Total 5
LOC 19 eLOC 14 lLOC 9 Comment 17 Lines 23
LOC 19 eLOC 14 lLOC 9 Comment 19 Lines 23
------------------------------------------------------------------------
~~ Total File Summary ~~
LOC 312 eLOC 259 lLOC 139 Comment 262 Lines 544
LOC 304 eLOC 253 lLOC 138 Comment 265 Lines 541
------------------------------------------------------------------------
~~ File Functional Summary ~~
File Function Count....: 8
Total Function LOC.....: 288 Total Function Pts LOC : 5.9
Total Function eLOC....: 237 Total Function Pts eLOC: 4.9
Total Function lLOC....: 137 Total Function Pts lLOC: 2.6
Total Function LOC.....: 280 Total Function Pts LOC : 5.7
Total Function eLOC....: 231 Total Function Pts eLOC: 4.8
Total Function lLOC....: 136 Total Function Pts lLOC: 2.6
Total Function Params .: 9 Total Function Return .: 8
Total Cyclo Complexity : 44 Total Function Complex.: 61
Total Cyclo Complexity : 43 Total Function Complex.: 60
------ ----- ----- ------ ------ -----
Max Function LOC ......: 117 Average Function LOC ..: 36.00
Max Function eLOC .....: 100 Average Function eLOC .: 29.63
Max Function lLOC .....: 61 Average Function lLOC .: 17.13
Max Function LOC ......: 112 Average Function LOC ..: 35.00
Max Function eLOC .....: 95 Average Function eLOC .: 28.88
Max Function lLOC .....: 61 Average Function lLOC .: 17.00
------ ----- ----- ------ ------ -----
Max Function Parameters: 2 Avg Function Parameters: 1.13
Max Function Returns ..: 1 Avg Function Returns ..: 1.00
Max Interface Complex. : 3 Avg Interface Complex. : 2.13
Max Cyclomatic Complex.: 16 Avg Cyclomatic Complex.: 5.50
Max Total Complexity ..: 18 Avg Total Complexity ..: 7.63
Max Cyclomatic Complex.: 15 Avg Cyclomatic Complex.: 5.38
Max Total Complexity ..: 17 Avg Total Complexity ..: 7.50
________________________________________________________________________
End of File: ..\src\qf\qep_msm.cpp
@ -1893,7 +1894,7 @@
Function Base : 1
Conditional if / else if: 1
Complexity Param 0 Return 1 Cyclo Vg 2 Total 3
LOC 11 eLOC 9 lLOC 6 Comment 13 Lines 14
LOC 11 eLOC 9 lLOC 6 Comment 13 Lines 15
Function: QP::QXK::schedLock
Parameters: (uint_fast8_t const ceiling)
@ -1928,7 +1929,7 @@
Loops while / do : 1
Conditional if / else if: 6
Complexity Param 0 Return 1 Cyclo Vg 8 Total 9
LOC 79 eLOC 69 lLOC 35 Comment 53 Lines 108
LOC 78 eLOC 68 lLOC 35 Comment 53 Lines 107
Function: QXK_current
Parameters: (void)
@ -1942,20 +1943,20 @@
~~ Total File Summary ~~
LOC 292 eLOC 249 lLOC 128 Comment 291 Lines 570
LOC 290 eLOC 247 lLOC 127 Comment 292 Lines 568
------------------------------------------------------------------------
~~ File Functional Summary ~~
File Function Count....: 12
Total Function LOC.....: 235 Total Function Pts LOC : 5.5
Total Function eLOC....: 201 Total Function Pts eLOC: 4.7
Total Function LOC.....: 234 Total Function Pts LOC : 5.5
Total Function eLOC....: 200 Total Function Pts eLOC: 4.7
Total Function lLOC....: 112 Total Function Pts lLOC: 2.4
Total Function Params .: 9 Total Function Return .: 12
Total Cyclo Complexity : 35 Total Function Complex.: 56
------ ----- ----- ------ ------ -----
Max Function LOC ......: 79 Average Function LOC ..: 19.58
Max Function eLOC .....: 69 Average Function eLOC .: 16.75
Max Function LOC ......: 78 Average Function LOC ..: 19.50
Max Function eLOC .....: 68 Average Function eLOC .: 16.67
Max Function lLOC .....: 35 Average Function lLOC .: 9.33
------ ----- ----- ------ ------ -----
Max Function Parameters: 6 Avg Function Parameters: 0.75
@ -1971,7 +1972,7 @@
________________________________________________________________________
Function: QP::QXMutex::init
Parameters: (uint_fast8_t ceiling)
Parameters: (uint_fast8_t const ceiling)
Cyclomatic Complexity Vg Detail
Function Base : 1
Conditional if / else if: 1
@ -2054,7 +2055,7 @@
Conditional if / else if: 1
Logical and ( && ) : 3
Complexity Param 1 Return 1 Cyclo Vg 5 Total 7
LOC 28 eLOC 25 lLOC 17 Comment 36 Lines 41
LOC 28 eLOC 25 lLOC 17 Comment 37 Lines 42
Function: QP::QXSemaphore::tryWait
Parameters: (void)
@ -2069,35 +2070,35 @@
Cyclomatic Complexity Vg Detail
Function Base : 1
Conditional if / else if: 3
Logical and ( && ) : 2
Complexity Param 0 Return 1 Cyclo Vg 6 Total 7
LOC 29 eLOC 23 lLOC 14 Comment 26 Lines 39
Logical and ( && ) : 3
Complexity Param 0 Return 1 Cyclo Vg 7 Total 8
LOC 30 eLOC 24 lLOC 14 Comment 28 Lines 41
------------------------------------------------------------------------
~~ Total File Summary ~~
LOC 95 eLOC 80 lLOC 43 Comment 144 Lines 240
LOC 96 eLOC 81 lLOC 43 Comment 147 Lines 244
------------------------------------------------------------------------
~~ File Functional Summary ~~
File Function Count....: 4
Total Function LOC.....: 78 Total Function Pts LOC : 1.8
Total Function eLOC....: 64 Total Function Pts eLOC: 1.5
Total Function LOC.....: 79 Total Function Pts LOC : 1.8
Total Function eLOC....: 65 Total Function Pts eLOC: 1.5
Total Function lLOC....: 43 Total Function Pts lLOC: 0.8
Total Function Params .: 3 Total Function Return .: 4
Total Cyclo Complexity : 14 Total Function Complex.: 21
Total Cyclo Complexity : 15 Total Function Complex.: 22
------ ----- ----- ------ ------ -----
Max Function LOC ......: 29 Average Function LOC ..: 19.50
Max Function eLOC .....: 25 Average Function eLOC .: 16.00
Max Function LOC ......: 30 Average Function LOC ..: 19.75
Max Function eLOC .....: 25 Average Function eLOC .: 16.25
Max Function lLOC .....: 17 Average Function lLOC .: 10.75
------ ----- ----- ------ ------ -----
Max Function Parameters: 2 Avg Function Parameters: 0.75
Max Function Returns ..: 1 Avg Function Returns ..: 1.00
Max Interface Complex. : 3 Avg Interface Complex. : 1.75
Max Cyclomatic Complex.: 6 Avg Cyclomatic Complex.: 3.50
Max Total Complexity ..: 7 Avg Total Complexity ..: 5.25
Max Cyclomatic Complex.: 7 Avg Cyclomatic Complex.: 3.75
Max Total Complexity ..: 8 Avg Total Complexity ..: 5.50
________________________________________________________________________
End of File: ..\src\qxk\qxk_sema.cpp
@ -2108,7 +2109,7 @@
Function: QP::QXThread::QXThread
Parameters: (QXThreadHandler const handler, uint_fast8_t const tickRate)
Complexity Param 2 Return 1 Cyclo Vg 1 Total 4
LOC 3 eLOC 1 lLOC 1 Comment 18 Lines 3
LOC 3 eLOC 1 lLOC 1 Comment 19 Lines 3
Function: QP::QXThread::init
Parameters: (QEvt const * const)
@ -2205,7 +2206,7 @@
~~ Total File Summary ~~
LOC 292 eLOC 243 lLOC 138 Comment 319 Lines 611
LOC 292 eLOC 243 lLOC 138 Comment 320 Lines 612
------------------------------------------------------------------------
~~ File Functional Summary ~~
@ -2238,7 +2239,7 @@
~~ Total Project Summary ~~
LOC 4915 eLOC 4348 lLOC 1895 Comment 6484 Lines 11684
LOC 4906 eLOC 4341 lLOC 1893 Comment 6498 Lines 11690
Average per File, metric/37 files
LOC 132 eLOC 117 lLOC 51 Comment 175 Lines 315
@ -2596,12 +2597,12 @@
Function: QP::QHsm::init
Parameters: (QEvt const * const e)
Complexity Param 1 Return 1 Cyclo Vg 6 Total 8
LOC 49 eLOC 46 lLOC 30 Comment 30 Lines 67
LOC 49 eLOC 46 lLOC 30 Comment 31 Lines 67
Function: QP::QHsm::top
Parameters: (void * const, QEvt const * const)
Complexity Param 2 Return 1 Cyclo Vg 1 Total 4
LOC 3 eLOC 2 lLOC 1 Comment 15 Lines 3
LOC 3 eLOC 2 lLOC 1 Comment 16 Lines 3
Function: QP::QHsm::dispatch
Parameters: (QEvt const * const e)
@ -2611,22 +2612,22 @@
Function: QP::QHsm::hsm_tran
Parameters: (QStateHandler (&path)[MAX_NEST_DEPTH_])
Complexity Param 1 Return 1 Cyclo Vg 15 Total 17
LOC 99 eLOC 79 lLOC 48 Comment 61 Lines 140
LOC 99 eLOC 79 lLOC 48 Comment 62 Lines 140
Function: QP::QHsm::isIn
Parameters: (QStateHandler const s)
Complexity Param 1 Return 1 Cyclo Vg 3 Total 5
LOC 16 eLOC 13 lLOC 9 Comment 21 Lines 23
LOC 16 eLOC 13 lLOC 9 Comment 22 Lines 23
Function: QP::QHsm::childState
Parameters: (QStateHandler const parent)
Complexity Param 1 Return 1 Cyclo Vg 3 Total 5
LOC 19 eLOC 16 lLOC 12 Comment 27 Lines 25
LOC 19 eLOC 16 lLOC 12 Comment 29 Lines 25
Function: QP::QMsm::QMsm
Parameters: (QStateHandler const initial)
Complexity Param 1 Return 1 Cyclo Vg 1 Total 3
LOC 4 eLOC 2 lLOC 2 Comment 13 Lines 4
LOC 4 eLOC 2 lLOC 2 Comment 15 Lines 4
Function: QP::QMsm::init
Parameters: (QEvt const * const e)
@ -2635,13 +2636,13 @@
Function: QP::QMsm::dispatch
Parameters: (QEvt const * const e)
Complexity Param 1 Return 1 Cyclo Vg 16 Total 18
LOC 117 eLOC 100 lLOC 61 Comment 73 Lines 159
Complexity Param 1 Return 1 Cyclo Vg 15 Total 17
LOC 112 eLOC 95 lLOC 61 Comment 72 Lines 153
Function: QP::QMsm::execTatbl_
Parameters: (QMTranActTable const * const tatbl)
Complexity Param 1 Return 1 Cyclo Vg 8 Total 10
LOC 56 eLOC 46 lLOC 21 Comment 31 Lines 67
LOC 53 eLOC 45 lLOC 20 Comment 30 Lines 63
Function: QP::QMsm::exitToTranSource_
Parameters: (QMState const *s, QMState const * const ts)
@ -2651,7 +2652,7 @@
Function: QP::QMsm::enterHistory_
Parameters: (QMState const * const hist)
Complexity Param 1 Return 1 Cyclo Vg 6 Total 8
LOC 40 eLOC 33 lLOC 21 Comment 22 Lines 48
LOC 40 eLOC 33 lLOC 21 Comment 23 Lines 48
Function: QP::QMsm::isInState
Parameters: (QMState const * const st)
@ -2661,7 +2662,7 @@
Function: QP::QMsm::childStateObj
Parameters: (QMState const * const parent)
Complexity Param 1 Return 1 Cyclo Vg 3 Total 5
LOC 19 eLOC 14 lLOC 9 Comment 17 Lines 23
LOC 19 eLOC 14 lLOC 9 Comment 19 Lines 23
Function: QP::QF::add_
Parameters: (QActive * const a)
@ -3006,7 +3007,7 @@
Function: QP::QActive::stop
Parameters: (void)
Complexity Param 0 Return 1 Cyclo Vg 2 Total 3
LOC 11 eLOC 9 lLOC 6 Comment 13 Lines 14
LOC 11 eLOC 9 lLOC 6 Comment 13 Lines 15
Function: QP::QXK::schedLock
Parameters: (uint_fast8_t const ceiling)
@ -3026,7 +3027,7 @@
Function: QXK_activate_
Parameters: (void)
Complexity Param 0 Return 1 Cyclo Vg 8 Total 9
LOC 79 eLOC 69 lLOC 35 Comment 53 Lines 108
LOC 78 eLOC 68 lLOC 35 Comment 53 Lines 107
Function: QXK_current
Parameters: (void)
@ -3034,7 +3035,7 @@
LOC 14 eLOC 12 lLOC 8 Comment 4 Lines 21
Function: QP::QXMutex::init
Parameters: (uint_fast8_t ceiling)
Parameters: (uint_fast8_t const ceiling)
Complexity Param 1 Return 1 Cyclo Vg 4 Total 6
LOC 16 eLOC 14 lLOC 8 Comment 30 Lines 24
@ -3061,7 +3062,7 @@
Function: QP::QXSemaphore::wait
Parameters: (uint_fast16_t const nTicks)
Complexity Param 1 Return 1 Cyclo Vg 5 Total 7
LOC 28 eLOC 25 lLOC 17 Comment 36 Lines 41
LOC 28 eLOC 25 lLOC 17 Comment 37 Lines 42
Function: QP::QXSemaphore::tryWait
Parameters: (void)
@ -3070,13 +3071,13 @@
Function: QP::QXSemaphore::signal
Parameters: (void)
Complexity Param 0 Return 1 Cyclo Vg 6 Total 7
LOC 29 eLOC 23 lLOC 14 Comment 26 Lines 39
Complexity Param 0 Return 1 Cyclo Vg 7 Total 8
LOC 30 eLOC 24 lLOC 14 Comment 28 Lines 41
Function: QP::QXThread::QXThread
Parameters: (QXThreadHandler const handler, uint_fast8_t const tickRate)
Complexity Param 2 Return 1 Cyclo Vg 1 Total 4
LOC 3 eLOC 1 lLOC 1 Comment 18 Lines 3
LOC 3 eLOC 1 lLOC 1 Comment 19 Lines 3
Function: QP::QXThread::init
Parameters: (QEvt const * const)
@ -3141,29 +3142,29 @@
LOC 14 eLOC 11 lLOC 7 Comment 2 Lines 16
Total: Functions
LOC 2785 eLOC 2317 lLOC 1373 InCmp 340 CycloCmp 480
Function Points FP(LOC) 47.5 FP(eLOC) 40.1 FP(lLOC) 24.0
LOC 2777 eLOC 2311 lLOC 1372 InCmp 340 CycloCmp 480
Function Points FP(LOC) 47.4 FP(eLOC) 40.0 FP(lLOC) 24.0
------------------------------------------------------------------------
~~ Project Functional Analysis ~~
Total Functions .......: 175 Total Physical Lines ..: 3850
Total LOC .............: 2785 Total Function Pts LOC : 47.5
Total eLOC ............: 2317 Total Function Pts eLOC: 40.1
Total lLOC.............: 1373 Total Function Pts lLOC: 24.0
Total Functions .......: 175 Total Physical Lines ..: 3843
Total LOC .............: 2777 Total Function Pts LOC : 47.4
Total eLOC ............: 2311 Total Function Pts eLOC: 40.0
Total lLOC.............: 1372 Total Function Pts lLOC: 24.0
Total Cyclomatic Comp. : 480 Total Interface Comp. .: 340
Total Parameters ......: 165 Total Return Points ...: 175
Total Comment Lines ...: 2715 Total Blank Lines .....: 520
Total Comment Lines ...: 2728 Total Blank Lines .....: 520
------ ----- ----- ------ ------ -----
Avg Physical Lines ....: 22.00
Avg LOC ...............: 15.91 Avg eLOC ..............: 13.24
Avg lLOC ..............: 7.85 Avg Cyclomatic Comp. ..: 2.74
Avg Physical Lines ....: 21.96
Avg LOC ...............: 15.87 Avg eLOC ..............: 13.21
Avg lLOC ..............: 7.84 Avg Cyclomatic Comp. ..: 2.74
Avg Interface Comp. ...: 1.94 Avg Parameters ........: 0.94
Avg Return Points .....: 1.00 Avg Comment Lines .....: 15.51
Avg Return Points .....: 1.00 Avg Comment Lines .....: 15.59
------ ----- ----- ------ ------ -----
Max LOC ...............: 117
Max eLOC ..............: 100 Max lLOC ..............: 61
Max LOC ...............: 112
Max eLOC ..............: 96 Max lLOC ..............: 61
Max Cyclomatic Comp. ..: 18 Max Interface Comp. ...: 7
Max Parameters ........: 6 Max Return Points .....: 1
Max Comment Lines .....: 111 Max Total Lines .......: 191

View File

@ -28,21 +28,55 @@ The standard QP/C++ distribution contains the POSIX port and @ref exa_posix "Exa
/*##########################################################################*/
/*! @page qt Qt GUI Framework
@image html logo_qt.jpg
<p>The QP/C++ ports and examples for [Qt](https://www.qt.io/) are described in the Quantum Leaps Application Note <a class="extern" target="_blank" href="https://state-machine.com/doc/AN_QP_and_Qt.pdf"><strong>QP and the Qt GUI Framework</strong></a>.
</p>
@image html under_construction.jpg
@htmlonly
<div class="image">
<a target="_blank" href="https://state-machine.com/doc/AN_QP_and_Qt.pdf"><img border="0" src="img/AN.jpg" title="Download PDF"></a>
<div class="caption">
Application Note: QP and the Qt GUI Framework
</div>
</div>
@endhtmlonly
The standard QP/C++ distribution contains the Qt port and @ref exa_qt "Example Projects for the Qt Framework".
*/
/*##########################################################################*/
/*! @page win32 Win32 API (Windows)
@image html under_construction.jpg
<p>The QP/C/C++ ports and examples for Windows (e.g., Windows Embedded, WindowsCE etc.) are described in the Quantum Leaps Application Note <a class="extern" target="_blank" href="https://state-machine.com/doc/AN_QP_and_Win32.pdf"><strong>QP and Win32 (Windows)</strong></a>.
</p>
@htmlonly
<div class="image">
<a target="_blank" href="https://state-machine.com/doc/AN_QP_and_Win32.pdf"><img border="0" src="img/AN.jpg" title="Download PDF"></a>
<div class="caption">
Application Note: QP and Win32 (Windows)
</div>
</div>
@endhtmlonly
The standard QP/C++ distribution contains the Win32 (Windows) port and @ref exa_win32 "Example Projects for Win32 (Windows)".
*/
/*##########################################################################*/
/*! @page win32-qv Win32-QV (Windows with QV)
@image html under_construction.jpg
<p>The QP/C/C++ ports and examples for Windows with single-thread (like the @ref qv "QV cooperative kernel") are described in the Quantum Leaps Application Note <a class="extern" target="_blank" href="https://state-machine.com/doc/AN_QP_and_Win32.pdf"><strong>QP and Win32 (Windows)</strong></a>.
</p>
@htmlonly
<div class="image">
<a target="_blank" href="https://state-machine.com/doc/AN_QP_and_Win32.pdf"><img border="0" src="img/AN.jpg" title="Download PDF"></a>
<div class="caption">
Application Note: QP and Win32 (Windows)
</div>
</div>
@endhtmlonly
The standard QP/C++ distribution contains the Win32-QV port and @ref exa_win32-qv "Example Projects for Win32-QV".
*/

View File

@ -1,22 +1,23 @@
//****************************************************************************
// Model: dpp_qmsm.qm
// File: ./dpp.h
//$file${.::dpp.h} ###########################################################
//
// This code has been generated by QM tool (see state-machine.com/qm).
// Model: dpp_qmsm.qm
// File: C:/qp_lab/qpcpp/examples/performance/dpp_efm32-slstk3401a/dpp.h
//
// This code has been generated by QM tool (https://state-machine.com/qm).
// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
//
// This code is covered by the following commercial QP license:
// License # : QPCPP-EVAL-170201
// This code is covered by the following QP license:
// License # : QPCPP-EVAL-171231
// Issued to : Company/individual evaluating the QP/C++ framework
// Framework(s): qpcpp
// Support ends: 2017-02-28
// Support ends: 2017-12-31
// Product(s) :
// This license is available only for evaluation purposes and
// the generated code is still licensed under the terms of GPL.
// Please submit request for extension of the evaluaion period at:
// https://state-machine.com/licensing/index.html#RequestForm
//****************************************************************************
//${.::dpp.h} ................................................................
// https://state-machine.com/licensing/#RequestForm
//
//$endhead${.::dpp.h} ########################################################
#ifndef dpp_h
#define dpp_h
@ -36,47 +37,47 @@ enum DPPSignals {
} // namespace DPP
//$declare${Events::TableEvt} ################################################
namespace DPP {
#if ((QP_VERSION < 580) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8)))
#error qpcpp version 5.8.0 or higher required
#endif
//${Events::TableEvt} ........................................................
class TableEvt : public QP::QEvt {
public:
uint8_t philoNum;
};
} // namespace DPP
} // namespace DPP//$enddecl${Events::TableEvt} ################################################
// number of philosophers
#define N_PHILO ((uint8_t)5)
//$declare${AOs::AO_Philo[N_PHILO]} ##########################################
namespace DPP {
extern QP::QActive * const AO_Philo[N_PHILO];
} // namespace DPP
} // namespace DPP//$enddecl${AOs::AO_Philo[N_PHILO]} ##########################################
//$declare${AOs::AO_Table} ###################################################
namespace DPP {
extern QP::QActive * const AO_Table;
} // namespace DPP
} // namespace DPP//$enddecl${AOs::AO_Table} ###################################################
#ifdef qxk_h
//$declare${AOs::XT_Test1} ###################################################
namespace DPP {
extern QP::QXThread * const XT_Test1;
} // namespace DPP
} // namespace DPP//$enddecl${AOs::XT_Test1} ###################################################
//$declare${AOs::XT_Test2} ###################################################
namespace DPP {
extern QP::QXThread * const XT_Test2;
} // namespace DPP
} // namespace DPP//$enddecl${AOs::XT_Test2} ###################################################
#endif // qxk_h
#endif // dpp_h
#endif // dpp_h

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<model version="4.0.0" links="0">
<documentation>Dining Philosopher Problem example with MSM state machines</documentation>
<framework name="qpcpp" license="../../../QPCPP-EVAL-170201.qlc"/>
<model version="4.1.0" links="0">
<documentation>Dining Philosopher Problem example with MSM state machines.</documentation>
<framework name="qpcpp" license="../../../QPCPP-EVAL-171231.qlc"/>
<package name="Events" stereotype="0x01" namespace="DPP::">
<class name="TableEvt" superclass="qpcpp::QEvt">
<attribute name="philoNum" type="uint8_t" visibility="0x00" properties="0x00"/>

View File

@ -1,22 +1,23 @@
//****************************************************************************
// Model: dpp_qmsm.qm
// File: ./philo.cpp
//$file${.::philo.cpp} #######################################################
//
// This code has been generated by QM tool (see state-machine.com/qm).
// Model: dpp_qmsm.qm
// File: C:/qp_lab/qpcpp/examples/performance/dpp_efm32-slstk3401a/philo.cpp
//
// This code has been generated by QM tool (https://state-machine.com/qm).
// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
//
// This code is covered by the following commercial QP license:
// License # : QPCPP-EVAL-170201
// This code is covered by the following QP license:
// License # : QPCPP-EVAL-171231
// Issued to : Company/individual evaluating the QP/C++ framework
// Framework(s): qpcpp
// Support ends: 2017-02-28
// Support ends: 2017-12-31
// Product(s) :
// This license is available only for evaluation purposes and
// the generated code is still licensed under the terms of GPL.
// Please submit request for extension of the evaluaion period at:
// https://state-machine.com/licensing/index.html#RequestForm
//****************************************************************************
//${.::philo.cpp} ............................................................
// https://state-machine.com/licensing/#RequestForm
//
//$endhead${.::philo.cpp} ####################################################
#include "qpcpp.h"
#include "dpp.h"
#include "bsp.h"
@ -24,13 +25,9 @@
Q_DEFINE_THIS_FILE
// Active object class -------------------------------------------------------
//$declare${AOs::Philo} ######################################################
namespace DPP {
#if ((QP_VERSION < 580) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8)))
#error qpcpp version 5.8.0 or higher required
#endif
//${AOs::Philo} ..............................................................
class Philo : public QP::QMActive {
private:
@ -54,7 +51,7 @@ protected:
static QP::QMState const eating_s;
};
} // namespace DPP
} // namespace DPP//$enddecl${AOs::Philo} ######################################################
namespace DPP {
@ -94,6 +91,11 @@ QP::QActive * const AO_Philo[N_PHILO] = { // "opaque" pointers to Philo AO
} // namespace DPP
// Philo definition ----------------------------------------------------------
//$define${AOs::Philo} #######################################################
// Check for the minimum required QP version
#if ((QP_VERSION < 601) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8)))
#error qpcpp version 6.0.1 or higher required
#endif
namespace DPP {
//${AOs::Philo} ..............................................................
@ -108,14 +110,14 @@ QP::QState Philo::initial(Philo * const me, QP::QEvt const * const e) {
static struct {
QP::QMState const *target;
QP::QActionHandler act[2];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&thinking_s, // target state
{
Q_ACTION_CAST(&thinking_e), // entry
Q_ACTION_CAST(0) // zero terminator
}
};
// ${AOs::Philo::SM::initial}
//${AOs::Philo::SM::initial}
static bool registered = false; // starts off with 0, per C-standard
(void)e; // suppress the compiler warning about unused parameter
if (!registered) {
@ -152,26 +154,26 @@ QP::QMState const Philo::thinking_s = {
Q_ACTION_CAST(&Philo::thinking_x),
Q_ACTION_CAST(0) // no intitial tran.
};
// ${AOs::Philo::SM::thinking}
//${AOs::Philo::SM::thinking}
QP::QState Philo::thinking_e(Philo * const me) {
me->m_timeEvt.armX(think_time(), 0U);
return QM_ENTRY(&thinking_s);
}
// ${AOs::Philo::SM::thinking}
//${AOs::Philo::SM::thinking}
QP::QState Philo::thinking_x(Philo * const me) {
(void)me->m_timeEvt.disarm();
return QM_EXIT(&thinking_s);
}
// ${AOs::Philo::SM::thinking}
//${AOs::Philo::SM::thinking}
QP::QState Philo::thinking(Philo * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${AOs::Philo::SM::thinking::TIMEOUT}
//${AOs::Philo::SM::thinking::TIMEOUT}
case TIMEOUT_SIG: {
static struct {
QP::QMState const *target;
QP::QActionHandler act[3];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&hungry_s, // target state
{
Q_ACTION_CAST(&thinking_x), // exit
@ -182,7 +184,7 @@ QP::QState Philo::thinking(Philo * const me, QP::QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
// ${AOs::Philo::SM::thinking::EAT, DONE}
//${AOs::Philo::SM::thinking::EAT, DONE}
case EAT_SIG: // intentionally fall through
case DONE_SIG: {
/* EAT or DONE must be for other Philos than this one */
@ -190,7 +192,7 @@ QP::QState Philo::thinking(Philo * const me, QP::QEvt const * const e) {
status_ = QM_HANDLED();
break;
}
// ${AOs::Philo::SM::thinking::TEST}
//${AOs::Philo::SM::thinking::TEST}
case TEST_SIG: {
status_ = QM_HANDLED();
break;
@ -211,25 +213,25 @@ QP::QMState const Philo::hungry_s = {
Q_ACTION_CAST(0), // no exit action
Q_ACTION_CAST(0) // no intitial tran.
};
// ${AOs::Philo::SM::hungry}
//${AOs::Philo::SM::hungry}
QP::QState Philo::hungry_e(Philo * const me) {
TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG);
pe->philoNum = PHILO_ID(me);
AO_Table->POST(pe, me);
return QM_ENTRY(&hungry_s);
}
// ${AOs::Philo::SM::hungry}
//${AOs::Philo::SM::hungry}
QP::QState Philo::hungry(Philo * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${AOs::Philo::SM::hungry::EAT}
//${AOs::Philo::SM::hungry::EAT}
case EAT_SIG: {
// ${AOs::Philo::SM::hungry::EAT::[Q_EVT_CAST(TableEvt)->philoNum=~}
//${AOs::Philo::SM::hungry::EAT::[Q_EVT_CAST(TableEvt)->philoNum=~}
if (Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me)) {
static struct {
QP::QMState const *target;
QP::QActionHandler act[2];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&eating_s, // target state
{
Q_ACTION_CAST(&eating_e), // entry
@ -243,7 +245,7 @@ QP::QState Philo::hungry(Philo * const me, QP::QEvt const * const e) {
}
break;
}
// ${AOs::Philo::SM::hungry::DONE}
//${AOs::Philo::SM::hungry::DONE}
case DONE_SIG: {
/* DONE must be for other Philos than this one */
Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me));
@ -265,12 +267,12 @@ QP::QMState const Philo::eating_s = {
Q_ACTION_CAST(&Philo::eating_x),
Q_ACTION_CAST(0) // no intitial tran.
};
// ${AOs::Philo::SM::eating}
//${AOs::Philo::SM::eating}
QP::QState Philo::eating_e(Philo * const me) {
me->m_timeEvt.armX(eat_time(), 0U);
return QM_ENTRY(&eating_s);
}
// ${AOs::Philo::SM::eating}
//${AOs::Philo::SM::eating}
QP::QState Philo::eating_x(Philo * const me) {
TableEvt *pe = Q_NEW(TableEvt, DONE_SIG);
pe->philoNum = PHILO_ID(me);
@ -278,16 +280,16 @@ QP::QState Philo::eating_x(Philo * const me) {
(void)me->m_timeEvt.disarm();
return QM_EXIT(&eating_s);
}
// ${AOs::Philo::SM::eating}
//${AOs::Philo::SM::eating}
QP::QState Philo::eating(Philo * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${AOs::Philo::SM::eating::TIMEOUT}
//${AOs::Philo::SM::eating::TIMEOUT}
case TIMEOUT_SIG: {
static struct {
QP::QMState const *target;
QP::QActionHandler act[3];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&thinking_s, // target state
{
Q_ACTION_CAST(&eating_x), // exit
@ -298,7 +300,7 @@ QP::QState Philo::eating(Philo * const me, QP::QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
// ${AOs::Philo::SM::eating::EAT, DONE}
//${AOs::Philo::SM::eating::EAT, DONE}
case EAT_SIG: // intentionally fall through
case DONE_SIG: {
/* EAT or DONE must be for other Philos than this one */
@ -314,4 +316,4 @@ QP::QState Philo::eating(Philo * const me, QP::QEvt const * const e) {
return status_;
}
} // namespace DPP
} // namespace DPP//$enddef${AOs::Philo} #######################################################

View File

@ -1,22 +1,23 @@
//****************************************************************************
// Model: dpp_qmsm.qm
// File: ./table.cpp
//$file${.::table.cpp} #######################################################
//
// This code has been generated by QM tool (see state-machine.com/qm).
// Model: dpp_qmsm.qm
// File: C:/qp_lab/qpcpp/examples/performance/dpp_efm32-slstk3401a/table.cpp
//
// This code has been generated by QM tool (https://state-machine.com/qm).
// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
//
// This code is covered by the following commercial QP license:
// License # : QPCPP-EVAL-170201
// This code is covered by the following QP license:
// License # : QPCPP-EVAL-171231
// Issued to : Company/individual evaluating the QP/C++ framework
// Framework(s): qpcpp
// Support ends: 2017-02-28
// Support ends: 2017-12-31
// Product(s) :
// This license is available only for evaluation purposes and
// the generated code is still licensed under the terms of GPL.
// Please submit request for extension of the evaluaion period at:
// https://state-machine.com/licensing/index.html#RequestForm
//****************************************************************************
//${.::table.cpp} ............................................................
// https://state-machine.com/licensing/#RequestForm
//
//$endhead${.::table.cpp} ####################################################
#include "qpcpp.h"
#include "dpp.h"
#include "bsp.h"
@ -24,13 +25,9 @@
Q_DEFINE_THIS_FILE
// Active object class -------------------------------------------------------
//$declare${AOs::Table} ######################################################
namespace DPP {
#if ((QP_VERSION < 580) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8)))
#error qpcpp version 5.8.0 or higher required
#endif
//${AOs::Table} ..............................................................
class Table : public QP::QMActive {
private:
@ -53,7 +50,7 @@ protected:
static QP::QMState const paused_s;
};
} // namespace DPP
} // namespace DPP//$enddecl${AOs::Table} ######################################################
namespace DPP {
@ -83,6 +80,11 @@ QP::QActive * const AO_Table = &l_table; // "opaque" AO pointer
} // namespace DPP
//............................................................................
//$define${AOs::Table} #######################################################
// Check for the minimum required QP version
#if ((QP_VERSION < 601) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8)))
#error qpcpp version 6.0.1 or higher required
#endif
namespace DPP {
//${AOs::Table} ..............................................................
@ -101,14 +103,14 @@ QP::QState Table::initial(Table * const me, QP::QEvt const * const e) {
static struct {
QP::QMState const *target;
QP::QActionHandler act[2];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&serving_s, // target state
{
Q_ACTION_CAST(&serving_e), // entry
Q_ACTION_CAST(0) // zero terminator
}
};
// ${AOs::Table::SM::initial}
//${AOs::Table::SM::initial}
(void)e; // suppress the compiler warning about unused parameter
QS_OBJ_DICTIONARY(&l_table);
@ -146,16 +148,16 @@ QP::QMState const Table::active_s = {
Q_ACTION_CAST(0), // no exit action
Q_ACTION_CAST(0) // no intitial tran.
};
// ${AOs::Table::SM::active}
//${AOs::Table::SM::active}
QP::QState Table::active(Table * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${AOs::Table::SM::active::TEST}
//${AOs::Table::SM::active::TEST}
case TEST_SIG: {
status_ = QM_HANDLED();
break;
}
// ${AOs::Table::SM::active::EAT}
//${AOs::Table::SM::active::EAT}
case EAT_SIG: {
Q_ERROR();
status_ = QM_HANDLED();
@ -177,7 +179,7 @@ QP::QMState const Table::serving_s = {
Q_ACTION_CAST(0), // no exit action
Q_ACTION_CAST(0) // no intitial tran.
};
// ${AOs::Table::SM::active::serving}
//${AOs::Table::SM::active::serving}
QP::QState Table::serving_e(Table * const me) {
for (uint8_t n = 0U; n < N_PHILO; ++n) { // give permissions to eat...
if (me->m_isHungry[n]
@ -195,11 +197,11 @@ QP::QState Table::serving_e(Table * const me) {
}
return QM_ENTRY(&serving_s);
}
// ${AOs::Table::SM::active::serving}
//${AOs::Table::SM::active::serving}
QP::QState Table::serving(Table * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${AOs::Table::SM::active::serving::HUNGRY}
//${AOs::Table::SM::active::serving::HUNGRY}
case HUNGRY_SIG: {
uint8_t n = Q_EVT_CAST(TableEvt)->philoNum;
// phil ID must be in range and he must be not hungry
@ -207,7 +209,7 @@ QP::QState Table::serving(Table * const me, QP::QEvt const * const e) {
BSP::displayPhilStat(n, HUNGRY);
uint8_t m = LEFT(n);
// ${AOs::Table::SM::active::serving::HUNGRY::[bothfree]}
//${AOs::Table::SM::active::serving::HUNGRY::[bothfree]}
if ((me->m_fork[m] == FREE) && (me->m_fork[n] == FREE)) {
me->m_fork[m] = USED;
me->m_fork[n] = USED;
@ -217,14 +219,14 @@ QP::QState Table::serving(Table * const me, QP::QEvt const * const e) {
BSP::displayPhilStat(n, EATING);
status_ = QM_HANDLED();
}
// ${AOs::Table::SM::active::serving::HUNGRY::[else]}
//${AOs::Table::SM::active::serving::HUNGRY::[else]}
else {
me->m_isHungry[n] = true;
status_ = QM_HANDLED();
}
break;
}
// ${AOs::Table::SM::active::serving::DONE}
//${AOs::Table::SM::active::serving::DONE}
case DONE_SIG: {
uint8_t n = Q_EVT_CAST(TableEvt)->philoNum;
// phil ID must be in range and he must be not hungry
@ -262,18 +264,18 @@ QP::QState Table::serving(Table * const me, QP::QEvt const * const e) {
status_ = QM_HANDLED();
break;
}
// ${AOs::Table::SM::active::serving::EAT}
//${AOs::Table::SM::active::serving::EAT}
case EAT_SIG: {
Q_ERROR();
status_ = QM_HANDLED();
break;
}
// ${AOs::Table::SM::active::serving::PAUSE}
//${AOs::Table::SM::active::serving::PAUSE}
case PAUSE_SIG: {
static struct {
QP::QMState const *target;
QP::QActionHandler act[2];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&paused_s, // target state
{
Q_ACTION_CAST(&paused_e), // entry
@ -298,28 +300,28 @@ QP::QMState const Table::paused_s = {
Q_ACTION_CAST(&Table::paused_x),
Q_ACTION_CAST(0) // no intitial tran.
};
// ${AOs::Table::SM::active::paused}
//${AOs::Table::SM::active::paused}
QP::QState Table::paused_e(Table * const me) {
BSP::displayPaused(1U);
(void)me; // avoid compiler warning in case 'me' is not used
return QM_ENTRY(&paused_s);
}
// ${AOs::Table::SM::active::paused}
//${AOs::Table::SM::active::paused}
QP::QState Table::paused_x(Table * const me) {
BSP::displayPaused(0U);
(void)me; // avoid compiler warning in case 'me' is not used
return QM_EXIT(&paused_s);
}
// ${AOs::Table::SM::active::paused}
//${AOs::Table::SM::active::paused}
QP::QState Table::paused(Table * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${AOs::Table::SM::active::paused::SERVE}
//${AOs::Table::SM::active::paused::SERVE}
case SERVE_SIG: {
static struct {
QP::QMState const *target;
QP::QActionHandler act[3];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&serving_s, // target state
{
Q_ACTION_CAST(&paused_x), // exit
@ -330,7 +332,7 @@ QP::QState Table::paused(Table * const me, QP::QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
// ${AOs::Table::SM::active::paused::HUNGRY}
//${AOs::Table::SM::active::paused::HUNGRY}
case HUNGRY_SIG: {
uint8_t n = Q_EVT_CAST(TableEvt)->philoNum;
// philo ID must be in range and he must be not hungry
@ -340,7 +342,7 @@ QP::QState Table::paused(Table * const me, QP::QEvt const * const e) {
status_ = QM_HANDLED();
break;
}
// ${AOs::Table::SM::active::paused::DONE}
//${AOs::Table::SM::active::paused::DONE}
case DONE_SIG: {
uint8_t n = Q_EVT_CAST(TableEvt)->philoNum;
// phil ID must be in range and he must be not hungry
@ -364,4 +366,4 @@ QP::QState Table::paused(Table * const me, QP::QEvt const * const e) {
return status_;
}
} // namespace DPP
} // namespace DPP//$enddef${AOs::Table} #######################################################

View File

@ -1,8 +1,9 @@
//****************************************************************************
// Model: qhsmtst.qm
// File: ./qhsmtst.cpp
//$file${.::qhsmtst.cpp} #####################################################
//
// This code has been generated by QM tool (see state-machine.com/qm).
// Model: qhsmtst.qm
// File: C:/qp_lab/qpcpp/examples/posix/qhsmtst/qhsmtst.cpp
//
// This code has been generated by QM tool (https://state-machine.com/qm).
// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
//
// This program is open source software: you can redistribute it and/or
@ -13,18 +14,14 @@
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//****************************************************************************
//${.::qhsmtst.cpp} ..........................................................
//
//$endhead${.::qhsmtst.cpp} ##################################################
#include "qpcpp.h"
#include "qhsmtst.h"
namespace QHSMTST {
#if ((QP_VERSION < 580) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8)))
#error qpcpp version 5.8.0 or higher required
#endif
//$declare${HSMs::QHsmTst} ###################################################
//${HSMs::QHsmTst} ...........................................................
class QHsmTst : public QP::QHsm {
private:
@ -44,18 +41,23 @@ protected:
static QP::QState s21(QHsmTst * const me, QP::QEvt const * const e);
static QP::QState s211(QHsmTst * const me, QP::QEvt const * const e);
};
//$enddecl${HSMs::QHsmTst} ###################################################
static QHsmTst l_hsmtst; // the only instance of the QHsmTst class
// global-scope definitions -----------------------------------------
QP::QHsm * const the_hsm = &l_hsmtst; // the opaque pointer
//$define${HSMs::QHsmTst} ####################################################
// Check for the minimum required QP version
#if ((QP_VERSION < 601) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8)))
#error qpcpp version 6.0.1 or higher required
#endif
//${HSMs::QHsmTst} ...........................................................
//${HSMs::QHsmTst::SM} .......................................................
QP::QState QHsmTst::initial(QHsmTst * const me, QP::QEvt const * const e) {
// ${HSMs::QHsmTst::SM::initial}
//${HSMs::QHsmTst::SM::initial}
(void)e; // avoid compiler warning
me->m_foo = 0U;
BSP_display("top-INIT;");
@ -65,27 +67,27 @@ QP::QState QHsmTst::initial(QHsmTst * const me, QP::QEvt const * const e) {
QP::QState QHsmTst::s(QHsmTst * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${HSMs::QHsmTst::SM::s}
//${HSMs::QHsmTst::SM::s}
case Q_ENTRY_SIG: {
BSP_display("s-ENTRY;");
status_ = Q_HANDLED();
break;
}
// ${HSMs::QHsmTst::SM::s}
//${HSMs::QHsmTst::SM::s}
case Q_EXIT_SIG: {
BSP_display("s-EXIT;");
status_ = Q_HANDLED();
break;
}
// ${HSMs::QHsmTst::SM::s::initial}
//${HSMs::QHsmTst::SM::s::initial}
case Q_INIT_SIG: {
BSP_display("s-INIT;");
status_ = Q_TRAN(&s11);
break;
}
// ${HSMs::QHsmTst::SM::s::I}
//${HSMs::QHsmTst::SM::s::I}
case I_SIG: {
// ${HSMs::QHsmTst::SM::s::I::[me->m_foo]}
//${HSMs::QHsmTst::SM::s::I::[me->m_foo]}
if (me->m_foo) {
me->m_foo = 0U;
BSP_display("s-I;");
@ -96,13 +98,13 @@ QP::QState QHsmTst::s(QHsmTst * const me, QP::QEvt const * const e) {
}
break;
}
// ${HSMs::QHsmTst::SM::s::E}
//${HSMs::QHsmTst::SM::s::E}
case E_SIG: {
BSP_display("s-E;");
status_ = Q_TRAN(&s11);
break;
}
// ${HSMs::QHsmTst::SM::s::TERMINATE}
//${HSMs::QHsmTst::SM::s::TERMINATE}
case TERMINATE_SIG: {
BSP_terminate(0);
status_ = Q_HANDLED();
@ -119,33 +121,33 @@ QP::QState QHsmTst::s(QHsmTst * const me, QP::QEvt const * const e) {
QP::QState QHsmTst::s1(QHsmTst * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${HSMs::QHsmTst::SM::s::s1}
//${HSMs::QHsmTst::SM::s::s1}
case Q_ENTRY_SIG: {
BSP_display("s1-ENTRY;");
status_ = Q_HANDLED();
break;
}
// ${HSMs::QHsmTst::SM::s::s1}
//${HSMs::QHsmTst::SM::s::s1}
case Q_EXIT_SIG: {
BSP_display("s1-EXIT;");
status_ = Q_HANDLED();
break;
}
// ${HSMs::QHsmTst::SM::s::s1::initial}
//${HSMs::QHsmTst::SM::s::s1::initial}
case Q_INIT_SIG: {
BSP_display("s1-INIT;");
status_ = Q_TRAN(&s11);
break;
}
// ${HSMs::QHsmTst::SM::s::s1::I}
//${HSMs::QHsmTst::SM::s::s1::I}
case I_SIG: {
BSP_display("s1-I;");
status_ = Q_HANDLED();
break;
}
// ${HSMs::QHsmTst::SM::s::s1::D}
//${HSMs::QHsmTst::SM::s::s1::D}
case D_SIG: {
// ${HSMs::QHsmTst::SM::s::s1::D::[!me->m_foo]}
//${HSMs::QHsmTst::SM::s::s1::D::[!me->m_foo]}
if (!me->m_foo) {
me->m_foo = true;
BSP_display("s1-D;");
@ -156,25 +158,25 @@ QP::QState QHsmTst::s1(QHsmTst * const me, QP::QEvt const * const e) {
}
break;
}
// ${HSMs::QHsmTst::SM::s::s1::A}
//${HSMs::QHsmTst::SM::s::s1::A}
case A_SIG: {
BSP_display("s1-A;");
status_ = Q_TRAN(&s1);
break;
}
// ${HSMs::QHsmTst::SM::s::s1::B}
//${HSMs::QHsmTst::SM::s::s1::B}
case B_SIG: {
BSP_display("s1-B;");
status_ = Q_TRAN(&s11);
break;
}
// ${HSMs::QHsmTst::SM::s::s1::F}
//${HSMs::QHsmTst::SM::s::s1::F}
case F_SIG: {
BSP_display("s1-F;");
status_ = Q_TRAN(&s211);
break;
}
// ${HSMs::QHsmTst::SM::s::s1::C}
//${HSMs::QHsmTst::SM::s::s1::C}
case C_SIG: {
BSP_display("s1-C;");
status_ = Q_TRAN(&s2);
@ -191,27 +193,27 @@ QP::QState QHsmTst::s1(QHsmTst * const me, QP::QEvt const * const e) {
QP::QState QHsmTst::s11(QHsmTst * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${HSMs::QHsmTst::SM::s::s1::s11}
//${HSMs::QHsmTst::SM::s::s1::s11}
case Q_ENTRY_SIG: {
BSP_display("s11-ENTRY;");
status_ = Q_HANDLED();
break;
}
// ${HSMs::QHsmTst::SM::s::s1::s11}
//${HSMs::QHsmTst::SM::s::s1::s11}
case Q_EXIT_SIG: {
BSP_display("s11-EXIT;");
status_ = Q_HANDLED();
break;
}
// ${HSMs::QHsmTst::SM::s::s1::s11::H}
//${HSMs::QHsmTst::SM::s::s1::s11::H}
case H_SIG: {
BSP_display("s11-H;");
status_ = Q_TRAN(&s);
break;
}
// ${HSMs::QHsmTst::SM::s::s1::s11::D}
//${HSMs::QHsmTst::SM::s::s1::s11::D}
case D_SIG: {
// ${HSMs::QHsmTst::SM::s::s1::s11::D::[me->m_foo]}
//${HSMs::QHsmTst::SM::s::s1::s11::D::[me->m_foo]}
if (me->m_foo) {
me->m_foo = false;
BSP_display("s11-D;");
@ -222,7 +224,7 @@ QP::QState QHsmTst::s11(QHsmTst * const me, QP::QEvt const * const e) {
}
break;
}
// ${HSMs::QHsmTst::SM::s::s1::s11::G}
//${HSMs::QHsmTst::SM::s::s1::s11::G}
case G_SIG: {
BSP_display("s11-G;");
status_ = Q_TRAN(&s211);
@ -239,27 +241,27 @@ QP::QState QHsmTst::s11(QHsmTst * const me, QP::QEvt const * const e) {
QP::QState QHsmTst::s2(QHsmTst * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${HSMs::QHsmTst::SM::s::s2}
//${HSMs::QHsmTst::SM::s::s2}
case Q_ENTRY_SIG: {
BSP_display("s2-ENTRY;");
status_ = Q_HANDLED();
break;
}
// ${HSMs::QHsmTst::SM::s::s2}
//${HSMs::QHsmTst::SM::s::s2}
case Q_EXIT_SIG: {
BSP_display("s2-EXIT;");
status_ = Q_HANDLED();
break;
}
// ${HSMs::QHsmTst::SM::s::s2::initial}
//${HSMs::QHsmTst::SM::s::s2::initial}
case Q_INIT_SIG: {
BSP_display("s2-INIT;");
status_ = Q_TRAN(&s211);
break;
}
// ${HSMs::QHsmTst::SM::s::s2::I}
//${HSMs::QHsmTst::SM::s::s2::I}
case I_SIG: {
// ${HSMs::QHsmTst::SM::s::s2::I::[!me->m_foo]}
//${HSMs::QHsmTst::SM::s::s2::I::[!me->m_foo]}
if (!me->m_foo) {
me->m_foo = true;
BSP_display("s2-I;");
@ -270,13 +272,13 @@ QP::QState QHsmTst::s2(QHsmTst * const me, QP::QEvt const * const e) {
}
break;
}
// ${HSMs::QHsmTst::SM::s::s2::F}
//${HSMs::QHsmTst::SM::s::s2::F}
case F_SIG: {
BSP_display("s2-F;");
status_ = Q_TRAN(&s11);
break;
}
// ${HSMs::QHsmTst::SM::s::s2::C}
//${HSMs::QHsmTst::SM::s::s2::C}
case C_SIG: {
BSP_display("s2-C;");
status_ = Q_TRAN(&s1);
@ -293,37 +295,37 @@ QP::QState QHsmTst::s2(QHsmTst * const me, QP::QEvt const * const e) {
QP::QState QHsmTst::s21(QHsmTst * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${HSMs::QHsmTst::SM::s::s2::s21}
//${HSMs::QHsmTst::SM::s::s2::s21}
case Q_ENTRY_SIG: {
BSP_display("s21-ENTRY;");
status_ = Q_HANDLED();
break;
}
// ${HSMs::QHsmTst::SM::s::s2::s21}
//${HSMs::QHsmTst::SM::s::s2::s21}
case Q_EXIT_SIG: {
BSP_display("s21-EXIT;");
status_ = Q_HANDLED();
break;
}
// ${HSMs::QHsmTst::SM::s::s2::s21::initial}
//${HSMs::QHsmTst::SM::s::s2::s21::initial}
case Q_INIT_SIG: {
BSP_display("s21-INIT;");
status_ = Q_TRAN(&s211);
break;
}
// ${HSMs::QHsmTst::SM::s::s2::s21::G}
//${HSMs::QHsmTst::SM::s::s2::s21::G}
case G_SIG: {
BSP_display("s21-G;");
status_ = Q_TRAN(&s1);
break;
}
// ${HSMs::QHsmTst::SM::s::s2::s21::A}
//${HSMs::QHsmTst::SM::s::s2::s21::A}
case A_SIG: {
BSP_display("s21-A;");
status_ = Q_TRAN(&s21);
break;
}
// ${HSMs::QHsmTst::SM::s::s2::s21::B}
//${HSMs::QHsmTst::SM::s::s2::s21::B}
case B_SIG: {
BSP_display("s21-B;");
status_ = Q_TRAN(&s211);
@ -340,25 +342,25 @@ QP::QState QHsmTst::s21(QHsmTst * const me, QP::QEvt const * const e) {
QP::QState QHsmTst::s211(QHsmTst * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${HSMs::QHsmTst::SM::s::s2::s21::s211}
//${HSMs::QHsmTst::SM::s::s2::s21::s211}
case Q_ENTRY_SIG: {
BSP_display("s211-ENTRY;");
status_ = Q_HANDLED();
break;
}
// ${HSMs::QHsmTst::SM::s::s2::s21::s211}
//${HSMs::QHsmTst::SM::s::s2::s21::s211}
case Q_EXIT_SIG: {
BSP_display("s211-EXIT;");
status_ = Q_HANDLED();
break;
}
// ${HSMs::QHsmTst::SM::s::s2::s21::s211::H}
//${HSMs::QHsmTst::SM::s::s2::s21::s211::H}
case H_SIG: {
BSP_display("s211-H;");
status_ = Q_TRAN(&s);
break;
}
// ${HSMs::QHsmTst::SM::s::s2::s21::s211::D}
//${HSMs::QHsmTst::SM::s::s2::s21::s211::D}
case D_SIG: {
BSP_display("s211-D;");
status_ = Q_TRAN(&s21);
@ -371,6 +373,6 @@ QP::QState QHsmTst::s211(QHsmTst * const me, QP::QEvt const * const e) {
}
return status_;
}
//$enddef${HSMs::QHsmTst} ####################################################
} // namespace QHSMTST
} // namespace QHSMTST

View File

@ -1,8 +1,9 @@
//****************************************************************************
// Model: qhsmtst.qm
// File: ./qhsmtst.h
//$file${.::qhsmtst.h} #######################################################
//
// This code has been generated by QM tool (see state-machine.com/qm).
// Model: qhsmtst.qm
// File: C:/qp_lab/qpcpp/examples/posix/qhsmtst/qhsmtst.h
//
// This code has been generated by QM tool (https://state-machine.com/qm).
// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
//
// This program is open source software: you can redistribute it and/or
@ -13,8 +14,8 @@
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//****************************************************************************
//${.::qhsmtst.h} ............................................................
//
//$endhead${.::qhsmtst.h} ####################################################
#ifndef qhsmtst_h
#define qhsmtst_h
@ -43,4 +44,4 @@ void BSP_terminate(int16_t const result);
} // namespace QHSMTST
#endif // qhsmtst_h
#endif // qhsmtst_h

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<model version="4.0.0" links="0">
<model version="4.1.0" links="0">
<documentation>QHsmTst is a contrived state machine from Chapter 2 of the PSiCC2 book for testing all possible transition topologies with up to 4-levels of state nesting.</documentation>
<framework name="qpcpp"/>
<package name="HSMs" stereotype="0x02">

View File

@ -1,32 +1,29 @@
//****************************************************************************
// Model: qmsmtst.qm
// File: ./qmsmtst.cpp
//$file${.::qmsmtst.cpp} #####################################################
//
// This code has been generated by QM tool (see state-machine.com/qm).
// Model: qmsmtst.qm
// File: C:/qp_lab/qpcpp/examples/posix/qmsmtst/qmsmtst.cpp
//
// This code has been generated by QM tool (https://state-machine.com/qm).
// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
//
// This code is covered by the following commercial QP license:
// License # : QPCPP-EVAL-170201
// This code is covered by the following QP license:
// License # : QPCPP-EVAL-171231
// Issued to : Company/individual evaluating the QP/C++ framework
// Framework(s): qpcpp
// Support ends: 2017-02-28
// Support ends: 2017-12-31
// Product(s) :
// This license is available only for evaluation purposes and
// the generated code is still licensed under the terms of GPL.
// Please submit request for extension of the evaluaion period at:
// https://state-machine.com/licensing/index.html#RequestForm
//****************************************************************************
//${.::qmsmtst.cpp} ..........................................................
// https://state-machine.com/licensing/#RequestForm
//
//$endhead${.::qmsmtst.cpp} ##################################################
#include "qpcpp.h"
#include "qmsmtst.h"
namespace QMSMTST {
#if ((QP_VERSION < 580) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8)))
#error qpcpp version 5.8.0 or higher required
#endif
//$declare${SMs::QMsmTst} ####################################################
//${SMs::QMsmTst} ............................................................
class QMsmTst : public QP::QMsm {
private:
@ -68,13 +65,18 @@ protected:
static QP::QState s211_x(QMsmTst * const me);
static QP::QMState const s211_s;
};
//$enddecl${SMs::QMsmTst} ####################################################
static QMsmTst l_msmtst; // the only instance of the QMsmTst class
// global-scope definitions -----------------------------------------
QP::QMsm * const the_msm = &l_msmtst; // the opaque pointer
//$define${SMs::QMsmTst} #####################################################
// Check for the minimum required QP version
#if ((QP_VERSION < 601) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8)))
#error qpcpp version 6.0.1 or higher required
#endif
//${SMs::QMsmTst} ............................................................
//${SMs::QMsmTst::SM} ........................................................
@ -82,7 +84,7 @@ QP::QState QMsmTst::initial(QMsmTst * const me, QP::QEvt const * const e) {
static struct {
QP::QMState const *target;
QP::QActionHandler act[4];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s2_s, // target state
{
Q_ACTION_CAST(&s_e), // entry
@ -91,7 +93,7 @@ QP::QState QMsmTst::initial(QMsmTst * const me, QP::QEvt const * const e) {
Q_ACTION_CAST(0) // zero terminator
}
};
// ${SMs::QMsmTst::SM::initial}
//${SMs::QMsmTst::SM::initial}
(void)e; // avoid compiler warning
me->m_foo = 0U;
BSP_display("top-INIT;");
@ -105,24 +107,24 @@ QP::QMState const QMsmTst::s_s = {
Q_ACTION_CAST(&QMsmTst::s_x),
Q_ACTION_CAST(&QMsmTst::s_i)
};
// ${SMs::QMsmTst::SM::s}
//${SMs::QMsmTst::SM::s}
QP::QState QMsmTst::s_e(QMsmTst * const me) {
BSP_display("s-ENTRY;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_ENTRY(&s_s);
}
// ${SMs::QMsmTst::SM::s}
//${SMs::QMsmTst::SM::s}
QP::QState QMsmTst::s_x(QMsmTst * const me) {
BSP_display("s-EXIT;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_EXIT(&s_s);
}
// ${SMs::QMsmTst::SM::s::initial}
//${SMs::QMsmTst::SM::s::initial}
QP::QState QMsmTst::s_i(QMsmTst * const me) {
static struct {
QP::QMState const *target;
QP::QActionHandler act[3];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s11_s, // target state
{
Q_ACTION_CAST(&s1_e), // entry
@ -130,17 +132,17 @@ QP::QState QMsmTst::s_i(QMsmTst * const me) {
Q_ACTION_CAST(0) // zero terminator
}
};
// ${SMs::QMsmTst::SM::s::initial}
//${SMs::QMsmTst::SM::s::initial}
BSP_display("s-INIT;");
return QM_TRAN_INIT(&tatbl_);
}
// ${SMs::QMsmTst::SM::s}
//${SMs::QMsmTst::SM::s}
QP::QState QMsmTst::s(QMsmTst * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${SMs::QMsmTst::SM::s::I}
//${SMs::QMsmTst::SM::s::I}
case I_SIG: {
// ${SMs::QMsmTst::SM::s::I::[me->m_foo]}
//${SMs::QMsmTst::SM::s::I::[me->m_foo]}
if (me->m_foo) {
me->m_foo = 0U;
BSP_display("s-I;");
@ -151,12 +153,12 @@ QP::QState QMsmTst::s(QMsmTst * const me, QP::QEvt const * const e) {
}
break;
}
// ${SMs::QMsmTst::SM::s::E}
//${SMs::QMsmTst::SM::s::E}
case E_SIG: {
static struct {
QP::QMState const *target;
QP::QActionHandler act[3];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s11_s, // target state
{
Q_ACTION_CAST(&s1_e), // entry
@ -168,7 +170,7 @@ QP::QState QMsmTst::s(QMsmTst * const me, QP::QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
// ${SMs::QMsmTst::SM::s::TERMINATE}
//${SMs::QMsmTst::SM::s::TERMINATE}
case TERMINATE_SIG: {
BSP_terminate(0);
status_ = QM_HANDLED();
@ -190,52 +192,52 @@ QP::QMState const QMsmTst::s1_s = {
Q_ACTION_CAST(&QMsmTst::s1_x),
Q_ACTION_CAST(&QMsmTst::s1_i)
};
// ${SMs::QMsmTst::SM::s::s1}
//${SMs::QMsmTst::SM::s::s1}
QP::QState QMsmTst::s1_e(QMsmTst * const me) {
BSP_display("s1-ENTRY;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_ENTRY(&s1_s);
}
// ${SMs::QMsmTst::SM::s::s1}
//${SMs::QMsmTst::SM::s::s1}
QP::QState QMsmTst::s1_x(QMsmTst * const me) {
BSP_display("s1-EXIT;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_EXIT(&s1_s);
}
// ${SMs::QMsmTst::SM::s::s1::initial}
//${SMs::QMsmTst::SM::s::s1::initial}
QP::QState QMsmTst::s1_i(QMsmTst * const me) {
static struct {
QP::QMState const *target;
QP::QActionHandler act[2];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s11_s, // target state
{
Q_ACTION_CAST(&s11_e), // entry
Q_ACTION_CAST(0) // zero terminator
}
};
// ${SMs::QMsmTst::SM::s::s1::initial}
//${SMs::QMsmTst::SM::s::s1::initial}
BSP_display("s1-INIT;");
return QM_TRAN_INIT(&tatbl_);
}
// ${SMs::QMsmTst::SM::s::s1}
//${SMs::QMsmTst::SM::s::s1}
QP::QState QMsmTst::s1(QMsmTst * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${SMs::QMsmTst::SM::s::s1::I}
//${SMs::QMsmTst::SM::s::s1::I}
case I_SIG: {
BSP_display("s1-I;");
status_ = QM_HANDLED();
break;
}
// ${SMs::QMsmTst::SM::s::s1::D}
//${SMs::QMsmTst::SM::s::s1::D}
case D_SIG: {
// ${SMs::QMsmTst::SM::s::s1::D::[!me->m_foo]}
//${SMs::QMsmTst::SM::s::s1::D::[!me->m_foo]}
if (!me->m_foo) {
static struct {
QP::QMState const *target;
QP::QActionHandler act[3];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s_s, // target state
{
Q_ACTION_CAST(&s1_x), // exit
@ -252,12 +254,12 @@ QP::QState QMsmTst::s1(QMsmTst * const me, QP::QEvt const * const e) {
}
break;
}
// ${SMs::QMsmTst::SM::s::s1::A}
//${SMs::QMsmTst::SM::s::s1::A}
case A_SIG: {
static struct {
QP::QMState const *target;
QP::QActionHandler act[4];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s1_s, // target state
{
Q_ACTION_CAST(&s1_x), // exit
@ -270,12 +272,12 @@ QP::QState QMsmTst::s1(QMsmTst * const me, QP::QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
// ${SMs::QMsmTst::SM::s::s1::B}
//${SMs::QMsmTst::SM::s::s1::B}
case B_SIG: {
static struct {
QP::QMState const *target;
QP::QActionHandler act[2];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s11_s, // target state
{
Q_ACTION_CAST(&s11_e), // entry
@ -286,12 +288,12 @@ QP::QState QMsmTst::s1(QMsmTst * const me, QP::QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
// ${SMs::QMsmTst::SM::s::s1::F}
//${SMs::QMsmTst::SM::s::s1::F}
case F_SIG: {
static struct {
QP::QMState const *target;
QP::QActionHandler act[5];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s211_s, // target state
{
Q_ACTION_CAST(&s1_x), // exit
@ -305,12 +307,12 @@ QP::QState QMsmTst::s1(QMsmTst * const me, QP::QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
// ${SMs::QMsmTst::SM::s::s1::C}
//${SMs::QMsmTst::SM::s::s1::C}
case C_SIG: {
static struct {
QP::QMState const *target;
QP::QActionHandler act[4];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s2_s, // target state
{
Q_ACTION_CAST(&s1_x), // exit
@ -338,28 +340,28 @@ QP::QMState const QMsmTst::s11_s = {
Q_ACTION_CAST(&QMsmTst::s11_x),
Q_ACTION_CAST(0) // no intitial tran.
};
// ${SMs::QMsmTst::SM::s::s1::s11}
//${SMs::QMsmTst::SM::s::s1::s11}
QP::QState QMsmTst::s11_e(QMsmTst * const me) {
BSP_display("s11-ENTRY;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_ENTRY(&s11_s);
}
// ${SMs::QMsmTst::SM::s::s1::s11}
//${SMs::QMsmTst::SM::s::s1::s11}
QP::QState QMsmTst::s11_x(QMsmTst * const me) {
BSP_display("s11-EXIT;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_EXIT(&s11_s);
}
// ${SMs::QMsmTst::SM::s::s1::s11}
//${SMs::QMsmTst::SM::s::s1::s11}
QP::QState QMsmTst::s11(QMsmTst * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${SMs::QMsmTst::SM::s::s1::s11::H}
//${SMs::QMsmTst::SM::s::s1::s11::H}
case H_SIG: {
static struct {
QP::QMState const *target;
QP::QActionHandler act[4];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s_s, // target state
{
Q_ACTION_CAST(&s11_x), // exit
@ -372,14 +374,14 @@ QP::QState QMsmTst::s11(QMsmTst * const me, QP::QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
// ${SMs::QMsmTst::SM::s::s1::s11::D}
//${SMs::QMsmTst::SM::s::s1::s11::D}
case D_SIG: {
// ${SMs::QMsmTst::SM::s::s1::s11::D::[me->m_foo]}
//${SMs::QMsmTst::SM::s::s1::s11::D::[me->m_foo]}
if (me->m_foo) {
static struct {
QP::QMState const *target;
QP::QActionHandler act[3];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s1_s, // target state
{
Q_ACTION_CAST(&s11_x), // exit
@ -396,12 +398,12 @@ QP::QState QMsmTst::s11(QMsmTst * const me, QP::QEvt const * const e) {
}
break;
}
// ${SMs::QMsmTst::SM::s::s1::s11::G}
//${SMs::QMsmTst::SM::s::s1::s11::G}
case G_SIG: {
static struct {
QP::QMState const *target;
QP::QActionHandler act[6];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s211_s, // target state
{
Q_ACTION_CAST(&s11_x), // exit
@ -431,24 +433,24 @@ QP::QMState const QMsmTst::s2_s = {
Q_ACTION_CAST(&QMsmTst::s2_x),
Q_ACTION_CAST(&QMsmTst::s2_i)
};
// ${SMs::QMsmTst::SM::s::s2}
//${SMs::QMsmTst::SM::s::s2}
QP::QState QMsmTst::s2_e(QMsmTst * const me) {
BSP_display("s2-ENTRY;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_ENTRY(&s2_s);
}
// ${SMs::QMsmTst::SM::s::s2}
//${SMs::QMsmTst::SM::s::s2}
QP::QState QMsmTst::s2_x(QMsmTst * const me) {
BSP_display("s2-EXIT;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_EXIT(&s2_s);
}
// ${SMs::QMsmTst::SM::s::s2::initial}
//${SMs::QMsmTst::SM::s::s2::initial}
QP::QState QMsmTst::s2_i(QMsmTst * const me) {
static struct {
QP::QMState const *target;
QP::QActionHandler act[3];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s211_s, // target state
{
Q_ACTION_CAST(&s21_e), // entry
@ -456,17 +458,17 @@ QP::QState QMsmTst::s2_i(QMsmTst * const me) {
Q_ACTION_CAST(0) // zero terminator
}
};
// ${SMs::QMsmTst::SM::s::s2::initial}
//${SMs::QMsmTst::SM::s::s2::initial}
BSP_display("s2-INIT;");
return QM_TRAN_INIT(&tatbl_);
}
// ${SMs::QMsmTst::SM::s::s2}
//${SMs::QMsmTst::SM::s::s2}
QP::QState QMsmTst::s2(QMsmTst * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${SMs::QMsmTst::SM::s::s2::I}
//${SMs::QMsmTst::SM::s::s2::I}
case I_SIG: {
// ${SMs::QMsmTst::SM::s::s2::I::[!me->m_foo]}
//${SMs::QMsmTst::SM::s::s2::I::[!me->m_foo]}
if (!me->m_foo) {
me->m_foo = true;
BSP_display("s2-I;");
@ -477,12 +479,12 @@ QP::QState QMsmTst::s2(QMsmTst * const me, QP::QEvt const * const e) {
}
break;
}
// ${SMs::QMsmTst::SM::s::s2::F}
//${SMs::QMsmTst::SM::s::s2::F}
case F_SIG: {
static struct {
QP::QMState const *target;
QP::QActionHandler act[4];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s11_s, // target state
{
Q_ACTION_CAST(&s2_x), // exit
@ -495,12 +497,12 @@ QP::QState QMsmTst::s2(QMsmTst * const me, QP::QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
// ${SMs::QMsmTst::SM::s::s2::C}
//${SMs::QMsmTst::SM::s::s2::C}
case C_SIG: {
static struct {
QP::QMState const *target;
QP::QActionHandler act[4];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s1_s, // target state
{
Q_ACTION_CAST(&s2_x), // exit
@ -528,44 +530,44 @@ QP::QMState const QMsmTst::s21_s = {
Q_ACTION_CAST(&QMsmTst::s21_x),
Q_ACTION_CAST(&QMsmTst::s21_i)
};
// ${SMs::QMsmTst::SM::s::s2::s21}
//${SMs::QMsmTst::SM::s::s2::s21}
QP::QState QMsmTst::s21_e(QMsmTst * const me) {
BSP_display("s21-ENTRY;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_ENTRY(&s21_s);
}
// ${SMs::QMsmTst::SM::s::s2::s21}
//${SMs::QMsmTst::SM::s::s2::s21}
QP::QState QMsmTst::s21_x(QMsmTst * const me) {
BSP_display("s21-EXIT;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_EXIT(&s21_s);
}
// ${SMs::QMsmTst::SM::s::s2::s21::initial}
//${SMs::QMsmTst::SM::s::s2::s21::initial}
QP::QState QMsmTst::s21_i(QMsmTst * const me) {
static struct {
QP::QMState const *target;
QP::QActionHandler act[2];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s211_s, // target state
{
Q_ACTION_CAST(&s211_e), // entry
Q_ACTION_CAST(0) // zero terminator
}
};
// ${SMs::QMsmTst::SM::s::s2::s21::initial}
//${SMs::QMsmTst::SM::s::s2::s21::initial}
BSP_display("s21-INIT;");
return QM_TRAN_INIT(&tatbl_);
}
// ${SMs::QMsmTst::SM::s::s2::s21}
//${SMs::QMsmTst::SM::s::s2::s21}
QP::QState QMsmTst::s21(QMsmTst * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${SMs::QMsmTst::SM::s::s2::s21::G}
//${SMs::QMsmTst::SM::s::s2::s21::G}
case G_SIG: {
static struct {
QP::QMState const *target;
QP::QActionHandler act[5];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s1_s, // target state
{
Q_ACTION_CAST(&s21_x), // exit
@ -579,12 +581,12 @@ QP::QState QMsmTst::s21(QMsmTst * const me, QP::QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
// ${SMs::QMsmTst::SM::s::s2::s21::A}
//${SMs::QMsmTst::SM::s::s2::s21::A}
case A_SIG: {
static struct {
QP::QMState const *target;
QP::QActionHandler act[4];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s21_s, // target state
{
Q_ACTION_CAST(&s21_x), // exit
@ -597,12 +599,12 @@ QP::QState QMsmTst::s21(QMsmTst * const me, QP::QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
// ${SMs::QMsmTst::SM::s::s2::s21::B}
//${SMs::QMsmTst::SM::s::s2::s21::B}
case B_SIG: {
static struct {
QP::QMState const *target;
QP::QActionHandler act[2];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s211_s, // target state
{
Q_ACTION_CAST(&s211_e), // entry
@ -628,28 +630,28 @@ QP::QMState const QMsmTst::s211_s = {
Q_ACTION_CAST(&QMsmTst::s211_x),
Q_ACTION_CAST(0) // no intitial tran.
};
// ${SMs::QMsmTst::SM::s::s2::s21::s211}
//${SMs::QMsmTst::SM::s::s2::s21::s211}
QP::QState QMsmTst::s211_e(QMsmTst * const me) {
BSP_display("s211-ENTRY;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_ENTRY(&s211_s);
}
// ${SMs::QMsmTst::SM::s::s2::s21::s211}
//${SMs::QMsmTst::SM::s::s2::s21::s211}
QP::QState QMsmTst::s211_x(QMsmTst * const me) {
BSP_display("s211-EXIT;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_EXIT(&s211_s);
}
// ${SMs::QMsmTst::SM::s::s2::s21::s211}
//${SMs::QMsmTst::SM::s::s2::s21::s211}
QP::QState QMsmTst::s211(QMsmTst * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${SMs::QMsmTst::SM::s::s2::s21::s211::H}
//${SMs::QMsmTst::SM::s::s2::s21::s211::H}
case H_SIG: {
static struct {
QP::QMState const *target;
QP::QActionHandler act[5];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s_s, // target state
{
Q_ACTION_CAST(&s211_x), // exit
@ -663,12 +665,12 @@ QP::QState QMsmTst::s211(QMsmTst * const me, QP::QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
// ${SMs::QMsmTst::SM::s::s2::s21::s211::D}
//${SMs::QMsmTst::SM::s::s2::s21::s211::D}
case D_SIG: {
static struct {
QP::QMState const *target;
QP::QActionHandler act[3];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s21_s, // target state
{
Q_ACTION_CAST(&s211_x), // exit
@ -687,6 +689,6 @@ QP::QState QMsmTst::s211(QMsmTst * const me, QP::QEvt const * const e) {
}
return status_;
}
//$enddef${SMs::QMsmTst} #####################################################
} // namespace QMSMTST
} // namespace QMSMTST

View File

@ -1,22 +1,23 @@
//****************************************************************************
// Model: qmsmtst.qm
// File: ./qmsmtst.h
//$file${.::qmsmtst.h} #######################################################
//
// This code has been generated by QM tool (see state-machine.com/qm).
// Model: qmsmtst.qm
// File: C:/qp_lab/qpcpp/examples/posix/qmsmtst/qmsmtst.h
//
// This code has been generated by QM tool (https://state-machine.com/qm).
// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
//
// This code is covered by the following commercial QP license:
// License # : QPCPP-EVAL-170201
// This code is covered by the following QP license:
// License # : QPCPP-EVAL-171231
// Issued to : Company/individual evaluating the QP/C++ framework
// Framework(s): qpcpp
// Support ends: 2017-02-28
// Support ends: 2017-12-31
// Product(s) :
// This license is available only for evaluation purposes and
// the generated code is still licensed under the terms of GPL.
// Please submit request for extension of the evaluaion period at:
// https://state-machine.com/licensing/index.html#RequestForm
//****************************************************************************
//${.::qmsmtst.h} ............................................................
// https://state-machine.com/licensing/#RequestForm
//
//$endhead${.::qmsmtst.h} ####################################################
#ifndef qmsmtst_h
#define qmsmtst_h
@ -45,4 +46,4 @@ void BSP_terminate(int16_t const result);
} // namespace QMSMTST
#endif // qmsmtst_h
#endif // qmsmtst_h

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<model version="4.0.0" links="0">
<model version="4.1.0" links="0">
<documentation>QMsmTst is a test for the QMsm state machine based on Chapter 2 of the PSiCC2 book.</documentation>
<framework name="qpcpp" license="../../../QPCPP-EVAL-170201.qlc"/>
<framework name="qpcpp" license="../../../QPCPP-EVAL-171231.qlc"/>
<package name="SMs" stereotype="0x02">
<class name="QMsmTst" superclass="qpcpp::QMsm">
<documentation>Test active object</documentation>

View File

@ -1,32 +1,29 @@
//****************************************************************************
// Model: qmsmtst.qm
// File: ./qmsmtst.cpp
//$file${.::qmsmtst.cpp} #####################################################
//
// This code has been generated by QM tool (see state-machine.com/qm).
// Model: qmsmtst.qm
// File: C:/qp_lab/qpcpp/examples/qutest/qmsmtst/qmsmtst.cpp
//
// This code has been generated by QM tool (https://state-machine.com/qm).
// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
//
// This code is covered by the following commercial QP license:
// License # : QPCPP-EVAL-590
// This code is covered by the following QP license:
// License # : QPCPP-EVAL-171231
// Issued to : Company/individual evaluating the QP/C++ framework
// Framework(s): qpcpp
// Support ends: 2017-06-30
// Support ends: 2017-12-31
// Product(s) :
// This license is available only for evaluation purposes and
// the generated code is still licensed under the terms of GPL.
// Please submit request for extension of the evaluaion period at:
// https://state-machine.com/licensing/#RequestForm
//****************************************************************************
//${.::qmsmtst.cpp} ..........................................................
//
//$endhead${.::qmsmtst.cpp} ##################################################
#include "qpcpp.h"
#include "qmsmtst.h"
namespace QMSMTST {
#if ((QP_VERSION < 580) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8)))
#error qpcpp version 5.8.0 or higher required
#endif
//$declare${SMs::QMsmTst} ####################################################
//${SMs::QMsmTst} ............................................................
class QMsmTst : public QP::QMsm {
private:
@ -68,13 +65,18 @@ protected:
static QP::QState s211_x(QMsmTst * const me);
static QP::QMState const s211_s;
};
//$enddecl${SMs::QMsmTst} ####################################################
static QMsmTst l_msmtst; // the only instance of the QMsmTst class
// global-scope definitions -----------------------------------------
QP::QMsm * const the_msm = &l_msmtst; // the opaque pointer
//$define${SMs::QMsmTst} #####################################################
// Check for the minimum required QP version
#if ((QP_VERSION < 601) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8)))
#error qpcpp version 6.0.1 or higher required
#endif
//${SMs::QMsmTst} ............................................................
//${SMs::QMsmTst::SM} ........................................................
@ -82,7 +84,7 @@ QP::QState QMsmTst::initial(QMsmTst * const me, QP::QEvt const * const e) {
static struct {
QP::QMState const *target;
QP::QActionHandler act[4];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s2_s, // target state
{
Q_ACTION_CAST(&s_e), // entry
@ -91,7 +93,7 @@ QP::QState QMsmTst::initial(QMsmTst * const me, QP::QEvt const * const e) {
Q_ACTION_CAST(0) // zero terminator
}
};
// ${SMs::QMsmTst::SM::initial}
//${SMs::QMsmTst::SM::initial}
(void)e; // avoid compiler warning
me->m_foo = 0U;
BSP_display("top-INIT;");
@ -124,24 +126,24 @@ QP::QMState const QMsmTst::s_s = {
Q_ACTION_CAST(&QMsmTst::s_x),
Q_ACTION_CAST(&QMsmTst::s_i)
};
// ${SMs::QMsmTst::SM::s}
//${SMs::QMsmTst::SM::s}
QP::QState QMsmTst::s_e(QMsmTst * const me) {
BSP_display("s-ENTRY;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_ENTRY(&s_s);
}
// ${SMs::QMsmTst::SM::s}
//${SMs::QMsmTst::SM::s}
QP::QState QMsmTst::s_x(QMsmTst * const me) {
BSP_display("s-EXIT;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_EXIT(&s_s);
}
// ${SMs::QMsmTst::SM::s::initial}
//${SMs::QMsmTst::SM::s::initial}
QP::QState QMsmTst::s_i(QMsmTst * const me) {
static struct {
QP::QMState const *target;
QP::QActionHandler act[3];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s11_s, // target state
{
Q_ACTION_CAST(&s1_e), // entry
@ -149,17 +151,17 @@ QP::QState QMsmTst::s_i(QMsmTst * const me) {
Q_ACTION_CAST(0) // zero terminator
}
};
// ${SMs::QMsmTst::SM::s::initial}
//${SMs::QMsmTst::SM::s::initial}
BSP_display("s-INIT;");
return QM_TRAN_INIT(&tatbl_);
}
// ${SMs::QMsmTst::SM::s}
//${SMs::QMsmTst::SM::s}
QP::QState QMsmTst::s(QMsmTst * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${SMs::QMsmTst::SM::s::I}
//${SMs::QMsmTst::SM::s::I}
case I_SIG: {
// ${SMs::QMsmTst::SM::s::I::[me->m_foo]}
//${SMs::QMsmTst::SM::s::I::[me->m_foo]}
if (me->m_foo) {
me->m_foo = 0U;
BSP_display("s-I;");
@ -170,12 +172,12 @@ QP::QState QMsmTst::s(QMsmTst * const me, QP::QEvt const * const e) {
}
break;
}
// ${SMs::QMsmTst::SM::s::E}
//${SMs::QMsmTst::SM::s::E}
case E_SIG: {
static struct {
QP::QMState const *target;
QP::QActionHandler act[3];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s11_s, // target state
{
Q_ACTION_CAST(&s1_e), // entry
@ -187,7 +189,7 @@ QP::QState QMsmTst::s(QMsmTst * const me, QP::QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
// ${SMs::QMsmTst::SM::s::TERMINATE}
//${SMs::QMsmTst::SM::s::TERMINATE}
case TERMINATE_SIG: {
BSP_terminate(0);
status_ = QM_HANDLED();
@ -209,52 +211,52 @@ QP::QMState const QMsmTst::s1_s = {
Q_ACTION_CAST(&QMsmTst::s1_x),
Q_ACTION_CAST(&QMsmTst::s1_i)
};
// ${SMs::QMsmTst::SM::s::s1}
//${SMs::QMsmTst::SM::s::s1}
QP::QState QMsmTst::s1_e(QMsmTst * const me) {
BSP_display("s1-ENTRY;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_ENTRY(&s1_s);
}
// ${SMs::QMsmTst::SM::s::s1}
//${SMs::QMsmTst::SM::s::s1}
QP::QState QMsmTst::s1_x(QMsmTst * const me) {
BSP_display("s1-EXIT;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_EXIT(&s1_s);
}
// ${SMs::QMsmTst::SM::s::s1::initial}
//${SMs::QMsmTst::SM::s::s1::initial}
QP::QState QMsmTst::s1_i(QMsmTst * const me) {
static struct {
QP::QMState const *target;
QP::QActionHandler act[2];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s11_s, // target state
{
Q_ACTION_CAST(&s11_e), // entry
Q_ACTION_CAST(0) // zero terminator
}
};
// ${SMs::QMsmTst::SM::s::s1::initial}
//${SMs::QMsmTst::SM::s::s1::initial}
BSP_display("s1-INIT;");
return QM_TRAN_INIT(&tatbl_);
}
// ${SMs::QMsmTst::SM::s::s1}
//${SMs::QMsmTst::SM::s::s1}
QP::QState QMsmTst::s1(QMsmTst * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${SMs::QMsmTst::SM::s::s1::I}
//${SMs::QMsmTst::SM::s::s1::I}
case I_SIG: {
BSP_display("s1-I;");
status_ = QM_HANDLED();
break;
}
// ${SMs::QMsmTst::SM::s::s1::D}
//${SMs::QMsmTst::SM::s::s1::D}
case D_SIG: {
// ${SMs::QMsmTst::SM::s::s1::D::[!me->m_foo]}
//${SMs::QMsmTst::SM::s::s1::D::[!me->m_foo]}
if (!me->m_foo) {
static struct {
QP::QMState const *target;
QP::QActionHandler act[3];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s_s, // target state
{
Q_ACTION_CAST(&s1_x), // exit
@ -271,12 +273,12 @@ QP::QState QMsmTst::s1(QMsmTst * const me, QP::QEvt const * const e) {
}
break;
}
// ${SMs::QMsmTst::SM::s::s1::A}
//${SMs::QMsmTst::SM::s::s1::A}
case A_SIG: {
static struct {
QP::QMState const *target;
QP::QActionHandler act[4];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s1_s, // target state
{
Q_ACTION_CAST(&s1_x), // exit
@ -289,12 +291,12 @@ QP::QState QMsmTst::s1(QMsmTst * const me, QP::QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
// ${SMs::QMsmTst::SM::s::s1::B}
//${SMs::QMsmTst::SM::s::s1::B}
case B_SIG: {
static struct {
QP::QMState const *target;
QP::QActionHandler act[2];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s11_s, // target state
{
Q_ACTION_CAST(&s11_e), // entry
@ -305,12 +307,12 @@ QP::QState QMsmTst::s1(QMsmTst * const me, QP::QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
// ${SMs::QMsmTst::SM::s::s1::F}
//${SMs::QMsmTst::SM::s::s1::F}
case F_SIG: {
static struct {
QP::QMState const *target;
QP::QActionHandler act[5];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s211_s, // target state
{
Q_ACTION_CAST(&s1_x), // exit
@ -324,12 +326,12 @@ QP::QState QMsmTst::s1(QMsmTst * const me, QP::QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
// ${SMs::QMsmTst::SM::s::s1::C}
//${SMs::QMsmTst::SM::s::s1::C}
case C_SIG: {
static struct {
QP::QMState const *target;
QP::QActionHandler act[4];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s2_s, // target state
{
Q_ACTION_CAST(&s1_x), // exit
@ -357,28 +359,28 @@ QP::QMState const QMsmTst::s11_s = {
Q_ACTION_CAST(&QMsmTst::s11_x),
Q_ACTION_CAST(0) // no intitial tran.
};
// ${SMs::QMsmTst::SM::s::s1::s11}
//${SMs::QMsmTst::SM::s::s1::s11}
QP::QState QMsmTst::s11_e(QMsmTst * const me) {
BSP_display("s11-ENTRY;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_ENTRY(&s11_s);
}
// ${SMs::QMsmTst::SM::s::s1::s11}
//${SMs::QMsmTst::SM::s::s1::s11}
QP::QState QMsmTst::s11_x(QMsmTst * const me) {
BSP_display("s11-EXIT;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_EXIT(&s11_s);
}
// ${SMs::QMsmTst::SM::s::s1::s11}
//${SMs::QMsmTst::SM::s::s1::s11}
QP::QState QMsmTst::s11(QMsmTst * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${SMs::QMsmTst::SM::s::s1::s11::H}
//${SMs::QMsmTst::SM::s::s1::s11::H}
case H_SIG: {
static struct {
QP::QMState const *target;
QP::QActionHandler act[4];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s_s, // target state
{
Q_ACTION_CAST(&s11_x), // exit
@ -391,14 +393,14 @@ QP::QState QMsmTst::s11(QMsmTst * const me, QP::QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
// ${SMs::QMsmTst::SM::s::s1::s11::D}
//${SMs::QMsmTst::SM::s::s1::s11::D}
case D_SIG: {
// ${SMs::QMsmTst::SM::s::s1::s11::D::[me->m_foo]}
//${SMs::QMsmTst::SM::s::s1::s11::D::[me->m_foo]}
if (me->m_foo) {
static struct {
QP::QMState const *target;
QP::QActionHandler act[3];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s1_s, // target state
{
Q_ACTION_CAST(&s11_x), // exit
@ -415,12 +417,12 @@ QP::QState QMsmTst::s11(QMsmTst * const me, QP::QEvt const * const e) {
}
break;
}
// ${SMs::QMsmTst::SM::s::s1::s11::G}
//${SMs::QMsmTst::SM::s::s1::s11::G}
case G_SIG: {
static struct {
QP::QMState const *target;
QP::QActionHandler act[6];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s211_s, // target state
{
Q_ACTION_CAST(&s11_x), // exit
@ -450,24 +452,24 @@ QP::QMState const QMsmTst::s2_s = {
Q_ACTION_CAST(&QMsmTst::s2_x),
Q_ACTION_CAST(&QMsmTst::s2_i)
};
// ${SMs::QMsmTst::SM::s::s2}
//${SMs::QMsmTst::SM::s::s2}
QP::QState QMsmTst::s2_e(QMsmTst * const me) {
BSP_display("s2-ENTRY;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_ENTRY(&s2_s);
}
// ${SMs::QMsmTst::SM::s::s2}
//${SMs::QMsmTst::SM::s::s2}
QP::QState QMsmTst::s2_x(QMsmTst * const me) {
BSP_display("s2-EXIT;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_EXIT(&s2_s);
}
// ${SMs::QMsmTst::SM::s::s2::initial}
//${SMs::QMsmTst::SM::s::s2::initial}
QP::QState QMsmTst::s2_i(QMsmTst * const me) {
static struct {
QP::QMState const *target;
QP::QActionHandler act[3];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s211_s, // target state
{
Q_ACTION_CAST(&s21_e), // entry
@ -475,17 +477,17 @@ QP::QState QMsmTst::s2_i(QMsmTst * const me) {
Q_ACTION_CAST(0) // zero terminator
}
};
// ${SMs::QMsmTst::SM::s::s2::initial}
//${SMs::QMsmTst::SM::s::s2::initial}
BSP_display("s2-INIT;");
return QM_TRAN_INIT(&tatbl_);
}
// ${SMs::QMsmTst::SM::s::s2}
//${SMs::QMsmTst::SM::s::s2}
QP::QState QMsmTst::s2(QMsmTst * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${SMs::QMsmTst::SM::s::s2::I}
//${SMs::QMsmTst::SM::s::s2::I}
case I_SIG: {
// ${SMs::QMsmTst::SM::s::s2::I::[!me->m_foo]}
//${SMs::QMsmTst::SM::s::s2::I::[!me->m_foo]}
if (!me->m_foo) {
me->m_foo = true;
BSP_display("s2-I;");
@ -496,12 +498,12 @@ QP::QState QMsmTst::s2(QMsmTst * const me, QP::QEvt const * const e) {
}
break;
}
// ${SMs::QMsmTst::SM::s::s2::F}
//${SMs::QMsmTst::SM::s::s2::F}
case F_SIG: {
static struct {
QP::QMState const *target;
QP::QActionHandler act[4];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s11_s, // target state
{
Q_ACTION_CAST(&s2_x), // exit
@ -514,12 +516,12 @@ QP::QState QMsmTst::s2(QMsmTst * const me, QP::QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
// ${SMs::QMsmTst::SM::s::s2::C}
//${SMs::QMsmTst::SM::s::s2::C}
case C_SIG: {
static struct {
QP::QMState const *target;
QP::QActionHandler act[4];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s1_s, // target state
{
Q_ACTION_CAST(&s2_x), // exit
@ -547,44 +549,44 @@ QP::QMState const QMsmTst::s21_s = {
Q_ACTION_CAST(&QMsmTst::s21_x),
Q_ACTION_CAST(&QMsmTst::s21_i)
};
// ${SMs::QMsmTst::SM::s::s2::s21}
//${SMs::QMsmTst::SM::s::s2::s21}
QP::QState QMsmTst::s21_e(QMsmTst * const me) {
BSP_display("s21-ENTRY;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_ENTRY(&s21_s);
}
// ${SMs::QMsmTst::SM::s::s2::s21}
//${SMs::QMsmTst::SM::s::s2::s21}
QP::QState QMsmTst::s21_x(QMsmTst * const me) {
BSP_display("s21-EXIT;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_EXIT(&s21_s);
}
// ${SMs::QMsmTst::SM::s::s2::s21::initial}
//${SMs::QMsmTst::SM::s::s2::s21::initial}
QP::QState QMsmTst::s21_i(QMsmTst * const me) {
static struct {
QP::QMState const *target;
QP::QActionHandler act[2];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s211_s, // target state
{
Q_ACTION_CAST(&s211_e), // entry
Q_ACTION_CAST(0) // zero terminator
}
};
// ${SMs::QMsmTst::SM::s::s2::s21::initial}
//${SMs::QMsmTst::SM::s::s2::s21::initial}
BSP_display("s21-INIT;");
return QM_TRAN_INIT(&tatbl_);
}
// ${SMs::QMsmTst::SM::s::s2::s21}
//${SMs::QMsmTst::SM::s::s2::s21}
QP::QState QMsmTst::s21(QMsmTst * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${SMs::QMsmTst::SM::s::s2::s21::G}
//${SMs::QMsmTst::SM::s::s2::s21::G}
case G_SIG: {
static struct {
QP::QMState const *target;
QP::QActionHandler act[5];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s1_s, // target state
{
Q_ACTION_CAST(&s21_x), // exit
@ -598,12 +600,12 @@ QP::QState QMsmTst::s21(QMsmTst * const me, QP::QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
// ${SMs::QMsmTst::SM::s::s2::s21::A}
//${SMs::QMsmTst::SM::s::s2::s21::A}
case A_SIG: {
static struct {
QP::QMState const *target;
QP::QActionHandler act[4];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s21_s, // target state
{
Q_ACTION_CAST(&s21_x), // exit
@ -616,12 +618,12 @@ QP::QState QMsmTst::s21(QMsmTst * const me, QP::QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
// ${SMs::QMsmTst::SM::s::s2::s21::B}
//${SMs::QMsmTst::SM::s::s2::s21::B}
case B_SIG: {
static struct {
QP::QMState const *target;
QP::QActionHandler act[2];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s211_s, // target state
{
Q_ACTION_CAST(&s211_e), // entry
@ -647,28 +649,28 @@ QP::QMState const QMsmTst::s211_s = {
Q_ACTION_CAST(&QMsmTst::s211_x),
Q_ACTION_CAST(0) // no intitial tran.
};
// ${SMs::QMsmTst::SM::s::s2::s21::s211}
//${SMs::QMsmTst::SM::s::s2::s21::s211}
QP::QState QMsmTst::s211_e(QMsmTst * const me) {
BSP_display("s211-ENTRY;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_ENTRY(&s211_s);
}
// ${SMs::QMsmTst::SM::s::s2::s21::s211}
//${SMs::QMsmTst::SM::s::s2::s21::s211}
QP::QState QMsmTst::s211_x(QMsmTst * const me) {
BSP_display("s211-EXIT;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_EXIT(&s211_s);
}
// ${SMs::QMsmTst::SM::s::s2::s21::s211}
//${SMs::QMsmTst::SM::s::s2::s21::s211}
QP::QState QMsmTst::s211(QMsmTst * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${SMs::QMsmTst::SM::s::s2::s21::s211::H}
//${SMs::QMsmTst::SM::s::s2::s21::s211::H}
case H_SIG: {
static struct {
QP::QMState const *target;
QP::QActionHandler act[5];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s_s, // target state
{
Q_ACTION_CAST(&s211_x), // exit
@ -682,12 +684,12 @@ QP::QState QMsmTst::s211(QMsmTst * const me, QP::QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
// ${SMs::QMsmTst::SM::s::s2::s21::s211::D}
//${SMs::QMsmTst::SM::s::s2::s21::s211::D}
case D_SIG: {
static struct {
QP::QMState const *target;
QP::QActionHandler act[3];
} const tatbl_ = { // transition-action table
} const tatbl_ = { // tran-action table
&s21_s, // target state
{
Q_ACTION_CAST(&s211_x), // exit
@ -706,6 +708,6 @@ QP::QState QMsmTst::s211(QMsmTst * const me, QP::QEvt const * const e) {
}
return status_;
}
//$enddef${SMs::QMsmTst} #####################################################
} // namespace QMSMTST
} // namespace QMSMTST

View File

@ -1,22 +1,23 @@
//****************************************************************************
// Model: qmsmtst.qm
// File: ./qmsmtst.h
//$file${.::qmsmtst.h} #######################################################
//
// This code has been generated by QM tool (see state-machine.com/qm).
// Model: qmsmtst.qm
// File: C:/qp_lab/qpcpp/examples/qutest/qmsmtst/qmsmtst.h
//
// This code has been generated by QM tool (https://state-machine.com/qm).
// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
//
// This code is covered by the following commercial QP license:
// License # : QPCPP-EVAL-590
// This code is covered by the following QP license:
// License # : QPCPP-EVAL-171231
// Issued to : Company/individual evaluating the QP/C++ framework
// Framework(s): qpcpp
// Support ends: 2017-06-30
// Support ends: 2017-12-31
// Product(s) :
// This license is available only for evaluation purposes and
// the generated code is still licensed under the terms of GPL.
// Please submit request for extension of the evaluaion period at:
// https://state-machine.com/licensing/#RequestForm
//****************************************************************************
//${.::qmsmtst.h} ............................................................
//
//$endhead${.::qmsmtst.h} ####################################################
#ifndef qmsmtst_h
#define qmsmtst_h
@ -45,4 +46,4 @@ void BSP_terminate(int16_t const result);
} // namespace QMSMTST
#endif // qmsmtst_h
#endif // qmsmtst_h

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<model version="4.0.1" links="0">
<model version="4.1.0" links="0">
<documentation>QMsmTst is a test for the QMsm state machine based on Chapter 2 of the PSiCC2 book.</documentation>
<framework name="qpcpp" license="../../../QPCPP-EVAL-590.qlc"/>
<framework name="qpcpp" license="../../../QPCPP-EVAL-171231.qlc"/>
<package name="SMs" stereotype="0x02">
<class name="QMsmTst" superclass="qpcpp::QMsm">
<documentation>Test active object</documentation>

View File

@ -1,8 +1,9 @@
//****************************************************************************
// Model: calc1_sub.qm
// File: ./calc1_sub.cpp
//$file${.::calc1_sub.cpp} ###################################################
//
// This code has been generated by QM tool (see state-machine.com/qm).
// Model: calc1_sub.qm
// File: C:/qp_lab/qpcpp/examples/win32/calc1_sub/calc1_sub.cpp
//
// This code has been generated by QM tool (https://state-machine.com/qm).
// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
//
// This code is covered by the following QP license:
@ -15,17 +16,13 @@
// the generated code is still licensed under the terms of GPL.
// Please submit request for extension of the evaluaion period at:
// https://state-machine.com/licensing/#RequestForm
//****************************************************************************
//${.::calc1_sub.cpp} ........................................................
//
//$endhead${.::calc1_sub.cpp} ################################################
#include "qpcpp.h" // QP/C++
#include "bsp.h" // board support package
#include "calc1_sub.h" // application
#if ((QP_VERSION < 591) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8)))
#error qpcpp version 5.9.1 or higher required
#endif
//$declare${SMs::Calc} #######################################################
//${SMs::Calc} ...............................................................
class Calc : public QP::QMsm {
private:
@ -108,13 +105,18 @@ protected:
static QP::QState operand_i(Calc * const me);
static QP::QMState const operand_s;
};
//$enddecl${SMs::Calc} #######################################################
static Calc l_calc; // the only instance of the Calc class
// global-scope definitions --------------------------------------
QP::QMsm * const the_calc = &l_calc; // "opaque" pointer to MSM
//$define${SMs::Calc} ########################################################
// Check for the minimum required QP version
#if ((QP_VERSION < 601) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8)))
#error qpcpp version 6.0.1 or higher required
#endif
//${SMs::Calc} ...............................................................
//${SMs::Calc::Calc} .........................................................
Calc::Calc()
@ -134,7 +136,7 @@ QP::QState Calc::initial(Calc * const me, QP::QEvt const * const e) {
Q_ACTION_CAST(0) // zero terminator
}
};
// ${SMs::Calc::SM::initial}
//${SMs::Calc::SM::initial}
BSP_clear();
(void)e; // unused parameter
return QM_TRAN_INIT(&tatbl_);
@ -147,19 +149,19 @@ QP::QMState const Calc::on_s = {
Q_ACTION_CAST(&Calc::on_x),
Q_ACTION_CAST(&Calc::on_i)
};
// ${SMs::Calc::SM::on}
//${SMs::Calc::SM::on}
QP::QState Calc::on_e(Calc * const me) {
BSP_message("on-ENTRY;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_ENTRY(&on_s);
}
// ${SMs::Calc::SM::on}
//${SMs::Calc::SM::on}
QP::QState Calc::on_x(Calc * const me) {
BSP_message("on-EXIT;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_EXIT(&on_s);
}
// ${SMs::Calc::SM::on::initial}
//${SMs::Calc::SM::on::initial}
QP::QState Calc::on_i(Calc * const me) {
static struct {
QP::QMState const *target;
@ -172,15 +174,15 @@ QP::QState Calc::on_i(Calc * const me) {
Q_ACTION_CAST(0) // zero terminator
}
};
// ${SMs::Calc::SM::on::initial}
//${SMs::Calc::SM::on::initial}
BSP_message("on-INIT;");
return QM_TRAN_INIT(&tatbl_);
}
// ${SMs::Calc::SM::on}
//${SMs::Calc::SM::on}
QP::QState Calc::on(Calc * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${SMs::Calc::SM::on::C}
//${SMs::Calc::SM::on::C}
case C_SIG: {
static struct {
QP::QMState const *target;
@ -198,7 +200,7 @@ QP::QState Calc::on(Calc * const me, QP::QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
// ${SMs::Calc::SM::on::OFF}
//${SMs::Calc::SM::on::OFF}
case OFF_SIG: {
static struct {
QP::QMState const *target;
@ -229,19 +231,19 @@ QP::QMState const Calc::ready_s = {
Q_ACTION_CAST(&Calc::ready_x),
Q_ACTION_CAST(&Calc::ready_i)
};
// ${SMs::Calc::SM::on::ready}
//${SMs::Calc::SM::on::ready}
QP::QState Calc::ready_e(Calc * const me) {
BSP_message("ready-ENTRY;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_ENTRY(&ready_s);
}
// ${SMs::Calc::SM::on::ready}
//${SMs::Calc::SM::on::ready}
QP::QState Calc::ready_x(Calc * const me) {
BSP_message("ready-EXIT;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_EXIT(&ready_s);
}
// ${SMs::Calc::SM::on::ready::initial}
//${SMs::Calc::SM::on::ready::initial}
QP::QState Calc::ready_i(Calc * const me) {
static struct {
QP::QMState const *target;
@ -253,15 +255,15 @@ QP::QState Calc::ready_i(Calc * const me) {
Q_ACTION_CAST(0) // zero terminator
}
};
// ${SMs::Calc::SM::on::ready::initial}
//${SMs::Calc::SM::on::ready::initial}
BSP_message("ready-INIT;");
return QM_TRAN_INIT(&tatbl_);
}
// ${SMs::Calc::SM::on::ready}
//${SMs::Calc::SM::on::ready}
QP::QState Calc::ready(Calc * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${SMs::Calc::SM::on::ready::DIGIT_0}
//${SMs::Calc::SM::on::ready::DIGIT_0}
case DIGIT_0_SIG: {
static struct {
QP::QMState const *target;
@ -279,7 +281,7 @@ QP::QState Calc::ready(Calc * const me, QP::QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
// ${SMs::Calc::SM::on::ready::DIGIT_1_9}
//${SMs::Calc::SM::on::ready::DIGIT_1_9}
case DIGIT_1_9_SIG: {
static struct {
QP::QMState const *target;
@ -295,10 +297,10 @@ QP::QState Calc::ready(Calc * const me, QP::QEvt const * const e) {
};
BSP_clear();
BSP_insert(Q_EVT_CAST(CalcEvt)->key_code);
status_ = QM_TRAN(&tatbl_);
status_ = QM_TRAN_EP(&tatbl_);
break;
}
// ${SMs::Calc::SM::on::ready::POINT}
//${SMs::Calc::SM::on::ready::POINT}
case POINT_SIG: {
static struct {
QP::QMState const *target;
@ -315,10 +317,10 @@ QP::QState Calc::ready(Calc * const me, QP::QEvt const * const e) {
BSP_clear();
BSP_insert((int)'0');
BSP_insert((int)'.');
status_ = QM_TRAN(&tatbl_);
status_ = QM_TRAN_EP(&tatbl_);
break;
}
// ${SMs::Calc::SM::on::ready::OPER}
//${SMs::Calc::SM::on::ready::OPER}
case OPER_SIG: {
static struct {
QP::QMState const *target;
@ -351,19 +353,19 @@ QP::QMState const Calc::result_s = {
Q_ACTION_CAST(&Calc::result_x),
Q_ACTION_CAST(0) // no intitial tran.
};
// ${SMs::Calc::SM::on::ready::result}
//${SMs::Calc::SM::on::ready::result}
QP::QState Calc::result_e(Calc * const me) {
BSP_message("result-ENTRY;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_ENTRY(&result_s);
}
// ${SMs::Calc::SM::on::ready::result}
//${SMs::Calc::SM::on::ready::result}
QP::QState Calc::result_x(Calc * const me) {
BSP_message("result-EXIT;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_EXIT(&result_s);
}
// ${SMs::Calc::SM::on::ready::result}
//${SMs::Calc::SM::on::ready::result}
QP::QState Calc::result(Calc * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
@ -383,25 +385,25 @@ QP::QMState const Calc::begin_s = {
Q_ACTION_CAST(&Calc::begin_x),
Q_ACTION_CAST(0) // no intitial tran.
};
// ${SMs::Calc::SM::on::ready::begin}
//${SMs::Calc::SM::on::ready::begin}
QP::QState Calc::begin_e(Calc * const me) {
BSP_message("begin-ENTRY;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_ENTRY(&begin_s);
}
// ${SMs::Calc::SM::on::ready::begin}
//${SMs::Calc::SM::on::ready::begin}
QP::QState Calc::begin_x(Calc * const me) {
BSP_message("begin-EXIT;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_EXIT(&begin_s);
}
// ${SMs::Calc::SM::on::ready::begin}
//${SMs::Calc::SM::on::ready::begin}
QP::QState Calc::begin(Calc * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${SMs::Calc::SM::on::ready::begin::OPER}
//${SMs::Calc::SM::on::ready::begin::OPER}
case OPER_SIG: {
// ${SMs::Calc::SM::on::ready::begin::OPER::[e->key=='-']}
//${SMs::Calc::SM::on::ready::begin::OPER::[e->key=='-']}
if (Q_EVT_CAST(CalcEvt)->key_code == KEY_MINUS) {
static struct {
QP::QMState const *target;
@ -416,9 +418,9 @@ QP::QState Calc::begin(Calc * const me, QP::QEvt const * const e) {
Q_ACTION_CAST(0) // zero terminator
}
};
status_ = QM_TRAN(&tatbl_);
status_ = QM_TRAN_EP(&tatbl_);
}
// ${SMs::Calc::SM::on::ready::begin::OPER::[else]}
//${SMs::Calc::SM::on::ready::begin::OPER::[else]}
else {
status_ = QM_HANDLED();
}
@ -441,14 +443,15 @@ Calc::SM_operand const Calc::operand1_s = {
Q_ACTION_CAST(0), // no exit action
Q_ACTION_CAST(0) // no intitial tran.
}
,Q_ACTION_CAST(&Calc::operand1_ce)
};
// ${SMs::Calc::SM::on::operand1}
//${SMs::Calc::SM::on::operand1}
QP::QState Calc::operand1_e(Calc * const me) {
me->sub_operand = &operand1_s; // attach submachine
return operand_e(me); // enter submachine
}
// ${SMs::Calc::SM::on::operand1}
//${SMs::Calc::SM::on::operand1}
QP::QState Calc::operand1_ce(Calc * const me) {
static struct {
QP::QMState const *target;
@ -466,11 +469,11 @@ QP::QState Calc::operand1_ce(Calc * const me) {
BSP_message("operand1-XP:ce;");
return QM_TRAN(&tatbl_);
}
// ${SMs::Calc::SM::on::operand1}
//${SMs::Calc::SM::on::operand1}
QP::QState Calc::operand1(Calc * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${SMs::Calc::SM::on::operand1::OPER}
//${SMs::Calc::SM::on::operand1::OPER}
case OPER_SIG: {
static struct {
QP::QMState const *target;
@ -487,7 +490,7 @@ QP::QState Calc::operand1(Calc * const me, QP::QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
// ${SMs::Calc::SM::on::operand1::EQUALS}
//${SMs::Calc::SM::on::operand1::EQUALS}
case EQUALS_SIG: {
static struct {
QP::QMState const *target;
@ -518,23 +521,23 @@ QP::QMState const Calc::opEntered_s = {
Q_ACTION_CAST(&Calc::opEntered_x),
Q_ACTION_CAST(0) // no intitial tran.
};
// ${SMs::Calc::SM::on::opEntered}
//${SMs::Calc::SM::on::opEntered}
QP::QState Calc::opEntered_e(Calc * const me) {
BSP_message("opEntered-ENTRY;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_ENTRY(&opEntered_s);
}
// ${SMs::Calc::SM::on::opEntered}
//${SMs::Calc::SM::on::opEntered}
QP::QState Calc::opEntered_x(Calc * const me) {
BSP_message("opEntered-EXIT;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_EXIT(&opEntered_s);
}
// ${SMs::Calc::SM::on::opEntered}
//${SMs::Calc::SM::on::opEntered}
QP::QState Calc::opEntered(Calc * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${SMs::Calc::SM::on::opEntered::DIGIT_0}
//${SMs::Calc::SM::on::opEntered::DIGIT_0}
case DIGIT_0_SIG: {
static struct {
QP::QMState const *target;
@ -549,10 +552,10 @@ QP::QState Calc::opEntered(Calc * const me, QP::QEvt const * const e) {
}
};
BSP_clear();
status_ = QM_TRAN(&tatbl_);
status_ = QM_TRAN_EP(&tatbl_);
break;
}
// ${SMs::Calc::SM::on::opEntered::DIGIT_1_9}
//${SMs::Calc::SM::on::opEntered::DIGIT_1_9}
case DIGIT_1_9_SIG: {
static struct {
QP::QMState const *target;
@ -568,10 +571,10 @@ QP::QState Calc::opEntered(Calc * const me, QP::QEvt const * const e) {
};
BSP_clear();
BSP_insert(Q_EVT_CAST(CalcEvt)->key_code);
status_ = QM_TRAN(&tatbl_);
status_ = QM_TRAN_EP(&tatbl_);
break;
}
// ${SMs::Calc::SM::on::opEntered::POINT}
//${SMs::Calc::SM::on::opEntered::POINT}
case POINT_SIG: {
static struct {
QP::QMState const *target;
@ -588,12 +591,12 @@ QP::QState Calc::opEntered(Calc * const me, QP::QEvt const * const e) {
BSP_clear();
BSP_insert((int)'0');
BSP_insert((int)'.');
status_ = QM_TRAN(&tatbl_);
status_ = QM_TRAN_EP(&tatbl_);
break;
}
// ${SMs::Calc::SM::on::opEntered::OPER}
//${SMs::Calc::SM::on::opEntered::OPER}
case OPER_SIG: {
// ${SMs::Calc::SM::on::opEntered::OPER::[e->key=='-']}
//${SMs::Calc::SM::on::opEntered::OPER::[e->key=='-']}
if (Q_EVT_CAST(CalcEvt)->key_code == KEY_MINUS) {
static struct {
QP::QMState const *target;
@ -607,9 +610,9 @@ QP::QState Calc::opEntered(Calc * const me, QP::QEvt const * const e) {
Q_ACTION_CAST(0) // zero terminator
}
};
status_ = QM_TRAN(&tatbl_);
status_ = QM_TRAN_EP(&tatbl_);
}
// ${SMs::Calc::SM::on::opEntered::OPER::[else]}
//${SMs::Calc::SM::on::opEntered::OPER::[else]}
else {
status_ = QM_HANDLED();
}
@ -631,19 +634,19 @@ QP::QMState const Calc::error_s = {
Q_ACTION_CAST(&Calc::error_x),
Q_ACTION_CAST(0) // no intitial tran.
};
// ${SMs::Calc::SM::on::error}
//${SMs::Calc::SM::on::error}
QP::QState Calc::error_e(Calc * const me) {
BSP_message("error-ENTRY;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_ENTRY(&error_s);
}
// ${SMs::Calc::SM::on::error}
//${SMs::Calc::SM::on::error}
QP::QState Calc::error_x(Calc * const me) {
BSP_message("error-EXIT;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_EXIT(&error_s);
}
// ${SMs::Calc::SM::on::error}
//${SMs::Calc::SM::on::error}
QP::QState Calc::error(Calc * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
@ -664,14 +667,15 @@ Calc::SM_operand const Calc::operand2_s = {
Q_ACTION_CAST(0), // no exit action
Q_ACTION_CAST(0) // no intitial tran.
}
,Q_ACTION_CAST(&Calc::operand2_ce)
};
// ${SMs::Calc::SM::on::operand2}
//${SMs::Calc::SM::on::operand2}
QP::QState Calc::operand2_e(Calc * const me) {
me->sub_operand = &operand2_s; // attach submachine
return operand_e(me); // enter submachine
}
// ${SMs::Calc::SM::on::operand2}
//${SMs::Calc::SM::on::operand2}
QP::QState Calc::operand2_ce(Calc * const me) {
static struct {
QP::QMState const *target;
@ -688,13 +692,13 @@ QP::QState Calc::operand2_ce(Calc * const me) {
BSP_message("operand2-XP:ce;");
return QM_TRAN(&tatbl_);
}
// ${SMs::Calc::SM::on::operand2}
//${SMs::Calc::SM::on::operand2}
QP::QState Calc::operand2(Calc * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${SMs::Calc::SM::on::operand2::OPER}
//${SMs::Calc::SM::on::operand2::OPER}
case OPER_SIG: {
// ${SMs::Calc::SM::on::operand2::OPER::[BSP_eval()]}
//${SMs::Calc::SM::on::operand2::OPER::[BSP_eval()]}
if (BSP_eval(me->m_op1, me->m_oper, BSP_get_value())) {
static struct {
QP::QMState const *target;
@ -708,7 +712,7 @@ QP::QState Calc::operand2(Calc * const me, QP::QEvt const * const e) {
};
status_ = QM_TRAN(&tatbl_);
}
// ${SMs::Calc::SM::on::operand2::OPER::[else]}
//${SMs::Calc::SM::on::operand2::OPER::[else]}
else {
static struct {
QP::QMState const *target;
@ -724,9 +728,9 @@ QP::QState Calc::operand2(Calc * const me, QP::QEvt const * const e) {
}
break;
}
// ${SMs::Calc::SM::on::operand2::EQUALS}
//${SMs::Calc::SM::on::operand2::EQUALS}
case EQUALS_SIG: {
// ${SMs::Calc::SM::on::operand2::EQUALS::[BSP_eval()]}
//${SMs::Calc::SM::on::operand2::EQUALS::[BSP_eval()]}
if (BSP_eval(me->m_op1, me->m_oper, BSP_get_value())) {
static struct {
QP::QMState const *target;
@ -741,7 +745,7 @@ QP::QState Calc::operand2(Calc * const me, QP::QEvt const * const e) {
};
status_ = QM_TRAN(&tatbl_);
}
// ${SMs::Calc::SM::on::operand2::EQUALS::[else]}
//${SMs::Calc::SM::on::operand2::EQUALS::[else]}
else {
static struct {
QP::QMState const *target;
@ -772,14 +776,14 @@ QP::QMState const Calc::final_s = {
Q_ACTION_CAST(0), // no exit action
Q_ACTION_CAST(0) // no intitial tran.
};
// ${SMs::Calc::SM::final}
//${SMs::Calc::SM::final}
QP::QState Calc::final_e(Calc * const me) {
BSP_message("final-ENTRY;");
BSP_exit();
(void)me; // avoid compiler warning in case 'me' is not used
return QM_ENTRY(&final_s);
}
// ${SMs::Calc::SM::final}
//${SMs::Calc::SM::final}
QP::QState Calc::final(Calc * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
@ -792,7 +796,7 @@ QP::QState Calc::final(Calc * const me, QP::QEvt const * const e) {
return status_;
}
//${SMs::Calc::SM::operand} ..................................................
// ${SMs::Calc::SM::operand}
//${SMs::Calc::SM::operand}
QP::QMState const Calc::operand_s = {
static_cast<QP::QMState const *>(0), // superstate unused
Q_STATE_CAST(&Calc::operand),
@ -800,18 +804,18 @@ QP::QMState const Calc::operand_s = {
Q_ACTION_CAST(&Calc::operand_x),
Q_ACTION_CAST(&Calc::operand_i)
};
// ${SMs::Calc::SM::operand}
//${SMs::Calc::SM::operand}
QP::QState Calc::operand_e(Calc * const me) {
BSP_message("operand-ENTRY;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_ENTRY(&operand_s);
}
// ${SMs::Calc::SM::operand}
//${SMs::Calc::SM::operand}
QP::QState Calc::operand_x(Calc * const me) {
BSP_message("operand-EXIT;");
return QM_SM_EXIT(&me->sub_operand->super);
}
// ${SMs::Calc::SM::operand::initial}
//${SMs::Calc::SM::operand::initial}
QP::QState Calc::operand_i(Calc * const me) {
static struct {
QP::QMState const *target;
@ -823,15 +827,15 @@ QP::QState Calc::operand_i(Calc * const me) {
Q_ACTION_CAST(0) // zero terminator
}
};
// ${SMs::Calc::SM::operand::initial}
//${SMs::Calc::SM::operand::initial}
BSP_message("operand-INIT;");
return QM_TRAN_INIT(&tatbl_);
}
// ${SMs::Calc::SM::operand}
//${SMs::Calc::SM::operand}
QP::QState Calc::operand(Calc * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${SMs::Calc::SM::operand::CE}
//${SMs::Calc::SM::operand::CE}
case CE_SIG: {
static QP::QMTranActTable const tatbl_ = { // tran-action table
&operand_s, // target submachine
@ -851,7 +855,7 @@ QP::QState Calc::operand(Calc * const me, QP::QEvt const * const e) {
}
return status_;
}
// ${SMs::Calc::SM::operand::zero}
//${SMs::Calc::SM::operand::zero}
QP::QState Calc::SM_operand::zero_ep(Calc * const me) {
static struct {
QP::QMState const *target;
@ -866,7 +870,7 @@ QP::QState Calc::SM_operand::zero_ep(Calc * const me) {
BSP_message("operand::zero-EP;");
return QM_TRAN_EP(&tatbl_);
}
// ${SMs::Calc::SM::operand::intgr}
//${SMs::Calc::SM::operand::intgr}
QP::QState Calc::SM_operand::intgr_ep(Calc * const me) {
static struct {
QP::QMState const *target;
@ -881,7 +885,7 @@ QP::QState Calc::SM_operand::intgr_ep(Calc * const me) {
BSP_message("operand::intgr-EP;");
return QM_TRAN_EP(&tatbl_);
}
// ${SMs::Calc::SM::operand::frac}
//${SMs::Calc::SM::operand::frac}
QP::QState Calc::SM_operand::frac_ep(Calc * const me) {
static struct {
QP::QMState const *target;
@ -896,7 +900,7 @@ QP::QState Calc::SM_operand::frac_ep(Calc * const me) {
BSP_message("operand::frac-EP;");
return QM_TRAN_EP(&tatbl_);
}
// ${SMs::Calc::SM::operand::neg}
//${SMs::Calc::SM::operand::neg}
QP::QState Calc::SM_operand::neg_ep(Calc * const me) {
static struct {
QP::QMState const *target;
@ -919,29 +923,29 @@ QP::QMState const Calc::SM_operand::zero_s = {
Q_ACTION_CAST(&Calc::SM_operand::zero_x),
Q_ACTION_CAST(0) // no intitial tran.
};
// ${SMs::Calc::SM::operand::zero}
//${SMs::Calc::SM::operand::zero}
QP::QState Calc::SM_operand::zero_e(Calc * const me) {
BSP_message("operand::zero-ENTRY;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_ENTRY(&SM_operand::zero_s);
}
// ${SMs::Calc::SM::operand::zero}
//${SMs::Calc::SM::operand::zero}
QP::QState Calc::SM_operand::zero_x(Calc * const me) {
BSP_message("operand::zero-EXIT;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_EXIT(&SM_operand::zero_s);
}
// ${SMs::Calc::SM::operand::zero}
//${SMs::Calc::SM::operand::zero}
QP::QState Calc::SM_operand::zero(Calc * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${SMs::Calc::SM::operand::zero::DIGIT_0}
//${SMs::Calc::SM::operand::zero::DIGIT_0}
case DIGIT_0_SIG: {
;
status_ = QM_HANDLED();
break;
}
// ${SMs::Calc::SM::operand::zero::DIGIT_1_9}
//${SMs::Calc::SM::operand::zero::DIGIT_1_9}
case DIGIT_1_9_SIG: {
static struct {
QP::QMState const *target;
@ -958,7 +962,7 @@ QP::QState Calc::SM_operand::zero(Calc * const me, QP::QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
// ${SMs::Calc::SM::operand::zero::POINT}
//${SMs::Calc::SM::operand::zero::POINT}
case POINT_SIG: {
static struct {
QP::QMState const *target;
@ -991,23 +995,23 @@ QP::QMState const Calc::SM_operand::intgr_s = {
Q_ACTION_CAST(&Calc::SM_operand::intgr_x),
Q_ACTION_CAST(0) // no intitial tran.
};
// ${SMs::Calc::SM::operand::intgr}
//${SMs::Calc::SM::operand::intgr}
QP::QState Calc::SM_operand::intgr_e(Calc * const me) {
BSP_message("operand::intgr-ENTRY;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_ENTRY(&SM_operand::intgr_s);
}
// ${SMs::Calc::SM::operand::intgr}
//${SMs::Calc::SM::operand::intgr}
QP::QState Calc::SM_operand::intgr_x(Calc * const me) {
BSP_message("operand::intgr-EXIT;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_EXIT(&SM_operand::intgr_s);
}
// ${SMs::Calc::SM::operand::intgr}
//${SMs::Calc::SM::operand::intgr}
QP::QState Calc::SM_operand::intgr(Calc * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${SMs::Calc::SM::operand::intgr::POINT}
//${SMs::Calc::SM::operand::intgr::POINT}
case POINT_SIG: {
static struct {
QP::QMState const *target;
@ -1024,7 +1028,7 @@ QP::QState Calc::SM_operand::intgr(Calc * const me, QP::QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
// ${SMs::Calc::SM::operand::intgr::DIGIT_0, DIGIT_1_9}
//${SMs::Calc::SM::operand::intgr::DIGIT_0, DIGIT_1_9}
case DIGIT_0_SIG: // intentionally fall through
case DIGIT_1_9_SIG: {
BSP_insert(Q_EVT_CAST(CalcEvt)->key_code);
@ -1047,29 +1051,29 @@ QP::QMState const Calc::SM_operand::frac_s = {
Q_ACTION_CAST(&Calc::SM_operand::frac_x),
Q_ACTION_CAST(0) // no intitial tran.
};
// ${SMs::Calc::SM::operand::frac}
//${SMs::Calc::SM::operand::frac}
QP::QState Calc::SM_operand::frac_e(Calc * const me) {
BSP_message("operand::frac-ENTRY;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_ENTRY(&SM_operand::frac_s);
}
// ${SMs::Calc::SM::operand::frac}
//${SMs::Calc::SM::operand::frac}
QP::QState Calc::SM_operand::frac_x(Calc * const me) {
BSP_message("operand::frac-EXIT;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_EXIT(&SM_operand::frac_s);
}
// ${SMs::Calc::SM::operand::frac}
//${SMs::Calc::SM::operand::frac}
QP::QState Calc::SM_operand::frac(Calc * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${SMs::Calc::SM::operand::frac::POINT}
//${SMs::Calc::SM::operand::frac::POINT}
case POINT_SIG: {
;
status_ = QM_HANDLED();
break;
}
// ${SMs::Calc::SM::operand::frac::DIGIT_0, DIGIT_1_9}
//${SMs::Calc::SM::operand::frac::DIGIT_0, DIGIT_1_9}
case DIGIT_0_SIG: // intentionally fall through
case DIGIT_1_9_SIG: {
BSP_insert(Q_EVT_CAST(CalcEvt)->key_code);
@ -1092,24 +1096,24 @@ QP::QMState const Calc::SM_operand::neg_s = {
Q_ACTION_CAST(&Calc::SM_operand::neg_x),
Q_ACTION_CAST(0) // no intitial tran.
};
// ${SMs::Calc::SM::operand::neg}
//${SMs::Calc::SM::operand::neg}
QP::QState Calc::SM_operand::neg_e(Calc * const me) {
BSP_message("operand::neg-ENTRY;");
BSP_negate();
(void)me; // avoid compiler warning in case 'me' is not used
return QM_ENTRY(&SM_operand::neg_s);
}
// ${SMs::Calc::SM::operand::neg}
//${SMs::Calc::SM::operand::neg}
QP::QState Calc::SM_operand::neg_x(Calc * const me) {
BSP_message("operand::neg-EXIT;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_EXIT(&SM_operand::neg_s);
}
// ${SMs::Calc::SM::operand::neg}
//${SMs::Calc::SM::operand::neg}
QP::QState Calc::SM_operand::neg(Calc * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${SMs::Calc::SM::operand::neg::DIGIT_0}
//${SMs::Calc::SM::operand::neg::DIGIT_0}
case DIGIT_0_SIG: {
static struct {
QP::QMState const *target;
@ -1126,7 +1130,7 @@ QP::QState Calc::SM_operand::neg(Calc * const me, QP::QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
// ${SMs::Calc::SM::operand::neg::DIGIT_1_9}
//${SMs::Calc::SM::operand::neg::DIGIT_1_9}
case DIGIT_1_9_SIG: {
static struct {
QP::QMState const *target;
@ -1143,7 +1147,7 @@ QP::QState Calc::SM_operand::neg(Calc * const me, QP::QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
// ${SMs::Calc::SM::operand::neg::POINT}
//${SMs::Calc::SM::operand::neg::POINT}
case POINT_SIG: {
static struct {
QP::QMState const *target;
@ -1160,14 +1164,14 @@ QP::QState Calc::SM_operand::neg(Calc * const me, QP::QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
// ${SMs::Calc::SM::operand::neg::OPER}
//${SMs::Calc::SM::operand::neg::OPER}
case OPER_SIG: {
// ${SMs::Calc::SM::operand::neg::OPER::[e->key=='-']}
//${SMs::Calc::SM::operand::neg::OPER::[e->key=='-']}
if (Q_EVT_CAST(CalcEvt)->key_code == KEY_MINUS) {
;
status_ = QM_HANDLED();
}
// ${SMs::Calc::SM::operand::neg::OPER::[else]}
//${SMs::Calc::SM::operand::neg::OPER::[else]}
else {
status_ = QM_HANDLED();
}
@ -1181,4 +1185,4 @@ QP::QState Calc::SM_operand::neg(Calc * const me, QP::QEvt const * const e) {
(void)me; // avoid compiler warning in case 'me' is not used
return status_;
}
//$enddef${SMs::Calc} ########################################################

View File

@ -1,8 +1,9 @@
//****************************************************************************
// Model: calc1_sub.qm
// File: ./calc1_sub.h
//$file${.::calc1_sub.h} #####################################################
//
// This code has been generated by QM tool (see state-machine.com/qm).
// Model: calc1_sub.qm
// File: C:/qp_lab/qpcpp/examples/win32/calc1_sub/calc1_sub.h
//
// This code has been generated by QM tool (https://state-machine.com/qm).
// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
//
// This code is covered by the following QP license:
@ -15,8 +16,8 @@
// the generated code is still licensed under the terms of GPL.
// Please submit request for extension of the evaluaion period at:
// https://state-machine.com/licensing/#RequestForm
//****************************************************************************
//${.::calc1_sub.h} ..........................................................
//
//$endhead${.::calc1_sub.h} ##################################################
#ifndef calc1_sub_h
#define calc1_sub_h
@ -31,18 +32,14 @@ enum CalcSignals {
OFF_SIG
};
#if ((QP_VERSION < 591) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8)))
#error qpcpp version 5.9.1 or higher required
#endif
//$declare${Events::CalcEvt} #################################################
//${Events::CalcEvt} .........................................................
class CalcEvt : public QP::QEvt {
public:
uint8_t key_code;
};
//$enddecl${Events::CalcEvt} #################################################
extern QP::QMsm * const the_calc; // "opaque" pointer to calculator MSM
#endif // calc1_sub_h
#endif // calc1_sub_h

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<model version="4.0.3" links="0">
<model version="4.1.0" links="0">
<documentation>Calc is the model of the Calculator described in Chapter 4 of PSiCC2.</documentation>
<framework name="qpcpp" license="../../../QPCPP-EVAL-171231.qlc"/>
<package name="Events" stereotype="0x01">

View File

@ -0,0 +1,264 @@
##############################################################################
# Product: Makefile for QP/C++, DPP console, Win32, MinGW
# Last updated for version 6.0.0
# Last updated on 2017-10-27
#
# Q u a n t u m L e a P s
# ---------------------------
# innovating embedded systems
#
# Copyright (C) Quantum Leaps, LLC. All rights reserved.
#
# This program is open source software: you can redistribute it and/or
# modify it under the terms of the GNU General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Alternatively, this program may be distributed and modified under the
# terms of Quantum Leaps commercial licenses, which expressly supersede
# the GNU General Public License and are specifically designed for
# licensees interested in retaining the proprietary status of their code.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Contact information:
# https://state-machine.com
# mailto:info@state-machine.com
##############################################################################
# examples of invoking this Makefile:
# building configurations: Debug (default), Release, and Spy
# make
# make CONF=rel
# make CONF=spy
#
# cleaning configurations: Debug (default), Release, and Spy
# make clean
# make CONF=rel clean
# make CONF=spy clean
#
# NOTE:
# To use this Makefile on Windows, you will need the GNU make utility, which
# is included in the Qtools collection for Windows, see:
# http://sourceforge.net/projects/qpc/files/Qtools/
#
#-----------------------------------------------------------------------------
# project name
#
PROJECT := dpp
#-----------------------------------------------------------------------------
# project directories
#
# location of the QP/C++ framework (if not provided in an environemnt var.)
ifeq ($(QPCPP),)
QPCPP := ../../..
endif
# QP port used in this project
QP_PORT_DIR := $(QPCPP)/ports/win32
# list of all source directories used by this project
VPATH = . \
cont \
comp
# list of all include directories needed by this project
INCLUDES = \
-I. \
-I$(QPCPP)/include \
-Icont
# list of resource include directories needed by this project
RCINCLUDES = \
-IRes
#-----------------------------------------------------------------------------
# files
#
# C source files...
C_SRCS :=
# C++ source files...
CPP_SRCS := \
bsp.cpp \
main.cpp \
philo.cpp \
table.cpp
# Resource files...
RC_SRCS :=
LIB_DIRS :=
LIBS :=
# defines...
# QP_API_VERSION controls the QP API compatibility; 9999 means the latest API
DEFINES := -DQP_API_VERSION=9999
#-----------------------------------------------------------------------------
# MinGW toolset (NOTE: assumed to be on your PATH)
#
# NOTE:
# MinGW toolset is included in the Qtools collection for Windows, see:
# http://sourceforge.net/projects/qpc/files/Qtools/
#
# NOTE:
# This Makefile assumes that the windres utility is available on the
# PATH (NOTE: windres is available in the Qtools collection for Windows)
#
CC := gcc
CPP := g++
#LINK := gcc # for C programs
LINK := g++ # for C++ programs
RC := windres
# basic utilities (included in Qtools for Windows), see:
# http://sourceforge.net/projects/qpc/files/Qtools
MKDIR := mkdir
RM := rm
#-----------------------------------------------------------------------------
# build options for various configurations
#
ifeq (rel, $(CONF)) # Release configuration ..................................
BIN_DIR := rel
CFLAGS = -ffunction-sections -fdata-sections \
-Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG
CPPFLAGS = -ffunction-sections -fdata-sections \
-Os -Wall -W $(INCLUDES) $(DEFINES) -DNDEBUG
else ifeq (spy, $(CONF)) # Spy configuration ................................
# make sure that QTOOLS exists...
ifeq ("$(wildcard $(QTOOLS))","")
$(error QTOOLS not found. Please install Qtools and define QTOOLS env. variable)
endif
INCLUDES += -I$(QTOOLS)/qspy/include
VPATH += $(QTOOLS)/qspy/source
C_SRCS += qspy.c
BIN_DIR := spy
CFLAGS = -g -ffunction-sections -fdata-sections \
-O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY
CPPFLAGS = -g -ffunction-sections -fdata-sections \
-O -Wall -W $(INCLUDES) $(DEFINES) -DQ_SPY
else # default Debug configuration ..........................................
BIN_DIR := dbg
CFLAGS = -g -ffunction-sections -fdata-sections \
-O -Wall -W $(INCLUDES) $(DEFINES)
CPPFLAGS = -g -ffunction-sections -fdata-sections \
-O -Wall -W $(INCLUDES) $(DEFINES)
endif # .....................................................................
LINKFLAGS := -Wl,-Map,$(BIN_DIR)/$(PROJECT).map,--cref,--gc-sections
# is it a GUI application (any GUI resources provided?) ...
ifneq (,$(RC_SRCS))
LINKFLAGS += -mwindows
DEFINES += -DQWIN_GUI
endif
#-----------------------------------------------------------------------------
# combine all the soruces...
INCLUDES += -I$(QP_PORT_DIR)
LIB_DIRS += -L$(QP_PORT_DIR)/$(BIN_DIR)
LIBS += -lqp
C_OBJS := $(patsubst %.c, %.o, $(C_SRCS))
CPP_OBJS := $(patsubst %.cpp, %.o, $(CPP_SRCS))
RC_OBJS := $(patsubst %.rc, %.o, $(RC_SRCS))
TARGET_BIN := $(BIN_DIR)/$(PROJECT).bin
TARGET_EXE := $(BIN_DIR)/$(PROJECT).exe
C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS))
C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT))
CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS))
CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT))
RC_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(RC_OBJS))
# create $(BIN_DIR) if it does not exist
ifeq ("$(wildcard $(BIN_DIR))","")
$(shell $(MKDIR) $(BIN_DIR))
endif
#-----------------------------------------------------------------------------
# rules
#
all: $(TARGET_EXE)
#all: $(TARGET_BIN)
$(TARGET_BIN): $(TARGET_EXE)
$(BIN) -O binary $< $@
$(TARGET_EXE) : $(C_OBJS_EXT) $(CPP_OBJS_EXT) $(RC_OBJS_EXT)
$(CPP) $(CPPFLAGS) -c $(QPCPP)/include/qstamp.cpp -o $(BIN_DIR)/qstamp.o
$(LINK) $(LINKFLAGS) $(LIB_DIRS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS)
$(BIN_DIR)/%.d : %.cpp
$(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@
$(BIN_DIR)/%.d : %.c
$(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@
$(BIN_DIR)/%.o : %.cpp
$(CPP) $(CPPFLAGS) -c $< -o $@
$(BIN_DIR)/%.o : %.c
$(CC) $(CFLAGS) -c $< -o $@
$(BIN_DIR)/%.o : %.rc
$(RC) $(RCINCLUDES) -i $< -o $@
# include dependency files only if our goal depends on their existence
ifneq ($(MAKECMDGOALS),clean)
ifneq ($(MAKECMDGOALS),show)
-include $(C_DEPS_EXT) $(CPP_DEPS_EXT)
endif
endif
.PHONY : clean
clean:
-$(RM) $(BIN_DIR)/*.o \
$(BIN_DIR)/*.d \
$(BIN_DIR)/*.exe \
$(BIN_DIR)/*.map
show:
@echo PROJECT = $(PROJECT)
@echo CONF = $(CONF)
@echo VPATH = $(VPATH)
@echo C_SRCS = $(C_SRCS)
@echo CPP_SRCS = $(CPP_SRCS)
@echo C_OBJS_EXT = $(C_OBJS_EXT)
@echo C_DEPS_EXT = $(C_DEPS_EXT)
@echo CPP_DEPS_EXT = $(CPP_DEPS_EXT)
@echo CPP_OBJS_EXT = $(CPP_OBJS_EXT)
@echo RC_OBJS_EXT = $(RC_OBJS_EXT)
@echo LIB_DIRS = $(LIB_DIRS)
@echo LIBS = $(LIBS)

View File

@ -0,0 +1,248 @@
//****************************************************************************
// Product: DPP example (console)
// Last Updated for Version: 6.0.0
// Date of the Last Update: 2017-10-28
//
// Q u a n t u m L e a P s
// ---------------------------
// innovating embedded systems
//
// Copyright (C) Quantum Leaps, LLC. All rights reserved.
//
// This program is open source software: you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Alternatively, this program may be distributed and modified under the
// terms of Quantum Leaps commercial licenses, which expressly supersede
// the GNU General Public License and are specifically designed for
// licensees interested in retaining the proprietary status of their code.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// Contact information:
// https://state-machine.com
// mailto:info@state-machine.com
//****************************************************************************
#include "qpcpp.h"
#include "dpp.h"
#include "bsp.h"
#include <conio.h>
#include <stdio.h>
#ifdef Q_SPY
#include <time.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h> // Win32 API
#include "qspy.h" // QSPY interface
#endif
Q_DEFINE_THIS_FILE
//****************************************************************************
namespace DPP {
// local variables -----------------------------------------------------------
static uint32_t l_rnd; // random seed
#ifdef Q_SPY
enum {
PHILO_STAT = QP::QS_USER
};
static bool l_isRunning;
static uint8_t const l_clock_tick = 0U;
#endif
//............................................................................
void BSP::init(void) {
printf("Dining Philosopher Problem example"
"\nQP %s\n"
"Press 'p' to pause\n"
"Press 's' to serve\n"
"Press ESC to quit...\n",
QP::versionStr);
BSP::randomSeed(1234U);
Q_ALLEGE(QS_INIT((void *)0));
QS_OBJ_DICTIONARY(&l_clock_tick); // must be called *after* QF::init()
QS_USR_DICTIONARY(PHILO_STAT);
}
//............................................................................
void BSP::terminate(int16_t result) {
(void)result;
#ifdef Q_SPY
l_isRunning = false; // stop the QS output thread
#endif
QP::QF::stop(); // stop the main "ticker thread"
}
//............................................................................
void BSP::displayPhilStat(uint8_t n, char const *stat) {
printf("Philosopher %2d is %s\n", (int)n, stat);
QS_BEGIN(PHILO_STAT, (void*)0) // application-specific record begin
QS_U8(1, n); // Philosopher number
QS_STR(stat); // Philosopher status
QS_END()
}
//............................................................................
void BSP::displayPaused(uint8_t paused) {
printf("Paused is %s\n", paused ? "ON" : "OFF");
}
//............................................................................
uint32_t BSP::random(void) { // a very cheap pseudo-random-number generator
// "Super-Duper" Linear Congruential Generator (LCG)
// LCG(2^32, 3*7*11*13*23, 0, seed)
//
l_rnd = l_rnd * (3U*7U*11U*13U*23U);
return l_rnd >> 8;
}
//............................................................................
void BSP::randomSeed(uint32_t seed) {
l_rnd = seed;
}
} // namespace DPP
//****************************************************************************
namespace QP {
//............................................................................
void QF::onStartup(void) {
QF_setTickRate(DPP::BSP::TICKS_PER_SEC); // set the desired tick rate
}
//............................................................................
void QF::onCleanup(void) {
}
//............................................................................
void QF_onClockTick(void) {
QF::TICK_X(0U, &DPP::l_clock_tick); // process time events at rate 0
if (_kbhit()) { // any key pressed?
int ch = _getch();
if (ch == '\33') { // see if the ESC key pressed
DPP::BSP::terminate(0);
}
else if (ch == 'p') {
QF::PUBLISH(Q_NEW(QEvt, DPP::PAUSE_SIG), &DPP::l_clock_tick);
}
else if (ch == 's') {
QF::PUBLISH(Q_NEW(QEvt, DPP::SERVE_SIG), &DPP::l_clock_tick);
}
}
}
//............................................................................
extern "C" void Q_onAssert(char const * const module, int loc) {
QS_ASSERTION(module, loc, 10000U); // report assertion to QS
fprintf(stderr, "Assertion failed in %s, location %d", module, loc);
QF::stop();
}
//----------------------------------------------------------------------------
#ifdef Q_SPY // define QS callbacks
//............................................................................
static DWORD WINAPI idleThread(LPVOID par) { // signature for CreateThread()
(void)par;
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_IDLE);
DPP::l_isRunning = true;
while (DPP::l_isRunning) {
uint16_t nBytes = 256;
uint8_t const *block;
QF_CRIT_ENTRY(dummy);
block = QS::getBlock(&nBytes);
QF_CRIT_EXIT(dummy);
if (block != (uint8_t *)0) {
QSPY_parse(block, nBytes);
}
Sleep(50); // wait for a while
}
return 0; // return success
}
//............................................................................
bool QS::onStartup(void const *arg) {
static uint8_t qsBuf[4*1024]; // 4K buffer for Quantum Spy
initBuf(qsBuf, sizeof(qsBuf));
(void)arg;
QSPY_config(QP_VERSION, // version
QS_OBJ_PTR_SIZE, // objPtrSize
QS_FUN_PTR_SIZE, // funPtrSize
QS_TIME_SIZE, // tstampSize
Q_SIGNAL_SIZE, // sigSize,
QF_EVENT_SIZ_SIZE, // evtSize
QF_EQUEUE_CTR_SIZE, // queueCtrSize
QF_MPOOL_CTR_SIZE, // poolCtrSize
QF_MPOOL_SIZ_SIZE, // poolBlkSize
QF_TIMEEVT_CTR_SIZE,// tevtCtrSize
(void *)0, // matFile,
(void *)0,
(QSPY_CustParseFun)0); // customized parser function
// set up the QS filters...
QS_FILTER_ON(QS_QEP_STATE_ENTRY);
QS_FILTER_ON(QS_QEP_STATE_EXIT);
QS_FILTER_ON(QS_QEP_STATE_INIT);
QS_FILTER_ON(QS_QEP_INIT_TRAN);
QS_FILTER_ON(QS_QEP_INTERN_TRAN);
QS_FILTER_ON(QS_QEP_TRAN);
QS_FILTER_ON(QS_QEP_IGNORED);
QS_FILTER_ON(QS_QEP_DISPATCH);
QS_FILTER_ON(QS_QEP_UNHANDLED);
QS_FILTER_ON(QS_QF_ACTIVE_POST_FIFO);
QS_FILTER_ON(QS_QF_ACTIVE_POST_LIFO);
QS_FILTER_ON(QS_QF_PUBLISH);
QS_FILTER_ON(DPP::PHILO_STAT);
return CreateThread(NULL, 1024, &idleThread, (void *)0, 0, NULL)
!= (HANDLE)0; // return the status of creating the idle thread
}
//............................................................................
void QS::onCleanup(void) {
DPP::l_isRunning = false;
QSPY_stop();
}
//............................................................................
void QS::onFlush(void) {
for (;;) {
uint16_t nBytes = 1024U;
uint8_t const *block;
QF_CRIT_ENTRY(dummy);
block = getBlock(&nBytes);
QF_CRIT_EXIT(dummy);
if (block != static_cast<uint8_t const *>(0)) {
QSPY_parse(block, nBytes);
nBytes = 1024U;
}
else {
break;
}
}
}
//............................................................................
QSTimeCtr QS::onGetTime(void) {
return (QSTimeCtr)clock();
}
//............................................................................
extern "C" void QSPY_onPrintLn(void) {
fputs(QSPY_line, stdout);
fputc('\n', stdout);
}
#endif // Q_SPY
//----------------------------------------------------------------------------
} // namespace QP

View File

@ -0,0 +1,59 @@
//****************************************************************************
// Product: DPP example
// Last Updated for Version: 5.6.0
// Date of the Last Update: 2015-12-28
//
// Q u a n t u m L e a P s
// ---------------------------
// innovating embedded systems
//
// Copyright (C) Quantum Leaps, LLC. All rights reserved.
//
// This program is open source software: you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Alternatively, this program may be distributed and modified under the
// terms of Quantum Leaps commercial licenses, which expressly supersede
// the GNU General Public License and are specifically designed for
// licensees interested in retaining the proprietary status of their code.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// Contact information:
// https://state-machine.com
// mailto:info@state-machine.com
//****************************************************************************
#ifndef bsp_h
#define bsp_h
namespace DPP {
class BSP {
public:
enum { TICKS_PER_SEC = 100 };
static void init(void);
static void displayPaused(uint8_t const paused);
static void displayPhilStat(uint8_t const n, char_t const *stat);
static void terminate(int16_t const result);
static void randomSeed(uint32_t const seed); // random seed
static uint32_t random(void); // pseudo-random generator
// for testing...
static void wait4SW1(void);
static void ledOn(void);
static void ledOff(void);
};
} // namespace DPP
#endif // bsp_h

View File

@ -0,0 +1,105 @@
<?xml version="1.0" encoding="UTF-8"?>
<package name="Comp" stereotype="0x02" namespace="DPP::">
<class name="Philo" superclass="qpcpp::QHsm">
<attribute name="m_timeEvt" type="CompTimeEvt" visibility="0x02" properties="0x00"/>
<operation name="Philo" type="" visibility="0x00" properties="0x00">
<code> : QHsm(Q_STATE_CAST(&amp;Philo::initial)),
m_timeEvt(AO_Table, this, TIMEOUT_SIG, 0U)</code>
</operation>
<statechart>
<initial target="../1">
<action>static bool registered = false; // starts off with 0, per C-standard
(void)e; // suppress the compiler warning about unused parameter
if (!registered) {
registered = true;
QS_FUN_DICTIONARY(&amp;Philo::initial);
QS_FUN_DICTIONARY(&amp;Philo::thinking);
QS_FUN_DICTIONARY(&amp;Philo::hungry);
QS_FUN_DICTIONARY(&amp;Philo::eating);
}
QS_SIG_DICTIONARY(HUNGRY_SIG, me); // signal for each Philos</action>
<initial_glyph conn="2,3,5,1,20,5,-4">
<action box="0,-2,6,2"/>
</initial_glyph>
</initial>
<state name="thinking">
<entry>me-&gt;m_timeEvt.armX(think_time(), 0U);</entry>
<exit>(void)me-&gt;m_timeEvt.disarm();</exit>
<tran trig="TIMEOUT" target="../../2">
<tran_glyph conn="2,14,3,1,20,12,-4">
<action box="0,-2,10,2"/>
</tran_glyph>
</tran>
<tran trig="TEST">
<tran_glyph conn="2,18,3,-1,12">
<action box="0,-2,11,4"/>
</tran_glyph>
</tran>
<state_glyph node="2,5,16,17">
<entry box="1,2,5,2"/>
<exit box="1,4,5,2"/>
</state_glyph>
</state>
<state name="hungry">
<entry>TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG);
pe-&gt;philo = me;
AO_Table-&gt;postLIFO(pe);</entry>
<tran trig="EAT" target="../../3">
<tran_glyph conn="2,31,3,1,19,9,-3">
<action box="0,-2,14,2"/>
</tran_glyph>
</tran>
<state_glyph node="2,24,16,12">
<entry box="1,2,5,2"/>
</state_glyph>
</state>
<state name="eating">
<entry>me-&gt;m_timeEvt.armX(eat_time(), 0U);</entry>
<exit>(void)me-&gt;m_timeEvt.disarm();
// asynchronously post event to the Container
TableEvt *pe = Q_NEW(TableEvt, DONE_SIG);
pe-&gt;philo = me;
AO_Table-&gt;postLIFO(pe);</exit>
<tran trig="TIMEOUT" target="../../1">
<tran_glyph conn="2,48,3,1,22,-38,-6">
<action box="0,-2,12,2"/>
</tran_glyph>
</tran>
<state_glyph node="2,38,16,14">
<entry box="1,2,5,2"/>
<exit box="1,4,5,2"/>
</state_glyph>
</state>
<state_diagram size="28,54"/>
</statechart>
</class>
<directory name=".">
<file name="philo.cpp">
<text>#include &quot;qpcpp.h&quot;
#include &quot;dpp.h&quot;
#include &quot;bsp.h&quot;
Q_DEFINE_THIS_FILE
namespace DPP {
// helper function to provide a randomized think time for Philos
inline QP::QTimeEvtCtr think_time() {
return static_cast&lt;QP::QTimeEvtCtr&gt;((BSP::random() % BSP::TICKS_PER_SEC)
+ (BSP::TICKS_PER_SEC/2U));
}
// helper function to provide a randomized eat time for Philos
inline QP::QTimeEvtCtr eat_time() {
return static_cast&lt;QP::QTimeEvtCtr&gt;((BSP::random() % BSP::TICKS_PER_SEC)
+ BSP::TICKS_PER_SEC);
}
} // namespace DPP
// Philo definition ----------------------------------------------------------
$define(Comp::Philo)</text>
</file>
</directory>
</package>

View File

@ -0,0 +1,162 @@
//$file${Comp::.::philo.cpp} #################################################
//
// Model: dpp.qm
// File: C:/qp_lab/qpcpp/examples/win32/dpp-comp/comp/philo.cpp
//
// This code has been generated by QM tool (https://state-machine.com/qm).
// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
//
// This program is open source software: you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
// by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
//$endhead${Comp::.::philo.cpp} ##############################################
#include "qpcpp.h"
#include "dpp.h"
#include "bsp.h"
Q_DEFINE_THIS_FILE
namespace DPP {
// helper function to provide a randomized think time for Philos
inline QP::QTimeEvtCtr think_time() {
return static_cast<QP::QTimeEvtCtr>((BSP::random() % BSP::TICKS_PER_SEC)
+ (BSP::TICKS_PER_SEC/2U));
}
// helper function to provide a randomized eat time for Philos
inline QP::QTimeEvtCtr eat_time() {
return static_cast<QP::QTimeEvtCtr>((BSP::random() % BSP::TICKS_PER_SEC)
+ BSP::TICKS_PER_SEC);
}
} // namespace DPP
// Philo definition ----------------------------------------------------------
//$define${Comp::Philo} ######################################################
// Check for the minimum required QP version
#if ((QP_VERSION < 601) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8)))
#error qpcpp version 6.0.1 or higher required
#endif
namespace DPP {
//${Comp::Philo} .............................................................
//${Comp::Philo::Philo} ......................................................
Philo::Philo()
: QHsm(Q_STATE_CAST(&Philo::initial)),
m_timeEvt(AO_Table, this, TIMEOUT_SIG, 0U)
{}
//${Comp::Philo::SM} .........................................................
QP::QState Philo::initial(Philo * const me, QP::QEvt const * const e) {
//${Comp::Philo::SM::initial}
static bool registered = false; // starts off with 0, per C-standard
(void)e; // suppress the compiler warning about unused parameter
if (!registered) {
registered = true;
QS_FUN_DICTIONARY(&Philo::initial);
QS_FUN_DICTIONARY(&Philo::thinking);
QS_FUN_DICTIONARY(&Philo::hungry);
QS_FUN_DICTIONARY(&Philo::eating);
}
QS_SIG_DICTIONARY(HUNGRY_SIG, me); // signal for each Philos
return Q_TRAN(&thinking);
}
//${Comp::Philo::SM::thinking} ...............................................
QP::QState Philo::thinking(Philo * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
//${Comp::Philo::SM::thinking}
case Q_ENTRY_SIG: {
me->m_timeEvt.armX(think_time(), 0U);
status_ = Q_HANDLED();
break;
}
//${Comp::Philo::SM::thinking}
case Q_EXIT_SIG: {
(void)me->m_timeEvt.disarm();
status_ = Q_HANDLED();
break;
}
//${Comp::Philo::SM::thinking::TIMEOUT}
case TIMEOUT_SIG: {
status_ = Q_TRAN(&hungry);
break;
}
//${Comp::Philo::SM::thinking::TEST}
case TEST_SIG: {
status_ = Q_HANDLED();
break;
}
default: {
status_ = Q_SUPER(&top);
break;
}
}
return status_;
}
//${Comp::Philo::SM::hungry} .................................................
QP::QState Philo::hungry(Philo * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
//${Comp::Philo::SM::hungry}
case Q_ENTRY_SIG: {
TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG);
pe->philo = me;
AO_Table->postLIFO(pe);
status_ = Q_HANDLED();
break;
}
//${Comp::Philo::SM::hungry::EAT}
case EAT_SIG: {
status_ = Q_TRAN(&eating);
break;
}
default: {
status_ = Q_SUPER(&top);
break;
}
}
return status_;
}
//${Comp::Philo::SM::eating} .................................................
QP::QState Philo::eating(Philo * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
//${Comp::Philo::SM::eating}
case Q_ENTRY_SIG: {
me->m_timeEvt.armX(eat_time(), 0U);
status_ = Q_HANDLED();
break;
}
//${Comp::Philo::SM::eating}
case Q_EXIT_SIG: {
(void)me->m_timeEvt.disarm();
// asynchronously post event to the Container
TableEvt *pe = Q_NEW(TableEvt, DONE_SIG);
pe->philo = me;
AO_Table->postLIFO(pe);
status_ = Q_HANDLED();
break;
}
//${Comp::Philo::SM::eating::TIMEOUT}
case TIMEOUT_SIG: {
status_ = Q_TRAN(&thinking);
break;
}
default: {
status_ = Q_SUPER(&top);
break;
}
}
return status_;
}
} // namespace DPP//$enddef${Comp::Philo} ######################################################

View File

@ -0,0 +1,337 @@
<?xml version="1.0" encoding="UTF-8"?>
<package name="Cont" stereotype="0x02" namespace="DPP::">
<class name="TableEvt" superclass="qpcpp::QEvt">
<attribute name="philo" type="DPP::Philo *" visibility="0x00" properties="0x00"/>
</class>
<class name="CompTimeEvt" superclass="qpcpp::QTimeEvt">
<documentation>Specialized time event for components. The time evnet can be owned by a component and can dispatch itself to the component.</documentation>
<attribute name="m_comp" type="QP::QHsm *" visibility="0x00" properties="0x00"/>
<operation name="CompTimeEvt" type="" visibility="0x00" properties="0x00">
<documentation>The constructor to initialize a Component Time Event.
When creating a time event, you must commit it to a specific active object 'act', event signal 'sig', and tick rate 'tickRate'. You cannot change these attributes later.</documentation>
<parameter name="act" type="QP::QActive *"/>
<parameter name="comp" type="QP::QHsm *"/>
<parameter name="sig" type="enum_t const"/>
<parameter name="tickRate" type="uint_fast8_t const"/>
<code> : QTimeEvt(act, sig, tickRate)
m_comp = comp;</code>
</operation>
<operation name="dispatchToComp" type="void" visibility="0x00" properties="0x0a">
<code>m_comp-&gt;dispatch(this);</code>
</operation>
</class>
<class name="Table" superclass="qpcpp::QActive">
<attribute name="m_philo[N_PHILO]" type="Philo" visibility="0x02" properties="0x00">
<documentation>Embedded component state machine objects</documentation>
</attribute>
<attribute name="m_fork[N_PHILO]" type="uint8_t" visibility="0x02" properties="0x00"/>
<attribute name="m_isHungry[N_PHILO]" type="bool" visibility="0x02" properties="0x00"/>
<operation name="Table" type="" visibility="0x00" properties="0x00">
<code> : QActive(Q_STATE_CAST(&amp;Table::initial))
for (uint8_t n = 0U; n &lt; N_PHILO; ++n) {
m_fork[n] = FREE;
m_isHungry[n] = false;
}</code>
</operation>
<statechart>
<initial target="../1/3">
<action>(void)e; // suppress the compiler warning about unused parameter
QS_OBJ_DICTIONARY(&amp;l_table);
QS_FUN_DICTIONARY(&amp;Table::initial);
QS_FUN_DICTIONARY(&amp;Table::active);
QS_FUN_DICTIONARY(&amp;Table::serving);
QS_FUN_DICTIONARY(&amp;Table::paused);
QS_SIG_DICTIONARY(DONE_SIG, (void *)0); // global signals
QS_SIG_DICTIONARY(EAT_SIG, (void *)0);
QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0);
QS_SIG_DICTIONARY(SERVE_SIG, (void *)0);
QS_SIG_DICTIONARY(TEST_SIG, (void *)0);
QS_SIG_DICTIONARY(TIMEOUT_SIG, me); // signal just for Table
QS_SIG_DICTIONARY(HUNGRY_SIG, me); // signal just for Table
me-&gt;subscribe(PAUSE_SIG);
me-&gt;subscribe(SERVE_SIG);
me-&gt;subscribe(TEST_SIG);
for (uint8_t n = 0U; n &lt; N_PHILO; ++n) {
me-&gt;m_philo[n].init(); // top-most initial tran.
me-&gt;m_fork[n] = FREE;
me-&gt;m_isHungry[n] = false;
BSP::displayPhilStat(n, THINKING);
}</action>
<initial_glyph conn="3,3,5,1,45,23,-10">
<action box="0,-2,6,2"/>
</initial_glyph>
</initial>
<state name="active">
<tran trig="TIMEOUT">
<action>Q_EVT_CAST(CompTimeEvt)-&gt;dispatchToComp();</action>
<tran_glyph conn="2,11,3,-1,14">
<action box="0,-2,11,4"/>
</tran_glyph>
</tran>
<tran trig="EAT">
<action>Q_ERROR();</action>
<tran_glyph conn="2,15,3,-1,14">
<action box="0,-2,10,4"/>
</tran_glyph>
</tran>
<tran trig="TEST">
<tran_glyph conn="2,20,3,-1,14">
<action box="0,-2,10,2"/>
</tran_glyph>
</tran>
<state name="serving">
<entry brief="give pending permitions to eat">for (uint8_t n = 0U; n &lt; N_PHILO; ++n) { // give permissions to eat...
if (me-&gt;m_isHungry[n]
&amp;&amp; (me-&gt;m_fork[LEFT(n)] == FREE)
&amp;&amp; (me-&gt;m_fork[n] == FREE))
{
me-&gt;m_fork[LEFT(n)] = USED;
me-&gt;m_fork[n] = USED;
// synchronoulsy dispatch EAT event to the Philo component
TableEvt evt;
evt.sig = EAT_SIG;
evt.philo = &amp;me-&gt;m_philo[n];
me-&gt;m_philo[n].dispatch(&amp;evt);
me-&gt;m_isHungry[n] = false;
BSP::displayPhilStat(n, EATING);
}
}</entry>
<tran trig="HUNGRY">
<action>// find the index of the Philo from the event
uint8_t n = (Q_EVT_CAST(TableEvt)-&gt;philo - &amp;me-&gt;m_philo[0]);
// philo ID must be in range and he must be not hungry
Q_ASSERT((n &lt; N_PHILO) &amp;&amp; (!me-&gt;m_isHungry[n]));
BSP::displayPhilStat(n, HUNGRY);
uint8_t m = LEFT(n);</action>
<choice>
<guard brief="both free">(me-&gt;m_fork[m] == FREE) &amp;&amp; (me-&gt;m_fork[n] == FREE)</guard>
<action>me-&gt;m_fork[m] = USED;
me-&gt;m_fork[n] = USED;
// synchronoulsy dispatch EAT event to the Philo component
TableEvt evt;
evt.sig = EAT_SIG;
evt.philo = &amp;me-&gt;m_philo[n];
me-&gt;m_philo[n].dispatch(&amp;evt);
BSP::displayPhilStat(n, EATING);</action>
<choice_glyph conn="19,31,5,-1,10">
<action box="1,0,10,2"/>
</choice_glyph>
</choice>
<choice>
<guard>else</guard>
<action>me-&gt;m_isHungry[n] = true;</action>
<choice_glyph conn="19,31,4,-1,5,10">
<action box="1,5,6,2"/>
</choice_glyph>
</choice>
<tran_glyph conn="4,31,3,-1,15">
<action box="0,-2,8,2"/>
</tran_glyph>
</tran>
<tran trig="DONE">
<action>// find the index of the Philo from the event
uint8_t n = (Q_EVT_CAST(TableEvt)-&gt;philo - &amp;me-&gt;m_philo[0]);
// philo ID must be in range and he must be not hungry
Q_ASSERT((n &lt; N_PHILO) &amp;&amp; (!me-&gt;m_isHungry[n]));
BSP::displayPhilStat(n, THINKING);
uint8_t m = LEFT(n);
// both forks of Phil[n] must be used
Q_ASSERT((me-&gt;m_fork[n] == USED) &amp;&amp; (me-&gt;m_fork[m] == USED));
me-&gt;m_fork[m] = FREE;
me-&gt;m_fork[n] = FREE;
m = RIGHT(n); // check the right neighbor
if (me-&gt;m_isHungry[m] &amp;&amp; (me-&gt;m_fork[m] == FREE)) {
me-&gt;m_fork[n] = USED;
me-&gt;m_fork[m] = USED;
me-&gt;m_isHungry[m] = false;
// synchronoulsy dispatch EAT event to the Philo component
TableEvt evt;
evt.sig = EAT_SIG;
evt.philo = &amp;me-&gt;m_philo[m];
me-&gt;m_philo[m].dispatch(&amp;evt);
BSP::displayPhilStat(m, EATING);
}
m = LEFT(n); // check the left neighbor
n = LEFT(m); // left fork of the left neighbor
if (me-&gt;m_isHungry[m] &amp;&amp; (me-&gt;m_fork[n] == FREE)) {
me-&gt;m_fork[m] = USED;
me-&gt;m_fork[n] = USED;
me-&gt;m_isHungry[m] = false;
// synchronoulsy dispatch EAT event to the Philo component
TableEvt evt;
evt.sig = EAT_SIG;
evt.philo = &amp;me-&gt;m_philo[m];
me-&gt;m_philo[m].dispatch(&amp;evt);
BSP::displayPhilStat(m, EATING);
}</action>
<tran_glyph conn="4,39,3,-1,15">
<action box="0,-2,6,2"/>
</tran_glyph>
</tran>
<tran trig="EAT">
<action>Q_ERROR();</action>
<tran_glyph conn="4,42,3,-1,15">
<action box="0,-2,12,4"/>
</tran_glyph>
</tran>
<tran trig="PAUSE" target="../../4">
<tran_glyph conn="4,46,3,1,37,6,-3">
<action box="0,-2,7,2"/>
</tran_glyph>
</tran>
<state_glyph node="4,24,34,24">
<entry box="1,2,27,2"/>
</state_glyph>
</state>
<state name="paused">
<entry>BSP::displayPaused(1U);</entry>
<exit>BSP::displayPaused(0U);</exit>
<tran trig="SERVE" target="../../3">
<tran_glyph conn="4,62,3,1,39,-29,-5">
<action box="0,-2,12,2"/>
</tran_glyph>
</tran>
<tran trig="HUNGRY">
<action>// find the index of the Philo from the event
uint8_t n = (Q_EVT_CAST(TableEvt)-&gt;philo - &amp;me-&gt;m_philo[0]);
// philo ID must be in range and he must be not hungry
Q_ASSERT((n &lt; N_PHILO) &amp;&amp; (!me-&gt;m_isHungry[n]));
me-&gt;m_isHungry[n] = true;
BSP::displayPhilStat(n, HUNGRY);</action>
<tran_glyph conn="4,65,3,-1,15">
<action box="0,-2,9,2"/>
</tran_glyph>
</tran>
<tran trig="DONE">
<action>// find the index of the Philo from the event
uint8_t n = (Q_EVT_CAST(TableEvt)-&gt;philo - &amp;me-&gt;m_philo[0]);
// philo ID must be in range and he must be not hungry
Q_ASSERT((n &lt; N_PHILO) &amp;&amp; (!me-&gt;m_isHungry[n]));
BSP::displayPhilStat(n, THINKING);
uint8_t m = LEFT(n);
// both forks of Phil[n] must be used
Q_ASSERT((me-&gt;m_fork[n] == USED) &amp;&amp; (me-&gt;m_fork[m] == USED));
me-&gt;m_fork[m] = FREE;
me-&gt;m_fork[n] = FREE;</action>
<tran_glyph conn="4,68,3,-1,15">
<action box="0,-2,6,2"/>
</tran_glyph>
</tran>
<state_glyph node="4,50,34,20">
<entry box="1,2,18,4"/>
<exit box="1,6,18,4"/>
</state_glyph>
</state>
<state_glyph node="2,5,44,67"/>
</state>
<state_diagram size="50,74"/>
</statechart>
</class>
<attribute name="AO_Table" type="QP::QActive * const" visibility="0x00" properties="0x00"/>
<directory name=".">
<file name="dpp.h">
<text>#ifndef dpp_h
#define dpp_h
namespace DPP {
enum DPPSignals {
EAT_SIG = QP::Q_USER_SIG, // published by Table to let a philosopher eat
DONE_SIG, // published by Philosopher when done eating
PAUSE_SIG, // published by BSP to pause the application
SERVE_SIG, // published by BSP to serve re-start serving forks
TEST_SIG, // published by BSP to test the application
MAX_PUB_SIG, // the last published signal
HUNGRY_SIG, // posted direclty to Table from hungry Philo
TIMEOUT_SIG, // used by the component time events
MAX_SIG // the last signal
};
class Philo; // forward declaration
} // namespace DPP
enum {
N_PHILO = 5 // number of Philos
};
$declare(Cont::CompTimeEvt)
$declare(Cont::AO_Table)
$declare(Comp::Philo)
$declare(Cont::TableEvt)
#endif // dpp_h</text>
</file>
<file name="table.cpp">
<text>#include &quot;qpcpp.h&quot;
#include &quot;dpp.h&quot;
#include &quot;bsp.h&quot;
Q_DEFINE_THIS_FILE
// Active object class -------------------------------------------------------
$declare(Cont::Table)
namespace DPP {
// helper function to provide the RIGHT neighbour of a Philo[n]
inline uint8_t RIGHT(uint8_t const n) {
return static_cast&lt;uint8_t&gt;((n + (N_PHILO - 1U)) % N_PHILO);
}
// helper function to provide the LEFT neighbour of a Philo[n]
inline uint8_t LEFT(uint8_t const n) {
return static_cast&lt;uint8_t&gt;((n + 1U) % N_PHILO);
}
static uint8_t const FREE = static_cast&lt;uint8_t&gt;(0);
static uint8_t const USED = static_cast&lt;uint8_t&gt;(1);
static char_t const * const THINKING = &amp;&quot;thinking&quot;[0];
static char_t const * const HUNGRY = &amp;&quot;hungry &quot;[0];
static char_t const * const EATING = &amp;&quot;eating &quot;[0];
// Local objects -------------------------------------------------------------
static Table l_table; // the single instance of the Table active object
// Global-scope objects ------------------------------------------------------
QP::QActive * const AO_Table = &amp;l_table; // &quot;opaque&quot; AO pointer
} // namespace DPP
//............................................................................
$define(Cont::CompTimeEvt)
$define(Cont::Table)</text>
</file>
</directory>
</package>

View File

@ -0,0 +1,104 @@
//$file${Cont::.::dpp.h} #####################################################
//
// Model: dpp.qm
// File: C:/qp_lab/qpcpp/examples/win32/dpp-comp/cont/dpp.h
//
// This code has been generated by QM tool (https://state-machine.com/qm).
// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
//
// This program is open source software: you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
// by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
//$endhead${Cont::.::dpp.h} ##################################################
#ifndef dpp_h
#define dpp_h
namespace DPP {
enum DPPSignals {
EAT_SIG = QP::Q_USER_SIG, // published by Table to let a philosopher eat
DONE_SIG, // published by Philosopher when done eating
PAUSE_SIG, // published by BSP to pause the application
SERVE_SIG, // published by BSP to serve re-start serving forks
TEST_SIG, // published by BSP to test the application
MAX_PUB_SIG, // the last published signal
HUNGRY_SIG, // posted direclty to Table from hungry Philo
TIMEOUT_SIG, // used by the component time events
MAX_SIG // the last signal
};
class Philo; // forward declaration
} // namespace DPP
enum {
N_PHILO = 5 // number of Philos
};
//$declare${Cont::CompTimeEvt} ###############################################
namespace DPP {
//${Cont::CompTimeEvt} .......................................................
class CompTimeEvt : public QP::QTimeEvt {
public:
QP::QHsm * m_comp;
public:
CompTimeEvt(
QP::QActive * act,
QP::QHsm * comp,
enum_t const sig,
uint_fast8_t const tickRate);
void dispatchToComp() const {
m_comp->dispatch(this);
}
};
} // namespace DPP//$enddecl${Cont::CompTimeEvt} ###############################################
//$declare${Cont::AO_Table} ##################################################
namespace DPP {
extern QP::QActive * const AO_Table;
} // namespace DPP//$enddecl${Cont::AO_Table} ##################################################
//$declare${Comp::Philo} #####################################################
namespace DPP {
//${Comp::Philo} .............................................................
class Philo : public QP::QHsm {
private:
CompTimeEvt m_timeEvt;
public:
Philo();
protected:
static QP::QState initial(Philo * const me, QP::QEvt const * const e);
static QP::QState thinking(Philo * const me, QP::QEvt const * const e);
static QP::QState hungry(Philo * const me, QP::QEvt const * const e);
static QP::QState eating(Philo * const me, QP::QEvt const * const e);
};
} // namespace DPP//$enddecl${Comp::Philo} #####################################################
//$declare${Cont::TableEvt} ##################################################
namespace DPP {
//${Cont::TableEvt} ..........................................................
class TableEvt : public QP::QEvt {
public:
DPP::Philo * philo;
};
} // namespace DPP//$enddecl${Cont::TableEvt} ##################################################
#endif // dpp_h

View File

@ -0,0 +1,354 @@
//$file${Cont::.::table.cpp} #################################################
//
// Model: dpp.qm
// File: C:/qp_lab/qpcpp/examples/win32/dpp-comp/cont/table.cpp
//
// This code has been generated by QM tool (https://state-machine.com/qm).
// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
//
// This program is open source software: you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
// by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
//$endhead${Cont::.::table.cpp} ##############################################
#include "qpcpp.h"
#include "dpp.h"
#include "bsp.h"
Q_DEFINE_THIS_FILE
// Active object class -------------------------------------------------------
//$declare${Cont::Table} #####################################################
namespace DPP {
//${Cont::Table} .............................................................
class Table : public QP::QActive {
private:
Philo m_philo[N_PHILO];
uint8_t m_fork[N_PHILO];
bool m_isHungry[N_PHILO];
public:
Table();
protected:
static QP::QState initial(Table * const me, QP::QEvt const * const e);
static QP::QState active(Table * const me, QP::QEvt const * const e);
static QP::QState serving(Table * const me, QP::QEvt const * const e);
static QP::QState paused(Table * const me, QP::QEvt const * const e);
};
} // namespace DPP//$enddecl${Cont::Table} #####################################################
namespace DPP {
// helper function to provide the RIGHT neighbour of a Philo[n]
inline uint8_t RIGHT(uint8_t const n) {
return static_cast<uint8_t>((n + (N_PHILO - 1U)) % N_PHILO);
}
// helper function to provide the LEFT neighbour of a Philo[n]
inline uint8_t LEFT(uint8_t const n) {
return static_cast<uint8_t>((n + 1U) % N_PHILO);
}
static uint8_t const FREE = static_cast<uint8_t>(0);
static uint8_t const USED = static_cast<uint8_t>(1);
static char_t const * const THINKING = &"thinking"[0];
static char_t const * const HUNGRY = &"hungry "[0];
static char_t const * const EATING = &"eating "[0];
// Local objects -------------------------------------------------------------
static Table l_table; // the single instance of the Table active object
// Global-scope objects ------------------------------------------------------
QP::QActive * const AO_Table = &l_table; // "opaque" AO pointer
} // namespace DPP
//............................................................................
//$define${Cont::CompTimeEvt} ################################################
// Check for the minimum required QP version
#if ((QP_VERSION < 601) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8)))
#error qpcpp version 6.0.1 or higher required
#endif
namespace DPP {
//${Cont::CompTimeEvt} .......................................................
//${Cont::CompTimeEvt::CompTimeEvt} ..........................................
CompTimeEvt::CompTimeEvt(
QP::QActive * act,
QP::QHsm * comp,
enum_t const sig,
uint_fast8_t const tickRate)
: QTimeEvt(act, sig, tickRate)
{
m_comp = comp;
}
} // namespace DPP//$enddef${Cont::CompTimeEvt} ################################################
//$define${Cont::Table} ######################################################
namespace DPP {
//${Cont::Table} .............................................................
//${Cont::Table::Table} ......................................................
Table::Table()
: QActive(Q_STATE_CAST(&Table::initial))
{
for (uint8_t n = 0U; n < N_PHILO; ++n) {
m_fork[n] = FREE;
m_isHungry[n] = false;
}
}
//${Cont::Table::SM} .........................................................
QP::QState Table::initial(Table * const me, QP::QEvt const * const e) {
//${Cont::Table::SM::initial}
(void)e; // suppress the compiler warning about unused parameter
QS_OBJ_DICTIONARY(&l_table);
QS_FUN_DICTIONARY(&Table::initial);
QS_FUN_DICTIONARY(&Table::active);
QS_FUN_DICTIONARY(&Table::serving);
QS_FUN_DICTIONARY(&Table::paused);
QS_SIG_DICTIONARY(DONE_SIG, (void *)0); // global signals
QS_SIG_DICTIONARY(EAT_SIG, (void *)0);
QS_SIG_DICTIONARY(PAUSE_SIG, (void *)0);
QS_SIG_DICTIONARY(SERVE_SIG, (void *)0);
QS_SIG_DICTIONARY(TEST_SIG, (void *)0);
QS_SIG_DICTIONARY(TIMEOUT_SIG, me); // signal just for Table
QS_SIG_DICTIONARY(HUNGRY_SIG, me); // signal just for Table
me->subscribe(PAUSE_SIG);
me->subscribe(SERVE_SIG);
me->subscribe(TEST_SIG);
for (uint8_t n = 0U; n < N_PHILO; ++n) {
me->m_philo[n].init(); // top-most initial tran.
me->m_fork[n] = FREE;
me->m_isHungry[n] = false;
BSP::displayPhilStat(n, THINKING);
}
return Q_TRAN(&serving);
}
//${Cont::Table::SM::active} .................................................
QP::QState Table::active(Table * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
//${Cont::Table::SM::active::TIMEOUT}
case TIMEOUT_SIG: {
Q_EVT_CAST(CompTimeEvt)->dispatchToComp();
status_ = Q_HANDLED();
break;
}
//${Cont::Table::SM::active::EAT}
case EAT_SIG: {
Q_ERROR();
status_ = Q_HANDLED();
break;
}
//${Cont::Table::SM::active::TEST}
case TEST_SIG: {
status_ = Q_HANDLED();
break;
}
default: {
status_ = Q_SUPER(&top);
break;
}
}
return status_;
}
//${Cont::Table::SM::active::serving} ........................................
QP::QState Table::serving(Table * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
//${Cont::Table::SM::active::serving}
case Q_ENTRY_SIG: {
for (uint8_t n = 0U; n < N_PHILO; ++n) { // give permissions to eat...
if (me->m_isHungry[n]
&& (me->m_fork[LEFT(n)] == FREE)
&& (me->m_fork[n] == FREE))
{
me->m_fork[LEFT(n)] = USED;
me->m_fork[n] = USED;
// synchronoulsy dispatch EAT event to the Philo component
TableEvt evt;
evt.sig = EAT_SIG;
evt.philo = &me->m_philo[n];
me->m_philo[n].dispatch(&evt);
me->m_isHungry[n] = false;
BSP::displayPhilStat(n, EATING);
}
}
status_ = Q_HANDLED();
break;
}
//${Cont::Table::SM::active::serving::HUNGRY}
case HUNGRY_SIG: {
// find the index of the Philo from the event
uint8_t n = (Q_EVT_CAST(TableEvt)->philo - &me->m_philo[0]);
// philo ID must be in range and he must be not hungry
Q_ASSERT((n < N_PHILO) && (!me->m_isHungry[n]));
BSP::displayPhilStat(n, HUNGRY);
uint8_t m = LEFT(n);
//${Cont::Table::SM::active::serving::HUNGRY::[bothfree]}
if ((me->m_fork[m] == FREE) && (me->m_fork[n] == FREE)) {
me->m_fork[m] = USED;
me->m_fork[n] = USED;
// synchronoulsy dispatch EAT event to the Philo component
TableEvt evt;
evt.sig = EAT_SIG;
evt.philo = &me->m_philo[n];
me->m_philo[n].dispatch(&evt);
BSP::displayPhilStat(n, EATING);
status_ = Q_HANDLED();
}
//${Cont::Table::SM::active::serving::HUNGRY::[else]}
else {
me->m_isHungry[n] = true;
status_ = Q_HANDLED();
}
break;
}
//${Cont::Table::SM::active::serving::DONE}
case DONE_SIG: {
// find the index of the Philo from the event
uint8_t n = (Q_EVT_CAST(TableEvt)->philo - &me->m_philo[0]);
// philo ID must be in range and he must be not hungry
Q_ASSERT((n < N_PHILO) && (!me->m_isHungry[n]));
BSP::displayPhilStat(n, THINKING);
uint8_t m = LEFT(n);
// both forks of Phil[n] must be used
Q_ASSERT((me->m_fork[n] == USED) && (me->m_fork[m] == USED));
me->m_fork[m] = FREE;
me->m_fork[n] = FREE;
m = RIGHT(n); // check the right neighbor
if (me->m_isHungry[m] && (me->m_fork[m] == FREE)) {
me->m_fork[n] = USED;
me->m_fork[m] = USED;
me->m_isHungry[m] = false;
// synchronoulsy dispatch EAT event to the Philo component
TableEvt evt;
evt.sig = EAT_SIG;
evt.philo = &me->m_philo[m];
me->m_philo[m].dispatch(&evt);
BSP::displayPhilStat(m, EATING);
}
m = LEFT(n); // check the left neighbor
n = LEFT(m); // left fork of the left neighbor
if (me->m_isHungry[m] && (me->m_fork[n] == FREE)) {
me->m_fork[m] = USED;
me->m_fork[n] = USED;
me->m_isHungry[m] = false;
// synchronoulsy dispatch EAT event to the Philo component
TableEvt evt;
evt.sig = EAT_SIG;
evt.philo = &me->m_philo[m];
me->m_philo[m].dispatch(&evt);
BSP::displayPhilStat(m, EATING);
}
status_ = Q_HANDLED();
break;
}
//${Cont::Table::SM::active::serving::EAT}
case EAT_SIG: {
Q_ERROR();
status_ = Q_HANDLED();
break;
}
//${Cont::Table::SM::active::serving::PAUSE}
case PAUSE_SIG: {
status_ = Q_TRAN(&paused);
break;
}
default: {
status_ = Q_SUPER(&active);
break;
}
}
return status_;
}
//${Cont::Table::SM::active::paused} .........................................
QP::QState Table::paused(Table * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
//${Cont::Table::SM::active::paused}
case Q_ENTRY_SIG: {
BSP::displayPaused(1U);
status_ = Q_HANDLED();
break;
}
//${Cont::Table::SM::active::paused}
case Q_EXIT_SIG: {
BSP::displayPaused(0U);
status_ = Q_HANDLED();
break;
}
//${Cont::Table::SM::active::paused::SERVE}
case SERVE_SIG: {
status_ = Q_TRAN(&serving);
break;
}
//${Cont::Table::SM::active::paused::HUNGRY}
case HUNGRY_SIG: {
// find the index of the Philo from the event
uint8_t n = (Q_EVT_CAST(TableEvt)->philo - &me->m_philo[0]);
// philo ID must be in range and he must be not hungry
Q_ASSERT((n < N_PHILO) && (!me->m_isHungry[n]));
me->m_isHungry[n] = true;
BSP::displayPhilStat(n, HUNGRY);
status_ = Q_HANDLED();
break;
}
//${Cont::Table::SM::active::paused::DONE}
case DONE_SIG: {
// find the index of the Philo from the event
uint8_t n = (Q_EVT_CAST(TableEvt)->philo - &me->m_philo[0]);
// philo ID must be in range and he must be not hungry
Q_ASSERT((n < N_PHILO) && (!me->m_isHungry[n]));
BSP::displayPhilStat(n, THINKING);
uint8_t m = LEFT(n);
// both forks of Phil[n] must be used
Q_ASSERT((me->m_fork[n] == USED) && (me->m_fork[m] == USED));
me->m_fork[m] = FREE;
me->m_fork[n] = FREE;
status_ = Q_HANDLED();
break;
}
default: {
status_ = Q_SUPER(&active);
break;
}
}
return status_;
}
} // namespace DPP//$enddef${Cont::Table} ######################################################

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<model version="4.1.0" links="0">
<documentation>Dining Philosopher Problem example with the &quot;Orthogonal Component&quot; state pattern (see https://www.state-machine.com/doc/Pattern_Orthogonal.pdf)
The model demonstrates the following features:
1. Partitioning the application into Container and Components
2. Packages for Container (cont) and Components (comp)
3. External packages with speparate QM-package model files
4. CompTimeEvt class for private time evnents of Components
5. Container to Component communication via synchronous event dispatching
6. Component to Container communication via asynchronous event posting using the LIFO policy.</documentation>
<framework name="qpcpp"/>
<package file="./cont/cont.qmp"/>
<package file="./comp/comp.qmp"/>
</model>

View File

@ -0,0 +1,91 @@
//****************************************************************************
// DPP example for Windows
// Last updated for version 6.0.0
// Last updated on 2017-10-28
//
// Q u a n t u m L e a P s
// ---------------------------
// innovating embedded systems
//
// Copyright (C) Quantum Leaps, LLC. All rights reserved.
//
// This program is open source software: you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Alternatively, this program may be distributed and modified under the
// terms of Quantum Leaps commercial licenses, which expressly supersede
// the GNU General Public License and are specifically designed for
// licensees interested in retaining the proprietary status of their code.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// Contact information:
// https://state-machine.com
// mailto:info@state-machine.com
//****************************************************************************
#include "qpcpp.h"
#include "dpp.h"
#include "bsp.h"
// "fudge factor" for Windows, see NOTE1
enum { WIN_FUDGE_FACTOR = 10 };
//............................................................................
int main() {
static QP::QEvt const *tableQueueSto[N_PHILO*WIN_FUDGE_FACTOR];
static QF_MPOOL_EL(DPP::TableEvt) smlPoolSto[2*N_PHILO*WIN_FUDGE_FACTOR];
static QP::QSubscrList subscrSto[DPP::MAX_PUB_SIG];
QP::QF::init(); // initialize the framework and the underlying RT kernel
DPP::BSP::init(); // initialize the BSP
// object dictionaries...
QS_OBJ_DICTIONARY(smlPoolSto);
QS_OBJ_DICTIONARY(tableQueueSto);
QP::QF::psInit(subscrSto, Q_DIM(subscrSto)); // init publish-subscribe
// initialize event pools...
QP::QF::poolInit(smlPoolSto,
sizeof(smlPoolSto), sizeof(smlPoolSto[0]));
// start the active objects...
DPP::AO_Table->start(
1U,
tableQueueSto, Q_DIM(tableQueueSto),
(void *)0, 0U);
return QP::QF::run(); // run the QF application
}
//****************************************************************************
// NOTE1:
// Windows is not a deterministic real-time system, which means that the
// system can occasionally and unexpectedly "choke and freeze" for a number
// of seconds. The designers of Windows have dealt with these sort of issues
// by massively oversizing the resources available to the applications. For
// example, the default Windows GUI message queues size is 10,000 entries,
// which can dynamically grow to an even larger number. Also the stacks of
// Win32 threads can dynamically grow to several megabytes.
//
// In contrast, the event queues, event pools, and stack size inside the
// real-time embedded (RTE) systems can be (and must be) much smaller,
// because you typically can put an upper bound on the real-time behavior
// and the resulting delays.
//
// To be able to run the unmodified applications designed originally for
// RTE systems on Windows, and to reduce the odds of resource shortages in
// this case, the generous WIN_FUDGE_FACTOR is used to oversize the
// event queues and event pools.
//

View File

@ -1,8 +1,9 @@
//****************************************************************************
// Model: history.qm
// File: ./history.cpp
//$file${.::history.cpp} #####################################################
//
// This code has been generated by QM tool (see state-machine.com/qm).
// Model: history.qm
// File: C:/qp_lab/qpcpp/examples/win32/history_qmsm/history.cpp
//
// This code has been generated by QM tool (https://state-machine.com/qm).
// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
//
// This code is covered by the following QP license:
@ -15,8 +16,8 @@
// the generated code is still licensed under the terms of GPL.
// Please submit request for extension of the evaluaion period at:
// https://state-machine.com/licensing/#RequestForm
//****************************************************************************
//${.::history.cpp} ..........................................................
//
//$endhead${.::history.cpp} ##################################################
#include "qep_port.h"
#include "qassert.h"
#include "history.h"
@ -27,11 +28,7 @@
Q_DEFINE_THIS_FILE
#if ((QP_VERSION < 591) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8)))
#error qpcpp version 5.9.1 or higher required
#endif
//$declare${SMs::ToastOven} ##################################################
//${SMs::ToastOven} ..........................................................
class ToastOven : public QP::QMsm {
public:
@ -69,13 +66,18 @@ protected:
protected:
QP::QMState const *his_doorClosed;
};
//$enddecl${SMs::ToastOven} ##################################################
static ToastOven l_oven; // the only instance of the ToastOven class
// global-scope definitions ------------------------------------
QP::QMsm * const the_oven = &l_oven; // the opaque pointer
//$define${SMs::ToastOven} ###################################################
// Check for the minimum required QP version
#if ((QP_VERSION < 601) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8)))
#error qpcpp version 6.0.1 or higher required
#endif
//${SMs::ToastOven} ..........................................................
//${SMs::ToastOven::ToastOven} ...............................................
ToastOven::ToastOven()
@ -95,7 +97,7 @@ QP::QState ToastOven::initial(ToastOven * const me, QP::QEvt const * const e) {
Q_ACTION_CAST(0) // zero terminator
}
};
// ${SMs::ToastOven::SM::initial}
//${SMs::ToastOven::SM::initial}
(void)e; /* avoid compiler warning */
// state history attributes
me->his_doorClosed = &off_s;
@ -109,19 +111,19 @@ QP::QMState const ToastOven::doorClosed_s = {
Q_ACTION_CAST(&ToastOven::doorClosed_x),
Q_ACTION_CAST(&ToastOven::doorClosed_i)
};
// ${SMs::ToastOven::SM::doorClosed}
//${SMs::ToastOven::SM::doorClosed}
QP::QState ToastOven::doorClosed_e(ToastOven * const me) {
printf("door-Closed;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_ENTRY(&doorClosed_s);
}
// ${SMs::ToastOven::SM::doorClosed}
//${SMs::ToastOven::SM::doorClosed}
QP::QState ToastOven::doorClosed_x(ToastOven * const me) {
// save deep history
me->his_doorClosed = me->stateObj();
return QM_EXIT(&doorClosed_s);
}
// ${SMs::ToastOven::SM::doorClosed::initial}
//${SMs::ToastOven::SM::doorClosed::initial}
QP::QState ToastOven::doorClosed_i(ToastOven * const me) {
static struct {
QP::QMState const *target;
@ -133,14 +135,14 @@ QP::QState ToastOven::doorClosed_i(ToastOven * const me) {
Q_ACTION_CAST(0) // zero terminator
}
};
// ${SMs::ToastOven::SM::doorClosed::initial}
//${SMs::ToastOven::SM::doorClosed::initial}
return QM_TRAN_INIT(&tatbl_);
}
// ${SMs::ToastOven::SM::doorClosed}
//${SMs::ToastOven::SM::doorClosed}
QP::QState ToastOven::doorClosed(ToastOven * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${SMs::ToastOven::SM::doorClosed::TERMINATE}
//${SMs::ToastOven::SM::doorClosed::TERMINATE}
case TERMINATE_SIG: {
static struct {
QP::QMState const *target;
@ -156,7 +158,7 @@ QP::QState ToastOven::doorClosed(ToastOven * const me, QP::QEvt const * const e)
status_ = QM_TRAN(&tatbl_);
break;
}
// ${SMs::ToastOven::SM::doorClosed::OPEN}
//${SMs::ToastOven::SM::doorClosed::OPEN}
case OPEN_SIG: {
static struct {
QP::QMState const *target;
@ -172,7 +174,7 @@ QP::QState ToastOven::doorClosed(ToastOven * const me, QP::QEvt const * const e)
status_ = QM_TRAN(&tatbl_);
break;
}
// ${SMs::ToastOven::SM::doorClosed::TOAST}
//${SMs::ToastOven::SM::doorClosed::TOAST}
case TOAST_SIG: {
static struct {
QP::QMState const *target;
@ -188,7 +190,7 @@ QP::QState ToastOven::doorClosed(ToastOven * const me, QP::QEvt const * const e)
status_ = QM_TRAN(&tatbl_);
break;
}
// ${SMs::ToastOven::SM::doorClosed::BAKE}
//${SMs::ToastOven::SM::doorClosed::BAKE}
case BAKE_SIG: {
static struct {
QP::QMState const *target;
@ -204,7 +206,7 @@ QP::QState ToastOven::doorClosed(ToastOven * const me, QP::QEvt const * const e)
status_ = QM_TRAN(&tatbl_);
break;
}
// ${SMs::ToastOven::SM::doorClosed::OFF}
//${SMs::ToastOven::SM::doorClosed::OFF}
case OFF_SIG: {
static struct {
QP::QMState const *target;
@ -234,19 +236,19 @@ QP::QMState const ToastOven::heating_s = {
Q_ACTION_CAST(&ToastOven::heating_x),
Q_ACTION_CAST(&ToastOven::heating_i)
};
// ${SMs::ToastOven::SM::doorClosed::heating}
//${SMs::ToastOven::SM::doorClosed::heating}
QP::QState ToastOven::heating_e(ToastOven * const me) {
printf("heater-On;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_ENTRY(&heating_s);
}
// ${SMs::ToastOven::SM::doorClosed::heating}
//${SMs::ToastOven::SM::doorClosed::heating}
QP::QState ToastOven::heating_x(ToastOven * const me) {
printf("heater-Off;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_EXIT(&heating_s);
}
// ${SMs::ToastOven::SM::doorClosed::heating::initial}
//${SMs::ToastOven::SM::doorClosed::heating::initial}
QP::QState ToastOven::heating_i(ToastOven * const me) {
static struct {
QP::QMState const *target;
@ -258,10 +260,10 @@ QP::QState ToastOven::heating_i(ToastOven * const me) {
Q_ACTION_CAST(0) // zero terminator
}
};
// ${SMs::ToastOven::SM::doorClosed::heating::initial}
//${SMs::ToastOven::SM::doorClosed::heating::initial}
return QM_TRAN_INIT(&tatbl_);
}
// ${SMs::ToastOven::SM::doorClosed::heating}
//${SMs::ToastOven::SM::doorClosed::heating}
QP::QState ToastOven::heating(ToastOven * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
@ -281,13 +283,13 @@ QP::QMState const ToastOven::toasting_s = {
Q_ACTION_CAST(0), // no exit action
Q_ACTION_CAST(0) // no intitial tran.
};
// ${SMs::ToastOven::SM::doorClosed::heating::toasting}
//${SMs::ToastOven::SM::doorClosed::heating::toasting}
QP::QState ToastOven::toasting_e(ToastOven * const me) {
printf("toasting;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_ENTRY(&toasting_s);
}
// ${SMs::ToastOven::SM::doorClosed::heating::toasting}
//${SMs::ToastOven::SM::doorClosed::heating::toasting}
QP::QState ToastOven::toasting(ToastOven * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
@ -307,13 +309,13 @@ QP::QMState const ToastOven::baking_s = {
Q_ACTION_CAST(0), // no exit action
Q_ACTION_CAST(0) // no intitial tran.
};
// ${SMs::ToastOven::SM::doorClosed::heating::baking}
//${SMs::ToastOven::SM::doorClosed::heating::baking}
QP::QState ToastOven::baking_e(ToastOven * const me) {
printf("baking;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_ENTRY(&baking_s);
}
// ${SMs::ToastOven::SM::doorClosed::heating::baking}
//${SMs::ToastOven::SM::doorClosed::heating::baking}
QP::QState ToastOven::baking(ToastOven * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
@ -333,13 +335,13 @@ QP::QMState const ToastOven::off_s = {
Q_ACTION_CAST(0), // no exit action
Q_ACTION_CAST(0) // no intitial tran.
};
// ${SMs::ToastOven::SM::doorClosed::off}
//${SMs::ToastOven::SM::doorClosed::off}
QP::QState ToastOven::off_e(ToastOven * const me) {
printf("toaster-Off;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_ENTRY(&off_s);
}
// ${SMs::ToastOven::SM::doorClosed::off}
//${SMs::ToastOven::SM::doorClosed::off}
QP::QState ToastOven::off(ToastOven * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
@ -359,23 +361,23 @@ QP::QMState const ToastOven::doorOpen_s = {
Q_ACTION_CAST(&ToastOven::doorOpen_x),
Q_ACTION_CAST(0) // no intitial tran.
};
// ${SMs::ToastOven::SM::doorOpen}
//${SMs::ToastOven::SM::doorOpen}
QP::QState ToastOven::doorOpen_e(ToastOven * const me) {
printf("door-Open,lamp-On;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_ENTRY(&doorOpen_s);
}
// ${SMs::ToastOven::SM::doorOpen}
//${SMs::ToastOven::SM::doorOpen}
QP::QState ToastOven::doorOpen_x(ToastOven * const me) {
printf("lamp-Off;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_EXIT(&doorOpen_s);
}
// ${SMs::ToastOven::SM::doorOpen}
//${SMs::ToastOven::SM::doorOpen}
QP::QState ToastOven::doorOpen(ToastOven * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${SMs::ToastOven::SM::doorOpen::CLOSE}
//${SMs::ToastOven::SM::doorOpen::CLOSE}
case CLOSE_SIG: {
static struct {
QP::QMState const *target;
@ -391,7 +393,7 @@ QP::QState ToastOven::doorOpen(ToastOven * const me, QP::QEvt const * const e) {
status_ = QM_TRAN_HIST(me->his_doorClosed, &tatbl_);
break;
}
// ${SMs::ToastOven::SM::doorOpen::TERMINATE}
//${SMs::ToastOven::SM::doorOpen::TERMINATE}
case TERMINATE_SIG: {
static struct {
QP::QMState const *target;
@ -422,14 +424,14 @@ QP::QMState const ToastOven::final_s = {
Q_ACTION_CAST(0), // no exit action
Q_ACTION_CAST(0) // no intitial tran.
};
// ${SMs::ToastOven::SM::final}
//${SMs::ToastOven::SM::final}
QP::QState ToastOven::final_e(ToastOven * const me) {
printf("-> final\nBye!Bye!\n");
_exit(0);
(void)me; // avoid compiler warning in case 'me' is not used
return QM_ENTRY(&final_s);
}
// ${SMs::ToastOven::SM::final}
//${SMs::ToastOven::SM::final}
QP::QState ToastOven::final(ToastOven * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
@ -441,4 +443,4 @@ QP::QState ToastOven::final(ToastOven * const me, QP::QEvt const * const e) {
(void)me; // avoid compiler warning in case 'me' is not used
return status_;
}
//$enddef${SMs::ToastOven} ###################################################

View File

@ -1,8 +1,9 @@
//****************************************************************************
// Model: history.qm
// File: ./history.h
//$file${.::history.h} #######################################################
//
// This code has been generated by QM tool (see state-machine.com/qm).
// Model: history.qm
// File: C:/qp_lab/qpcpp/examples/win32/history_qmsm/history.h
//
// This code has been generated by QM tool (https://state-machine.com/qm).
// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
//
// This code is covered by the following QP license:
@ -15,8 +16,8 @@
// the generated code is still licensed under the terms of GPL.
// Please submit request for extension of the evaluaion period at:
// https://state-machine.com/licensing/#RequestForm
//****************************************************************************
//${.::history.h} ............................................................
//
//$endhead${.::history.h} ####################################################
#ifndef history_h
#define history_h
@ -31,4 +32,4 @@ enum ToastOvenSignals {
extern QP::QMsm * const the_oven; // opaque pointer to the oven MSM
#endif // history_h
#endif // history_h

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<model version="4.0.3" links="0">
<model version="4.1.0" links="0">
<documentation>QMsmTst is a contrived state machine from Chapter 2 of the PSiCC2 book for testing the QMsm class implementation.</documentation>
<framework name="qpcpp" license="../../../QPCPP-EVAL-171231.qlc"/>
<package name="SMs" stereotype="0x02">

View File

@ -1,8 +1,9 @@
//****************************************************************************
// Model: qmsmtst.qm
// File: ./qmsmtst.cpp
//$file${.::qmsmtst.cpp} #####################################################
//
// This code has been generated by QM tool (see state-machine.com/qm).
// Model: qmsmtst.qm
// File: C:/qp_lab/qpcpp/examples/win32/qmsmtst/qmsmtst.cpp
//
// This code has been generated by QM tool (https://state-machine.com/qm).
// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
//
// This code is covered by the following QP license:
@ -15,18 +16,14 @@
// the generated code is still licensed under the terms of GPL.
// Please submit request for extension of the evaluaion period at:
// https://state-machine.com/licensing/#RequestForm
//****************************************************************************
//${.::qmsmtst.cpp} ..........................................................
//
//$endhead${.::qmsmtst.cpp} ##################################################
#include "qpcpp.h"
#include "qmsmtst.h"
namespace QMSMTST {
#if ((QP_VERSION < 591) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8)))
#error qpcpp version 5.9.1 or higher required
#endif
//$declare${SMs::QMsmTst} ####################################################
//${SMs::QMsmTst} ............................................................
class QMsmTst : public QP::QMsm {
private:
@ -68,13 +65,18 @@ protected:
static QP::QState s211_x(QMsmTst * const me);
static QP::QMState const s211_s;
};
//$enddecl${SMs::QMsmTst} ####################################################
static QMsmTst l_msmtst; // the only instance of the QMsmTst class
// global-scope definitions -----------------------------------------
QP::QMsm * const the_msm = &l_msmtst; // the opaque pointer
//$define${SMs::QMsmTst} #####################################################
// Check for the minimum required QP version
#if ((QP_VERSION < 601) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8)))
#error qpcpp version 6.0.1 or higher required
#endif
//${SMs::QMsmTst} ............................................................
//${SMs::QMsmTst::SM} ........................................................
@ -91,7 +93,7 @@ QP::QState QMsmTst::initial(QMsmTst * const me, QP::QEvt const * const e) {
Q_ACTION_CAST(0) // zero terminator
}
};
// ${SMs::QMsmTst::SM::initial}
//${SMs::QMsmTst::SM::initial}
(void)e; // avoid compiler warning
me->m_foo = 0U;
BSP_display("top-INIT;");
@ -105,19 +107,19 @@ QP::QMState const QMsmTst::s_s = {
Q_ACTION_CAST(&QMsmTst::s_x),
Q_ACTION_CAST(&QMsmTst::s_i)
};
// ${SMs::QMsmTst::SM::s}
//${SMs::QMsmTst::SM::s}
QP::QState QMsmTst::s_e(QMsmTst * const me) {
BSP_display("s-ENTRY;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_ENTRY(&s_s);
}
// ${SMs::QMsmTst::SM::s}
//${SMs::QMsmTst::SM::s}
QP::QState QMsmTst::s_x(QMsmTst * const me) {
BSP_display("s-EXIT;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_EXIT(&s_s);
}
// ${SMs::QMsmTst::SM::s::initial}
//${SMs::QMsmTst::SM::s::initial}
QP::QState QMsmTst::s_i(QMsmTst * const me) {
static struct {
QP::QMState const *target;
@ -130,17 +132,17 @@ QP::QState QMsmTst::s_i(QMsmTst * const me) {
Q_ACTION_CAST(0) // zero terminator
}
};
// ${SMs::QMsmTst::SM::s::initial}
//${SMs::QMsmTst::SM::s::initial}
BSP_display("s-INIT;");
return QM_TRAN_INIT(&tatbl_);
}
// ${SMs::QMsmTst::SM::s}
//${SMs::QMsmTst::SM::s}
QP::QState QMsmTst::s(QMsmTst * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${SMs::QMsmTst::SM::s::I}
//${SMs::QMsmTst::SM::s::I}
case I_SIG: {
// ${SMs::QMsmTst::SM::s::I::[me->m_foo]}
//${SMs::QMsmTst::SM::s::I::[me->m_foo]}
if (me->m_foo) {
me->m_foo = 0U;
BSP_display("s-I;");
@ -151,7 +153,7 @@ QP::QState QMsmTst::s(QMsmTst * const me, QP::QEvt const * const e) {
}
break;
}
// ${SMs::QMsmTst::SM::s::E}
//${SMs::QMsmTst::SM::s::E}
case E_SIG: {
static struct {
QP::QMState const *target;
@ -168,7 +170,7 @@ QP::QState QMsmTst::s(QMsmTst * const me, QP::QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
// ${SMs::QMsmTst::SM::s::TERMINATE}
//${SMs::QMsmTst::SM::s::TERMINATE}
case TERMINATE_SIG: {
BSP_terminate(0);
status_ = QM_HANDLED();
@ -190,19 +192,19 @@ QP::QMState const QMsmTst::s1_s = {
Q_ACTION_CAST(&QMsmTst::s1_x),
Q_ACTION_CAST(&QMsmTst::s1_i)
};
// ${SMs::QMsmTst::SM::s::s1}
//${SMs::QMsmTst::SM::s::s1}
QP::QState QMsmTst::s1_e(QMsmTst * const me) {
BSP_display("s1-ENTRY;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_ENTRY(&s1_s);
}
// ${SMs::QMsmTst::SM::s::s1}
//${SMs::QMsmTst::SM::s::s1}
QP::QState QMsmTst::s1_x(QMsmTst * const me) {
BSP_display("s1-EXIT;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_EXIT(&s1_s);
}
// ${SMs::QMsmTst::SM::s::s1::initial}
//${SMs::QMsmTst::SM::s::s1::initial}
QP::QState QMsmTst::s1_i(QMsmTst * const me) {
static struct {
QP::QMState const *target;
@ -214,23 +216,23 @@ QP::QState QMsmTst::s1_i(QMsmTst * const me) {
Q_ACTION_CAST(0) // zero terminator
}
};
// ${SMs::QMsmTst::SM::s::s1::initial}
//${SMs::QMsmTst::SM::s::s1::initial}
BSP_display("s1-INIT;");
return QM_TRAN_INIT(&tatbl_);
}
// ${SMs::QMsmTst::SM::s::s1}
//${SMs::QMsmTst::SM::s::s1}
QP::QState QMsmTst::s1(QMsmTst * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${SMs::QMsmTst::SM::s::s1::I}
//${SMs::QMsmTst::SM::s::s1::I}
case I_SIG: {
BSP_display("s1-I;");
status_ = QM_HANDLED();
break;
}
// ${SMs::QMsmTst::SM::s::s1::D}
//${SMs::QMsmTst::SM::s::s1::D}
case D_SIG: {
// ${SMs::QMsmTst::SM::s::s1::D::[!me->m_foo]}
//${SMs::QMsmTst::SM::s::s1::D::[!me->m_foo]}
if (!me->m_foo) {
static struct {
QP::QMState const *target;
@ -252,7 +254,7 @@ QP::QState QMsmTst::s1(QMsmTst * const me, QP::QEvt const * const e) {
}
break;
}
// ${SMs::QMsmTst::SM::s::s1::A}
//${SMs::QMsmTst::SM::s::s1::A}
case A_SIG: {
static struct {
QP::QMState const *target;
@ -270,7 +272,7 @@ QP::QState QMsmTst::s1(QMsmTst * const me, QP::QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
// ${SMs::QMsmTst::SM::s::s1::B}
//${SMs::QMsmTst::SM::s::s1::B}
case B_SIG: {
static struct {
QP::QMState const *target;
@ -286,7 +288,7 @@ QP::QState QMsmTst::s1(QMsmTst * const me, QP::QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
// ${SMs::QMsmTst::SM::s::s1::F}
//${SMs::QMsmTst::SM::s::s1::F}
case F_SIG: {
static struct {
QP::QMState const *target;
@ -305,7 +307,7 @@ QP::QState QMsmTst::s1(QMsmTst * const me, QP::QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
// ${SMs::QMsmTst::SM::s::s1::C}
//${SMs::QMsmTst::SM::s::s1::C}
case C_SIG: {
static struct {
QP::QMState const *target;
@ -338,23 +340,23 @@ QP::QMState const QMsmTst::s11_s = {
Q_ACTION_CAST(&QMsmTst::s11_x),
Q_ACTION_CAST(0) // no intitial tran.
};
// ${SMs::QMsmTst::SM::s::s1::s11}
//${SMs::QMsmTst::SM::s::s1::s11}
QP::QState QMsmTst::s11_e(QMsmTst * const me) {
BSP_display("s11-ENTRY;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_ENTRY(&s11_s);
}
// ${SMs::QMsmTst::SM::s::s1::s11}
//${SMs::QMsmTst::SM::s::s1::s11}
QP::QState QMsmTst::s11_x(QMsmTst * const me) {
BSP_display("s11-EXIT;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_EXIT(&s11_s);
}
// ${SMs::QMsmTst::SM::s::s1::s11}
//${SMs::QMsmTst::SM::s::s1::s11}
QP::QState QMsmTst::s11(QMsmTst * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${SMs::QMsmTst::SM::s::s1::s11::H}
//${SMs::QMsmTst::SM::s::s1::s11::H}
case H_SIG: {
static struct {
QP::QMState const *target;
@ -372,9 +374,9 @@ QP::QState QMsmTst::s11(QMsmTst * const me, QP::QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
// ${SMs::QMsmTst::SM::s::s1::s11::D}
//${SMs::QMsmTst::SM::s::s1::s11::D}
case D_SIG: {
// ${SMs::QMsmTst::SM::s::s1::s11::D::[me->m_foo]}
//${SMs::QMsmTst::SM::s::s1::s11::D::[me->m_foo]}
if (me->m_foo) {
static struct {
QP::QMState const *target;
@ -396,7 +398,7 @@ QP::QState QMsmTst::s11(QMsmTst * const me, QP::QEvt const * const e) {
}
break;
}
// ${SMs::QMsmTst::SM::s::s1::s11::G}
//${SMs::QMsmTst::SM::s::s1::s11::G}
case G_SIG: {
static struct {
QP::QMState const *target;
@ -431,19 +433,19 @@ QP::QMState const QMsmTst::s2_s = {
Q_ACTION_CAST(&QMsmTst::s2_x),
Q_ACTION_CAST(&QMsmTst::s2_i)
};
// ${SMs::QMsmTst::SM::s::s2}
//${SMs::QMsmTst::SM::s::s2}
QP::QState QMsmTst::s2_e(QMsmTst * const me) {
BSP_display("s2-ENTRY;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_ENTRY(&s2_s);
}
// ${SMs::QMsmTst::SM::s::s2}
//${SMs::QMsmTst::SM::s::s2}
QP::QState QMsmTst::s2_x(QMsmTst * const me) {
BSP_display("s2-EXIT;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_EXIT(&s2_s);
}
// ${SMs::QMsmTst::SM::s::s2::initial}
//${SMs::QMsmTst::SM::s::s2::initial}
QP::QState QMsmTst::s2_i(QMsmTst * const me) {
static struct {
QP::QMState const *target;
@ -456,17 +458,17 @@ QP::QState QMsmTst::s2_i(QMsmTst * const me) {
Q_ACTION_CAST(0) // zero terminator
}
};
// ${SMs::QMsmTst::SM::s::s2::initial}
//${SMs::QMsmTst::SM::s::s2::initial}
BSP_display("s2-INIT;");
return QM_TRAN_INIT(&tatbl_);
}
// ${SMs::QMsmTst::SM::s::s2}
//${SMs::QMsmTst::SM::s::s2}
QP::QState QMsmTst::s2(QMsmTst * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${SMs::QMsmTst::SM::s::s2::I}
//${SMs::QMsmTst::SM::s::s2::I}
case I_SIG: {
// ${SMs::QMsmTst::SM::s::s2::I::[!me->m_foo]}
//${SMs::QMsmTst::SM::s::s2::I::[!me->m_foo]}
if (!me->m_foo) {
me->m_foo = true;
BSP_display("s2-I;");
@ -477,7 +479,7 @@ QP::QState QMsmTst::s2(QMsmTst * const me, QP::QEvt const * const e) {
}
break;
}
// ${SMs::QMsmTst::SM::s::s2::F}
//${SMs::QMsmTst::SM::s::s2::F}
case F_SIG: {
static struct {
QP::QMState const *target;
@ -495,7 +497,7 @@ QP::QState QMsmTst::s2(QMsmTst * const me, QP::QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
// ${SMs::QMsmTst::SM::s::s2::C}
//${SMs::QMsmTst::SM::s::s2::C}
case C_SIG: {
static struct {
QP::QMState const *target;
@ -528,19 +530,19 @@ QP::QMState const QMsmTst::s21_s = {
Q_ACTION_CAST(&QMsmTst::s21_x),
Q_ACTION_CAST(&QMsmTst::s21_i)
};
// ${SMs::QMsmTst::SM::s::s2::s21}
//${SMs::QMsmTst::SM::s::s2::s21}
QP::QState QMsmTst::s21_e(QMsmTst * const me) {
BSP_display("s21-ENTRY;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_ENTRY(&s21_s);
}
// ${SMs::QMsmTst::SM::s::s2::s21}
//${SMs::QMsmTst::SM::s::s2::s21}
QP::QState QMsmTst::s21_x(QMsmTst * const me) {
BSP_display("s21-EXIT;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_EXIT(&s21_s);
}
// ${SMs::QMsmTst::SM::s::s2::s21::initial}
//${SMs::QMsmTst::SM::s::s2::s21::initial}
QP::QState QMsmTst::s21_i(QMsmTst * const me) {
static struct {
QP::QMState const *target;
@ -552,15 +554,15 @@ QP::QState QMsmTst::s21_i(QMsmTst * const me) {
Q_ACTION_CAST(0) // zero terminator
}
};
// ${SMs::QMsmTst::SM::s::s2::s21::initial}
//${SMs::QMsmTst::SM::s::s2::s21::initial}
BSP_display("s21-INIT;");
return QM_TRAN_INIT(&tatbl_);
}
// ${SMs::QMsmTst::SM::s::s2::s21}
//${SMs::QMsmTst::SM::s::s2::s21}
QP::QState QMsmTst::s21(QMsmTst * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${SMs::QMsmTst::SM::s::s2::s21::G}
//${SMs::QMsmTst::SM::s::s2::s21::G}
case G_SIG: {
static struct {
QP::QMState const *target;
@ -579,7 +581,7 @@ QP::QState QMsmTst::s21(QMsmTst * const me, QP::QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
// ${SMs::QMsmTst::SM::s::s2::s21::A}
//${SMs::QMsmTst::SM::s::s2::s21::A}
case A_SIG: {
static struct {
QP::QMState const *target;
@ -597,7 +599,7 @@ QP::QState QMsmTst::s21(QMsmTst * const me, QP::QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
// ${SMs::QMsmTst::SM::s::s2::s21::B}
//${SMs::QMsmTst::SM::s::s2::s21::B}
case B_SIG: {
static struct {
QP::QMState const *target;
@ -628,23 +630,23 @@ QP::QMState const QMsmTst::s211_s = {
Q_ACTION_CAST(&QMsmTst::s211_x),
Q_ACTION_CAST(0) // no intitial tran.
};
// ${SMs::QMsmTst::SM::s::s2::s21::s211}
//${SMs::QMsmTst::SM::s::s2::s21::s211}
QP::QState QMsmTst::s211_e(QMsmTst * const me) {
BSP_display("s211-ENTRY;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_ENTRY(&s211_s);
}
// ${SMs::QMsmTst::SM::s::s2::s21::s211}
//${SMs::QMsmTst::SM::s::s2::s21::s211}
QP::QState QMsmTst::s211_x(QMsmTst * const me) {
BSP_display("s211-EXIT;");
(void)me; // avoid compiler warning in case 'me' is not used
return QM_EXIT(&s211_s);
}
// ${SMs::QMsmTst::SM::s::s2::s21::s211}
//${SMs::QMsmTst::SM::s::s2::s21::s211}
QP::QState QMsmTst::s211(QMsmTst * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// ${SMs::QMsmTst::SM::s::s2::s21::s211::H}
//${SMs::QMsmTst::SM::s::s2::s21::s211::H}
case H_SIG: {
static struct {
QP::QMState const *target;
@ -663,7 +665,7 @@ QP::QState QMsmTst::s211(QMsmTst * const me, QP::QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
// ${SMs::QMsmTst::SM::s::s2::s21::s211::D}
//${SMs::QMsmTst::SM::s::s2::s21::s211::D}
case D_SIG: {
static struct {
QP::QMState const *target;
@ -687,6 +689,6 @@ QP::QState QMsmTst::s211(QMsmTst * const me, QP::QEvt const * const e) {
}
return status_;
}
//$enddef${SMs::QMsmTst} #####################################################
} // namespace QMSMTST
} // namespace QMSMTST

View File

@ -1,8 +1,9 @@
//****************************************************************************
// Model: qmsmtst.qm
// File: ./qmsmtst.h
//$file${.::qmsmtst.h} #######################################################
//
// This code has been generated by QM tool (see state-machine.com/qm).
// Model: qmsmtst.qm
// File: C:/qp_lab/qpcpp/examples/win32/qmsmtst/qmsmtst.h
//
// This code has been generated by QM tool (https://state-machine.com/qm).
// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
//
// This code is covered by the following QP license:
@ -15,8 +16,8 @@
// the generated code is still licensed under the terms of GPL.
// Please submit request for extension of the evaluaion period at:
// https://state-machine.com/licensing/#RequestForm
//****************************************************************************
//${.::qmsmtst.h} ............................................................
//
//$endhead${.::qmsmtst.h} ####################################################
#ifndef qmsmtst_h
#define qmsmtst_h
@ -45,4 +46,4 @@ void BSP_terminate(int16_t const result);
} // namespace QMSMTST
#endif // qmsmtst_h
#endif // qmsmtst_h

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<model version="4.0.3" links="0">
<model version="4.1.0" links="0">
<documentation>QMsmTst is a test for the QMsm state machine based on Chapter 2 of the PSiCC2 book.</documentation>
<framework name="qpcpp" license="../../../QPCPP-EVAL-171231.qlc"/>
<package name="SMs" stereotype="0x02">

View File

@ -50,8 +50,8 @@
// and Z is a 1-digit release number.
#define QP_VERSION_STR "6.0.1"
//! Tamperproof current QP release (6.0.1) and date (2017-10-20)
#define QP_RELEASE 0x9A1068E6U
//! Tamperproof current QP release (6.0.1) and date (2017-11-10)
#define QP_RELEASE 0x9A02AD46U
//****************************************************************************
@ -275,11 +275,11 @@ QState const Q_RET_TRAN = static_cast<QState>(8);
//! initial transition taken
QState const Q_RET_TRAN_INIT = static_cast<QState>(9);
//! event handled (transition to history)
QState const Q_RET_TRAN_HIST = static_cast<QState>(10);
//! entry-point transition into a submachine
QState const Q_RET_TRAN_EP = static_cast<QState>(11);
QState const Q_RET_TRAN_EP = static_cast<QState>(10);
//! transition to history of a given state
QState const Q_RET_TRAN_HIST = static_cast<QState>(11);
//! exit-point transition out of a submachine
QState const Q_RET_TRAN_XP = static_cast<QState>(12);

View File

@ -3,8 +3,8 @@
/// @ingroup qxk
/// @cond
///***************************************************************************
/// Last updated for version 5.9.9
/// Last updated on 2017-09-29
/// Last updated for version 6.0.1
/// Last updated on 2017-11-03
///
/// Q u a n t u m L e a P s
/// ---------------------------
@ -211,7 +211,7 @@ private:
class QXMutex {
public:
//! initialize the QXK priority-ceiling mutex QP::QXMutex
void init(uint_fast8_t ceiling);
void init(uint_fast8_t const ceiling);
//! lock the QXK priority-ceiling mutex QP::QXMutex
bool lock(uint_fast16_t const nTicks = QXTHREAD_NO_TIMEOUT);

View File

@ -3,8 +3,8 @@
/// @ingroup qep
/// @cond
///***************************************************************************
/// Last updated for version 5.9.0
/// Last updated on 2017-05-08
/// Last updated for version 6.0.1
/// Last updated on 2017-11-03
///
/// Q u a n t u m L e a P s
/// ---------------------------
@ -131,7 +131,8 @@ QHsm::~QHsm() {
///
/// @param[in] e pointer to the initialization event (might be NULL)
///
/// @note Must be called exactly __once__ before the QP::QHsm::dispatch().
/// @note
/// Must be called exactly __once__ before the QP::QHsm::dispatch().
///
void QHsm::init(QEvt const * const e) {
QStateHandler t = m_state.fun;
@ -208,8 +209,9 @@ void QHsm::init(QEvt const * const e) {
///
/// @param[in] e pointer to the event to be dispatched to the HSM
///
/// @returns Always returns #Q_RET_IGNORED, which means that the top state
/// ignores all events.
/// @returns
/// Always returns #Q_RET_IGNORED, which means that the top state ignores
/// all events.
///
/// @note
/// The arguments to this state handler are not used. They are provided for
@ -386,7 +388,8 @@ void QHsm::dispatch(QEvt const * const e) {
/// @param[in,out] path array of pointers to state-handler functions
/// to execute the entry actions
///
/// @returns the depth of the entry path stored in the @p path parameter.
/// @returns
/// the depth of the entry path stored in the @p path parameter.
////
int_fast8_t QHsm::hsm_tran(QStateHandler (&path)[MAX_NEST_DEPTH_]) {
// transition entry path index
@ -539,7 +542,8 @@ int_fast8_t QHsm::hsm_tran(QStateHandler (&path)[MAX_NEST_DEPTH_]) {
///
/// @param[in] state pointer to the state-handler function to be tested
///
/// @returns 'true' if the HSM is in the @p state and 'false' otherwise
/// @returns
/// 'true' if the HSM is in the @p state and 'false' otherwise
///
bool QHsm::isIn(QStateHandler const s) {
@ -575,16 +579,18 @@ bool QHsm::isIn(QStateHandler const s) {
///
/// @param[in] parent pointer to the state-handler function
///
/// @returns the child of a given @c parent state, which is an ancestor of
/// the currently active state
/// @returns
/// the child of a given @c parent state, which is an ancestor of the
/// currently active state
///
/// @note this function is designed to be called during state transitions,
/// so it does not necessarily start in a stable state configuration.
/// @note
/// this function is designed to be called during state transitions, so it
/// does not necessarily start in a stable state configuration.
/// However, the function establishes stable state configuration upon exit.
///
QStateHandler QHsm::childState(QStateHandler const parent) {
QStateHandler child = m_state.fun; // start with the current state
bool isConfirmed = false; // start with the child not confirmed
bool isFound = false; // start with the child not found
QState r;
// establish stable state configuration
@ -592,7 +598,7 @@ QStateHandler QHsm::childState(QStateHandler const parent) {
do {
// is this the parent of the current child?
if (m_temp.fun == parent) {
isConfirmed = true; // child is confirmed
isFound = true; // child is found
r = Q_RET_IGNORED; // cause breaking out of the loop
}
else {
@ -603,7 +609,7 @@ QStateHandler QHsm::childState(QStateHandler const parent) {
m_temp.fun = m_state.fun; // establish stable state configuration
/// @post the child must be confirmed
Q_ENSURE_ID(710, isConfirmed);
Q_ENSURE_ID(810, isFound);
return child; // return the child
}

View File

@ -3,8 +3,8 @@
/// @ingroup qep
/// @cond
///***************************************************************************
/// Last updated for version 5.9.1
/// Last updated on 2017-05-24
/// Last updated for version 6.0.1
/// Last updated on 2017-11-03
///
/// Q u a n t u m L e a P s
/// ---------------------------
@ -75,10 +75,12 @@ QMState const QMsm::msm_top_s = {
///
/// @param[in] initial the top-most initial transition for the MSM.
///
/// @note The constructor is protected to prevent direct instantiating
/// of the QP::QMsm objects. This class is intended for subclassing only.
/// @note
/// The constructor is protected to prevent direct instantiating of the
/// QP::QMsm objects. This class is intended for subclassing only.
///
/// @sa The QP::QMsm example illustrates how to use the QMsm constructor
/// @sa
/// The QP::QMsm example illustrates how to use the QMsm constructor
/// in the constructor initializer list of the derived state machines.
///
QMsm::QMsm(QStateHandler const initial)
@ -139,22 +141,23 @@ void QMsm::init(QEvt const * const e) {
///
/// @param[in] e pointer to the event to be dispatched to the MSM
///
/// @note Must be called after QP::QMsm::init().
/// @note
/// Must be called after QP::QMsm::init().
///
void QMsm::dispatch(QEvt const * const e) {
QMState const *s = m_state.obj; // store the current state
QMState const *t = s;
QState r = Q_RET_SUPER;
QState r;
QS_CRIT_STAT_
/// @pre current state must be initialized
Q_REQUIRE_ID(300, s != static_cast<QMState const *>(0));
QS_BEGIN_(QS_QEP_DISPATCH, QS::priv_.locFilter[QS::SM_OBJ], this)
QS_TIME_(); // time stamp
QS_SIG_(e->sig); // the signal of the event
QS_OBJ_(this); // this state machine object
QS_FUN_(s->stateHandler); // the current state handler
QS_TIME_(); // time stamp
QS_SIG_(e->sig); // the signal of the event
QS_OBJ_(this); // this state machine object
QS_FUN_(s->stateHandler); // the current state handler
QS_END_()
// scan the state hierarchy up to the top state...
@ -204,14 +207,11 @@ void QMsm::dispatch(QEvt const * const e) {
QMTranActTable const *tatbl = m_temp.tatbl;
QHsmAttr tmp; // temporary to save intermediate values
// was a regular state transition segment taken?
if (r == Q_RET_TRAN) {
// was TRAN, TRAN_INIT, or TRAN_EP taken?
if (r < Q_RET_TRAN_HIST) {
exitToTranSource_(s, t);
r = execTatbl_(tatbl);
}
// was an initial transition segment taken?
else if (r == Q_RET_TRAN_INIT) {
r = execTatbl_(tatbl);
s = m_state.obj;
}
// was a transition segment to history taken?
else if (r == Q_RET_TRAN_HIST) {
@ -220,10 +220,7 @@ void QMsm::dispatch(QEvt const * const e) {
exitToTranSource_(s, t);
(void)execTatbl_(tatbl);
r = enterHistory_(tmp.obj);
}
// was a transition segment to an entry point taken?
else if (r == Q_RET_TRAN_EP) {
r = execTatbl_(tatbl);
s = m_state.obj;
}
// was a transition segment to an exit point taken?
else if (r == Q_RET_TRAN_XP) {
@ -231,32 +228,32 @@ void QMsm::dispatch(QEvt const * const e) {
m_state.obj = s; // restore the original state
r = (*act)(this); // execute the XP action
if (r == Q_RET_TRAN) {
if (r == Q_RET_TRAN) { // XP -> TRAN ?
exitToTranSource_(s, t);
tmp.tatbl = m_temp.tatbl; // save XP-Segment
// take the tran-to-XP segment inside submachine
(void)execTatbl_(tatbl);
m_state.obj = s; // restore original state
#ifdef Q_SPY
t = m_temp.tatbl->target; // store for tracing
#endif /* Q_SPY */
// take the XP-Segment from submachine-state
r = execTatbl_(tmp.tatbl);
QS_BEGIN_(QS_QEP_TRAN_XP,
QS::priv_.locFilter[QS::SM_OBJ], this)
QS_OBJ_(this); // this state machine object
QS_FUN_(s); // source handler
QS_FUN_(t); // target handler
QS_END_()
s = m_state.obj;
}
else if (r == Q_RET_TRAN_HIST) { // XP -> HIST ?
tmp.obj = m_state.obj; // save the history
m_state.obj = s; // restore the original state
exitToTranSource_(s, t);
// take the tran-to-XP segment inside submachine
(void)execTatbl_(tatbl);
s = m_state.obj;
m_state.obj = tmp.obj; // restore the history
}
else {
// TRAN_XP must NOT be followed by any other tran type
Q_ASSERT_ID(330, r < Q_RET_TRAN);
}
}
else {
// no other return value should be produced
Q_ERROR_ID(330);
Q_ERROR_ID(340);
}
s = m_state.obj;
t = s;
t = s; // set target to the current state
} while (r >= Q_RET_TRAN);
@ -307,7 +304,8 @@ void QMsm::dispatch(QEvt const * const e) {
///
/// @param[in] tatbl pointer to the transition-action table
///
/// @returns status of the last action from the transition-action table.
/// @returns
/// the status of the last action from the transition-action table.
///
/// @note
/// This function is for internal use inside the QEP event processor and
@ -371,13 +369,9 @@ QState QMsm::execTatbl_(QMTranActTable const * const tatbl) {
#endif // Q_SPY
}
if (r >= Q_RET_TRAN_INIT) {
m_state.obj = m_temp.tatbl->target; // the tran. target
}
else {
m_state.obj = tatbl->target; // the tran. target
}
m_state.obj = (r >= Q_RET_TRAN)
? m_temp.tatbl->target
: tatbl->target;
return r;
}
@ -424,8 +418,9 @@ void QMsm::exitToTranSource_(QMState const *s,
///
/// @param[in] hist pointer to the history substate
///
/// @returns QP::Q_RET_INIT, if an initial transition has been executed in
/// the last entered state or QP::Q_RET_NULL if no such transition was taken.
/// @returns
/// QP::Q_RET_INIT, if an initial transition has been executed in the last
/// entered state or QP::Q_RET_NULL if no such transition was taken.
///
QState QMsm::enterHistory_(QMState const * const hist) {
QMState const *s = hist;
@ -477,17 +472,17 @@ QState QMsm::enterHistory_(QMState const * const hist) {
}
//****************************************************************************
/// \description
/// @description
/// Tests if a state machine derived from QMsm is-in a given state.
///
/// \note For a MSM, to "be-in" a state means also to "be-in" a superstate of
/// @note
/// For a MSM, to "be-in" a state means also to "be-in" a superstate of
/// of the state.
///
/// \arguments
/// \arg[in] \c st pointer to the QMState object that corresponds to the
/// @param[in] st pointer to the QMState object that corresponds to the
/// tested state.
///
/// \returns 'true' if the MSM is in the \c st and 'false' otherwise
/// @returns
/// 'true' if the MSM is in the \c st and 'false' otherwise
///
bool QMsm::isInState(QMState const * const st) const {
bool inState = false; // assume that this MSM is not in 'state'
@ -514,20 +509,22 @@ bool QMsm::isInState(QMState const * const st) const {
///
/// @param[in] parent pointer to the state-handler object
///
/// @returns the child of a given @c parent state, which is an ancestor of
/// the currently active state
/// @returns
/// the child of a given @c parent state, which is an ancestor of the
/// currently active state. For the corner case when the currently active
/// state is the given @c parent state, function returns the @c parent state.
///
QMState const *QMsm::childStateObj(QMState const * const parent) const {
QMState const *child = m_state.obj;
bool isConfirmed = false; // start with the child not confirmed
bool isFound = false; // start with the child not found
QMState const *s;
for (s = m_state.obj->superstate;
for (s = m_state.obj;
s != static_cast<QMState const *>(0);
s = s->superstate)
{
if (s == parent) {
isConfirmed = true; // child is confirmed
isFound = true; // child is found
break;
}
else {
@ -535,8 +532,8 @@ QMState const *QMsm::childStateObj(QMState const * const parent) const {
}
}
/// @post the child must be confirmed
Q_ENSURE_ID(810, isConfirmed != false);
/// @post the child must be found
Q_ENSURE_ID(810, isFound);
return child; // return the child
}

View File

@ -389,8 +389,8 @@ uint_fast8_t QXK_sched_(void) {
QP::QS::priv_.locFilter[QP::QS::AO_OBJ],
QXK_attr_.next)
QS_TIME_(); // timestamp
QS_2U8_(static_cast<uint8_t>(p), // prio of the next thread
static_cast<uint8_t>( // prio of the curent thread
QS_2U8_(static_cast<uint8_t>(p), /* prio of the next AO */
static_cast<uint8_t>( /* prio of the curent AO */
QXK_attr_.actPrio));
QS_END_NOCRIT_()
@ -416,7 +416,7 @@ uint_fast8_t QXK_sched_(void) {
p = static_cast<uint_fast8_t>(0); // no activation needed
QXK_CONTEXT_SWITCH_();
}
else { // next is the same as the current
else { // next is the same as the current
// no need to context-switch
QXK_attr_.next = static_cast<QP::QActive *>(0);
p = static_cast<uint_fast8_t>(0); // no activation needed

View File

@ -4,8 +4,8 @@
/// @cond
///***************************************************************************
/// Product: QK/C++
/// Last updated for version 5.9.9
/// Last updated on 2017-09-29
/// Last updated for version 6.0.1
/// Last updated on 2017-11-03
///
/// Q u a n t u m L e a P s
/// ---------------------------
@ -81,7 +81,7 @@ Q_DEFINE_THIS_MODULE("qxk_mutex")
/// @usage
/// @include qxk_mux.cpp
///
void QXMutex::init(uint_fast8_t ceiling) {
void QXMutex::init(uint_fast8_t const ceiling) {
QF_CRIT_STAT_
QF_CRIT_ENTRY_();

View File

@ -95,7 +95,7 @@ void QXThread::dispatch(QEvt const * const /*e*/) {
//****************************************************************************
///
/// @description
/// Starts an extended thread and registers it with the framework.
/// Starts execution of an extended thread and registers it with the framework.
/// The extended thread becomes ready-to-run immediately and is scheduled
/// if the QXK is already running.
///
@ -287,15 +287,15 @@ bool QXThread::post_(QEvt const * const e, uint_fast16_t const margin,
QS_TIME_(); // timestamp
QS_OBJ_(sender); // the sender object
QS_SIG_(e->sig); // the signal of the event
QS_OBJ_(this); // this active object
QS_2U8_(e->poolId_, e->refCtr_); // poolID & refCtr of the evt
QS_OBJ_(this); // this active object (recipient)
QS_2U8_(e->poolId_, e->refCtr_); // poolID & ref Count
QS_EQC_(nFree); // number of free entries
QS_EQC_(static_cast<QEQueueCtr>(margin)); // margin requested
QS_END_NOCRIT_()
QF_CRIT_EXIT_();
QF::gc(e); // recycle the evnet to avoid a leak
QF::gc(e); // recycle the event to avoid a leak
status = false; // event not posted
}
}

View File

@ -1,2 +1,2 @@
QP/C++ 6.0.1
2017-10-20
2017-11-10