This commit is contained in:
Quantum Leaps 2014-01-07 19:59:39 -05:00
parent 9d72aa81de
commit b9752c09d9
70 changed files with 2497 additions and 230 deletions

View File

@ -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: Dec 28, 2013
Build Date : Sep 2 2009 Run Date: Jan 06, 2014
(C)1996-2009 M Squared Technologies LLC
________________________________________________________________________
@ -564,7 +564,7 @@
~~ Total File Summary ~~
LOC 72 eLOC 72 lLOC 0 Comment 40 Lines 121
LOC 71 eLOC 71 lLOC 0 Comment 40 Lines 120
________________________________________________________________________
End of File: ..\include\qs_dummy.h
@ -941,23 +941,23 @@
Loops for / foreach : 2
Conditional if / else if: 6
Complexity Param 1 Return 1 Cyclo Vg 9 Total 11
LOC 71 eLOC 59 lLOC 34 Comment 38 Lines 87
LOC 72 eLOC 60 lLOC 35 Comment 38 Lines 89
Function: QP::QMsm::msm_tran
Parameters: (void)
Parameters: (QActionHandler const *a)
Cyclomatic Complexity Vg Detail
Function Base : 1
Loops while / do : 1
Loops for / foreach : 2
Conditional if / else if: 3
Complexity Param 0 Return 1 Cyclo Vg 7 Total 8
LOC 52 eLOC 43 lLOC 18 Comment 14 Lines 57
Complexity Param 1 Return 1 Cyclo Vg 7 Total 9
LOC 51 eLOC 42 lLOC 17 Comment 14 Lines 56
------------------------------------------------------------------------
~~ Total File Summary ~~
LOC 128 eLOC 106 lLOC 52 Comment 90 Lines 195
LOC 128 eLOC 106 lLOC 52 Comment 90 Lines 196
------------------------------------------------------------------------
~~ File Functional Summary ~~
@ -966,18 +966,18 @@
Total Function LOC.....: 123 Total Function Pts LOC : 2.4
Total Function eLOC....: 102 Total Function Pts eLOC: 2.0
Total Function lLOC....: 52 Total Function Pts lLOC: 1.0
Total Function Params .: 1 Total Function Return .: 2
Total Cyclo Complexity : 16 Total Function Complex.: 19
Total Function Params .: 2 Total Function Return .: 2
Total Cyclo Complexity : 16 Total Function Complex.: 20
------ ----- ----- ------ ------ -----
Max Function LOC ......: 71 Average Function LOC ..: 61.50
Max Function eLOC .....: 59 Average Function eLOC .: 51.00
Max Function lLOC .....: 34 Average Function lLOC .: 26.00
Max Function LOC ......: 72 Average Function LOC ..: 61.50
Max Function eLOC .....: 60 Average Function eLOC .: 51.00
Max Function lLOC .....: 35 Average Function lLOC .: 26.00
------ ----- ----- ------ ------ -----
Max Function Parameters: 1 Avg Function Parameters: 0.50
Max Function Parameters: 1 Avg Function Parameters: 1.00
Max Function Returns ..: 1 Avg Function Returns ..: 1.00
Max Interface Complex. : 2 Avg Interface Complex. : 1.50
Max Interface Complex. : 2 Avg Interface Complex. : 2.00
Max Cyclomatic Complex.: 9 Avg Cyclomatic Complex.: 8.00
Max Total Complexity ..: 11 Avg Total Complexity ..: 9.50
Max Total Complexity ..: 11 Avg Total Complexity ..: 10.00
________________________________________________________________________
End of File: ..\qep\source\qmsm_dis.cpp
@ -2934,7 +2934,7 @@
~~ Total Project Summary ~~
LOC 3988 eLOC 3549 lLOC 1564 Comment 6251 Lines 10408
LOC 3987 eLOC 3548 lLOC 1564 Comment 6251 Lines 10408
Average per File, metric/68 files
LOC 58 eLOC 52 lLOC 23 Comment 91 Lines 153
@ -3264,12 +3264,12 @@
Function: QP::QMsm::dispatch
Parameters: (QEvt const * const e)
Complexity Param 1 Return 1 Cyclo Vg 9 Total 11
LOC 71 eLOC 59 lLOC 34 Comment 38 Lines 87
LOC 72 eLOC 60 lLOC 35 Comment 38 Lines 89
Function: QP::QMsm::msm_tran
Parameters: (void)
Complexity Param 0 Return 1 Cyclo Vg 7 Total 8
LOC 52 eLOC 43 lLOC 18 Comment 14 Lines 57
Parameters: (QActionHandler const *a)
Complexity Param 1 Return 1 Cyclo Vg 7 Total 9
LOC 51 eLOC 42 lLOC 17 Comment 14 Lines 56
Function: QP::QMsm::~QMsm
Parameters: ()
@ -3674,25 +3674,25 @@
LOC 15 eLOC 13 lLOC 10 Comment 5 Lines 18
Total: Functions
LOC 2083 eLOC 1757 lLOC 1160 InCmp 291 CycloCmp 320
LOC 2083 eLOC 1757 lLOC 1160 InCmp 292 CycloCmp 320
Function Points FP(LOC) 35.9 FP(eLOC) 30.8 FP(lLOC) 20.5
------------------------------------------------------------------------
~~ Project Functional Analysis ~~
Total Functions .......: 144 Total Physical Lines ..: 2466
Total Functions .......: 144 Total Physical Lines ..: 2467
Total LOC .............: 2083 Total Function Pts LOC : 35.9
Total eLOC ............: 1757 Total Function Pts eLOC: 30.8
Total lLOC.............: 1160 Total Function Pts lLOC: 20.5
Total Cyclomatic Comp. : 320 Total Interface Comp. .: 291
Total Parameters ......: 147 Total Return Points ...: 144
Total Comment Lines ...: 1072 Total Blank Lines .....: 302
Total Cyclomatic Comp. : 320 Total Interface Comp. .: 292
Total Parameters ......: 148 Total Return Points ...: 144
Total Comment Lines ...: 1072 Total Blank Lines .....: 303
------ ----- ----- ------ ------ -----
Avg Physical Lines ....: 17.13
Avg LOC ...............: 14.47 Avg eLOC ..............: 12.20
Avg lLOC ..............: 8.06 Avg Cyclomatic Comp. ..: 2.22
Avg Interface Comp. ...: 2.02 Avg Parameters ........: 1.02
Avg Interface Comp. ...: 2.03 Avg Parameters ........: 1.03
Avg Return Points .....: 1.00 Avg Comment Lines .....: 7.44
------ ----- ----- ------ ------ -----
Max LOC ...............: 98

View File

@ -3,6 +3,23 @@ namespace QP {
/**
\page rev_page Revision History
\section qpcpp_5_2_1 Version 5.2.1, Release date: Jan 06, 2014
This release fixes two bugs.
1. In file qmsm_dis.cpp added saving of the action-table into a
temporary variable *before* exiting the current state to the transition
source. Also, changed the signature of the QMsm::msm_tran() helper
function to take the action table as parameter. NOTE: This bug only
affected the Spy configuration and because of this escaped regression
testing. The internal testing process have been updated to test all
build configurations: Debug, Release, and Spy.
2. In file qs_mem.cpp fixed an error in accounting used bytes in the QS
trace buffer.
<HR>
\section qpcpp_5_2_0 Version 5.2.0, Release date: Dec 28, 2013
This release matches the new QM 3.0.0, for which it provides model
@ -23,33 +40,38 @@ standard code metrics (e.g., lines of code), is now included in the
"QP/C++ Reference Manual", see
http://www.state-machine.com/qp/qpcpp/metrics.html
Also, in this release all internal QP data that were previously
uninitialized are now explicitly initialized to zero. In other words,
this release no longer assumes that all uninitialized data (global and
static inside functions) is implicitly initialized to zero before the
control is transferred to main(). This is a requirement of the C
Standard, but some embedded startup code fails to do this.
Finally, this release demonstrates safer stack allocation and safer
exception handlers in all ARM Cortex-M examples. The techniques are
described in the Embedded.com article "Are We Shooting Ourselves in the
Foot with Stack Overflow?".
Changes in detail:
1. In file qp_port.h defined "API Compatibility Layer", which is
controlled by the macro #QP_API_VERSION. For example, specifying
QP_API_VERSION=500 chooses API compatible with QP version 5.0.0 or
newer, but excludes APIs that became deprecated in the earlier versions.
If the macro #QP_API_VERSION is not defined by the user (typically on
the command line for the compiler), the default value of 0 is assumed.
This default means maximum backwards compatibility (from version 0.0.0).
On the other hand, higher values of #QP_API_VERSION mean less backwards
compatibility. For example QP_API_VERSION=9999 will specify
compatibility only with the latest version of QP.
The API Compatibility Layer for QP_API_VERSION < 500 provides macros:
postLIFO(), publish(), and tick(). These macros resolve to POST(),
PUBLISH(), and TICK_X() respectively.
1. for backwards compatibility, in file qp_port.h defined "API
Compatibility Layer", which is controlled by the macro #QP_API_VERSION.
For example, specifying QP_API_VERSION=500 chooses API compatible with
QP version 5.0.0 or newer, but excludes APIs that became deprecated in
the earlier versions. If the macro #QP_API_VERSION is not defined by the
user (typically on the command line for the compiler), the default value
of 0 is assumed. This default means maximum backwards compatibility
(from version 0.0.0). On the other hand, higher values of
#QP_API_VERSION mean less backwards compatibility. For example
QP_API_VERSION=9999 will specify compatibility only with the latest
version of QP. The API Compatibility Layer for QP_API_VERSION < 500
provides macros: postLIFO(), publish(), and tick(). These macros resolve
to POST(), PUBLISH(), and TICK_X() respectively.
2. In file qhsm_dis.cpp, broken up the function QHsm::dispatch() into
two functions QHsm::dispatch() and a private helper QHsm::hsm_tran().
This has reduced the cyclomatic complexity from 25 for the original
function, to 11 and 15 for QHsm::dispatch() and QHsm::hsm_tran(),
function, to 11 and 15 for QHsm::dispatch_() and QHsm::hsm_tran(),
respectively.
3. In file qmsm_dis.cpp, broken up the function QMsm::dispatch() into
@ -65,7 +87,12 @@ capabilities of QM3.
5. Added the QMsmTst example application analogous to the QHsmTst to
test the QMsm base class. The QMsmTst comes with the QM model qmsmtst.qm.
6. Updated all examples for ARM Cortex-M to use safer stack allocation
6. In file qf_act.cpp added the function QF::bzero(), and in files
qvanilla.cpp and qk.cpp added calls to QF::bzero() to explicitly clear
the uninitialized data. Also added calls to QF::bzero() inside
qf_psini.cpp.
7. Updated all examples for ARM Cortex-M to use safer stack allocation
and safer exception handlers in all ARM Cortex-M examples, as described
in the Embedded.com article "Are We Shooting Ourselves in the Foot with
Stack Overflow?".

View File

@ -1,4 +1,4 @@
QHsmTst example, QEP 5.2.0
QHsmTst example, QEP 5.2.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

@ -128,7 +128,6 @@ void BSP_init(void) {
if (QS_INIT((void *)0) == 0) { // initialize the QS software tracing
Q_ERROR();
}
QS_RESET();
QS_OBJ_DICTIONARY(&l_SysTick_Handler);
QS_OBJ_DICTIONARY(&l_GPIOPortA_IRQHandler);
}

View File

@ -146,7 +146,6 @@ void BSP_init(void) {
if (QS_INIT((void *)0) == 0) { // initialize the QS software tracing
Q_ERROR();
}
QS_RESET();
QS_OBJ_DICTIONARY(&l_SysTick_Handler);
}
//............................................................................

View File

@ -188,7 +188,6 @@ void BSP_init(void) {
BSP_randomSeed(1234U);
Q_ALLEGE(QS_INIT(static_cast<void *>(0)));
QS_RESET();
QS_OBJ_DICTIONARY(&l_SysTick_Handler);
QS_OBJ_DICTIONARY(&l_GPIOPortA_IRQHandler);
QS_USR_DICTIONARY(PHILO_STAT);

View File

@ -121,7 +121,6 @@ void BSP_init(void) {
if (QS_INIT((void *)0) == 0) { // initialize the QS software tracing
Q_ERROR();
}
QS_RESET();
QS_OBJ_DICTIONARY(&l_SysTick_Handler);
QS_OBJ_DICTIONARY(&l_GPIOPortA_IRQHandler);
}

View File

@ -121,7 +121,6 @@ void BSP_init(void) {
if (QS_INIT((void *)0) == 0) { // initialize the QS software tracing
Q_ERROR();
}
QS_RESET();
QS_OBJ_DICTIONARY(&l_SysTick_Handler);
QS_OBJ_DICTIONARY(&l_GPIOPortA_IRQHandler);
}

View File

@ -140,7 +140,6 @@ void BSP_init(void) {
if (QS_INIT((void *)0) == 0) { // initialize the QS software tracing
Q_ERROR();
}
QS_RESET();
QS_OBJ_DICTIONARY(&l_SysTick_Handler);
}
//............................................................................

View File

@ -181,7 +181,6 @@ void BSP_init(void) {
BSP_randomSeed(1234U);
Q_ALLEGE(QS_INIT(static_cast<void *>(0)));
QS_RESET();
QS_OBJ_DICTIONARY(&l_SysTick_Handler);
QS_OBJ_DICTIONARY(&l_GPIOPortA_IRQHandler);
QS_USR_DICTIONARY(PHILO_STAT);

View File

@ -69,7 +69,6 @@ void BSP_init(void) {
BSP_randomSeed(1234U);
Q_ALLEGE(QS_INIT((void *)0));
QS_RESET();
QS_OBJ_DICTIONARY(&l_clock_tick); // must be called *after* QF_init()
QS_USR_DICTIONARY(PHILO_STAT);
}

View File

@ -1,13 +1,13 @@
##############################################################################
# Product: Generic Makefile for QP/C++ application, POSIX, GNU compiler
# Last Updated for Version: 5.1.2
# Date of the Last Update: Nov 04, 2013
# Last Updated for Version: 5.2.1
# Date of the Last Update: Jan 06, 2014
#
# Q u a n t u m L e a P s
# ---------------------------
# innovating embedded systems
#
# Copyright (C) 2002-2013 Quantum Leaps, LLC. All rights reserved.
# Copyright (C) 2002-2014 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
@ -116,7 +116,7 @@ BIN_DIR := spy
INCLUDES += -I$(QTOOLS)/qspy/include
VPATH += $(QTOOLS)/qspy/source
C_SRCS += qspy.c
#C_SRCS += qspy.c
CFLAGS = -c -g -pthread $(INCLUDES) $(DEFINES) -DQ_SPY

View File

@ -1,4 +1,4 @@
QHsmTst example, QEP 5.2.0
QHsmTst example, QEP 5.2.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,4 +1,4 @@
QMsmTst example, QEP 5.2.0
QHsmTst example, QEP 5.2.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,23 +1,23 @@
QMsmTst example, QEP 5.2.0
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;
D:s211-D;s211-EXIT;s21-INIT;s211-ENTRY;
E:s-E;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s11-ENTRY;
I:s1-I;
F:s1-F;s11-EXIT;s1-EXIT;s2-ENTRY;s21-ENTRY;s211-ENTRY;
I:s2-I;
I:s-I;
F:s2-F;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s11-ENTRY;
A:s1-A;s11-EXIT;s1-EXIT;s1-ENTRY;s1-INIT;s11-ENTRY;
B:s1-B;s11-EXIT;s11-ENTRY;
D:s1-D;s11-EXIT;s1-EXIT;s-INIT;s1-ENTRY;s11-ENTRY;
D:s11-D;s11-EXIT;s1-INIT;s11-ENTRY;
E:s-E;s11-EXIT;s1-EXIT;s1-ENTRY;s11-ENTRY;
G:s11-G;s11-EXIT;s1-EXIT;s2-ENTRY;s21-ENTRY;s211-ENTRY;
H:s211-H;s211-EXIT;s21-EXIT;s2-EXIT;s-INIT;s1-ENTRY;s11-ENTRY;
H:s11-H;s11-EXIT;s1-EXIT;s-INIT;s1-ENTRY;s11-ENTRY;
C:s1-C;s11-EXIT;s1-EXIT;s2-ENTRY;s2-INIT;s21-ENTRY;s211-ENTRY;
G:s21-G;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s1-INIT;s11-ENTRY;
C:s1-C;s11-EXIT;s1-EXIT;s2-ENTRY;s2-INIT;s21-ENTRY;s211-ENTRY;
QHsmTst example, QEP 5.2.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;
D:s211-D;s211-EXIT;s21-INIT;s211-ENTRY;
E:s-E;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s11-ENTRY;
I:s1-I;
F:s1-F;s11-EXIT;s1-EXIT;s2-ENTRY;s21-ENTRY;s211-ENTRY;
I:s2-I;
I:s-I;
F:s2-F;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s11-ENTRY;
A:s1-A;s11-EXIT;s1-EXIT;s1-ENTRY;s1-INIT;s11-ENTRY;
B:s1-B;s11-EXIT;s11-ENTRY;
D:s1-D;s11-EXIT;s1-EXIT;s-INIT;s1-ENTRY;s11-ENTRY;
D:s11-D;s11-EXIT;s1-INIT;s11-ENTRY;
E:s-E;s11-EXIT;s1-EXIT;s1-ENTRY;s11-ENTRY;
G:s11-G;s11-EXIT;s1-EXIT;s2-ENTRY;s21-ENTRY;s211-ENTRY;
H:s211-H;s211-EXIT;s21-EXIT;s2-EXIT;s-INIT;s1-ENTRY;s11-ENTRY;
H:s11-H;s11-EXIT;s1-EXIT;s-INIT;s1-ENTRY;s11-ENTRY;
C:s1-C;s11-EXIT;s1-EXIT;s2-ENTRY;s2-INIT;s21-ENTRY;s211-ENTRY;
G:s21-G;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s1-INIT;s11-ENTRY;
C:s1-C;s11-EXIT;s1-EXIT;s2-ENTRY;s2-INIT;s21-ENTRY;s211-ENTRY;
C:s2-C;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s1-INIT;s11-ENTRY;

View File

@ -1,13 +1,13 @@
//****************************************************************************
// Product: QHsmTst Example, POSIX
// Last Updated for Version: 4.5.02
// Date of the Last Update: Aug 14, 2012
// Last Updated for Version: 5.2.1
// Date of the Last Update: Jan 06, 2014
//
// 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.
// Copyright (C) 2002-2014 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
@ -152,3 +152,31 @@ static void dispatch(QP::QSignal sig) {
}
} // namespace QHSMTST
//----------------------------------------------------------------------------
#ifdef Q_SPY
#include "qs_port.h"
namespace QP {
//............................................................................
void QF::onStartup(void) {
}
//............................................................................
void QF_onClockTick(void) {
}
//............................................................................
void QF::onCleanup(void) {
}
//............................................................................
void QS::onCleanup(void) {
}
//............................................................................
QSTimeCtr QS::onGetTime(void) {
return static_cast<QSTimeCtr>(clock());
}
} // namespace QP
#endif // Q_SPY

View File

@ -1,13 +1,13 @@
##############################################################################
# Product: Generic Makefile for QP/C++ application, POSIX, GNU compiler
# Last Updated for Version: 5.1.2
# Date of the Last Update: Nov 04, 2013
# Last Updated for Version: 5.2.1
# Date of the Last Update: Jan 06, 2014
#
# Q u a n t u m L e a P s
# ---------------------------
# innovating embedded systems
#
# Copyright (C) 2002-2013 Quantum Leaps, LLC. All rights reserved.
# Copyright (C) 2002-2014 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
@ -116,7 +116,7 @@ BIN_DIR := spy
INCLUDES += -I$(QTOOLS)/qspy/include
VPATH += $(QTOOLS)/qspy/source
C_SRCS += qspy.c
#C_SRCS += qspy.c
CFLAGS = -c -g -pthread $(INCLUDES) $(DEFINES) -DQ_SPY

View File

@ -1,23 +1,23 @@
QHsmTst example, QEP 5.2.0
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;
D:s211-D;s211-EXIT;s21-INIT;s211-ENTRY;
E:s-E;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s11-ENTRY;
I:s1-I;
F:s1-F;s11-EXIT;s1-EXIT;s2-ENTRY;s21-ENTRY;s211-ENTRY;
I:s2-I;
I:s-I;
F:s2-F;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s11-ENTRY;
A:s1-A;s11-EXIT;s1-EXIT;s1-ENTRY;s1-INIT;s11-ENTRY;
B:s1-B;s11-EXIT;s11-ENTRY;
D:s1-D;s11-EXIT;s1-EXIT;s-INIT;s1-ENTRY;s11-ENTRY;
D:s11-D;s11-EXIT;s1-INIT;s11-ENTRY;
E:s-E;s11-EXIT;s1-EXIT;s1-ENTRY;s11-ENTRY;
G:s11-G;s11-EXIT;s1-EXIT;s2-ENTRY;s21-ENTRY;s211-ENTRY;
H:s211-H;s211-EXIT;s21-EXIT;s2-EXIT;s-INIT;s1-ENTRY;s11-ENTRY;
H:s11-H;s11-EXIT;s1-EXIT;s-INIT;s1-ENTRY;s11-ENTRY;
C:s1-C;s11-EXIT;s1-EXIT;s2-ENTRY;s2-INIT;s21-ENTRY;s211-ENTRY;
G:s21-G;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s1-INIT;s11-ENTRY;
C:s1-C;s11-EXIT;s1-EXIT;s2-ENTRY;s2-INIT;s21-ENTRY;s211-ENTRY;
QMsmTst example, QEP 5.2.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;
D:s211-D;s211-EXIT;s21-INIT;s211-ENTRY;
E:s-E;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s11-ENTRY;
I:s1-I;
F:s1-F;s11-EXIT;s1-EXIT;s2-ENTRY;s21-ENTRY;s211-ENTRY;
I:s2-I;
I:s-I;
F:s2-F;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s11-ENTRY;
A:s1-A;s11-EXIT;s1-EXIT;s1-ENTRY;s1-INIT;s11-ENTRY;
B:s1-B;s11-EXIT;s11-ENTRY;
D:s1-D;s11-EXIT;s1-EXIT;s-INIT;s1-ENTRY;s11-ENTRY;
D:s11-D;s11-EXIT;s1-INIT;s11-ENTRY;
E:s-E;s11-EXIT;s1-EXIT;s1-ENTRY;s11-ENTRY;
G:s11-G;s11-EXIT;s1-EXIT;s2-ENTRY;s21-ENTRY;s211-ENTRY;
H:s211-H;s211-EXIT;s21-EXIT;s2-EXIT;s-INIT;s1-ENTRY;s11-ENTRY;
H:s11-H;s11-EXIT;s1-EXIT;s-INIT;s1-ENTRY;s11-ENTRY;
C:s1-C;s11-EXIT;s1-EXIT;s2-ENTRY;s2-INIT;s21-ENTRY;s211-ENTRY;
G:s21-G;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s1-INIT;s11-ENTRY;
C:s1-C;s11-EXIT;s1-EXIT;s2-ENTRY;s2-INIT;s21-ENTRY;s211-ENTRY;
C:s2-C;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s1-INIT;s11-ENTRY;

View File

@ -0,0 +1,23 @@
QMsmTst example, QEP 5.2.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;
D:s211-D;s211-EXIT;s21-INIT;s211-ENTRY;
E:s-E;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s11-ENTRY;
I:s1-I;
F:s1-F;s11-EXIT;s1-EXIT;s2-ENTRY;s21-ENTRY;s211-ENTRY;
I:s2-I;
I:s-I;
F:s2-F;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s11-ENTRY;
A:s1-A;s11-EXIT;s1-EXIT;s1-ENTRY;s1-INIT;s11-ENTRY;
B:s1-B;s11-EXIT;s11-ENTRY;
D:s1-D;s11-EXIT;s1-EXIT;s-INIT;s1-ENTRY;s11-ENTRY;
D:s11-D;s11-EXIT;s1-INIT;s11-ENTRY;
E:s-E;s11-EXIT;s1-EXIT;s1-ENTRY;s11-ENTRY;
G:s11-G;s11-EXIT;s1-EXIT;s2-ENTRY;s21-ENTRY;s211-ENTRY;
H:s211-H;s211-EXIT;s21-EXIT;s2-EXIT;s-INIT;s1-ENTRY;s11-ENTRY;
H:s11-H;s11-EXIT;s1-EXIT;s-INIT;s1-ENTRY;s11-ENTRY;
C:s1-C;s11-EXIT;s1-EXIT;s2-ENTRY;s2-INIT;s21-ENTRY;s211-ENTRY;
G:s21-G;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s1-INIT;s11-ENTRY;
C:s1-C;s11-EXIT;s1-EXIT;s2-ENTRY;s2-INIT;s21-ENTRY;s211-ENTRY;
C:s2-C;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s1-INIT;s11-ENTRY;

View File

@ -0,0 +1,23 @@
QMsmTst example, QEP 5.2.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;
D:s211-D;s211-EXIT;s21-INIT;s211-ENTRY;
E:s-E;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s11-ENTRY;
I:s1-I;
F:s1-F;s11-EXIT;s1-EXIT;s2-ENTRY;s21-ENTRY;s211-ENTRY;
I:s2-I;
I:s-I;
F:s2-F;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s11-ENTRY;
A:s1-A;s11-EXIT;s1-EXIT;s1-ENTRY;s1-INIT;s11-ENTRY;
B:s1-B;s11-EXIT;s11-ENTRY;
D:s1-D;s11-EXIT;s1-EXIT;s-INIT;s1-ENTRY;s11-ENTRY;
D:s11-D;s11-EXIT;s1-INIT;s11-ENTRY;
E:s-E;s11-EXIT;s1-EXIT;s1-ENTRY;s11-ENTRY;
G:s11-G;s11-EXIT;s1-EXIT;s2-ENTRY;s21-ENTRY;s211-ENTRY;
H:s211-H;s211-EXIT;s21-EXIT;s2-EXIT;s-INIT;s1-ENTRY;s11-ENTRY;
H:s11-H;s11-EXIT;s1-EXIT;s-INIT;s1-ENTRY;s11-ENTRY;
C:s1-C;s11-EXIT;s1-EXIT;s2-ENTRY;s2-INIT;s21-ENTRY;s211-ENTRY;
G:s21-G;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s1-INIT;s11-ENTRY;
C:s1-C;s11-EXIT;s1-EXIT;s2-ENTRY;s2-INIT;s21-ENTRY;s211-ENTRY;
C:s2-C;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s1-INIT;s11-ENTRY;

View File

@ -1,13 +1,13 @@
//****************************************************************************
// Product: QMsmTst Example, POSIX
// Last Updated for Version: 5.2.0
// Date of the Last Update: Dec 27, 2013
// Last Updated for Version: 5.2.1
// Date of the Last Update: Jan 06, 2014
//
// Q u a n t u m L e a P s
// ---------------------------
// innovating embedded systems
//
// Copyright (C) 2002-2013 Quantum Leaps, LLC. All rights reserved.
// Copyright (C) 2002-2014 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
@ -152,3 +152,33 @@ static void dispatch(QP::QSignal sig) {
}
} // namespace QMSMTST
//----------------------------------------------------------------------------
#ifdef Q_SPY
#include "qs_port.h"
namespace QP {
//............................................................................
void QF::onStartup(void) {
}
//............................................................................
void QF_onClockTick(void) {
}
//............................................................................
void QF::onCleanup(void) {
}
//............................................................................
void QS::onCleanup(void) {
}
//............................................................................
QSTimeCtr QS::onGetTime(void) {
return static_cast<QSTimeCtr>(clock());
}
} // namespace QP
#endif // Q_SPY

View File

@ -65,7 +65,6 @@ void QP::QF::onCleanup(void) {
//............................................................................
void BSP_init(void) {
Q_ALLEGE(QS_INIT((char *)0));
QS_RESET();
QS_OBJ_DICTIONARY(&l_time_tick);
QS_USR_DICTIONARY(PHILO_STAT);

View File

@ -58,7 +58,6 @@ static QTextStream l_stdOutStream(stdout, QIODevice::WriteOnly);
//............................................................................
void BSP_init(void) {
Q_ALLEGE(QS_INIT((char *)0));
QS_RESET();
QS_OBJ_DICTIONARY(&l_time_tick);
QS_USR_DICTIONARY(PHILO_STAT);

View File

@ -73,7 +73,6 @@ void QP::QF::onCleanup(void) {
//............................................................................
void BSP_init() {
Q_ALLEGE(QS_INIT((char *)0));
QS_RESET();
QS_OBJ_DICTIONARY(&l_time_tick);
QS_OBJ_DICTIONARY(&l_bsp);
QS_USR_DICTIONARY(PLAYER_TRIGGER);

View File

@ -0,0 +1,224 @@
##############################################################################
# Product: Generic Makefile for QP/C++ GUI application, Win32-GUI, MinGW
# Last Updated for Version: 5.2.0
# Date of the Last Update: Dec 03, 2013
#
# Q u a n t u m L e a P s
# ---------------------------
# innovating embedded systems
#
# Copyright (C) 2002-2013 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
# http://www.state-machine.com
# e-mail: info@quantum-leaps.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: Typically, you should have no need to change anything in this Makefile
#
##############################################################################
#-----------------------------------------------------------------------------
# NOTE: the Makefile expects that the QPCPP environment variable is defined
# and points to the QP/C++ installation directory
#
ifndef QPCPP
$(error The QPCPP environment variable must be defined)
endif
#-----------------------------------------------------------------------------
# NOTE: this Makefile assumes that the MinGW\bin directory is added
# to the PATH variable.
#
CC := gcc
CPP := g++
#LINK := gcc # for C programs
LINK := g++ # for C++ programs
RC := windres
RM := rm
#-----------------------------------------------------------------------------
# directories
#
# Project name is derived from the directory name
PROJECT := $(notdir $(CURDIR))
QP_PORT_DIR := $(QPCPP)/ports\win32
APP_DIR := .
VPATH = $(APP_DIR)
# include directories
INCLUDES = -I. \
-I$(QPCPP)/include \
-I$(QP_PORT_DIR)
# resource directory
RCINCLUDES = -IRes
# defines
DEFINES =
#-----------------------------------------------------------------------------
# files
#
# assembler source files
ASM_SRCS :=
# C source files
C_SRCS := $(wildcard *.c)
# C++ source files
CPP_SRCS := $(wildcard *.cpp)
# Resource files
RC_SRCS := $(wildcard *.rc)
LD_SCRIPT :=
#-----------------------------------------------------------------------------
# build options for various configurations
#
ifeq (rel, $(CONF)) # Release configuration ............................
BIN_DIR := rel
ASFLAGS =
CFLAGS = -c -Wall -O2 $(INCLUDES) $(DEFINES) -DNDEBUG
CPPFLAGS = -c -Wall -O2 $(INCLUDES) $(DEFINES) -DNDEBUG
LINKFLAGS = -s -L$(QP_PORT_DIR)/mingw\$(BIN_DIR) -mwindows
else ifeq (spy, $(CONF)) # Spy configuration ................................
BIN_DIR := spy
INCLUDES += -I$(QTOOLS)/qspy\include
VPATH += $(QTOOLS)/qspy\source
C_SRCS += qspy.c
ASFLAGS =
CFLAGS = -c -g $(INCLUDES) $(DEFINES) -DQ_SPY
CPPFLAGS = -c -Wall -g $(INCLUDES) $(DEFINES) -DQ_SPY
LINKFLAGS = -s -L$(QP_PORT_DIR)/mingw\$(BIN_DIR) -mwindows
else # default Debug configuration .......................
BIN_DIR := dbg
ASFLAGS =
CFLAGS = -c -Wall -g $(INCLUDES) $(DEFINES)
CPPFLAGS = -c -Wall -g $(INCLUDES) $(DEFINES)
LINKFLAGS = -s -L$(QP_PORT_DIR)/mingw\$(BIN_DIR) -mwindows
endif
ASM_OBJS := $(patsubst %.s,%.o,$(ASM_SRCS))
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
ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS))
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))
#-----------------------------------------------------------------------------
# rules
#
all: $(BIN_DIR) $(TARGET_EXE)
#all: $(BIN_DIR) $(TARGET_BIN)
$(BIN_DIR):
@echo
mkdir $@
$(TARGET_BIN): $(TARGET_EXE)
$(BIN) -O binary $< $@
$(TARGET_EXE) : $(ASM_OBJS_EXT) $(CPP_OBJS_EXT) $(C_OBJS_EXT) $(RC_OBJS_EXT)
$(LINK) $(LINKFLAGS) -o $@ $^ -lqp
$(BIN_DIR)/%.d : %.cpp
$(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@
$(BIN_DIR)/%.d : %.c
$(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@
$(BIN_DIR)/%.o : %.s
$(AS) $(ASFLAGS) $< -o $@
$(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 $(C_DEPS_EXT) $(CPP_DEPS_EXT)
.PHONY : clean
clean:
-$(RM) $(BIN_DIR)/*.o \
$(BIN_DIR)/*.d \
$(BIN_DIR)/*.exe \
$(BIN_DIR)/*.map
show:
@echo PROJECT = $(PROJECT)
@echo CONF = $(CONF)
@echo ASM_SRCS = $(ASM_SRCS)
@echo VPATH = $(VPATH)
@echo C_SRCS = $(C_SRCS)
@echo CPP_SRCS = $(CPP_SRCS)
@echo ASM_OBJS_EXT = $(ASM_OBJS_EXT)
@echo C_OBJS_EXT = $(C_OBJS_EXT)
@echo C_DEPS_EXT = $(C_DEPS_EXT)
@echo RC_OBJS_EXT = $(RC_OBJS_EXT)

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -0,0 +1,433 @@
//****************************************************************************
// Product: DPP example
// Last Updated for Version: 5.2.0
// Date of the Last Update: Jan 06, 2014
//
// Q u a n t u m L e a P s
// ---------------------------
// innovating embedded systems
//
// Copyright (C) 2002-2014 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
// http://www.state-machine.com
// e-mail: info@quantum-leaps.com
//****************************************************************************
#include "qp_port.h"
#include "dpp.h"
#include "bsp.h"
#include "win32_gui.h" // Win32 GUI elements for embedded front panels
#include "resource.h" // GUI resource IDs generated by the resource editior
#include <stdio.h> // for snprintf()
//............................................................................
int_t main_gui(void); // prototype for appThread()
// thread function for running the application main()
static DWORD WINAPI appThread(LPVOID par) {
(void)par; // unused parameter
return main_gui(); // run the QF application
}
//****************************************************************************
namespace DPP {
Q_DEFINE_THIS_FILE
// local variables -----------------------------------------------------------
static HINSTANCE l_hInst; // this application instance
static HWND l_hWnd; // main window handle
static LPSTR l_cmdLine; // the command line string
static SegmentDisplay l_philos; // SegmentDisplay to show Philo status
static OwnerDrawnButton l_pauseBtn; // owner-drawn button
static unsigned l_rnd; // random seed
#ifdef Q_SPY
enum {
PHILO_STAT = QP::QS_USER
};
static uint8_t const l_clock_tick = 0U;
#endif
// Local functions -----------------------------------------------------------
static LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg,
WPARAM wParam, LPARAM lParam);
//............................................................................
extern "C" int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst,
LPSTR cmdLine, int iCmdShow)
{
(void)hPrevInst; // avoid compiler warning about unused parameter
l_hInst = hInst; // save the application instance
l_cmdLine = cmdLine; // save the command line string
// create the main custom dialog window
HWND hWnd = CreateCustDialog(hInst, IDD_APPLICATION, NULL,
&WndProc, "QP_APP");
ShowWindow(hWnd, iCmdShow); // show the main window
// enter the message loop...
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
//............................................................................
static LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg,
WPARAM wParam, LPARAM lParam)
{
switch (iMsg) {
// Perform initialization upon cration of the main dialog window
// NOTE: Any child-windows are NOT created yet at this time, so
// the GetDlgItem() function can't be used (it will return NULL).
//
case WM_CREATE: {
l_hWnd = hWnd; // save the window handle
// initialize the owner-drawn buttons
// NOTE: must be done *before* the first drawing of the buttons,
// so WM_INITDIALOG is too late.
//
l_pauseBtn.init(LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_BTN_UP)),
LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_BTN_DWN)),
LoadCursor(NULL, IDC_HAND));
return 0;
}
// Perform initialization after all child windows have been created
case WM_INITDIALOG: {
l_philos.init(N_PHILO, // N_PHILO "segments" for the Philos
3U); // 3 bitmaps (for thinking/hungry/eating)
l_philos.initSegment(0U, GetDlgItem(hWnd, IDC_PHILO_0));
l_philos.initSegment(1U, GetDlgItem(hWnd, IDC_PHILO_1));
l_philos.initSegment(2U, GetDlgItem(hWnd, IDC_PHILO_2));
l_philos.initSegment(3U, GetDlgItem(hWnd, IDC_PHILO_3));
l_philos.initSegment(4U, GetDlgItem(hWnd, IDC_PHILO_4));
l_philos.initBitmap(0U,
LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_THINKING)));
l_philos.initBitmap(1U,
LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_HUNGRY)));
l_philos.initBitmap(2U,
LoadBitmap(l_hInst, MAKEINTRESOURCE(IDB_EATING)));
// --> QP: spawn the application thread to run main()
Q_ALLEGE(CreateThread(NULL, 0, &appThread, NULL, 0, NULL)
!= (HANDLE)0);
return 0;
}
case WM_DESTROY: {
BSP_terminate(0);
return 0;
}
// commands from regular buttons and menus...
case WM_COMMAND: {
SetFocus(hWnd);
switch (wParam) {
case IDOK:
case IDCANCEL: {
//QP::QF::PUBLISH(Q_NEW(QP::QEvt, TERMINATE_SIG), (void *)0);
BSP_terminate(0);
break;
}
}
return 0;
}
// owner-drawn buttons...
case WM_DRAWITEM: {
LPDRAWITEMSTRUCT pdis = (LPDRAWITEMSTRUCT)lParam;
switch (pdis->CtlID) {
case IDC_PAUSE: { // PAUSE owner-drawn button
static QP::QEvt pe = QEVT_INITIALIZER(PAUSE_SIG);
switch (l_pauseBtn.draw(pdis)) {
case OwnerDrawnButton::BTN_DEPRESSED: {
AO_Table->POST(&pe, (void *)0);
break;
}
case OwnerDrawnButton::BTN_RELEASED: {
AO_Table->POST(&pe, (void *)0);
break;
}
}
break;
}
}
return 0;
}
// mouse input...
case WM_MOUSEWHEEL: {
return 0;
}
// keyboard input...
case WM_KEYDOWN: {
return 0;
}
}
return DefWindowProc(hWnd, iMsg, wParam, lParam) ;
}
//............................................................................
void BSP_init(void) {
Q_ALLEGE(QS_INIT(l_cmdLine));
QS_OBJ_DICTIONARY(&l_clock_tick); // must be called *after* QF::init()
QS_USR_DICTIONARY(PHILO_STAT);
}
//............................................................................
void BSP_terminate(int16_t result) {
QP::QF::stop();
PostQuitMessage(result);
}
//............................................................................
void BSP_displayPhilStat(uint8_t n, char const *stat) {
UINT bitmapNum = 0;
Q_REQUIRE(n < N_PHILO);
switch (stat[0]) {
case 't': bitmapNum = 0U; break;
case 'h': bitmapNum = 1U; break;
case 'e': bitmapNum = 2U; break;
default: Q_ERROR(); break;
}
// set the "segment" # n to the bitmap # 'bitmapNum'
l_philos.setSegment((UINT)n, bitmapNum);
QS_BEGIN(PHILO_STAT, AO_Philo[n]) // application-specific record begin
QS_U8(1, n); // Philosopher number
QS_STR(stat); // Philosopher status
QS_END()
}
//............................................................................
void BSP_displayPaused(uint8_t paused) {
char buf[16];
LoadString(l_hInst,
(paused != 0U) ? IDS_PAUSED : IDS_RUNNING, buf, Q_DIM(buf));
SetDlgItemText(l_hWnd, IDC_PAUSED, buf);
}
//............................................................................
uint32_t BSP_random(void) { // a very cheap pseudo-random-number generator
// "Super-Duper" Linear Congruential Generator (LCG)
// LCG(2^32, 3*7*11*13*23, 0, seed)
//
l_rnd = l_rnd * (3U*7U*11U*13U*23U);
return l_rnd >> 8;
}
//............................................................................
void BSP_randomSeed(uint32_t seed) {
l_rnd = seed;
}
} // namespace DPP
//****************************************************************************
namespace QP {
//............................................................................
void QF::onStartup(void) {
QF_setTickRate(DPP::BSP_TICKS_PER_SEC); // set the desired tick rate
}
//............................................................................
void QF::onCleanup(void) {
}
//............................................................................
void QF_onClockTick(void) {
QF::TICK(&DPP::l_clock_tick); // perform the QF clock tick processing
}
//............................................................................
extern "C" void Q_onAssert(char const Q_ROM * const file, int line) {
char message[80];
QF::stop(); // stop ticking
snprintf(message, Q_DIM(message) - 1,
"Assertion failed in module %hs line %d", file, line);
MessageBox(DPP::l_hWnd, message, "!!! ASSERTION !!!",
MB_OK | MB_ICONEXCLAMATION | MB_APPLMODAL);
PostQuitMessage(-1);
}
//----------------------------------------------------------------------------
#ifdef Q_SPY // define QS callbacks
#include "qspy.h"
#include <time.h>
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 = 256U;
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 while
}
return 0; // return success
}
//............................................................................
static int custParserFun(QSpyRecord * const qrec) {
static uint32_t mpool0;
int ret = 0; // perform standard QSPY parsing
switch (qrec->rec) {
case QS_QF_MPOOL_INIT: { // example record to parse
if (mpool0 == 0U) { // MPool[0]?
mpool0 = (uint32_t)QSpyRecord_getUint64(qrec,QS_OBJ_PTR_SIZE);
}
break;
}
case QS_QF_MPOOL_GET: { // example record to parse
int nFree;
uint32_t mpool;
(void)QSpyRecord_getUint32(qrec, QS_TIME_SIZE);
mpool = (uint32_t)QSpyRecord_getUint64(qrec, QS_OBJ_PTR_SIZE);
nFree = (int)QSpyRecord_getUint32(qrec, QF_MPOOL_CTR_SIZE);
(void)QSpyRecord_getUint32(qrec, QF_MPOOL_CTR_SIZE); // nMin
if (QSpyRecord_OK(qrec) && (mpool == mpool0)) { // MPool[0]?
SetDlgItemInt(DPP::l_hWnd, IDC_MPOOL0, nFree, FALSE);
ret = 0; // don't perform standard QSPY parsing
}
break;
}
}
return ret;
}
//............................................................................
bool QS::onStartup(void const *arg) {
static uint8_t qsBuf[4*1024]; // 4K buffer for Quantum Spy
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
&custParserFun); // customized parser function
QS_FILTER_ON(QS_ALL_RECORDS);
// QS_FILTER_OFF(QS_QEP_STATE_EMPTY);
// QS_FILTER_OFF(QS_QEP_STATE_ENTRY);
// QS_FILTER_OFF(QS_QEP_STATE_EXIT);
// QS_FILTER_OFF(QS_QEP_STATE_INIT);
// QS_FILTER_OFF(QS_QEP_INIT_TRAN);
// QS_FILTER_OFF(QS_QEP_INTERN_TRAN);
// QS_FILTER_OFF(QS_QEP_TRAN);
// QS_FILTER_OFF(QS_QEP_IGNORED);
// QS_FILTER_OFF(QS_QEP_DISPATCH);
// QS_FILTER_OFF(QS_QEP_UNHANDLED);
QS_FILTER_OFF(QS_QF_ACTIVE_ADD);
QS_FILTER_OFF(QS_QF_ACTIVE_REMOVE);
QS_FILTER_OFF(QS_QF_ACTIVE_SUBSCRIBE);
QS_FILTER_OFF(QS_QF_ACTIVE_UNSUBSCRIBE);
QS_FILTER_OFF(QS_QF_ACTIVE_POST_FIFO);
QS_FILTER_OFF(QS_QF_ACTIVE_POST_LIFO);
QS_FILTER_OFF(QS_QF_ACTIVE_GET);
QS_FILTER_OFF(QS_QF_ACTIVE_GET_LAST);
QS_FILTER_OFF(QS_QF_EQUEUE_INIT);
QS_FILTER_OFF(QS_QF_EQUEUE_POST_FIFO);
QS_FILTER_OFF(QS_QF_EQUEUE_POST_LIFO);
QS_FILTER_OFF(QS_QF_EQUEUE_GET);
QS_FILTER_OFF(QS_QF_EQUEUE_GET_LAST);
// QS_FILTER_OFF(QS_QF_MPOOL_INIT);
// QS_FILTER_OFF(QS_QF_MPOOL_GET);
QS_FILTER_OFF(QS_QF_MPOOL_PUT);
QS_FILTER_OFF(QS_QF_PUBLISH);
QS_FILTER_OFF(QS_QF_NEW);
QS_FILTER_OFF(QS_QF_GC_ATTEMPT);
QS_FILTER_OFF(QS_QF_GC);
QS_FILTER_OFF(QS_QF_TICK);
QS_FILTER_OFF(QS_QF_TIMEEVT_ARM);
QS_FILTER_OFF(QS_QF_TIMEEVT_AUTO_DISARM);
QS_FILTER_OFF(QS_QF_TIMEEVT_DISARM_ATTEMPT);
QS_FILTER_OFF(QS_QF_TIMEEVT_DISARM);
QS_FILTER_OFF(QS_QF_TIMEEVT_REARM);
QS_FILTER_OFF(QS_QF_TIMEEVT_POST);
QS_FILTER_OFF(QS_QF_CRIT_ENTRY);
QS_FILTER_OFF(QS_QF_CRIT_EXIT);
QS_FILTER_OFF(QS_QF_ISR_ENTRY);
QS_FILTER_OFF(QS_QF_ISR_EXIT);
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) {
uint16_t nBytes = 1024U;
uint8_t const *block;
while ((block = getBlock(&nBytes)) != (uint8_t *)0) {
QSPY_parse(block, nBytes);
nBytes = 1024U;
}
}
//............................................................................
QSTimeCtr QS::onGetTime(void) {
return (QSTimeCtr)clock();
}
//............................................................................
void QSPY_onPrintLn(void) {
OutputDebugString(QSPY_line);
OutputDebugString("\n");
}
#endif // Q_SPY
//----------------------------------------------------------------------------
} // namespace QP

View File

@ -0,0 +1,55 @@
//****************************************************************************
// Product: DPP example
// Last Updated for Version: 5.1.0
// Date of the Last Update: Oct 10, 2013
//
// Q u a n t u m L e a P s
// ---------------------------
// innovating embedded systems
//
// Copyright (C) 2002-2013 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
// http://www.state-machine.com
// e-mail: info@quantum-leaps.com
//****************************************************************************
#ifndef bsp_h
#define bsp_h
namespace DPP {
uint32_t const BSP_TICKS_PER_SEC = static_cast<uint32_t>(50);
void BSP_init(void);
void BSP_displayPaused(uint8_t const paused);
void BSP_displayPhilStat(uint8_t const n, char_t const *stat);
void BSP_terminate(int16_t const result);
void BSP_randomSeed(uint32_t const seed); // random seed
uint32_t BSP_random(void); // pseudo-random generator
} // namespace DPP
// Windows-GUI does not use the regular main()
#define main() main_gui()
#endif // bsp_h

View File

@ -0,0 +1,61 @@
//****************************************************************************
// Model: dpp.qm
// File: ./dpp.h
//
// This code has been generated by QM tool (see 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.
//****************************************************************************
// @(/3/0) ...................................................................
#ifndef dpp_h
#define dpp_h
namespace DPP {
enum DPPSignals {
EAT_SIG = QP::Q_USER_SIG, // published by Table to let a philosopher eat
DONE_SIG, // published by Philosopher when done eating
PAUSE_SIG, // published by BSP to pause the application
TERMINATE_SIG, // published by BSP to terminate the application
MAX_PUB_SIG, // the last published signal
HUNGRY_SIG, // posted direclty to Table from hungry Philo
MAX_SIG // the last signal
};
} // namespace DPP
namespace DPP {
// @(/1/0) ...................................................................
class TableEvt : public QP::QEvt {
public:
uint8_t philoNum;
};
} // namespace DPP
// number of philosophers
#define N_PHILO ((uint8_t)5)
namespace DPP {
extern QP::QActive * const AO_Philo[N_PHILO];
} // namespace DPP
namespace DPP {
extern QP::QActive * const AO_Table;
} // namespace DPP
#endif // dpp_h

View File

@ -0,0 +1,488 @@
<?xml version="1.0" encoding="UTF-8"?>
<model version="3.0.0">
<documentation>Dining Philosopher Problem example</documentation>
<framework name="qpcpp"/>
<package name="Events" stereotype="0x01" namespace="DPP::">
<class name="TableEvt" superclass="qpcpp::QEvt">
<attribute name="philoNum" type="uint8_t" visibility="0x00" properties="0x00"/>
</class>
</package>
<package name="AOs" stereotype="0x02" namespace="DPP::">
<class name="Philo" superclass="qpcpp::QMActive">
<attribute name="m_timeEvt" type="QP::QTimeEvt" visibility="0x02" properties="0x00"/>
<operation name="Philo" type="" visibility="0x00" properties="0x00">
<code> : QMActive(Q_STATE_CAST(&amp;Philo::initial)),
m_timeEvt(this, TIMEOUT_SIG, 0U)</code>
</operation>
<statechart>
<initial target="../1">
<action>static bool registered = false; // starts off with 0, per C-standard
(void)e; // suppress the compiler warning about unused parameter
if (!registered) {
registered = true;
QS_OBJ_DICTIONARY(&amp;l_philo[0]);
QS_OBJ_DICTIONARY(&amp;l_philo[0].m_timeEvt);
QS_OBJ_DICTIONARY(&amp;l_philo[1]);
QS_OBJ_DICTIONARY(&amp;l_philo[1].m_timeEvt);
QS_OBJ_DICTIONARY(&amp;l_philo[2]);
QS_OBJ_DICTIONARY(&amp;l_philo[2].m_timeEvt);
QS_OBJ_DICTIONARY(&amp;l_philo[3]);
QS_OBJ_DICTIONARY(&amp;l_philo[3].m_timeEvt);
QS_OBJ_DICTIONARY(&amp;l_philo[4]);
QS_OBJ_DICTIONARY(&amp;l_philo[4].m_timeEvt);
QS_FUN_DICTIONARY(&amp;Philo::initial);
QS_FUN_DICTIONARY(&amp;Philo::thinking);
QS_FUN_DICTIONARY(&amp;Philo::hungry);
QS_FUN_DICTIONARY(&amp;Philo::eating);
}
QS_SIG_DICTIONARY(HUNGRY_SIG, me); // signal for each Philos
QS_SIG_DICTIONARY(TIMEOUT_SIG, me); // signal for each Philos
me-&gt;subscribe(EAT_SIG);</action>
<initial_glyph conn="2,3,5,1,20,5,-3">
<action box="0,-2,6,2"/>
</initial_glyph>
</initial>
<state name="thinking">
<entry>me-&gt;m_timeEvt.armX(think_time(), 0U);</entry>
<exit>(void)me-&gt;m_timeEvt.disarm();</exit>
<tran trig="TIMEOUT" target="../../2">
<tran_glyph conn="2,14,3,1,20,11,-3">
<action box="0,-2,6,2"/>
</tran_glyph>
</tran>
<tran trig="EAT, DONE">
<action>/* EAT or DONE must be for other Philos than this one */
Q_ASSERT(Q_EVT_CAST(TableEvt)-&gt;philoNum != PHILO_ID(me));</action>
<tran_glyph conn="2,18,3,-1,13">
<action box="0,-2,14,2"/>
</tran_glyph>
</tran>
<state_glyph node="2,5,17,16">
<entry box="1,2,5,2"/>
<exit box="1,4,5,2"/>
</state_glyph>
</state>
<state name="hungry">
<entry>TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG);
pe-&gt;philoNum = PHILO_ID(me);
AO_Table-&gt;POST(pe, me);</entry>
<tran trig="EAT">
<choice target="../../../3">
<guard>Q_EVT_CAST(TableEvt)-&gt;philoNum == PHILO_ID(me)</guard>
<choice_glyph conn="15,30,5,1,7,13,-3">
<action box="1,0,19,4"/>
</choice_glyph>
</choice>
<tran_glyph conn="2,30,3,-1,13">
<action box="0,-2,14,2"/>
</tran_glyph>
</tran>
<tran trig="DONE">
<action>/* DONE must be for other Philos than this one */
Q_ASSERT(Q_EVT_CAST(TableEvt)-&gt;philoNum != PHILO_ID(me));</action>
<tran_glyph conn="2,36,3,-1,14">
<action box="0,-2,14,2"/>
</tran_glyph>
</tran>
<state_glyph node="2,23,17,16">
<entry box="1,2,5,2"/>
</state_glyph>
</state>
<state name="eating">
<entry>me-&gt;m_timeEvt.armX(eat_time(), 0U);</entry>
<exit>TableEvt *pe = Q_NEW(TableEvt, DONE_SIG);
pe-&gt;philoNum = PHILO_ID(me);
QP::QF::PUBLISH(pe, me);
(void)me-&gt;m_timeEvt.disarm();</exit>
<tran trig="TIMEOUT" target="../../1">
<tran_glyph conn="2,51,3,1,22,-41,-5">
<action box="0,-2,6,2"/>
</tran_glyph>
</tran>
<tran trig="EAT, DONE">
<action>/* EAT or DONE must be for other Philos than this one */
Q_ASSERT(Q_EVT_CAST(TableEvt)-&gt;philoNum != PHILO_ID(me));</action>
<tran_glyph conn="2,55,3,-1,13">
<action box="0,-2,14,2"/>
</tran_glyph>
</tran>
<state_glyph node="2,41,17,18">
<entry box="1,2,5,2"/>
<exit box="1,4,5,2"/>
</state_glyph>
</state>
<state_diagram size="37,61"/>
</statechart>
</class>
<class name="Table" superclass="qpcpp::QMActive">
<attribute name="m_fork[N_PHILO]" type="uint8_t" visibility="0x02" properties="0x00"/>
<attribute name="m_isHungry[N_PHILO]" type="bool" visibility="0x02" properties="0x00"/>
<operation name="Table" type="" visibility="0x00" properties="0x00">
<code> : QMActive(Q_STATE_CAST(&amp;Table::initial))
for (uint8_t n = 0U; n &lt; N_PHILO; ++n) {
m_fork[n] = FREE;
m_isHungry[n] = false;
}</code>
</operation>
<statechart>
<initial target="../1/2">
<action>(void)e; // suppress the compiler warning about unused parameter
QS_OBJ_DICTIONARY(&amp;l_table);
QS_FUN_DICTIONARY(&amp;QP::QHsm::top);
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(TERMINATE_SIG, (void *)0);
QS_SIG_DICTIONARY(HUNGRY_SIG, me); // signal just for Table
me-&gt;subscribe(DONE_SIG);
me-&gt;subscribe(PAUSE_SIG);
me-&gt;subscribe(TERMINATE_SIG);
for (uint8_t n = 0U; n &lt; N_PHILO; ++n) {
me-&gt;m_fork[n] = FREE;
me-&gt;m_isHungry[n] = false;
BSP_displayPhilStat(n, THINKING);
}</action>
<initial_glyph conn="3,3,5,1,44,18,-9">
<action box="0,-2,6,2"/>
</initial_glyph>
</initial>
<state name="active">
<tran trig="TERMINATE">
<action>BSP_terminate(0);</action>
<tran_glyph conn="2,11,3,-1,14">
<action box="0,-2,11,4"/>
</tran_glyph>
</tran>
<tran trig="EAT">
<action>Q_ERROR();</action>
<tran_glyph conn="2,15,3,-1,14">
<action box="0,-2,10,4"/>
</tran_glyph>
</tran>
<state name="serving">
<entry brief="give pending permitions to eat">for (uint8_t n = 0U; n &lt; N_PHILO; ++n) { // give permissions to eat...
if (me-&gt;m_isHungry[n]
&amp;&amp; (me-&gt;m_fork[LEFT(n)] == FREE)
&amp;&amp; (me-&gt;m_fork[n] == FREE))
{
me-&gt;m_fork[LEFT(n)] = USED;
me-&gt;m_fork[n] = USED;
TableEvt *te = Q_NEW(TableEvt, EAT_SIG);
te-&gt;philoNum = n;
QP::QF::PUBLISH(te, me);
me-&gt;m_isHungry[n] = false;
BSP_displayPhilStat(n, EATING);
}
}</entry>
<tran trig="HUNGRY">
<action>uint8_t n = Q_EVT_CAST(TableEvt)-&gt;philoNum;
// phil ID must be in range and he must be not hungry
Q_ASSERT((n &lt; N_PHILO) &amp;&amp; (!me-&gt;m_isHungry[n]));
BSP_displayPhilStat(n, HUNGRY);
uint8_t m = LEFT(n);</action>
<choice>
<guard brief="both free">(me-&gt;m_fork[m] == FREE) &amp;&amp; (me-&gt;m_fork[n] == FREE)</guard>
<action>me-&gt;m_fork[m] = USED;
me-&gt;m_fork[n] = USED;
TableEvt *pe = Q_NEW(TableEvt, EAT_SIG);
pe-&gt;philoNum = n;
QP::QF::PUBLISH(pe, me);
BSP_displayPhilStat(n, EATING);</action>
<choice_glyph conn="19,26,5,-1,10">
<action box="1,0,10,2"/>
</choice_glyph>
</choice>
<choice>
<guard>else</guard>
<action>me-&gt;m_isHungry[n] = true;</action>
<choice_glyph conn="19,26,4,-1,5,10">
<action box="1,5,6,2"/>
</choice_glyph>
</choice>
<tran_glyph conn="4,26,3,-1,15">
<action box="0,-2,8,2"/>
</tran_glyph>
</tran>
<tran trig="DONE">
<action>uint8_t n = Q_EVT_CAST(TableEvt)-&gt;philoNum;
// phil ID must be in range and he must be not hungry
Q_ASSERT((n &lt; N_PHILO) &amp;&amp; (!me-&gt;m_isHungry[n]));
BSP_displayPhilStat(n, THINKING);
uint8_t m = LEFT(n);
// both forks of Phil[n] must be used
Q_ASSERT((me-&gt;m_fork[n] == USED) &amp;&amp; (me-&gt;m_fork[m] == USED));
me-&gt;m_fork[m] = FREE;
me-&gt;m_fork[n] = FREE;
m = RIGHT(n); // check the right neighbor
if (me-&gt;m_isHungry[m] &amp;&amp; (me-&gt;m_fork[m] == FREE)) {
me-&gt;m_fork[n] = USED;
me-&gt;m_fork[m] = USED;
me-&gt;m_isHungry[m] = false;
TableEvt *pe = Q_NEW(TableEvt, EAT_SIG);
pe-&gt;philoNum = m;
QP::QF::PUBLISH(pe, me);
BSP_displayPhilStat(m, EATING);
}
m = LEFT(n); // check the left neighbor
n = LEFT(m); // left fork of the left neighbor
if (me-&gt;m_isHungry[m] &amp;&amp; (me-&gt;m_fork[n] == FREE)) {
me-&gt;m_fork[m] = USED;
me-&gt;m_fork[n] = USED;
me-&gt;m_isHungry[m] = false;
TableEvt *pe = Q_NEW(TableEvt, EAT_SIG);
pe-&gt;philoNum = m;
QP::QF::PUBLISH(pe, me);
BSP_displayPhilStat(m, EATING);
}</action>
<tran_glyph conn="4,34,3,-1,15">
<action box="0,-2,6,2"/>
</tran_glyph>
</tran>
<tran trig="EAT">
<action>Q_ERROR();</action>
<tran_glyph conn="4,37,3,-1,15">
<action box="0,-2,12,4"/>
</tran_glyph>
</tran>
<tran trig="PAUSE" target="../../3">
<tran_glyph conn="4,41,3,1,37,6,-3">
<action box="0,-2,7,2"/>
</tran_glyph>
</tran>
<state_glyph node="4,19,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="PAUSE" target="../../2">
<tran_glyph conn="4,57,3,1,39,-20,-5">
<action box="0,-2,7,2"/>
</tran_glyph>
</tran>
<tran trig="HUNGRY">
<action>uint8_t n = Q_EVT_CAST(TableEvt)-&gt;philoNum;
// philo ID must be in range and he must be not hungry
Q_ASSERT((n &lt; N_PHILO) &amp;&amp; (!me-&gt;m_isHungry[n]));
me-&gt;m_isHungry[n] = true;
BSP_displayPhilStat(n, HUNGRY);</action>
<tran_glyph conn="4,60,3,-1,15">
<action box="0,-2,6,2"/>
</tran_glyph>
</tran>
<tran trig="DONE">
<action>uint8_t n = Q_EVT_CAST(TableEvt)-&gt;philoNum;
// phil ID must be in range and he must be not hungry
Q_ASSERT((n &lt; N_PHILO) &amp;&amp; (!me-&gt;m_isHungry[n]));
BSP_displayPhilStat(n, THINKING);
uint8_t m = LEFT(n);
/* both forks of Phil[n] must be used */
Q_ASSERT((me-&gt;m_fork[n] == USED) &amp;&amp; (me-&gt;m_fork[m] == USED));
me-&gt;m_fork[m] = FREE;
me-&gt;m_fork[n] = FREE;</action>
<tran_glyph conn="4,63,3,-1,15">
<action box="0,-2,6,2"/>
</tran_glyph>
</tran>
<state_glyph node="4,45,34,20">
<entry box="1,2,18,4"/>
<exit box="1,6,18,4"/>
</state_glyph>
</state>
<state_glyph node="2,5,43,62"/>
</state>
<state_diagram size="49,69"/>
</statechart>
</class>
<attribute name="AO_Philo[N_PHILO]" type="QP::QActive * const" visibility="0x00" properties="0x00"/>
<attribute name="AO_Table" type="QP::QActive * const" visibility="0x00" properties="0x00"/>
</package>
<directory name=".">
<file name="dpp.h">
<text>#ifndef dpp_h
#define dpp_h
namespace DPP {
enum DPPSignals {
EAT_SIG = QP::Q_USER_SIG, // published by Table to let a philosopher eat
DONE_SIG, // published by Philosopher when done eating
PAUSE_SIG, // published by BSP to pause the application
TERMINATE_SIG, // published by BSP to terminate the application
MAX_PUB_SIG, // the last published signal
HUNGRY_SIG, // posted direclty to Table from hungry Philo
MAX_SIG // the last signal
};
} // namespace DPP
$declare(Events::TableEvt)
// number of philosophers
#define N_PHILO ((uint8_t)5)
$declare(AOs::AO_Philo[N_PHILO])
$declare(AOs::AO_Table)
#endif // dpp_h</text>
</file>
<file name="philo.cpp">
<text>#include &quot;qp_port.h&quot;
#include &quot;dpp.h&quot;
#include &quot;bsp.h&quot;
Q_DEFINE_THIS_FILE
// Active object class -------------------------------------------------------
$declare(AOs::Philo)
namespace DPP {
// Local objects -------------------------------------------------------------
static Philo l_philo[N_PHILO]; // storage for all Philos
// helper function to provide a randomized think time for Philos
inline QP::QTimeEvtCtr think_time() {
return static_cast&lt;QP::QTimeEvtCtr&gt;((BSP_random() % BSP_TICKS_PER_SEC)
+ (BSP_TICKS_PER_SEC/2U));
}
// helper function to provide a randomized eat time for Philos
inline QP::QTimeEvtCtr eat_time() {
return static_cast&lt;QP::QTimeEvtCtr&gt;((BSP_random() % BSP_TICKS_PER_SEC)
+ BSP_TICKS_PER_SEC);
}
// helper function to provide the ID of Philo &quot;me&quot;
inline uint8_t PHILO_ID(Philo const * const me) {
return static_cast&lt;uint8_t&gt;(me - l_philo);
}
enum InternalSignals { // internal signals
TIMEOUT_SIG = MAX_SIG
};
// Global objects ------------------------------------------------------------
QP::QActive * const AO_Philo[N_PHILO] = { // &quot;opaque&quot; pointers to Philo AO
&amp;l_philo[0],
&amp;l_philo[1],
&amp;l_philo[2],
&amp;l_philo[3],
&amp;l_philo[4]
};
} // namespace DPP
// Philo definition ----------------------------------------------------------
$define(AOs::Philo)</text>
</file>
<file name="table.cpp">
<text>#include &quot;qp_port.h&quot;
#include &quot;dpp.h&quot;
#include &quot;bsp.h&quot;
Q_DEFINE_THIS_FILE
// Active object class -------------------------------------------------------
$declare(AOs::Table)
namespace DPP {
// helper function to provide the RIGHT neighbour of a Philo[n]
inline uint8_t RIGHT(uint8_t const n) {
return static_cast&lt;uint8_t&gt;((n + (N_PHILO - 1U)) % N_PHILO);
}
// helper function to provide the LEFT neighbour of a Philo[n]
inline uint8_t LEFT(uint8_t const n) {
return static_cast&lt;uint8_t&gt;((n + 1U) % N_PHILO);
}
static uint8_t const FREE = static_cast&lt;uint8_t&gt;(0);
static uint8_t const USED = static_cast&lt;uint8_t&gt;(1);
static char_t const * const THINKING = &amp;&quot;thinking&quot;[0];
static char_t const * const HUNGRY = &amp;&quot;hungry &quot;[0];
static char_t const * const EATING = &amp;&quot;eating &quot;[0];
// Local objects -------------------------------------------------------------
static Table l_table; // the single instance of the Table active object
// Global-scope objects ------------------------------------------------------
QP::QActive * const AO_Table = &amp;l_table; // &quot;opaque&quot; AO pointer
} // namespace DPP
//............................................................................
$define(AOs::Table)</text>
</file>
<file name="main.cpp">
<text>#include &quot;qp_port.h&quot;
#include &quot;dpp.h&quot;
#include &quot;bsp.h&quot;
//............................................................................
int main() {
static QP::QEvt const *tableQueueSto[N_PHILO];
static QP::QEvt const *philoQueueSto[N_PHILO][N_PHILO];
static QP::QSubscrList subscrSto[DPP::MAX_PUB_SIG];
static QF_MPOOL_EL(DPP::TableEvt) smlPoolSto[2*N_PHILO];
QP::QF::init(); // initialize the framework and the underlying RT kernel
DPP::BSP_init(); // initialize the BSP
// object dictionaries...
QS_OBJ_DICTIONARY(smlPoolSto);
QS_OBJ_DICTIONARY(tableQueueSto);
QS_OBJ_DICTIONARY(philoQueueSto[0]);
QS_OBJ_DICTIONARY(philoQueueSto[1]);
QS_OBJ_DICTIONARY(philoQueueSto[2]);
QS_OBJ_DICTIONARY(philoQueueSto[3]);
QS_OBJ_DICTIONARY(philoQueueSto[4]);
QP::QF::psInit(subscrSto, Q_DIM(subscrSto)); // init publish-subscribe
// initialize event pools...
QP::QF::poolInit(smlPoolSto,
sizeof(smlPoolSto), sizeof(smlPoolSto[0]));
// start the active objects...
for (uint8_t n = 0U; n &lt; N_PHILO; ++n) {
DPP::AO_Philo[n]-&gt;start((uint8_t)(n + 1U),
philoQueueSto[n], Q_DIM(philoQueueSto[n]),
(void *)0, 0U);
}
DPP::AO_Table-&gt;start((uint8_t)(N_PHILO + 1U),
tableQueueSto, Q_DIM(tableQueueSto),
(void *)0, 0U);
return QP::QF::run(); // run the QF application
}</text>
</file>
</directory>
</model>

View File

@ -0,0 +1,79 @@
// Generated by ResEdit 1.5.11
// Copyright (C) 2006-2012
// http://www.resedit.net
#include <windows.h>
#include <commctrl.h>
#include <richedit.h>
#include "resource.h"
//
// Bitmap resources
//
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
IDB_BTN_DWN BITMAP "Res\\BTN_DWN.bmp"
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
IDB_BTN_UP BITMAP "Res\\BTN_UP.bmp"
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
IDB_EATING BITMAP "Res\\eating.bmp"
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
IDB_HUNGRY BITMAP "Res\\hungry.bmp"
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
IDB_THINKING BITMAP "Res\\thinking.bmp"
//
// Dialog resources
//
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
IDD_APPLICATION DIALOGEX 0, 0, 230, 205
STYLE DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_POPUP | WS_SYSMENU
CAPTION "DPP Example"
CLASS "QP_APP"
FONT 8, "MS Shell Dlg", 0, 0, 1
{
CTEXT "www.state-machine.com", IDC_STATIC, 64, 190, 103, 8, SS_CENTER, WS_EX_TRANSPARENT
CONTROL IDB_THINKING, IDC_PHILO_0, WC_STATIC, SS_BITMAP, 90, 7, 53, 46
CONTROL IDB_THINKING, IDC_PHILO_1, WC_STATIC, SS_BITMAP, 170, 58, 53, 46, WS_EX_TRANSPARENT
CONTROL IDB_THINKING, IDC_PHILO_4, WC_STATIC, SS_BITMAP, 7, 55, 53, 46
DEFPUSHBUTTON "Quit", IDOK, 173, 7, 50, 14, WS_GROUP
CONTROL IDB_THINKING, IDC_PHILO_2, WC_STATIC, SS_BITMAP, 137, 135, 53, 46
CONTROL IDB_THINKING, IDC_PHILO_3, WC_STATIC, SS_BITMAP, 46, 134, 53, 46
CONTROL "", IDC_PAUSE, WC_BUTTON, WS_TABSTOP | WS_TABSTOP | BS_OWNERDRAW | BS_BITMAP, 103, 73, 31, 27
LTEXT "RUNNING...", IDC_PAUSED, 103, 102, 41, 8, SS_LEFT
LTEXT "?", IDC_MPOOL0, 122, 114, 34, 8, SS_LEFT
RTEXT "MPool[0]:", IDC_STATIC, 87, 113, 31, 8, SS_RIGHT
}
//
// String Table resources
//
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
STRINGTABLE
{
IDS_APP_TITLE "DPP"
IDS_PAUSED "PAUSED"
IDS_RUNNING "RUNNING..."
}
//
// Icon resources
//
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
IDI_APPLICATION ICON "Res\\qp.ico"

View File

@ -0,0 +1,61 @@
//****************************************************************************
// Model: dpp.qm
// File: ./main.cpp
//
// This code has been generated by QM tool (see 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.
//****************************************************************************
// @(/3/3) ...................................................................
#include "qp_port.h"
#include "dpp.h"
#include "bsp.h"
//............................................................................
int main() {
static QP::QEvt const *tableQueueSto[N_PHILO];
static QP::QEvt const *philoQueueSto[N_PHILO][N_PHILO];
static QP::QSubscrList subscrSto[DPP::MAX_PUB_SIG];
static QF_MPOOL_EL(DPP::TableEvt) smlPoolSto[2*N_PHILO];
QP::QF::init(); // initialize the framework and the underlying RT kernel
DPP::BSP_init(); // initialize the BSP
// object dictionaries...
QS_OBJ_DICTIONARY(smlPoolSto);
QS_OBJ_DICTIONARY(tableQueueSto);
QS_OBJ_DICTIONARY(philoQueueSto[0]);
QS_OBJ_DICTIONARY(philoQueueSto[1]);
QS_OBJ_DICTIONARY(philoQueueSto[2]);
QS_OBJ_DICTIONARY(philoQueueSto[3]);
QS_OBJ_DICTIONARY(philoQueueSto[4]);
QP::QF::psInit(subscrSto, Q_DIM(subscrSto)); // init publish-subscribe
// initialize event pools...
QP::QF::poolInit(smlPoolSto,
sizeof(smlPoolSto), sizeof(smlPoolSto[0]));
// start the active objects...
for (uint8_t n = 0U; n < N_PHILO; ++n) {
DPP::AO_Philo[n]->start((uint8_t)(n + 1U),
philoQueueSto[n], Q_DIM(philoQueueSto[n]),
(void *)0, 0U);
}
DPP::AO_Table->start((uint8_t)(N_PHILO + 1U),
tableQueueSto, Q_DIM(tableQueueSto),
(void *)0, 0U);
return QP::QF::run(); // run the QF application
}

View File

@ -0,0 +1,265 @@
//****************************************************************************
// Model: dpp.qm
// File: ./philo.cpp
//
// This code has been generated by QM tool (see 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.
//****************************************************************************
// @(/3/1) ...................................................................
#include "qp_port.h"
#include "dpp.h"
#include "bsp.h"
Q_DEFINE_THIS_FILE
// Active object class -------------------------------------------------------
namespace DPP {
// @(/2/0) ...................................................................
class Philo : public QP::QMActive {
private:
QP::QTimeEvt m_timeEvt;
public:
Philo();
protected:
static QP::QState initial(Philo * const me, QP::QEvt const * const e);
static QP::QState thinking (Philo * const me, QP::QEvt const * const e);
static QP::QState thinking_e(Philo * const me);
static QP::QState thinking_x(Philo * const me);
static QP::QMState const thinking_s;
static QP::QState hungry (Philo * const me, QP::QEvt const * const e);
static QP::QState hungry_e(Philo * const me);
static QP::QMState const hungry_s;
static QP::QState eating (Philo * const me, QP::QEvt const * const e);
static QP::QState eating_e(Philo * const me);
static QP::QState eating_x(Philo * const me);
static QP::QMState const eating_s;
};
} // namespace DPP
namespace DPP {
// Local objects -------------------------------------------------------------
static Philo l_philo[N_PHILO]; // storage for all Philos
// helper function to provide a randomized think time for Philos
inline QP::QTimeEvtCtr think_time() {
return static_cast<QP::QTimeEvtCtr>((BSP_random() % BSP_TICKS_PER_SEC)
+ (BSP_TICKS_PER_SEC/2U));
}
// helper function to provide a randomized eat time for Philos
inline QP::QTimeEvtCtr eat_time() {
return static_cast<QP::QTimeEvtCtr>((BSP_random() % BSP_TICKS_PER_SEC)
+ BSP_TICKS_PER_SEC);
}
// helper function to provide the ID of Philo "me"
inline uint8_t PHILO_ID(Philo const * const me) {
return static_cast<uint8_t>(me - l_philo);
}
enum InternalSignals { // internal signals
TIMEOUT_SIG = MAX_SIG
};
// Global objects ------------------------------------------------------------
QP::QActive * const AO_Philo[N_PHILO] = { // "opaque" pointers to Philo AO
&l_philo[0],
&l_philo[1],
&l_philo[2],
&l_philo[3],
&l_philo[4]
};
} // namespace DPP
// Philo definition ----------------------------------------------------------
namespace DPP {
// @(/2/0) ...................................................................
// @(/2/0/1) .................................................................
Philo::Philo()
: QMActive(Q_STATE_CAST(&Philo::initial)),
m_timeEvt(this, TIMEOUT_SIG, 0U)
{}
// @(/2/0/2) .................................................................
// @(/2/0/2/0)
QP::QState Philo::initial(Philo * const me, QP::QEvt const * const e) {
static QP::QActionHandler const act_[] = {
Q_ACTION_CAST(&Philo::thinking_e),
Q_ACTION_CAST(0)
};
static bool registered = false; // starts off with 0, per C-standard
(void)e; // suppress the compiler warning about unused parameter
if (!registered) {
registered = true;
QS_OBJ_DICTIONARY(&l_philo[0]);
QS_OBJ_DICTIONARY(&l_philo[0].m_timeEvt);
QS_OBJ_DICTIONARY(&l_philo[1]);
QS_OBJ_DICTIONARY(&l_philo[1].m_timeEvt);
QS_OBJ_DICTIONARY(&l_philo[2]);
QS_OBJ_DICTIONARY(&l_philo[2].m_timeEvt);
QS_OBJ_DICTIONARY(&l_philo[3]);
QS_OBJ_DICTIONARY(&l_philo[3].m_timeEvt);
QS_OBJ_DICTIONARY(&l_philo[4]);
QS_OBJ_DICTIONARY(&l_philo[4].m_timeEvt);
QS_FUN_DICTIONARY(&Philo::initial);
QS_FUN_DICTIONARY(&Philo::thinking);
QS_FUN_DICTIONARY(&Philo::hungry);
QS_FUN_DICTIONARY(&Philo::eating);
}
QS_SIG_DICTIONARY(HUNGRY_SIG, me); // signal for each Philos
QS_SIG_DICTIONARY(TIMEOUT_SIG, me); // signal for each Philos
me->subscribe(EAT_SIG);
return QM_INITIAL(&Philo::thinking_s, &act_[0]);
}
// @(/2/0/2/1) ...............................................................
QP::QMState const Philo::thinking_s = {
static_cast<QP::QMState const *>(0),
Q_STATE_CAST(&Philo::thinking),
Q_ACTION_CAST(&Philo::thinking_x)
};
QP::QState Philo::thinking_e(Philo * const me) {
me->m_timeEvt.armX(think_time(), 0U);
return QM_ENTRY(&thinking_s);
}
QP::QState Philo::thinking_x(Philo * const me) {
(void)me->m_timeEvt.disarm();
return QM_EXIT(&thinking_s);
}
QP::QState Philo::thinking(Philo * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// @(/2/0/2/1/0)
case TIMEOUT_SIG: {
static QP::QActionHandler const act_[] = {
Q_ACTION_CAST(&Philo::thinking_x),
Q_ACTION_CAST(&Philo::hungry_e),
Q_ACTION_CAST(0)
};
status_ = QM_TRAN(&hungry_s, &act_[0]);
break;
}
// @(/2/0/2/1/1)
case EAT_SIG: /* intentionally fall through */
case DONE_SIG: {
/* EAT or DONE must be for other Philos than this one */
Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me));
status_ = QM_HANDLED();
break;
}
default: {
status_ = QM_SUPER();
break;
}
}
return status_;
}
// @(/2/0/2/2) ...............................................................
QP::QMState const Philo::hungry_s = {
static_cast<QP::QMState const *>(0),
Q_STATE_CAST(&Philo::hungry),
Q_ACTION_CAST(0)
};
QP::QState Philo::hungry_e(Philo * const me) {
TableEvt *pe = Q_NEW(TableEvt, HUNGRY_SIG);
pe->philoNum = PHILO_ID(me);
AO_Table->POST(pe, me);
return QM_ENTRY(&hungry_s);
}
QP::QState Philo::hungry(Philo * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// @(/2/0/2/2/0)
case EAT_SIG: {
// @(/2/0/2/2/0/0)
if (Q_EVT_CAST(TableEvt)->philoNum == PHILO_ID(me)) {
static QP::QActionHandler const act_[] = {
Q_ACTION_CAST(&Philo::eating_e),
Q_ACTION_CAST(0)
};
status_ = QM_TRAN(&eating_s, &act_[0]);
}
else {
status_ = QM_UNHANDLED();
}
break;
}
// @(/2/0/2/2/1)
case DONE_SIG: {
/* DONE must be for other Philos than this one */
Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me));
status_ = QM_HANDLED();
break;
}
default: {
status_ = QM_SUPER();
break;
}
}
return status_;
}
// @(/2/0/2/3) ...............................................................
QP::QMState const Philo::eating_s = {
static_cast<QP::QMState const *>(0),
Q_STATE_CAST(&Philo::eating),
Q_ACTION_CAST(&Philo::eating_x)
};
QP::QState Philo::eating_e(Philo * const me) {
me->m_timeEvt.armX(eat_time(), 0U);
return QM_ENTRY(&eating_s);
}
QP::QState Philo::eating_x(Philo * const me) {
TableEvt *pe = Q_NEW(TableEvt, DONE_SIG);
pe->philoNum = PHILO_ID(me);
QP::QF::PUBLISH(pe, me);
(void)me->m_timeEvt.disarm();
return QM_EXIT(&eating_s);
}
QP::QState Philo::eating(Philo * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// @(/2/0/2/3/0)
case TIMEOUT_SIG: {
static QP::QActionHandler const act_[] = {
Q_ACTION_CAST(&Philo::eating_x),
Q_ACTION_CAST(&Philo::thinking_e),
Q_ACTION_CAST(0)
};
status_ = QM_TRAN(&thinking_s, &act_[0]);
break;
}
// @(/2/0/2/3/1)
case EAT_SIG: /* intentionally fall through */
case DONE_SIG: {
/* EAT or DONE must be for other Philos than this one */
Q_ASSERT(Q_EVT_CAST(TableEvt)->philoNum != PHILO_ID(me));
status_ = QM_HANDLED();
break;
}
default: {
status_ = QM_SUPER();
break;
}
}
return status_;
}
} // namespace DPP

View File

@ -0,0 +1,21 @@
#ifndef IDC_STATIC
#define IDC_STATIC (-1)
#endif
#define IDD_APPLICATION 101
#define IDB_THINKING 134
#define IDB_EATING 135
#define IDB_HUNGRY 136
#define IDB_BTN_UP 137
#define IDB_BTN_DWN 138
#define IDC_PHILO_0 1000
#define IDC_PHILO_1 1001
#define IDC_PHILO_2 1002
#define IDC_PHILO_3 1003
#define IDC_PHILO_4 1004
#define IDC_MPOOL0 1005
#define IDC_PAUSE 1006
#define IDC_PAUSED 1009
#define IDS_APP_TITLE 40000
#define IDS_PAUSED 40001
#define IDS_RUNNING 40002

View File

@ -0,0 +1,326 @@
//****************************************************************************
// Model: dpp.qm
// File: ./table.cpp
//
// This code has been generated by QM tool (see 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.
//****************************************************************************
// @(/3/2) ...................................................................
#include "qp_port.h"
#include "dpp.h"
#include "bsp.h"
Q_DEFINE_THIS_FILE
// Active object class -------------------------------------------------------
namespace DPP {
// @(/2/1) ...................................................................
class Table : public QP::QMActive {
private:
uint8_t m_fork[N_PHILO];
bool m_isHungry[N_PHILO];
public:
Table();
protected:
static QP::QState initial(Table * const me, QP::QEvt const * const e);
static QP::QState active (Table * const me, QP::QEvt const * const e);
static QP::QMState const active_s;
static QP::QState serving (Table * const me, QP::QEvt const * const e);
static QP::QState serving_e(Table * const me);
static QP::QMState const serving_s;
static QP::QState paused (Table * const me, QP::QEvt const * const e);
static QP::QState paused_e(Table * const me);
static QP::QState paused_x(Table * const me);
static QP::QMState const paused_s;
};
} // namespace DPP
namespace DPP {
// helper function to provide the RIGHT neighbour of a Philo[n]
inline uint8_t RIGHT(uint8_t const n) {
return static_cast<uint8_t>((n + (N_PHILO - 1U)) % N_PHILO);
}
// helper function to provide the LEFT neighbour of a Philo[n]
inline uint8_t LEFT(uint8_t const n) {
return static_cast<uint8_t>((n + 1U) % N_PHILO);
}
static uint8_t const FREE = static_cast<uint8_t>(0);
static uint8_t const USED = static_cast<uint8_t>(1);
static char_t const * const THINKING = &"thinking"[0];
static char_t const * const HUNGRY = &"hungry "[0];
static char_t const * const EATING = &"eating "[0];
// Local objects -------------------------------------------------------------
static Table l_table; // the single instance of the Table active object
// Global-scope objects ------------------------------------------------------
QP::QActive * const AO_Table = &l_table; // "opaque" AO pointer
} // namespace DPP
//............................................................................
namespace DPP {
// @(/2/1) ...................................................................
// @(/2/1/2) .................................................................
Table::Table()
: QMActive(Q_STATE_CAST(&Table::initial))
{
for (uint8_t n = 0U; n < N_PHILO; ++n) {
m_fork[n] = FREE;
m_isHungry[n] = false;
}
}
// @(/2/1/3) .................................................................
// @(/2/1/3/0)
QP::QState Table::initial(Table * const me, QP::QEvt const * const e) {
static QP::QActionHandler const act_[] = {
Q_ACTION_CAST(&Table::serving_e),
Q_ACTION_CAST(0)
};
(void)e; // suppress the compiler warning about unused parameter
QS_OBJ_DICTIONARY(&l_table);
QS_FUN_DICTIONARY(&QP::QHsm::top);
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(TERMINATE_SIG, (void *)0);
QS_SIG_DICTIONARY(HUNGRY_SIG, me); // signal just for Table
me->subscribe(DONE_SIG);
me->subscribe(PAUSE_SIG);
me->subscribe(TERMINATE_SIG);
for (uint8_t n = 0U; n < N_PHILO; ++n) {
me->m_fork[n] = FREE;
me->m_isHungry[n] = false;
BSP_displayPhilStat(n, THINKING);
}
return QM_INITIAL(&Table::serving_s, &act_[0]);
}
// @(/2/1/3/1) ...............................................................
QP::QMState const Table::active_s = {
static_cast<QP::QMState const *>(0),
Q_STATE_CAST(&Table::active),
Q_ACTION_CAST(0)
};
QP::QState Table::active(Table * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// @(/2/1/3/1/0)
case TERMINATE_SIG: {
BSP_terminate(0);
status_ = QM_HANDLED();
break;
}
// @(/2/1/3/1/1)
case EAT_SIG: {
Q_ERROR();
status_ = QM_HANDLED();
break;
}
default: {
status_ = QM_SUPER();
break;
}
}
return status_;
}
// @(/2/1/3/1/2) .............................................................
QP::QMState const Table::serving_s = {
&Table::active_s,
Q_STATE_CAST(&Table::serving),
Q_ACTION_CAST(0)
};
QP::QState Table::serving_e(Table * const me) {
for (uint8_t n = 0U; n < N_PHILO; ++n) { // give permissions to eat...
if (me->m_isHungry[n]
&& (me->m_fork[LEFT(n)] == FREE)
&& (me->m_fork[n] == FREE))
{
me->m_fork[LEFT(n)] = USED;
me->m_fork[n] = USED;
TableEvt *te = Q_NEW(TableEvt, EAT_SIG);
te->philoNum = n;
QP::QF::PUBLISH(te, me);
me->m_isHungry[n] = false;
BSP_displayPhilStat(n, EATING);
}
}
return QM_ENTRY(&serving_s);
}
QP::QState Table::serving(Table * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// @(/2/1/3/1/2/0)
case HUNGRY_SIG: {
uint8_t n = Q_EVT_CAST(TableEvt)->philoNum;
// phil ID must be in range and he must be not hungry
Q_ASSERT((n < N_PHILO) && (!me->m_isHungry[n]));
BSP_displayPhilStat(n, HUNGRY);
uint8_t m = LEFT(n);
// @(/2/1/3/1/2/0/0)
if ((me->m_fork[m] == FREE) && (me->m_fork[n] == FREE)) {
me->m_fork[m] = USED;
me->m_fork[n] = USED;
TableEvt *pe = Q_NEW(TableEvt, EAT_SIG);
pe->philoNum = n;
QP::QF::PUBLISH(pe, me);
BSP_displayPhilStat(n, EATING);
status_ = QM_HANDLED();
}
// @(/2/1/3/1/2/0/1)
else {
me->m_isHungry[n] = true;
status_ = QM_HANDLED();
}
break;
}
// @(/2/1/3/1/2/1)
case DONE_SIG: {
uint8_t n = Q_EVT_CAST(TableEvt)->philoNum;
// phil ID must be in range and he must be not hungry
Q_ASSERT((n < N_PHILO) && (!me->m_isHungry[n]));
BSP_displayPhilStat(n, THINKING);
uint8_t m = LEFT(n);
// both forks of Phil[n] must be used
Q_ASSERT((me->m_fork[n] == USED) && (me->m_fork[m] == USED));
me->m_fork[m] = FREE;
me->m_fork[n] = FREE;
m = RIGHT(n); // check the right neighbor
if (me->m_isHungry[m] && (me->m_fork[m] == FREE)) {
me->m_fork[n] = USED;
me->m_fork[m] = USED;
me->m_isHungry[m] = false;
TableEvt *pe = Q_NEW(TableEvt, EAT_SIG);
pe->philoNum = m;
QP::QF::PUBLISH(pe, me);
BSP_displayPhilStat(m, EATING);
}
m = LEFT(n); // check the left neighbor
n = LEFT(m); // left fork of the left neighbor
if (me->m_isHungry[m] && (me->m_fork[n] == FREE)) {
me->m_fork[m] = USED;
me->m_fork[n] = USED;
me->m_isHungry[m] = false;
TableEvt *pe = Q_NEW(TableEvt, EAT_SIG);
pe->philoNum = m;
QP::QF::PUBLISH(pe, me);
BSP_displayPhilStat(m, EATING);
}
status_ = QM_HANDLED();
break;
}
// @(/2/1/3/1/2/2)
case EAT_SIG: {
Q_ERROR();
status_ = QM_HANDLED();
break;
}
// @(/2/1/3/1/2/3)
case PAUSE_SIG: {
static QP::QActionHandler const act_[] = {
Q_ACTION_CAST(&Table::paused_e),
Q_ACTION_CAST(0)
};
status_ = QM_TRAN(&paused_s, &act_[0]);
break;
}
default: {
status_ = QM_SUPER();
break;
}
}
return status_;
}
// @(/2/1/3/1/3) .............................................................
QP::QMState const Table::paused_s = {
&Table::active_s,
Q_STATE_CAST(&Table::paused),
Q_ACTION_CAST(&Table::paused_x)
};
QP::QState Table::paused_e(Table * const me) {
BSP_displayPaused(1U);
return QM_ENTRY(&paused_s);
}
QP::QState Table::paused_x(Table * const me) {
BSP_displayPaused(0U);
return QM_EXIT(&paused_s);
}
QP::QState Table::paused(Table * const me, QP::QEvt const * const e) {
QP::QState status_;
switch (e->sig) {
// @(/2/1/3/1/3/0)
case PAUSE_SIG: {
static QP::QActionHandler const act_[] = {
Q_ACTION_CAST(&Table::paused_x),
Q_ACTION_CAST(&Table::serving_e),
Q_ACTION_CAST(0)
};
status_ = QM_TRAN(&serving_s, &act_[0]);
break;
}
// @(/2/1/3/1/3/1)
case HUNGRY_SIG: {
uint8_t n = Q_EVT_CAST(TableEvt)->philoNum;
// philo ID must be in range and he must be not hungry
Q_ASSERT((n < N_PHILO) && (!me->m_isHungry[n]));
me->m_isHungry[n] = true;
BSP_displayPhilStat(n, HUNGRY);
status_ = QM_HANDLED();
break;
}
// @(/2/1/3/1/3/2)
case DONE_SIG: {
uint8_t n = Q_EVT_CAST(TableEvt)->philoNum;
// phil ID must be in range and he must be not hungry
Q_ASSERT((n < N_PHILO) && (!me->m_isHungry[n]));
BSP_displayPhilStat(n, THINKING);
uint8_t m = LEFT(n);
/* both forks of Phil[n] must be used */
Q_ASSERT((me->m_fork[n] == USED) && (me->m_fork[m] == USED));
me->m_fork[m] = FREE;
me->m_fork[n] = FREE;
status_ = QM_HANDLED();
break;
}
default: {
status_ = QM_SUPER();
break;
}
}
return status_;
}
} // namespace DPP

View File

@ -65,7 +65,6 @@ void BSP_init(void) {
BSP_randomSeed(1234U);
Q_ALLEGE(QS_INIT((void *)0));
QS_RESET();
QS_OBJ_DICTIONARY(&l_clock_tick); // must be called *after* QF::init()
QS_USR_DICTIONARY(PHILO_STAT);
}

View File

@ -86,7 +86,7 @@ INCLUDES = -I. \
RCINCLUDES = -IRes
# defines
DEFINES =-DQP_API_VERSION=9999
DEFINES =
#-----------------------------------------------------------------------------
# files

View File

@ -99,7 +99,7 @@ QP::QState Mine1::initial(Mine1 * const me, QP::QEvt const * const e) {
QS_SIG_DICTIONARY(MINE_RECYCLE_SIG, me);
QS_SIG_DICTIONARY(SHIP_IMG_SIG, me);
QS_SIG_DICTIONARY(MISSILE_IMG_SIG, me);
return QM_INITIAL(&Mine1::unused_s, QP::QMsm::s_emptyAction_);
return QM_INITIAL(&Mine1::unused_s, &QP::QMsm::s_emptyAction_[0]);
}
// @(/2/3/4/1) ...............................................................
QP::QMState const Mine1::unused_s = {
@ -114,7 +114,7 @@ QP::QState Mine1::unused(Mine1 * const me, QP::QEvt const * const e) {
case MINE_PLANT_SIG: {
me->m_x = Q_EVT_CAST(ObjectPosEvt)->x;
me->m_y = Q_EVT_CAST(ObjectPosEvt)->y;
status_ = QM_TRAN(&planted_s, QP::QMsm::s_emptyAction_);
status_ = QM_TRAN(&planted_s, &QP::QMsm::s_emptyAction_[0]);
break;
}
default: {

View File

@ -99,7 +99,7 @@ QP::QState Mine2::initial(Mine2 * const me, QP::QEvt const * const e) {
QS_SIG_DICTIONARY(MINE_RECYCLE_SIG, me);
QS_SIG_DICTIONARY(SHIP_IMG_SIG, me);
QS_SIG_DICTIONARY(MISSILE_IMG_SIG, me);
return QM_INITIAL(&Mine2::unused_s, QP::QMsm::s_emptyAction_);
return QM_INITIAL(&Mine2::unused_s, &QP::QMsm::s_emptyAction_[0]);
}
// @(/2/4/4/1) ...............................................................
QP::QMState const Mine2::unused_s = {
@ -114,7 +114,7 @@ QP::QState Mine2::unused(Mine2 * const me, QP::QEvt const * const e) {
case MINE_PLANT_SIG: {
me->m_x = Q_EVT_CAST(ObjectPosEvt)->x;
me->m_y = Q_EVT_CAST(ObjectPosEvt)->y;
status_ = QM_TRAN(&planted_s, QP::QMsm::s_emptyAction_);
status_ = QM_TRAN(&planted_s, &QP::QMsm::s_emptyAction_[0]);
break;
}
default: {

View File

@ -80,7 +80,7 @@ QP::QState Missile::initial(Missile * const me, QP::QEvt const * const e) {
QS_SIG_DICTIONARY(MISSILE_FIRE_SIG, &l_missile); // local signals
QS_SIG_DICTIONARY(HIT_WALL_SIG, &l_missile);
QS_SIG_DICTIONARY(DESTROYED_MINE_SIG, &l_missile);
return QM_INITIAL(&Missile::armed_s, QP::QMsm::s_emptyAction_);
return QM_INITIAL(&Missile::armed_s, &QP::QMsm::s_emptyAction_[0]);
}
// @(/2/2/4/1) ...............................................................
QP::QMState const Missile::armed_s = {
@ -95,7 +95,7 @@ QP::QState Missile::armed(Missile * const me, QP::QEvt const * const e) {
case MISSILE_FIRE_SIG: {
me->m_x = Q_EVT_CAST(ObjectPosEvt)->x;
me->m_y = Q_EVT_CAST(ObjectPosEvt)->y;
status_ = QM_TRAN(&flying_s, QP::QMsm::s_emptyAction_);
status_ = QM_TRAN(&flying_s, &QP::QMsm::s_emptyAction_[0]);
break;
}
default: {
@ -129,7 +129,7 @@ QP::QState Missile::flying(Missile * const me, QP::QEvt const * const e) {
}
// @(/2/2/4/2/0/1)
else {
status_ = QM_TRAN(&armed_s, QP::QMsm::s_emptyAction_);
status_ = QM_TRAN(&armed_s, &QP::QMsm::s_emptyAction_[0]);
}
break;
}
@ -145,7 +145,7 @@ QP::QState Missile::flying(Missile * const me, QP::QEvt const * const e) {
// @(/2/2/4/2/2)
case DESTROYED_MINE_SIG: {
AO_Ship->POST(e, me);
status_ = QM_TRAN(&armed_s, QP::QMsm::s_emptyAction_);
status_ = QM_TRAN(&armed_s, &QP::QMsm::s_emptyAction_[0]);
break;
}
default: {
@ -185,7 +185,7 @@ QP::QState Missile::exploding(Missile * const me, QP::QEvt const * const e) {
}
// @(/2/2/4/3/0/1)
else {
status_ = QM_TRAN(&armed_s, QP::QMsm::s_emptyAction_);
status_ = QM_TRAN(&armed_s, &QP::QMsm::s_emptyAction_[0]);
}
break;
}

View File

@ -108,7 +108,7 @@ QP::QMState const Ship::active_s = {
Q_ACTION_CAST(0)
};
QP::QState Ship::active_i(Ship * const me) {
return QM_INITIAL(&Ship::parked_s, QP::QMsm::s_emptyAction_);
return QM_INITIAL(&Ship::parked_s, &QP::QMsm::s_emptyAction_[0]);
}
QP::QState Ship::active(Ship * const me, QP::QEvt const * const e) {
QP::QState status_;
@ -259,7 +259,7 @@ QP::QState Ship::exploding(Ship * const me, QP::QEvt const * const e) {
ScoreEvt *gameOver = Q_NEW(ScoreEvt, GAME_OVER_SIG);
gameOver->score = me->m_score;
AO_Tunnel->POST(gameOver, me);
status_ = QM_TRAN(&parked_s, QP::QMsm::s_emptyAction_);
status_ = QM_TRAN(&parked_s, &QP::QMsm::s_emptyAction_[0]);
}
break;
}

View File

@ -1,58 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<session version="3.0.0">
<item name="license">GPL</item>
<group name="locked"/>
<group name="settings">
<item name="tabs">1</item>
<item name="windows">0</item>
<item name="grid">3</item>
</group>
<group name="windows"/>
<group name="search">
<item name="options">4129280</item>
<item name="replace">0</item>
</group>
<group name="vars"/>
<group name="tools">
<group name="tool">
<item name="icon">0</item>
<item name="title"></item>
<item name="command"></item>
<item name="args"></item>
<item name="initial"></item>
<item name="options">0</item>
</group>
<group name="tool">
<item name="icon">0</item>
<item name="title"></item>
<item name="command"></item>
<item name="args"></item>
<item name="initial"></item>
<item name="options">0</item>
</group>
<group name="tool">
<item name="icon">0</item>
<item name="title"></item>
<item name="command"></item>
<item name="args"></item>
<item name="initial"></item>
<item name="options">0</item>
</group>
<group name="tool">
<item name="icon">0</item>
<item name="title"></item>
<item name="command"></item>
<item name="args"></item>
<item name="initial"></item>
<item name="options">0</item>
</group>
<group name="tool">
<item name="icon">0</item>
<item name="title"></item>
<item name="command"></item>
<item name="args"></item>
<item name="initial"></item>
<item name="options">0</item>
</group>
</group>
</session>

View File

@ -1,13 +1,13 @@
##############################################################################
# Product: Generic Makefile for QP/C++ application, Win32, MinGW compiler
# Last Updated for Version: 5.2.0
# Date of the Last Update: Dec 03, 2013
# Last Updated for Version: 5.2.1
# Date of the Last Update: Jan 06, 2014
#
# Q u a n t u m L e a P s
# ---------------------------
# innovating embedded systems
#
# Copyright (C) 2002-2013 Quantum Leaps, LLC. All rights reserved.
# Copyright (C) 2002-2014 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
@ -122,7 +122,7 @@ BIN_DIR := spy
INCLUDES += -I$(QTOOLS)/qspy/include
VPATH += $(QTOOLS)/qspy/source
C_SRCS += qspy.c
#C_SRCS += qspy.c
ASFLAGS =

View File

@ -0,0 +1,23 @@
QHsmTst example, QEP 5.2.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;
D:s211-D;s211-EXIT;s21-INIT;s211-ENTRY;
E:s-E;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s11-ENTRY;
I:s1-I;
F:s1-F;s11-EXIT;s1-EXIT;s2-ENTRY;s21-ENTRY;s211-ENTRY;
I:s2-I;
I:s-I;
F:s2-F;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s11-ENTRY;
A:s1-A;s11-EXIT;s1-EXIT;s1-ENTRY;s1-INIT;s11-ENTRY;
B:s1-B;s11-EXIT;s11-ENTRY;
D:s1-D;s11-EXIT;s1-EXIT;s-INIT;s1-ENTRY;s11-ENTRY;
D:s11-D;s11-EXIT;s1-INIT;s11-ENTRY;
E:s-E;s11-EXIT;s1-EXIT;s1-ENTRY;s11-ENTRY;
G:s11-G;s11-EXIT;s1-EXIT;s2-ENTRY;s21-ENTRY;s211-ENTRY;
H:s211-H;s211-EXIT;s21-EXIT;s2-EXIT;s-INIT;s1-ENTRY;s11-ENTRY;
H:s11-H;s11-EXIT;s1-EXIT;s-INIT;s1-ENTRY;s11-ENTRY;
C:s1-C;s11-EXIT;s1-EXIT;s2-ENTRY;s2-INIT;s21-ENTRY;s211-ENTRY;
G:s21-G;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s1-INIT;s11-ENTRY;
C:s1-C;s11-EXIT;s1-EXIT;s2-ENTRY;s2-INIT;s21-ENTRY;s211-ENTRY;
C:s2-C;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s1-INIT;s11-ENTRY;

View File

@ -0,0 +1,23 @@
QHsmTst example, QEP 5.2.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;
D:s211-D;s211-EXIT;s21-INIT;s211-ENTRY;
E:s-E;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s11-ENTRY;
I:s1-I;
F:s1-F;s11-EXIT;s1-EXIT;s2-ENTRY;s21-ENTRY;s211-ENTRY;
I:s2-I;
I:s-I;
F:s2-F;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s11-ENTRY;
A:s1-A;s11-EXIT;s1-EXIT;s1-ENTRY;s1-INIT;s11-ENTRY;
B:s1-B;s11-EXIT;s11-ENTRY;
D:s1-D;s11-EXIT;s1-EXIT;s-INIT;s1-ENTRY;s11-ENTRY;
D:s11-D;s11-EXIT;s1-INIT;s11-ENTRY;
E:s-E;s11-EXIT;s1-EXIT;s1-ENTRY;s11-ENTRY;
G:s11-G;s11-EXIT;s1-EXIT;s2-ENTRY;s21-ENTRY;s211-ENTRY;
H:s211-H;s211-EXIT;s21-EXIT;s2-EXIT;s-INIT;s1-ENTRY;s11-ENTRY;
H:s11-H;s11-EXIT;s1-EXIT;s-INIT;s1-ENTRY;s11-ENTRY;
C:s1-C;s11-EXIT;s1-EXIT;s2-ENTRY;s2-INIT;s21-ENTRY;s211-ENTRY;
G:s21-G;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s1-INIT;s11-ENTRY;
C:s1-C;s11-EXIT;s1-EXIT;s2-ENTRY;s2-INIT;s21-ENTRY;s211-ENTRY;
C:s2-C;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s1-INIT;s11-ENTRY;

View File

@ -0,0 +1,23 @@
QHsmTst example, QEP 5.2.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;
D:s211-D;s211-EXIT;s21-INIT;s211-ENTRY;
E:s-E;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s11-ENTRY;
I:s1-I;
F:s1-F;s11-EXIT;s1-EXIT;s2-ENTRY;s21-ENTRY;s211-ENTRY;
I:s2-I;
I:s-I;
F:s2-F;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s11-ENTRY;
A:s1-A;s11-EXIT;s1-EXIT;s1-ENTRY;s1-INIT;s11-ENTRY;
B:s1-B;s11-EXIT;s11-ENTRY;
D:s1-D;s11-EXIT;s1-EXIT;s-INIT;s1-ENTRY;s11-ENTRY;
D:s11-D;s11-EXIT;s1-INIT;s11-ENTRY;
E:s-E;s11-EXIT;s1-EXIT;s1-ENTRY;s11-ENTRY;
G:s11-G;s11-EXIT;s1-EXIT;s2-ENTRY;s21-ENTRY;s211-ENTRY;
H:s211-H;s211-EXIT;s21-EXIT;s2-EXIT;s-INIT;s1-ENTRY;s11-ENTRY;
H:s11-H;s11-EXIT;s1-EXIT;s-INIT;s1-ENTRY;s11-ENTRY;
C:s1-C;s11-EXIT;s1-EXIT;s2-ENTRY;s2-INIT;s21-ENTRY;s211-ENTRY;
G:s21-G;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s1-INIT;s11-ENTRY;
C:s1-C;s11-EXIT;s1-EXIT;s2-ENTRY;s2-INIT;s21-ENTRY;s211-ENTRY;
C:s2-C;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s1-INIT;s11-ENTRY;

View File

@ -1,13 +1,13 @@
//****************************************************************************
// Product: QHsmTst Example
// Last Updated for Version: 4.5.02
// Date of the Last Update: Aug 14, 2012
// Last Updated for Version: 5.2.0
// Date of the Last Update: Jan 06, 2014
//
// 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.
// Copyright (C) 2002-2014 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
@ -146,3 +146,33 @@ static void dispatch(QP::QSignal sig) {
}
} // namespace QHSMTST
//----------------------------------------------------------------------------
#ifdef Q_SPY
#include "qs_port.h"
namespace QP {
//............................................................................
void QF::onStartup(void) {
}
//............................................................................
void QF_onClockTick(void) {
}
//............................................................................
void QF::onCleanup(void) {
}
//............................................................................
void QS::onCleanup(void) {
}
//............................................................................
QSTimeCtr QS::onGetTime(void) {
return static_cast<QSTimeCtr>(clock());
}
} // namespace QP
#endif // Q_SPY

View File

@ -1,13 +1,13 @@
##############################################################################
# Product: Generic Makefile for QP/C++ application, Win32, MinGW compiler
# Last Updated for Version: 5.2.0
# Date of the Last Update: Dec 03, 2013
# Last Updated for Version: 5.2.1
# Date of the Last Update: Jan 06, 2014
#
# Q u a n t u m L e a P s
# ---------------------------
# innovating embedded systems
#
# Copyright (C) 2002-2013 Quantum Leaps, LLC. All rights reserved.
# Copyright (C) 2002-2014 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
@ -122,7 +122,7 @@ BIN_DIR := spy
INCLUDES += -I$(QTOOLS)/qspy/include
VPATH += $(QTOOLS)/qspy/source
C_SRCS += qspy.c
#C_SRCS += qspy.c
ASFLAGS =

View File

@ -0,0 +1,23 @@
QMsmTst example, QEP 5.2.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;
D:s211-D;s211-EXIT;s21-INIT;s211-ENTRY;
E:s-E;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s11-ENTRY;
I:s1-I;
F:s1-F;s11-EXIT;s1-EXIT;s2-ENTRY;s21-ENTRY;s211-ENTRY;
I:s2-I;
I:s-I;
F:s2-F;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s11-ENTRY;
A:s1-A;s11-EXIT;s1-EXIT;s1-ENTRY;s1-INIT;s11-ENTRY;
B:s1-B;s11-EXIT;s11-ENTRY;
D:s1-D;s11-EXIT;s1-EXIT;s-INIT;s1-ENTRY;s11-ENTRY;
D:s11-D;s11-EXIT;s1-INIT;s11-ENTRY;
E:s-E;s11-EXIT;s1-EXIT;s1-ENTRY;s11-ENTRY;
G:s11-G;s11-EXIT;s1-EXIT;s2-ENTRY;s21-ENTRY;s211-ENTRY;
H:s211-H;s211-EXIT;s21-EXIT;s2-EXIT;s-INIT;s1-ENTRY;s11-ENTRY;
H:s11-H;s11-EXIT;s1-EXIT;s-INIT;s1-ENTRY;s11-ENTRY;
C:s1-C;s11-EXIT;s1-EXIT;s2-ENTRY;s2-INIT;s21-ENTRY;s211-ENTRY;
G:s21-G;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s1-INIT;s11-ENTRY;
C:s1-C;s11-EXIT;s1-EXIT;s2-ENTRY;s2-INIT;s21-ENTRY;s211-ENTRY;
C:s2-C;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s1-INIT;s11-ENTRY;

View File

@ -0,0 +1,23 @@
QMsmTst example, QEP 5.2.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;
D:s211-D;s211-EXIT;s21-INIT;s211-ENTRY;
E:s-E;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s11-ENTRY;
I:s1-I;
F:s1-F;s11-EXIT;s1-EXIT;s2-ENTRY;s21-ENTRY;s211-ENTRY;
I:s2-I;
I:s-I;
F:s2-F;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s11-ENTRY;
A:s1-A;s11-EXIT;s1-EXIT;s1-ENTRY;s1-INIT;s11-ENTRY;
B:s1-B;s11-EXIT;s11-ENTRY;
D:s1-D;s11-EXIT;s1-EXIT;s-INIT;s1-ENTRY;s11-ENTRY;
D:s11-D;s11-EXIT;s1-INIT;s11-ENTRY;
E:s-E;s11-EXIT;s1-EXIT;s1-ENTRY;s11-ENTRY;
G:s11-G;s11-EXIT;s1-EXIT;s2-ENTRY;s21-ENTRY;s211-ENTRY;
H:s211-H;s211-EXIT;s21-EXIT;s2-EXIT;s-INIT;s1-ENTRY;s11-ENTRY;
H:s11-H;s11-EXIT;s1-EXIT;s-INIT;s1-ENTRY;s11-ENTRY;
C:s1-C;s11-EXIT;s1-EXIT;s2-ENTRY;s2-INIT;s21-ENTRY;s211-ENTRY;
G:s21-G;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s1-INIT;s11-ENTRY;
C:s1-C;s11-EXIT;s1-EXIT;s2-ENTRY;s2-INIT;s21-ENTRY;s211-ENTRY;
C:s2-C;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s1-INIT;s11-ENTRY;

View File

@ -0,0 +1,23 @@
QMsmTst example, QEP 5.2.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;
D:s211-D;s211-EXIT;s21-INIT;s211-ENTRY;
E:s-E;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s11-ENTRY;
I:s1-I;
F:s1-F;s11-EXIT;s1-EXIT;s2-ENTRY;s21-ENTRY;s211-ENTRY;
I:s2-I;
I:s-I;
F:s2-F;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s11-ENTRY;
A:s1-A;s11-EXIT;s1-EXIT;s1-ENTRY;s1-INIT;s11-ENTRY;
B:s1-B;s11-EXIT;s11-ENTRY;
D:s1-D;s11-EXIT;s1-EXIT;s-INIT;s1-ENTRY;s11-ENTRY;
D:s11-D;s11-EXIT;s1-INIT;s11-ENTRY;
E:s-E;s11-EXIT;s1-EXIT;s1-ENTRY;s11-ENTRY;
G:s11-G;s11-EXIT;s1-EXIT;s2-ENTRY;s21-ENTRY;s211-ENTRY;
H:s211-H;s211-EXIT;s21-EXIT;s2-EXIT;s-INIT;s1-ENTRY;s11-ENTRY;
H:s11-H;s11-EXIT;s1-EXIT;s-INIT;s1-ENTRY;s11-ENTRY;
C:s1-C;s11-EXIT;s1-EXIT;s2-ENTRY;s2-INIT;s21-ENTRY;s211-ENTRY;
G:s21-G;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s1-INIT;s11-ENTRY;
C:s1-C;s11-EXIT;s1-EXIT;s2-ENTRY;s2-INIT;s21-ENTRY;s211-ENTRY;
C:s2-C;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s1-INIT;s11-ENTRY;

View File

@ -1,13 +1,13 @@
//****************************************************************************
// Product: QMsmTst Example
// Last Updated for Version: 5.1.1
// Date of the Last Update: Nov 25, 2013
// Last Updated for Version: 5.2.0
// Date of the Last Update: Jan 06, 2014
//
// Q u a n t u m L e a P s
// ---------------------------
// innovating embedded systems
//
// Copyright (C) 2002-2013 Quantum Leaps, LLC. All rights reserved.
// Copyright (C) 2002-2014 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
@ -146,3 +146,32 @@ static void dispatch(QP::QSignal sig) {
}
} // namespace QMSMTST
//----------------------------------------------------------------------------
#ifdef Q_SPY
#include "qs_port.h"
namespace QP {
//............................................................................
void QF::onStartup(void) {
}
//............................................................................
void QF_onClockTick(void) {
}
//............................................................................
void QF::onCleanup(void) {
}
//............................................................................
void QS::onCleanup(void) {
}
//............................................................................
QSTimeCtr QS::onGetTime(void) {
return static_cast<QSTimeCtr>(clock());
}
} // namespace QP
#endif // Q_SPY

View File

@ -1,13 +1,13 @@
//****************************************************************************
// Product: DPP example
// Last Updated for Version: 5.2.0
// Date of the Last Update: Nov 04, 2013
// Date of the Last Update: Jan 06, 2014
//
// Q u a n t u m L e a P s
// ---------------------------
// innovating embedded systems
//
// Copyright (C) 2002-2013 Quantum Leaps, LLC. All rights reserved.
// Copyright (C) 2002-2014 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
@ -200,7 +200,6 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg,
//............................................................................
void BSP_init(void) {
Q_ALLEGE(QS_INIT(l_cmdLine));
QS_RESET();
QS_OBJ_DICTIONARY(&l_clock_tick); // must be called *after* QF::init()
QS_USR_DICTIONARY(PHILO_STAT);
}

View File

@ -65,7 +65,6 @@ void BSP_init(void) {
BSP_randomSeed(1234U);
Q_ALLEGE(QS_INIT((void *)0));
QS_RESET();
QS_OBJ_DICTIONARY(&l_clock_tick); // must be called *after* QF::init()
QS_USR_DICTIONARY(PHILO_STAT);
}

Binary file not shown.

View File

@ -264,7 +264,6 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg,
//............................................................................
void BSP_init(void) {
Q_ALLEGE(QS_INIT(l_cmdLine));
QS_RESET();
QS_OBJ_DICTIONARY(&l_clock_tick);
QS_USR_DICTIONARY(PLAYER_TRIGGER);
}
@ -471,7 +470,7 @@ void QF::onCleanup(void) {
//............................................................................
void QF_onClockTick(void) {
static QP::QEvt const tickEvt = QEVT_INITIALIZER(GAME::TIME_TICK_SIG);
QP::QF::TICK(&GAME::l_clock_tick); //perform the QF clock tick processing
QP::QF::TICK_X(0U, &GAME::l_clock_tick); // process time events at rate 0
QP::QF::PUBLISH(&tickEvt, &GAME::l_clock_tick); // publish the tick event
}
//............................................................................

View File

@ -1,13 +1,13 @@
//****************************************************************************
// Product: QEP/C++ platform-independent public interface
// Last Updated for Version: 5.2.0
// Date of the Last Update: Dec 27, 2013
// Date of the Last Update: Jan 06, 2014
//
// Q u a n t u m L e a P s
// ---------------------------
// innovating embedded systems
//
// Copyright (C) 2002-2013 Quantum Leaps, LLC. All rights reserved.
// Copyright (C) 2002-2014 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
@ -207,7 +207,7 @@ protected:
private:
/// \brief internal helper function to take a transition
void msm_tran(void);
void msm_tran(QActionHandler const *a);
friend class QFsm;
friend class QHsm;

View File

@ -1,7 +1,7 @@
//****************************************************************************
// Product: QP/C++
// Last Updated for Version: 5.2.0
// Date of the Last Update: Dec 28, 2013
// Last Updated for Version: 5.2.1
// Date of the Last Update: Jan 06, 2013
//
// Q u a n t u m L e a P s
// ---------------------------
@ -50,13 +50,13 @@
/// major version number, Y is a 1-digit minor version number, and Z is
/// a 1-digit release number.
///
#define QP_VERSION 520
#define QP_VERSION 521
/// \brief The current QP version string
#define QP_VERSION_STR "5.2.0"
#define QP_VERSION_STR "5.2.1"
/// \brief Tamperproof current QP release (5.2.0) and date (13-12-28)
#define QP_RELEASE 0xB1C83037U
/// \brief Tamperproof current QP release (5.2.1) and date (14-01-06)
#define QP_RELEASE 0xAC7D8356U
#ifndef Q_ROM
/// \brief Macro to specify compiler-specific directive for placing a

View File

@ -1,7 +1,7 @@
//****************************************************************************
// Product: QF/C++ port to POSIX/P-threads, GNU
// Last Updated for Version: 5.2.0
// Date of the Last Update: Dec 27, 2013
// Last Updated for Version: 5.2.1
// Date of the Last Update: Jan 06, 2014
//
// Q u a n t u m L e a P s
// ---------------------------
@ -119,8 +119,6 @@ void QActive::start(uint_t prio,
QF::add_(this); // make QF aware of this AO
this->init(ie); // execute initial transition (virtual call)
QS_FLUSH(); // flush the trace buffer to the host
pthread_attr_t attr;
pthread_attr_init(&attr);

Binary file not shown.

View File

@ -1,13 +1,13 @@
//****************************************************************************
// Product: QEP/C++
// Last Updated for Version: 5.2.0
// Date of the Last Update: Dec 26, 2013
// Last Updated for Version: 5.2.1
// Date of the Last Update: Jan 06, 2014
//
// Q u a n t u m L e a P s
// ---------------------------
// innovating embedded systems
//
// Copyright (C) 2002-2013 Quantum Leaps, LLC. All rights reserved.
// Copyright (C) 2002-2014 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
@ -79,6 +79,8 @@ void QMsm::dispatch(QEvt const * const e) {
if (r == Q_RET_TRAN) { // transition taken?
Q_ASSERT(t != static_cast<QMState const *>(0));// source can't be null
QActionHandler const *a = m_temp.act;
// exit states starting from the current state to the source state
for (; s != t; s = s->parent) {
if (s->exitAction != Q_ACTION_CAST(0)) { // exit action defined?
@ -91,7 +93,7 @@ void QMsm::dispatch(QEvt const * const e) {
}
}
msm_tran(); // take the MSM transition
msm_tran(a); // take the MSM transition
QS_BEGIN_(QS_QEP_TRAN, QS::priv_.smObjFilter, this)
QS_TIME_(); // time stamp
@ -133,8 +135,7 @@ void QMsm::dispatch(QEvt const * const e) {
}
//............................................................................
void QMsm::msm_tran(void) {
QActionHandler const *a = m_temp.act;
void QMsm::msm_tran(QActionHandler const *a) {
QState r = Q_RET_TRAN;
#ifdef Q_SPY
QMState const *t = m_state.obj; // target of the transition

View File

@ -1,13 +1,13 @@
//****************************************************************************
// Product: QS/C++
// Last Updated for Version: 5.1.0
// Date of the Last Update: Sep 23, 2013
// Last Updated for Version: 5.2.1
// Date of the Last Update: Jan 06, 2014
//
// Q u a n t u m L e a P s
// ---------------------------
// innovating embedded systems
//
// Copyright (C) 2002-2013 Quantum Leaps, LLC. All rights reserved.
// Copyright (C) 2002-2014 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
@ -48,8 +48,8 @@ void QS::mem(uint8_t const *blk, uint8_t size) {
QSCtr head_ = priv_.head; // put in a temporary (register)
QSCtr end_ = priv_.end; // put in a temporary (register)
priv_.used += static_cast<QSCtr>(size) // size+1 bytes to be added
+ static_cast<QSCtr>(1);
priv_.used += (static_cast<QSCtr>(size) // size+2 bytes to be added
+ static_cast<QSCtr>(2));
QS_INSERT_BYTE(b)
QS_INSERT_ESC_BYTE(size)