This commit is contained in:
Quantum Leaps 2017-11-12 21:33:46 -05:00
parent 254befce89
commit 25636b87b0
47 changed files with 2475 additions and 698 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

@ -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

@ -1,18 +1,42 @@
/**
@page history Revision History
@section qpc_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.c 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.c 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 qpc_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(+)"
- [bug#186](https://sourceforge.net/p/qpc/bugs/186/) "QXK: Extended thread context switch causes assertion in PendSV_Handler"
Additionally, this release includes a workaround for a [bug indetified in the GNU-ARM toolset](https://bugs.launchpad.net/gcc-arm-embedded/+bug/1722849). This problem affected the ARMv6-M architecture (Cortex-M0/M0+/M1) and manifested itself in generation of incorrect code for the QP critical section at certain gcc optimization levels (such as -O). This bug was first discovered and filed as [bug#184](https://sourceforge.net/p/qpc/bugs/184/). The bug affected the GNU-ARM ports to all built-in kernels @ref qv "QV", @ref qk "QK", and @ref qxk "QXK".
Additionally, this release includes a fix for the bug found in ARM Cortex-M0 port with the GNU-ARM compiler:
- [bug#189](https://sourceforge.net/p/qpc/bugs/184/) "QS_END() leaves all interrupts disabled w/ GNU ARM"
@note
This specific problem observed in QSpy turned out to be caused by a bug in the GNU-ARM compiler itself. This problem affected the ARMv6-M architecture (Cortex-M0/M0+/M1) and manifested itself in generation of incorrect code for the QP critical section at certain gcc optimization levels (such as -O). This bug was first discovered and filed as [bug#184](https://sourceforge.net/p/qpc/bugs/184/). The bug affected the GNU-ARM ports to all built-in kernels @ref qv "QV", @ref qk "QK", and @ref qxk "QXK".
@attention
This release no longer contains the directory `qpc/source`, which was scheduled to be phased out in QP5. In QP6 the source code is found only in the `qpc/src` directory.
-----------------------------------------------------------------------------
------------------------------------------------------------------------------
@section qpc_5_9_9 Version 5.9.9, 2017-09-29
This release implements the feature request [#132 "Extend the QXK mutex to support also simple operation without the priority-ceiling protocol"](https://sourceforge.net/p/qpc/feature-requests/132/).

View File

@ -42,7 +42,7 @@ The QP/C™ framework is a unique offering on the embedded software market.
Even though it is written in @ref misra "MISRA-compliant" ANSI-C, QP/C&trade; is fundamentally an **object-oriented** framework, which means that the framework itself and your applications derived from the framework are fundamentally composed of <a href="https://en.wikipedia.org/wiki/Class_(computer_programming)" target="_blank" class="extern">classes</a> and only classes can have @ref sm "state machines" associated with them.<br>
@note
If you program in C and object-oriented programming is new to you, please refer to the Application Note <a class="pdf" target="_blank" href="https://state-machine.com/doc/AN_Simple_OOP_in_C.pdf">"Simple Object-Oriented Programming in C"</a>, which describes how you can implement the concepts of _classes_, _inheritance_, and _polymorphism_ to portable ANSI-C.
If you program in C and object-oriented programming is new to you, please refer to the Application Note <a class="pdf" target="_blank" href="https://state-machine.com/doc/AN_OOP_in_C.pdf">"Object-Oriented Programming in C"</a>, which describes how you can implement the concepts of _classes_, _inheritance_, and _polymorphism_ to portable ANSI-C.
<br>
@htmlonly
<div class="image">

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-12
:: 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 13, 2017
Build Date : Sep 2 2009 Run Date: Nov 12, 2017
(C)1996-2009 M Squared Technologies LLC
________________________________________________________________________
@ -31,7 +31,7 @@
~~ Total File Summary ~~
LOC 156 eLOC 152 lLOC 56 Comment 404 Lines 614
LOC 156 eLOC 152 lLOC 56 Comment 405 Lines 616
________________________________________________________________________
End of File: ..\include\qep.h
@ -292,13 +292,13 @@
Loops while / do : 1
Conditional if / else if: 1
Complexity Param 2 Return 1 Cyclo Vg 3 Total 6
LOC 19 eLOC 15 lLOC 12 Comment 30 Lines 25
LOC 19 eLOC 15 lLOC 12 Comment 33 Lines 25
------------------------------------------------------------------------
~~ Total File Summary ~~
LOC 345 eLOC 298 lLOC 177 Comment 317 Lines 628
LOC 345 eLOC 298 lLOC 177 Comment 320 Lines 631
------------------------------------------------------------------------
~~ File Functional Summary ~~
@ -329,7 +329,7 @@
Function: QMsm_ctor
Parameters: (QMsm * const me, QStateHandler initial)
Complexity Param 2 Return 1 Cyclo Vg 1 Total 4
LOC 9 eLOC 7 lLOC 4 Comment 28 Lines 10
LOC 9 eLOC 7 lLOC 4 Comment 29 Lines 10
Function: QMsm_init_
Parameters: (QMsm * const me, QEvt const * const e)
@ -338,25 +338,26 @@
Loops while / do : 1
Logical and ( && ) : 2
Complexity Param 2 Return 1 Cyclo Vg 4 Total 7
LOC 23 eLOC 22 lLOC 13 Comment 25 Lines 37
LOC 23 eLOC 22 lLOC 13 Comment 26 Lines 37
Function: QMsm_dispatch_
Parameters: (QMsm * const me, QEvt const * const e)
Cyclomatic Complexity Vg Detail
Function Base : 1
Loops while / do : 2
Conditional if / else if: 13
Complexity Param 2 Return 1 Cyclo Vg 16 Total 19
LOC 116 eLOC 99 lLOC 61 Comment 77 Lines 157
Conditional if / else if: 12
Complexity Param 2 Return 1 Cyclo Vg 15 Total 18
LOC 112 eLOC 95 lLOC 61 Comment 75 Lines 152
Function: QMsm_execTatbl_
Parameters: (QMsm * const me, QMTranActTable 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 2 Return 1 Cyclo Vg 8 Total 11
LOC 53 eLOC 43 lLOC 21 Comment 33 Lines 64
LOC 50 eLOC 42 lLOC 20 Comment 32 Lines 60
Function: QMsm_exitToTranSource_
Parameters: (QMsm * const me, QMState const *s, QMState const *ts)
@ -374,7 +375,7 @@
Loops while / do : 2
Conditional if / else if: 3
Complexity Param 2 Return 1 Cyclo Vg 6 Total 9
LOC 40 eLOC 33 lLOC 21 Comment 24 Lines 48
LOC 40 eLOC 33 lLOC 21 Comment 25 Lines 48
Function: QMsm_isInState
Parameters: (QMsm const * const me, QMState const * const state)
@ -383,7 +384,7 @@
Loops for / foreach : 1
Conditional if / else if: 1
Complexity Param 2 Return 1 Cyclo Vg 3 Total 6
LOC 11 eLOC 8 lLOC 6 Comment 16 Lines 12
LOC 11 eLOC 8 lLOC 6 Comment 17 Lines 12
Function: QMsm_childStateObj_
Parameters: (QMsm const * const me, QMState const * const parent)
@ -392,33 +393,33 @@
Loops for / foreach : 1
Conditional if / else if: 1
Complexity Param 2 Return 1 Cyclo Vg 3 Total 6
LOC 19 eLOC 13 lLOC 9 Comment 20 Lines 23
LOC 19 eLOC 13 lLOC 9 Comment 22 Lines 23
------------------------------------------------------------------------
~~ Total File Summary ~~
LOC 315 eLOC 262 lLOC 146 Comment 300 Lines 582
LOC 308 eLOC 257 lLOC 145 Comment 304 Lines 581
------------------------------------------------------------------------
~~ File Functional Summary ~~
File Function Count....: 8
Total Function LOC.....: 288 Total Function Pts LOC : 2.5
Total Function eLOC....: 237 Total Function Pts eLOC: 2.0
Total Function lLOC....: 141 Total Function Pts lLOC: 1.1
Total Function LOC.....: 281 Total Function Pts LOC : 2.4
Total Function eLOC....: 232 Total Function Pts eLOC: 2.0
Total Function lLOC....: 140 Total Function Pts lLOC: 1.1
Total Function Params .: 17 Total Function Return .: 8
Total Cyclo Complexity : 45 Total Function Complex.: 70
Total Cyclo Complexity : 44 Total Function Complex.: 69
------ ----- ----- ------ ------ -----
Max Function LOC ......: 116 Average Function LOC ..: 36.00
Max Function eLOC .....: 99 Average Function eLOC .: 29.63
Max Function lLOC .....: 61 Average Function lLOC .: 17.63
Max Function LOC ......: 112 Average Function LOC ..: 35.13
Max Function eLOC .....: 95 Average Function eLOC .: 29.00
Max Function lLOC .....: 61 Average Function lLOC .: 17.50
------ ----- ----- ------ ------ -----
Max Function Parameters: 3 Avg Function Parameters: 2.13
Max Function Returns ..: 1 Avg Function Returns ..: 1.00
Max Interface Complex. : 4 Avg Interface Complex. : 3.13
Max Cyclomatic Complex.: 16 Avg Cyclomatic Complex.: 5.63
Max Total Complexity ..: 19 Avg Total Complexity ..: 8.75
Max Cyclomatic Complex.: 15 Avg Cyclomatic Complex.: 5.50
Max Total Complexity ..: 18 Avg Total Complexity ..: 8.63
________________________________________________________________________
End of File: ..\src\qf\qep_msm.c
@ -505,7 +506,7 @@
Function Base : 1
Conditional if / else if: 4
Complexity Param 2 Return 1 Cyclo Vg 5 Total 8
LOC 37 eLOC 31 lLOC 22 Comment 37 Lines 50
LOC 37 eLOC 31 lLOC 22 Comment 40 Lines 50
Function: QActive_get_
Parameters: (QActive * const me)
@ -559,7 +560,7 @@
~~ Total File Summary ~~
LOC 248 eLOC 214 lLOC 128 Comment 255 Lines 462
LOC 248 eLOC 214 lLOC 128 Comment 258 Lines 465
------------------------------------------------------------------------
~~ File Functional Summary ~~
@ -591,7 +592,7 @@
Parameters: (QActive const * const me, QEQueue * const eq, QEvt const *
const e)
Complexity Param 3 Return 1 Cyclo Vg 1 Total 5
LOC 4 eLOC 2 lLOC 2 Comment 24 Lines 5
LOC 4 eLOC 2 lLOC 2 Comment 26 Lines 5
Function: QActive_recall
Parameters: (QActive * const me, QEQueue * const eq)
@ -599,7 +600,7 @@
Function Base : 1
Conditional if / else if: 2
Complexity Param 2 Return 1 Cyclo Vg 3 Total 6
LOC 19 eLOC 15 lLOC 10 Comment 33 Lines 36
LOC 19 eLOC 15 lLOC 10 Comment 35 Lines 36
Function: QActive_flushDeferred
Parameters: (QActive const * const me, QEQueue * const eq)
@ -607,13 +608,13 @@
Function Base : 1
Loops for / foreach : 1
Complexity Param 2 Return 1 Cyclo Vg 2 Total 5
LOC 10 eLOC 7 lLOC 7 Comment 17 Lines 12
LOC 10 eLOC 7 lLOC 7 Comment 19 Lines 12
------------------------------------------------------------------------
~~ Total File Summary ~~
LOC 47 eLOC 38 lLOC 19 Comment 121 Lines 167
LOC 47 eLOC 38 lLOC 19 Comment 127 Lines 173
------------------------------------------------------------------------
~~ File Functional Summary ~~
@ -1346,7 +1347,7 @@
Function Base : 1
Conditional if / else if: 5
Complexity Param 0 Return 1 Cyclo Vg 6 Total 7
LOC 51 eLOC 41 lLOC 23 Comment 34 Lines 70
LOC 50 eLOC 40 lLOC 22 Comment 35 Lines 66
Function: QXK_activate_
Parameters: (void)
@ -1369,21 +1370,21 @@
~~ Total File Summary ~~
LOC 273 eLOC 234 lLOC 131 Comment 317 Lines 577
LOC 272 eLOC 233 lLOC 130 Comment 318 Lines 573
------------------------------------------------------------------------
~~ File Functional Summary ~~
File Function Count....: 11
Total Function LOC.....: 254 Total Function Pts LOC : 2.1
Total Function eLOC....: 215 Total Function Pts eLOC: 1.8
Total Function lLOC....: 129 Total Function Pts lLOC: 1.0
Total Function LOC.....: 253 Total Function Pts LOC : 2.1
Total Function eLOC....: 214 Total Function Pts eLOC: 1.8
Total Function lLOC....: 128 Total Function Pts lLOC: 1.0
Total Function Params .: 10 Total Function Return .: 11
Total Cyclo Complexity : 37 Total Function Complex.: 58
------ ----- ----- ------ ------ -----
Max Function LOC ......: 75 Average Function LOC ..: 23.09
Max Function eLOC .....: 65 Average Function eLOC .: 19.55
Max Function lLOC .....: 36 Average Function lLOC .: 11.73
Max Function LOC ......: 75 Average Function LOC ..: 23.00
Max Function eLOC .....: 65 Average Function eLOC .: 19.45
Max Function lLOC .....: 36 Average Function lLOC .: 11.64
------ ----- ----- ------ ------ -----
Max Function Parameters: 7 Avg Function Parameters: 0.91
Max Function Returns ..: 1 Avg Function Returns ..: 1.00
@ -1569,7 +1570,7 @@
Logical or ( || ) : 1
Logical and ( && ) : 1
Complexity Param 3 Return 1 Cyclo Vg 12 Total 16
LOC 80 eLOC 65 lLOC 45 Comment 79 Lines 113
LOC 80 eLOC 65 lLOC 45 Comment 83 Lines 113
Function: QXThread_postLIFO_
Parameters: (QActive * const me, QEvt const * const e)
@ -1641,7 +1642,7 @@
~~ Total File Summary ~~
LOC 316 eLOC 269 lLOC 158 Comment 352 Lines 659
LOC 316 eLOC 269 lLOC 158 Comment 356 Lines 663
------------------------------------------------------------------------
~~ File Functional Summary ~~
@ -1674,9 +1675,9 @@
~~ Total Project Summary ~~
LOC 4544 eLOC 4104 lLOC 1833 Comment 7188 Lines 11910
LOC 4536 eLOC 4098 lLOC 1831 Comment 7210 Lines 11923
Average per File, metric/37 files
LOC 122 eLOC 110 lLOC 49 Comment 194 Lines 321
LOC 122 eLOC 110 lLOC 49 Comment 194 Lines 322
------------------------------------------------------------------------
@ -1720,27 +1721,27 @@
Function: QHsm_childState_
Parameters: (QHsm * const me, QStateHandler const parent)
Complexity Param 2 Return 1 Cyclo Vg 3 Total 6
LOC 19 eLOC 15 lLOC 12 Comment 30 Lines 25
LOC 19 eLOC 15 lLOC 12 Comment 33 Lines 25
Function: QMsm_ctor
Parameters: (QMsm * const me, QStateHandler initial)
Complexity Param 2 Return 1 Cyclo Vg 1 Total 4
LOC 9 eLOC 7 lLOC 4 Comment 28 Lines 10
LOC 9 eLOC 7 lLOC 4 Comment 29 Lines 10
Function: QMsm_init_
Parameters: (QMsm * const me, QEvt const * const e)
Complexity Param 2 Return 1 Cyclo Vg 4 Total 7
LOC 23 eLOC 22 lLOC 13 Comment 25 Lines 37
LOC 23 eLOC 22 lLOC 13 Comment 26 Lines 37
Function: QMsm_dispatch_
Parameters: (QMsm * const me, QEvt const * const e)
Complexity Param 2 Return 1 Cyclo Vg 16 Total 19
LOC 116 eLOC 99 lLOC 61 Comment 77 Lines 157
Complexity Param 2 Return 1 Cyclo Vg 15 Total 18
LOC 112 eLOC 95 lLOC 61 Comment 75 Lines 152
Function: QMsm_execTatbl_
Parameters: (QMsm * const me, QMTranActTable const *tatbl)
Complexity Param 2 Return 1 Cyclo Vg 8 Total 11
LOC 53 eLOC 43 lLOC 21 Comment 33 Lines 64
LOC 50 eLOC 42 lLOC 20 Comment 32 Lines 60
Function: QMsm_exitToTranSource_
Parameters: (QMsm * const me, QMState const *s, QMState const *ts)
@ -1750,17 +1751,17 @@
Function: QMsm_enterHistory_
Parameters: (QMsm * const me, QMState const *const hist)
Complexity Param 2 Return 1 Cyclo Vg 6 Total 9
LOC 40 eLOC 33 lLOC 21 Comment 24 Lines 48
LOC 40 eLOC 33 lLOC 21 Comment 25 Lines 48
Function: QMsm_isInState
Parameters: (QMsm const * const me, QMState const * const state)
Complexity Param 2 Return 1 Cyclo Vg 3 Total 6
LOC 11 eLOC 8 lLOC 6 Comment 16 Lines 12
LOC 11 eLOC 8 lLOC 6 Comment 17 Lines 12
Function: QMsm_childStateObj_
Parameters: (QMsm const * const me, QMState const * const parent)
Complexity Param 2 Return 1 Cyclo Vg 3 Total 6
LOC 19 eLOC 13 lLOC 9 Comment 20 Lines 23
LOC 19 eLOC 13 lLOC 9 Comment 22 Lines 23
Function: QF_add_
Parameters: (QActive * const a)
@ -1791,7 +1792,7 @@
Function: QActive_postLIFO_
Parameters: (QActive * const me, QEvt const * const e)
Complexity Param 2 Return 1 Cyclo Vg 5 Total 8
LOC 37 eLOC 31 lLOC 22 Comment 37 Lines 50
LOC 37 eLOC 31 lLOC 22 Comment 40 Lines 50
Function: QActive_get_
Parameters: (QActive * const me)
@ -1833,17 +1834,17 @@
Parameters: (QActive const * const me, QEQueue * const eq, QEvt const *
const e)
Complexity Param 3 Return 1 Cyclo Vg 1 Total 5
LOC 4 eLOC 2 lLOC 2 Comment 24 Lines 5
LOC 4 eLOC 2 lLOC 2 Comment 26 Lines 5
Function: QActive_recall
Parameters: (QActive * const me, QEQueue * const eq)
Complexity Param 2 Return 1 Cyclo Vg 3 Total 6
LOC 19 eLOC 15 lLOC 10 Comment 33 Lines 36
LOC 19 eLOC 15 lLOC 10 Comment 35 Lines 36
Function: QActive_flushDeferred
Parameters: (QActive const * const me, QEQueue * const eq)
Complexity Param 2 Return 1 Cyclo Vg 2 Total 5
LOC 10 eLOC 7 lLOC 7 Comment 17 Lines 12
LOC 10 eLOC 7 lLOC 7 Comment 19 Lines 12
Function: QEvt_ctor
Parameters: (QEvt * const me, enum_t const sig)
@ -2116,7 +2117,7 @@
Function: QXK_sched_
Parameters: (void)
Complexity Param 0 Return 1 Cyclo Vg 6 Total 7
LOC 51 eLOC 41 lLOC 23 Comment 34 Lines 70
LOC 50 eLOC 40 lLOC 22 Comment 35 Lines 66
Function: QXK_activate_
Parameters: (void)
@ -2196,7 +2197,7 @@
Parameters: (QActive * const me, QEvt const * const e, uint_fast16_t con
st margin)
Complexity Param 3 Return 1 Cyclo Vg 12 Total 16
LOC 80 eLOC 65 lLOC 45 Comment 79 Lines 113
LOC 80 eLOC 65 lLOC 45 Comment 83 Lines 113
Function: QXThread_postLIFO_
Parameters: (QActive * const me, QEvt const * const e)
@ -2245,32 +2246,32 @@
LOC 10 eLOC 9 lLOC 7 Comment 12 Lines 12
Total: Functions
LOC 2614 eLOC 2196 lLOC 1396 InCmp 293 CycloCmp 414
LOC 2606 eLOC 2190 lLOC 1394 InCmp 293 CycloCmp 413
Function Points FP(LOC) 20.2 FP(eLOC) 17.0 FP(lLOC) 10.8
------------------------------------------------------------------------
~~ Project Functional Analysis ~~
Total Functions .......: 108 Total Physical Lines ..: 3705
Total LOC .............: 2614 Total Function Pts LOC : 20.2
Total eLOC ............: 2196 Total Function Pts eLOC: 17.0
Total lLOC.............: 1396 Total Function Pts lLOC: 10.8
Total Cyclomatic Comp. : 414 Total Interface Comp. .: 293
Total Functions .......: 108 Total Physical Lines ..: 3692
Total LOC .............: 2606 Total Function Pts LOC : 20.2
Total eLOC ............: 2190 Total Function Pts eLOC: 17.0
Total lLOC.............: 1394 Total Function Pts lLOC: 10.8
Total Cyclomatic Comp. : 413 Total Interface Comp. .: 293
Total Parameters ......: 185 Total Return Points ...: 108
Total Comment Lines ...: 2937 Total Blank Lines .....: 551
Total Comment Lines ...: 2957 Total Blank Lines .....: 549
------ ----- ----- ------ ------ -----
Avg Physical Lines ....: 34.31
Avg LOC ...............: 24.20 Avg eLOC ..............: 20.33
Avg lLOC ..............: 12.93 Avg Cyclomatic Comp. ..: 3.83
Avg Physical Lines ....: 34.19
Avg LOC ...............: 24.13 Avg eLOC ..............: 20.28
Avg lLOC ..............: 12.91 Avg Cyclomatic Comp. ..: 3.82
Avg Interface Comp. ...: 2.71 Avg Parameters ........: 1.71
Avg Return Points .....: 1.00 Avg Comment Lines .....: 27.19
Avg Return Points .....: 1.00 Avg Comment Lines .....: 27.38
------ ----- ----- ------ ------ -----
Max LOC ...............: 116
Max eLOC ..............: 99 Max lLOC ..............: 62
Max LOC ...............: 112
Max eLOC ..............: 95 Max lLOC ..............: 62
Max Cyclomatic Comp. ..: 18 Max Interface Comp. ...: 8
Max Parameters ........: 7 Max Return Points .....: 1
Max Comment Lines .....: 79 Max Total Lines .......: 157
Max Comment Lines .....: 83 Max Total Lines .......: 152
------ ----- ----- ------ ------ -----
Min LOC ...............: 3
Min eLOC ..............: 2 Min lLOC ..............: 1

View File

@ -4,23 +4,59 @@
- @subpage posix (Linux, embedded-Linux, BSD, etc.)
- @subpage win32 API (Windows)
- @subpage win32-qv (Windows with QV)
*/
/*##########################################################################*/
/*! @page posix POSIX
@image html under_construction.jpg
<p>The QP/C/C++ ports and examples for POSIX (e.g., Embedded Linux, BSD, VxWorks, QNX, etc.) are described in the Quantum Leaps Application Note <a class="extern" target="_blank" href="https://state-machine.com/doc/AN_QP_and_POSIX.pdf"><strong>QP and POSIX</strong></a>.
</p>
@htmlonly
<div class="image">
<a target="_blank" href="https://state-machine.com/doc/AN_QP_and_POSIX.pdf"><img border="0" src="img/AN.jpg" title="Download PDF"></a>
<div class="caption">
Application Note: QP and POSIX
</div>
</div>
@endhtmlonly
The standard QP/C distribution contains the POSIX port and @ref exa_posix "Example Projects for POSIX".
*/
/*##########################################################################*/
/*! @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,30 +1,27 @@
/*****************************************************************************
/*$file${.::qmsmtst.c} #####################################################*/
/*
* Model: qmsmtst.qm
* File: ./qmsmtst.c
* File: C:/qp_lab/qpc/examples/posix/qmsmtst/qmsmtst.c
*
* This code has been generated by QM tool (see state-machine.com/qm).
* 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 # : QPC-EVAL-170201
* This code is covered by the following QP license:
* License # : QPC-EVAL-171231
* Issued to : Company/individual evaluating the QP/C framework
* Framework(s): qpc
* 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.c} ..........................................................*/
* https://state-machine.com/licensing/#RequestForm
*/
/*$endhead${.::qmsmtst.c} ##################################################*/
#include "qpc.h"
#include "qmsmtst.h"
#if ((QP_VERSION < 580) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8)))
#error qpc version 5.8.0 or higher required
#endif
/*$declare${SMs::QMsmTst} ##################################################*/
/*${SMs::QMsmTst} ..........................................................*/
typedef struct {
/* protected: */
@ -100,25 +97,32 @@ static QMState const QMsmTst_s211_s = {
Q_ACTION_CAST(&QMsmTst_s211_x),
Q_ACTION_CAST(0) /* no intitial tran. */
};
/*$enddecl${SMs::QMsmTst} ##################################################*/
static QMsmTst l_msmtst; /* the only instance of the QMsmTst class */
/* global-scope definitions ---------------------------------------*/
QMsm * const the_msm = (QMsm *)&l_msmtst; /* the opaque pointer */
/*$define${SMs::QMsmTst_ctor} ##############################################*/
/* Check for the minimum required QP version */
#if ((QP_VERSION < 601) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8)))
#error qpc version 6.0.1 or higher required
#endif
/*${SMs::QMsmTst_ctor} .....................................................*/
void QMsmTst_ctor(void) {
QMsmTst *me = &l_msmtst;
QMsm_ctor(&me->super, Q_STATE_CAST(&QMsmTst_initial));
}
/*$enddef${SMs::QMsmTst_ctor} ##############################################*/
/*$define${SMs::QMsmTst} ###################################################*/
/*${SMs::QMsmTst} ..........................................................*/
/*${SMs::QMsmTst::SM} ......................................................*/
static QState QMsmTst_initial(QMsmTst * const me, QEvt const * const e) {
static struct {
QMState const *target;
QActionHandler act[4];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s2_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_s_e), /* entry */
@ -127,31 +131,31 @@ static QState QMsmTst_initial(QMsmTst * const me, QEvt const * const e) {
Q_ACTION_CAST(0) /* zero terminator */
}
};
/* ${SMs::QMsmTst::SM::initial} */
/*${SMs::QMsmTst::SM::initial} */
(void)e; /* avoid compiler warning */
me->foo = 0U;
BSP_display("top-INIT;");
return QM_TRAN_INIT(&tatbl_);
}
/*${SMs::QMsmTst::SM::s} ...................................................*/
/* ${SMs::QMsmTst::SM::s} */
/*${SMs::QMsmTst::SM::s} */
static 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(&QMsmTst_s_s);
}
/* ${SMs::QMsmTst::SM::s} */
/*${SMs::QMsmTst::SM::s} */
static 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(&QMsmTst_s_s);
}
/* ${SMs::QMsmTst::SM::s::initial} */
/*${SMs::QMsmTst::SM::s::initial} */
static QState QMsmTst_s_i(QMsmTst * const me) {
static struct {
QMState const *target;
QActionHandler act[3];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s11_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_s1_e), /* entry */
@ -159,17 +163,17 @@ static 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} */
static QState QMsmTst_s(QMsmTst * const me, QEvt const * const e) {
QState status_;
switch (e->sig) {
/* ${SMs::QMsmTst::SM::s::I} */
/*${SMs::QMsmTst::SM::s::I} */
case I_SIG: {
/* ${SMs::QMsmTst::SM::s::I::[me->foo]} */
/*${SMs::QMsmTst::SM::s::I::[me->foo]} */
if (me->foo) {
me->foo = 0U;
BSP_display("s-I;");
@ -180,12 +184,12 @@ static QState QMsmTst_s(QMsmTst * const me, QEvt const * const e) {
}
break;
}
/* ${SMs::QMsmTst::SM::s::E} */
/*${SMs::QMsmTst::SM::s::E} */
case E_SIG: {
static struct {
QMState const *target;
QActionHandler act[3];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s11_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_s1_e), /* entry */
@ -197,7 +201,7 @@ static QState QMsmTst_s(QMsmTst * const me, QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
/* ${SMs::QMsmTst::SM::s::TERMINATE} */
/*${SMs::QMsmTst::SM::s::TERMINATE} */
case TERMINATE_SIG: {
BSP_exit();
status_ = QM_HANDLED();
@ -212,52 +216,52 @@ static QState QMsmTst_s(QMsmTst * const me, QEvt const * const e) {
return status_;
}
/*${SMs::QMsmTst::SM::s::s1} ...............................................*/
/* ${SMs::QMsmTst::SM::s::s1} */
/*${SMs::QMsmTst::SM::s::s1} */
static 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(&QMsmTst_s1_s);
}
/* ${SMs::QMsmTst::SM::s::s1} */
/*${SMs::QMsmTst::SM::s::s1} */
static 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(&QMsmTst_s1_s);
}
/* ${SMs::QMsmTst::SM::s::s1::initial} */
/*${SMs::QMsmTst::SM::s::s1::initial} */
static QState QMsmTst_s1_i(QMsmTst * const me) {
static struct {
QMState const *target;
QActionHandler act[2];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s11_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_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} */
static QState QMsmTst_s1(QMsmTst * const me, QEvt const * const e) {
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->foo]} */
/*${SMs::QMsmTst::SM::s::s1::D::[!me->foo]} */
if (!me->foo) {
static struct {
QMState const *target;
QActionHandler act[3];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_s1_x), /* exit */
@ -274,12 +278,12 @@ static QState QMsmTst_s1(QMsmTst * const me, QEvt const * const e) {
}
break;
}
/* ${SMs::QMsmTst::SM::s::s1::A} */
/*${SMs::QMsmTst::SM::s::s1::A} */
case A_SIG: {
static struct {
QMState const *target;
QActionHandler act[4];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s1_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_s1_x), /* exit */
@ -292,12 +296,12 @@ static QState QMsmTst_s1(QMsmTst * const me, 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 {
QMState const *target;
QActionHandler act[2];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s11_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_s11_e), /* entry */
@ -308,12 +312,12 @@ static QState QMsmTst_s1(QMsmTst * const me, 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 {
QMState const *target;
QActionHandler act[5];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s211_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_s1_x), /* exit */
@ -327,12 +331,12 @@ static QState QMsmTst_s1(QMsmTst * const me, 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 {
QMState const *target;
QActionHandler act[4];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s2_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_s1_x), /* exit */
@ -353,28 +357,28 @@ static QState QMsmTst_s1(QMsmTst * const me, QEvt const * const e) {
return status_;
}
/*${SMs::QMsmTst::SM::s::s1::s11} ..........................................*/
/* ${SMs::QMsmTst::SM::s::s1::s11} */
/*${SMs::QMsmTst::SM::s::s1::s11} */
static 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(&QMsmTst_s11_s);
}
/* ${SMs::QMsmTst::SM::s::s1::s11} */
/*${SMs::QMsmTst::SM::s::s1::s11} */
static 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(&QMsmTst_s11_s);
}
/* ${SMs::QMsmTst::SM::s::s1::s11} */
/*${SMs::QMsmTst::SM::s::s1::s11} */
static QState QMsmTst_s11(QMsmTst * const me, QEvt const * const e) {
QState status_;
switch (e->sig) {
/* ${SMs::QMsmTst::SM::s::s1::s11::H} */
/*${SMs::QMsmTst::SM::s::s1::s11::H} */
case H_SIG: {
static struct {
QMState const *target;
QActionHandler act[4];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_s11_x), /* exit */
@ -387,14 +391,14 @@ static QState QMsmTst_s11(QMsmTst * const me, 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->foo]} */
/*${SMs::QMsmTst::SM::s::s1::s11::D::[me->foo]} */
if (me->foo) {
static struct {
QMState const *target;
QActionHandler act[3];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s1_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_s11_x), /* exit */
@ -411,12 +415,12 @@ static QState QMsmTst_s11(QMsmTst * const me, QEvt const * const e) {
}
break;
}
/* ${SMs::QMsmTst::SM::s::s1::s11::G} */
/*${SMs::QMsmTst::SM::s::s1::s11::G} */
case G_SIG: {
static struct {
QMState const *target;
QActionHandler act[6];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s211_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_s11_x), /* exit */
@ -439,24 +443,24 @@ static QState QMsmTst_s11(QMsmTst * const me, QEvt const * const e) {
return status_;
}
/*${SMs::QMsmTst::SM::s::s2} ...............................................*/
/* ${SMs::QMsmTst::SM::s::s2} */
/*${SMs::QMsmTst::SM::s::s2} */
static 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(&QMsmTst_s2_s);
}
/* ${SMs::QMsmTst::SM::s::s2} */
/*${SMs::QMsmTst::SM::s::s2} */
static 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(&QMsmTst_s2_s);
}
/* ${SMs::QMsmTst::SM::s::s2::initial} */
/*${SMs::QMsmTst::SM::s::s2::initial} */
static QState QMsmTst_s2_i(QMsmTst * const me) {
static struct {
QMState const *target;
QActionHandler act[3];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s211_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_s21_e), /* entry */
@ -464,17 +468,17 @@ static 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} */
static QState QMsmTst_s2(QMsmTst * const me, QEvt const * const e) {
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->foo]} */
/*${SMs::QMsmTst::SM::s::s2::I::[!me->foo]} */
if (!me->foo) {
me->foo = 1U;
BSP_display("s2-I;");
@ -485,12 +489,12 @@ static QState QMsmTst_s2(QMsmTst * const me, QEvt const * const e) {
}
break;
}
/* ${SMs::QMsmTst::SM::s::s2::F} */
/*${SMs::QMsmTst::SM::s::s2::F} */
case F_SIG: {
static struct {
QMState const *target;
QActionHandler act[4];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s11_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_s2_x), /* exit */
@ -503,12 +507,12 @@ static QState QMsmTst_s2(QMsmTst * const me, 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 {
QMState const *target;
QActionHandler act[4];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s1_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_s2_x), /* exit */
@ -529,44 +533,44 @@ static QState QMsmTst_s2(QMsmTst * const me, QEvt const * const e) {
return status_;
}
/*${SMs::QMsmTst::SM::s::s2::s21} ..........................................*/
/* ${SMs::QMsmTst::SM::s::s2::s21} */
/*${SMs::QMsmTst::SM::s::s2::s21} */
static 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(&QMsmTst_s21_s);
}
/* ${SMs::QMsmTst::SM::s::s2::s21} */
/*${SMs::QMsmTst::SM::s::s2::s21} */
static 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(&QMsmTst_s21_s);
}
/* ${SMs::QMsmTst::SM::s::s2::s21::initial} */
/*${SMs::QMsmTst::SM::s::s2::s21::initial} */
static QState QMsmTst_s21_i(QMsmTst * const me) {
static struct {
QMState const *target;
QActionHandler act[2];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s211_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_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} */
static QState QMsmTst_s21(QMsmTst * const me, QEvt const * const e) {
QState status_;
switch (e->sig) {
/* ${SMs::QMsmTst::SM::s::s2::s21::G} */
/*${SMs::QMsmTst::SM::s::s2::s21::G} */
case G_SIG: {
static struct {
QMState const *target;
QActionHandler act[5];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s1_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_s21_x), /* exit */
@ -580,12 +584,12 @@ static QState QMsmTst_s21(QMsmTst * const me, 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 {
QMState const *target;
QActionHandler act[4];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s21_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_s21_x), /* exit */
@ -598,12 +602,12 @@ static QState QMsmTst_s21(QMsmTst * const me, 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 {
QMState const *target;
QActionHandler act[2];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s211_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_s211_e), /* entry */
@ -622,28 +626,28 @@ static QState QMsmTst_s21(QMsmTst * const me, QEvt const * const e) {
return status_;
}
/*${SMs::QMsmTst::SM::s::s2::s21::s211} ....................................*/
/* ${SMs::QMsmTst::SM::s::s2::s21::s211} */
/*${SMs::QMsmTst::SM::s::s2::s21::s211} */
static 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(&QMsmTst_s211_s);
}
/* ${SMs::QMsmTst::SM::s::s2::s21::s211} */
/*${SMs::QMsmTst::SM::s::s2::s21::s211} */
static 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(&QMsmTst_s211_s);
}
/* ${SMs::QMsmTst::SM::s::s2::s21::s211} */
/*${SMs::QMsmTst::SM::s::s2::s21::s211} */
static QState QMsmTst_s211(QMsmTst * const me, QEvt const * const e) {
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 {
QMState const *target;
QActionHandler act[5];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_s211_x), /* exit */
@ -657,12 +661,12 @@ static QState QMsmTst_s211(QMsmTst * const me, 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 {
QMState const *target;
QActionHandler act[3];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s21_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_s211_x), /* exit */
@ -681,4 +685,4 @@ static QState QMsmTst_s211(QMsmTst * const me, QEvt const * const e) {
}
return status_;
}
/*$enddef${SMs::QMsmTst} ###################################################*/

View File

@ -1,22 +1,23 @@
/*****************************************************************************
/*$file${.::qmsmtst.h} #####################################################*/
/*
* Model: qmsmtst.qm
* File: ./qmsmtst.h
* File: C:/qp_lab/qpc/examples/posix/qmsmtst/qmsmtst.h
*
* This code has been generated by QM tool (see state-machine.com/qm).
* 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 # : QPC-EVAL-170201
* This code is covered by the following QP license:
* License # : QPC-EVAL-171231
* Issued to : Company/individual evaluating the QP/C framework
* Framework(s): qpc
* 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
@ -37,12 +38,13 @@ enum QMsmTstSignals {
extern QMsm * const the_msm; /* opaque pointer to the test MSM */
/*$declare${SMs::QMsmTst_ctor} #############################################*/
/*${SMs::QMsmTst_ctor} .....................................................*/
void QMsmTst_ctor(void);
/*$enddecl${SMs::QMsmTst_ctor} #############################################*/
/* BSP functions to dispaly a message and exit */
void BSP_display(char const *msg);
void BSP_exit(void);
#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 QMsm state machine test based on the 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="qpc" license="../../../QPC-EVAL-170201.qlc"/>
<framework name="qpc" license="../../../QPC-EVAL-171231.qlc"/>
<package name="SMs" stereotype="0x02">
<class name="QMsmTst" superclass="qpc::QMsm">
<documentation>Test active object</documentation>

View File

@ -1,30 +1,27 @@
/*****************************************************************************
/*$file${.::qmsmtst.c} #####################################################*/
/*
* Model: qmsmtst.qm
* File: ./qmsmtst.c
* File: C:/qp_lab/qpc/examples/qutest/qmsmtst/qmsmtst.c
*
* This code has been generated by QM tool (see state-machine.com/qm).
* 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 # : QPC-EVAL-590
* This code is covered by the following QP license:
* License # : QPC-EVAL-171231
* Issued to : Company/individual evaluating the QP/C framework
* Framework(s): qpc
* 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.c} ..........................................................*/
*/
/*$endhead${.::qmsmtst.c} ##################################################*/
#include "qpc.h"
#include "qmsmtst.h"
#if ((QP_VERSION < 580) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8)))
#error qpc version 5.8.0 or higher required
#endif
/*$declare${SMs::QMsmTst} ##################################################*/
/*${SMs::QMsmTst} ..........................................................*/
typedef struct {
/* protected: */
@ -100,25 +97,32 @@ static QMState const QMsmTst_s211_s = {
Q_ACTION_CAST(&QMsmTst_s211_x),
Q_ACTION_CAST(0) /* no intitial tran. */
};
/*$enddecl${SMs::QMsmTst} ##################################################*/
static QMsmTst l_msmtst; /* the only instance of the QMsmTst class */
/* global-scope definitions ---------------------------------------*/
QMsm * const the_msm = (QMsm *)&l_msmtst; /* the opaque pointer */
/*$define${SMs::QMsmTst_ctor} ##############################################*/
/* Check for the minimum required QP version */
#if ((QP_VERSION < 601) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8)))
#error qpc version 6.0.1 or higher required
#endif
/*${SMs::QMsmTst_ctor} .....................................................*/
void QMsmTst_ctor(void) {
QMsmTst *me = &l_msmtst;
QMsm_ctor(&me->super, Q_STATE_CAST(&QMsmTst_initial));
}
/*$enddef${SMs::QMsmTst_ctor} ##############################################*/
/*$define${SMs::QMsmTst} ###################################################*/
/*${SMs::QMsmTst} ..........................................................*/
/*${SMs::QMsmTst::SM} ......................................................*/
static QState QMsmTst_initial(QMsmTst * const me, QEvt const * const e) {
static struct {
QMState const *target;
QActionHandler act[4];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s2_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_s_e), /* entry */
@ -127,7 +131,7 @@ static QState QMsmTst_initial(QMsmTst * const me, QEvt const * const e) {
Q_ACTION_CAST(0) /* zero terminator */
}
};
/* ${SMs::QMsmTst::SM::initial} */
/*${SMs::QMsmTst::SM::initial} */
(void)e; /* avoid compiler warning */
me->foo = 0U;
BSP_display("top-INIT;");
@ -153,24 +157,24 @@ static QState QMsmTst_initial(QMsmTst * const me, QEvt const * const e) {
return QM_TRAN_INIT(&tatbl_);
}
/*${SMs::QMsmTst::SM::s} ...................................................*/
/* ${SMs::QMsmTst::SM::s} */
/*${SMs::QMsmTst::SM::s} */
static 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(&QMsmTst_s_s);
}
/* ${SMs::QMsmTst::SM::s} */
/*${SMs::QMsmTst::SM::s} */
static 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(&QMsmTst_s_s);
}
/* ${SMs::QMsmTst::SM::s::initial} */
/*${SMs::QMsmTst::SM::s::initial} */
static QState QMsmTst_s_i(QMsmTst * const me) {
static struct {
QMState const *target;
QActionHandler act[3];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s11_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_s1_e), /* entry */
@ -178,17 +182,17 @@ static 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} */
static QState QMsmTst_s(QMsmTst * const me, QEvt const * const e) {
QState status_;
switch (e->sig) {
/* ${SMs::QMsmTst::SM::s::I} */
/*${SMs::QMsmTst::SM::s::I} */
case I_SIG: {
/* ${SMs::QMsmTst::SM::s::I::[me->foo]} */
/*${SMs::QMsmTst::SM::s::I::[me->foo]} */
if (me->foo) {
me->foo = 0U;
BSP_display("s-I;");
@ -199,12 +203,12 @@ static QState QMsmTst_s(QMsmTst * const me, QEvt const * const e) {
}
break;
}
/* ${SMs::QMsmTst::SM::s::E} */
/*${SMs::QMsmTst::SM::s::E} */
case E_SIG: {
static struct {
QMState const *target;
QActionHandler act[3];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s11_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_s1_e), /* entry */
@ -216,7 +220,7 @@ static QState QMsmTst_s(QMsmTst * const me, QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
/* ${SMs::QMsmTst::SM::s::TERMINATE} */
/*${SMs::QMsmTst::SM::s::TERMINATE} */
case TERMINATE_SIG: {
BSP_exit();
status_ = QM_HANDLED();
@ -231,52 +235,52 @@ static QState QMsmTst_s(QMsmTst * const me, QEvt const * const e) {
return status_;
}
/*${SMs::QMsmTst::SM::s::s1} ...............................................*/
/* ${SMs::QMsmTst::SM::s::s1} */
/*${SMs::QMsmTst::SM::s::s1} */
static 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(&QMsmTst_s1_s);
}
/* ${SMs::QMsmTst::SM::s::s1} */
/*${SMs::QMsmTst::SM::s::s1} */
static 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(&QMsmTst_s1_s);
}
/* ${SMs::QMsmTst::SM::s::s1::initial} */
/*${SMs::QMsmTst::SM::s::s1::initial} */
static QState QMsmTst_s1_i(QMsmTst * const me) {
static struct {
QMState const *target;
QActionHandler act[2];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s11_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_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} */
static QState QMsmTst_s1(QMsmTst * const me, QEvt const * const e) {
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->foo]} */
/*${SMs::QMsmTst::SM::s::s1::D::[!me->foo]} */
if (!me->foo) {
static struct {
QMState const *target;
QActionHandler act[3];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_s1_x), /* exit */
@ -293,12 +297,12 @@ static QState QMsmTst_s1(QMsmTst * const me, QEvt const * const e) {
}
break;
}
/* ${SMs::QMsmTst::SM::s::s1::A} */
/*${SMs::QMsmTst::SM::s::s1::A} */
case A_SIG: {
static struct {
QMState const *target;
QActionHandler act[4];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s1_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_s1_x), /* exit */
@ -311,12 +315,12 @@ static QState QMsmTst_s1(QMsmTst * const me, 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 {
QMState const *target;
QActionHandler act[2];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s11_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_s11_e), /* entry */
@ -327,12 +331,12 @@ static QState QMsmTst_s1(QMsmTst * const me, 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 {
QMState const *target;
QActionHandler act[5];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s211_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_s1_x), /* exit */
@ -346,12 +350,12 @@ static QState QMsmTst_s1(QMsmTst * const me, 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 {
QMState const *target;
QActionHandler act[4];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s2_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_s1_x), /* exit */
@ -372,28 +376,28 @@ static QState QMsmTst_s1(QMsmTst * const me, QEvt const * const e) {
return status_;
}
/*${SMs::QMsmTst::SM::s::s1::s11} ..........................................*/
/* ${SMs::QMsmTst::SM::s::s1::s11} */
/*${SMs::QMsmTst::SM::s::s1::s11} */
static 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(&QMsmTst_s11_s);
}
/* ${SMs::QMsmTst::SM::s::s1::s11} */
/*${SMs::QMsmTst::SM::s::s1::s11} */
static 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(&QMsmTst_s11_s);
}
/* ${SMs::QMsmTst::SM::s::s1::s11} */
/*${SMs::QMsmTst::SM::s::s1::s11} */
static QState QMsmTst_s11(QMsmTst * const me, QEvt const * const e) {
QState status_;
switch (e->sig) {
/* ${SMs::QMsmTst::SM::s::s1::s11::H} */
/*${SMs::QMsmTst::SM::s::s1::s11::H} */
case H_SIG: {
static struct {
QMState const *target;
QActionHandler act[4];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_s11_x), /* exit */
@ -406,14 +410,14 @@ static QState QMsmTst_s11(QMsmTst * const me, 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->foo]} */
/*${SMs::QMsmTst::SM::s::s1::s11::D::[me->foo]} */
if (me->foo) {
static struct {
QMState const *target;
QActionHandler act[3];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s1_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_s11_x), /* exit */
@ -430,12 +434,12 @@ static QState QMsmTst_s11(QMsmTst * const me, QEvt const * const e) {
}
break;
}
/* ${SMs::QMsmTst::SM::s::s1::s11::G} */
/*${SMs::QMsmTst::SM::s::s1::s11::G} */
case G_SIG: {
static struct {
QMState const *target;
QActionHandler act[6];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s211_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_s11_x), /* exit */
@ -458,24 +462,24 @@ static QState QMsmTst_s11(QMsmTst * const me, QEvt const * const e) {
return status_;
}
/*${SMs::QMsmTst::SM::s::s2} ...............................................*/
/* ${SMs::QMsmTst::SM::s::s2} */
/*${SMs::QMsmTst::SM::s::s2} */
static 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(&QMsmTst_s2_s);
}
/* ${SMs::QMsmTst::SM::s::s2} */
/*${SMs::QMsmTst::SM::s::s2} */
static 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(&QMsmTst_s2_s);
}
/* ${SMs::QMsmTst::SM::s::s2::initial} */
/*${SMs::QMsmTst::SM::s::s2::initial} */
static QState QMsmTst_s2_i(QMsmTst * const me) {
static struct {
QMState const *target;
QActionHandler act[3];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s211_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_s21_e), /* entry */
@ -483,17 +487,17 @@ static 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} */
static QState QMsmTst_s2(QMsmTst * const me, QEvt const * const e) {
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->foo]} */
/*${SMs::QMsmTst::SM::s::s2::I::[!me->foo]} */
if (!me->foo) {
me->foo = 1U;
BSP_display("s2-I;");
@ -504,12 +508,12 @@ static QState QMsmTst_s2(QMsmTst * const me, QEvt const * const e) {
}
break;
}
/* ${SMs::QMsmTst::SM::s::s2::F} */
/*${SMs::QMsmTst::SM::s::s2::F} */
case F_SIG: {
static struct {
QMState const *target;
QActionHandler act[4];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s11_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_s2_x), /* exit */
@ -522,12 +526,12 @@ static QState QMsmTst_s2(QMsmTst * const me, 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 {
QMState const *target;
QActionHandler act[4];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s1_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_s2_x), /* exit */
@ -548,44 +552,44 @@ static QState QMsmTst_s2(QMsmTst * const me, QEvt const * const e) {
return status_;
}
/*${SMs::QMsmTst::SM::s::s2::s21} ..........................................*/
/* ${SMs::QMsmTst::SM::s::s2::s21} */
/*${SMs::QMsmTst::SM::s::s2::s21} */
static 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(&QMsmTst_s21_s);
}
/* ${SMs::QMsmTst::SM::s::s2::s21} */
/*${SMs::QMsmTst::SM::s::s2::s21} */
static 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(&QMsmTst_s21_s);
}
/* ${SMs::QMsmTst::SM::s::s2::s21::initial} */
/*${SMs::QMsmTst::SM::s::s2::s21::initial} */
static QState QMsmTst_s21_i(QMsmTst * const me) {
static struct {
QMState const *target;
QActionHandler act[2];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s211_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_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} */
static QState QMsmTst_s21(QMsmTst * const me, QEvt const * const e) {
QState status_;
switch (e->sig) {
/* ${SMs::QMsmTst::SM::s::s2::s21::G} */
/*${SMs::QMsmTst::SM::s::s2::s21::G} */
case G_SIG: {
static struct {
QMState const *target;
QActionHandler act[5];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s1_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_s21_x), /* exit */
@ -599,12 +603,12 @@ static QState QMsmTst_s21(QMsmTst * const me, 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 {
QMState const *target;
QActionHandler act[4];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s21_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_s21_x), /* exit */
@ -617,12 +621,12 @@ static QState QMsmTst_s21(QMsmTst * const me, 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 {
QMState const *target;
QActionHandler act[2];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s211_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_s211_e), /* entry */
@ -641,28 +645,28 @@ static QState QMsmTst_s21(QMsmTst * const me, QEvt const * const e) {
return status_;
}
/*${SMs::QMsmTst::SM::s::s2::s21::s211} ....................................*/
/* ${SMs::QMsmTst::SM::s::s2::s21::s211} */
/*${SMs::QMsmTst::SM::s::s2::s21::s211} */
static 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(&QMsmTst_s211_s);
}
/* ${SMs::QMsmTst::SM::s::s2::s21::s211} */
/*${SMs::QMsmTst::SM::s::s2::s21::s211} */
static 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(&QMsmTst_s211_s);
}
/* ${SMs::QMsmTst::SM::s::s2::s21::s211} */
/*${SMs::QMsmTst::SM::s::s2::s21::s211} */
static QState QMsmTst_s211(QMsmTst * const me, QEvt const * const e) {
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 {
QMState const *target;
QActionHandler act[5];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_s211_x), /* exit */
@ -676,12 +680,12 @@ static QState QMsmTst_s211(QMsmTst * const me, 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 {
QMState const *target;
QActionHandler act[3];
} const tatbl_ = { /* transition-action table */
} const tatbl_ = { /* tran-action table */
&QMsmTst_s21_s, /* target state */
{
Q_ACTION_CAST(&QMsmTst_s211_x), /* exit */
@ -700,4 +704,4 @@ static QState QMsmTst_s211(QMsmTst * const me, QEvt const * const e) {
}
return status_;
}
/*$enddef${SMs::QMsmTst} ###################################################*/

View File

@ -1,22 +1,23 @@
/*****************************************************************************
/*$file${.::qmsmtst.h} #####################################################*/
/*
* Model: qmsmtst.qm
* File: ./qmsmtst.h
* File: C:/qp_lab/qpc/examples/qutest/qmsmtst/qmsmtst.h
*
* This code has been generated by QM tool (see state-machine.com/qm).
* 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 # : QPC-EVAL-590
* This code is covered by the following QP license:
* License # : QPC-EVAL-171231
* Issued to : Company/individual evaluating the QP/C framework
* Framework(s): qpc
* 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
@ -37,12 +38,13 @@ enum QMsmTstSignals {
extern QMsm * const the_msm; /* opaque pointer to the test MSM */
/*$declare${SMs::QMsmTst_ctor} #############################################*/
/*${SMs::QMsmTst_ctor} .....................................................*/
void QMsmTst_ctor(void);
/*$enddecl${SMs::QMsmTst_ctor} #############################################*/
/* BSP functions to dispaly a message and exit */
void BSP_display(char const *msg);
void BSP_exit(void);
#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 QMsm state machine test based on the 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="qpc" license="../../../QPC-EVAL-590.qlc"/>
<framework name="qpc" license="../../../QPC-EVAL-171231.qlc"/>
<package name="SMs" stereotype="0x02">
<class name="QMsmTst" superclass="qpc::QMsm">
<documentation>Test active object</documentation>

View File

@ -1,8 +1,9 @@
/*****************************************************************************
/*$file${.::calc1_sub.c} ###################################################*/
/*
* Model: calc1_sub.qm
* File: ./calc1_sub.c
* File: C:/qp_lab/qpc/examples/win32/calc1_sub/calc1_sub.c
*
* This code has been generated by QM tool (see state-machine.com/qm).
* 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.c} ........................................................*/
*/
/*$endhead${.::calc1_sub.c} ################################################*/
#include "qep_port.h" /* QEP/C interface */
#include "bsp.h" /* board support package */
#include "calc1_sub.h" /* application */
#if ((QP_VERSION < 591) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8)))
#error qpc version 5.9.1 or higher required
#endif
/*$declare${SMs::Calc} #####################################################*/
/*${SMs::Calc} .............................................................*/
typedef struct {
/* protected: */
@ -196,18 +193,25 @@ static QMState const Calc_operand_neg_s = {
Q_ACTION_CAST(&Calc_operand_neg_x),
Q_ACTION_CAST(0) /* no intitial tran. */
};
/*$enddecl${SMs::Calc} #####################################################*/
static Calc l_calc; /* the only instance of the Calc class */
/* global-scope definitions ---------------------------------------*/
QMsm * const the_calc = &l_calc.super; /* "opaque" pointer to MSM */
/*$define${SMs::Calc_ctor} #################################################*/
/* Check for the minimum required QP version */
#if ((QP_VERSION < 601) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8)))
#error qpc version 6.0.1 or higher required
#endif
/*${SMs::Calc_ctor} ........................................................*/
void Calc_ctor(void) {
Calc *me = &l_calc;
QMsm_ctor(&me->super, Q_STATE_CAST(&Calc_initial));
}
/*$enddef${SMs::Calc_ctor} #################################################*/
/*$define${SMs::Calc} ######################################################*/
/*${SMs::Calc} .............................................................*/
/*${SMs::Calc::SM} .........................................................*/
static QState Calc_initial(Calc * const me, QEvt const * const e) {
@ -222,25 +226,25 @@ static QState Calc_initial(Calc * const me, 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_);
}
/*${SMs::Calc::SM::on} .....................................................*/
/* ${SMs::Calc::SM::on} */
/*${SMs::Calc::SM::on} */
static 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(&Calc_on_s);
}
/* ${SMs::Calc::SM::on} */
/*${SMs::Calc::SM::on} */
static 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(&Calc_on_s);
}
/* ${SMs::Calc::SM::on::initial} */
/*${SMs::Calc::SM::on::initial} */
static QState Calc_on_i(Calc * const me) {
static struct {
QMState const *target;
@ -253,15 +257,15 @@ static 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} */
static QState Calc_on(Calc * const me, QEvt const * const e) {
QState status_;
switch (e->sig) {
/* ${SMs::Calc::SM::on::C} */
/*${SMs::Calc::SM::on::C} */
case C_SIG: {
static struct {
QMState const *target;
@ -279,7 +283,7 @@ static QState Calc_on(Calc * const me, QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
/* ${SMs::Calc::SM::on::OFF} */
/*${SMs::Calc::SM::on::OFF} */
case OFF_SIG: {
static struct {
QMState const *target;
@ -303,19 +307,19 @@ static QState Calc_on(Calc * const me, QEvt const * const e) {
return status_;
}
/*${SMs::Calc::SM::on::ready} ..............................................*/
/* ${SMs::Calc::SM::on::ready} */
/*${SMs::Calc::SM::on::ready} */
static 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(&Calc_ready_s);
}
/* ${SMs::Calc::SM::on::ready} */
/*${SMs::Calc::SM::on::ready} */
static 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(&Calc_ready_s);
}
/* ${SMs::Calc::SM::on::ready::initial} */
/*${SMs::Calc::SM::on::ready::initial} */
static QState Calc_ready_i(Calc * const me) {
static struct {
QMState const *target;
@ -327,15 +331,15 @@ static 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} */
static QState Calc_ready(Calc * const me, QEvt const * const e) {
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 {
QMState const *target;
@ -350,10 +354,10 @@ static QState Calc_ready(Calc * const me, QEvt const * const e) {
}
};
BSP_clear();
status_ = QM_TRAN(&tatbl_);
status_ = QM_TRAN_EP(&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 {
QMState const *target;
@ -369,10 +373,10 @@ static QState Calc_ready(Calc * const me, 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 {
QMState const *target;
@ -389,10 +393,10 @@ static QState Calc_ready(Calc * const me, 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 {
QMState const *target;
@ -418,19 +422,19 @@ static QState Calc_ready(Calc * const me, QEvt const * const e) {
return status_;
}
/*${SMs::Calc::SM::on::ready::result} ......................................*/
/* ${SMs::Calc::SM::on::ready::result} */
/*${SMs::Calc::SM::on::ready::result} */
static 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(&Calc_result_s);
}
/* ${SMs::Calc::SM::on::ready::result} */
/*${SMs::Calc::SM::on::ready::result} */
static 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(&Calc_result_s);
}
/* ${SMs::Calc::SM::on::ready::result} */
/*${SMs::Calc::SM::on::ready::result} */
static QState Calc_result(Calc * const me, QEvt const * const e) {
QState status_;
switch (e->sig) {
@ -443,25 +447,25 @@ static QState Calc_result(Calc * const me, QEvt const * const e) {
return status_;
}
/*${SMs::Calc::SM::on::ready::begin} .......................................*/
/* ${SMs::Calc::SM::on::ready::begin} */
/*${SMs::Calc::SM::on::ready::begin} */
static 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(&Calc_begin_s);
}
/* ${SMs::Calc::SM::on::ready::begin} */
/*${SMs::Calc::SM::on::ready::begin} */
static 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(&Calc_begin_s);
}
/* ${SMs::Calc::SM::on::ready::begin} */
/*${SMs::Calc::SM::on::ready::begin} */
static QState Calc_begin(Calc * const me, QEvt const * const e) {
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 {
QMState const *target;
@ -476,9 +480,9 @@ static QState Calc_begin(Calc * const me, 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();
}
@ -493,12 +497,12 @@ static QState Calc_begin(Calc * const me, QEvt const * const e) {
return status_;
}
/*${SMs::Calc::SM::on::operand1} ...........................................*/
/* ${SMs::Calc::SM::on::operand1} */
/*${SMs::Calc::SM::on::operand1} */
static QState Calc_operand1_e(Calc * const me) {
me->sub_operand = &Calc_operand1_s; /* attach submachine */
return Calc_operand_e(me); /* enter submachine */
}
/* ${SMs::Calc::SM::on::operand1} */
/*${SMs::Calc::SM::on::operand1} */
static QState Calc_operand1_ce(Calc * const me) {
static struct {
QMState const *target;
@ -515,11 +519,11 @@ static QState Calc_operand1_ce(Calc * const me) {
(void)me; /* avoid compiler warning in case 'me' is not used */
return QM_TRAN(&tatbl_);
}
/* ${SMs::Calc::SM::on::operand1} */
/*${SMs::Calc::SM::on::operand1} */
static QState Calc_operand1(Calc * const me, QEvt const * const e) {
QState status_;
switch (e->sig) {
/* ${SMs::Calc::SM::on::operand1::OPER} */
/*${SMs::Calc::SM::on::operand1::OPER} */
case OPER_SIG: {
static struct {
QMState const *target;
@ -536,7 +540,7 @@ static QState Calc_operand1(Calc * const me, 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 {
QMState const *target;
@ -560,23 +564,23 @@ static QState Calc_operand1(Calc * const me, QEvt const * const e) {
return status_;
}
/*${SMs::Calc::SM::on::opEntered} ..........................................*/
/* ${SMs::Calc::SM::on::opEntered} */
/*${SMs::Calc::SM::on::opEntered} */
static 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(&Calc_opEntered_s);
}
/* ${SMs::Calc::SM::on::opEntered} */
/*${SMs::Calc::SM::on::opEntered} */
static 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(&Calc_opEntered_s);
}
/* ${SMs::Calc::SM::on::opEntered} */
/*${SMs::Calc::SM::on::opEntered} */
static QState Calc_opEntered(Calc * const me, QEvt const * const e) {
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 {
QMState const *target;
@ -591,10 +595,10 @@ static QState Calc_opEntered(Calc * const me, 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 {
QMState const *target;
@ -610,10 +614,10 @@ static QState Calc_opEntered(Calc * const me, 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 {
QMState const *target;
@ -630,12 +634,12 @@ static QState Calc_opEntered(Calc * const me, 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 {
QMState const *target;
@ -649,9 +653,9 @@ static QState Calc_opEntered(Calc * const me, 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();
}
@ -666,19 +670,19 @@ static QState Calc_opEntered(Calc * const me, QEvt const * const e) {
return status_;
}
/*${SMs::Calc::SM::on::error} ..............................................*/
/* ${SMs::Calc::SM::on::error} */
/*${SMs::Calc::SM::on::error} */
static 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(&Calc_error_s);
}
/* ${SMs::Calc::SM::on::error} */
/*${SMs::Calc::SM::on::error} */
static 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(&Calc_error_s);
}
/* ${SMs::Calc::SM::on::error} */
/*${SMs::Calc::SM::on::error} */
static QState Calc_error(Calc * const me, QEvt const * const e) {
QState status_;
switch (e->sig) {
@ -691,12 +695,12 @@ static QState Calc_error(Calc * const me, QEvt const * const e) {
return status_;
}
/*${SMs::Calc::SM::on::operand2} ...........................................*/
/* ${SMs::Calc::SM::on::operand2} */
/*${SMs::Calc::SM::on::operand2} */
static QState Calc_operand2_e(Calc * const me) {
me->sub_operand = &Calc_operand2_s; /* attach submachine */
return Calc_operand_e(me); /* enter submachine */
}
/* ${SMs::Calc::SM::on::operand2} */
/*${SMs::Calc::SM::on::operand2} */
static QState Calc_operand2_ce(Calc * const me) {
static struct {
QMState const *target;
@ -712,13 +716,13 @@ static QState Calc_operand2_ce(Calc * const me) {
(void)me; /* avoid compiler warning in case 'me' is not used */
return QM_TRAN(&tatbl_);
}
/* ${SMs::Calc::SM::on::operand2} */
/*${SMs::Calc::SM::on::operand2} */
static QState Calc_operand2(Calc * const me, QEvt const * const e) {
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->op1, me->oper, BSP_get_value())) {
static struct {
QMState const *target;
@ -732,7 +736,7 @@ static QState Calc_operand2(Calc * const me, 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 {
QMState const *target;
@ -748,9 +752,9 @@ static QState Calc_operand2(Calc * const me, 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->op1, me->oper, BSP_get_value())) {
static struct {
QMState const *target;
@ -765,7 +769,7 @@ static QState Calc_operand2(Calc * const me, 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 {
QMState const *target;
@ -789,14 +793,14 @@ static QState Calc_operand2(Calc * const me, QEvt const * const e) {
return status_;
}
/*${SMs::Calc::SM::final} ..................................................*/
/* ${SMs::Calc::SM::final} */
/*${SMs::Calc::SM::final} */
static 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(&Calc_final_s);
}
/* ${SMs::Calc::SM::final} */
/*${SMs::Calc::SM::final} */
static QState Calc_final(Calc * const me, QEvt const * const e) {
QState status_;
switch (e->sig) {
@ -809,22 +813,22 @@ static QState Calc_final(Calc * const me, QEvt const * const e) {
return status_;
}
/*${SMs::Calc::SM::operand} ................................................*/
/* ${SMs::Calc::SM::operand} */
/*${SMs::Calc::SM::operand} */
static 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(&Calc_operand_s);
}
/* ${SMs::Calc::SM::operand} */
/*${SMs::Calc::SM::operand} */
static QState Calc_operand_x(Calc * const me) {
BSP_message("operand-EXIT;");
return QM_SM_EXIT(&me->sub_operand->super);
}
/* ${SMs::Calc::SM::operand} */
/*${SMs::Calc::SM::operand} */
static QState Calc_operand(Calc * const me, QEvt const * const e) {
QState status_;
switch (e->sig) {
/* ${SMs::Calc::SM::operand::CE} */
/*${SMs::Calc::SM::operand::CE} */
case CE_SIG: {
static QMTranActTable const tatbl_ = { /* tran-action table */
&Calc_operand_s, /* target submachine */
@ -844,7 +848,7 @@ static QState Calc_operand(Calc * const me, QEvt const * const e) {
}
return status_;
}
/* ${SMs::Calc::SM::operand::zero} */
/*${SMs::Calc::SM::operand::zero} */
static QState Calc_operand_zero_ep(Calc * const me) {
static struct {
QMState const *target;
@ -859,7 +863,7 @@ static QState Calc_operand_zero_ep(Calc * const me) {
BSP_message("EP:zero;");
return QM_TRAN_EP(&tatbl_);
}
/* ${SMs::Calc::SM::operand::intgr} */
/*${SMs::Calc::SM::operand::intgr} */
static QState Calc_operand_intgr_ep(Calc * const me) {
static struct {
QMState const *target;
@ -874,7 +878,7 @@ static QState Calc_operand_intgr_ep(Calc * const me) {
BSP_message("EP:intgr;");
return QM_TRAN_EP(&tatbl_);
}
/* ${SMs::Calc::SM::operand::frac} */
/*${SMs::Calc::SM::operand::frac} */
static QState Calc_operand_frac_ep(Calc * const me) {
static struct {
QMState const *target;
@ -889,7 +893,7 @@ static QState Calc_operand_frac_ep(Calc * const me) {
BSP_message("EP:frac;");
return QM_TRAN_EP(&tatbl_);
}
/* ${SMs::Calc::SM::operand::neg} */
/*${SMs::Calc::SM::operand::neg} */
static QState Calc_operand_neg_ep(Calc * const me) {
static struct {
QMState const *target;
@ -905,29 +909,29 @@ static QState Calc_operand_neg_ep(Calc * const me) {
return QM_TRAN_EP(&tatbl_);
}
/*${SMs::Calc::SM::operand::zero} ..........................................*/
/* ${SMs::Calc::SM::operand::zero} */
/*${SMs::Calc::SM::operand::zero} */
static QState Calc_operand_zero_e(Calc * const me) {
BSP_message("zero-ENTRY;");
(void)me; /* avoid compiler warning in case 'me' is not used */
return QM_ENTRY(&Calc_operand_zero_s);
}
/* ${SMs::Calc::SM::operand::zero} */
/*${SMs::Calc::SM::operand::zero} */
static QState Calc_operand_zero_x(Calc * const me) {
BSP_message("zero-EXIT;");
(void)me; /* avoid compiler warning in case 'me' is not used */
return QM_EXIT(&Calc_operand_zero_s);
}
/* ${SMs::Calc::SM::operand::zero} */
/*${SMs::Calc::SM::operand::zero} */
static QState Calc_operand_zero(Calc * const me, QEvt const * const e) {
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 {
QMState const *target;
@ -944,7 +948,7 @@ static QState Calc_operand_zero(Calc * const me, 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 {
QMState const *target;
@ -970,23 +974,23 @@ static QState Calc_operand_zero(Calc * const me, QEvt const * const e) {
return status_;
}
/*${SMs::Calc::SM::operand::intgr} .........................................*/
/* ${SMs::Calc::SM::operand::intgr} */
/*${SMs::Calc::SM::operand::intgr} */
static QState Calc_operand_intgr_e(Calc * const me) {
BSP_message("intgr-ENTRY;");
(void)me; /* avoid compiler warning in case 'me' is not used */
return QM_ENTRY(&Calc_operand_intgr_s);
}
/* ${SMs::Calc::SM::operand::intgr} */
/*${SMs::Calc::SM::operand::intgr} */
static QState Calc_operand_intgr_x(Calc * const me) {
BSP_message("intgr-EXIT;");
(void)me; /* avoid compiler warning in case 'me' is not used */
return QM_EXIT(&Calc_operand_intgr_s);
}
/* ${SMs::Calc::SM::operand::intgr} */
/*${SMs::Calc::SM::operand::intgr} */
static QState Calc_operand_intgr(Calc * const me, QEvt const * const e) {
QState status_;
switch (e->sig) {
/* ${SMs::Calc::SM::operand::intgr::POINT} */
/*${SMs::Calc::SM::operand::intgr::POINT} */
case POINT_SIG: {
static struct {
QMState const *target;
@ -1003,7 +1007,7 @@ static QState Calc_operand_intgr(Calc * const me, 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);
@ -1019,29 +1023,29 @@ static QState Calc_operand_intgr(Calc * const me, QEvt const * const e) {
return status_;
}
/*${SMs::Calc::SM::operand::frac} ..........................................*/
/* ${SMs::Calc::SM::operand::frac} */
/*${SMs::Calc::SM::operand::frac} */
static QState Calc_operand_frac_e(Calc * const me) {
BSP_message("frac-ENTRY;");
(void)me; /* avoid compiler warning in case 'me' is not used */
return QM_ENTRY(&Calc_operand_frac_s);
}
/* ${SMs::Calc::SM::operand::frac} */
/*${SMs::Calc::SM::operand::frac} */
static QState Calc_operand_frac_x(Calc * const me) {
BSP_message("frac-EXIT;");
(void)me; /* avoid compiler warning in case 'me' is not used */
return QM_EXIT(&Calc_operand_frac_s);
}
/* ${SMs::Calc::SM::operand::frac} */
/*${SMs::Calc::SM::operand::frac} */
static QState Calc_operand_frac(Calc * const me, QEvt const * const e) {
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);
@ -1057,24 +1061,24 @@ static QState Calc_operand_frac(Calc * const me, QEvt const * const e) {
return status_;
}
/*${SMs::Calc::SM::operand::neg} ...........................................*/
/* ${SMs::Calc::SM::operand::neg} */
/*${SMs::Calc::SM::operand::neg} */
static QState Calc_operand_neg_e(Calc * const me) {
BSP_message("neg-ENTRY;");
BSP_negate();
(void)me; /* avoid compiler warning in case 'me' is not used */
return QM_ENTRY(&Calc_operand_neg_s);
}
/* ${SMs::Calc::SM::operand::neg} */
/*${SMs::Calc::SM::operand::neg} */
static QState Calc_operand_neg_x(Calc * const me) {
BSP_message("neg-EXIT;");
(void)me; /* avoid compiler warning in case 'me' is not used */
return QM_EXIT(&Calc_operand_neg_s);
}
/* ${SMs::Calc::SM::operand::neg} */
/*${SMs::Calc::SM::operand::neg} */
static QState Calc_operand_neg(Calc * const me, QEvt const * const e) {
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 {
QMState const *target;
@ -1091,7 +1095,7 @@ static QState Calc_operand_neg(Calc * const me, 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 {
QMState const *target;
@ -1108,7 +1112,7 @@ static QState Calc_operand_neg(Calc * const me, 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 {
QMState const *target;
@ -1125,14 +1129,14 @@ static QState Calc_operand_neg(Calc * const me, 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();
}
@ -1146,4 +1150,4 @@ static QState Calc_operand_neg(Calc * const me, 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 @@
/*****************************************************************************
/*$file${.::calc1_sub.h} ###################################################*/
/*
* Model: calc1_sub.qm
* File: ./calc1_sub.h
* File: C:/qp_lab/qpc/examples/win32/calc1_sub/calc1_sub.h
*
* This code has been generated by QM tool (see state-machine.com/qm).
* 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,11 +32,7 @@ enum CalcSignals {
OFF_SIG
};
#if ((QP_VERSION < 591) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8)))
#error qpc version 5.9.1 or higher required
#endif
/*$declare${Events::CalcEvt} ###############################################*/
/*${Events::CalcEvt} .......................................................*/
typedef struct {
/* protected: */
@ -44,11 +41,12 @@ typedef struct {
/* public: */
uint8_t key_code;
} CalcEvt;
/*$enddecl${Events::CalcEvt} ###############################################*/
/*$declare${SMs::Calc_ctor} ################################################*/
/*${SMs::Calc_ctor} ........................................................*/
void Calc_ctor(void);
/*$enddecl${SMs::Calc_ctor} ################################################*/
extern 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. This version demonstrates the use of sub-machines and sub-machine states.</documentation>
<framework name="qpc" license="../../../QPC-EVAL-171231.qlc"/>
<package name="Events" stereotype="0x01">

View File

@ -0,0 +1,263 @@
##############################################################################
# Product: Makefile for QP/C, DPP console, Win32, MinGW
# Last Updated for Version: 6.0.1
# Date of the Last Update: 2017-10-29
#
# 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 ($(QPC),)
QPC := ../../..
endif
# QP port used in this project
QP_PORT_DIR := $(QPC)/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$(QPC)/include \
-Icont
# list of resource include directories needed by this project
RCINCLUDES = \
-IRes
#-----------------------------------------------------------------------------
# files
#
# C source files...
C_SRCS := \
bsp.c \
main.c \
philo.c \
table.c
# C++ source files...
CPP_SRCS :=
# 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)
$(CC) $(CFLAGS) -c $(QPC)/include/qstamp.c -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,246 @@
/*****************************************************************************
* Product: DPP example, Windows (console)
* Last updated for version 6.0.1
* Last updated on 2017-10-29
*
* 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 "qpc.h"
#include "dpp.h"
#include "bsp.h"
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
Q_DEFINE_THIS_FILE
/* local variables ---------------------------------------------------------*/
static uint32_t l_rnd; /* random seed */
#ifdef Q_SPY
enum {
PHILO_STAT = QS_USER
};
static uint8_t l_running;
static uint8_t const l_clock_tick = 0U;
#endif
/*..........................................................................*/
void QF_onStartup(void) {
QF_setTickRate(BSP_TICKS_PER_SEC); /* set the desired tick rate */
}
/*..........................................................................*/
void QF_onCleanup(void) {
printf("\nBye! Bye!\n");
}
/*..........................................................................*/
void QF_onClockTick(void) {
QF_TICK_X(0U, &l_clock_tick); /* perform the QF clock tick processing */
if (_kbhit()) { /* any key pressed? */
int ch = _getch();
if (ch == '\33') { /* see if the ESC key pressed */
BSP_terminate(0);
}
else if (ch == 'p') {
QF_PUBLISH(Q_NEW(QEvt, PAUSE_SIG), &l_clock_tick);
}
else if (ch == 's') {
QF_PUBLISH(Q_NEW(QEvt, SERVE_SIG), &l_clock_tick);
}
}
}
/*..........................................................................*/
void Q_onAssert(char const * const module, int_t loc) {
QS_ASSERTION(module, loc, (uint32_t)10000U); /* report assertion to QS */
fprintf(stderr, "Assertion failed in %s, line %d", module, loc);
exit(-1);
}
/*..........................................................................*/
void BSP_init(int argc, char *argv[]) {
(void)argc;
(void)argv;
printf("Dining Philosophers 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((argc > 1) ? argv[1] : ""));
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_running = (uint8_t)0; /* stop the QS output thread */
#endif
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;
}
/*--------------------------------------------------------------------------*/
#ifdef Q_SPY /* define QS callbacks */
#include "qspy.h"
#include <time.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h> /* Win32 API for multithreading */
static uint8_t l_running;
/*..........................................................................*/
static DWORD WINAPI idleThread(LPVOID par) {/* signature for CreateThread() */
(void)par;
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_IDLE);
l_running = (uint8_t)1;
while (l_running) {
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(10U); /* wait for a clock tick */
}
return 0; /* return success */
}
/*..........................................................................*/
uint8_t QS_onStartup(void const *arg) {
static uint8_t qsBuf[2*1024]; /* 4K buffer for Quantum Spy */
QS_initBuf(qsBuf, sizeof(qsBuf));
/* here 'arg' is ignored, but this command-line parameter can be used
* to setup the QSP_config(), to set up the QS filters, or for any
* other purpose.
*/
(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, // mscFile
(QSPY_CustParseFun)0); // no customized parser function
/* setup 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(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) {
l_running = (uint8_t)0;
QSPY_stop();
}
/*..........................................................................*/
void QS_onFlush(void) {
for (;;) {
uint16_t nBytes = 1024;
uint8_t const *block;
QF_CRIT_ENTRY(dummy);
block = QS_getBlock(&nBytes);
QF_CRIT_EXIT(dummy);
if (block != (uint8_t const *)0) {
QSPY_parse(block, nBytes);
nBytes = 1024;
}
else {
break;
}
}
}
/*..........................................................................*/
QSTimeCtr QS_onGetTime(void) {
return (QSTimeCtr)clock();
}
/*..........................................................................*/
void QSPY_onPrintLn(void) {
fputs(QSPY_line, stdout);
fputc('\n', stdout);
}
#endif /* Q_SPY */
/*--------------------------------------------------------------------------*/

View File

@ -0,0 +1,48 @@
/*****************************************************************************
* Product: DPP example
* Last Updated for Version: 4.5.02
* Date of the Last Update: Jul 04, 2012
*
* Q u a n t u m L e a P s
* ---------------------------
* innovating embedded systems
*
* Copyright (C) 2002-2012 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:
* Quantum Leaps Web sites: http://www.quantum-leaps.com
* https://state-machine.com
* e-mail: info@quantum-leaps.com
*****************************************************************************/
#ifndef bsp_h
#define bsp_h
#define BSP_TICKS_PER_SEC 50U
void BSP_init(int argc, char *argv[]);
void BSP_displayPaused(uint8_t paused);
void BSP_displayPhilStat(uint8_t n, char_t const *stat);
void BSP_terminate(int16_t result);
void BSP_randomSeed(uint32_t seed); /* random seed */
uint32_t BSP_random(void); /* pseudo-random generator */
#endif /* bsp_h */

View File

@ -0,0 +1,95 @@
<?xml version="1.0" encoding="UTF-8"?>
<package name="Comp" stereotype="0x02">
<class name="Philo" superclass="qpc::QHsm">
<attribute name="timeEvt" type="CompTimeEvt" visibility="0x02" properties="0x00"/>
<operation name="ctor" type="void" visibility="0x00" properties="0x00">
<code>QHsm_ctor(&amp;me-&gt;super, Q_STATE_CAST(&amp;Philo_initial));
CompTimeEvt_ctor(&amp;me-&gt;timeEvt, AO_Table, &amp;me-&gt;super, TIMEOUT_SIG, 0U);</code>
</operation>
<statechart>
<initial target="../1">
<action>static uint8_t registered = (uint8_t)0; /* starts off with 0, per C-standard */
(void)e; /* suppress the compiler warning about unused parameter */
if (registered == (uint8_t)0) {
registered = (uint8_t)1;
QS_FUN_DICTIONARY(&amp;Philo_initial);
QS_FUN_DICTIONARY(&amp;Philo_thinking);
QS_FUN_DICTIONARY(&amp;Philo_hungry);
QS_FUN_DICTIONARY(&amp;Philo_eating);
}</action>
<initial_glyph conn="2,4,5,1,20,5,-2">
<action box="0,-2,6,2"/>
</initial_glyph>
</initial>
<state name="thinking">
<entry>QTimeEvt_armX(&amp;me-&gt;timeEvt.super, THINK_TIME, 0U);</entry>
<exit>QTimeEvt_disarm(&amp;me-&gt;timeEvt.super);</exit>
<tran trig="TIMEOUT" target="../../2">
<tran_glyph conn="2,16,3,1,20,10,-2">
<action box="0,-2,9,2"/>
</tran_glyph>
</tran>
<tran trig="TEST">
<tran_glyph conn="2,20,3,-1,13">
<action box="0,-2,11,4"/>
</tran_glyph>
</tran>
<state_glyph node="2,6,18,16">
<entry box="1,2,5,2"/>
<exit box="1,4,6,2"/>
</state_glyph>
</state>
<state name="hungry">
<entry>/* asynchronously post event to the Container */
TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG);
pe-&gt;philo = me;
QACTIVE_POST_LIFO(AO_Table, &amp;pe-&gt;super);</entry>
<tran trig="EAT" target="../../3">
<tran_glyph conn="2,31,3,1,20,11,-2">
<action box="0,-2,14,2"/>
</tran_glyph>
</tran>
<state_glyph node="2,24,18,14">
<entry box="1,2,5,2"/>
</state_glyph>
</state>
<state name="eating">
<entry>QTimeEvt_armX(&amp;me-&gt;timeEvt.super, EAT_TIME, 0U);</entry>
<exit>QTimeEvt_disarm(&amp;me-&gt;timeEvt.super);
/* asynchronously post event to the Container */
TableEvt *pe = Q_NEW(TableEvt, DONE_SIG);
pe-&gt;philo = me;
QACTIVE_POST_LIFO(AO_Table, &amp;pe-&gt;super);</exit>
<tran trig="TIMEOUT" target="../../1">
<tran_glyph conn="2,50,3,1,22,-39,-4">
<action box="0,-2,10,2"/>
</tran_glyph>
</tran>
<state_glyph node="2,40,18,14">
<entry box="1,2,5,2"/>
<exit box="1,4,5,2"/>
</state_glyph>
</state>
<state_diagram size="28,56"/>
</statechart>
</class>
<directory name=".">
<file name="philo.c">
<text>#include &quot;qpc.h&quot;
#include &quot;dpp.h&quot;
#include &quot;bsp.h&quot;
Q_DEFINE_THIS_FILE
/* helper macros to provide a randomized think time for Philos */
#define THINK_TIME \
(QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U))
#define EAT_TIME \
(QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC)
/* Philo definition --------------------------------------------------------*/
$define(Comp::Philo)</text>
</file>
</directory>
</package>

View File

@ -0,0 +1,149 @@
/*$file${Comp::.::philo.c} #################################################*/
/*
* Model: dpp.qm
* File: C:/qp_lab/qpc/examples/win32/dpp-comp/comp/philo.c
*
* 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.c} ##############################################*/
#include "qpc.h"
#include "dpp.h"
#include "bsp.h"
Q_DEFINE_THIS_FILE
/* helper macros to provide a randomized think time for Philos */
#define THINK_TIME \
(QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + (BSP_TICKS_PER_SEC/2U))
#define EAT_TIME \
(QTimeEvtCtr)((BSP_random() % BSP_TICKS_PER_SEC) + BSP_TICKS_PER_SEC)
/* Philo definition --------------------------------------------------------*/
/*$define${Comp::Philo} ####################################################*/
/* Check for the minimum required QP version */
#if ((QP_VERSION < 601) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8)))
#error qpc version 6.0.1 or higher required
#endif
/*${Comp::Philo} ...........................................................*/
/*${Comp::Philo::ctor} .....................................................*/
void Philo_ctor(Philo * const me) {
QHsm_ctor(&me->super, Q_STATE_CAST(&Philo_initial));
CompTimeEvt_ctor(&me->timeEvt, AO_Table, &me->super, TIMEOUT_SIG, 0U);
}
/*${Comp::Philo::SM} .......................................................*/
QState Philo_initial(Philo * const me, QEvt const * const e) {
/*${Comp::Philo::SM::initial} */
static uint8_t registered = (uint8_t)0; /* starts off with 0, per C-standard */
(void)e; /* suppress the compiler warning about unused parameter */
if (registered == (uint8_t)0) {
registered = (uint8_t)1;
QS_FUN_DICTIONARY(&Philo_initial);
QS_FUN_DICTIONARY(&Philo_thinking);
QS_FUN_DICTIONARY(&Philo_hungry);
QS_FUN_DICTIONARY(&Philo_eating);
}
return Q_TRAN(&Philo_thinking);
}
/*${Comp::Philo::SM::thinking} .............................................*/
QState Philo_thinking(Philo * const me, QEvt const * const e) {
QState status_;
switch (e->sig) {
/*${Comp::Philo::SM::thinking} */
case Q_ENTRY_SIG: {
QTimeEvt_armX(&me->timeEvt.super, THINK_TIME, 0U);
status_ = Q_HANDLED();
break;
}
/*${Comp::Philo::SM::thinking} */
case Q_EXIT_SIG: {
QTimeEvt_disarm(&me->timeEvt.super);
status_ = Q_HANDLED();
break;
}
/*${Comp::Philo::SM::thinking::TIMEOUT} */
case TIMEOUT_SIG: {
status_ = Q_TRAN(&Philo_hungry);
break;
}
/*${Comp::Philo::SM::thinking::TEST} */
case TEST_SIG: {
status_ = Q_HANDLED();
break;
}
default: {
status_ = Q_SUPER(&QHsm_top);
break;
}
}
return status_;
}
/*${Comp::Philo::SM::hungry} ...............................................*/
QState Philo_hungry(Philo * const me, QEvt const * const e) {
QState status_;
switch (e->sig) {
/*${Comp::Philo::SM::hungry} */
case Q_ENTRY_SIG: {
/* asynchronously post event to the Container */
TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG);
pe->philo = me;
QACTIVE_POST_LIFO(AO_Table, &pe->super);
status_ = Q_HANDLED();
break;
}
/*${Comp::Philo::SM::hungry::EAT} */
case EAT_SIG: {
status_ = Q_TRAN(&Philo_eating);
break;
}
default: {
status_ = Q_SUPER(&QHsm_top);
break;
}
}
return status_;
}
/*${Comp::Philo::SM::eating} ...............................................*/
QState Philo_eating(Philo * const me, QEvt const * const e) {
QState status_;
switch (e->sig) {
/*${Comp::Philo::SM::eating} */
case Q_ENTRY_SIG: {
QTimeEvt_armX(&me->timeEvt.super, EAT_TIME, 0U);
status_ = Q_HANDLED();
break;
}
/*${Comp::Philo::SM::eating} */
case Q_EXIT_SIG: {
QTimeEvt_disarm(&me->timeEvt.super);
/* asynchronously post event to the Container */
TableEvt *pe = Q_NEW(TableEvt, DONE_SIG);
pe->philo = me;
QACTIVE_POST_LIFO(AO_Table, &pe->super);
status_ = Q_HANDLED();
break;
}
/*${Comp::Philo::SM::eating::TIMEOUT} */
case TIMEOUT_SIG: {
status_ = Q_TRAN(&Philo_thinking);
break;
}
default: {
status_ = Q_SUPER(&QHsm_top);
break;
}
}
return status_;
}
/*$enddef${Comp::Philo} ####################################################*/

View File

@ -0,0 +1,329 @@
<?xml version="1.0" encoding="UTF-8"?>
<package name="Cont" stereotype="0x02">
<class name="TableEvt" superclass="qpc::QEvt">
<attribute name="philo" type="Philo*" visibility="0x00" properties="0x00"/>
</class>
<class name="CompTimeEvt" superclass="qpc::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="comp" type="QHsm*" visibility="0x00" properties="0x00"/>
<operation name="ctor" type="void" 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="QActive *"/>
<parameter name="comp" type="QHsm *"/>
<parameter name="sig" type="enum_t const"/>
<parameter name="tickRate" type="uint_fast8_t const"/>
<code>QTimeEvt_ctorX(&amp;me-&gt;super, act, sig, tickRate);
me-&gt;comp = comp;</code>
</operation>
<operation name="dispatchToComp" type="void" visibility="0x00" properties="0x08">
<code>QHSM_DISPATCH(me-&gt;comp, (QEvt const *)me);</code>
</operation>
</class>
<class name="Table" superclass="qpc::QActive">
<attribute name="philo[N_PHILO]" type="Philo" visibility="0x02" properties="0x00">
<documentation>Embedded component state machine objects</documentation>
</attribute>
<attribute name="fork[N_PHILO]" type="uint8_t" visibility="0x02" properties="0x00"/>
<attribute name="isHungry[N_PHILO]" type="uint8_t" visibility="0x02" properties="0x00"/>
<statechart>
<initial target="../1/3">
<action>uint8_t n;
(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(HUNGRY_SIG, (void *)0);
QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0);
QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0);
QActive_subscribe(&amp;me-&gt;super, PAUSE_SIG);
QActive_subscribe(&amp;me-&gt;super, SERVE_SIG);
QActive_subscribe(&amp;me-&gt;super, TEST_SIG);
for (n = 0U; n &lt; N_PHILO; ++n) {
QHSM_INIT(&amp;me-&gt;philo[n].super, (QEvt *)0);
me-&gt;fork[n] = FREE;
me-&gt;isHungry[n] = 0U;
BSP_displayPhilStat(n, &quot;thinking&quot;);
}</action>
<initial_glyph conn="3,3,5,1,43,25,-8">
<action box="0,-2,6,2"/>
</initial_glyph>
</initial>
<state name="active">
<tran trig="TIMEOUT">
<action>CompTimeEvt_dispatchToComp(Q_EVT_CAST(CompTimeEvt));</action>
<tran_glyph conn="2,11,3,-1,14">
<action box="0,-2,26,4"/>
</tran_glyph>
</tran>
<tran trig="EAT">
<action>Q_ERROR();</action>
<tran_glyph conn="2,16,3,-1,14">
<action box="0,-2,10,4"/>
</tran_glyph>
</tran>
<tran trig="TEST">
<tran_glyph conn="2,22,3,-1,14">
<action box="0,-2,10,2"/>
</tran_glyph>
</tran>
<state name="serving">
<entry brief="give pending permissions to eat">uint8_t n;
for (n = 0U; n &lt; N_PHILO; ++n) { /* give permissions to eat... */
if ((me-&gt;isHungry[n] != 0U)
&amp;&amp; (me-&gt;fork[LEFT(n)] == FREE)
&amp;&amp; (me-&gt;fork[n] == FREE))
{
TableEvt evt;
me-&gt;fork[LEFT(n)] = USED;
me-&gt;fork[n] = USED;
/* synchronoulsy dispatch EAT event to the Philo component */
evt.super.sig = EAT_SIG;
evt.philo = &amp;me-&gt;philo[n];
QHSM_DISPATCH(&amp;me-&gt;philo[n].super, (QEvt const *)&amp;evt);
me-&gt;isHungry[n] = 0U;
BSP_displayPhilStat(n, &quot;eating &quot;);
}
}</entry>
<tran trig="HUNGRY">
<action>uint8_t n, m;
/* find the index of the Philo from the event */
n = (Q_EVT_CAST(TableEvt)-&gt;philo - &amp;me-&gt;philo[0]);
/* philo ID must be in range and he must be not hungry */
Q_ASSERT((n &lt; N_PHILO) &amp;&amp; (!me-&gt;isHungry[n]));
BSP_displayPhilStat(n, &quot;hungry &quot;);
m = LEFT(n);</action>
<choice>
<guard brief="both free">(me-&gt;fork[m] == FREE) &amp;&amp; (me-&gt;fork[n] == FREE)</guard>
<action>TableEvt evt;
me-&gt;fork[m] = USED;
me-&gt;fork[n] = USED;
/* synchronoulsy dispatch EAT event to the Philo component */
evt.super.sig = EAT_SIG;
evt.philo = &amp;me-&gt;philo[n];
QHSM_DISPATCH(&amp;me-&gt;philo[n].super, (QEvt const *)&amp;evt);
BSP_displayPhilStat(n, &quot;eating &quot;);</action>
<choice_glyph conn="20,33,5,-1,10">
<action box="1,0,10,2"/>
</choice_glyph>
</choice>
<choice>
<guard>else</guard>
<action>me-&gt;isHungry[n] = 1U;</action>
<choice_glyph conn="20,33,4,-1,5,10">
<action box="1,5,6,2"/>
</choice_glyph>
</choice>
<tran_glyph conn="4,33,3,-1,16">
<action box="0,-2,8,2"/>
</tran_glyph>
</tran>
<tran trig="DONE">
<action>uint8_t n, m;
TableEvt evt;
/* find the index of the Philo from the event */
n = (Q_EVT_CAST(TableEvt)-&gt;philo - &amp;me-&gt;philo[0]);
/* philo ID must be in range and he must be not hungry */
Q_ASSERT((n &lt; N_PHILO) &amp;&amp; (!me-&gt;isHungry[n]));
BSP_displayPhilStat(n, &quot;thinking&quot;);
m = LEFT(n);
/* both forks of Phil[n] must be used */
Q_ASSERT((me-&gt;fork[n] == USED) &amp;&amp; (me-&gt;fork[m] == USED));
me-&gt;fork[m] = FREE;
me-&gt;fork[n] = FREE;
m = RIGHT(n); /* check the right neighbor */
if ((me-&gt;isHungry[m] != 0U) &amp;&amp; (me-&gt;fork[m] == FREE)) {
me-&gt;fork[n] = USED;
me-&gt;fork[m] = USED;
me-&gt;isHungry[m] = 0U;
/* synchronoulsy dispatch EAT event to the Philo component */
evt.super.sig = EAT_SIG;
evt.philo = &amp;me-&gt;philo[m];
QHSM_DISPATCH(&amp;me-&gt;philo[m].super, (QEvt const *)&amp;evt);
BSP_displayPhilStat(m, &quot;eating &quot;);
}
m = LEFT(n); /* check the left neighbor */
n = LEFT(m); /* left fork of the left neighbor */
if ((me-&gt;isHungry[m] != 0U) &amp;&amp; (me-&gt;fork[n] == FREE)) {
me-&gt;fork[m] = USED;
me-&gt;fork[n] = USED;
me-&gt;isHungry[m] = 0U;
/* synchronoulsy dispatch EAT event to the Philo component */
evt.super.sig = EAT_SIG;
evt.philo = &amp;me-&gt;philo[m];
QHSM_DISPATCH(&amp;me-&gt;philo[m].super, (QEvt const *)&amp;evt);
BSP_displayPhilStat(m, &quot;eating &quot;);
}</action>
<tran_glyph conn="4,41,3,-1,16">
<action box="0,-2,6,2"/>
</tran_glyph>
</tran>
<tran trig="EAT">
<action>Q_ERROR();</action>
<tran_glyph conn="4,44,3,-1,16">
<action box="0,-2,12,4"/>
</tran_glyph>
</tran>
<tran trig="PAUSE" target="../../4">
<tran_glyph conn="4,48,3,1,36,6,-2">
<action box="0,-2,7,2"/>
</tran_glyph>
</tran>
<state_glyph node="4,26,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,64,3,1,38,-20,-4">
<action box="0,-2,7,2"/>
</tran_glyph>
</tran>
<tran trig="HUNGRY">
<action>uint8_t n;
/* find the index of the Philo from the event */
n = (Q_EVT_CAST(TableEvt)-&gt;philo - &amp;me-&gt;philo[0]);
/* philo ID must be in range and he must be not hungry */
Q_ASSERT((n &lt; N_PHILO) &amp;&amp; (!me-&gt;isHungry[n]));
me-&gt;isHungry[n] = 1U;
BSP_displayPhilStat(n, &quot;hungry &quot;);</action>
<tran_glyph conn="4,68,3,-1,16">
<action box="0,-2,12,2"/>
</tran_glyph>
</tran>
<tran trig="DONE">
<action>uint8_t n, m;
/* find the index of the Philo from the event */
n = (Q_EVT_CAST(TableEvt)-&gt;philo - &amp;me-&gt;philo[0]);
/* philo ID must be in range and he must be not hungry */
Q_ASSERT((n &lt; N_PHILO) &amp;&amp; (!me-&gt;isHungry[n]));
BSP_displayPhilStat(n, &quot;thinking&quot;);
m = LEFT(n);
/* both forks of Phil[n] must be used */
Q_ASSERT((me-&gt;fork[n] == USED) &amp;&amp; (me-&gt;fork[m] == USED));
me-&gt;fork[m] = FREE;
me-&gt;fork[n] = FREE;</action>
<tran_glyph conn="4,72,3,-1,16">
<action box="0,-2,11,2"/>
</tran_glyph>
</tran>
<state_glyph node="4,52,34,22">
<entry box="1,2,18,4"/>
<exit box="1,6,18,4"/>
</state_glyph>
</state>
<state_glyph node="2,5,42,71"/>
</state>
<state_diagram size="50,78"/>
</statechart>
</class>
<attribute name="AO_Table" type="QActive * const" visibility="0x00" properties="0x00"/>
<operation name="Table_ctor" type="void" visibility="0x00" properties="0x00">
<code>uint8_t n;
Table *me = &amp;l_table;
QActive_ctor(&amp;me-&gt;super, Q_STATE_CAST(&amp;Table_initial));
for (n = 0U; n &lt; N_PHILO; ++n) {
Philo_ctor(&amp;me-&gt;philo[n]);
me-&gt;fork[n] = FREE;
me-&gt;isHungry[n] = 0U;
}</code>
</operation>
<directory name=".">
<file name="dpp.h">
<text>#ifndef dpp_h
#define dpp_h
enum DPPSignals {
EAT_SIG = 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 serving forks */
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 Philosophers for time events */
MAX_SIG /* the last signal */
};
enum {
N_PHILO = 5 /* number of Philos */
};
struct Philo; /* forward declaration */
$declare(Cont::CompTimeEvt)
$declare(Comp::Philo)
$declare(Cont::TableEvt)
$declare(Cont::Table_ctor)
$declare(Cont::AO_Table)
#endif /* dpp_h */</text>
</file>
<file name="table.c">
<text>#include &quot;qpc.h&quot;
#include &quot;dpp.h&quot;
#include &quot;bsp.h&quot;
Q_DEFINE_THIS_FILE
/* Active object class -----------------------------------------------------*/
$declare(Cont::Table)
#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO))
#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO))
#define FREE ((uint8_t)0)
#define USED ((uint8_t)1)
/* Local objects -----------------------------------------------------------*/
static Table l_table; /* the single instance of the Table active object */
/* Global-scope objects ----------------------------------------------------*/
QActive * const AO_Table = &amp;l_table.super; /* &quot;opaque&quot; AO pointer */
//............................................................................
$define(Cont::CompTimeEvt)
$define(Cont::Table_ctor)
$define(Cont::Table)</text>
</file>
</directory>
</package>

View File

@ -0,0 +1,100 @@
/*$file${Cont::.::dpp.h} ###################################################*/
/*
* Model: dpp.qm
* File: C:/qp_lab/qpc/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
enum DPPSignals {
EAT_SIG = 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 serving forks */
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 Philosophers for time events */
MAX_SIG /* the last signal */
};
enum {
N_PHILO = 5 /* number of Philos */
};
struct Philo; /* forward declaration */
/*$declare${Cont::CompTimeEvt} #############################################*/
/*${Cont::CompTimeEvt} .....................................................*/
typedef struct {
/* protected: */
QTimeEvt super;
/* public: */
QHsm* comp;
} CompTimeEvt;
/* public: */
void CompTimeEvt_ctor(
CompTimeEvt * const me,
QActive * act,
QHsm * comp,
enum_t const sig,
uint_fast8_t const tickRate);
void CompTimeEvt_dispatchToComp(CompTimeEvt const * const me);
/*$enddecl${Cont::CompTimeEvt} #############################################*/
/*$declare${Comp::Philo} ###################################################*/
/*${Comp::Philo} ...........................................................*/
typedef struct {
/* protected: */
QHsm super;
/* private: */
CompTimeEvt timeEvt;
} Philo;
/* public: */
void Philo_ctor(Philo * const me);
/* protected: */
QState Philo_initial(Philo * const me, QEvt const * const e);
QState Philo_thinking(Philo * const me, QEvt const * const e);
QState Philo_hungry(Philo * const me, QEvt const * const e);
QState Philo_eating(Philo * const me, QEvt const * const e);
/*$enddecl${Comp::Philo} ###################################################*/
/*$declare${Cont::TableEvt} ################################################*/
/*${Cont::TableEvt} ........................................................*/
typedef struct {
/* protected: */
QEvt super;
/* public: */
Philo* philo;
} TableEvt;
/*$enddecl${Cont::TableEvt} ################################################*/
/*$declare${Cont::Table_ctor} ##############################################*/
/*${Cont::Table_ctor} ......................................................*/
void Table_ctor(void);
/*$enddecl${Cont::Table_ctor} ##############################################*/
/*$declare${Cont::AO_Table} ################################################*/
extern QActive * const AO_Table;
/*$enddecl${Cont::AO_Table} ################################################*/
#endif /* dpp_h */

View File

@ -0,0 +1,346 @@
/*$file${Cont::.::table.c} #################################################*/
/*
* Model: dpp.qm
* File: C:/qp_lab/qpc/examples/win32/dpp-comp/cont/table.c
*
* 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.c} ##############################################*/
#include "qpc.h"
#include "dpp.h"
#include "bsp.h"
Q_DEFINE_THIS_FILE
/* Active object class -----------------------------------------------------*/
/*$declare${Cont::Table} ###################################################*/
/*${Cont::Table} ...........................................................*/
typedef struct {
/* protected: */
QActive super;
/* private: */
Philo philo[N_PHILO];
uint8_t fork[N_PHILO];
uint8_t isHungry[N_PHILO];
} Table;
/* protected: */
static QState Table_initial(Table * const me, QEvt const * const e);
static QState Table_active(Table * const me, QEvt const * const e);
static QState Table_serving(Table * const me, QEvt const * const e);
static QState Table_paused(Table * const me, QEvt const * const e);
/*$enddecl${Cont::Table} ###################################################*/
#define RIGHT(n_) ((uint8_t)(((n_) + (N_PHILO - 1U)) % N_PHILO))
#define LEFT(n_) ((uint8_t)(((n_) + 1U) % N_PHILO))
#define FREE ((uint8_t)0)
#define USED ((uint8_t)1)
/* Local objects -----------------------------------------------------------*/
static Table l_table; /* the single instance of the Table active object */
/* Global-scope objects ----------------------------------------------------*/
QActive * const AO_Table = &l_table.super; /* "opaque" AO pointer */
//............................................................................
/*$define${Cont::CompTimeEvt} ##############################################*/
/* Check for the minimum required QP version */
#if ((QP_VERSION < 601) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8)))
#error qpc version 6.0.1 or higher required
#endif
/*${Cont::CompTimeEvt} .....................................................*/
/*${Cont::CompTimeEvt::ctor} ...............................................*/
void CompTimeEvt_ctor(
CompTimeEvt * const me,
QActive * act,
QHsm * comp,
enum_t const sig,
uint_fast8_t const tickRate)
{
QTimeEvt_ctorX(&me->super, act, sig, tickRate);
me->comp = comp;
}
/*${Cont::CompTimeEvt::dispatchToComp} .....................................*/
void CompTimeEvt_dispatchToComp(CompTimeEvt const * const me) {
QHSM_DISPATCH(me->comp, (QEvt const *)me);
}
/*$enddef${Cont::CompTimeEvt} ##############################################*/
/*$define${Cont::Table_ctor} ###############################################*/
/*${Cont::Table_ctor} ......................................................*/
void Table_ctor(void) {
uint8_t n;
Table *me = &l_table;
QActive_ctor(&me->super, Q_STATE_CAST(&Table_initial));
for (n = 0U; n < N_PHILO; ++n) {
Philo_ctor(&me->philo[n]);
me->fork[n] = FREE;
me->isHungry[n] = 0U;
}
}
/*$enddef${Cont::Table_ctor} ###############################################*/
/*$define${Cont::Table} ####################################################*/
/*${Cont::Table} ...........................................................*/
/*${Cont::Table::SM} .......................................................*/
static QState Table_initial(Table * const me, QEvt const * const e) {
/*${Cont::Table::SM::initial} */
uint8_t n;
(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(HUNGRY_SIG, (void *)0);
QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0);
QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0);
QActive_subscribe(&me->super, PAUSE_SIG);
QActive_subscribe(&me->super, SERVE_SIG);
QActive_subscribe(&me->super, TEST_SIG);
for (n = 0U; n < N_PHILO; ++n) {
QHSM_INIT(&me->philo[n].super, (QEvt *)0);
me->fork[n] = FREE;
me->isHungry[n] = 0U;
BSP_displayPhilStat(n, "thinking");
}
return Q_TRAN(&Table_serving);
}
/*${Cont::Table::SM::active} ...............................................*/
static QState Table_active(Table * const me, QEvt const * const e) {
QState status_;
switch (e->sig) {
/*${Cont::Table::SM::active::TIMEOUT} */
case TIMEOUT_SIG: {
CompTimeEvt_dispatchToComp(Q_EVT_CAST(CompTimeEvt));
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(&QHsm_top);
break;
}
}
return status_;
}
/*${Cont::Table::SM::active::serving} ......................................*/
static QState Table_serving(Table * const me, QEvt const * const e) {
QState status_;
switch (e->sig) {
/*${Cont::Table::SM::active::serving} */
case Q_ENTRY_SIG: {
uint8_t n;
for (n = 0U; n < N_PHILO; ++n) { /* give permissions to eat... */
if ((me->isHungry[n] != 0U)
&& (me->fork[LEFT(n)] == FREE)
&& (me->fork[n] == FREE))
{
TableEvt evt;
me->fork[LEFT(n)] = USED;
me->fork[n] = USED;
/* synchronoulsy dispatch EAT event to the Philo component */
evt.super.sig = EAT_SIG;
evt.philo = &me->philo[n];
QHSM_DISPATCH(&me->philo[n].super, (QEvt const *)&evt);
me->isHungry[n] = 0U;
BSP_displayPhilStat(n, "eating ");
}
}
status_ = Q_HANDLED();
break;
}
/*${Cont::Table::SM::active::serving::HUNGRY} */
case HUNGRY_SIG: {
uint8_t n, m;
/* find the index of the Philo from the event */
n = (Q_EVT_CAST(TableEvt)->philo - &me->philo[0]);
/* philo ID must be in range and he must be not hungry */
Q_ASSERT((n < N_PHILO) && (!me->isHungry[n]));
BSP_displayPhilStat(n, "hungry ");
m = LEFT(n);
/*${Cont::Table::SM::active::serving::HUNGRY::[bothfree]} */
if ((me->fork[m] == FREE) && (me->fork[n] == FREE)) {
TableEvt evt;
me->fork[m] = USED;
me->fork[n] = USED;
/* synchronoulsy dispatch EAT event to the Philo component */
evt.super.sig = EAT_SIG;
evt.philo = &me->philo[n];
QHSM_DISPATCH(&me->philo[n].super, (QEvt const *)&evt);
BSP_displayPhilStat(n, "eating ");
status_ = Q_HANDLED();
}
/*${Cont::Table::SM::active::serving::HUNGRY::[else]} */
else {
me->isHungry[n] = 1U;
status_ = Q_HANDLED();
}
break;
}
/*${Cont::Table::SM::active::serving::DONE} */
case DONE_SIG: {
uint8_t n, m;
TableEvt evt;
/* find the index of the Philo from the event */
n = (Q_EVT_CAST(TableEvt)->philo - &me->philo[0]);
/* philo ID must be in range and he must be not hungry */
Q_ASSERT((n < N_PHILO) && (!me->isHungry[n]));
BSP_displayPhilStat(n, "thinking");
m = LEFT(n);
/* both forks of Phil[n] must be used */
Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED));
me->fork[m] = FREE;
me->fork[n] = FREE;
m = RIGHT(n); /* check the right neighbor */
if ((me->isHungry[m] != 0U) && (me->fork[m] == FREE)) {
me->fork[n] = USED;
me->fork[m] = USED;
me->isHungry[m] = 0U;
/* synchronoulsy dispatch EAT event to the Philo component */
evt.super.sig = EAT_SIG;
evt.philo = &me->philo[m];
QHSM_DISPATCH(&me->philo[m].super, (QEvt const *)&evt);
BSP_displayPhilStat(m, "eating ");
}
m = LEFT(n); /* check the left neighbor */
n = LEFT(m); /* left fork of the left neighbor */
if ((me->isHungry[m] != 0U) && (me->fork[n] == FREE)) {
me->fork[m] = USED;
me->fork[n] = USED;
me->isHungry[m] = 0U;
/* synchronoulsy dispatch EAT event to the Philo component */
evt.super.sig = EAT_SIG;
evt.philo = &me->philo[m];
QHSM_DISPATCH(&me->philo[m].super, (QEvt const *)&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(&Table_paused);
break;
}
default: {
status_ = Q_SUPER(&Table_active);
break;
}
}
return status_;
}
/*${Cont::Table::SM::active::paused} .......................................*/
static QState Table_paused(Table * const me, QEvt const * const e) {
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(&Table_serving);
break;
}
/*${Cont::Table::SM::active::paused::HUNGRY} */
case HUNGRY_SIG: {
uint8_t n;
/* find the index of the Philo from the event */
n = (Q_EVT_CAST(TableEvt)->philo - &me->philo[0]);
/* philo ID must be in range and he must be not hungry */
Q_ASSERT((n < N_PHILO) && (!me->isHungry[n]));
me->isHungry[n] = 1U;
BSP_displayPhilStat(n, "hungry ");
status_ = Q_HANDLED();
break;
}
/*${Cont::Table::SM::active::paused::DONE} */
case DONE_SIG: {
uint8_t n, m;
/* find the index of the Philo from the event */
n = (Q_EVT_CAST(TableEvt)->philo - &me->philo[0]);
/* philo ID must be in range and he must be not hungry */
Q_ASSERT((n < N_PHILO) && (!me->isHungry[n]));
BSP_displayPhilStat(n, "thinking");
m = LEFT(n);
/* both forks of Phil[n] must be used */
Q_ASSERT((me->fork[n] == USED) && (me->fork[m] == USED));
me->fork[m] = FREE;
me->fork[n] = FREE;
status_ = Q_HANDLED();
break;
}
default: {
status_ = Q_SUPER(&Table_active);
break;
}
}
return status_;
}
/*$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://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="qpc"/>
<package file="./cont/cont.qmp"/>
<package file="./comp/comp.qmp"/>
</model>

View File

@ -0,0 +1,92 @@
/*****************************************************************************
* Product: DPP example for Windows
* Last Updated for Version: 6.0.1
* Date of the Last Update: 2017-10-29
*
* 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 "qpc.h"
#include "dpp.h"
#include "bsp.h"
/* "fudge factor" for Windows, see NOTE1 */
enum { WIN_FUDGE_FACTOR = 10 };
/*..........................................................................*/
int main(int argc, char *argv[]) {
static QEvt const *tableQueueSto[N_PHILO*WIN_FUDGE_FACTOR];
static QSubscrList subscrSto[MAX_PUB_SIG];
static QF_MPOOL_EL(TableEvt) smlPoolSto[2*N_PHILO*WIN_FUDGE_FACTOR];
Table_ctor(); /* instantiate the Table active object */
QF_init(); /* initialize the framework and the underlying RT kernel */
BSP_init(argc, argv); /* initialize the Board Support Package */
/* object dictionaries... */
QS_OBJ_DICTIONARY(smlPoolSto);
QS_OBJ_DICTIONARY(tableQueueSto);
/* initialize publish-subscribe... */
QF_psInit(subscrSto, Q_DIM(subscrSto));
/* initialize event pools... */
QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0]));
QACTIVE_START(AO_Table, /* AO to start */
(uint_fast8_t)1, /* QP priority of the AO */
tableQueueSto, /* event queue storage */
Q_DIM(tableQueueSto), /* queue length [events] */
(void *)0, /* stack storage (not used) */
0U, /* size of the stack [bytes] */
(QEvt *)0); /* initialization event */
return 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 @@
/*****************************************************************************
/*$file${.::history.c} #####################################################*/
/*
* Model: history.qm
* File: ./history.c
* File: C:/qp_lab/qpc/examples/win32/history_qmsm/history.c
*
* This code has been generated by QM tool (see state-machine.com/qm).
* 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.c} ..........................................................*/
*/
/*$endhead${.::history.c} ##################################################*/
#include "qpc.h"
#include "history.h"
@ -26,11 +27,7 @@
Q_DEFINE_THIS_FILE
#if ((QP_VERSION < 591) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8)))
#error qpc version 5.9.1 or higher required
#endif
/*$declare${SMs::ToastOven} ################################################*/
/*${SMs::ToastOven} ........................................................*/
typedef struct {
/* protected: */
@ -110,18 +107,25 @@ static QMState const ToastOven_final_s = {
Q_ACTION_CAST(0), /* no exit action */
Q_ACTION_CAST(0) /* no intitial tran. */
};
/*$enddecl${SMs::ToastOven} ################################################*/
static ToastOven l_oven; /* the only instance of the ToastOven class */
/* global-scope definitions -----------------------------------------*/
QMsm * const the_oven = (QMsm *)&l_oven; /* the opaque pointer */
/*$define${SMs::ToastOven_ctor} ############################################*/
/* Check for the minimum required QP version */
#if ((QP_VERSION < 601) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8)))
#error qpc version 6.0.1 or higher required
#endif
/*${SMs::ToastOven_ctor} ...................................................*/
void ToastOven_ctor(void) {
ToastOven *me = &l_oven;
QMsm_ctor(&me->super, Q_STATE_CAST(&ToastOven_initial));
}
/*$enddef${SMs::ToastOven_ctor} ############################################*/
/*$define${SMs::ToastOven} #################################################*/
/*${SMs::ToastOven} ........................................................*/
/*${SMs::ToastOven::SM} ....................................................*/
static QState ToastOven_initial(ToastOven * const me, QEvt const * const e) {
@ -136,26 +140,26 @@ static QState ToastOven_initial(ToastOven * const me, 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 = &ToastOven_off_s;
return QM_TRAN_INIT(&tatbl_);
}
/*${SMs::ToastOven::SM::doorClosed} ........................................*/
/* ${SMs::ToastOven::SM::doorClosed} */
/*${SMs::ToastOven::SM::doorClosed} */
static QState ToastOven_doorClosed_e(ToastOven * const me) {
printf("door-Closed;");
(void)me; /* avoid compiler warning in case 'me' is not used */
return QM_ENTRY(&ToastOven_doorClosed_s);
}
/* ${SMs::ToastOven::SM::doorClosed} */
/*${SMs::ToastOven::SM::doorClosed} */
static QState ToastOven_doorClosed_x(ToastOven * const me) {
/* save deep history */
me->his_doorClosed = QMsm_stateObj(me);
return QM_EXIT(&ToastOven_doorClosed_s);
}
/* ${SMs::ToastOven::SM::doorClosed::initial} */
/*${SMs::ToastOven::SM::doorClosed::initial} */
static QState ToastOven_doorClosed_i(ToastOven * const me) {
static struct {
QMState const *target;
@ -167,14 +171,14 @@ static 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} */
static QState ToastOven_doorClosed(ToastOven * const me, QEvt const * const e) {
QState status_;
switch (e->sig) {
/* ${SMs::ToastOven::SM::doorClosed::TERMINATE} */
/*${SMs::ToastOven::SM::doorClosed::TERMINATE} */
case TERMINATE_SIG: {
static struct {
QMState const *target;
@ -190,7 +194,7 @@ static QState ToastOven_doorClosed(ToastOven * const me, QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
/* ${SMs::ToastOven::SM::doorClosed::OPEN} */
/*${SMs::ToastOven::SM::doorClosed::OPEN} */
case OPEN_SIG: {
static struct {
QMState const *target;
@ -206,7 +210,7 @@ static QState ToastOven_doorClosed(ToastOven * const me, QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
/* ${SMs::ToastOven::SM::doorClosed::TOAST} */
/*${SMs::ToastOven::SM::doorClosed::TOAST} */
case TOAST_SIG: {
static struct {
QMState const *target;
@ -222,7 +226,7 @@ static QState ToastOven_doorClosed(ToastOven * const me, QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
/* ${SMs::ToastOven::SM::doorClosed::BAKE} */
/*${SMs::ToastOven::SM::doorClosed::BAKE} */
case BAKE_SIG: {
static struct {
QMState const *target;
@ -238,7 +242,7 @@ static QState ToastOven_doorClosed(ToastOven * const me, QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
/* ${SMs::ToastOven::SM::doorClosed::OFF} */
/*${SMs::ToastOven::SM::doorClosed::OFF} */
case OFF_SIG: {
static struct {
QMState const *target;
@ -261,19 +265,19 @@ static QState ToastOven_doorClosed(ToastOven * const me, QEvt const * const e) {
return status_;
}
/*${SMs::ToastOven::SM::doorClosed::heating} ...............................*/
/* ${SMs::ToastOven::SM::doorClosed::heating} */
/*${SMs::ToastOven::SM::doorClosed::heating} */
static QState ToastOven_heating_e(ToastOven * const me) {
printf("heater-On;");
(void)me; /* avoid compiler warning in case 'me' is not used */
return QM_ENTRY(&ToastOven_heating_s);
}
/* ${SMs::ToastOven::SM::doorClosed::heating} */
/*${SMs::ToastOven::SM::doorClosed::heating} */
static QState ToastOven_heating_x(ToastOven * const me) {
printf("heater-Off;");
(void)me; /* avoid compiler warning in case 'me' is not used */
return QM_EXIT(&ToastOven_heating_s);
}
/* ${SMs::ToastOven::SM::doorClosed::heating::initial} */
/*${SMs::ToastOven::SM::doorClosed::heating::initial} */
static QState ToastOven_heating_i(ToastOven * const me) {
static struct {
QMState const *target;
@ -285,10 +289,10 @@ static 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} */
static QState ToastOven_heating(ToastOven * const me, QEvt const * const e) {
QState status_;
switch (e->sig) {
@ -301,13 +305,13 @@ static QState ToastOven_heating(ToastOven * const me, QEvt const * const e) {
return status_;
}
/*${SMs::ToastOven::SM::doorClosed::heating::toasting} .....................*/
/* ${SMs::ToastOven::SM::doorClosed::heating::toasting} */
/*${SMs::ToastOven::SM::doorClosed::heating::toasting} */
static QState ToastOven_toasting_e(ToastOven * const me) {
printf("toasting;");
(void)me; /* avoid compiler warning in case 'me' is not used */
return QM_ENTRY(&ToastOven_toasting_s);
}
/* ${SMs::ToastOven::SM::doorClosed::heating::toasting} */
/*${SMs::ToastOven::SM::doorClosed::heating::toasting} */
static QState ToastOven_toasting(ToastOven * const me, QEvt const * const e) {
QState status_;
switch (e->sig) {
@ -320,13 +324,13 @@ static QState ToastOven_toasting(ToastOven * const me, QEvt const * const e) {
return status_;
}
/*${SMs::ToastOven::SM::doorClosed::heating::baking} .......................*/
/* ${SMs::ToastOven::SM::doorClosed::heating::baking} */
/*${SMs::ToastOven::SM::doorClosed::heating::baking} */
static QState ToastOven_baking_e(ToastOven * const me) {
printf("baking;");
(void)me; /* avoid compiler warning in case 'me' is not used */
return QM_ENTRY(&ToastOven_baking_s);
}
/* ${SMs::ToastOven::SM::doorClosed::heating::baking} */
/*${SMs::ToastOven::SM::doorClosed::heating::baking} */
static QState ToastOven_baking(ToastOven * const me, QEvt const * const e) {
QState status_;
switch (e->sig) {
@ -339,13 +343,13 @@ static QState ToastOven_baking(ToastOven * const me, QEvt const * const e) {
return status_;
}
/*${SMs::ToastOven::SM::doorClosed::off} ...................................*/
/* ${SMs::ToastOven::SM::doorClosed::off} */
/*${SMs::ToastOven::SM::doorClosed::off} */
static QState ToastOven_off_e(ToastOven * const me) {
printf("toaster-Off;");
(void)me; /* avoid compiler warning in case 'me' is not used */
return QM_ENTRY(&ToastOven_off_s);
}
/* ${SMs::ToastOven::SM::doorClosed::off} */
/*${SMs::ToastOven::SM::doorClosed::off} */
static QState ToastOven_off(ToastOven * const me, QEvt const * const e) {
QState status_;
switch (e->sig) {
@ -358,23 +362,23 @@ static QState ToastOven_off(ToastOven * const me, QEvt const * const e) {
return status_;
}
/*${SMs::ToastOven::SM::doorOpen} ..........................................*/
/* ${SMs::ToastOven::SM::doorOpen} */
/*${SMs::ToastOven::SM::doorOpen} */
static 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(&ToastOven_doorOpen_s);
}
/* ${SMs::ToastOven::SM::doorOpen} */
/*${SMs::ToastOven::SM::doorOpen} */
static QState ToastOven_doorOpen_x(ToastOven * const me) {
printf("lamp-Off;");
(void)me; /* avoid compiler warning in case 'me' is not used */
return QM_EXIT(&ToastOven_doorOpen_s);
}
/* ${SMs::ToastOven::SM::doorOpen} */
/*${SMs::ToastOven::SM::doorOpen} */
static QState ToastOven_doorOpen(ToastOven * const me, QEvt const * const e) {
QState status_;
switch (e->sig) {
/* ${SMs::ToastOven::SM::doorOpen::CLOSE} */
/*${SMs::ToastOven::SM::doorOpen::CLOSE} */
case CLOSE_SIG: {
static struct {
QMState const *target;
@ -390,7 +394,7 @@ static QState ToastOven_doorOpen(ToastOven * const me, 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 {
QMState const *target;
@ -414,14 +418,14 @@ static QState ToastOven_doorOpen(ToastOven * const me, QEvt const * const e) {
return status_;
}
/*${SMs::ToastOven::SM::final} .............................................*/
/* ${SMs::ToastOven::SM::final} */
/*${SMs::ToastOven::SM::final} */
static QState ToastOven_final_e(ToastOven * const me) {
printf("\nBye! Bye!\n");
exit(0);
(void)me; /* avoid compiler warning in case 'me' is not used */
return QM_ENTRY(&ToastOven_final_s);
}
/* ${SMs::ToastOven::SM::final} */
/*${SMs::ToastOven::SM::final} */
static QState ToastOven_final(ToastOven * const me, QEvt const * const e) {
QState status_;
switch (e->sig) {
@ -433,4 +437,4 @@ static QState ToastOven_final(ToastOven * const me, 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 @@
/*****************************************************************************
/*$file${.::history.h} #####################################################*/
/*
* Model: history.qm
* File: ./history.h
* File: C:/qp_lab/qpc/examples/win32/history_qmsm/history.h
*
* This code has been generated by QM tool (see state-machine.com/qm).
* 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,8 +32,9 @@ enum ToastOvenSignals {
extern QMsm * const the_oven; /* opaque pointer to the oven MSM */
/*$declare${SMs::ToastOven_ctor} ###########################################*/
/*${SMs::ToastOven_ctor} ...................................................*/
void ToastOven_ctor(void);
/*$enddecl${SMs::ToastOven_ctor} ###########################################*/
#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="qpc" license="../../../QPC-EVAL-171231.qlc"/>
<package name="SMs" stereotype="0x02">

View File

@ -1,4 +1,4 @@
QMsmTst example, QP 5.9.1
QMsmTst example, QP 6.0.1
top-INIT;s-ENTRY;s2-ENTRY;s2-INIT;s21-ENTRY;s211-ENTRY;
A:s21-A;s211-EXIT;s21-EXIT;s21-ENTRY;s21-INIT;s211-ENTRY;
B:s21-B;s211-EXIT;s211-ENTRY;

View File

@ -1,8 +1,9 @@
/*****************************************************************************
/*$file${.::qmsmtst.c} #####################################################*/
/*
* Model: qmsmtst.qm
* File: ./qmsmtst.c
* File: C:/qp_lab/qpc/examples/win32/qmsmtst/qmsmtst.c
*
* This code has been generated by QM tool (see state-machine.com/qm).
* 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,16 +16,12 @@
* 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.c} ..........................................................*/
*/
/*$endhead${.::qmsmtst.c} ##################################################*/
#include "qpc.h"
#include "qmsmtst.h"
#if ((QP_VERSION < 591) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8)))
#error qpc version 5.9.1 or higher required
#endif
/*$declare${SMs::QMsmTst} ##################################################*/
/*${SMs::QMsmTst} ..........................................................*/
typedef struct {
/* protected: */
@ -100,18 +97,25 @@ static QMState const QMsmTst_s211_s = {
Q_ACTION_CAST(&QMsmTst_s211_x),
Q_ACTION_CAST(0) /* no intitial tran. */
};
/*$enddecl${SMs::QMsmTst} ##################################################*/
static QMsmTst l_msmtst; /* the only instance of the QMsmTst class */
/* global-scope definitions ---------------------------------------*/
QMsm * const the_msm = (QMsm *)&l_msmtst; /* the opaque pointer */
/*$define${SMs::QMsmTst_ctor} ##############################################*/
/* Check for the minimum required QP version */
#if ((QP_VERSION < 601) || (QP_VERSION != ((QP_RELEASE^4294967295U) % 0x3E8)))
#error qpc version 6.0.1 or higher required
#endif
/*${SMs::QMsmTst_ctor} .....................................................*/
void QMsmTst_ctor(void) {
QMsmTst *me = &l_msmtst;
QMsm_ctor(&me->super, Q_STATE_CAST(&QMsmTst_initial));
}
/*$enddef${SMs::QMsmTst_ctor} ##############################################*/
/*$define${SMs::QMsmTst} ###################################################*/
/*${SMs::QMsmTst} ..........................................................*/
/*${SMs::QMsmTst::SM} ......................................................*/
static QState QMsmTst_initial(QMsmTst * const me, QEvt const * const e) {
@ -127,26 +131,26 @@ static QState QMsmTst_initial(QMsmTst * const me, QEvt const * const e) {
Q_ACTION_CAST(0) /* zero terminator */
}
};
/* ${SMs::QMsmTst::SM::initial} */
/*${SMs::QMsmTst::SM::initial} */
(void)e; /* avoid compiler warning */
me->foo = 0U;
BSP_display("top-INIT;");
return QM_TRAN_INIT(&tatbl_);
}
/*${SMs::QMsmTst::SM::s} ...................................................*/
/* ${SMs::QMsmTst::SM::s} */
/*${SMs::QMsmTst::SM::s} */
static 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(&QMsmTst_s_s);
}
/* ${SMs::QMsmTst::SM::s} */
/*${SMs::QMsmTst::SM::s} */
static 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(&QMsmTst_s_s);
}
/* ${SMs::QMsmTst::SM::s::initial} */
/*${SMs::QMsmTst::SM::s::initial} */
static QState QMsmTst_s_i(QMsmTst * const me) {
static struct {
QMState const *target;
@ -159,17 +163,17 @@ static 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} */
static QState QMsmTst_s(QMsmTst * const me, QEvt const * const e) {
QState status_;
switch (e->sig) {
/* ${SMs::QMsmTst::SM::s::I} */
/*${SMs::QMsmTst::SM::s::I} */
case I_SIG: {
/* ${SMs::QMsmTst::SM::s::I::[me->foo]} */
/*${SMs::QMsmTst::SM::s::I::[me->foo]} */
if (me->foo) {
me->foo = 0U;
BSP_display("s-I;");
@ -180,7 +184,7 @@ static QState QMsmTst_s(QMsmTst * const me, QEvt const * const e) {
}
break;
}
/* ${SMs::QMsmTst::SM::s::E} */
/*${SMs::QMsmTst::SM::s::E} */
case E_SIG: {
static struct {
QMState const *target;
@ -197,7 +201,7 @@ static QState QMsmTst_s(QMsmTst * const me, QEvt const * const e) {
status_ = QM_TRAN(&tatbl_);
break;
}
/* ${SMs::QMsmTst::SM::s::TERMINATE} */
/*${SMs::QMsmTst::SM::s::TERMINATE} */
case TERMINATE_SIG: {
BSP_exit();
status_ = QM_HANDLED();
@ -212,19 +216,19 @@ static QState QMsmTst_s(QMsmTst * const me, QEvt const * const e) {
return status_;
}
/*${SMs::QMsmTst::SM::s::s1} ...............................................*/
/* ${SMs::QMsmTst::SM::s::s1} */
/*${SMs::QMsmTst::SM::s::s1} */
static 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(&QMsmTst_s1_s);
}
/* ${SMs::QMsmTst::SM::s::s1} */
/*${SMs::QMsmTst::SM::s::s1} */
static 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(&QMsmTst_s1_s);
}
/* ${SMs::QMsmTst::SM::s::s1::initial} */
/*${SMs::QMsmTst::SM::s::s1::initial} */
static QState QMsmTst_s1_i(QMsmTst * const me) {
static struct {
QMState const *target;
@ -236,23 +240,23 @@ static 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} */
static QState QMsmTst_s1(QMsmTst * const me, QEvt const * const e) {
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->foo]} */
/*${SMs::QMsmTst::SM::s::s1::D::[!me->foo]} */
if (!me->foo) {
static struct {
QMState const *target;
@ -274,7 +278,7 @@ static QState QMsmTst_s1(QMsmTst * const me, QEvt const * const e) {
}
break;
}
/* ${SMs::QMsmTst::SM::s::s1::A} */
/*${SMs::QMsmTst::SM::s::s1::A} */
case A_SIG: {
static struct {
QMState const *target;
@ -292,7 +296,7 @@ static QState QMsmTst_s1(QMsmTst * const me, 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 {
QMState const *target;
@ -308,7 +312,7 @@ static QState QMsmTst_s1(QMsmTst * const me, 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 {
QMState const *target;
@ -327,7 +331,7 @@ static QState QMsmTst_s1(QMsmTst * const me, 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 {
QMState const *target;
@ -353,23 +357,23 @@ static QState QMsmTst_s1(QMsmTst * const me, QEvt const * const e) {
return status_;
}
/*${SMs::QMsmTst::SM::s::s1::s11} ..........................................*/
/* ${SMs::QMsmTst::SM::s::s1::s11} */
/*${SMs::QMsmTst::SM::s::s1::s11} */
static 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(&QMsmTst_s11_s);
}
/* ${SMs::QMsmTst::SM::s::s1::s11} */
/*${SMs::QMsmTst::SM::s::s1::s11} */
static 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(&QMsmTst_s11_s);
}
/* ${SMs::QMsmTst::SM::s::s1::s11} */
/*${SMs::QMsmTst::SM::s::s1::s11} */
static QState QMsmTst_s11(QMsmTst * const me, QEvt const * const e) {
QState status_;
switch (e->sig) {
/* ${SMs::QMsmTst::SM::s::s1::s11::H} */
/*${SMs::QMsmTst::SM::s::s1::s11::H} */
case H_SIG: {
static struct {
QMState const *target;
@ -387,9 +391,9 @@ static QState QMsmTst_s11(QMsmTst * const me, 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->foo]} */
/*${SMs::QMsmTst::SM::s::s1::s11::D::[me->foo]} */
if (me->foo) {
static struct {
QMState const *target;
@ -411,7 +415,7 @@ static QState QMsmTst_s11(QMsmTst * const me, QEvt const * const e) {
}
break;
}
/* ${SMs::QMsmTst::SM::s::s1::s11::G} */
/*${SMs::QMsmTst::SM::s::s1::s11::G} */
case G_SIG: {
static struct {
QMState const *target;
@ -439,19 +443,19 @@ static QState QMsmTst_s11(QMsmTst * const me, QEvt const * const e) {
return status_;
}
/*${SMs::QMsmTst::SM::s::s2} ...............................................*/
/* ${SMs::QMsmTst::SM::s::s2} */
/*${SMs::QMsmTst::SM::s::s2} */
static 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(&QMsmTst_s2_s);
}
/* ${SMs::QMsmTst::SM::s::s2} */
/*${SMs::QMsmTst::SM::s::s2} */
static 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(&QMsmTst_s2_s);
}
/* ${SMs::QMsmTst::SM::s::s2::initial} */
/*${SMs::QMsmTst::SM::s::s2::initial} */
static QState QMsmTst_s2_i(QMsmTst * const me) {
static struct {
QMState const *target;
@ -464,17 +468,17 @@ static 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} */
static QState QMsmTst_s2(QMsmTst * const me, QEvt const * const e) {
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->foo]} */
/*${SMs::QMsmTst::SM::s::s2::I::[!me->foo]} */
if (!me->foo) {
me->foo = 1U;
BSP_display("s2-I;");
@ -485,7 +489,7 @@ static QState QMsmTst_s2(QMsmTst * const me, QEvt const * const e) {
}
break;
}
/* ${SMs::QMsmTst::SM::s::s2::F} */
/*${SMs::QMsmTst::SM::s::s2::F} */
case F_SIG: {
static struct {
QMState const *target;
@ -503,7 +507,7 @@ static QState QMsmTst_s2(QMsmTst * const me, 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 {
QMState const *target;
@ -529,19 +533,19 @@ static QState QMsmTst_s2(QMsmTst * const me, QEvt const * const e) {
return status_;
}
/*${SMs::QMsmTst::SM::s::s2::s21} ..........................................*/
/* ${SMs::QMsmTst::SM::s::s2::s21} */
/*${SMs::QMsmTst::SM::s::s2::s21} */
static 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(&QMsmTst_s21_s);
}
/* ${SMs::QMsmTst::SM::s::s2::s21} */
/*${SMs::QMsmTst::SM::s::s2::s21} */
static 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(&QMsmTst_s21_s);
}
/* ${SMs::QMsmTst::SM::s::s2::s21::initial} */
/*${SMs::QMsmTst::SM::s::s2::s21::initial} */
static QState QMsmTst_s21_i(QMsmTst * const me) {
static struct {
QMState const *target;
@ -553,15 +557,15 @@ static 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} */
static QState QMsmTst_s21(QMsmTst * const me, QEvt const * const e) {
QState status_;
switch (e->sig) {
/* ${SMs::QMsmTst::SM::s::s2::s21::G} */
/*${SMs::QMsmTst::SM::s::s2::s21::G} */
case G_SIG: {
static struct {
QMState const *target;
@ -580,7 +584,7 @@ static QState QMsmTst_s21(QMsmTst * const me, 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 {
QMState const *target;
@ -598,7 +602,7 @@ static QState QMsmTst_s21(QMsmTst * const me, 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 {
QMState const *target;
@ -622,23 +626,23 @@ static QState QMsmTst_s21(QMsmTst * const me, QEvt const * const e) {
return status_;
}
/*${SMs::QMsmTst::SM::s::s2::s21::s211} ....................................*/
/* ${SMs::QMsmTst::SM::s::s2::s21::s211} */
/*${SMs::QMsmTst::SM::s::s2::s21::s211} */
static 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(&QMsmTst_s211_s);
}
/* ${SMs::QMsmTst::SM::s::s2::s21::s211} */
/*${SMs::QMsmTst::SM::s::s2::s21::s211} */
static 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(&QMsmTst_s211_s);
}
/* ${SMs::QMsmTst::SM::s::s2::s21::s211} */
/*${SMs::QMsmTst::SM::s::s2::s21::s211} */
static QState QMsmTst_s211(QMsmTst * const me, QEvt const * const e) {
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 {
QMState const *target;
@ -657,7 +661,7 @@ static QState QMsmTst_s211(QMsmTst * const me, 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 {
QMState const *target;
@ -681,4 +685,4 @@ static QState QMsmTst_s211(QMsmTst * const me, QEvt const * const e) {
}
return status_;
}
/*$enddef${SMs::QMsmTst} ###################################################*/

View File

@ -1,8 +1,9 @@
/*****************************************************************************
/*$file${.::qmsmtst.h} #####################################################*/
/*
* Model: qmsmtst.qm
* File: ./qmsmtst.h
* File: C:/qp_lab/qpc/examples/win32/qmsmtst/qmsmtst.h
*
* This code has been generated by QM tool (see state-machine.com/qm).
* 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
@ -37,12 +38,13 @@ enum QMsmTstSignals {
extern QMsm * const the_msm; /* opaque pointer to the test MSM */
/*$declare${SMs::QMsmTst_ctor} #############################################*/
/*${SMs::QMsmTst_ctor} .....................................................*/
void QMsmTst_ctor(void);
/*$enddecl${SMs::QMsmTst_ctor} #############################################*/
/* BSP functions to dispaly a message and exit */
void BSP_display(char const *msg);
void BSP_exit(void);
#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 QMsm state machine test based on the 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="qpc" license="../../../QPC-EVAL-171231.qlc"/>
<package name="SMs" stereotype="0x02">

View File

@ -4,8 +4,8 @@
* @ingroup qep
* @cond
******************************************************************************
* Last updated for version 6.0.0
* Last updated on 2017-10-12
* Last updated for version 6.0.1
* Last updated on 2017-11-01
*
* Q u a n t u m L e a P s
* ---------------------------
@ -45,16 +45,16 @@
* major version number, Y is a 1-digit minor version number, and Z is
* a 1-digit release number.
*/
#define QP_VERSION 600
#define QP_VERSION 601
/*! The current QP version number string of the form X.Y.Z, where X is
* a 1-digit major version number, Y is a 1-digit minor version number,
* and Z is a 1-digit release number.
*/
#define QP_VERSION_STR "6.0.0"
#define QP_VERSION_STR "6.0.1"
/*! Tamperproof current QP release (6.0.0) and date (2017-10-13) */
#define QP_RELEASE 0x9A117A57U
/*! Tamperproof current QP release (6.0.1) and date (2017-11-10) */
#define QP_RELEASE 0x9A02AD46U
/****************************************************************************/
@ -509,10 +509,12 @@ enum {
Q_RET_NULL, /*!< return value without any effect */
/* transitions need to execute transition-action table in ::QMsm */
Q_RET_TRAN, /*!< event handled (regular transition) */
Q_RET_TRAN, /*!< regular transition */
Q_RET_TRAN_INIT, /*!< initial transition in a state or submachine */
Q_RET_TRAN_HIST, /*!< event handled (transition to history) */
Q_RET_TRAN_EP, /*!< entry-point transition into a submachine */
/* transitions that additionally clobber me->state */
Q_RET_TRAN_HIST, /*!< transition to history of a given state */
Q_RET_TRAN_XP /*!< exit-point transition out of a submachine */
};

View File

@ -1,7 +1,7 @@
;*****************************************************************************
; Product: QXK port to ARM Cortex-M (M0,M0+,M3,M4,M7), ARM-Keil assembler
; Last Updated for Version: 6.0.0
; Date of the Last Update: 2017-10-10
; Last Updated for Version: 6.0.1
; Date of the Last Update: 2017-10-17
;
; Q u a n t u m L e a P s
; ---------------------------
@ -40,7 +40,6 @@
IMPORT QXK_attr_ ; QXK attribute structure
IMPORT QXK_activate_ ; external reference
IMPORT QXK_threadRet_ ; return from a thread function
IMPORT assert_failed ; assert-failure handler
; NOTE: keep in synch with QF_BASEPRI value defined in "qf_port.h" !!!
QF_BASEPRI EQU (0xFF:SHR:2)
@ -195,7 +194,7 @@ PendSV_Handler FUNCTION
; to run, which is set in QXK_ISR_EXIT(). This pointer must not be NULL.
LDR r0,[r3,#QXK_NEXT] ; r1 := QXK_attr_.next
CMP r0,#0 ; is (QXK_attr_.next == 0)?
BEQ PendSV_error ; branch if (QXK_attr_.next == 0)
BEQ PendSV_return ; branch if (QXK_attr_.next == 0)
; Load pointers into registers...
MOV r12,r0 ; save QXK_attr_.next in r12
@ -234,11 +233,6 @@ PendSV_activate
MVNS r0,r0 ; r0 := ~6 == 0xFFFFFFF9
BX r0 ; exception-return to the QXK activator
;-------------------------------------------------------------------------
PendSV_error
LDR r3,=assert_failed
BX r3 ; long-branch to the assertion-handler
;=========================================================================
; Saving AO-thread before crossing to eXtended-thread
; expected register contents:
@ -282,7 +276,8 @@ PendSV_save_ao
; r12 -> QXK_attr_.next
PendSV_restore_ao
MOVS r0,#0
STR r0,[r3,#QXK_CURR] ; QXK_attr_.curr := 0 (QXK_attr_.next)
STR r0,[r3,#QXK_CURR] ; QXK_attr_.curr := 0
STR r0,[r3,#QXK_NEXT] ; QXK_attr_.next := 0
IF {TARGET_ARCH_THUMB} == 3 ; Cortex-M0/M0+/M1 (v6-M, v6S-M)?
MOV r0,sp ; r0 := top of stack
@ -317,7 +312,8 @@ PendSV_restore_ao
CMP r1,r0
BCC PendSV_activate ; if (next->prio > topPrio) activate the next AO
; otherwise re-enable interrupts and return to the preempted AO-thread
; otherwise re-enable interrupts and return from PendSV
PendSV_return
IF {TARGET_ARCH_THUMB} == 3 ; Cortex-M0/M0+/M1 (v6-M, v6S-M)?
CPSIE i ; enable interrupts (clear PRIMASK)
ELSE ; M3/M4/M7
@ -378,6 +374,8 @@ PendSV_save_ex
; r12 -> QXK_attr_.next
PendSV_restore_ex
STR r0,[r3,#QXK_CURR] ; QXK_attr_.curr := r0 (QXK_attr_.next)
MOVS r0,#0
STR r0,[r3,#QXK_NEXT] ; QXK_attr_.next := 0
; exit the critical section
IF {TARGET_ARCH_THUMB} == 3 ; Cortex-M0/M0+/M1 (v6-M, v6S-M)?

View File

@ -1,7 +1,7 @@
/*****************************************************************************
* Product: QXK port to ARM Cortex-M (M0,M0+,M3,M4,M7), GNU-ARM assembler
* Last Updated for Version: 6.0.0
* Date of the Last Update: 2017-10-10
* Last Updated for Version: 6.0.1
* Date of the Last Update: 2017-10-17
*
* Q u a n t u m L e a P s
* ---------------------------
@ -193,7 +193,7 @@ PendSV_Handler:
*/
LDR r0,[r3,#QXK_NEXT] /* r1 := QXK_attr_.next */
CMP r0,#0 /* is (QXK_attr_.next == 0)? */
BEQ PendSV_error /* branch if (QXK_attr_.next == 0) */
BEQ PendSV_return /* branch if (QXK_attr_.next == 0) */
/* Load pointers into registers... */
MOV r12,r0 /* save QXK_attr_.next in r12 */
@ -233,11 +233,6 @@ PendSV_activate:
MVNS r0,r0 /* r0 := ~6 == 0xFFFFFFF9 */
BX r0 /* exception-return to the QXK activator */
/*----------------------------------------------------------------------*/
PendSV_error:
LDR r3,=assert_failed
BX r3 /* long-branch to the assertion-handler */
/*========================================================================
* Saving AO-thread before crossing to eXtended-thread
* expected register contents:
@ -283,7 +278,8 @@ PendSV_save_ao:
*/
PendSV_restore_ao:
MOVS r0,#0
STR r0,[r3,#QXK_CURR] /* QXK_attr_.curr := 0 (QXK_attr_.next) */
STR r0,[r3,#QXK_CURR] /* QXK_attr_.curr := 0 */
STR r0,[r3,#QXK_NEXT] /* QXK_attr_.next := 0 */
.if __ARM_ARCH == 6 /* Cortex-M0/M0+/M1 (v6-M, v6S-M)? */
MOV r0,sp /* r0 := top of stack */
@ -318,7 +314,8 @@ PendSV_restore_ao:
CMP r1,r0
BCC PendSV_activate /* if (next->prio > topPrio) activate next AO */
/* otherwise re-enable interrupts and return to the preempted AO-thread */
/* otherwise re-enable interrupts and return from PendSV */
PendSV_return:
.if __ARM_ARCH == 6 /* Cortex-M0/M0+/M1 (v6-M, v6S-M)? */
CPSIE i /* enable interrupts (clear PRIMASK) */
.else /* M3/M4/M7 */
@ -381,6 +378,8 @@ PendSV_save_ex:
*/
PendSV_restore_ex:
STR r0,[r3,#QXK_CURR] /* QXK_attr_.curr := r0 (QXK_attr_.next) */
MOVS r0,#0
STR r0,[r3,#QXK_NEXT] /* QXK_attr_.next := 0 */
/* exit the critical section */
.if __ARM_ARCH == 6 /* Cortex-M0/M0+/M1 (v6-M, v6S-M)? */

View File

@ -1,7 +1,7 @@
;*****************************************************************************
; Product: QXK port to ARM Cortex-M (M0,M0+,M3,M4,M7), IAR-ARM assembler
; Last Updated for Version: 6.0.0
; Date of the Last Update: 2017-10-10
; Last Updated for Version: 6.0.1
; Date of the Last Update: 2017-10-17
;
; Q u a n t u m L e a P s
; ---------------------------
@ -40,7 +40,6 @@
EXTERN QXK_attr_ ; QXK attribute structure
EXTERN QXK_activate_ ; external reference
EXTERN QXK_threadRet_ ; return from a thread function
EXTERN assert_failed ; assert-failure handler
; NOTE: keep in synch with QF_BASEPRI value defined in "qf_port.h" !!!
QF_BASEPRI EQU (0xFF >> 2)
@ -193,7 +192,7 @@ PendSV_Handler:
; to run, which is set in QXK_ISR_EXIT(). This pointer must not be NULL.
LDR r0,[r3,#QXK_NEXT] ; r1 := QXK_attr_.next
CMP r0,#0 ; is (QXK_attr_.next == 0)?
BEQ PendSV_error ; branch if (QXK_attr_.next == 0)
BEQ PendSV_return ; branch if (QXK_attr_.next == 0)
; Load pointers into registers...
MOV r12,r0 ; save QXK_attr_.next in r12
@ -232,11 +231,6 @@ PendSV_activate:
MVNS r0,r0 ; r0 := ~6 == 0xFFFFFFF9
BX r0 ; exception-return to the QXK activator
;-------------------------------------------------------------------------
PendSV_error:
LDR r3,=assert_failed
BX r3 ; long-branch to the assertion-handler
;=========================================================================
; Saving AO-thread before crossing to eXtended-thread
; expected register contents:
@ -280,7 +274,8 @@ PendSV_save_ao:
; r12 -> QXK_attr_.next
PendSV_restore_ao:
MOVS r0,#0
STR r0,[r3,#QXK_CURR] ; QXK_attr_.curr := 0 (QXK_attr_.next)
STR r0,[r3,#QXK_CURR] ; QXK_attr_.curr := 0
STR r0,[r3,#QXK_NEXT] ; QXK_attr_.next := 0
#if (__CORE__ == __ARM6M__) ; Cortex-M0/M0+/M1 ?
MOV r0,sp ; r0 := top of stack
@ -315,7 +310,8 @@ PendSV_restore_ao:
CMP r1,r0
BCC PendSV_activate ; if (next->prio > topPrio) activate the next AO
; otherwise re-enable interrupts and return to the preempted AO-thread
; otherwise re-enable interrupts and return from PendSV
PendSV_return:
#if (__CORE__ == __ARM6M__) ; Cortex-M0/M0+/M1 ?
CPSIE i ; enable interrupts (clear PRIMASK)
#else ; M3/M4/M7
@ -376,6 +372,8 @@ PendSV_save_ex:
; r12 -> QXK_attr_.next
PendSV_restore_ex:
STR r0,[r3,#QXK_CURR] ; QXK_attr_.curr := r0 (QXK_attr_.next)
MOVS r0,#0
STR r0,[r3,#QXK_NEXT] ; QXK_attr_.next := 0
; exit the critical section
#if (__CORE__ == __ARM6M__) ; Cortex-M0/M0+/M1 ?

View File

@ -1,7 +1,7 @@
;*****************************************************************************
; Product: QXK port to ARM Cortex-M (M0,M0+,M3,M4,M7), TI-ARM assembler
; Last Updated for Version: 6.0.0
; Date of the Last Update: 2017-10-10
; Last Updated for Version: 6.0.1
; Date of the Last Update: 2017-10-17
;
; Q u a n t u m L e a P s
; ---------------------------
@ -43,7 +43,6 @@
.global QF_crit_entry ; enter critical section
.global QXK_get_IPSR ; get the IPSR
.global assert_failed ; low-level assert handler
.ref QXK_attr_ ; QXK attribute structure
.ref QXK_threadRet_ ; return from an extended thread function
@ -198,7 +197,7 @@ PendSV_Handler: .asmfunc
; to run, which is set in QXK_ISR_EXIT(). This pointer must not be NULL.
LDR r0,[r3,#QXK_NEXT] ; r1 := QXK_attr_.next
CMP r0,#0 ; is (QXK_attr_.next == 0)?
BEQ PendSV_error ; branch if (QXK_attr_.next == 0)
BEQ PendSV_return ; branch if (QXK_attr_.next == 0)
; Load pointers into registers...
MOV r12,r0 ; save QXK_attr_.next in r12
@ -237,11 +236,6 @@ PendSV_activate:
MVNS r0,r0 ; r0 := ~6 == 0xFFFFFFF9
BX r0 ; exception-return to the QXK activator
;-------------------------------------------------------------------------
PendSV_error:
LDR r3,assert_failed_addr
BX r3 ; long-branch to the assertion-handler
;=========================================================================
; Saving AO-thread before crossing to eXtended-thread
; expected register contents:
@ -285,7 +279,8 @@ PendSV_save_ao:
; r12 -> QXK_attr_.next
PendSV_restore_ao:
MOVS r0,#0
STR r0,[r3,#QXK_CURR] ; QXK_attr_.curr := 0 (QXK_attr_.next)
STR r0,[r3,#QXK_CURR] ; QXK_attr_.curr := 0
STR r0,[r3,#QXK_NEXT] ; QXK_attr_.next := 0
.if __TI_TMS470_V7M3__ | __TI_TMS470_V7M4__ ; | __TI_TMS470_V7M7__
.if __TI_VFP_SUPPORT__ ; if VFP available...
@ -320,7 +315,8 @@ PendSV_restore_ao:
CMP r1,r0
BCC PendSV_activate ; if (next->prio > topPrio) activate the next AO
; otherwise re-enable interrupts and return to the preempted AO-thread
; otherwise re-enable interrupts and return from PendSV
PendSV_return:
.if __TI_TMS470_V7M3__ | __TI_TMS470_V7M4__ ; | __TI_TMS470_V7M7__
MOVS r0,#0
MSR BASEPRI,r0 ; enable interrupts (clear BASEPRI)
@ -381,6 +377,8 @@ PendSV_save_ex:
; r12 -> QXK_attr_.next
PendSV_restore_ex:
STR r0,[r3,#QXK_CURR] ; QXK_attr_.curr := r0 (QXK_attr_.next)
MOVS r0,#0
STR r0,[r3,#QXK_NEXT] ; QXK_attr_.next := 0
; exit the critical section
.if __TI_TMS470_V7M3__ | __TI_TMS470_V7M4__ ; | __TI_TMS470_V7M7__

View File

@ -4,8 +4,8 @@
* @ingroup qep
* @cond
******************************************************************************
* Last updated for version 5.9.0
* Last updated on 2017-05-10
* Last updated for version 6.0.1
* Last updated on 2017-10-25
*
* Q u a n t u m L e a P s
* ---------------------------
@ -590,11 +590,14 @@ bool QHsm_isIn(QHsm * const me, QStateHandler const state) {
* @param[in] me pointer (see @ref oop)
* @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 current
* active state. For the corner case when the currently active state is the
* given @c parent state, function returns the @c parent 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.
*
* @sa QHsm_childState()
@ -603,7 +606,7 @@ QStateHandler QHsm_childState_(QHsm * const me,
QStateHandler const parent)
{
QStateHandler child = me->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 */
@ -611,7 +614,7 @@ QStateHandler QHsm_childState_(QHsm * const me,
do {
/* is this the parent of the current child? */
if (me->temp.fun == parent) {
isConfirmed = true; /* child is confirmed */
isFound = true; /* child is found */
r = (QState)Q_RET_IGNORED; /* break out of the loop */
}
else {
@ -621,8 +624,8 @@ QStateHandler QHsm_childState_(QHsm * const me,
} while (r != (QState)Q_RET_IGNORED); /* QHsm_top() state not reached */
me->temp.fun = me->state.fun; /* establish stable state configuration */
/** @post the child must be confirmed */
Q_ENSURE_ID(710, isConfirmed != false);
/** @post the child must be found */
Q_ENSURE_ID(810, isFound != false);
return child; /* return the child */
}

View File

@ -4,8 +4,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-01
*
* Q u a n t u m L e a P s
* ---------------------------
@ -64,7 +64,8 @@ static QMState const l_msm_top_s = {
/*! Internal QEP macro to increment the given action table @p act_ */
/**
* @note Incrementing a pointer violates the MISRA-C 2004 Rule 17.4(req),
* @note
* Incrementing a pointer violates the MISRA-C 2004 Rule 17.4(req),
* pointer arithmetic other than array indexing. Encapsulating this violation
* in a macro allows to selectively suppress this specific deviation.
*/
@ -90,7 +91,8 @@ static QState QMsm_enterHistory_(QMsm * const me, QMState const * const hist);
* @param[in,out] me pointer (see @ref oop)
* @param[in] initial the top-most initial transition for the MSM.
*
* @note Must be called only ONCE before QHSM_INIT().
* @note
* Must be called only ONCE before QHSM_INIT().
*
* @note
* QMsm inherits QHsm, so by the @ref oop convention it should call the
@ -124,7 +126,8 @@ void QMsm_ctor(QMsm * const me, QStateHandler initial) {
* @param[in,out] me pointer (see @ref oop)
* @param[in] e pointer to the initialization event (might be NULL)
*
* @note Must be called only ONCE after the QMsm_ctor().
* @note
* Must be called only ONCE after the QMsm_ctor().
*/
void QMsm_init_(QMsm * const me, QEvt const * const e) {
QState r;
@ -180,7 +183,7 @@ void QMsm_init_(QMsm * const me, QEvt const * const e) {
void QMsm_dispatch_(QMsm * const me, QEvt const * const e) {
QMState const *s = me->state.obj; /* store the current state */
QMState const *t = s;
QState r = (QState)Q_RET_SUPER;
QState r;
QS_CRIT_STAT_
/** @pre current state must be initialized */
@ -241,14 +244,11 @@ void QMsm_dispatch_(QMsm * const me, QEvt const * const e) {
QMTranActTable const *tatbl = me->temp.tatbl;
union QHsmAttr tmp; /* temporary to save intermediate values */
/* was a regular state transition segment taken? */
if (r == (QState)Q_RET_TRAN) {
/* was TRAN, TRAN_INIT, or TRAN_EP taken? */
if (r < (QState)Q_RET_TRAN_HIST) {
QMsm_exitToTranSource_(me, s, t);
r = QMsm_execTatbl_(me, tatbl);
}
/* was an initial transition segment taken? */
else if (r == (QState)Q_RET_TRAN_INIT) {
r = QMsm_execTatbl_(me, tatbl);
s = me->state.obj;
}
/* was a transition segment to history taken? */
else if (r == (QState)Q_RET_TRAN_HIST) {
@ -257,41 +257,39 @@ void QMsm_dispatch_(QMsm * const me, QEvt const * const e) {
QMsm_exitToTranSource_(me, s, t);
(void)QMsm_execTatbl_(me, tatbl);
r = QMsm_enterHistory_(me, tmp.obj);
}
/* was a transition segment to an entry point taken? */
else if (r == (QState)Q_RET_TRAN_EP) {
r = QMsm_execTatbl_(me, tatbl);
s = me->state.obj;
}
/* was a transition segment to an exit point taken? */
else if (r == (QState)Q_RET_TRAN_XP) {
tmp.act = me->state.act; /* save XP action */
me->state.obj = s; /* restore the original state */
r = (*tmp.act)(me); /* execute the XP action */
if (r == (QState)Q_RET_TRAN) {
if (r == (QState)Q_RET_TRAN) { /* XP -> TRAN ? */
QMsm_exitToTranSource_(me, s, t);
tmp.tatbl = me->temp.tatbl; /* save XP-Segment */
/* take the tran-to-XP segment inside submachine */
(void)QMsm_execTatbl_(me, tatbl);
me->state.obj = s; /* restore original state */
#ifdef Q_SPY
t = me->temp.tatbl->target; /* store for tracing */
#endif /* Q_SPY */
/* take the XP-Segment from submachine-state */
r = QMsm_execTatbl_(me, tmp.tatbl);
QS_BEGIN_(QS_QEP_TRAN_XP, QS_priv_.locFilter[SM_OBJ], me)
QS_OBJ_(me); /* this state machine object */
QS_FUN_(s); /* source handler */
QS_FUN_(t); /* target handler */
QS_END_()
s = me->state.obj;
}
else if (r == (QState)Q_RET_TRAN_HIST) { /* XP -> HIST ? */
tmp.obj = me->state.obj; /* save the history */
me->state.obj = s; /* restore the original state */
QMsm_exitToTranSource_(me, s, t);
/* take the tran-to-XP segment inside submachine */
(void)QMsm_execTatbl_(me, tatbl);
s = me->state.obj;
me->state.obj = tmp.obj; /* restore the history */
}
else {
/* TRAN_XP must NOT be followed by any other tran type */
Q_ASSERT_ID(330, r < (QState)Q_RET_TRAN);
}
}
else {
/* no other return value should be produced */
Q_ERROR_ID(330);
Q_ERROR_ID(340);
}
s = me->state.obj;
t = s;
t = s; /* set target to the current state */
} while (r >= (QState)Q_RET_TRAN);
@ -343,11 +341,12 @@ void QMsm_dispatch_(QMsm * const me, QEvt const * const e) {
* @param[in,out] me pointer (see @ref oop)
* @param[in] tatbl pointer to the transition-action table
*
* @returns status of the last action from the transition-action table.
* @returns
* status of the last action from the transition-action table.
*
* @note
* This function is for internal use inside the QEP event processor and should
* __not__ be called directly from the applications.
* This function is for internal use inside the QEP event processor and
* should __not__ be called directly from the applications.
*/
static QState QMsm_execTatbl_(QMsm * const me, QMTranActTable const *tatbl) {
QActionHandler const *a;
@ -404,13 +403,9 @@ static QState QMsm_execTatbl_(QMsm * const me, QMTranActTable const *tatbl) {
#endif /* Q_SPY */
}
if (r >= (QState)Q_RET_TRAN_INIT) {
me->state.obj = me->temp.tatbl->target; /* the tran. target */
}
else {
me->state.obj = tatbl->target; /* the tran. target */
}
me->state.obj = (r >= (QState)Q_RET_TRAN)
? me->temp.tatbl->target
: tatbl->target;
return r;
}
@ -460,8 +455,9 @@ static void QMsm_exitToTranSource_(QMsm * const me, QMState const *s,
* @param[in,out] me pointer (see @ref oop)
* @param[in] hist pointer to the history substate
*
* @returns #Q_RET_INIT, if an initial transition has been executed
* in the last entered state or #Q_RET_NULL if no such transition was taken.
* @returns
* #Q_RET_INIT, if an initial transition has been executed in the last entered
* state or #Q_RET_NULL if no such transition was taken.
*/
static QState QMsm_enterHistory_(QMsm * const me, QMState const *const hist) {
QMState const *s = hist;
@ -517,14 +513,15 @@ static QState QMsm_enterHistory_(QMsm * const me, QMState const *const hist) {
* @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.
*
* @param[in] me pointer (see @ref oop)
* @param[in] state pointer to the QMState object that corresponds to the
* tested state.
*
* @returns 'true' if the MSM "is in" the @p state and 'false' otherwise
* @returns
* 'true' if the MSM "is in" the @p state and 'false' otherwise
*/
bool QMsm_isInState(QMsm const * const me, QMState const * const state) {
bool inState = false; /* assume that this MSM is not in 'state' */
@ -550,8 +547,10 @@ bool QMsm_isInState(QMsm const * const me, QMState const * const state) {
* @param[in] me pointer (see @ref oop)
* @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.
*
* @sa QMsm_childStateObj()
*/
@ -559,15 +558,15 @@ QMState const *QMsm_childStateObj_(QMsm const * const me,
QMState const * const parent)
{
QMState const *child = me->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 = me->state.obj->superstate;
for (s = me->state.obj;
s != (QMState const *)0;
s = s->superstate)
{
if (s == parent) {
isConfirmed = true; /* child is confirmed */
isFound = true; /* child is found */
break;
}
else {
@ -575,8 +574,8 @@ QMState const *QMsm_childStateObj_(QMsm const * const me,
}
}
/** @post the child must be confirmed */
Q_ENSURE_ID(810, isConfirmed != false);
/** @post the child must be found */
Q_ENSURE_ID(810, isFound != false);
return child; /* return the child */
}

View File

@ -9,8 +9,8 @@
* @ingroup qf
* @cond
******************************************************************************
* Last updated for version 5.9.8
* Last updated on 2017-09-20
* Last updated for version 6.0.1
* Last updated on 2017-10-29
*
* Q u a n t u m L e a P s
* ---------------------------
@ -194,7 +194,10 @@ bool QActive_post_(QActive * const me, QEvt const * const e,
* @param[in] me pointer (see @ref oop)
* @param[in e pointer to the event to post to the queue
*
* @sa QActive_post_()
* @attention
* This function should be called only via the macro QACTIVE_POST_LIFO().
*
* @sa QActive_post_(), QACTIVE_POST(), QACTIVE_POST_X()
*/
void QActive_postLIFO_(QActive * const me, QEvt const * const e) {
QEvt const *frontEvt; /* temporary to avoid UB for volatile access */

View File

@ -4,8 +4,8 @@
* @ingroup qf
* @cond
******************************************************************************
* Last updated for version 5.9.6
* Last updated on 2017-08-01
* Last updated for version 6.0.1
* Last updated on 2017-10-29
*
* Q u a n t u m L e a P s
* ---------------------------
@ -64,13 +64,15 @@ Q_DEFINE_THIS_MODULE("qf_defer")
* an event from.
* @param[in] e pointer to the event to be deferred
*
* @returns 'true' (success) when the event could be deferred and 'false'
* (failure) if event deferral failed due to overflowing the queue.
* @returns
* 'true' (success) when the event could be deferred and 'false' (failure)
* if event deferral failed due to overflowing the queue.
*
* An active object can use multiple event queues to defer events of
* different kinds.
*
* @sa QActive_recall(), QEQueue, QActive_flushDeferred()
* @sa
* QActive_recall(), QEQueue, QActive_flushDeferred()
*/
bool QActive_defer(QActive const * const me, QEQueue * const eq,
QEvt const * const e)
@ -92,13 +94,15 @@ bool QActive_defer(QActive const * const me, QEQueue * const eq,
* @param[in,out] me pointer (see @ref oop)
* @param[in] eq pointer to a "raw" thread-safe queue to recall
* an event from.
* @returns
* 'true' if an event has been recalled and 'false' if not.
*
* @returns 'true' if an event has been recalled and 'false' if not.
*
* @note An active object can use multiple event queues to defer events of
* @note
* An active object can use multiple event queues to defer events of
* different kinds.
*
* @sa QActive_recall(), QEQueue, QActive_postLIFO_()
* @sa
* QActive_recall(), ::QEQueue, QACTIVE_POST_LIFO()
*/
bool QActive_recall(QActive * const me, QEQueue * const eq) {
QEvt const *e = QEQueue_get(eq); /* get an event from deferred queue */
@ -147,9 +151,11 @@ bool QActive_recall(QActive * const me, QEQueue * const eq) {
* @param[in,out] me pointer (see @ref oop)
* @param[in] eq pointer to a "raw" thread-safe queue to flush.
*
* @returns the number of events actually flushed from the queue.
* @returns
* the number of events actually flushed from the queue.
*
* @sa QActive_defer(), QActive_recall(), QEQueue
* @sa
* QActive_defer(), QActive_recall(), QEQueue
*/
uint_fast16_t QActive_flushDeferred(QActive const * const me,
QEQueue * const eq)

View File

@ -4,8 +4,8 @@
* @ingroup qxk
* @cond
******************************************************************************
* Last updated for version 6.0.0
* Last updated on 2017-10-11
* Last updated for version 6.0.1
* Last updated on 2017-10-17
*
* Q u a n t u m L e a P s
* ---------------------------
@ -386,7 +386,7 @@ uint_fast8_t QXK_sched_(void) {
/* is the current thread a basic-thread? */
if (QXK_attr_.curr == (struct QActive *)0) {
/* is the next a basic-thread? */
/* is next a basic-thread? */
if (next->osObject == (void *)0) {
if (p <= QXK_attr_.actPrio) {
QXK_attr_.next = (struct QActive *)0;
@ -413,26 +413,22 @@ uint_fast8_t QXK_sched_(void) {
}
else { /* currently executing an extended-thread */
/* is the new prio different from the current prio? */
if (p != QXK_attr_.curr->prio) {
/* is the next thread different from the current? */
if (next != QXK_attr_.curr) {
QS_BEGIN_NOCRIT_(QS_SCHED_NEXT, QS_priv_.locFilter[AO_OBJ],
QXK_attr_.next)
QS_TIME_(); /* timestamp */
QS_2U8_((uint8_t)p, /* priority of the next AO */
/* priority of the curent AO */
(uint8_t)QXK_attr_.curr->prio);
QS_2U8_((uint8_t)p, /* next prio */
(uint8_t)QXK_attr_.curr->prio); /* curr prio */
QS_END_NOCRIT_()
QXK_attr_.next = next;
p = (uint_fast8_t)0; /* no activation needed */
QXK_CONTEXT_SWITCH_();
}
else {
/* the current QXK thread must be the same as 'next' */
Q_ASSERT_ID(620, QXK_attr_.curr == next);
QXK_attr_.next = next;
else { /* next is the same as the current */
QXK_attr_.next = (QActive *)0; /* no need to context-switch */
p = (uint_fast8_t)0; /* no activation needed */
}
}
@ -505,7 +501,8 @@ void QXK_activate_(void) {
}
a = QF_active_[p];
Q_ASSERT_ID(710, a != (QActive *)0); /* must be registered */
/* the AO must be registered in QF */
Q_ASSERT_ID(710, a != (QActive *)0);
/* is the next a basic thread? */
if (a->osObject == (void *)0) {
@ -522,9 +519,8 @@ void QXK_activate_(void) {
QS_BEGIN_NOCRIT_(QS_SCHED_NEXT, QS_priv_.locFilter[AO_OBJ],
QXK_attr_.next)
QS_TIME_(); /* timestamp */
QS_2U8_((uint8_t)p, /* priority of the next AO */
/* priority of the curent AO */
(uint8_t)QXK_attr_.actPrio);
QS_2U8_((uint8_t)p, /* next prio */
(uint8_t)QXK_attr_.actPrio); /* curr prio */
QS_END_NOCRIT_()
QXK_attr_.next = a;
@ -541,8 +537,8 @@ void QXK_activate_(void) {
QS_BEGIN_NOCRIT_(QS_SCHED_RESUME, QS_priv_.locFilter[AO_OBJ], a)
QS_TIME_(); /* timestamp */
QS_2U8_((uint8_t)pin, /* priority of the resumed AO */
(uint8_t)pprev); /* previous priority */
QS_2U8_((uint8_t)pin, /* resumed prio */
(uint8_t)pprev); /* previous prio */
QS_END_NOCRIT_()
}
else { /* resuming priority==0 --> idle */

View File

@ -4,8 +4,8 @@
* @ingroup qxk
* @cond
******************************************************************************
* Last updated for version 5.9.8
* Last updated on 2017-09-07
* Last updated for version 6.0.1
* Last updated on 2017-10-17
*
* Q u a n t u m L e a P s
* ---------------------------
@ -32,7 +32,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Contact information:
* https://www.state-machine.com
* https://state-machine.com
* mailto:info@state-machine.com
******************************************************************************
* @endcond
@ -128,7 +128,7 @@ static void QXThread_dispatch_(QMsm * const me, QEvt const * const e) {
/****************************************************************************/
/**
* @description
* Starts execution of the 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.
*
@ -161,7 +161,7 @@ static void QXThread_start_(QActive * const me, uint_fast8_t prio,
* - NOT be called from an ISR;
* - the thread priority cannot exceed #QF_MAX_ACTIVE;
* - the stack storage must be provided;
* - the thread object must be instantiated (see QXThread_ctor()).
* - the thread must be instantiated (see QXThread_ctor()).
*/
Q_REQUIRE_ID(200, (!QXK_ISR_CONTEXT_()) /* don't call from an ISR! */
&& (prio <= (uint_fast8_t)QF_MAX_ACTIVE)
@ -216,17 +216,21 @@ static void QXThread_start_(QActive * const me, uint_fast8_t prio,
* posting the event. The special value #QF_NO_MARGIN
* means that this function will assert if posting fails.
*
* @returns
* 'true' (success) if the posting succeeded (with the provided margin) and
* 'false' (failure) when the posting fails.
*
* @note
* Should be called only via the macro QXTHREAD_POST_X().
*
* @note
* The #QF_NO_MARGIN value of the @p margin parameter is special and denotes
* situation when the post() operation is assumed to succeed (event delivery
* guarantee). An assertion fires, when the event cannot be delivered in this
* case.
* The #QF_NO_MARGIN value of the @p margin parameter is special and
* denotes situation when the post() operation is assumed to succeed
* (event delivery guarantee). An assertion fires, when the event cannot
* be delivered in this case.
*
* @note
* For compatibility with the V-table from the superclass QActive, the
* For compatibility with the V-table from the superclass ::QActive, the
* me-pointer is typed as pointing to QActive. However, the @p me pointer
* here actually points to the QXThread subclass. Therefore the downcast
* (QXThread *)me is always correct.
@ -295,7 +299,7 @@ static bool QXThread_post_(QActive * const me, QEvt const * const e,
me->eQueue.nMin = nFree; /* update minimum so far */
}
/* empty queue? */
/* queue empty? */
if (me->eQueue.frontEvt == (QEvt const *)0) {
me->eQueue.frontEvt = e; /* deliver event directly */
@ -335,7 +339,7 @@ static bool QXThread_post_(QActive * const me, QEvt const * const e,
QS_OBJ_(me); /* this active object (recipient) */
QS_2U8_(e->poolId_, e->refCtr_); /* pool Id & ref Count */
QS_EQC_(nFree); /* number of free entries */
QS_EQC_(margin); /* margin requested */
QS_EQC_((QEQueueCtr)margin); /* margin requested */
QS_END_NOCRIT_()
QF_CRIT_EXIT_();
@ -447,11 +451,11 @@ QEvt const *QXThread_queueGet(uint_fast16_t const nTicks) {
QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_GET,
QS_priv_.locFilter[AO_OBJ], thr)
QS_TIME_(); /* timestamp */
QS_SIG_(e->sig); /* the signal of this event */
QS_OBJ_(&thr->super); /* this active object */
QS_TIME_(); /* timestamp */
QS_SIG_(e->sig); /* the signal of this event */
QS_OBJ_(&thr->super); /* this active object */
QS_2U8_(e->poolId_, e->refCtr_); /* pool Id & ref Count */
QS_EQC_(nFree); /* number of free entries */
QS_EQC_(nFree); /* number of free entries */
QS_END_NOCRIT_()
}
else {
@ -462,9 +466,9 @@ QEvt const *QXThread_queueGet(uint_fast16_t const nTicks) {
QS_BEGIN_NOCRIT_(QS_QF_ACTIVE_GET_LAST,
QS_priv_.locFilter[AO_OBJ], thr)
QS_TIME_(); /* timestamp */
QS_SIG_(e->sig); /* the signal of this event */
QS_OBJ_(&thr->super); /* this active object */
QS_TIME_(); /* timestamp */
QS_SIG_(e->sig); /* the signal of this event */
QS_OBJ_(&thr->super); /* this active object */
QS_2U8_(e->poolId_, e->refCtr_); /* pool Id & ref Count */
QS_END_NOCRIT_()
}

View File

@ -1,2 +0,0 @@
QP/C 6.0.0
2017-10-13

2
version-6.0.1 Normal file
View File

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