first commit after fixing history
This commit is contained in:
MMS 2022-10-28 21:48:01 -04:00
parent c3f6173f0c
commit f3c9a649b5
584 changed files with 21738 additions and 34038 deletions

@ -1 +1 @@
Subproject commit 8a2ebb9e76a63a2f46b8ad906657154ab21a15e8 Subproject commit cc0333938b9618b5a25394ebd81c8f235f5ff192

View File

@ -3,12 +3,15 @@
# What's New? # What's New?
View QP/C Revision History at: https://www.state-machine.com/qpc/history.html View QP/C Revision History at: https://www.state-machine.com/qpc/history.html
>**NOTE:** If you're interested in the latest QP/C version from Git, > **NOTE:** If you're interested in the latest QP/C version from GitHub,
it is highly recommened that you download the latest it is recommened that you clone this repo like that:
[QP/C Release](https://github.com/QuantumLeaps/qpc/releases)
as opposed to cloning the repo directy. This is because the `3rd_party` ```
directory needed to build the examples is no longer provided in the git clone https://github.com/QuantumLeaps/qpc --recurse-submodules --depth 1
`qpc` repository (and is provided in the QP/C release). ```
Alternatively, you can also download the latest
[QP/C Release](https://github.com/QuantumLeaps/qpc/releases).
# Getting Started with QP/C # Getting Started with QP/C

View File

@ -1,13 +1,11 @@
# Doxyfile 1.9.4 # Doxyfile 1.9.5
@INCLUDE = ../../ql-doxygen/ql-doxyfile
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# Project related configuration options # Project related configuration options
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8 DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = "QP/C" PROJECT_NAME = QP/C
PROJECT_NUMBER = 7.0.1 PROJECT_NUMBER = 7.1.2
PROJECT_BRIEF = "Real-Time Embedded Framework" PROJECT_BRIEF = "Real-Time Embedded Framework"
PROJECT_LOGO = ../../ql-doxygen/images/logo_ql.png PROJECT_LOGO = ../../ql-doxygen/images/logo_ql.png
OUTPUT_DIRECTORY = OUTPUT_DIRECTORY =
@ -42,6 +40,17 @@ PYTHON_DOCSTRING = YES
INHERIT_DOCS = YES INHERIT_DOCS = YES
SEPARATE_MEMBER_PAGES = NO SEPARATE_MEMBER_PAGES = NO
TAB_SIZE = 4 TAB_SIZE = 4
ALIASES = "nav{2}=<span class=\"prev_button\">@ref \1</span><span class=\"next_button\">@ref \2</span>" \
"nav_prev{1}=<span class=\"prev_button\">@ref \1</span>" \
"nav_next{1}=<span class=\"next_button\">@ref \1</span>" \
"next{1}=<span class=\"next_button\">@ref \1</span>" \
"description=@par Description" \
"usage=@par Usage" \
"hint=@par Hint" \
"label{1}=<div class=\"label\">\1</div>" \
"caption{1}=<div class=\"caption\" align=\"center\">\1</div>" \
"webref{2}=<a class=\"extern\" target=\"_blank\" href=\"https://www.state-machine.com/\1\">\2</a>" \
"tr{1}=@xrefitem tr \"Traceability\" \"\" traces to: @ref \1"
OPTIMIZE_OUTPUT_FOR_C = NO OPTIMIZE_OUTPUT_FOR_C = NO
OPTIMIZE_OUTPUT_JAVA = NO OPTIMIZE_OUTPUT_JAVA = NO
OPTIMIZE_FOR_FORTRAN = NO OPTIMIZE_FOR_FORTRAN = NO
@ -147,9 +156,10 @@ INPUT = main.dox \
dir.dox \ dir.dox \
config.h \ config.h \
../include \ ../include \
../src ../src \
../ports/lint-plus/qpc.lnt
INPUT_ENCODING = UTF-8 INPUT_ENCODING = UTF-8
INPUT_FILE_ENCODING =
FILE_PATTERNS = *.dox \ FILE_PATTERNS = *.dox \
*.h \ *.h \
*.hpp \ *.hpp \
@ -158,11 +168,9 @@ FILE_PATTERNS = *.dox \
*.s \ *.s \
*.asm \ *.asm \
*.lnt *.lnt
RECURSIVE = YES RECURSIVE = YES
EXCLUDE = ../include/qs_dummy.h \ EXCLUDE = ../include/qs_dummy.h \
../include/quit.h ../include/quit.h
EXCLUDE_SYMLINKS = NO EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS = EXCLUDE_PATTERNS =
EXCLUDE_SYMBOLS = QP_IMPL EXCLUDE_SYMBOLS = QP_IMPL
@ -172,7 +180,6 @@ EXAMPLE_PATH = snippets \
../ports \ ../ports \
../ports/lint-plus \ ../ports/lint-plus \
../examples ../examples
EXAMPLE_PATTERNS = * EXAMPLE_PATTERNS = *
EXAMPLE_RECURSIVE = NO EXAMPLE_RECURSIVE = NO
IMAGE_PATH = images \ IMAGE_PATH = images \
@ -183,12 +190,13 @@ FILTER_PATTERNS =
FILTER_SOURCE_FILES = NO FILTER_SOURCE_FILES = NO
FILTER_SOURCE_PATTERNS = FILTER_SOURCE_PATTERNS =
USE_MDFILE_AS_MAINPAGE = USE_MDFILE_AS_MAINPAGE =
FORTRAN_COMMENT_AFTER = 72
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# Configuration options related to source browsing # Configuration options related to source browsing
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
SOURCE_BROWSER = YES SOURCE_BROWSER = YES
INLINE_SOURCES = NO INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = YES STRIP_CODE_COMMENTS = NO
REFERENCED_BY_RELATION = NO REFERENCED_BY_RELATION = NO
REFERENCES_RELATION = NO REFERENCES_RELATION = NO
REFERENCES_LINK_SOURCE = YES REFERENCES_LINK_SOURCE = YES
@ -217,12 +225,11 @@ HTML_EXTRA_STYLESHEET = ../../ql-doxygen/doxygen-awesome.css \
../../ql-doxygen/doxygen-awesome-sidebar-only.css \ ../../ql-doxygen/doxygen-awesome-sidebar-only.css \
../../ql-doxygen/doxygen-awesome-sidebar-only-darkmode-toggle.css \ ../../ql-doxygen/doxygen-awesome-sidebar-only-darkmode-toggle.css \
../../ql-doxygen/ql-awesome.css ../../ql-doxygen/ql-awesome.css
HTML_EXTRA_FILES = ../../ql-doxygen/doxygen-awesome-darkmode-toggle.js \ HTML_EXTRA_FILES = ../../ql-doxygen/doxygen-awesome-darkmode-toggle.js \
../../ql-doxygen/doxygen-awesome-fragment-copy-button.js \ ../../ql-doxygen/doxygen-awesome-fragment-copy-button.js \
../../ql-doxygen/doxygen-awesome-paragraph-link.js \ ../../ql-doxygen/doxygen-awesome-paragraph-link.js \
../../ql-doxygen/ql-preview.js ../../ql-doxygen/ql-preview.js
HTML_COLORSTYLE = AUTO_LIGHT
HTML_COLORSTYLE_HUE = 209 HTML_COLORSTYLE_HUE = 209
HTML_COLORSTYLE_SAT = 255 HTML_COLORSTYLE_SAT = 255
HTML_COLORSTYLE_GAMMA = 113 HTML_COLORSTYLE_GAMMA = 113
@ -262,7 +269,6 @@ EXT_LINKS_IN_WINDOW = NO
OBFUSCATE_EMAILS = NO OBFUSCATE_EMAILS = NO
HTML_FORMULA_FORMAT = png HTML_FORMULA_FORMAT = png
FORMULA_FONTSIZE = 10 FORMULA_FONTSIZE = 10
FORMULA_TRANSPARENT = YES
FORMULA_MACROFILE = FORMULA_MACROFILE =
USE_MATHJAX = NO USE_MATHJAX = NO
MATHJAX_VERSION = MathJax_2 MATHJAX_VERSION = MathJax_2
@ -278,6 +284,68 @@ SEARCHDATA_FILE = searchdata.xml
EXTERNAL_SEARCH_ID = QPC EXTERNAL_SEARCH_ID = QPC
EXTRA_SEARCH_MAPPINGS = EXTRA_SEARCH_MAPPINGS =
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# Configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_LATEX = NO
LATEX_OUTPUT = latex
LATEX_CMD_NAME = latex
MAKEINDEX_CMD_NAME = makeindex
LATEX_MAKEINDEX_CMD = makeindex
COMPACT_LATEX = NO
PAPER_TYPE = letter
EXTRA_PACKAGES =
LATEX_HEADER =
LATEX_FOOTER =
LATEX_EXTRA_STYLESHEET =
LATEX_EXTRA_FILES =
PDF_HYPERLINKS = YES
USE_PDFLATEX = YES
LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
LATEX_BIB_STYLE = plain
LATEX_TIMESTAMP = NO
LATEX_EMOJI_DIRECTORY =
#---------------------------------------------------------------------------
# Configuration options related to the RTF output
#---------------------------------------------------------------------------
GENERATE_RTF = NO
RTF_OUTPUT = rtf
COMPACT_RTF = NO
RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# Configuration options related to the man page output
#---------------------------------------------------------------------------
GENERATE_MAN = NO
MAN_OUTPUT = man
MAN_EXTENSION = .3
MAN_SUBDIR =
MAN_LINKS = NO
#---------------------------------------------------------------------------
# Configuration options related to the XML output
#---------------------------------------------------------------------------
GENERATE_XML = NO
XML_OUTPUT = xml
XML_PROGRAMLISTING = YES
XML_NS_MEMB_FILE_SCOPE = NO
#---------------------------------------------------------------------------
# Configuration options related to the DOCBOOK output
#---------------------------------------------------------------------------
GENERATE_DOCBOOK = NO
DOCBOOK_OUTPUT = docbook
#---------------------------------------------------------------------------
# Configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# Configuration options related to the Perl module output
#---------------------------------------------------------------------------
GENERATE_PERLMOD = NO
PERLMOD_LATEX = NO
PERLMOD_PRETTY = YES
PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor # Configuration options related to the preprocessor
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
ENABLE_PREPROCESSING = YES ENABLE_PREPROCESSING = YES
@ -289,8 +357,6 @@ INCLUDE_FILE_PATTERNS =
PREDEFINED = Q_SPY \ PREDEFINED = Q_SPY \
QP_IMPL \ QP_IMPL \
Q_UTEST \ Q_UTEST \
QK_ON_CONTEXT_SW \
QXK_ON_CONTEXT_SW \
QF_MAX_ACTIVE=32 \ QF_MAX_ACTIVE=32 \
QF_MAX_TICK_RATE=2 \ QF_MAX_TICK_RATE=2 \
QF_MAX_EPOOL=3 \ QF_MAX_EPOOL=3 \
@ -300,6 +366,59 @@ PREDEFINED = Q_SPY \
QF_MPOOL_CTR_SIZE=2 \ QF_MPOOL_CTR_SIZE=2 \
QF_TIMEEVT_CTR_SIZE=4 \ QF_TIMEEVT_CTR_SIZE=4 \
QF_ACTIVE_STOP=0 \ QF_ACTIVE_STOP=0 \
QS_TIME_SIZE=4 QS_TIME_SIZE=4 \
QF_EQUEUE_TYPE=QEQueue \
QF_OS_OBJECT_TYPE=void* \
QF_THREAD_TYPE=void* \
QK_ON_CONTEXT_SW \
QXK_ON_CONTEXT_SW
EXPAND_AS_DEFINED = EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration options related to external references
#---------------------------------------------------------------------------
TAGFILES =
GENERATE_TAGFILE =
ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
EXTERNAL_PAGES = YES
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
DIA_PATH =
HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = NO
DOT_NUM_THREADS = 0
DOT_COMMON_ATTR = "fontname=Helvetica,fontsize=10"
DOT_EDGE_ATTR = "labelfontname=Helvetica,labelfontsize=10"
DOT_NODE_ATTR = "shape=box,height=0.2,width=0.4"
DOT_FONTPATH =
CLASS_GRAPH = YES
COLLABORATION_GRAPH = NO
GROUP_GRAPHS = YES
UML_LOOK = YES
UML_LIMIT_NUM_FIELDS = 10
DOT_UML_DETAILS = NO
DOT_WRAP_THRESHOLD = 17
TEMPLATE_RELATIONS = NO
INCLUDE_GRAPH = YES
INCLUDED_BY_GRAPH = YES
CALL_GRAPH = NO
CALLER_GRAPH = NO
GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES
DIR_GRAPH_MAX_DEPTH = 1
DOT_IMAGE_FORMAT = png
INTERACTIVE_SVG = NO
DOT_PATH = C:/tools/graphviz/bin
DOTFILE_DIRS =
MSCFILE_DIRS =
DIAFILE_DIRS =
PLANTUML_JAR_PATH =
PLANTUML_CFG_FILE =
PLANTUML_INCLUDE_PATH =
DOT_GRAPH_MAX_NODES = 50
MAX_DOT_GRAPH_DEPTH = 0
DOT_MULTI_TARGETS = NO
GENERATE_LEGEND = YES
DOT_CLEANUP = YES

View File

@ -142,7 +142,7 @@
* *
* @description * @description
* This macro can be defined in the QF ports to configure the internal tick * This macro can be defined in the QF ports to configure the internal tick
* counters of Time Events. If the macro is not defined, the default of 2 * counters of Time Events. If the macro is not defined, the default of 4
* bytes will be chosen in qf.h. The valid #QF_TIMEEVT_CTR_SIZE values of 1, * bytes will be chosen in qf.h. The valid #QF_TIMEEVT_CTR_SIZE values of 1,
* 2, or 4, correspond to tick counters of uint8_t, uint16_t, and uint32_t, * 2, or 4, correspond to tick counters of uint8_t, uint16_t, and uint32_t,
* respectively. The tick counter representation determines the dynamic range * respectively. The tick counter representation determines the dynamic range
@ -155,7 +155,7 @@
* this macro only once in the qf_port.h header file and henceforth include * this macro only once in the qf_port.h header file and henceforth include
* this header file in all builds. * this header file in all builds.
*/ */
#define QF_TIMEEVT_CTR_SIZE 2U #define QF_TIMEEVT_CTR_SIZE 4U
/*! Define the interrupt disabling policy. /*! Define the interrupt disabling policy.
* *

View File

@ -46,3 +46,13 @@ Files in this directory need to be included in the QP application build only if
/*! @dir src/qs /*! @dir src/qs
@brief Platform-independent implementation of the @ref qs component (software tracing). @brief Platform-independent implementation of the @ref qs component (software tracing).
*/ */
/*##########################################################################*/
/*! @dir test
@brief System-level tests of the QP/C framework itself.
@note
The `qpc/test/` directory is planned to contain a growing number of system-level tests, which are based on QUTest, but *without* the QP-stub. The tests take advantage of the new QUTest configuration, where the QP-stub is NOT included (because the actual QP framework is linked). This configuration is activated by defining macro `Q_UTEST=0`.
@attention
Many tests provided in the `qpc/test/` directory run only on embedded targets and cannot run on the host machine.
*/

View File

@ -145,7 +145,7 @@ The DPP example is provided for most supported boards as well as in the command-
The Dining Philosophers Problem (DPP) example is described in the @webref{doc/AN_DPP.pdf, Application Note: Dining Philosophers Problem (DPP) Example}. The Dining Philosophers Problem (DPP) example is described in the @webref{doc/AN_DPP.pdf, Application Note: Dining Philosophers Problem (DPP) Example}.
[![Application Note: Dining Philosophers Problem (DPP) Example](AN_DPP.jpg)](https://www.state-machine.com/doc/AN_Fly-n-Shoot.pdf) [![Application Note: Dining Philosophers Problem (DPP) Example](AN_DPP.jpg)](https://www.state-machine.com/doc/AN_DPP.pdf)
@note @note
There is also a DPP variant that implements the "Philosophers" as passive "Orthogonal Components" of the "Table" active object. That DPP version is located in <span class="img folder">qpc/examples/examples/workstation/dpp-comp/</span> There is also a DPP variant that implements the "Philosophers" as passive "Orthogonal Components" of the "Table" active object. That DPP version is located in <span class="img folder">qpc/examples/examples/workstation/dpp-comp/</span>

View File

@ -1,5 +1,84 @@
/*! @page history Revision History /*! @page history Revision History
@section qpc_7_1_2 Version 7.1.2, 2022-10-07
This release improves preemption-threshold scheduling (PTS) in @ref srs_qk "QK" kernel, especially the generation of the software tracing information about the scheduler activity. Also, PTS has been removed from the @ref srs_qxk "QXK" kernel because of the inherent complexity of that kernel.
Additionally, the default for #QF_TIMEEVT_CTR_SIZE has been increased from 2 to 4 bytes. This increases the default dynamic range for QTimeEvt counters to 32-bits.
__Source__
- Modified QK_sched_() and QK_activate_()
- Modified QXK_sched_() and QXK_activate_()
- Added QXK_contextSw() to handle context switching (generation of software tracing information and invoking of the QXK_onContextSw() callback, if configured
- increased default for #QF_TIMEEVT_CTR_SIZE 4
- changed inclusion guards in the QP/C header files (e.g. `QF_H` -> `QP_INC_QF_H_`) for compliance with the updated Quantum Leaps coding standard and to make the names more unique.
__Ports__
- Modified QXK ports (assembly) to call QXK_contextSw()
- Added port to RISC-V with the cooperative @ref srs_qvk "QV" kernel
__Testing__
- Added new directory `qpc/test/` for **system**-level testing of QP/C itself.
- Added new tests for QK: `qpc/test/qk`
- Added new tests for QXK: `qpc/test/qutest/qxk`
@note
The `qpc/test/` directory is planned to contain a growing number of system-level tests, which are based on QUTest, but *without* the QP-stub. The tests take advantage of the new QUTest configuration, where the QP-stub is NOT included (because the actual QP framework is linked). This configuration is activated by defining macro `Q_UTEST=0`.
@attention
Most tests provided in the `qpc/test/` directory run only on embedded targets and cannot run on the host machine.
@section qpc_7_1_0 Version 7.1.0, 2022-08-30
This QP/C release introduces [<b>preemption-threshold scheduling</b> (PTS)](https://www.state-machine.com/doc/Ghattas07.pdf) for the preemptive QK and QXK kernels. Specifically, it is now possible to limit preemption of a given QActive/QXThread by giving it both the QF-priority and preemption-threshold.
The following diagram shows the relationship between the "QF-priority" and "preemption-threshold" (see also ::QPrioSpec):
![QF-priority and preemption-threshold relations](qp-prio.png)
@note
For backwards-compatibility, ::QPrioSpec data type might contain only the "QF-priority" component (and the "preemption-threshold" component left at zero). In that case, the "preemption-threshold" will be assumed to be the same as the "QF-priority". This corresponds exactly to the previous semantics of AO priority.
__Source__
- modified the QP/C code for preemption-threshold
- improved QS tracing of Scheduler activities in QK and QXK
- improved implementation of QXSemaphore and QXMutex in QXK
__Ports__
- Modified QK and QXK ports to ARM Cortex-M for preemption-threshold and for handling the context-switch callback
- Updated Zephyr port and examples for Zephyr 3.1.99
__Examples__
- Added Q_PRIO() macro for setting QF-priority and preemption-threshold to various examples (in calls to QACTIVE_START())
- increased size of the main stack in most examples from 1024 to 2048 bytes. This is to prevent stack overflow that was observed with the lower limit.
__Testing__
- modified QUTest to also allow testing of the QP framework itself.
@section qpc_7_0_2 Version 7.0.2, 2022-08-12
__Bug Fixes:__
- [bug#312 "Bug in QK and QXK 7.0.1"](https://sourceforge.net/p/qpc/bugs/312)
__Ports__
Modified QK and QXK ports to ARM Cortex-M
- `qpc/ports/arm-cm/qk`
- `qpc/ports/arm-cm/qxk`
Modified Zephyr port
- moved the port from the usual location in `qpc/ports/zephyr` up a level to `qpc/zephyr`. This was done to make QPC into an external [Zephyr module](https://docs.zephyrproject.org/latest/develop/modules.html), which has to comply with the Zephyr specification.
__Examples (ARM Cortex-M):__
- `qpc/examples/arm-cm/dpp_efm32-slstk3401a/qk` provided examples of configuring either NMI or IRQ for Cortex-M4 (ARMv7m)
- `qpc/examples/arm-cm/dpp_efm32-slstk3401a/qxk` provided examples of configuring either NMI or IRQ for Cortex-M4 (ARMv7m)
- `qpc/examples/arm-cm/dpp_nucleo-l053r8/qk` provided examples of configuring either NMI or IRQ for Cortex-M0+ (ARMv6m)
- `qpc/examples/arm-cm/dpp_nucleo-l053r8/qk` provided examples of configuring either NMI or IRQ for Cortex-M0+ (ARMv6m)
__Examples (Zephyr):__
- `qpc/examples/zephyr/blinky` - modified to use the new Zephyr port
- `qpc/examples/zephyr/dpp` - modified to use the new Zephyr port and to demonstrate QSPY software tracing.
@section qpc_7_0_1 Version 7.0.1, 2022-07-31 @section qpc_7_0_1 Version 7.0.1, 2022-07-31
This release is the first one that contains the complete [QM model](https://www.state-machine.com/products/qm) of the QP/C framework (in the file `qpc/qpc.qm`). This model is then used to **generate all QP/C source code**: This release is the first one that contains the complete [QM model](https://www.state-machine.com/products/qm) of the QP/C framework (in the file `qpc/qpc.qm`). This model is then used to **generate all QP/C source code**:
- `qpc/` - `qpc/`

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

BIN
doxygen/images/oop-in-C.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

BIN
doxygen/images/qp-prio.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

View File

@ -1,177 +0,0 @@
/**
* @file
* @brief Various macros for configuring and porting QP/C
*/
/*! The preprocessor switch to disable checking assertions */
/**
* When defined, Q_NASSERT disables the following macros #Q_ASSERT,
* #Q_REQUIRE, #Q_ENSURE, #Q_INVARIANT, #Q_ERROR as well as
* #Q_ASSERT_ID, #Q_REQUIRE_ID, #Q_ENSURE_ID, #Q_INVARIANT_ID, and
* #Q_ERROR_ID do _not_ evaluate the test condition passed as the
* argument to these macros.
*
* @note The notable exceptions are the macros #Q_ALLEGE and
* #Q_ALLEGE_ID, that still evaluate the test condition, but do not
* report assertion failures when the switch #Q_NASSERT is defined.
*/
#define Q_NASSERT
/*! The preprocessor switch to activate the QS software tracing
* instrumentation in the code */
/**
* When defined, Q_SPY activates the QS software tracing instrumentation.
* When Q_SPY is not defined, the QS instrumentation in the code does
* not generate any code.
*/
#define Q_SPY
/*! The preprocessor switch to activate the QUTest unit testing
* instrumentation in the code */
/**
* @note
* This macro requires that #Q_SPY be defined as well.
*/
#define Q_UTEST
/*! The preprocessor switch to enable constructor in the ::QEvt class
* instrumentation in the code */
/**
* @rtr{RQP005}
*/
#define Q_EVT_CTOR
/*! This macro defines the type of the thread handle used for AOs */
#define QF_THREAD_TYPE void*
/*! This macro defines the type of the event-queue used for AOs */
#define QF_EQUEUE_TYPE QEQueue
/*! This macro defines the type of the OS-Object used for blocking
* the native ::QEQueue when the queue is empty */
/**
* @description
* This macro is used when ::QEQueue is used as the event-queue for AOs
* but also the AO queue must *block* when the queue is empty.
* In that case, #QF_OS_OBJECT_TYPE specifies the blocking mechanism.
* For examle, in the POSIX port, the blocking mechanism is a condition
* variable.
*/
#define QF_OS_OBJECT_TYPE pthread_cond_t
/*! Platform-dependent macro defining how QF should block the
* calling task when the QF native queue is empty */
/**
* @note This is just an example of QACTIVE_EQUEUE_WAIT_() for the QK-port
* of QF. QK never activates a task that has no events to process, so in
* this case the macro asserts that the queue is not empty. In other QF
* ports you need to define the macro appropriately for the underlying
* kernel/OS you're using.
*/
#define QACTIVE_EQUEUE_WAIT_(me_) \
(Q_ASSERT((me_)->eQueue.frontEvt != (QEvt *)0))
#if (QF_MAX_ACTIVE <= 8U)
#define QACTIVE_EQUEUE_SIGNAL_(me_) do { \
QPSet8_insert(&QK_readySet_, (me_)->prio); \
if (QK_intNest_ == 0U) { \
uint_fast8_t p = QK_schedPrio_(); \
if (p != 0U) { \
QK_sched_(p); \
} \
} \
} while (0)
#else
/*! Platform-dependent macro defining how QF should signal the
* active object task that an event has just arrived. */
/**
* The macro is necessary only when the native QF event queue is used.
* The signaling of task involves unblocking the task if it is blocked.
*
* @note QACTIVE_EQUEUE_SIGNAL_() is called from a critical section.
* It might leave the critical section internally, but must restore
* the critical section before exiting to the caller.
*
* @note This is just an example of QACTIVE_EQUEUE_SIGNAL_() for the
* QK-port of QF. In other QF ports you need to define the macro
* appropriately for the underlying kernel/OS you're using.
*/
#define QACTIVE_EQUEUE_SIGNAL_(me_) do { \
QPSet64_insert(&QK_readySet_, (me_)->prio); \
if (QK_intNest_ == 0U) { \
uint_fast8_t p = QK_schedPrio_(); \
if (p != 0U) { \
QK_sched_(p); \
} \
} \
} while (0)
#endif
/*! This macro defines the type of the event pool used in the QK kernel. */
/**
* @note This is a specific implementation for the QK-port of QF.
* In other QF ports you need to define the macro appropriately for
* the underlying kernel/OS you're using.
*/
#define QF_EPOOL_TYPE_ QMPool
/*! This macro enables calling the QK context-switch callback
* QK_onContextSw() */
#define QK_ON_CONTEXT_SW
/*! This macro enables calling the QXK context-switch callback
* QXK_onContextSw() */
#define QXK_ON_CONTEXT_SW
/*! Platform-dependent macro defining the event pool initialization */
/**
* @note
* This is an example implementation based on the native ::QMPool class.
* In other QF ports, the port might be using a memory pool from the
* underlying kernel/OS.
*/
#define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \
(QMPool_init(&(p_), (poolSto_), (poolSize_), (QMPoolSize)(evtSize_)))
/*! Platform-dependent macro defining how QF should obtain the
* event pool block-size */
/**
* @note This is a specific implementation for the QK-port of QF.
* In other QF ports you need to define the macro appropriately for
* the underlying kernel/OS you're using.
*/
#define QF_EPOOL_EVENT_SIZE_(p_) ((QEvtSize)(p_).blockSize)
/*! Platform-dependent macro defining how QF should obtain an event
* @a e_ from the event pool @a p_ with the free margin @a m_. */
/**
* @note
* This is an example implementation based on the native ::QMPool class.
* In other QF ports, the port might be using a memory pool from the
* underlying kernel/OS.
*/
#define QF_EPOOL_GET_(p_, e_, m_, qs_id_) \
((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qs_id_)))
/*! Platform-dependent macro defining how QF should return an event
* @a e_ to the event pool @a p_ */
/**
* @note
* This is an example implementation based on the native ::QMPool class.
* In other QF ports, the port might be using a memory pool from the
* underlying kernel/OS.
*/
#define QF_EPOOL_PUT_(p_, e_, qs_id_) \
(QMPool_put(&(p_), (e_), (qs_id_)))
/*! Macro defined only for the internal QP implementation. It should
* be not defined for the application-level code
*/
#define QP_IMPL
/*! Macro that should be defined (typically on the compiler's command line)
in the Win32-GUI applications that use the @ref win32 or @ref win32-qv ports.
*/
#define WIN32_GUI

View File

@ -2,26 +2,21 @@
@image html qp_banner.jpg @image html qp_banner.jpg
@remark @remark
<a target="_blank" href="https://github.com/QuantumLeaps/qpc" title="QP/C on GitHub"><img style="float:right; clear:right;" src="img/logo_github.png"></a> <a target="_blank" href="https://github.com/QuantumLeaps/qpc" title="QP/C on GitHub"><img class="right" src="img/logo_github.png"></a>
To check what's new in QP&trade;/C, please see @ref history "QP/C Revision History". You can also get the latest **QP&trade;/C code**, with the recent enhancements and bug fixes, from the <a class="extern" target="_blank" href="https://github.com/QuantumLeaps/qpc"><strong>GitHub QP&trade;/C repository</strong></a>. To check what's new in QP&trade;/C, please see @ref history "QP/C Revision History". You can also get the latest **QP&trade;/C code**, with the recent enhancements and bug fixes, from the <a class="extern" target="_blank" href="https://github.com/QuantumLeaps/qpc"><strong>GitHub QP&trade;/C repository</strong></a>.
<div style="clear:both"></div> <div style="clear:both"></div>
@section over_about What is it? @section over_about What is it?
<b>QP&trade;/C Real-Time Embedded Framework (RTEF)</b> is a lightweight implementation of the @webref{active-object, Active Object model of computation} specifically tailored for real-time embedded (RTE) systems. QP is both a software infrastructure for building applications consisting of Active Objects (actors) and a runtime environment for executing the Active Objects in a deterministic fashion. Additionally, QP Framework supports @webref{fsm#HSM, Hierarchical State Machines} with which to specify the behavior of Active Objects @ref srs_ref "[ROOM:94], [UML 2.5],[Sutter:10]". <b>QP&trade;/C Real-Time Embedded Framework (RTEF)</b> is a lightweight implementation of the @webref{active-object, Active Object model of computation} specifically tailored for real-time embedded (RTE) systems. QP is both a *software infrastructure* for building applications consisting of active objects (actors) and a *runtime environment* for executing the active objects in a deterministic fashion. Additionally, QP Framework supports @webref{fsm#HSM, Hierarchical State Machines} with which to specify the behavior of Active Objects @ref srs_ref "[ROOM:94], [UML 2.5],[Sutter:10]". You can think of the QP/C RTEF as a modern, truly *event-driven* real-time operating system (RTOS).
@note
<a href="https://www.state-machine.com/products/qp#CERT" title="QP Cert-Pack"><img src="cert-pack.png" style="float:right; margin:0 20px 0 20px;"></img></a>
The @webref{products/qp#CERT,QP Certification Pack} provides:
- @ref srs "Software Requirements Specification" with a good @ref srs_over "overview" of the QP/C Framework
- @ref sas "Software Architecture Specification" with concise description of QP/C @ref sas_core "architecture"
- @ref sds "Software Design Specification" with detailed description of the QP/C @ref sds "design".
@section over_goals What does it do? @section over_goals What does it do?
The main objectives of the QP/C RTEF are: The main objectives of the QP/C RTEF are:
- to provide a modern, event-driven model of concurrency based on the best practices of concurrent programming @ref srs_ref "[ROOM:94], [Cummings:10], [Sutter:10]", collectively known as the @webref{active-object, Active Object (Actor) model of computation}, which is inherently *safer* than the traditional "shared-state concurrency, mutual-exclusion, and blocking" approach based on a conventional Real-Time Operating System (RTOS); - to provide a modern, event-driven model of concurrency based on the best practices of concurrent programming collectively known as the @webref{active-object, Active Object (Actor) model of computation}, which is inherently *safer* than the traditional "shared-state concurrency, mutual-exclusion, and blocking" approach based on a conventional Real-Time Operating System (RTOS);
- to provide an efficient, @ref tr "bidirectionally traceable" implementation of @webref{fsm#HSM, Hierarchical State Machines} for specifying the internal behavior of Active Objects;
- to provide a *higher-level of abstraction* closer to the problem domain than the "naked" RTOS threads; - to provide a *higher-level of abstraction* closer to the problem domain than the "naked" RTOS threads;
@ -31,16 +26,20 @@ The main objectives of the QP/C RTEF are:
@section over_special What's special about it? @section over_special What's special about it?
The QP&trade;/C Real-Time Embedded Framework (RTEF) is a unique offering on the embedded software market. It provides a modern, reusable **architecture** of embedded applications, which combines object-orientation with the particular model of concurrency, known as @webref{active-object, <strong>active objects</strong>} (actors). This architecture is generally **safer**, more responsive and easier to understand than "free threading" with a traditional Real-Time Operating System (RTOS). It also provides sufficiently high level of abstraction and the right abstractions to effectively apply modeling and code generation to deeply embedded systems. The QP&trade;/C Real-Time Embedded Framework (RTEF) provides a modern, reusable **architecture** of embedded applications, which combines the model of concurrency, known as @webref{active-object, <strong>active objects</strong>} (actors) with @webref{fsm#HSM, Hierarchical State Machines}. This architecture is generally **safer**, more responsive and easier to understand than "free threading" with a traditional Real-Time Operating System (RTOS). It also provides sufficiently high level of abstraction and the *right* abstractions to effectively apply modeling and code generation to deeply embedded systems.
@note
The most unique aspect of the QP&trade;/C RTEF is its @ref over_eff "tiny size and efficiency" suitable for embedded microcontrollers, such as MCUs based on ARM Cortex-M.
@subsection over_oop Object Orientation @subsection over_oop Object Orientation
Even though it is written in @ref misra "MISRA-compliant" ISO-C99, QP&trade;/C is fundamentally an **object-oriented** framework, which means that the framework itself and your applications derived from the framework are fundamentally composed of @ref sas_core "classes" and only classes can have @ref srs_sm "state machines" associated with them. Even though it is written in @ref misra "MISRA-compliant" ISO-C99, QP&trade;/C is fundamentally an **object-oriented** framework, which means that the framework itself and your applications derived from the framework are fundamentally composed of @ref sas_core "classes" and only classes can have @ref srs_sm "state machines" associated with them.
@anchor oop @anchor oop
@note @remark
If you program in C and object-oriented programming is new to you, please refer to the article and set of videos @webref{oop, "Object-Oriented Programming"}, which among others describes how you can implement the concepts of *classes*, *inheritance*, and *polymorphism* to portable ISO-C. If you program in C and object-oriented programming is new to you, please refer to the article and set of videos @webref{oop, "Object-Oriented Programming"}, which among others describes how you can implement the concepts of *classes*, *inheritance*, and *polymorphism* to portable ISO-C.<br>
@webref{oop, ![Object-Oriented Programming in C](an-oop_in_c.jpg)} <br>
<a target="_blank" href="https://www.state-machine.com/oop" title="OOP in C"><img src="oop-in-C.jpg"></img></a>
@subsection over_hsms Hierarchical State Machines @subsection over_hsms Hierarchical State Machines
@ -51,8 +50,8 @@ The behavior of active objects is specified in QP&trade;/C by means of @webref{f
The QP&trade;/C framework can run on @ref exa_native "bare-metal single-chip microcontrollers", completely replacing a traditional RTOS. The framework contains a selection of built-in real-time kernels, such as the cooperative @ref srs_qv "QV kernel", the preemptive non-blocking @ref srs_qk "QK kernel", and the preemptive, dual-mode, blocking @ref srs_qxk "QXK kernel". The QXK kernel <span class="highlight">provides all the features you might expect from a traditional <strong>RTOS kernel</strong></span> and has been specifically designed for mixing event-driven active objects with traditional blocking code, such as commercial middleware (TCP/IP stacks, UDP stacks, embedded file systems, etc.) or legacy software. @ref ports_native "Native QP ports" and ready-to-use @ref exa_native "examples" are provided for major @ref exa_ref_mcu "CPU families". The QP&trade;/C framework can run on @ref exa_native "bare-metal single-chip microcontrollers", completely replacing a traditional RTOS. The framework contains a selection of built-in real-time kernels, such as the cooperative @ref srs_qv "QV kernel", the preemptive non-blocking @ref srs_qk "QK kernel", and the preemptive, dual-mode, blocking @ref srs_qxk "QXK kernel". The QXK kernel <span class="highlight">provides all the features you might expect from a traditional <strong>RTOS kernel</strong></span> and has been specifically designed for mixing event-driven active objects with traditional blocking code, such as commercial middleware (TCP/IP stacks, UDP stacks, embedded file systems, etc.) or legacy software. @ref ports_native "Native QP ports" and ready-to-use @ref exa_native "examples" are provided for major @ref exa_ref_mcu "CPU families".
@subsection over_eff Efficiency @subsection over_eff Size and Efficiency
Even though QP&trade;/C offers much higher level of abstraction than a traditional RTOS, it typically outperforms equivalent traditional RTOS offerings both in RAM/ROM footprint and in CPU efficiency. The specific measurements and results are reported in the following @webref{doc/AN_QP_Performance.pdf, Application Note: "QP Performance Tests and Results"}: Even though QP&trade;/C offers much higher level of abstraction than a traditional RTOS, it typically outperforms equivalent traditional RTOS applications both in RAM/ROM footprint and in CPU efficiency. The specific measurements and results are reported in the following @webref{doc/AN_QP_Performance.pdf, Application Note: "QP Performance Tests and Results"}:
[![Application Note: "QP Performance Tests and Results"](an-qp_performance.png)](https://www.state-machine.com/doc/AN_QP_Performance.pdf) [![Application Note: "QP Performance Tests and Results"](an-qp_performance.png)](https://www.state-machine.com/doc/AN_QP_Performance.pdf)
@ -62,7 +61,7 @@ The QP Framework is simple to get started, simple to use and simple to build. Th
@subsection over_inter Interoperability @subsection over_inter Interoperability
QP/C can also work with many traditional @ref exa_rtos "RTOSes" and @ref exa_os "general-purpose OSes" (such as Linux and Windows). QP/C can also work with many traditional @ref exa_rtos "Real-Time Operating Systems (RTOSes)" and @ref exa_os "general-purpose operating systems (GPOSes)" (such as Linux (POSIX) and Windows).
@subsection over_trace Traceability @subsection over_trace Traceability

View File

@ -44,6 +44,9 @@
:: HTML outut directory ...................................................... :: HTML outut directory ......................................................
@set HTML_OUT=%QPC%\html @set HTML_OUT=%QPC%\html
if "%1"=="-CERT" (
@set HTML_OUT=%QPC%\cert-pack
)
:: Generate metrics.dox file... :: Generate metrics.dox file...
@set METRICS_INP=%QPC%\include %QPC%\src -x %QPC%\src\qs\* @set METRICS_INP=%QPC%\include %QPC%\src -x %QPC%\src\qs\*

View File

@ -5,123 +5,123 @@
================================================ ================================================
NLOC CCN token PARAM length location NLOC CCN token PARAM length location
------------------------------------------------ ------------------------------------------------
3 1 15 1 3 QEQueue_getNFree@310-312@..\include\qequeue.h 3 1 15 1 3 QEQueue_getNFree@306-308@..\include\qequeue.h
3 1 15 1 3 QEQueue_getNMin@327-329@..\include\qequeue.h 3 1 15 1 3 QEQueue_getNMin@323-325@..\include\qequeue.h
3 1 21 1 3 QEQueue_isEmpty@346-348@..\include\qequeue.h 3 1 21 1 3 QEQueue_isEmpty@342-344@..\include\qequeue.h
5 2 33 1 8 QPSet_setEmpty@194-201@..\include\qf.h 5 2 33 1 8 QPSet_setEmpty@245-252@..\include\qf.h
4 3 44 1 7 QPSet_isEmpty@204-210@..\include\qf.h 4 3 44 1 7 QPSet_isEmpty@255-261@..\include\qf.h
4 3 44 1 7 QPSet_notEmpty@213-219@..\include\qf.h 4 3 44 1 7 QPSet_notEmpty@264-270@..\include\qf.h
8 3 95 2 11 QPSet_hasElement@222-232@..\include\qf.h 8 3 95 2 11 QPSet_hasElement@273-283@..\include\qf.h
11 3 105 2 14 QPSet_insert@235-248@..\include\qf.h 11 3 105 2 14 QPSet_insert@286-299@..\include\qf.h
12 3 117 2 15 QPSet_remove@251-265@..\include\qf.h 12 3 117 2 15 QPSet_remove@302-316@..\include\qf.h
6 3 56 1 9 QPSet_findMax@268-276@..\include\qf.h 6 3 56 1 9 QPSet_findMax@319-327@..\include\qf.h
3 1 18 1 3 QActive_getPrio@735-737@..\include\qf.h 3 1 27 1 3 QActive_getPrio@782-784@..\include\qf.h
5 1 22 2 5 QActive_setPrio@742-746@..\include\qf.h 6 1 20 2 6 QF_psInit@1406-1411@..\include\qf.h
6 1 20 2 6 QF_psInit@1368-1373@..\include\qf.h 14 3 67 1 14 QS_rxPut@782-795@..\include\qs.h
14 3 67 1 14 QS_rxPut@810-823@..\include\qs.h 5 1 20 1 20 Q_DEFINE_THIS_MODULE@54-73@..\src\qf\qep_hsm.c
5 1 20 1 20 Q_DEFINE_THIS_MODULE@58-77@..\src\qf\qep_hsm.c 18 3 99 2 24 QHsm_isIn@128-151@..\src\qf\qep_hsm.c
18 3 99 2 24 QHsm_isIn@132-155@..\src\qf\qep_hsm.c 3 1 19 1 3 QHsm_state@154-156@..\src\qf\qep_hsm.c
3 1 19 1 3 QHsm_state@158-160@..\src\qf\qep_hsm.c 22 4 123 2 31 QHsm_childState@159-189@..\src\qf\qep_hsm.c
22 4 123 2 31 QHsm_childState@163-193@..\src\qf\qep_hsm.c 12 2 56 2 14 QHsm_ctor@192-205@..\src\qf\qep_hsm.c
12 2 56 2 14 QHsm_ctor@196-209@..\src\qf\qep_hsm.c 7 1 29 2 7 QHsm_top@208-214@..\src\qf\qep_hsm.c
7 1 29 2 7 QHsm_top@212-218@..\src\qf\qep_hsm.c 51 8 352 3 77 QHsm_init_@217-293@..\src\qf\qep_hsm.c
51 8 352 3 77 QHsm_init_@221-297@..\src\qf\qep_hsm.c 105 15 636 3 156 QHsm_dispatch_@296-451@..\src\qf\qep_hsm.c
105 15 636 3 156 QHsm_dispatch_@300-455@..\src\qf\qep_hsm.c 3 1 16 1 3 QHsm_getStateHandler_@455-457@..\src\qf\qep_hsm.c
3 1 16 1 3 QHsm_getStateHandler_@459-461@..\src\qf\qep_hsm.c 97 15 471 3 135 QHsm_tran_@461-595@..\src\qf\qep_hsm.c
97 15 471 3 135 QHsm_tran_@465-599@..\src\qf\qep_hsm.c 15 3 69 2 16 QMsm_isInState@81-96@..\src\qf\qep_msm.c
15 3 69 2 16 QMsm_isInState@85-100@..\src\qf\qep_msm.c 3 1 17 1 3 QMsm_stateObj@99-101@..\src\qf\qep_msm.c
3 1 17 1 3 QMsm_stateObj@103-105@..\src\qf\qep_msm.c 22 4 97 2 29 QMsm_childStateObj@104-132@..\src\qf\qep_msm.c
22 4 97 2 29 QMsm_childStateObj@108-136@..\src\qf\qep_msm.c 12 2 59 2 15 QMsm_ctor@135-149@..\src\qf\qep_msm.c
12 2 59 2 15 QMsm_ctor@139-153@..\src\qf\qep_msm.c 27 4 202 3 45 QMsm_init_@152-196@..\src\qf\qep_msm.c
27 4 202 3 45 QMsm_init_@156-200@..\src\qf\qep_msm.c 117 19 728 3 168 QMsm_dispatch_@199-366@..\src\qf\qep_msm.c
117 19 728 3 168 QMsm_dispatch_@203-370@..\src\qf\qep_msm.c 3 1 18 1 3 QMsm_getStateHandler_@370-372@..\src\qf\qep_msm.c
3 1 18 1 3 QMsm_getStateHandler_@374-376@..\src\qf\qep_msm.c 55 9 316 3 68 QMsm_execTatbl_@376-443@..\src\qf\qep_msm.c
55 9 316 3 68 QMsm_execTatbl_@380-447@..\src\qf\qep_msm.c 24 4 130 4 32 QMsm_exitToTranSource_@446-477@..\src\qf\qep_msm.c
24 4 130 4 32 QMsm_exitToTranSource_@450-481@..\src\qf\qep_msm.c 45 6 243 3 54 QMsm_enterHistory_@480-533@..\src\qf\qep_msm.c
45 6 243 3 54 QMsm_enterHistory_@484-537@..\src\qf\qep_msm.c 82 14 431 4 120 QActive_post_@70-189@..\src\qf\qf_actq.c
82 13 431 4 118 QActive_post_@74-191@..\src\qf\qf_actq.c 44 7 266 2 66 QActive_postLIFO_@194-259@..\src\qf\qf_actq.c
44 7 266 2 66 QActive_postLIFO_@196-261@..\src\qf\qf_actq.c 34 3 233 1 44 QActive_get_@264-307@..\src\qf\qf_actq.c
34 3 233 1 44 QActive_get_@266-309@..\src\qf\qf_actq.c 10 2 60 1 11 QF_getQueueMin@313-323@..\src\qf\qf_actq.c
10 2 60 1 11 QF_getQueueMin@315-325@..\src\qf\qf_actq.c 16 2 79 2 20 QTicker_ctor@342-361@..\src\qf\qf_actq.c
16 2 79 2 20 QTicker_ctor@344-363@..\src\qf\qf_actq.c 10 1 45 3 11 QTicker_init_@364-374@..\src\qf\qf_actq.c
10 1 45 3 11 QTicker_init_@366-376@..\src\qf\qf_actq.c 17 2 92 3 20 QTicker_dispatch_@377-396@..\src\qf\qf_actq.c
17 2 92 3 20 QTicker_dispatch_@379-398@..\src\qf\qf_actq.c 30 2 156 4 37 QTicker_post_@399-435@..\src\qf\qf_actq.c
30 2 156 4 37 QTicker_post_@401-437@..\src\qf\qf_actq.c 8 1 30 2 9 QTicker_postLIFO_@438-446@..\src\qf\qf_actq.c
8 1 30 2 9 QTicker_postLIFO_@440-448@..\src\qf\qf_actq.c 15 1 84 3 17 QActive_defer@65-81@..\src\qf\qf_defer.c
15 1 84 3 17 QActive_defer@69-85@..\src\qf\qf_defer.c 34 3 169 2 54 QActive_recall@86-139@..\src\qf\qf_defer.c
34 3 169 2 54 QActive_recall@90-143@..\src\qf\qf_defer.c 13 3 68 2 15 QActive_flushDeferred@144-158@..\src\qf\qf_defer.c
13 2 68 2 13 QActive_flushDeferred@148-160@..\src\qf\qf_defer.c 17 3 116 3 26 QF_poolInit@86-111@..\src\qf\qf_dyn.c
17 3 116 3 26 QF_poolInit@76-101@..\src\qf\qf_dyn.c 3 1 17 1 3 QF_poolGetMaxBlockSize@114-116@..\src\qf\qf_dyn.c
3 1 17 1 3 QF_poolGetMaxBlockSize@104-106@..\src\qf\qf_dyn.c 9 3 59 1 12 QF_getPoolMin@119-130@..\src\qf\qf_dyn.c
9 3 59 1 12 QF_getPoolMin@109-120@..\src\qf\qf_dyn.c 39 7 234 3 57 QF_newX_@133-189@..\src\qf\qf_dyn.c
39 7 234 3 57 QF_newX_@123-179@..\src\qf\qf_dyn.c 30 4 192 1 46 QF_gc@192-237@..\src\qf\qf_dyn.c
30 4 186 1 46 QF_gc@182-227@..\src\qf\qf_dyn.c 20 2 99 2 28 QF_newRef_@240-267@..\src\qf\qf_dyn.c
19 2 94 2 26 QF_newRef_@230-255@..\src\qf\qf_dyn.c 11 2 67 1 15 QF_deleteRef_@270-284@..\src\qf\qf_dyn.c
11 1 67 1 13 QF_deleteRef_@258-270@..\src\qf\qf_dyn.c 32 5 233 4 50 QMPool_init@67-116@..\src\qf\qf_mem.c
32 5 233 4 50 QMPool_init@71-120@..\src\qf\qf_mem.c 44 4 238 3 67 QMPool_get@119-185@..\src\qf\qf_mem.c
44 4 238 3 67 QMPool_get@123-189@..\src\qf\qf_mem.c 19 2 114 3 26 QMPool_put@188-213@..\src\qf\qf_mem.c
19 2 114 3 26 QMPool_put@192-217@..\src\qf\qf_mem.c 8 1 35 2 13 QActive_psInit@73-85@..\src\qf\qf_ps.c
8 1 35 2 13 QActive_psInit@77-89@..\src\qf\qf_ps.c 43 6 232 3 73 QActive_publish_@90-162@..\src\qf\qf_ps.c
41 5 220 3 68 QActive_publish_@94-161@..\src\qf\qf_ps.c 18 5 111 2 24 QActive_subscribe@167-190@..\src\qf\qf_ps.c
18 5 111 2 24 QActive_subscribe@166-189@..\src\qf\qf_ps.c 18 5 111 2 27 QActive_unsubscribe@195-221@..\src\qf\qf_ps.c
18 5 111 2 27 QActive_unsubscribe@194-220@..\src\qf\qf_ps.c 19 5 130 1 24 QActive_unsubscribeAll@226-249@..\src\qf\qf_ps.c
19 5 130 1 24 QActive_unsubscribeAll@225-248@..\src\qf\qf_ps.c 10 2 46 2 10 QF_bzero@80-89@..\src\qf\qf_qact.c
10 2 46 2 10 QF_bzero@88-97@..\src\qf\qf_qact.c 16 2 72 2 23 QActive_ctor@96-118@..\src\qf\qf_qact.c
16 2 72 2 23 QActive_ctor@104-126@..\src\qf\qf_qact.c 28 10 225 1 47 QActive_register_@123-169@..\src\qf\qf_qact.c
10 3 66 1 16 QActive_register_@131-146@..\src\qf\qf_qact.c 10 3 79 1 15 QActive_unregister_@174-188@..\src\qf\qf_qact.c
10 3 79 1 15 QActive_unregister_@151-165@..\src\qf\qf_qact.c 24 6 143 1 29 QF_LOG2@196-224@..\src\qf\qf_qact.c
24 6 143 1 29 QF_LOG2@173-201@..\src\qf\qf_qact.c 14 2 85 3 14 QEQueue_init@67-80@..\src\qf\qf_qeq.c
14 2 85 3 14 QEQueue_init@71-84@..\src\qf\qf_qeq.c 57 8 301 4 76 QEQueue_post@83-158@..\src\qf\qf_qeq.c
57 8 301 4 76 QEQueue_post@87-162@..\src\qf\qf_qeq.c 36 5 199 3 46 QEQueue_postLIFO@161-206@..\src\qf\qf_qeq.c
36 5 199 3 46 QEQueue_postLIFO@165-210@..\src\qf\qf_qeq.c 38 4 219 2 48 QEQueue_get@209-256@..\src\qf\qf_qeq.c
38 4 219 2 48 QEQueue_get@213-260@..\src\qf\qf_qeq.c 16 2 79 2 35 QMActive_ctor@74-108@..\src\qf\qf_qmact.c
16 2 79 2 34 QMActive_ctor@78-111@..\src\qf\qf_qmact.c 15 2 96 4 32 QTimeEvt_ctorX@78-109@..\src\qf\qf_time.c
15 2 99 4 32 QTimeEvt_ctorX@82-113@..\src\qf\qf_time.c 33 8 225 3 59 QTimeEvt_armX@112-170@..\src\qf\qf_time.c
33 8 225 3 59 QTimeEvt_armX@116-174@..\src\qf\qf_time.c 31 3 173 1 41 QTimeEvt_disarm@173-213@..\src\qf\qf_time.c
31 3 173 1 41 QTimeEvt_disarm@177-217@..\src\qf\qf_time.c 36 8 230 2 64 QTimeEvt_rearm@216-279@..\src\qf\qf_time.c
36 8 230 2 64 QTimeEvt_rearm@220-283@..\src\qf\qf_time.c 5 1 36 1 5 QTimeEvt_wasDisarmed@282-286@..\src\qf\qf_time.c
5 1 36 1 5 QTimeEvt_wasDisarmed@286-290@..\src\qf\qf_time.c 7 1 30 1 8 QTimeEvt_currCtr@289-296@..\src\qf\qf_time.c
7 1 30 1 8 QTimeEvt_currCtr@293-300@..\src\qf\qf_time.c 69 7 380 2 110 QTimeEvt_tick_@299-408@..\src\qf\qf_time.c
69 7 380 2 110 QTimeEvt_tick_@303-412@..\src\qf\qf_time.c 14 3 75 1 16 QTimeEvt_noActive@411-426@..\src\qf\qf_time.c
14 3 75 1 16 QTimeEvt_noActive@415-430@..\src\qf\qf_time.c 21 2 112 1 31 QK_schedLock@74-104@..\src\qk\qk.c
61 16 348 1 106 QK_activate_@78-183@..\src\qk\qk.c 20 4 118 1 33 QK_schedUnlock@107-139@..\src\qk\qk.c
14 3 74 1 17 QK_sched_@186-202@..\src\qk\qk.c 9 3 74 1 17 QF_init@144-160@..\src\qk\qk.c
22 2 112 1 33 QK_schedLock@205-237@..\src\qk\qk.c 3 1 10 1 4 QF_stop@163-166@..\src\qk\qk.c
21 4 124 1 33 QK_schedUnlock@240-272@..\src\qk\qk.c 15 4 61 1 25 QF_run@169-193@..\src\qk\qk.c
11 2 77 1 16 QF_init@277-292@..\src\qk\qk.c 25 3 156 7 34 QActive_start_@200-233@..\src\qk\qk.c
3 1 10 1 4 QF_stop@295-298@..\src\qk\qk.c 19 4 78 1 24 QK_sched_@238-261@..\src\qk\qk.c
15 4 61 1 25 QF_run@301-325@..\src\qk\qk.c 65 17 384 1 112 QK_activate_@264-375@..\src\qk\qk.c
24 5 145 7 34 QActive_start_@332-365@..\src\qk\qk.c 7 3 52 1 13 QF_init@73-85@..\src\qv\qv.c
9 2 64 1 13 QF_init@77-89@..\src\qv\qv.c 3 1 10 1 4 QF_stop@88-91@..\src\qv\qv.c
3 1 10 1 4 QF_stop@92-95@..\src\qv\qv.c 39 10 197 1 77 QF_run@94-170@..\src\qv\qv.c
39 9 197 1 76 QF_run@98-173@..\src\qv\qv.c 18 1 124 7 25 QActive_start_@177-201@..\src\qv\qv.c
17 3 115 7 23 QActive_start_@180-202@..\src\qv\qv.c 23 3 131 1 34 QXK_schedLock@71-104@..\src\qxk\qxk.c
74 16 467 1 129 QXK_activate_@78-206@..\src\qxk\qxk.c 20 4 118 1 33 QXK_schedUnlock@107-139@..\src\qxk\qxk.c
47 7 264 1 65 QXK_sched_@209-273@..\src\qxk\qxk.c 11 3 103 1 21 QF_init@144-164@..\src\qxk\qxk.c
23 3 131 1 34 QXK_schedLock@276-309@..\src\qxk\qxk.c 3 1 10 1 4 QF_stop@167-170@..\src\qxk\qxk.c
20 4 124 1 33 QXK_schedUnlock@312-344@..\src\qxk\qxk.c 18 4 92 1 30 QF_run@173-202@..\src\qxk\qxk.c
12 2 72 1 18 QXK_current@347-364@..\src\qxk\qxk.c 29 5 178 7 42 QActive_start_@209-250@..\src\qxk\qxk.c
13 2 106 1 21 QF_init@369-389@..\src\qxk\qxk.c 42 8 220 1 53 QXK_sched_@258-310@..\src\qxk\qxk.c
3 1 10 1 4 QF_stop@392-395@..\src\qxk\qxk.c 59 16 383 1 98 QXK_activate_@313-410@..\src\qxk\qxk.c
15 4 61 1 25 QF_run@398-422@..\src\qxk\qxk.c 12 2 72 1 18 QXK_current@413-430@..\src\qxk\qxk.c
26 6 165 7 36 QActive_start_@429-464@..\src\qxk\qxk.c 23 7 132 1 34 QXK_contextSw@434-467@..\src\qxk\qxk.c
13 2 104 1 23 QXK_threadExit_@470-492@..\src\qxk\qxk.c 13 2 104 1 23 QXK_threadExit_@474-496@..\src\qxk\qxk.c
18 4 114 2 27 QXMutex_init@78-104@..\src\qxk\qxk_mutex.c 10 2 64 2 13 QXMutex_init@74-86@..\src\qxk\qxk_mutex.c
67 12 536 2 108 QXMutex_lock@107-214@..\src\qxk\qxk_mutex.c 81 11 724 2 138 QXMutex_lock@89-226@..\src\qxk\qxk_mutex.c
43 10 311 1 67 QXMutex_tryLock@217-283@..\src\qxk\qxk_mutex.c 59 9 502 1 97 QXMutex_tryLock@229-325@..\src\qxk\qxk_mutex.c
63 16 496 1 110 QXMutex_unlock@286-395@..\src\qxk\qxk_mutex.c 78 12 670 1 135 QXMutex_unlock@328-462@..\src\qxk\qxk_mutex.c
9 1 51 3 11 QXSemaphore_init@77-87@..\src\qxk\qxk_sema.c 9 1 51 3 11 QXSemaphore_init@73-83@..\src\qxk\qxk_sema.c
45 7 319 2 71 QXSemaphore_wait@90-160@..\src\qxk\qxk_sema.c 57 7 389 2 84 QXSemaphore_wait@86-169@..\src\qxk\qxk_sema.c
15 2 61 1 20 QXSemaphore_tryWait@163-182@..\src\qxk\qxk_sema.c 28 3 139 1 39 QXSemaphore_tryWait@172-210@..\src\qxk\qxk_sema.c
29 6 193 1 47 QXSemaphore_signal@185-231@..\src\qxk\qxk_sema.c 42 7 275 1 66 QXSemaphore_signal@213-278@..\src\qxk\qxk_sema.c
21 2 113 3 26 QXThread_ctor@78-103@..\src\qxk\qxk_xthr.c 21 2 113 3 26 QXThread_ctor@74-99@..\src\qxk\qxk_xthr.c
21 4 195 1 38 QXThread_delay@106-143@..\src\qxk\qxk_xthr.c 21 4 195 1 38 QXThread_delay@102-139@..\src\qxk\qxk_xthr.c
14 2 68 1 16 QXThread_delayCancel@146-161@..\src\qxk\qxk_xthr.c 14 2 68 1 16 QXThread_delayCancel@142-157@..\src\qxk\qxk_xthr.c
58 7 493 1 85 QXThread_queueGet@164-248@..\src\qxk\qxk_xthr.c 58 7 493 1 85 QXThread_queueGet@160-244@..\src\qxk\qxk_xthr.c
10 1 39 3 11 QXThread_init_@251-261@..\src\qxk\qxk_xthr.c 10 1 39 3 11 QXThread_init_@247-257@..\src\qxk\qxk_xthr.c
10 1 39 3 11 QXThread_dispatch_@264-274@..\src\qxk\qxk_xthr.c 10 1 39 3 11 QXThread_dispatch_@260-270@..\src\qxk\qxk_xthr.c
29 6 201 7 50 QXThread_start_@277-326@..\src\qxk\qxk_xthr.c 31 7 216 7 52 QXThread_start_@273-324@..\src\qxk\qxk_xthr.c
101 13 527 4 136 QXThread_post_@329-464@..\src\qxk\qxk_xthr.c 100 15 527 4 138 QXThread_post_@327-464@..\src\qxk\qxk_xthr.c
8 1 30 2 9 QXThread_postLIFO_@467-475@..\src\qxk\qxk_xthr.c 8 1 30 2 9 QXThread_postLIFO_@467-475@..\src\qxk\qxk_xthr.c
5 1 49 1 7 QXThread_block_@478-484@..\src\qxk\qxk_xthr.c 5 1 49 1 7 QXThread_block_@478-484@..\src\qxk\qxk_xthr.c
8 3 56 1 8 QXThread_unblock_@487-494@..\src\qxk\qxk_xthr.c 8 3 56 1 8 QXThread_unblock_@487-494@..\src\qxk\qxk_xthr.c
@ -131,45 +131,45 @@
============================================================== ==============================================================
NLOC Avg.NLOC AvgCCN Avg.token function_cnt file NLOC Avg.NLOC AvgCCN Avg.token function_cnt file
-------------------------------------------------------------- --------------------------------------------------------------
7 0.0 0.0 0.0 0 ..\include\qassert.h 6 0.0 0.0 0.0 0 ..\include\qassert.h
124 0.0 0.0 0.0 0 ..\include\qep.h 124 0.0 0.0 0.0 0 ..\include\qep.h
33 3.0 1.0 17.0 3 ..\include\qequeue.h 33 3.0 1.0 17.0 3 ..\include\qequeue.h
229 6.4 2.3 55.4 10 ..\include\qf.h 225 6.6 2.4 60.1 9 ..\include\qf.h
9 0.0 0.0 0.0 0 ..\include\qf_pkg.h 9 0.0 0.0 0.0 0 ..\include\qf_pkg.h
18 0.0 0.0 0.0 0 ..\include\qk.h 19 0.0 0.0 0.0 0 ..\include\qk.h
25 0.0 0.0 0.0 0 ..\include\qmpool.h 25 0.0 0.0 0.0 0 ..\include\qmpool.h
8 0.0 0.0 0.0 0 ..\include\qpc.h 8 0.0 0.0 0.0 0 ..\include\qpc.h
344 14.0 3.0 67.0 1 ..\include\qs.h 356 14.0 3.0 67.0 1 ..\include\qs.h
3 0.0 0.0 0.0 0 ..\include\qstamp.c 3 0.0 0.0 0.0 0 ..\include\qstamp.c
2 0.0 0.0 0.0 0 ..\include\qstamp.h 2 0.0 0.0 0.0 0 ..\include\qstamp.h
0 0.0 0.0 0.0 0 ..\include\qs_dummy.h 0 0.0 0.0 0.0 0 ..\include\qs_dummy.h
19 0.0 0.0 0.0 0 ..\include\qs_pkg.h 19 0.0 0.0 0.0 0 ..\include\qs_pkg.h
7 0.0 0.0 0.0 0 ..\include\qv.h 7 0.0 0.0 0.0 0 ..\include\qv.h
97 0.0 0.0 0.0 0 ..\include\qxk.h 96 0.0 0.0 0.0 0 ..\include\qxk.h
334 32.3 5.1 182.1 10 ..\src\qf\qep_hsm.c 334 32.3 5.1 182.1 10 ..\src\qf\qep_hsm.c
336 32.3 5.3 187.9 10 ..\src\qf\qep_msm.c 336 32.3 5.3 187.9 10 ..\src\qf\qep_msm.c
2 0.0 0.0 0.0 0 ..\src\qf\qf_act.c 2 0.0 0.0 0.0 0 ..\src\qf\qf_act.c
258 27.9 3.7 154.7 9 ..\src\qf\qf_actq.c 258 27.9 3.8 154.7 9 ..\src\qf\qf_actq.c
69 20.7 2.0 107.0 3 ..\src\qf\qf_defer.c 69 20.7 2.3 107.0 3 ..\src\qf\qf_defer.c
135 18.3 3.0 110.4 7 ..\src\qf\qf_dyn.c 138 18.4 3.1 112.0 7 ..\src\qf\qf_dyn.c
102 31.7 3.7 195.0 3 ..\src\qf\qf_mem.c 102 31.7 3.7 195.0 3 ..\src\qf\qf_mem.c
113 20.8 4.2 121.4 5 ..\src\qf\qf_ps.c 115 21.2 4.4 123.8 5 ..\src\qf\qf_ps.c
79 14.0 3.2 81.2 5 ..\src\qf\qf_qact.c 95 17.6 4.6 113.0 5 ..\src\qf\qf_qact.c
152 36.2 4.8 201.0 4 ..\src\qf\qf_qeq.c 152 36.2 4.8 201.0 4 ..\src\qf\qf_qeq.c
18 16.0 2.0 79.0 1 ..\src\qf\qf_qmact.c 18 16.0 2.0 79.0 1 ..\src\qf\qf_qmact.c
218 26.2 4.1 156.0 8 ..\src\qf\qf_time.c 218 26.2 4.1 155.6 8 ..\src\qf\qf_time.c
179 21.4 4.6 118.9 8 ..\src\qk\qk.c 185 22.1 4.8 124.1 8 ..\src\qk\qk.c
75 17.0 3.8 96.5 4 ..\src\qv\qv.c 74 16.8 3.8 95.8 4 ..\src\qv\qv.c
254 24.6 4.7 150.4 10 ..\src\qxk\qxk.c 261 23.0 5.0 140.3 11 ..\src\qxk\qxk.c
198 47.8 10.5 364.2 4 ..\src\qxk\qxk_mutex.c 235 57.0 8.5 490.0 4 ..\src\qxk\qxk_mutex.c
105 24.5 4.0 156.0 4 ..\src\qxk\qxk_sema.c 143 34.0 4.5 213.5 4 ..\src\qxk\qxk_sema.c
324 24.3 3.5 154.8 13 ..\src\qxk\qxk_xthr.c 325 24.4 3.8 156.0 13 ..\src\qxk\qxk_xthr.c
============================================================================================================= =============================================================================================================
No thresholds exceeded (cyclomatic_complexity > 20 or length > 500 or nloc > 1000000 or parameter_count > 10) No thresholds exceeded (cyclomatic_complexity > 20 or length > 500 or nloc > 1000000 or parameter_count > 10)
========================================================================================== ==========================================================================================
Total nloc Avg.NLOC AvgCCN Avg.token Fun Cnt Warning cnt Fun Rt nloc Rt Total nloc Avg.NLOC AvgCCN Avg.token Fun Cnt Warning cnt Fun Rt nloc Rt
------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------
3876 23.8 4.1 143.6 122 0 0.00 0.00 3992 24.7 4.2 151.8 122 0 0.00 0.00
@endcode @endcode
*/ */

View File

@ -1,267 +0,0 @@
/*! @defgroup qep QEP
@brief
Hierarchical Event Processor
QEP is a universal, UML-compliant event processor that enables developers to code UML state machines in highly readable ANSI-C, in which every state machine element is mapped to code precisely, unambiguously, and exactly once (traceability). QEP fully supports hierarchical state nesting, which is the fundamental mechanism for reusing behavior across many states instead of repeating the same actions and transitions over and over again.
*/
/*##########################################################################*/
/*! @defgroup qf QF
@brief
Active Object (Actor) Framework
QF is a portable, event-driven, real-time framework for execution of active objects (concurrent state machines) specifically designed for real-time embedded (RTE) systems.
*/
/*##########################################################################*/
/*! @defgroup qs QS
@brief
Software Tracing Instrumentation
QS is software tracing system that enables developers to monitor live QP applications with minimal target system resources and without stopping or significantly slowing down the code. QS is an ideal tool for testing, troubleshooting, and optimizing QP applications. QS can even be used to support acceptance testing in product manufacturing. Please see <a href="https://www.state-machine.com/qtools/qs.html"><b>QS Manual</b></a> inside the <a href="https://www.state-machine.com/qtools" target="_blank" class="extern">QTools collection</a> for more information.
*/
/*##########################################################################*/
/*! @defgroup qv QV
@brief
Cooperative Kernel
@description
QV is a simple **cooperative** kernel (previously called "Vanilla" kernel). This kernel executes active objects one at a time, with priority-based scheduling performed before processing of each event. Due to naturally short duration of event processing in state machines, the simple QV kernel is often adequate for many real-time systems.
@note
The QV scheduler is described in Section 6.3.7 of the book ["Practical UML Statecharts in C/C++, 2nd Ed" (PSiCC2)](https://www.state-machine.com/psicc2/).
@section qv_overview QV Overview
The QV scheduler is engaged after every RTC step of any active object to choose the next active object to execute. The QV scheduler always chooses the highest-priority active object that has any events in its event queue. The QV scheduler then extracts the next event from this queue and dispatches it to the state machine associated with the active object. The state machine runs to completion, after which the QV scheduler runs and the cycle repeats.
![QV scheduler operation](qv.gif)
Please note that because the state machines always return to the QV scheduler after each RTC step, a single stack can be used to process all state machines (memory-friendly architecture).
The QV scheduler can also very easily detect when all event queues are empty, at which point it can call the idle callback to let the application put the CPU and peripherals to a **low-power sleep mode** (power-friendly architecture).
Given the simplicity, portability, and low-resource consumption, the QV scheduler is very attractive. It allows you to partition the problem into active objects and execute these active objects orderly. The thread-level response of this scheduler is the longest RTC step in the whole system, but because event-driven active objects dont block, the RTC steps tend to be very short (typically just a few microseconds). Also, often you can break up longer RTC steps into shorter pieces, by posting an event to self and returning (“Reminder” state pattern). The self-posted event then triggers the continuation of longer processing.
@remarks
Sometimes it is not practical to break up long RTC steps, and consequently the thread-level response of the simple @ref qv "QV kernel" might be too slow. In this cases you need to use a *preemptive* kernel. The big advantage of preemptive kernel is that it effectively decouples high-priority thread from low-priority threads in the time domain. The timeliness of execution of high-priority thread is almost independent on the low-priority threads. But of course there is no such thing as a free lunch. Preemptive kernels open the whole new class of problems related to race conditions. So you need to be very careful about sharing any resources.
@next{qk}
*/
/*##########################################################################*/
/*! @defgroup qk QK
@brief
Preemptive Run-To-Completion (Non-Blocking) Kernel
<p>The preemptive, non-blocking QK kernel is specifically designed to execute non-blocking active objects (see also [[PSiCC2](https://www.state-machine.com/psicc2/), Chapter 10]). QK runs active objects in the same way as prioritized interrupt controller (such as NVIC in ARM Cortex-M) runs interrupts using **single stack**. Active objects process their events in run-to-completion (RTC) fashion and remove themselves from the call stack, the same way as nested interrupts remove themselves from the stack upon completion. At the same time high-priority active objects can **preempt** lower-priority active objects, just like interrupts can preempt each other under a prioritized interrupt controller. <span class="highlight">QK meets all the requirement of the Rate Monotonic Scheduling (a.k.a. Rate Monotonic Analysis RMA) and can be used in hard real-time systems</span>.
</p>
@note
The non-blocking, run-to-completion, preemptive threads are known in the literature as "basic threads" (OSEK/AUTOSAR terminology), sometimes also called "fibers" (e.g., Q-Kernel) or "software interrupts" (e.g., TI-RTOS).
@section qk_overview QK Overview
The preemptive, run-to-completion (RTC) QK kernel breaks entirely with the endless-loop structure of the thread routines and instead uses threads structured as one-shot, discrete, run-to-completion functions, very much like ISRs [[PSiCC2](https://www.state-machine.com/psicc2/), Chapter 10]. In fact, the QK kernel views interrupts very much like threads of a “super-high” priority, except that interrupts are prioritized in hardware by the interrupt controller, whereas threads are prioritized in software by the RTC kernel.
As a fully preemptive multithreading kernel, QK must ensure that at all times the CPU executes the highest-priority thread (active object) that is ready to run. Fortunately, only two scenarios can lead to readying a higher-priority thread:
<ul class="tag">
<li><span class="tag">1</span>
When a lower-priority thread posts an event to a higher-priority thread, the kernel must immediately suspend the execution of the lower-priority thread and start the higher-priority thread. This type of preemption is called <b>synchronous preemption</b> because it happens synchronously with posting an event to the thread's event queue.
> NOTE: The stack usage shown in the bottom panel displays stack growing down (towards lower addresses), as it is the case in ARM Cortex-M.
</li>
</ul>
@anchor qk-synch-fig
@image html qk_synch.gif "Synchronous Preemption in QK"
<ul class="tag">
<li><span class="tag">2</span>
When an interrupt posts an event to a higher-priority thread than the interrupted thread, upon completion of the ISR the kernel must start execution of the higher-priority thread instead of resuming the lower-priority thread. This type of preemption is called <b>asynchronous preemption</b> because it can happen asynchronously, any time interrupts are not explicitly disabled.
> NOTE: The stack usage during asynchronous preemption on ARM Cortex-M is slightly simplified in the diagram below. A more detailed stack usage diagram is discussed later in the section explaining the @ref arm-cm_qk_port-asm_pendsv "Detailed stack allocation in QK for ARM Cortex-M".
</li>
</ul>
@anchor qk-asynch-fig
@image html qk_asynch.gif "Asynchronous Preemption in QK"
@note
A traditional RTOS kernel does not distinguish between the synchronous and asynchronous preemptions and makes all preemptions look like the more stack-intensive asynchronous preemptions. In contrast, a RTC kernel can implement synchronous preemption as a simple function call (to QK_activate_()), which is much more efficient than a full context-switch.
@next{qxk}
*/
/*##########################################################################*/
/*! @defgroup qxk QXK
@brief
Preemptive Dual-Mode (Run-to-Completion/Blocking) RTOS Kernel
QXK is a small, preemptive, priority-based, dual-mode **blocking** kernel that executes active objects like the @ref qk "QK kernel" (@ref qxk_basic "basic threads"), but can also execute traditional __blocking__ threads (@ref qxk_extended "extended threads"). In this respect, QXK behaves exactly like a __conventional RTOS__ (Real-Time Operating System).
QXK has been designed specifically for mixing event-driven active objects with traditional blocking code, such as commercial middleware (TCP/IP stacks, UDP stacks, embedded file systems, etc.) or legacy software. To this end, QXK is not only more efficient than running QP on top of a @ref ports_rtos "traditional 3rd-party RTOS" (because non-blocking @ref qxk_basic "basic threads" take far less stack space and CPU cycles for context switch than the much heavier @ref qxk_extended "extended threads"). But the biggest advantage of QXK is that it __protects__ the application-level code from inadvertent mixing of blocking calls inside the event-driven active objects. Specifically, QXK "knows" the type of the thread context (extended/basic) and asserts internally if a blocking call (e.g., semaphore-wait or a time-delay) is attempted in a basic thread (active object). This is something that a QP port to a @ref ports_rtos "conventional 3rd-party RTOS" cannot do, because such an RTOS runs all code (including active objects) in the context of havyweight extended threads.
Currently, the QXK kernel has been ported to the following CPUs:
- @ref arm-cm_qxk "Cortex-M (M0/M0+/M1/M3/M4/M4F/M7)"@n
Supported toolchains include: ARM-KEIL MDK, IAR-ARM, GNU-ARM, TI-ARM.
Currently, the QXK kernel is illustrated by the following examples:
- @ref arm-cm_dpp_efm32-slstk3401a (ARM Cortex-M4F)@n
Example illustrates: 6 active objects plus two extended threads, QXK blocking delay, QXK semaphore, QXK mutex, QXK blocking message queue.
- @ref arm-cm_dpp_ek-tm4c123gxl (ARM Cortex-M4F)@n
Example illustrates: 6 active objects plus two extended threads, QXK blocking delay, QXK semaphore, QXK mutex, QXK blocking message queue.
- @ref arm-cm_dpp_nucleo-l053r8 (ARM Cortex-M0+)@n
Example illustrates: 6 active objects plus two extended threads, QXK blocking delay, QXK semaphore, QXK mutex, QXK blocking message queue.
@section qxk_basic Basic Threads
QXK supports **basic**-threads (non-blocking, run-to-completion activations). The basic-threads all nest on the same stack (Main Stack Pointer in ARM Cortex-M), so the stack usage is reduced. The additional advantage of basic-threads is that switching from basic-thread to another basic-thread requires only @ref QXK_activate_() "activation" of the basic-thread, which is much simpler and faster than full context-switch required for @ref qxk_extended "extended"-threads that QXK also supports (see below).
@remarks
QXK adopts the "basic/exteded thread" terms from the <a class="extern" target="_blank" href="https://www.autosar.org">OSEK/AUTOSAR Operating System</a> specification. Other real-time kernels might use different terminology for similar concepts. For example, the <a class="extern" target="_blank" href="http://www.quasarsoft.com/">Q-Kernel</a> uses the term "fibers", while <a class="extern" target="_blank" href="http://www.ti.com/tool/TI-RTOS">TI-RTOS</a> uses the term "software interrupts" for concepts closely related to "basic threads".
@section qxk_extended Extended Threads
QXK supports **extended**-threads (blocking, typically structrued as endless loops). The extended-threads use private per-thread stacks, as in conventional RTOS kernels. Any switching from basic-to-extended thread or extended-to-extended thread requires full context switch.
@remarks
QXK is a unique dual-mode kernel on the market that supports interleaving the priorities of basic threads and extended threads. Other dual-mode kernels typically limit the priorities of basic threads to be always higher (more urgent) than any of the extended threads.
@sa ::QXThread
@section qxk_classes Classes in QXK
The figure below shows the main classes introduced in the QXK kernel and their relation to the classes of the QP framework.
@image html qxk_classes.gif "Classes of the QXK dual-mode kernel"
<ul class="tag">
<li><span class="tag">0</span> The abstract ::QActive class represents active objects in QP. This class contains the @c thread object of the underlying kernel (QXK thread-control-block in this case) as well as the event queue and the unique priority of the active object.
</li>
<li><span class="tag">1</span> The ::QXThread class represents the extended (blocking) threads of the QXK kernel. It inherits ::QActive, so that extended-threads can be treated as active objects internally in the framework. However, the extended-threads **do not implement state machines**. Instead, the data fields used for storing the current state in active objects are re-used to store the private stack of the extended-thread. The ::QXThread class also contains the @c timeEvt object (see ::QTimeEvt) for generating timeouts when the extended-thread is blocked.
</li>
<li><span class="tag">2</span> The ::QXMutex class represents the **priority-ceiling mutex** of the QXK kernel. The mutex can block and can be used only in the extended-threads (in case they share resources that need to be protected). The mutex is recursive, meaning that it can be locked multiple times from the same extended thread (but it needs to be unlocked equal number of times).
</li>
<li><span class="tag">3</span> The ::QXSemaphore class represents the **counting semaphore** of the QXK kernel. The semaphore can be waited on only in the extended-threads and the QXK kernel would assert if an active object thread would attempt to wait on a semaphore. On the other hand, a semaphore can be signaled from anywhere in the code, including active objects and ISRs.
</li>
</ul>
@note
The main takeaway from the QXK class diagram is QXK's **optimal, tight integration** with the QP framework. The QXK kernel reuses all mechanisms already provided in QP, thus avoiding any code duplication, inefficient layers of indirection, and additional licensing costs, which are inevitable when using @ref ports_rtos "3rd-party RTOS kernels" to run QP applications.
@section qxk_features QXK Feature Summary
As you can see in the list below, <span class="highlight">QXK provides most features you might expect of a traditional blocking **RTOS** kernel and is <strong>recommended</strong> as the preferred RTOS kernel for QP applications</span> that need to mix active objects with traditional blocking code.
<ul class="tag">
<li><span class="bullet">&gt;</span>Preemptive, priority-based scheduling of up to 64 threads. Each thread must be assigned its own unique priority (1 .. #QF_MAX_ACTIVE);
</li>
> NOTE: QXK always executes the highest-priority thread that is ready to run (is not blocked). The scheduling algorithm used in QXK meets all the requirement of the Rate Monotonic Scheduling (a.k.a. Rate Monotonic Analysis — RMA) and can be used in hard real-time systems.
<li><span class="bullet">&gt;</span>QXK distinguishes between two types of threads:
</li>
- **basic threads** of active objects that are made ready-to-run by events posted to the active objects. Such basic threads are non-blocking, run-to-completion activations that cannot block in the middle of the RTC step. QXK asserts when a basic thread attempts to use a blocking mechanism, such as a time-delay or a semaphore-wait. All basic threads share the common stack.
- **extended threads** that can block anywhere in their thread-handler function, whereas QXK provides a typical assortments of blocking primitives for extended-threads, such as time-delay, blocking message queue, counting semaphore, or a mutex. Each extended thread must be provided with its own private stack.
<li><span class="bullet">&gt;</span>Tightly integrated mechanisms for communication between event-driven active objects and extended blocking threads:
</li>
- Basic threads (Active Objects) can signal semaphores and send messages to extended threads.
- Extended threads can post or publish events to active objects or other extended threads;
- Extended threads can subscribe to events and thus can receive events published in the system.
<li><span class="bullet">&gt;</span>Priority-Ceiling, recursive Mutexes with optional timeout;
</li>
> **NOTE:** Priority-ceiling protocol implemented in QXK is immune to priority-inversions, but requires a unique QP thread priority level (the ceiling priority) to be assigned to the mutex. This ceiling priority is unavailable to QP threads.@n
> **NOTE:** A QXK mutex can be configured not to use the priority-ceiling protocol (when initialized with a zero priority-ceiling). In that case, the mutex does not require a separate priority level.
<li><span class="bullet">&gt;</span>Counting Semaphores with optional timeout that can block multiple extended-threads;
</li>
<li><span class="bullet">&gt;</span>Blocking "zero-copy" message queue with optional timeout bound to each extended-thread;
</li>
<li><span class="bullet">&gt;</span>Deterministic fixed-size memory pools for dynamic memory management available both to extended-threads and active objects;
</li>
<li><span class="bullet">&gt;</span>Interrupt management, including "zero-latency", kernel-unaware interrupts that are never disabled;
</li>
> NOTE: This feature is only supported on CPUs that allow selective interrupt disabling, such as ARM Cortex-M3/M4 (but not ARM Cortex-M0/M0+);
<li><span class="bullet">&gt;</span> @ref qxk_tls "Thread-Local Storage" for all threads (basic threads and extended threads).
</li>
</ul>
@subsection qxk_tls Thread Local Storage
<b>Thread-local storage (TLS)</b> is a programming method that uses static or global memory local to a thread. TLS is specifically useful for writing library-type code, which is used in a multithreaded environment and needs to access per-thread data in an independent way.
TLS is used in some places where ordinary, single-threaded programs would use static or global variables, but where this would be inappropriate in multithreaded cases. An example of such situations is where library-type functions use a global variable to set an error condition (for example the global variable errno used by many functions of the C library). If errno were simply a global variable, a call of a system function on one thread may overwrite the value previously set by a call of a system function on a different thread, possibly before following code on that different thread could check for the error condition. The solution is to have errno be a variable that looks like it is global, but in fact exists once per thread—i.e., it lives in *thread-local storage*. A second use case would be multiple threads accumulating information into a global variable. To avoid a race condition, every access to this global variable would have to be protected by a mutual-exclusion mechanism. Alternatively, each thread might accumulate into a thread-local variable (that, by definition, cannot be read from or written to from other threads, implying that there can be no race conditions). Threads then only have to synchronize a final accumulation from their own thread-local variable into a single, truly global variable.
The TLS implementations vary, but many systems, including QXK, implement TLS by providing a pointer-sized variable thread-local. This pointer can be set to arbitrarily sized memory blocks in a thread-local manner, by allocating such a memory block (statically or dynamically) and storing the memory address of that block in the thread-local variable.
Typical usage of TLS in QXK is illustrated in the example <span class="img folder">qpc/examples/arm-cm/dpp_efm32-slstk3401a/qxk/</span>, <span class="img file_c">test.c</span>, and consists:
- define the TLS structure
@code{c}
typedef struct {
uint32_t foo;
uint8_t bar[10];
} TLS_test;
@endcode
- allocate the TLS storage for all participating threads (extended or basic threads)
@code{c}
static TLS_test l_tls1;
static TLS_test l_tls2;
@endcode
- initialize the TLS per-thread pointer in each thread routine (for extended threads) or the top-most initial transition (for basic threads of active objects):
@code{c}
static void Thread1_run(QXThread * const me) {
me->super.thread = &l_tls1; /* initialize the TLS for Thread1 */
. . .
}
. . .
static void Thread2_run(QXThread * const me) {
me->super.thread = &l_tls2; /* initialize the TLS for Thread2 */
. . .
}
@endcode
- access the TLS from your code:
@code{c}
void lib_fun(uint32_t x) {
QXK_TLS(TLS_test *)->foo = x;
}
@endcode
@sa
- QXK_current()
- QXK_TLS()
*/

View File

@ -87,7 +87,7 @@ C# File Extensions : cs
Java File Extensions : java Java File Extensions : java
# Other files are not officially supported by RSM # Other files are not officially supported by RSM
# but lines will be counted as LOC # but lines will be counted as LOC
Other File Extensions : Other File Extensions :
# When analyzing *.h files, treat header files as # When analyzing *.h files, treat header files as
# both C and C++. If you use separate extensions for C++ and # both C and C++. If you use separate extensions for C++ and
@ -136,7 +136,7 @@ Wrap long names in reports : Yes
# are to be created. The path must be a location with write # are to be created. The path must be a location with write
# permissions. RSM will create work files in the current # permissions. RSM will create work files in the current
# directory if no path is specified. # directory if no path is specified.
Work file location path : Work file location path :
# When processing code line differentials, ignore # When processing code line differentials, ignore
# blank line changes in the code. # blank line changes in the code.
@ -261,7 +261,7 @@ Maximum Function Name Length : 32
# Emit a quality notice when a file does not contain # Emit a quality notice when a file does not contain
# the specified key string. # the specified key string.
Quality Notice 21 : No Quality Notice 21 : No
RSM KEY String : RSM KEY String :
# RSM Quality Notices For Stability and Maintainability ################ # RSM Quality Notices For Stability and Maintainability ################
@ -492,13 +492,13 @@ Min. Class/Struct LOC content analysis : 10
# or interface white space percentage is less than # or interface white space percentage is less than
# the specified minimum. # the specified minimum.
Quality Notice 16 : Yes Quality Notice 16 : Yes
Minimum Function Whitespace Percent : 10.00 Minimum Function Whitespace Percent : 10.00
# Quality Notice No. 17 # Quality Notice No. 17
# Emit a quality notice when function comment line # Emit a quality notice when function comment line
# percentage is less than the specified minimum. # percentage is less than the specified minimum.
Quality Notice 17 : No Quality Notice 17 : No
Minimum Function Comment Line Percent : 10.00 Minimum Function Comment Line Percent : 10.00
# Quality Notice No. 18 # Quality Notice No. 18
# Emit a quality notice when the eLOC within a # Emit a quality notice when the eLOC within a
@ -517,14 +517,14 @@ Minimum Function lLOC : 0
# Emit a quality notice when class/struct comment line # Emit a quality notice when class/struct comment line
# percentage is less than the specified minimum. # percentage is less than the specified minimum.
Quality Notice 31 : Yes Quality Notice 31 : Yes
Minimum Class/Struct Comment Percent : 10.00 Minimum Class/Struct Comment Percent : 10.00
# Quality Notice No. 46 # Quality Notice No. 46
# Emit a quality notice when function, struct, class # Emit a quality notice when function, struct, class
# or interface blank line percentage is less than the # or interface blank line percentage is less than the
# specified minimum. # specified minimum.
Quality Notice 46 : No Quality Notice 46 : No
Minimum Function Blank Line Percent : 10.00 Minimum Function Blank Line Percent : 10.00
# Quality Notice No. 51 # Quality Notice No. 51
# Emit a quality notice when a function # Emit a quality notice when a function
@ -553,20 +553,20 @@ Quality Notice 54 : Yes
# percentage is less than the specified minimum. # percentage is less than the specified minimum.
# Consider setting Notice 30 to No. # Consider setting Notice 30 to No.
Quality Notice 19 : Yes Quality Notice 19 : Yes
Minimum File Whitespace Percent : 10.00 Minimum File Whitespace Percent : 10.00
A TAB is equivalent to n space : 2 A TAB is equivalent to n space : 2
# Quality Notice No. 20 # Quality Notice No. 20
# Emit a quality notice when file comment line # Emit a quality notice when file comment line
# percentage is less than the specified minimum. # percentage is less than the specified minimum.
Quality Notice 20 : Yes Quality Notice 20 : Yes
Minimum File Comment Line Percent : 10.00 Minimum File Comment Line Percent : 10.00
# Quality Notice No. 47 # Quality Notice No. 47
# Emit a quality notice when file blank line # Emit a quality notice when file blank line
# percentage is less than the specified minimum. # percentage is less than the specified minimum.
Quality Notice 47 : No Quality Notice 47 : No
Minimum File Blank Line Percent : 10.00 Minimum File Blank Line Percent : 10.00
# Quality Notice No. 57 # Quality Notice No. 57
# Emit a quality notice when RSM skip lines conditions # Emit a quality notice when RSM skip lines conditions

View File

@ -1,4 +1,6 @@
#include "qpc.h" #include "qpc.h"
#include "dpp.h"
#include "bsp.h"
Q_DEFINE_THIS_FILE Q_DEFINE_THIS_FILE
@ -7,7 +9,7 @@ int main(void) {
QF_init(); /* initialize the framework and the underlying RT kernel */ QF_init(); /* initialize the framework and the underlying RT kernel */
BSP_init(); /* initialize the BSP */ BSP_init(); /* initialize the BSP */
/* init publish-subscribe... */ /* initialize publish-subscribe... */
static QSubscrList l_subscrSto[MAX_PUB_SIG]; static QSubscrList l_subscrSto[MAX_PUB_SIG];
QF_psInit(l_subscrSto, Q_DIM(l_subscrSto)); QF_psInit(l_subscrSto, Q_DIM(l_subscrSto));
@ -20,17 +22,23 @@ int main(void) {
static QEvt const *l_philoQueueSto[N_PHILO][N_PHILO]; static QEvt const *l_philoQueueSto[N_PHILO][N_PHILO];
for (uint8_t n = 0U; n < N_PHILO; ++n) { for (uint8_t n = 0U; n < N_PHILO; ++n) {
QACTIVE_START(AO_Philo[n], (uint8_t)(n + 1), QACTIVE_START(AO_Philo[n],
l_philoQueueSto[n], Q_DIM(l_philoQueueSto[n]), Q_PRIO(n + 1U, N_PHILO), /* QF-priority/preemption-threshold */
(void *)0, 0U, (QEvt *)0); l_philoQueueSto[n], /* event queue storage */
Q_DIM(l_philoQueueSto[n]),/* event queue length [events] */
(void *)0, /* stack storage (not used) */
0U, /* stack size [bytes] (not used) */
(void *)0); /* initialization parameter (not used) */
} }
Table_ctor(); /* instantiate the Table active object */ Table_ctor(); /* instantiate the Table active object */
static QEvt const *l_tableQueueSto[N_PHILO]; static QEvt const *l_tableQueueSto[N_PHILO];
QACTIVE_START(AO_Table, (uint8_t)(N_PHILO + 1), QACTIVE_START(AO_Table,
l_tableQueueSto, Q_DIM(l_tableQueueSto), N_PHILO + 1U , /* QF-priority/preemption-threshold */
(void *)0, 0U, (QEvt *)0); l_tableQueueSto, Q_DIM(l_tableQueueSto),
(void *)0, 0U,
(void *)0);
return QF_run(); /* run the QF application, QF_run() does not return */ return QF_run(); /* run the QF application, QF_run() does not return */
} }

View File

@ -15,24 +15,24 @@ int main() {
/* start the active objects (basic threads)... */ /* start the active objects (basic threads)... */
Table_ctor(); /* instantiate the Table AO */ Table_ctor(); /* instantiate the Table AO */
QACTIVE_START(AO_Table, /* AO to start */ QACTIVE_START(AO_Table, /* AO to start */
N_PHILO + 2U, /* QP priority of the AO */ n + 1U, /* QF-priority */
tableQueueSto, /* event queue storage */ tableQueueSto, /* event queue storage */
Q_DIM(tableQueueSto), /* queue length [events] */ Q_DIM(tableQueueSto), /* queue length [events] */
tableStackSto, /* stack storage */ tableStackSto, /* stack storage */
sizeof(tableStackSto), /* stack size [bytes] */ sizeof(tableStackSto), /* stack size [bytes] */
(void *)0); /* initialization param */ (void *)0); /* initialization param */
. . . . . .
/* start the extended-threads... */ /* start the extended-threads... */
Test_ctor(); /* instantiate the Test extended thread */ Test_ctor(); /* instantiate the Test extended thread */
QXTHREAD_START(XT_Test, /* Thread to start */ QXTHREAD_START(XT_Test, /* Thread to start */
10U, /* QP priority of the thread */ 10U, /* QF-priority */
testQueueSto, /* message queue storage */ testQueueSto, /* message queue storage */
Q_DIM(testQueueSto), /* message length [events] */ Q_DIM(testQueueSto), /* message length [events] */
testStackSto, /* stack storage */ testStackSto, /* stack storage */
sizeof(testStackSto), /* stack size [bytes] */ sizeof(testStackSto), /* stack size [bytes] */
(void *)0); /* initialization param */ (void *)0); /* initialization param */
return QF_run(); /* run the QF application */ return QF_run(); /* run the QF application */
} }

View File

@ -6,12 +6,10 @@ QXThread blinky; /* QXK extended-thread object */
void main_blinky(QXThread * const me) { /* thread function */ void main_blinky(QXThread * const me) { /* thread function */
while (1) { while (1) {
uint32_t volatile i; BSP_ledOn();
for (i = 1500U; i != 0U; --i) { QXThread_delay(100U); /* BLOCK */
BSP_ledGreenOn(); BSP_ledOff();
BSP_ledGreenOff(); QXThread_delay(200U); /* BLOCK */
}
QXThread_delay(1U); /* block for 1 tick */
} }
} }
@ -20,7 +18,7 @@ int main() {
/* initialize and start blinky thread */ /* initialize and start blinky thread */
QXThread_ctor(&blinky, &main_blinky, 0); QXThread_ctor(&blinky, &main_blinky, 0);
static uint32_t stack_blinky[80]; /* stack for the thread */ static uint64_t stack_blinky[40]; /* stack for the thread */
QXTHREAD_START(&blinky, QXTHREAD_START(&blinky,
5U, /* priority */ 5U, /* priority */
(void *)0, 0, /* message queue (not used) */ (void *)0, 0, /* message queue (not used) */

View File

@ -1,20 +0,0 @@
@subpage gs "&nbsp;"
@subpage srs "&nbsp;"
@subpage struct "&nbsp;"
@subpage api "&nbsp;"
@subpage exa "&nbsp;"
@subpage exa_native "&nbsp;"
@subpage exa_low-power "&nbsp;"
@subpage exa_rtos "&nbsp;"
@subpage exa_os "&nbsp;"
@subpage exa_qutest "&nbsp;"
@subpage exa_mware "&nbsp;"
@subpage ports "&nbsp;"
@subpage ports_native "&nbsp;"
@subpage ports_rtos "&nbsp;"
@subpage ports_os "&nbsp;"
@subpage ports_lint "&nbsp;"
@subpage traceability "&nbsp;"
@subpage history "&nbsp;"
@subpage help "&nbsp;"

View File

@ -1,36 +0,0 @@
About this Example
==================
This directory contains a QP example application for the
EFM32-SLSTK3401A board (Pearl Gecko Starter Kit). This directory
contains portable code that should compile with any C compiler for
ARM Cortex-M.
The sub-directories contain code and project files, which are specific
to the particular ARM toolchains, such as ARM (MDK-ARM), GNU, and IAR.
Please refer to the README files in the sub-directories for specific
instructions how to use and customize the example to your needs.
Support Code for EFM32-SLSTK3401A Board
=======================================
The directory qpc\3rd_party\efm32pg1b contains the CMSIS-compliant
device code for the EFM32PG1B200F256GM48 MCU. Please see the README.txt
file in this folder for more details.
QS Software Tracing Instrumentation
-----------------------------------
This example provides the "Spy" build configuration, which outputs the QS
(Quantum Spy) software tracing data through UART0, which is connected to
the virtual COM port of the TI Stellaris debugger.
The output is generated at 115200 baud rate.
Here is an example invocation of the QSPY host application to receive
the QS data from EFM32-SLSTK3401A:
qspy -cCOM1
The actual COM port number might be different on your Windows machine.
Please check the Device Manager to find the COM port number.

View File

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
* Product: "Blinky" example * Product: "Blinky" example
* Last updated for version 6.4.0 * Last updated for version 7.1.1
* Last updated on 2019-02-08 * Last updated on 2022-09-22
* *
* Q u a n t u m L e a P s * Q u a n t u m L e a P s
* ------------------------ * ------------------------
@ -39,8 +39,6 @@ Q_DEFINE_THIS_FILE
/*..........................................................................*/ /*..........................................................................*/
int main() { int main() {
static QEvt const *l_blinkyQSto[10]; /* Event queue storage for Blinky */
QF_init(); /* initialize the framework and the underlying RT kernel */ QF_init(); /* initialize the framework and the underlying RT kernel */
BSP_init(); /* initialize the Board Support Package */ BSP_init(); /* initialize the Board Support Package */
@ -49,10 +47,11 @@ int main() {
/* instantiate and start the active objects... */ /* instantiate and start the active objects... */
Blinky_ctor(); Blinky_ctor();
static QEvt const *l_blinkyQSto[10]; /* Event queue storage for Blinky */
QACTIVE_START(AO_Blinky, /* AO pointer to start */ QACTIVE_START(AO_Blinky, /* AO pointer to start */
1U, /* unique QP priority of the AO */ 2U, /* QF-priority/preemption-threshold */
l_blinkyQSto, /* storage for the AO's queue */ l_blinkyQSto, /* storage for the AO's queue */
Q_DIM(l_blinkyQSto), /* lenght of the queue [entries] */ Q_DIM(l_blinkyQSto), /* length of the queue [entries] */
(void *)0, /* stack storage (not used in QK) */ (void *)0, /* stack storage (not used in QK) */
0U, /* stack size [bytes] (not used in QK) */ 0U, /* stack size [bytes] (not used in QK) */
(QEvt *)0); /* initial event (or 0) */ (QEvt *)0); /* initial event (or 0) */

View File

@ -355,7 +355,7 @@
<ClangAsOpt>4</ClangAsOpt> <ClangAsOpt>4</ClangAsOpt>
<VariousControls> <VariousControls>
<MiscControls></MiscControls> <MiscControls></MiscControls>
<Define>Stack_Size=1024 Heap_Size=16</Define> <Define>Stack_Size=2048 Heap_Size=16</Define>
<Undefine></Undefine> <Undefine></Undefine>
<IncludePath></IncludePath> <IncludePath></IncludePath>
</VariousControls> </VariousControls>
@ -980,7 +980,7 @@
<ClangAsOpt>4</ClangAsOpt> <ClangAsOpt>4</ClangAsOpt>
<VariousControls> <VariousControls>
<MiscControls></MiscControls> <MiscControls></MiscControls>
<Define>Stack_Size=1024 Heap_Size=16</Define> <Define>Stack_Size=2048 Heap_Size=16</Define>
<Undefine></Undefine> <Undefine></Undefine>
<IncludePath></IncludePath> <IncludePath></IncludePath>
</VariousControls> </VariousControls>
@ -1605,7 +1605,7 @@
<ClangAsOpt>4</ClangAsOpt> <ClangAsOpt>4</ClangAsOpt>
<VariousControls> <VariousControls>
<MiscControls></MiscControls> <MiscControls></MiscControls>
<Define>Stack_Size=1024 Heap_Size=16</Define> <Define>Stack_Size=2048 Heap_Size=16</Define>
<Undefine></Undefine> <Undefine></Undefine>
<IncludePath></IncludePath> <IncludePath></IncludePath>
</VariousControls> </VariousControls>

View File

@ -41,7 +41,7 @@ MEMORY { /* memory map of Pearl Gecko EFM32PG1B200F256GM48 */
} }
/* The size of the stack used by the application. NOTE: you need to adjust */ /* The size of the stack used by the application. NOTE: you need to adjust */
STACK_SIZE = 1024; STACK_SIZE = 2048;
/* The size of the heap used by the application. NOTE: you need to adjust */ /* The size of the heap used by the application. NOTE: you need to adjust */
HEAP_SIZE = 0; HEAP_SIZE = 0;

View File

@ -1,13 +1,13 @@
::============================================================================ ::============================================================================
:: Batch file to program the flash of EFM32-SLSTK3401A board :: Batch file to program the flash of EFM32-SLSTK3401A board
:: ::
:: NOTE: requires the J-Link commander (JLink.exe) from SEGGER, see: :: NOTE: requires the J-Link commander (JLink.exe) from SEGGER, see:
:: https://www.segger.com/j-link-commander.html :: https://www.segger.com/j-link-commander.html
:: ::
setlocal setlocal
@echo off @echo off
@echo Load a given binary file to the flash of EFM32-SLSTK3401A @echo Load a given binary file to the flash of EFM32-SLSTK3401A
@echo usage: flash bin-file @echo usage: flash bin-file
@echo example: flash dbg\blinky-qk.bin @echo example: flash dbg\blinky-qk.bin
@ -17,7 +17,7 @@ setlocal
:: ::
if [%JLINK%] EQU [] set JLINK=%QTOOLS%\..\JLink if [%JLINK%] EQU [] set JLINK=%QTOOLS%\..\JLink
if not exist "%JLINK%\JLink.exe" ( if not exist "%JLINK%\JLink.exe" (
@echo The JLink tool not found. Please adjust flash.bat @echo The JLink tool not found. Please adjust flash.bat
@goto end @goto end
) )

View File

@ -9,7 +9,7 @@ define symbol __ICFEDIT_region_ROM_end__ = 0x0003FFFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__ = 0x20007FFF; define symbol __ICFEDIT_region_RAM_end__ = 0x20007FFF;
/*-Sizes-*/ /*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 1024; define symbol __ICFEDIT_size_cstack__ = 2048;
define symbol __ICFEDIT_size_heap__ = 0; define symbol __ICFEDIT_size_heap__ = 0;
/**** End of ICF editor section. ###ICF###*/ /**** End of ICF editor section. ###ICF###*/
@ -25,5 +25,5 @@ do not initialize { section .noinit };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in ROM_region { readonly }; place in ROM_region { readonly };
place at start of RAM_region {block CSTACK }; place at start of RAM_region {block CSTACK };
place in RAM_region { readwrite, block HEAP }; place in RAM_region { readwrite, block HEAP };

View File

@ -354,7 +354,7 @@
<uClangAs>0</uClangAs> <uClangAs>0</uClangAs>
<VariousControls> <VariousControls>
<MiscControls></MiscControls> <MiscControls></MiscControls>
<Define>Stack_Size=1024 Heap_Size=16</Define> <Define>Stack_Size=2048 Heap_Size=16</Define>
<Undefine></Undefine> <Undefine></Undefine>
<IncludePath></IncludePath> <IncludePath></IncludePath>
</VariousControls> </VariousControls>
@ -978,7 +978,7 @@
<uClangAs>0</uClangAs> <uClangAs>0</uClangAs>
<VariousControls> <VariousControls>
<MiscControls></MiscControls> <MiscControls></MiscControls>
<Define>Stack_Size=1024 Heap_Size=16</Define> <Define>Stack_Size=2048 Heap_Size=16</Define>
<Undefine></Undefine> <Undefine></Undefine>
<IncludePath></IncludePath> <IncludePath></IncludePath>
</VariousControls> </VariousControls>
@ -1602,7 +1602,7 @@
<uClangAs>0</uClangAs> <uClangAs>0</uClangAs>
<VariousControls> <VariousControls>
<MiscControls></MiscControls> <MiscControls></MiscControls>
<Define>Stack_Size=1024 Heap_Size=16</Define> <Define>Stack_Size=2048 Heap_Size=16</Define>
<Undefine></Undefine> <Undefine></Undefine>
<IncludePath></IncludePath> <IncludePath></IncludePath>
</VariousControls> </VariousControls>

View File

@ -41,7 +41,7 @@ MEMORY { /* memory map of Pearl Gecko EFM32PG1B200F256GM48 */
} }
/* The size of the stack used by the application. NOTE: you need to adjust */ /* The size of the stack used by the application. NOTE: you need to adjust */
STACK_SIZE = 1024; STACK_SIZE = 2048;
/* The size of the heap used by the application. NOTE: you need to adjust */ /* The size of the heap used by the application. NOTE: you need to adjust */
HEAP_SIZE = 0; HEAP_SIZE = 0;

View File

@ -1,13 +1,13 @@
::============================================================================ ::============================================================================
:: Batch file to program the flash of EFM32-SLSTK3401A board :: Batch file to program the flash of EFM32-SLSTK3401A board
:: ::
:: NOTE: requires the J-Link commander (JLink.exe) from SEGGER, see: :: NOTE: requires the J-Link commander (JLink.exe) from SEGGER, see:
:: https://www.segger.com/j-link-commander.html :: https://www.segger.com/j-link-commander.html
:: ::
setlocal setlocal
@echo off @echo off
@echo Load a given binary file to the flash of EFM32-SLSTK3401A @echo Load a given binary file to the flash of EFM32-SLSTK3401A
@echo usage: flash bin-file @echo usage: flash bin-file
@echo example: flash dbg\blinky-qk.bin @echo example: flash dbg\blinky-qk.bin
@ -17,7 +17,7 @@ setlocal
:: ::
if [%JLINK%] EQU [] set JLINK=%QTOOLS%\..\JLink if [%JLINK%] EQU [] set JLINK=%QTOOLS%\..\JLink
if not exist "%JLINK%\JLink.exe" ( if not exist "%JLINK%\JLink.exe" (
@echo The JLink tool not found. Please adjust flash.bat @echo The JLink tool not found. Please adjust flash.bat
@goto end @goto end
) )

View File

@ -25,5 +25,5 @@ do not initialize { section .noinit };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in ROM_region { readonly }; place in ROM_region { readonly };
place at start of RAM_region {block CSTACK }; place at start of RAM_region {block CSTACK };
place in RAM_region { readwrite, block HEAP }; place in RAM_region { readwrite, block HEAP };

View File

@ -1,37 +0,0 @@
About this Example
==================
This directory contains the simple "Blinky" QP example application for
the EK-TM4C123GXL board (TivaC LauchPad) with the coopertative QV kernel
and the preemptive QK kernel. This directory contains portable code that
should compile with any C compiler for ARM Cortex-M.
The sub-directories contain code and project files, which are specific
to the particular ARM toolchains, such as ARM (MDK-ARM), GNU, and IAR.
Please refer to the README files in the sub-directories for specific
instructions how to use and customize the example to your needs.
Support Code for EK-TM4C123GXL Board
====================================
The directory qpc\3rd_party\ek-tm4c123gxl contains the CMSIS-compliant
device code for the TM4C123GH6PM MCU. Please see the README.txt file in
this folder for more details.
QS Software Tracing Instrumentation
-----------------------------------
This example provides the "Spy" build configuration, which outputs the QS
(Quantum Spy) software tracing data through UART0, which is connected to
the virtual COM port of the TI Stellaris debugger.
The output is generated at 115200 baud rate.
Here is an example invocation of the QSPY host application to receive
the QS data from EK-TM4C123GXL:
qspy -cCOM1
The actual COM port number might be different on your Windows machine.
Please check the Device Manager to find the COM port number.

View File

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
* Product: "Blinky" example * Product: "Blinky" example
* Last updated for version 6.4.0 * Last updated for version 7.1.1
* Last updated on 2019-02-08 * Last updated on 2022-09-22
* *
* Q u a n t u m L e a P s * Q u a n t u m L e a P s
* ------------------------ * ------------------------
@ -39,8 +39,6 @@ Q_DEFINE_THIS_FILE
/*..........................................................................*/ /*..........................................................................*/
int main() { int main() {
static QEvt const *l_blinkyQSto[10]; /* Event queue storage for Blinky */
QF_init(); /* initialize the framework and the underlying RT kernel */ QF_init(); /* initialize the framework and the underlying RT kernel */
BSP_init(); /* initialize the Board Support Package */ BSP_init(); /* initialize the Board Support Package */
@ -49,10 +47,11 @@ int main() {
/* instantiate and start the active objects... */ /* instantiate and start the active objects... */
Blinky_ctor(); Blinky_ctor();
static QEvt const *l_blinkyQSto[10]; /* Event queue storage for Blinky */
QACTIVE_START(AO_Blinky, /* AO pointer to start */ QACTIVE_START(AO_Blinky, /* AO pointer to start */
1U, /* unique QP priority of the AO */ 2U, /* QF-priority/preemption-threshold */
l_blinkyQSto, /* storage for the AO's queue */ l_blinkyQSto, /* storage for the AO's queue */
Q_DIM(l_blinkyQSto), /* lenght of the queue [entries] */ Q_DIM(l_blinkyQSto), /* length of the queue [entries] */
(void *)0, /* stack storage (not used in QK) */ (void *)0, /* stack storage (not used in QK) */
0U, /* stack size [bytes] (not used in QK) */ 0U, /* stack size [bytes] (not used in QK) */
(QEvt *)0); /* initial event (or 0) */ (QEvt *)0); /* initial event (or 0) */

View File

@ -354,7 +354,7 @@
<uClangAs>0</uClangAs> <uClangAs>0</uClangAs>
<VariousControls> <VariousControls>
<MiscControls></MiscControls> <MiscControls></MiscControls>
<Define>Stack_Size=1024 Heap_Size=16</Define> <Define>Stack_Size=2048 Heap_Size=16</Define>
<Undefine></Undefine> <Undefine></Undefine>
<IncludePath></IncludePath> <IncludePath></IncludePath>
</VariousControls> </VariousControls>
@ -973,7 +973,7 @@
<uClangAs>0</uClangAs> <uClangAs>0</uClangAs>
<VariousControls> <VariousControls>
<MiscControls></MiscControls> <MiscControls></MiscControls>
<Define>Stack_Size=1024 Heap_Size=16</Define> <Define>Stack_Size=2048 Heap_Size=16</Define>
<Undefine></Undefine> <Undefine></Undefine>
<IncludePath></IncludePath> <IncludePath></IncludePath>
</VariousControls> </VariousControls>
@ -1592,7 +1592,7 @@
<uClangAs>0</uClangAs> <uClangAs>0</uClangAs>
<VariousControls> <VariousControls>
<MiscControls></MiscControls> <MiscControls></MiscControls>
<Define>Stack_Size=1024 Heap_Size=16</Define> <Define>Stack_Size=2048 Heap_Size=16</Define>
<Undefine></Undefine> <Undefine></Undefine>
<IncludePath></IncludePath> <IncludePath></IncludePath>
</VariousControls> </VariousControls>

View File

@ -41,7 +41,7 @@ MEMORY { /* memory map of Tiva TM4C123GH6PM */
} }
/* The size of the stack used by the application. NOTE: you need to adjust */ /* The size of the stack used by the application. NOTE: you need to adjust */
STACK_SIZE = 1024; STACK_SIZE = 2048;
/* The size of the heap used by the application. NOTE: you need to adjust */ /* The size of the heap used by the application. NOTE: you need to adjust */
HEAP_SIZE = 0; HEAP_SIZE = 0;

View File

@ -1,8 +1,8 @@
::============================================================================ ::============================================================================
:: Batch file to program the flash of EK-TM4C123GXL :: Batch file to program the flash of EK-TM4C123GXL
:: ::
:: NOTE: requires the LMFlash programmer (included in QTools for Windows) :: NOTE: requires the LMFlash programmer (included in QTools for Windows)
:: ::
@echo off @echo off
setlocal setlocal

View File

@ -9,7 +9,7 @@ define symbol __ICFEDIT_region_ROM_end__ = 0x0003FFFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__ = 0x20007FFF; define symbol __ICFEDIT_region_RAM_end__ = 0x20007FFF;
/*-Sizes-*/ /*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 1024; define symbol __ICFEDIT_size_cstack__ = 2048;
define symbol __ICFEDIT_size_heap__ = 0; define symbol __ICFEDIT_size_heap__ = 0;
/**** End of ICF editor section. ###ICF###*/ /**** End of ICF editor section. ###ICF###*/
@ -25,5 +25,5 @@ do not initialize { section .noinit };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in ROM_region { readonly }; place in ROM_region { readonly };
place at start of RAM_region {block CSTACK }; place at start of RAM_region {block CSTACK };
place in RAM_region { readwrite, block HEAP }; place in RAM_region { readwrite, block HEAP };

View File

@ -355,7 +355,7 @@
<ClangAsOpt>4</ClangAsOpt> <ClangAsOpt>4</ClangAsOpt>
<VariousControls> <VariousControls>
<MiscControls></MiscControls> <MiscControls></MiscControls>
<Define>Stack_Size=1024 Heap_Size=16</Define> <Define>Stack_Size=2048 Heap_Size=16</Define>
<Undefine></Undefine> <Undefine></Undefine>
<IncludePath></IncludePath> <IncludePath></IncludePath>
</VariousControls> </VariousControls>
@ -975,7 +975,7 @@
<ClangAsOpt>4</ClangAsOpt> <ClangAsOpt>4</ClangAsOpt>
<VariousControls> <VariousControls>
<MiscControls></MiscControls> <MiscControls></MiscControls>
<Define>Stack_Size=1024 Heap_Size=16</Define> <Define>Stack_Size=2048 Heap_Size=16</Define>
<Undefine></Undefine> <Undefine></Undefine>
<IncludePath></IncludePath> <IncludePath></IncludePath>
</VariousControls> </VariousControls>
@ -1595,7 +1595,7 @@
<ClangAsOpt>4</ClangAsOpt> <ClangAsOpt>4</ClangAsOpt>
<VariousControls> <VariousControls>
<MiscControls></MiscControls> <MiscControls></MiscControls>
<Define>Stack_Size=1024 Heap_Size=16</Define> <Define>Stack_Size=2048 Heap_Size=16</Define>
<Undefine></Undefine> <Undefine></Undefine>
<IncludePath></IncludePath> <IncludePath></IncludePath>
</VariousControls> </VariousControls>

View File

@ -41,7 +41,7 @@ MEMORY { /* memory map of Tiva TM4C123GH6PM */
} }
/* The size of the stack used by the application. NOTE: you need to adjust */ /* The size of the stack used by the application. NOTE: you need to adjust */
STACK_SIZE = 1024; STACK_SIZE = 2048;
/* The size of the heap used by the application. NOTE: you need to adjust */ /* The size of the heap used by the application. NOTE: you need to adjust */
HEAP_SIZE = 0; HEAP_SIZE = 0;

View File

@ -1,8 +1,8 @@
::============================================================================ ::============================================================================
:: Batch file to program the flash of EK-TM4C123GXL :: Batch file to program the flash of EK-TM4C123GXL
:: ::
:: NOTE: requires the LMFlash programmer (included in QTools for Windows) :: NOTE: requires the LMFlash programmer (included in QTools for Windows)
:: ::
@echo off @echo off
setlocal setlocal

View File

@ -9,7 +9,7 @@ define symbol __ICFEDIT_region_ROM_end__ = 0x0003FFFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__ = 0x20007FFF; define symbol __ICFEDIT_region_RAM_end__ = 0x20007FFF;
/*-Sizes-*/ /*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 1024; define symbol __ICFEDIT_size_cstack__ = 2048;
define symbol __ICFEDIT_size_heap__ = 0; define symbol __ICFEDIT_size_heap__ = 0;
/**** End of ICF editor section. ###ICF###*/ /**** End of ICF editor section. ###ICF###*/
@ -25,5 +25,5 @@ do not initialize { section .noinit };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in ROM_region { readonly }; place in ROM_region { readonly };
place at start of RAM_region {block CSTACK }; place at start of RAM_region {block CSTACK };
place in RAM_region { readwrite, block HEAP }; place in RAM_region { readwrite, block HEAP };

View File

@ -1,78 +0,0 @@
About this Example
==================
This directory contains a QP example application for the
EFM32-SLSTK3401A board (Pearl Gecko Starter Kit). This directory
contains portable code that should compile with any C compiler for
ARM Cortex-M.
The sub-directories contain code and project files, which are specific
to the particular ARM toolchains, such as ARM (MDK-ARM), GNU, and IAR.
Please refer to the README files in the sub-directories for specific
instructions how to use and customize the example to your needs.
Support Code for EFM32-SLSTK3401A Board
=======================================
The directory 3rd_party\efm32pg1b contains the CMSIS-compliant
device code for the EFM32PG1B200F256GM48 MCU. Please see the README.txt
file in this folder for more details.
QS Software Tracing Instrumentation
-----------------------------------
This example provides the "Spy" build configuration, which outputs the QS
(Quantum Spy) software tracing data through UART0, which is connected to
the virtual COM port of the TI Stellaris debugger.
The output is generated at 115200 baud rate.
Here is an example invocation of the QSPY host application to receive
the QS data from EFM32-SLSTK3401A:
qspy -u -c COM1 (Windows)
qspy -u -c /dev/ttyS1 (POSIX)
The actual serial-port number might be different on your workstation.
Please check the Device Manager to find the COM port number.
Win32-GUI Emulation
===================
The sub-directory "win32-gui" provides the emulation of the example
on Windows GUI, either single-threaded (win32-qv) or multithreded (win32).
This sub-directory contains the Makefile for the GNU-GCC toolset (MinGW)
and Visual Studio solution file (dpp-gui.sln) for Visual C++.
The Win32-GUI emulation is based on the QWin<69> GUI Prototyping Toolkit, see:
https://www.state-machine.com/qtools/qwin.html
The emulation uses exactly the same code as the embedded board and differs
only in the Board Support Package (bsp.c). This example demonstrates the
"dual targeting" development approach, where most of the embedded code is
developed on the workstation (Windows), but is intended for a deeply
embedded target (EFM32-SLSTK3401A here).
QS Software Tracing Instrumentation
-----------------------------------
The "win32-gui" emulation also supports the "Spy" build configuration,
in which case it attempts to connect to the QSPY host application via
a TCP/IP socket. This requires launching the QSPY host application with
the command-line parameter -t
qspy -u -t
QSpyView Visualization
======================
The sub-directory "qspyview" provides the QSpyView Visualization
example for the DPP application, see:
https://www.state-machine.com/qtools/qspyview.html
This QSpyView Visualization works with all versions of the software
running in the Spy build configuration, including the code for the
EFM32-SLSTK3401A board and the Win32-GUI emulation.

View File

@ -3,7 +3,7 @@
* Model: dpp.qm * Model: dpp.qm
* File: ${.::dpp.h} * File: ${.::dpp.h}
* *
* This code has been generated by QM 5.2.1 <www.state-machine.com/qm>. * This code has been generated by QM 5.2.2 <www.state-machine.com/qm>.
* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. * DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
* *
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
@ -83,12 +83,12 @@ void Philo_ctor(uint8_t n);
extern QActive * const AO_Philo[N_PHILO]; extern QActive * const AO_Philo[N_PHILO];
/*$enddecl${AOs::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ /*$enddecl${AOs::AO_Philo[N_PHILO]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
#ifdef QXK_H #ifdef QP_INC_QXK_H_
void Test1_ctor(void); void Test1_ctor(void);
extern QXThread * const XT_Test1; extern QXThread * const XT_Test1;
void Test2_ctor(void); void Test2_ctor(void);
extern QXThread * const XT_Test2; extern QXThread * const XT_Test2;
#endif /* QXK_H */ #endif /* QP_INC_QXK_H_ */
#endif /* DPP_H */ #endif /* DPP_H */

View File

@ -23,7 +23,7 @@
<statechart properties="0x01"> <statechart properties="0x01">
<!--${AOs::Philo::SM::initial}--> <!--${AOs::Philo::SM::initial}-->
<initial target="../1"> <initial target="../1">
<action>(void)par; /* unused parameter */ <action>Q_UNUSED_PAR(par);
static bool registered = false; static bool registered = false;
if (!registered) { if (!registered) {
@ -34,16 +34,10 @@ if (!registered) {
QS_FUN_DICTIONARY(&amp;Philo_hungry); QS_FUN_DICTIONARY(&amp;Philo_hungry);
QS_FUN_DICTIONARY(&amp;Philo_eating); QS_FUN_DICTIONARY(&amp;Philo_eating);
QS_OBJ_DICTIONARY(&amp;Philo_inst[0]); for (uint8_t n = 0U; n &lt; N_PHILO; ++n) {
QS_OBJ_DICTIONARY(&amp;Philo_inst[0].timeEvt); QS_OBJ_ARR_DICTIONARY(&amp;Philo_inst[n], n);
QS_OBJ_DICTIONARY(&amp;Philo_inst[1]); QS_OBJ_ARR_DICTIONARY(&amp;Philo_inst[n].timeEvt, n);
QS_OBJ_DICTIONARY(&amp;Philo_inst[1].timeEvt); }
QS_OBJ_DICTIONARY(&amp;Philo_inst[2]);
QS_OBJ_DICTIONARY(&amp;Philo_inst[2].timeEvt);
QS_OBJ_DICTIONARY(&amp;Philo_inst[3]);
QS_OBJ_DICTIONARY(&amp;Philo_inst[3].timeEvt);
QS_OBJ_DICTIONARY(&amp;Philo_inst[4]);
QS_OBJ_DICTIONARY(&amp;Philo_inst[4].timeEvt);
} }
QActive_subscribe(&amp;me-&gt;super, EAT_SIG); QActive_subscribe(&amp;me-&gt;super, EAT_SIG);
@ -155,6 +149,7 @@ QS_OBJ_DICTIONARY(&amp;Table_inst);
QActive_subscribe(&amp;me-&gt;super, DONE_SIG); QActive_subscribe(&amp;me-&gt;super, DONE_SIG);
QActive_subscribe(&amp;me-&gt;super, PAUSE_SIG); QActive_subscribe(&amp;me-&gt;super, PAUSE_SIG);
QActive_subscribe(&amp;me-&gt;super, SERVE_SIG); QActive_subscribe(&amp;me-&gt;super, SERVE_SIG);
QActive_subscribe(&amp;me-&gt;super, EAT_SIG); //???
QActive_subscribe(&amp;me-&gt;super, TEST_SIG); QActive_subscribe(&amp;me-&gt;super, TEST_SIG);
for (uint8_t n = 0U; n &lt; N_PHILO; ++n) { for (uint8_t n = 0U; n &lt; N_PHILO; ++n) {
@ -170,7 +165,7 @@ for (uint8_t n = 0U; n &lt; N_PHILO; ++n) {
<state name="active"> <state name="active">
<!--${AOs::Table::SM::active::EAT}--> <!--${AOs::Table::SM::active::EAT}-->
<tran trig="EAT"> <tran trig="EAT">
<action>Q_ERROR_ID(60);</action> <action>//???Q_ERROR_ID(60);</action>
<tran_glyph conn="2,15,3,-1,14"> <tran_glyph conn="2,15,3,-1,14">
<action box="0,-2,17,4"/> <action box="0,-2,17,4"/>
</tran_glyph> </tran_glyph>
@ -399,12 +394,12 @@ $declare${AOs::AO_Table}
$declare${AOs::Philo_ctor} $declare${AOs::Philo_ctor}
$declare${AOs::AO_Philo[N_PHILO]} $declare${AOs::AO_Philo[N_PHILO]}
#ifdef QXK_H #ifdef QP_INC_QXK_H_
void Test1_ctor(void); void Test1_ctor(void);
extern QXThread * const XT_Test1; extern QXThread * const XT_Test1;
void Test2_ctor(void); void Test2_ctor(void);
extern QXThread * const XT_Test2; extern QXThread * const XT_Test2;
#endif /* QXK_H */ #endif /* QP_INC_QXK_H_ */
#endif /* DPP_H */ #endif /* DPP_H */
</text> </text>

View File

@ -3,7 +3,7 @@
* Model: dpp.qm * Model: dpp.qm
* File: ${.::philo.c} * File: ${.::philo.c}
* *
* This code has been generated by QM 5.2.1 <www.state-machine.com/qm>. * This code has been generated by QM 5.2.2 <www.state-machine.com/qm>.
* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. * DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
* *
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
@ -103,7 +103,7 @@ Philo Philo_inst[N_PHILO];
/*${AOs::Philo::SM} ........................................................*/ /*${AOs::Philo::SM} ........................................................*/
static QState Philo_initial(Philo * const me, void const * const par) { static QState Philo_initial(Philo * const me, void const * const par) {
/*${AOs::Philo::SM::initial} */ /*${AOs::Philo::SM::initial} */
(void)par; /* unused parameter */ Q_UNUSED_PAR(par);
static bool registered = false; static bool registered = false;
if (!registered) { if (!registered) {
@ -114,16 +114,10 @@ static QState Philo_initial(Philo * const me, void const * const par) {
QS_FUN_DICTIONARY(&Philo_hungry); QS_FUN_DICTIONARY(&Philo_hungry);
QS_FUN_DICTIONARY(&Philo_eating); QS_FUN_DICTIONARY(&Philo_eating);
QS_OBJ_DICTIONARY(&Philo_inst[0]); for (uint8_t n = 0U; n < N_PHILO; ++n) {
QS_OBJ_DICTIONARY(&Philo_inst[0].timeEvt); QS_OBJ_ARR_DICTIONARY(&Philo_inst[n], n);
QS_OBJ_DICTIONARY(&Philo_inst[1]); QS_OBJ_ARR_DICTIONARY(&Philo_inst[n].timeEvt, n);
QS_OBJ_DICTIONARY(&Philo_inst[1].timeEvt); }
QS_OBJ_DICTIONARY(&Philo_inst[2]);
QS_OBJ_DICTIONARY(&Philo_inst[2].timeEvt);
QS_OBJ_DICTIONARY(&Philo_inst[3]);
QS_OBJ_DICTIONARY(&Philo_inst[3].timeEvt);
QS_OBJ_DICTIONARY(&Philo_inst[4]);
QS_OBJ_DICTIONARY(&Philo_inst[4].timeEvt);
} }
QActive_subscribe(&me->super, EAT_SIG); QActive_subscribe(&me->super, EAT_SIG);

View File

@ -11,6 +11,24 @@ libraries. These relative paths must be modified when the project
is moved to different relative location. is moved to different relative location.
Selecting QK Exception
======================
The QK kernel needs a dedicated exception to return to the thread
context after preemption. The default is to use the NMI exception
for that purpose. However, in case NMI is needed for some other
purpose, the QK port allows you to select a any, otherwise unused
IRQ for that purpose. To choose a given IRQ, you need to define
the macros QK_USE_IRQ_NUM and QK_USE_IRQ_HANDLER. These macros can
be provided on the command-line to the compiler.
For example, for the EFM32 MCU, you might dedicate the IRQ
"CRYPTO_IRQHandler" (see the vector table), with IRQ number 25,
as follows:
QK_USE_IRQ_HANDLER=CRYPTO_IRQHandler
QK_USE_IRQ_NUM=25
Adjusting Stack and Heap Sizes Adjusting Stack and Heap Sizes
============================== ==============================
The stack and heap sizes are determined in this project by the The stack and heap sizes are determined in this project by the
@ -24,7 +42,7 @@ yyy should be 0, as the using the heap is not recommended).
Startup Code Startup Code
============ ============
The startup code for the TM4C123GH6PM MCU used in this project is The startup code for the EFM32 MCU used in this project is
located in the "3rd_party" folder in the following location: located in the "3rd_party" folder in the following location:
3rd_party\efm32pg1b\arm\startup_efm32pg1b.s 3rd_party\efm32pg1b\arm\startup_efm32pg1b.s
@ -47,4 +65,3 @@ because stack might be corrupted by the time this function is called.
Also, assert_failed() is intended to handle catastrophic errors and Also, assert_failed() is intended to handle catastrophic errors and
should NOT return. should NOT return.
*** ***

View File

@ -75,7 +75,7 @@
<OPTFL> <OPTFL>
<tvExp>1</tvExp> <tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<IsCurrentTarget>1</IsCurrentTarget> <IsCurrentTarget>0</IsCurrentTarget>
</OPTFL> </OPTFL>
<CpuCode>3</CpuCode> <CpuCode>3</CpuCode>
<DebugOpt> <DebugOpt>
@ -120,7 +120,7 @@
<SetRegEntry> <SetRegEntry>
<Number>0</Number> <Number>0</Number>
<Key>DLGUARM</Key> <Key>DLGUARM</Key>
<Name></Name> <Name>d</Name>
</SetRegEntry> </SetRegEntry>
<SetRegEntry> <SetRegEntry>
<Number>0</Number> <Number>0</Number>
@ -297,7 +297,7 @@
<bEvRecOn>1</bEvRecOn> <bEvRecOn>1</bEvRecOn>
<bSchkAxf>0</bSchkAxf> <bSchkAxf>0</bSchkAxf>
<bTchkAxf>0</bTchkAxf> <bTchkAxf>0</bTchkAxf>
<nTsel>3</nTsel> <nTsel>4</nTsel>
<sDll></sDll> <sDll></sDll>
<sDllPa></sDllPa> <sDllPa></sDllPa>
<sDlgDll></sDlgDll> <sDlgDll></sDlgDll>
@ -463,7 +463,7 @@
<OPTFL> <OPTFL>
<tvExp>1</tvExp> <tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<IsCurrentTarget>0</IsCurrentTarget> <IsCurrentTarget>1</IsCurrentTarget>
</OPTFL> </OPTFL>
<CpuCode>3</CpuCode> <CpuCode>3</CpuCode>
<DebugOpt> <DebugOpt>
@ -491,7 +491,7 @@
<bEvRecOn>1</bEvRecOn> <bEvRecOn>1</bEvRecOn>
<bSchkAxf>0</bSchkAxf> <bSchkAxf>0</bSchkAxf>
<bTchkAxf>0</bTchkAxf> <bTchkAxf>0</bTchkAxf>
<nTsel>3</nTsel> <nTsel>4</nTsel>
<sDll></sDll> <sDll></sDll>
<sDllPa></sDllPa> <sDllPa></sDllPa>
<sDlgDll></sDlgDll> <sDlgDll></sDlgDll>
@ -505,6 +505,11 @@
<pMon>Segger\JL2CM3.dll</pMon> <pMon>Segger\JL2CM3.dll</pMon>
</DebugOpt> </DebugOpt>
<TargetDriverDllRegistry> <TargetDriverDllRegistry>
<SetRegEntry>
<Number>0</Number>
<Key>DLGUARM</Key>
<Name></Name>
</SetRegEntry>
<SetRegEntry> <SetRegEntry>
<Number>0</Number> <Number>0</Number>
<Key>JL2CM3</Key> <Key>JL2CM3</Key>
@ -537,6 +542,18 @@
</SetRegEntry> </SetRegEntry>
</TargetDriverDllRegistry> </TargetDriverDllRegistry>
<Breakpoint/> <Breakpoint/>
<WatchWindow1>
<Ww>
<count>0</count>
<WinNumber>1</WinNumber>
<ItemText>QK_attr_</ItemText>
</Ww>
<Ww>
<count>1</count>
<WinNumber>1</WinNumber>
<ItemText>QActive_registry_</ItemText>
</Ww>
</WatchWindow1>
<MemoryWindow1> <MemoryWindow1>
<Mm> <Mm>
<WinNumber>1</WinNumber> <WinNumber>1</WinNumber>
@ -577,7 +594,7 @@
<aPa1>0</aPa1> <aPa1>0</aPa1>
<AscS4>0</AscS4> <AscS4>0</AscS4>
<aSer4>0</aSer4> <aSer4>0</aSer4>
<StkLoc>0</StkLoc> <StkLoc>1</StkLoc>
<TrcWin>0</TrcWin> <TrcWin>0</TrcWin>
<newCpu>0</newCpu> <newCpu>0</newCpu>
<uProt>0</uProt> <uProt>0</uProt>
@ -980,7 +997,7 @@
<GroupNumber>4</GroupNumber> <GroupNumber>4</GroupNumber>
<FileNumber>30</FileNumber> <FileNumber>30</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>1</tvExp> <tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2> <bDave2>0</bDave2>
<PathWithFileName>..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.c</PathWithFileName> <PathWithFileName>..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.c</PathWithFileName>

View File

@ -337,7 +337,7 @@
<v6Rtti>0</v6Rtti> <v6Rtti>0</v6Rtti>
<VariousControls> <VariousControls>
<MiscControls></MiscControls> <MiscControls></MiscControls>
<Define>EFM32PG1B200F256GM48=1 __FPU_PRESENT</Define> <Define>QK_USE_IRQ_NUM=25 QK_USE_IRQ_HANDLER=CRYPTO_IRQHandler</Define>
<Undefine></Undefine> <Undefine></Undefine>
<IncludePath>..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\efm32pg1b</IncludePath> <IncludePath>..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\efm32pg1b</IncludePath>
</VariousControls> </VariousControls>
@ -355,7 +355,7 @@
<ClangAsOpt>4</ClangAsOpt> <ClangAsOpt>4</ClangAsOpt>
<VariousControls> <VariousControls>
<MiscControls></MiscControls> <MiscControls></MiscControls>
<Define>Stack_Size=1024 Heap_Size=16</Define> <Define>Stack_Size=2048 Heap_Size=16</Define>
<Undefine></Undefine> <Undefine></Undefine>
<IncludePath></IncludePath> <IncludePath></IncludePath>
</VariousControls> </VariousControls>
@ -547,57 +547,6 @@
<FileName>qk_port.c</FileName> <FileName>qk_port.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.c</FilePath> <FilePath>..\..\..\..\..\ports\arm-cm\qk\armclang\qk_port.c</FilePath>
<FileOption>
<CommonProperty>
<UseCPPCompiler>2</UseCPPCompiler>
<RVCTCodeConst>0</RVCTCodeConst>
<RVCTZI>0</RVCTZI>
<RVCTOtherData>0</RVCTOtherData>
<ModuleSelection>0</ModuleSelection>
<IncludeInBuild>2</IncludeInBuild>
<AlwaysBuild>2</AlwaysBuild>
<GenerateAssemblyFile>2</GenerateAssemblyFile>
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<FileArmAds>
<Cads>
<interw>2</interw>
<Optim>0</Optim>
<oTime>2</oTime>
<SplitLS>2</SplitLS>
<OneElfS>2</OneElfS>
<Strict>2</Strict>
<EnumInt>2</EnumInt>
<PlainCh>2</PlainCh>
<Ropi>2</Ropi>
<Rwpi>2</Rwpi>
<wLevel>0</wLevel>
<uThumb>2</uThumb>
<uSurpInc>2</uSurpInc>
<uC99>2</uC99>
<uGnu>2</uGnu>
<useXO>2</useXO>
<v6Lang>0</v6Lang>
<v6LangP>0</v6LangP>
<vShortEn>2</vShortEn>
<vShortWch>2</vShortWch>
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define>QK_USE_IRQ_NUM=25 QK_USE_IRQ_HANDLER=CRYPTO_IRQHandler</Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
</FileArmAds>
</FileOption>
</File> </File>
<File> <File>
<FileName>qk_port.h</FileName> <FileName>qk_port.h</FileName>
@ -711,7 +660,7 @@
<TargetName>dpp-rel</TargetName> <TargetName>dpp-rel</TargetName>
<ToolsetNumber>0x4</ToolsetNumber> <ToolsetNumber>0x4</ToolsetNumber>
<ToolsetName>ARM-ADS</ToolsetName> <ToolsetName>ARM-ADS</ToolsetName>
<pCCUsed>6070000::V6.7::.\ARMCLANG</pCCUsed> <pCCUsed>6160000::V6.16::ARMCLANG</pCCUsed>
<uAC6>1</uAC6> <uAC6>1</uAC6>
<TargetOption> <TargetOption>
<TargetCommonOption> <TargetCommonOption>
@ -1038,7 +987,7 @@
<v6Rtti>0</v6Rtti> <v6Rtti>0</v6Rtti>
<VariousControls> <VariousControls>
<MiscControls></MiscControls> <MiscControls></MiscControls>
<Define>NDEBUG EFM32PG1B200F256GM48=1 __FPU_PRESENT</Define> <Define>NDEBUG</Define>
<Undefine></Undefine> <Undefine></Undefine>
<IncludePath>..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\efm32pg1b</IncludePath> <IncludePath>..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\efm32pg1b</IncludePath>
</VariousControls> </VariousControls>
@ -1056,7 +1005,7 @@
<ClangAsOpt>4</ClangAsOpt> <ClangAsOpt>4</ClangAsOpt>
<VariousControls> <VariousControls>
<MiscControls></MiscControls> <MiscControls></MiscControls>
<Define>Stack_Size=1024 Heap_Size=16</Define> <Define>Stack_Size=2048 Heap_Size=16</Define>
<Undefine></Undefine> <Undefine></Undefine>
<IncludePath></IncludePath> <IncludePath></IncludePath>
</VariousControls> </VariousControls>
@ -1361,7 +1310,7 @@
<TargetName>dpp-spy</TargetName> <TargetName>dpp-spy</TargetName>
<ToolsetNumber>0x4</ToolsetNumber> <ToolsetNumber>0x4</ToolsetNumber>
<ToolsetName>ARM-ADS</ToolsetName> <ToolsetName>ARM-ADS</ToolsetName>
<pCCUsed>6070000::V6.7::.\ARMCLANG</pCCUsed> <pCCUsed>6160000::V6.16::ARMCLANG</pCCUsed>
<uAC6>1</uAC6> <uAC6>1</uAC6>
<TargetOption> <TargetOption>
<TargetCommonOption> <TargetCommonOption>
@ -1688,7 +1637,7 @@
<v6Rtti>0</v6Rtti> <v6Rtti>0</v6Rtti>
<VariousControls> <VariousControls>
<MiscControls></MiscControls> <MiscControls></MiscControls>
<Define>Q_SPY EFM32PG1B200F256GM48=1 __FPU_PRESENT</Define> <Define>Q_SPY</Define>
<Undefine></Undefine> <Undefine></Undefine>
<IncludePath>..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\efm32pg1b</IncludePath> <IncludePath>..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\efm32pg1b</IncludePath>
</VariousControls> </VariousControls>
@ -1706,7 +1655,7 @@
<ClangAsOpt>4</ClangAsOpt> <ClangAsOpt>4</ClangAsOpt>
<VariousControls> <VariousControls>
<MiscControls></MiscControls> <MiscControls></MiscControls>
<Define>Stack_Size=1024 Heap_Size=16</Define> <Define>Stack_Size=2048 Heap_Size=16</Define>
<Undefine></Undefine> <Undefine></Undefine>
<IncludePath></IncludePath> <IncludePath></IncludePath>
</VariousControls> </VariousControls>

View File

@ -83,7 +83,7 @@ void SysTick_Handler(void) {
static struct ButtonsDebouncing { static struct ButtonsDebouncing {
uint32_t depressed; uint32_t depressed;
uint32_t previous; uint32_t previous;
} buttons = { ~0U, ~0U }; } buttons = { 0U, 0U };
uint32_t current; uint32_t current;
uint32_t tmp; uint32_t tmp;
@ -96,8 +96,8 @@ void SysTick_Handler(void) {
} }
#endif #endif
//QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); /* process time events for rate 0 */ QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); /* process time events for rate 0 */
QACTIVE_POST(the_Ticker0, 0, &l_SysTick_Handler); /* post to Ticker0 */ //QACTIVE_POST(the_Ticker0, 0, &l_SysTick_Handler); /* post to Ticker0 */
/* Perform the debouncing of buttons. The algorithm for debouncing /* Perform the debouncing of buttons. The algorithm for debouncing
* adapted from the book "Embedded Systems Dictionary" by Jack Ganssle * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle
@ -216,6 +216,7 @@ void BSP_init(void) {
QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0); QS_SIG_DICTIONARY(HUNGRY_SIG, (void *)0);
QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0); QS_SIG_DICTIONARY(TIMEOUT_SIG, (void *)0);
QS_OBJ_DICTIONARY(the_Ticker0);
QS_OBJ_DICTIONARY(&l_SysTick_Handler); QS_OBJ_DICTIONARY(&l_SysTick_Handler);
QS_OBJ_DICTIONARY(&l_GPIO_EVEN_IRQHandler); QS_OBJ_DICTIONARY(&l_GPIO_EVEN_IRQHandler);
@ -223,9 +224,11 @@ void BSP_init(void) {
QS_USR_DICTIONARY(COMMAND_STAT); QS_USR_DICTIONARY(COMMAND_STAT);
/* setup the QS filters... */ /* setup the QS filters... */
QS_GLB_FILTER(QS_SM_RECORDS); /* state machine records */ //QS_GLB_FILTER(QS_SM_RECORDS); /* state machine records */
//QS_GLB_FILTER(QS_AO_RECORDS); /* active object records */ //QS_GLB_FILTER(QS_AO_RECORDS); /* active object records */
QS_GLB_FILTER(QS_UA_RECORDS); /* all user records */ //QS_GLB_FILTER(QS_UA_RECORDS); /* all user records */
QS_GLB_FILTER(QS_ALL_RECORDS); /* all records */
QS_GLB_FILTER(-QS_QF_TICK); /* exclude the clock tick */
} }
/*..........................................................................*/ /*..........................................................................*/
void BSP_displayPhilStat(uint8_t n, char const *stat) { void BSP_displayPhilStat(uint8_t n, char const *stat) {

View File

@ -44,6 +44,24 @@ script (.ld file), which provides a template of the recommended GCC linker
script for QP applications. script for QP applications.
Selecting QK Exception
======================
The QK kernel needs a dedicated exception to return to the thread
context after preemption. The default is to use the NMI exception
for that purpose. However, in case NMI is needed for some other
purpose, the QK port allows you to select a any, otherwise unused
IRQ for that purpose. To choose a given IRQ, you need to define
the macros QK_USE_IRQ_NUM and QK_USE_IRQ_HANDLER. These macros can
be provided on the command-line to the compiler.
For example, for the EFM32 MCU, you might dedicate the IRQ
"CRYPTO_IRQHandler" (see the vector table), with IRQ number 25,
as follows:
QK_USE_IRQ_HANDLER=CRYPTO_IRQHandler
QK_USE_IRQ_NUM=25
Startup Code Startup Code
============ ============
The startup code for the EFM32PG1B200F256GM48 MCU used in this project The startup code for the EFM32PG1B200F256GM48 MCU used in this project

View File

@ -41,7 +41,7 @@ MEMORY { /* memory map of Pearl Gecko EFM32PG1B200F256GM48 */
} }
/* The size of the stack used by the application. NOTE: you need to adjust */ /* The size of the stack used by the application. NOTE: you need to adjust */
STACK_SIZE = 1024; STACK_SIZE = 2048;
/* The size of the heap used by the application. NOTE: you need to adjust */ /* The size of the heap used by the application. NOTE: you need to adjust */
HEAP_SIZE = 0; HEAP_SIZE = 0;

View File

@ -1,13 +1,13 @@
::============================================================================ ::============================================================================
:: Batch file to program the flash of EFM32-SLSTK3401A board :: Batch file to program the flash of EFM32-SLSTK3401A board
:: ::
:: NOTE: requires the J-Link commander (JLink.exe) from SEGGER, see: :: NOTE: requires the J-Link commander (JLink.exe) from SEGGER, see:
:: https://www.segger.com/j-link-commander.html :: https://www.segger.com/j-link-commander.html
:: ::
setlocal setlocal
@echo off @echo off
@echo Load a given binary file to the flash of EFM32-SLSTK3401A @echo Load a given binary file to the flash of EFM32-SLSTK3401A
@echo usage: flash bin-file @echo usage: flash bin-file
@echo example: flash dbg\blinky-qk.bin @echo example: flash dbg\blinky-qk.bin
@ -17,7 +17,7 @@ setlocal
:: ::
if [%JLINK%] EQU [] set JLINK=%QTOOLS%\..\JLink if [%JLINK%] EQU [] set JLINK=%QTOOLS%\..\JLink
if not exist "%JLINK%\JLink.exe" ( if not exist "%JLINK%\JLink.exe" (
@echo The JLink tool not found. Please adjust flash.bat @echo The JLink tool not found. Please adjust flash.bat
@goto end @goto end
) )

View File

@ -0,0 +1,79 @@
0045455691 Sch-Idle Pri=1->0
TE0-ADis Obj=Philo_inst[2].timeEvt,AO=Philo_inst[2]
0053770644 TE0-Post Obj=Philo_inst[2].timeEvt,Sig=TIMEOUT_SIG,AO=Philo_inst[2]
0053771337 AO-Post Sdr=l_SysTick_Handler,Obj=Philo_inst[2],Evt<Sig=TIMEOUT_SIG,Pool=0,Ref=0>,Que<Free=5,Min=5>
0053772439 Sch-Next Pri=0->3
0053772827 AO-GetL Obj=Philo_inst[2],Evt<Sig=TIMEOUT_SIG,Pool=0,Ref=0>
0053773411 Disp===> Obj=Philo_inst[2],Sig=TIMEOUT_SIG,State=Philo_eating
0053774335 MP-Get Obj=EvtPool1,Free=9,Min=8
0053774896 QF-New Sig=DONE_SIG,Size=6
0053775356 QF-Pub Sdr=Philo_inst[2],Evt<Sig=DONE_SIG,Pool=1,Ref=0>
0053775958 Sch-Lock Ceil=0->6
0053776428 AO-Post Sdr=Philo_inst[2],Obj=Table_inst,Evt<Sig=DONE_SIG,Pool=1,Ref=2>,Que<Free=5,Min=5>
0053777295 Sch-Unlk Ceil=6->0
0053777749 Sch-Next Pri=3->6
0053778131 AO-GetL Obj=Table_inst,Evt<Sig=DONE_SIG,Pool=1,Ref=2>
0053778715 Disp===> Obj=Table_inst,Sig=DONE_SIG,State=Table_serving
0053779422 PHILO_STAT 2 thinking
0053780152 MP-Get Obj=EvtPool1,Free=8,Min=8
0053780713 QF-New Sig=EAT_SIG,Size=6
0053781163 QF-Pub Sdr=Table_inst,Evt<Sig=EAT_SIG,Pool=1,Ref=0>
0053781750 Sch-Lock Ceil=0->6
0053782202 AO-Post Sdr=Table_inst,Obj=Table_inst,Evt<Sig=EAT_SIG,Pool=1,Ref=2>,Que<Free=5,Min=5>
0053783101 AO-Post Sdr=Table_inst,Obj=Philo_inst[4],Evt<Sig=EAT_SIG,Pool=1,Ref=3>,Que<Free=5,Min=5>
0053784001 AO-Post Sdr=Table_inst,Obj=Philo_inst[3],Evt<Sig=EAT_SIG,Pool=1,Ref=4>,Que<Free=5,Min=5>
0053784901 AO-Post Sdr=Table_inst,Obj=Philo_inst[2],Evt<Sig=EAT_SIG,Pool=1,Ref=5>,Que<Free=5,Min=5>
0053785801 AO-Post Sdr=Table_inst,Obj=Philo_inst[1],Evt<Sig=EAT_SIG,Pool=1,Ref=6>,Que<Free=5,Min=5>
0053786701 AO-Post Sdr=Table_inst,Obj=Philo_inst[0],Evt<Sig=EAT_SIG,Pool=1,Ref=7>,Que<Free=5,Min=5>
0053787560 Sch-Unlk Ceil=6->0
0053787984 QF-gcA Evt<Sig=EAT_SIG,Pool=1,Ref=7>
0053788466 PHILO_STAT 3 eating
0053789030 =>Intern Obj=Table_inst,Sig=DONE_SIG,State=Table_serving
0053789667 QF-gcA Evt<Sig=DONE_SIG,Pool=1,Ref=2>
0053790128 Sch-Next Pri=6->6
0053790504 AO-GetL Obj=Table_inst,Evt<Sig=EAT_SIG,Pool=1,Ref=6>
0053791087 Disp===> Obj=Table_inst,Sig=EAT_SIG,State=Table_serving
0053791796 =>Intern Obj=Table_inst,Sig=EAT_SIG,State=Table_active
0053792427 QF-gcA Evt<Sig=EAT_SIG,Pool=1,Ref=6>
0053792901 Sch-Next Pri=6->5
0053793273 AO-GetL Obj=Philo_inst[4],Evt<Sig=EAT_SIG,Pool=1,Ref=5>
0053793856 Disp===> Obj=Philo_inst[4],Sig=EAT_SIG,State=Philo_thinking
0053794533 =>Intern Obj=Philo_inst[4],Sig=EAT_SIG,State=Philo_thinking
0053795165 QF-gcA Evt<Sig=EAT_SIG,Pool=1,Ref=5>
0053795639 Sch-Next Pri=5->4
0053796011 AO-GetL Obj=Philo_inst[3],Evt<Sig=EAT_SIG,Pool=1,Ref=4>
0053796594 Disp===> Obj=Philo_inst[3],Sig=EAT_SIG,State=Philo_hungry
0053797557 Sch-Lock Ceil=0->5
0053797959 Sch-Unlk Ceil=5->0
0053798428 TE0-Arm Obj=Philo_inst[3].timeEvt,AO=Philo_inst[3],Tim=197,Int=0
===RTC===> St-Entry Obj=Philo_inst[3],State=Philo_eating
0053799586 ===>Tran Obj=Philo_inst[3],Sig=EAT_SIG,State=Philo_hungry->Philo_eating
0053800328 QF-gcA Evt<Sig=EAT_SIG,Pool=1,Ref=4>
0053800804 Sch-Rsme Prio=4->3
0053801202 QF-gc Evt<Sig=DONE_SIG,Pool=1,Ref=1>
0053801667 MP-Put Obj=EvtPool1,Free=9
0053802194 TE0-DisA Obj=Philo_inst[2].timeEvt,AO=Philo_inst[2]
===RTC===> St-Exit Obj=Philo_inst[2],State=Philo_eating
0053803294 Sch-Lock Ceil=0->5
0053803694 Sch-Unlk Ceil=5->0
0053804165 TE0-Arm Obj=Philo_inst[2].timeEvt,AO=Philo_inst[2],Tim=77,Int=0
===RTC===> St-Entry Obj=Philo_inst[2],State=Philo_thinking
0053805318 ===>Tran Obj=Philo_inst[2],Sig=TIMEOUT_SIG,State=Philo_eating->Philo_thinking
0053806100 Sch-Next Pri=3->3
0053806487 AO-GetL Obj=Philo_inst[2],Evt<Sig=EAT_SIG,Pool=1,Ref=3>
0053807071 Disp===> Obj=Philo_inst[2],Sig=EAT_SIG,State=Philo_thinking
0053807760 =>Intern Obj=Philo_inst[2],Sig=EAT_SIG,State=Philo_thinking
0053808392 QF-gcA Evt<Sig=EAT_SIG,Pool=1,Ref=3>
0053808867 Sch-Next Pri=3->2
0053809239 AO-GetL Obj=Philo_inst[1],Evt<Sig=EAT_SIG,Pool=1,Ref=2>
0053809822 Disp===> Obj=Philo_inst[1],Sig=EAT_SIG,State=Philo_hungry
===RTC===> St-Unhnd Obj=Philo_inst[1],Sig=EAT_SIG,State=Philo_hungry
0053810966 =>Ignore Obj=Philo_inst[1],Sig=EAT_SIG,State=Philo_hungry
0053811583 QF-gcA Evt<Sig=EAT_SIG,Pool=1,Ref=2>
0053812054 Sch-Next Pri=2->1
0053812427 AO-GetL Obj=Philo_inst[0],Evt<Sig=EAT_SIG,Pool=1,Ref=1>
0053813010 Disp===> Obj=Philo_inst[0],Sig=EAT_SIG,State=Philo_eating
0053813685 =>Intern Obj=Philo_inst[0],Sig=EAT_SIG,State=Philo_eating
0053814318 QF-gc Evt<Sig=EAT_SIG,Pool=1,Ref=1>
0053814781 MP-Put Obj=EvtPool1,Free=10
0053815312 Sch-Idle Pri=1->0

View File

@ -0,0 +1,79 @@
0045455658 Sch-Idle Pri=1->0
TE0-ADis Obj=Philo_inst[2].timeEvt,AO=Philo_inst[2]
0053770644 TE0-Post Obj=Philo_inst[2].timeEvt,Sig=TIMEOUT_SIG,AO=Philo_inst[2]
0053771338 AO-Post Sdr=l_SysTick_Handler,Obj=Philo_inst[2],Evt<Sig=TIMEOUT_SIG,Pool=0,Ref=0>,Que<Free=5,Min=5>
0053772441 Sch-Next Pri=0->3
0053772827 AO-GetL Obj=Philo_inst[2],Evt<Sig=TIMEOUT_SIG,Pool=0,Ref=0>
0053773412 Disp===> Obj=Philo_inst[2],Sig=TIMEOUT_SIG,State=Philo_eating
0053774333 MP-Get Obj=EvtPool1,Free=9,Min=8
0053774896 QF-New Sig=DONE_SIG,Size=6
0053775356 QF-Pub Sdr=Philo_inst[2],Evt<Sig=DONE_SIG,Pool=1,Ref=0>
0053775957 Sch-Lock Ceil=0->2
0053776427 AO-Post Sdr=Philo_inst[2],Obj=Table_inst,Evt<Sig=DONE_SIG,Pool=1,Ref=2>,Que<Free=5,Min=5>
0053777293 Sch-Unlk Ceil=2->0
0053777742 Sch-Next Pri=3->6
0053778121 AO-GetL Obj=Table_inst,Evt<Sig=DONE_SIG,Pool=1,Ref=2>
0053778706 Disp===> Obj=Table_inst,Sig=DONE_SIG,State=Table_serving
0053779419 PHILO_STAT 2 thinking
0053780149 MP-Get Obj=EvtPool1,Free=8,Min=8
0053780712 QF-New Sig=EAT_SIG,Size=6
0053781162 QF-Pub Sdr=Table_inst,Evt<Sig=EAT_SIG,Pool=1,Ref=0>
0053781749 Sch-Lock Ceil=0->2
0053782201 AO-Post Sdr=Table_inst,Obj=Table_inst,Evt<Sig=EAT_SIG,Pool=1,Ref=2>,Que<Free=5,Min=5>
0053783100 AO-Post Sdr=Table_inst,Obj=Philo_inst[4],Evt<Sig=EAT_SIG,Pool=1,Ref=3>,Que<Free=5,Min=5>
0053783993 AO-Post Sdr=Table_inst,Obj=Philo_inst[3],Evt<Sig=EAT_SIG,Pool=1,Ref=4>,Que<Free=5,Min=5>
0053784886 AO-Post Sdr=Table_inst,Obj=Philo_inst[2],Evt<Sig=EAT_SIG,Pool=1,Ref=5>,Que<Free=5,Min=5>
0053785779 AO-Post Sdr=Table_inst,Obj=Philo_inst[1],Evt<Sig=EAT_SIG,Pool=1,Ref=6>,Que<Free=5,Min=5>
0053786672 AO-Post Sdr=Table_inst,Obj=Philo_inst[0],Evt<Sig=EAT_SIG,Pool=1,Ref=7>,Que<Free=5,Min=5>
0053787523 Sch-Unlk Ceil=2->0
0053787943 QF-gcA Evt<Sig=EAT_SIG,Pool=1,Ref=7>
0053788426 PHILO_STAT 3 eating
0053788992 =>Intern Obj=Table_inst,Sig=DONE_SIG,State=Table_serving
0053789639 QF-gcA Evt<Sig=DONE_SIG,Pool=1,Ref=2>
0053790098 Sch-Next Pri=6->6
0053790474 AO-GetL Obj=Table_inst,Evt<Sig=EAT_SIG,Pool=1,Ref=6>
0053791059 Disp===> Obj=Table_inst,Sig=EAT_SIG,State=Table_serving
0053791774 =>Intern Obj=Table_inst,Sig=EAT_SIG,State=Table_active
0053792405 QF-gcA Evt<Sig=EAT_SIG,Pool=1,Ref=6>
0053792872 Sch-Rsme Prio=6->3
0053793269 QF-gc Evt<Sig=DONE_SIG,Pool=1,Ref=1>
0053793733 MP-Put Obj=EvtPool1,Free=9
0053794259 TE0-DisA Obj=Philo_inst[2].timeEvt,AO=Philo_inst[2]
===RTC===> St-Exit Obj=Philo_inst[2],State=Philo_eating
0053795376 Sch-Lock Ceil=0->5
0053795777 Sch-Unlk Ceil=5->0
0053796248 TE0-Arm Obj=Philo_inst[2].timeEvt,AO=Philo_inst[2],Tim=147,Int=0
===RTC===> St-Entry Obj=Philo_inst[2],State=Philo_thinking
0053797402 ===>Tran Obj=Philo_inst[2],Sig=TIMEOUT_SIG,State=Philo_eating->Philo_thinking
0053798185 Sch-Next Pri=3->5
0053798573 AO-GetL Obj=Philo_inst[4],Evt<Sig=EAT_SIG,Pool=1,Ref=5>
0053799158 Disp===> Obj=Philo_inst[4],Sig=EAT_SIG,State=Philo_thinking
0053799844 =>Intern Obj=Philo_inst[4],Sig=EAT_SIG,State=Philo_thinking
0053800478 QF-gcA Evt<Sig=EAT_SIG,Pool=1,Ref=5>
0053800951 Sch-Next Pri=5->4
0053801324 AO-GetL Obj=Philo_inst[3],Evt<Sig=EAT_SIG,Pool=1,Ref=4>
0053801906 Disp===> Obj=Philo_inst[3],Sig=EAT_SIG,State=Philo_hungry
0053802845 Sch-Lock Ceil=0->5
0053803248 Sch-Unlk Ceil=5->0
0053803717 TE0-Arm Obj=Philo_inst[3].timeEvt,AO=Philo_inst[3],Tim=127,Int=0
===RTC===> St-Entry Obj=Philo_inst[3],State=Philo_eating
0053804870 ===>Tran Obj=Philo_inst[3],Sig=EAT_SIG,State=Philo_hungry->Philo_eating
0053805615 QF-gcA Evt<Sig=EAT_SIG,Pool=1,Ref=4>
0053806094 Sch-Next Pri=4->3
0053806470 AO-GetL Obj=Philo_inst[2],Evt<Sig=EAT_SIG,Pool=1,Ref=3>
0053807055 Disp===> Obj=Philo_inst[2],Sig=EAT_SIG,State=Philo_thinking
0053807741 =>Intern Obj=Philo_inst[2],Sig=EAT_SIG,State=Philo_thinking
0053808384 QF-gcA Evt<Sig=EAT_SIG,Pool=1,Ref=3>
0053808855 Sch-Next Pri=3->2
0053809228 AO-GetL Obj=Philo_inst[1],Evt<Sig=EAT_SIG,Pool=1,Ref=2>
0053809810 Disp===> Obj=Philo_inst[1],Sig=EAT_SIG,State=Philo_hungry
===RTC===> St-Unhnd Obj=Philo_inst[1],Sig=EAT_SIG,State=Philo_hungry
0053810949 =>Ignore Obj=Philo_inst[1],Sig=EAT_SIG,State=Philo_hungry
0053811567 QF-gcA Evt<Sig=EAT_SIG,Pool=1,Ref=2>
0053812037 Sch-Next Pri=2->1
0053812413 AO-GetL Obj=Philo_inst[0],Evt<Sig=EAT_SIG,Pool=1,Ref=1>
0053812998 Disp===> Obj=Philo_inst[0],Sig=EAT_SIG,State=Philo_eating
0053813671 =>Intern Obj=Philo_inst[0],Sig=EAT_SIG,State=Philo_eating
0053814305 QF-gc Evt<Sig=EAT_SIG,Pool=1,Ref=1>
0053814766 MP-Put Obj=EvtPool1,Free=10
0053815296 Sch-Idle Pri=1->0

View File

@ -15,7 +15,7 @@ relative location.
Stack Size and Heap Size Stack Size and Heap Size
------------------------ ------------------------
In this project, the size of the C stack and heap are determined in In this project, the size of the C stack and heap are determined in
the linker script blinky-qk.icf (see the next section). the linker script dpp-qk.icf (see the next section).
Linker Script Linker Script
@ -26,6 +26,24 @@ application-specific sizes of the Stack and Heap. This file can be edited
from the IAR EWARM IDE via the Project Options/Linker settings. from the IAR EWARM IDE via the Project Options/Linker settings.
Selecting QK Exception
======================
The QK kernel needs a dedicated exception to return to the thread
context after preemption. The default is to use the NMI exception
for that purpose. However, in case NMI is needed for some other
purpose, the QK port allows you to select a any, otherwise unused
IRQ for that purpose. To choose a given IRQ, you need to define
the macros QK_USE_IRQ_NUM and QK_USE_IRQ_HANDLER. These macros can
be provided on the command-line to the compiler.
For example, for the EFM32 MCU, you might dedicate the IRQ
"CRYPTO_IRQHandler" (see the vector table), with IRQ number 25,
as follows:
QK_USE_IRQ_HANDLER=CRYPTO_IRQHandler
QK_USE_IRQ_NUM=25
Startup Code Startup Code
============ ============
The startup code for the TM4C123GH6PM MCU used in this project is The startup code for the TM4C123GH6PM MCU used in this project is

View File

@ -215,6 +215,8 @@
<option> <option>
<name>CCDefines</name> <name>CCDefines</name>
<state>EFM32PG1B200F256GM48</state> <state>EFM32PG1B200F256GM48</state>
<state>QK_USE_IRQ_HANDLER=CRYPTO_IRQHandler</state>
<state>QK_USE_IRQ_NUM=25</state>
</option> </option>
<option> <option>
<name>CCPreprocFile</name> <name>CCPreprocFile</name>
@ -1122,7 +1124,7 @@
</option> </option>
<option> <option>
<name>OGLastSavedByProductVersion</name> <name>OGLastSavedByProductVersion</name>
<state>7.60.1.11206</state> <state>9.10.2.39304</state>
</option> </option>
<option> <option>
<name>OGChipSelectEditMenu</name> <name>OGChipSelectEditMenu</name>
@ -1146,7 +1148,7 @@
</option> </option>
<option> <option>
<name>RTConfigPath2</name> <name>RTConfigPath2</name>
<state>$TOOLKIT_DIR$\INC\c\DLib_Config_Normal.h</state> <state>$TOOLKIT_DIR$\inc\c\DLib_Config_Normal.h</state>
</option> </option>
<option> <option>
<name>GBECoreSlave</name> <name>GBECoreSlave</name>
@ -1232,7 +1234,7 @@
</option> </option>
<option> <option>
<name>DSPExtension</name> <name>DSPExtension</name>
<state>0</state> <state>1</state>
</option> </option>
<option> <option>
<name>TrustZone</name> <name>TrustZone</name>

View File

@ -9,7 +9,7 @@ define symbol __ICFEDIT_region_ROM_end__ = 0x0003FFFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__ = 0x20007FFF; define symbol __ICFEDIT_region_RAM_end__ = 0x20007FFF;
/*-Sizes-*/ /*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 1024; define symbol __ICFEDIT_size_cstack__ = 2048;
define symbol __ICFEDIT_size_heap__ = 0; define symbol __ICFEDIT_size_heap__ = 0;
/**** End of ICF editor section. ###ICF###*/ /**** End of ICF editor section. ###ICF###*/
@ -25,5 +25,5 @@ do not initialize { section .noinit };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in ROM_region { readonly }; place in ROM_region { readonly };
place at start of RAM_region {block CSTACK }; place at start of RAM_region {block CSTACK };
place in RAM_region { readwrite, block HEAP }; place in RAM_region { readwrite, block HEAP };

View File

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
* Product: DPP example * Product: DPP example
* Last updated for version 6.8.2 * Last updated for version 7.1.1
* Last updated on 2020-07-17 * Last updated on 2022-09-22
* *
* Q u a n t u m L e a P s * Q u a n t u m L e a P s
* ------------------------ * ------------------------
@ -62,24 +62,23 @@ int main() {
/* start the active objects... */ /* start the active objects... */
for (uint8_t n = 0U; n < N_PHILO; ++n) { for (uint8_t n = 0U; n < N_PHILO; ++n) {
Philo_ctor(n); /* instantiate Philo[n] AO */ Philo_ctor(n); /* instantiate Philo[n] AO */
QACTIVE_START(AO_Philo[n], /* AO to start */ QACTIVE_START(AO_Philo[n], /* AO to start */
(uint_fast8_t)(n + 2), /* QP priority of the AO */ Q_PRIO(n + 2U, N_PHILO + 1U),/* QF-prio/pre-thre. */
philoQueueSto[n], /* event queue storage */ philoQueueSto[n], /* event queue storage */
Q_DIM(philoQueueSto[n]), /* queue length [events] */ Q_DIM(philoQueueSto[n]), /* queue length [events] */
(void *)0, /* stack storage (not used) */ (void *)0, /* stack storage (not used) */
0U, /* size of the stack [bytes] */ 0U, /* size of the stack [bytes] */
(QEvt *)0); /* initialization event */ (QEvt *)0); /* initialization event */
} }
Table_ctor(); /* instantiate the Table active object */ Table_ctor(); /* instantiate the Table active object */
QACTIVE_START(AO_Table, /* AO to start */ QACTIVE_START(AO_Table, /* AO to start */
(uint_fast8_t)(N_PHILO + 2), /* QP priority of the AO */ N_PHILO + 2U, /* QF-prio/pre-thre. */
tableQueueSto, /* event queue storage */ tableQueueSto, /* event queue storage */
Q_DIM(tableQueueSto), /* queue length [events] */ Q_DIM(tableQueueSto), /* queue length [events] */
(void *)0, /* stack storage (not used) */ (void *)0, /* stack storage (not used) */
0U, /* size of the stack [bytes] */ 0U, /* size of the stack [bytes] */
(QEvt *)0); /* initialization event */ (QEvt *)0); /* initialization event */
return QF_run(); /* run the QF application */ return QF_run(); /* run the QF application */
} }

View File

@ -0,0 +1,79 @@
0045455691 Sch-Idle Pri=1->0
TE0-ADis Obj=Philo_inst[2].timeEvt,AO=Philo_inst[2]
0053770644 TE0-Post Obj=Philo_inst[2].timeEvt,Sig=TIMEOUT_SIG,AO=Philo_inst[2]
0053771337 AO-Post Sdr=l_SysTick_Handler,Obj=Philo_inst[2],Evt<Sig=TIMEOUT_SIG,Pool=0,Ref=0>,Que<Free=5,Min=5>
0053772439 Sch-Next Pri=0->3
0053772827 AO-GetL Obj=Philo_inst[2],Evt<Sig=TIMEOUT_SIG,Pool=0,Ref=0>
0053773411 Disp===> Obj=Philo_inst[2],Sig=TIMEOUT_SIG,State=Philo_eating
0053774335 MP-Get Obj=EvtPool1,Free=9,Min=8
0053774896 QF-New Sig=DONE_SIG,Size=6
0053775356 QF-Pub Sdr=Philo_inst[2],Evt<Sig=DONE_SIG,Pool=1,Ref=0>
0053775958 Sch-Lock Ceil=0->6
0053776428 AO-Post Sdr=Philo_inst[2],Obj=Table_inst,Evt<Sig=DONE_SIG,Pool=1,Ref=2>,Que<Free=5,Min=5>
0053777295 Sch-Unlk Ceil=6->0
0053777749 Sch-Next Pri=3->6
0053778131 AO-GetL Obj=Table_inst,Evt<Sig=DONE_SIG,Pool=1,Ref=2>
0053778715 Disp===> Obj=Table_inst,Sig=DONE_SIG,State=Table_serving
0053779422 PHILO_STAT 2 thinking
0053780152 MP-Get Obj=EvtPool1,Free=8,Min=8
0053780713 QF-New Sig=EAT_SIG,Size=6
0053781163 QF-Pub Sdr=Table_inst,Evt<Sig=EAT_SIG,Pool=1,Ref=0>
0053781750 Sch-Lock Ceil=0->6
0053782202 AO-Post Sdr=Table_inst,Obj=Table_inst,Evt<Sig=EAT_SIG,Pool=1,Ref=2>,Que<Free=5,Min=5>
0053783101 AO-Post Sdr=Table_inst,Obj=Philo_inst[4],Evt<Sig=EAT_SIG,Pool=1,Ref=3>,Que<Free=5,Min=5>
0053784001 AO-Post Sdr=Table_inst,Obj=Philo_inst[3],Evt<Sig=EAT_SIG,Pool=1,Ref=4>,Que<Free=5,Min=5>
0053784901 AO-Post Sdr=Table_inst,Obj=Philo_inst[2],Evt<Sig=EAT_SIG,Pool=1,Ref=5>,Que<Free=5,Min=5>
0053785801 AO-Post Sdr=Table_inst,Obj=Philo_inst[1],Evt<Sig=EAT_SIG,Pool=1,Ref=6>,Que<Free=5,Min=5>
0053786701 AO-Post Sdr=Table_inst,Obj=Philo_inst[0],Evt<Sig=EAT_SIG,Pool=1,Ref=7>,Que<Free=5,Min=5>
0053787560 Sch-Unlk Ceil=6->0
0053787984 QF-gcA Evt<Sig=EAT_SIG,Pool=1,Ref=7>
0053788466 PHILO_STAT 3 eating
0053789030 =>Intern Obj=Table_inst,Sig=DONE_SIG,State=Table_serving
0053789667 QF-gcA Evt<Sig=DONE_SIG,Pool=1,Ref=2>
0053790128 Sch-Next Pri=6->6
0053790504 AO-GetL Obj=Table_inst,Evt<Sig=EAT_SIG,Pool=1,Ref=6>
0053791087 Disp===> Obj=Table_inst,Sig=EAT_SIG,State=Table_serving
0053791796 =>Intern Obj=Table_inst,Sig=EAT_SIG,State=Table_active
0053792427 QF-gcA Evt<Sig=EAT_SIG,Pool=1,Ref=6>
0053792901 Sch-Next Pri=6->5
0053793273 AO-GetL Obj=Philo_inst[4],Evt<Sig=EAT_SIG,Pool=1,Ref=5>
0053793856 Disp===> Obj=Philo_inst[4],Sig=EAT_SIG,State=Philo_thinking
0053794533 =>Intern Obj=Philo_inst[4],Sig=EAT_SIG,State=Philo_thinking
0053795165 QF-gcA Evt<Sig=EAT_SIG,Pool=1,Ref=5>
0053795639 Sch-Next Pri=5->4
0053796011 AO-GetL Obj=Philo_inst[3],Evt<Sig=EAT_SIG,Pool=1,Ref=4>
0053796594 Disp===> Obj=Philo_inst[3],Sig=EAT_SIG,State=Philo_hungry
0053797557 Sch-Lock Ceil=0->5
0053797959 Sch-Unlk Ceil=5->0
0053798428 TE0-Arm Obj=Philo_inst[3].timeEvt,AO=Philo_inst[3],Tim=197,Int=0
===RTC===> St-Entry Obj=Philo_inst[3],State=Philo_eating
0053799586 ===>Tran Obj=Philo_inst[3],Sig=EAT_SIG,State=Philo_hungry->Philo_eating
0053800328 QF-gcA Evt<Sig=EAT_SIG,Pool=1,Ref=4>
0053800804 Sch-Rsme Prio=4->3
0053801202 QF-gc Evt<Sig=DONE_SIG,Pool=1,Ref=1>
0053801667 MP-Put Obj=EvtPool1,Free=9
0053802194 TE0-DisA Obj=Philo_inst[2].timeEvt,AO=Philo_inst[2]
===RTC===> St-Exit Obj=Philo_inst[2],State=Philo_eating
0053803294 Sch-Lock Ceil=0->5
0053803694 Sch-Unlk Ceil=5->0
0053804165 TE0-Arm Obj=Philo_inst[2].timeEvt,AO=Philo_inst[2],Tim=77,Int=0
===RTC===> St-Entry Obj=Philo_inst[2],State=Philo_thinking
0053805318 ===>Tran Obj=Philo_inst[2],Sig=TIMEOUT_SIG,State=Philo_eating->Philo_thinking
0053806100 Sch-Next Pri=3->3
0053806487 AO-GetL Obj=Philo_inst[2],Evt<Sig=EAT_SIG,Pool=1,Ref=3>
0053807071 Disp===> Obj=Philo_inst[2],Sig=EAT_SIG,State=Philo_thinking
0053807760 =>Intern Obj=Philo_inst[2],Sig=EAT_SIG,State=Philo_thinking
0053808392 QF-gcA Evt<Sig=EAT_SIG,Pool=1,Ref=3>
0053808867 Sch-Next Pri=3->2
0053809239 AO-GetL Obj=Philo_inst[1],Evt<Sig=EAT_SIG,Pool=1,Ref=2>
0053809822 Disp===> Obj=Philo_inst[1],Sig=EAT_SIG,State=Philo_hungry
===RTC===> St-Unhnd Obj=Philo_inst[1],Sig=EAT_SIG,State=Philo_hungry
0053810966 =>Ignore Obj=Philo_inst[1],Sig=EAT_SIG,State=Philo_hungry
0053811583 QF-gcA Evt<Sig=EAT_SIG,Pool=1,Ref=2>
0053812054 Sch-Next Pri=2->1
0053812427 AO-GetL Obj=Philo_inst[0],Evt<Sig=EAT_SIG,Pool=1,Ref=1>
0053813010 Disp===> Obj=Philo_inst[0],Sig=EAT_SIG,State=Philo_eating
0053813685 =>Intern Obj=Philo_inst[0],Sig=EAT_SIG,State=Philo_eating
0053814318 QF-gc Evt<Sig=EAT_SIG,Pool=1,Ref=1>
0053814781 MP-Put Obj=EvtPool1,Free=10
0053815312 Sch-Idle Pri=1->0

View File

@ -0,0 +1,79 @@
0045455658 Sch-Idle Pri=1->0
TE0-ADis Obj=Philo_inst[2].timeEvt,AO=Philo_inst[2]
0053770644 TE0-Post Obj=Philo_inst[2].timeEvt,Sig=TIMEOUT_SIG,AO=Philo_inst[2]
0053771338 AO-Post Sdr=l_SysTick_Handler,Obj=Philo_inst[2],Evt<Sig=TIMEOUT_SIG,Pool=0,Ref=0>,Que<Free=5,Min=5>
0053772441 Sch-Next Pri=0->3
0053772827 AO-GetL Obj=Philo_inst[2],Evt<Sig=TIMEOUT_SIG,Pool=0,Ref=0>
0053773412 Disp===> Obj=Philo_inst[2],Sig=TIMEOUT_SIG,State=Philo_eating
0053774333 MP-Get Obj=EvtPool1,Free=9,Min=8
0053774896 QF-New Sig=DONE_SIG,Size=6
0053775356 QF-Pub Sdr=Philo_inst[2],Evt<Sig=DONE_SIG,Pool=1,Ref=0>
0053775957 Sch-Lock Ceil=0->2
0053776427 AO-Post Sdr=Philo_inst[2],Obj=Table_inst,Evt<Sig=DONE_SIG,Pool=1,Ref=2>,Que<Free=5,Min=5>
0053777293 Sch-Unlk Ceil=2->0
0053777742 Sch-Next Pri=3->6
0053778121 AO-GetL Obj=Table_inst,Evt<Sig=DONE_SIG,Pool=1,Ref=2>
0053778706 Disp===> Obj=Table_inst,Sig=DONE_SIG,State=Table_serving
0053779419 PHILO_STAT 2 thinking
0053780149 MP-Get Obj=EvtPool1,Free=8,Min=8
0053780712 QF-New Sig=EAT_SIG,Size=6
0053781162 QF-Pub Sdr=Table_inst,Evt<Sig=EAT_SIG,Pool=1,Ref=0>
0053781749 Sch-Lock Ceil=0->2
0053782201 AO-Post Sdr=Table_inst,Obj=Table_inst,Evt<Sig=EAT_SIG,Pool=1,Ref=2>,Que<Free=5,Min=5>
0053783100 AO-Post Sdr=Table_inst,Obj=Philo_inst[4],Evt<Sig=EAT_SIG,Pool=1,Ref=3>,Que<Free=5,Min=5>
0053783993 AO-Post Sdr=Table_inst,Obj=Philo_inst[3],Evt<Sig=EAT_SIG,Pool=1,Ref=4>,Que<Free=5,Min=5>
0053784886 AO-Post Sdr=Table_inst,Obj=Philo_inst[2],Evt<Sig=EAT_SIG,Pool=1,Ref=5>,Que<Free=5,Min=5>
0053785779 AO-Post Sdr=Table_inst,Obj=Philo_inst[1],Evt<Sig=EAT_SIG,Pool=1,Ref=6>,Que<Free=5,Min=5>
0053786672 AO-Post Sdr=Table_inst,Obj=Philo_inst[0],Evt<Sig=EAT_SIG,Pool=1,Ref=7>,Que<Free=5,Min=5>
0053787523 Sch-Unlk Ceil=2->0
0053787943 QF-gcA Evt<Sig=EAT_SIG,Pool=1,Ref=7>
0053788426 PHILO_STAT 3 eating
0053788992 =>Intern Obj=Table_inst,Sig=DONE_SIG,State=Table_serving
0053789639 QF-gcA Evt<Sig=DONE_SIG,Pool=1,Ref=2>
0053790098 Sch-Next Pri=6->6
0053790474 AO-GetL Obj=Table_inst,Evt<Sig=EAT_SIG,Pool=1,Ref=6>
0053791059 Disp===> Obj=Table_inst,Sig=EAT_SIG,State=Table_serving
0053791774 =>Intern Obj=Table_inst,Sig=EAT_SIG,State=Table_active
0053792405 QF-gcA Evt<Sig=EAT_SIG,Pool=1,Ref=6>
0053792872 Sch-Rsme Prio=6->3
0053793269 QF-gc Evt<Sig=DONE_SIG,Pool=1,Ref=1>
0053793733 MP-Put Obj=EvtPool1,Free=9
0053794259 TE0-DisA Obj=Philo_inst[2].timeEvt,AO=Philo_inst[2]
===RTC===> St-Exit Obj=Philo_inst[2],State=Philo_eating
0053795376 Sch-Lock Ceil=0->5
0053795777 Sch-Unlk Ceil=5->0
0053796248 TE0-Arm Obj=Philo_inst[2].timeEvt,AO=Philo_inst[2],Tim=147,Int=0
===RTC===> St-Entry Obj=Philo_inst[2],State=Philo_thinking
0053797402 ===>Tran Obj=Philo_inst[2],Sig=TIMEOUT_SIG,State=Philo_eating->Philo_thinking
0053798185 Sch-Next Pri=3->5
0053798573 AO-GetL Obj=Philo_inst[4],Evt<Sig=EAT_SIG,Pool=1,Ref=5>
0053799158 Disp===> Obj=Philo_inst[4],Sig=EAT_SIG,State=Philo_thinking
0053799844 =>Intern Obj=Philo_inst[4],Sig=EAT_SIG,State=Philo_thinking
0053800478 QF-gcA Evt<Sig=EAT_SIG,Pool=1,Ref=5>
0053800951 Sch-Next Pri=5->4
0053801324 AO-GetL Obj=Philo_inst[3],Evt<Sig=EAT_SIG,Pool=1,Ref=4>
0053801906 Disp===> Obj=Philo_inst[3],Sig=EAT_SIG,State=Philo_hungry
0053802845 Sch-Lock Ceil=0->5
0053803248 Sch-Unlk Ceil=5->0
0053803717 TE0-Arm Obj=Philo_inst[3].timeEvt,AO=Philo_inst[3],Tim=127,Int=0
===RTC===> St-Entry Obj=Philo_inst[3],State=Philo_eating
0053804870 ===>Tran Obj=Philo_inst[3],Sig=EAT_SIG,State=Philo_hungry->Philo_eating
0053805615 QF-gcA Evt<Sig=EAT_SIG,Pool=1,Ref=4>
0053806094 Sch-Next Pri=4->3
0053806470 AO-GetL Obj=Philo_inst[2],Evt<Sig=EAT_SIG,Pool=1,Ref=3>
0053807055 Disp===> Obj=Philo_inst[2],Sig=EAT_SIG,State=Philo_thinking
0053807741 =>Intern Obj=Philo_inst[2],Sig=EAT_SIG,State=Philo_thinking
0053808384 QF-gcA Evt<Sig=EAT_SIG,Pool=1,Ref=3>
0053808855 Sch-Next Pri=3->2
0053809228 AO-GetL Obj=Philo_inst[1],Evt<Sig=EAT_SIG,Pool=1,Ref=2>
0053809810 Disp===> Obj=Philo_inst[1],Sig=EAT_SIG,State=Philo_hungry
===RTC===> St-Unhnd Obj=Philo_inst[1],Sig=EAT_SIG,State=Philo_hungry
0053810949 =>Ignore Obj=Philo_inst[1],Sig=EAT_SIG,State=Philo_hungry
0053811567 QF-gcA Evt<Sig=EAT_SIG,Pool=1,Ref=2>
0053812037 Sch-Next Pri=2->1
0053812413 AO-GetL Obj=Philo_inst[0],Evt<Sig=EAT_SIG,Pool=1,Ref=1>
0053812998 Disp===> Obj=Philo_inst[0],Sig=EAT_SIG,State=Philo_eating
0053813671 =>Intern Obj=Philo_inst[0],Sig=EAT_SIG,State=Philo_eating
0053814305 QF-gc Evt<Sig=EAT_SIG,Pool=1,Ref=1>
0053814766 MP-Put Obj=EvtPool1,Free=10
0053815296 Sch-Idle Pri=1->0

View File

@ -354,7 +354,7 @@
<uClangAs>0</uClangAs> <uClangAs>0</uClangAs>
<VariousControls> <VariousControls>
<MiscControls></MiscControls> <MiscControls></MiscControls>
<Define>Stack_Size=1024 Heap_Size=16</Define> <Define>Stack_Size=2048 Heap_Size=16</Define>
<Undefine></Undefine> <Undefine></Undefine>
<IncludePath></IncludePath> <IncludePath></IncludePath>
</VariousControls> </VariousControls>
@ -1003,7 +1003,7 @@
<uClangAs>0</uClangAs> <uClangAs>0</uClangAs>
<VariousControls> <VariousControls>
<MiscControls></MiscControls> <MiscControls></MiscControls>
<Define>Stack_Size=1024 Heap_Size=16</Define> <Define>Stack_Size=2048 Heap_Size=16</Define>
<Undefine></Undefine> <Undefine></Undefine>
<IncludePath></IncludePath> <IncludePath></IncludePath>
</VariousControls> </VariousControls>
@ -1652,7 +1652,7 @@
<uClangAs>0</uClangAs> <uClangAs>0</uClangAs>
<VariousControls> <VariousControls>
<MiscControls></MiscControls> <MiscControls></MiscControls>
<Define>Stack_Size=1024 Heap_Size=16</Define> <Define>Stack_Size=2048 Heap_Size=16</Define>
<Undefine></Undefine> <Undefine></Undefine>
<IncludePath></IncludePath> <IncludePath></IncludePath>
</VariousControls> </VariousControls>

View File

@ -83,7 +83,7 @@ void SysTick_Handler(void) {
static struct ButtonsDebouncing { static struct ButtonsDebouncing {
uint32_t depressed; uint32_t depressed;
uint32_t previous; uint32_t previous;
} buttons = { ~0U, ~0U }; } buttons = { 0U, 0U };
uint32_t current; uint32_t current;
uint32_t tmp; uint32_t tmp;

View File

@ -41,7 +41,7 @@ MEMORY { /* memory map of Pearl Gecko EFM32PG1B200F256GM48 */
} }
/* The size of the stack used by the application. NOTE: you need to adjust */ /* The size of the stack used by the application. NOTE: you need to adjust */
STACK_SIZE = 1024; STACK_SIZE = 2048;
/* The size of the heap used by the application. NOTE: you need to adjust */ /* The size of the heap used by the application. NOTE: you need to adjust */
HEAP_SIZE = 0; HEAP_SIZE = 0;

View File

@ -1,13 +1,13 @@
::============================================================================ ::============================================================================
:: Batch file to program the flash of EFM32-SLSTK3401A board :: Batch file to program the flash of EFM32-SLSTK3401A board
:: ::
:: NOTE: requires the J-Link commander (JLink.exe) from SEGGER, see: :: NOTE: requires the J-Link commander (JLink.exe) from SEGGER, see:
:: https://www.segger.com/j-link-commander.html :: https://www.segger.com/j-link-commander.html
:: ::
setlocal setlocal
@echo off @echo off
@echo Load a given binary file to the flash of EFM32-SLSTK3401A @echo Load a given binary file to the flash of EFM32-SLSTK3401A
@echo usage: flash bin-file @echo usage: flash bin-file
@echo example: flash dbg\blinky-qk.bin @echo example: flash dbg\blinky-qk.bin
@ -17,7 +17,7 @@ setlocal
:: ::
if [%JLINK%] EQU [] set JLINK=%QTOOLS%\..\JLink if [%JLINK%] EQU [] set JLINK=%QTOOLS%\..\JLink
if not exist "%JLINK%\JLink.exe" ( if not exist "%JLINK%\JLink.exe" (
@echo The JLink tool not found. Please adjust flash.bat @echo The JLink tool not found. Please adjust flash.bat
@goto end @goto end
) )

View File

@ -9,7 +9,7 @@ define symbol __ICFEDIT_region_ROM_end__ = 0x0003FFFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__ = 0x20007FFF; define symbol __ICFEDIT_region_RAM_end__ = 0x20007FFF;
/*-Sizes-*/ /*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 1024; define symbol __ICFEDIT_size_cstack__ = 2048;
define symbol __ICFEDIT_size_heap__ = 0; define symbol __ICFEDIT_size_heap__ = 0;
/**** End of ICF editor section. ###ICF###*/ /**** End of ICF editor section. ###ICF###*/
@ -25,5 +25,5 @@ do not initialize { section .noinit };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in ROM_region { readonly }; place in ROM_region { readonly };
place at start of RAM_region {block CSTACK }; place at start of RAM_region {block CSTACK };
place in RAM_region { readwrite, block HEAP }; place in RAM_region { readwrite, block HEAP };

View File

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
* Product: DPP example * Product: DPP example
* Last updated for version 6.8.2 * Last updated for version 7.1.2
* Last updated on 2020-07-17 * Last updated on 2022-09-22
* *
* Q u a n t u m L e a P s * Q u a n t u m L e a P s
* ------------------------ * ------------------------
@ -70,23 +70,23 @@ int main() {
/* start the active objects... */ /* start the active objects... */
for (uint8_t n = 0U; n < N_PHILO; ++n) { for (uint8_t n = 0U; n < N_PHILO; ++n) {
Philo_ctor(n); /* instantiate Philo[n] AO */ Philo_ctor(n); /* instantiate Philo[n] AO */
QACTIVE_START(AO_Philo[n], /* AO to start */ QACTIVE_START(AO_Philo[n], /* AO to start */
(uint_fast8_t)(n + 2), /* QP priority of the AO */ n + 2U, /* QF-priority */
philoQueueSto[n], /* event queue storage */ philoQueueSto[n], /* event queue storage */
Q_DIM(philoQueueSto[n]), /* queue length [events] */ Q_DIM(philoQueueSto[n]), /* queue length [events] */
(void *)0, /* stack storage (not used) */ (void *)0, /* stack storage (not used) */
0U, /* size of the stack [bytes] */ 0U, /* size of the stack [bytes] */
(QEvt *)0); /* initialization event */ (void *)0); /* initialization param */
} }
Table_ctor(); /* instantiate the Table active object */ Table_ctor(); /* instantiate the Table active object */
QACTIVE_START(AO_Table, /* AO to start */ QACTIVE_START(AO_Table, /* AO to start */
(uint_fast8_t)(N_PHILO + 2), /* QP priority of the AO */ N_PHILO + 2U, /* QF-priority */
tableQueueSto, /* event queue storage */ tableQueueSto, /* event queue storage */
Q_DIM(tableQueueSto), /* queue length [events] */ Q_DIM(tableQueueSto), /* queue length [events] */
(void *)0, /* stack storage (not used) */ (void *)0, /* stack storage (not used) */
0U, /* size of the stack [bytes] */ 0U, /* size of the stack [bytes] */
(QEvt *)0); /* initialization event */ (void *)0); /* initialization param */
return QF_run(); /* run the QF application */ return QF_run(); /* run the QF application */
} }

View File

@ -22,9 +22,27 @@ numerical value of the heap size (for most embedded projects
yyy should be 0, as the using the heap is not recommended). yyy should be 0, as the using the heap is not recommended).
Selecting QXK Exception
=======================
The QXK kernel needs a dedicated exception to return to the thread
context after preemption by a basic thread. The default is to use
the NMI exception for that purpose. However, in case NMI is needed
for some other purpose, the QXK port allows you to select a any,
otherwise unused IRQ for that purpose. To choose a given IRQ, you
need to define the macros QXK_USE_IRQ_NUM and QXK_USE_IRQ_HANDLER.
These macros can be provided on the command-line to the compiler.
For example, for the EFM32 MCU, you might dedicate the IRQ
"CRYPTO_IRQHandler" (see the vector table), with IRQ number 25,
as follows:
QXK_USE_IRQ_HANDLER=CRYPTO_IRQHandler
QXK_USE_IRQ_NUM=25
Startup Code Startup Code
============ ============
The startup code for the TM4C123GH6PM MCU used in this project is The startup code for the EFM32 MCU used in this project is
located in the "3rd_party" folder in the following location: located in the "3rd_party" folder in the following location:
3rd_party\efm32pg1b\arm\startup_efm32pg1b.s 3rd_party\efm32pg1b\arm\startup_efm32pg1b.s
@ -47,4 +65,3 @@ because stack might be corrupted by the time this function is called.
Also, assert_failed() is intended to handle catastrophic errors and Also, assert_failed() is intended to handle catastrophic errors and
should NOT return. should NOT return.
*** ***

View File

@ -75,7 +75,7 @@
<OPTFL> <OPTFL>
<tvExp>1</tvExp> <tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<IsCurrentTarget>1</IsCurrentTarget> <IsCurrentTarget>0</IsCurrentTarget>
</OPTFL> </OPTFL>
<CpuCode>3</CpuCode> <CpuCode>3</CpuCode>
<DebugOpt> <DebugOpt>
@ -153,7 +153,52 @@
<Name>-U0E2006F4 -O4622 -S4 -FO61</Name> <Name>-U0E2006F4 -O4622 -S4 -FO61</Name>
</SetRegEntry> </SetRegEntry>
</TargetDriverDllRegistry> </TargetDriverDllRegistry>
<Breakpoint/> <Breakpoint>
<Bp>
<Number>0</Number>
<Type>0</Type>
<LineNumber>363</LineNumber>
<EnabledFlag>1</EnabledFlag>
<Address>10268</Address>
<ByteObject>0</ByteObject>
<HtxType>0</HtxType>
<ManyObjects>0</ManyObjects>
<SizeOfObject>0</SizeOfObject>
<BreakByAccess>0</BreakByAccess>
<BreakIfRCount>1</BreakIfRCount>
<Filename>..\bsp.c</Filename>
<ExecCommand></ExecCommand>
<Expression>\\dpp_qxk\../bsp.c\363</Expression>
</Bp>
<Bp>
<Number>1</Number>
<Type>0</Type>
<LineNumber>361</LineNumber>
<EnabledFlag>1</EnabledFlag>
<Address>6678</Address>
<ByteObject>0</ByteObject>
<HtxType>0</HtxType>
<ManyObjects>0</ManyObjects>
<SizeOfObject>0</SizeOfObject>
<BreakByAccess>0</BreakByAccess>
<BreakIfRCount>1</BreakIfRCount>
<Filename>..\..\..\..\..\src\qxk\qxk.c</Filename>
<ExecCommand></ExecCommand>
<Expression>\\dpp_qxk\../../../../../src/qxk/qxk.c\361</Expression>
</Bp>
</Breakpoint>
<WatchWindow1>
<Ww>
<count>0</count>
<WinNumber>1</WinNumber>
<ItemText>QF_readySet_</ItemText>
</Ww>
<Ww>
<count>1</count>
<WinNumber>1</WinNumber>
<ItemText>QXK_attr_</ItemText>
</Ww>
</WatchWindow1>
<MemoryWindow1> <MemoryWindow1>
<Mm> <Mm>
<WinNumber>1</WinNumber> <WinNumber>1</WinNumber>
@ -297,7 +342,7 @@
<bEvRecOn>1</bEvRecOn> <bEvRecOn>1</bEvRecOn>
<bSchkAxf>0</bSchkAxf> <bSchkAxf>0</bSchkAxf>
<bTchkAxf>0</bTchkAxf> <bTchkAxf>0</bTchkAxf>
<nTsel>3</nTsel> <nTsel>4</nTsel>
<sDll></sDll> <sDll></sDll>
<sDllPa></sDllPa> <sDllPa></sDllPa>
<sDlgDll></sDlgDll> <sDlgDll></sDlgDll>
@ -463,7 +508,7 @@
<OPTFL> <OPTFL>
<tvExp>1</tvExp> <tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<IsCurrentTarget>0</IsCurrentTarget> <IsCurrentTarget>1</IsCurrentTarget>
</OPTFL> </OPTFL>
<CpuCode>3</CpuCode> <CpuCode>3</CpuCode>
<DebugOpt> <DebugOpt>
@ -508,7 +553,7 @@
<SetRegEntry> <SetRegEntry>
<Number>0</Number> <Number>0</Number>
<Key>DLGUARM</Key> <Key>DLGUARM</Key>
<Name>/</Name> <Name>d</Name>
</SetRegEntry> </SetRegEntry>
<SetRegEntry> <SetRegEntry>
<Number>0</Number> <Number>0</Number>
@ -542,6 +587,38 @@
</SetRegEntry> </SetRegEntry>
</TargetDriverDllRegistry> </TargetDriverDllRegistry>
<Breakpoint/> <Breakpoint/>
<WatchWindow1>
<Ww>
<count>0</count>
<WinNumber>1</WinNumber>
<ItemText>QF_readySet_</ItemText>
</Ww>
<Ww>
<count>1</count>
<WinNumber>1</WinNumber>
<ItemText>QXK_attr_</ItemText>
</Ww>
<Ww>
<count>2</count>
<WinNumber>1</WinNumber>
<ItemText>QActive_registry_</ItemText>
</Ww>
<Ww>
<count>3</count>
<WinNumber>1</WinNumber>
<ItemText>l_test1</ItemText>
</Ww>
<Ww>
<count>4</count>
<WinNumber>1</WinNumber>
<ItemText>l_test2</ItemText>
</Ww>
<Ww>
<count>5</count>
<WinNumber>1</WinNumber>
<ItemText>thr</ItemText>
</Ww>
</WatchWindow1>
<MemoryWindow1> <MemoryWindow1>
<Mm> <Mm>
<WinNumber>1</WinNumber> <WinNumber>1</WinNumber>

View File

@ -337,7 +337,7 @@
<v6Rtti>0</v6Rtti> <v6Rtti>0</v6Rtti>
<VariousControls> <VariousControls>
<MiscControls></MiscControls> <MiscControls></MiscControls>
<Define>EFM32PG1B200F256GM48=1 __FPU_PRESENT</Define> <Define>QXK_USE_IRQ_HANDLER=CRYPTO_IRQHandler QXK_USE_IRQ_NUM=25</Define>
<Undefine></Undefine> <Undefine></Undefine>
<IncludePath>..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qxk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\efm32pg1b</IncludePath> <IncludePath>..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qxk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\efm32pg1b</IncludePath>
</VariousControls> </VariousControls>
@ -355,7 +355,7 @@
<ClangAsOpt>4</ClangAsOpt> <ClangAsOpt>4</ClangAsOpt>
<VariousControls> <VariousControls>
<MiscControls></MiscControls> <MiscControls></MiscControls>
<Define>Stack_Size=1024 Heap_Size=16</Define> <Define>Stack_Size=2048 Heap_Size=16</Define>
<Undefine></Undefine> <Undefine></Undefine>
<IncludePath></IncludePath> <IncludePath></IncludePath>
</VariousControls> </VariousControls>
@ -572,57 +572,6 @@
<FileName>qxk_port.c</FileName> <FileName>qxk_port.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.c</FilePath> <FilePath>..\..\..\..\..\ports\arm-cm\qxk\armclang\qxk_port.c</FilePath>
<FileOption>
<CommonProperty>
<UseCPPCompiler>2</UseCPPCompiler>
<RVCTCodeConst>0</RVCTCodeConst>
<RVCTZI>0</RVCTZI>
<RVCTOtherData>0</RVCTOtherData>
<ModuleSelection>0</ModuleSelection>
<IncludeInBuild>2</IncludeInBuild>
<AlwaysBuild>2</AlwaysBuild>
<GenerateAssemblyFile>2</GenerateAssemblyFile>
<AssembleAssemblyFile>2</AssembleAssemblyFile>
<PublicsOnly>2</PublicsOnly>
<StopOnExitCode>11</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<FileArmAds>
<Cads>
<interw>2</interw>
<Optim>0</Optim>
<oTime>2</oTime>
<SplitLS>2</SplitLS>
<OneElfS>2</OneElfS>
<Strict>2</Strict>
<EnumInt>2</EnumInt>
<PlainCh>2</PlainCh>
<Ropi>2</Ropi>
<Rwpi>2</Rwpi>
<wLevel>0</wLevel>
<uThumb>2</uThumb>
<uSurpInc>2</uSurpInc>
<uC99>2</uC99>
<uGnu>2</uGnu>
<useXO>2</useXO>
<v6Lang>0</v6Lang>
<v6LangP>0</v6LangP>
<vShortEn>2</vShortEn>
<vShortWch>2</vShortWch>
<v6Lto>2</v6Lto>
<v6WtE>2</v6WtE>
<v6Rtti>2</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define>QXK_USE_IRQ_NUM=25 QXK_USE_IRQ_HANDLER=CRYPTO_IRQHandler</Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Cads>
</FileArmAds>
</FileOption>
</File> </File>
<File> <File>
<FileName>qxk_port.h</FileName> <FileName>qxk_port.h</FileName>
@ -1058,7 +1007,7 @@
<v6Rtti>0</v6Rtti> <v6Rtti>0</v6Rtti>
<VariousControls> <VariousControls>
<MiscControls></MiscControls> <MiscControls></MiscControls>
<Define>NDEBUG EFM32PG1B200F256GM48=1 __FPU_PRESENT</Define> <Define>NDEBUG</Define>
<Undefine></Undefine> <Undefine></Undefine>
<IncludePath>..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qxk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\efm32pg1b</IncludePath> <IncludePath>..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qxk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\efm32pg1b</IncludePath>
</VariousControls> </VariousControls>
@ -1076,7 +1025,7 @@
<ClangAsOpt>4</ClangAsOpt> <ClangAsOpt>4</ClangAsOpt>
<VariousControls> <VariousControls>
<MiscControls></MiscControls> <MiscControls></MiscControls>
<Define>Stack_Size=1024 Heap_Size=16</Define> <Define>Stack_Size=2048 Heap_Size=16</Define>
<Undefine></Undefine> <Undefine></Undefine>
<IncludePath></IncludePath> <IncludePath></IncludePath>
</VariousControls> </VariousControls>
@ -1704,7 +1653,7 @@
</ArmAdsMisc> </ArmAdsMisc>
<Cads> <Cads>
<interw>0</interw> <interw>0</interw>
<Optim>2</Optim> <Optim>1</Optim>
<oTime>0</oTime> <oTime>0</oTime>
<SplitLS>0</SplitLS> <SplitLS>0</SplitLS>
<OneElfS>1</OneElfS> <OneElfS>1</OneElfS>
@ -1728,7 +1677,8 @@
<v6Rtti>0</v6Rtti> <v6Rtti>0</v6Rtti>
<VariousControls> <VariousControls>
<MiscControls></MiscControls> <MiscControls></MiscControls>
<Define>Q_SPY EFM32PG1B200F256GM48=1 __FPU_PRESENT</Define> <Define>Q_SPY QXK_ON_CONTEXT_SW QXK_USE_IRQ_HANDLER=CRYPTO_IRQHandler QXK_USE_IRQ_NUM=25
</Define>
<Undefine></Undefine> <Undefine></Undefine>
<IncludePath>..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qxk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\efm32pg1b</IncludePath> <IncludePath>..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qxk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\efm32pg1b</IncludePath>
</VariousControls> </VariousControls>
@ -1746,7 +1696,7 @@
<ClangAsOpt>4</ClangAsOpt> <ClangAsOpt>4</ClangAsOpt>
<VariousControls> <VariousControls>
<MiscControls></MiscControls> <MiscControls></MiscControls>
<Define>Stack_Size=1024 Heap_Size=16</Define> <Define>Stack_Size=2048 Heap_Size=16</Define>
<Undefine></Undefine> <Undefine></Undefine>
<IncludePath></IncludePath> <IncludePath></IncludePath>
</VariousControls> </VariousControls>

View File

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
* Product: DPP example, EFM32-SLSTK3401A board, preemptive QXK kernel * Product: DPP example, EFM32-SLSTK3401A board, preemptive QXK kernel
* Last updated for version 6.9.3 * Last updated for version 7.1.0
* Last updated on 2021-03-03 * Last updated on 2022-08-28
* *
* Q u a n t u m L e a P s * Q u a n t u m L e a P s
* ------------------------ * ------------------------
@ -73,6 +73,7 @@ static uint32_t l_rnd; /* random seed */
enum AppRecords { /* application-specific trace records */ enum AppRecords { /* application-specific trace records */
PHILO_STAT = QS_USER, PHILO_STAT = QS_USER,
PAUSED_STAT, PAUSED_STAT,
CONTEXT_SW,
COMMAND_STAT COMMAND_STAT
}; };
@ -84,7 +85,7 @@ void SysTick_Handler(void) {
static struct ButtonsDebouncing { static struct ButtonsDebouncing {
uint32_t depressed; uint32_t depressed;
uint32_t previous; uint32_t previous;
} buttons = { ~0U, ~0U }; } buttons = { 0U, 0U };
uint32_t current; uint32_t current;
uint32_t tmp; uint32_t tmp;
@ -97,8 +98,8 @@ void SysTick_Handler(void) {
} }
#endif #endif
/*QTIMEEVT_TICK_X(0U, &l_SysTick_Handler);*/ /* process time events for rate 0 */ QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); /* process time events for rate 0 */
QACTIVE_POST(the_Ticker0, 0, &l_SysTick_Handler); /* post to Ticker0 */ //QACTIVE_POST(the_Ticker0, 0, &l_SysTick_Handler); /* post to Ticker0 */
/* Perform the debouncing of buttons. The algorithm for debouncing /* Perform the debouncing of buttons. The algorithm for debouncing
* adapted from the book "Embedded Systems Dictionary" by Jack Ganssle * adapted from the book "Embedded Systems Dictionary" by Jack Ganssle
@ -202,15 +203,14 @@ void BSP_init(void) {
QS_USR_DICTIONARY(PHILO_STAT); QS_USR_DICTIONARY(PHILO_STAT);
QS_USR_DICTIONARY(PAUSED_STAT); QS_USR_DICTIONARY(PAUSED_STAT);
QS_USR_DICTIONARY(CONTEXT_SW);
QS_USR_DICTIONARY(COMMAND_STAT); QS_USR_DICTIONARY(COMMAND_STAT);
QS_FUN_DICTIONARY(&QHsm_top);
/* setup the QS filters... */ /* setup the QS filters... */
QS_GLB_FILTER(QS_SM_RECORDS); /* state machine records */ QS_GLB_FILTER(QS_ALL_RECORDS); /* all records */
QS_GLB_FILTER(QS_UA_RECORDS); /* all usedr records */ QS_GLB_FILTER(-QS_QF_TICK); /* exclude the clock tick */
/*
QS_GLB_FILTER(QS_MUTEX_LOCK);
QS_GLB_FILTER(QS_MUTEX_UNLOCK);
*/
} }
/*..........................................................................*/ /*..........................................................................*/
void BSP_displayPhilStat(uint8_t n, char const *stat) { void BSP_displayPhilStat(uint8_t n, char const *stat) {
@ -310,6 +310,20 @@ void QF_onStartup(void) {
void QF_onCleanup(void) { void QF_onCleanup(void) {
} }
/*..........................................................................*/ /*..........................................................................*/
#ifdef QXK_ON_CONTEXT_SW
/* NOTE: the context-switch callback is called with interrupts DISABLED */
void QXK_onContextSw(QActive *prev, QActive *next) {
(void)prev;
if (next != (QActive *)0) {
//_impure_ptr = next->thread; /* switch to next TLS */
}
QS_BEGIN_NOCRIT(CONTEXT_SW, 0U) /* no critical section! */
QS_OBJ(prev);
QS_OBJ(next);
QS_END_NOCRIT()
}
#endif /* QXK_ON_CONTEXT_SW */
/*..........................................................................*/
void QXK_onIdle(void) { void QXK_onIdle(void) {
float volatile x; float volatile x;
@ -371,6 +385,8 @@ Q_NORETURN Q_onAssert(char const * const module, int_t const loc) {
#ifdef Q_SPY #ifdef Q_SPY
/*..........................................................................*/ /*..........................................................................*/
uint8_t QS_onStartup(void const *arg) { uint8_t QS_onStartup(void const *arg) {
Q_UNUSED_PAR(arg);
static uint8_t qsTxBuf[2*1024]; /* buffer for QS transmit channel */ static uint8_t qsTxBuf[2*1024]; /* buffer for QS transmit channel */
static uint8_t qsRxBuf[100]; /* buffer for QS receive channel */ static uint8_t qsRxBuf[100]; /* buffer for QS receive channel */
static USART_InitAsync_TypeDef init = { static USART_InitAsync_TypeDef init = {

View File

@ -1,7 +1,7 @@
############################################################################## ##############################################################################
# Product: Makefile for QP/C on EMF32-SLSTK3401A, QXK kernel, GNU-ARM # Product: Makefile for QP/C on EMF32-SLSTK3401A, QXK kernel, GNU-ARM
# Last Updated for Version: 7.0.1 # Last Updated for Version: 7.0.2
# Date of the Last Update: 2022-05-23 # Date of the Last Update: 2022-08-18
# #
# Q u a n t u m L e a P s # Q u a n t u m L e a P s
# ------------------------ # ------------------------
@ -142,8 +142,9 @@ LIBS :=
# defines # defines
DEFINES := -DEFM32PG1B200F256GM48=1 \ DEFINES := -DEFM32PG1B200F256GM48=1 \
-DQXK_USE_IRQ_NUM=25 \ -DQXK_ON_CONTEXT_SW \
-DQXK_USE_IRQ_HANDLER=CRYPTO_IRQHandler -DQXK_USE_IRQ_HANDLER=CRYPTO_IRQHandler \
-DQXK_USE_IRQ_NUM=25
# ARM CPU, ARCH, FPU, and Float-ABI types... # ARM CPU, ARCH, FPU, and Float-ABI types...
# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] # ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4]

View File

@ -0,0 +1,325 @@
##############################################################################
# Product: Makefile for QP/C on EMF32-SLSTK3401A, QXK kernel, GNU-ARM
# Last Updated for Version: 7.1.0
# Date of the Last Update: 2022-08-28
#
# Q u a n t u m L e a P s
# ------------------------
# Modern Embedded Software
#
# Copyright (C) 2005-2022 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:
# <www.state-machine.com/licensing>
# <info@state-machine.com>
##############################################################################
# examples of invoking this Makefile:
# building configurations: Debug (default), Release, and Spy
# make
# make CONF=rel
# make CONF=spy
#
# cleaning configurations: Debug (default), Release, and Spy
# make clean
# make CONF=rel clean
# make CONF=spy clean
#
# NOTE:
# To use this Makefile on Windows, you will need the GNU make utility, which
# is included in the Qtools collection for Windows, see:
# https://sourceforge.net/projects/qpc/files/QTools/
#
#-----------------------------------------------------------------------------
# project name
#
PROJECT := dpp-qxk
#-----------------------------------------------------------------------------
# project directories
#
# location of the QP/C framework (if not provided in an environemnt var.)
ifeq ($(QPC),)
QPC := ../../../../..
endif
# QP port used in this project
QP_PORT_DIR := $(QPC)/ports/arm-cm/qxk/gnu
# list of all source directories used by this project
VPATH = \
.. \
../.. \
$(QPC)/src/qf \
$(QPC)/src/qxk \
$(QPC)/src/qs \
$(QP_PORT_DIR) \
$(QPC)/3rd_party/efm32pg1b \
$(QPC)/3rd_party/efm32pg1b/gnu
# list of all include directories needed by this project
INCLUDES = \
-I../.. \
-I$(QPC)/include \
-I$(QP_PORT_DIR) \
-I$(QPC)/3rd_party/CMSIS/Include \
-I$(QPC)/3rd_party/efm32pg1b
#-----------------------------------------------------------------------------
# files
#
# assembler source files
ASM_SRCS :=
# C source files
C_SRCS := \
bsp.c \
main.c \
philo.c \
table.c \
test.c \
startup_efm32pg1b.c \
system_efm32pg1b.c \
em_cmu.c \
em_emu.c \
em_gpio.c \
em_usart.c
# C++ source files
CPP_SRCS :=
OUTPUT := $(PROJECT)
LD_SCRIPT := $(PROJECT).ld
QP_SRCS := \
qep_hsm.c \
qep_msm.c \
qf_act.c \
qf_actq.c \
qf_defer.c \
qf_dyn.c \
qf_mem.c \
qf_ps.c \
qf_qact.c \
qf_qeq.c \
qf_qmact.c \
qf_time.c \
qxk.c \
qxk_xthr.c \
qxk_sema.c \
qxk_mutex.c \
qxk_port.c
QP_ASMS :=
QS_SRCS := \
qs.c \
qs_rx.c \
qs_fp.c
LIB_DIRS :=
LIBS :=
# defines
DEFINES := -DEFM32PG1B200F256GM48=1 \
-DQXK_ON_CONTEXT_SW \
-DQXK_USE_IRQ_HANDLER=CRYPTO_IRQHandler \
-DQXK_USE_IRQ_NUM=25 \
-DQ_NASSERT
# ARM CPU, ARCH, FPU, and Float-ABI types...
# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4]
# ARM_FPU: [ | vfp]
# FLOAT_ABI: [ | soft | softfp | hard]
#
ARM_CPU := -mcpu=cortex-m4
ARM_FPU := -mfpu=vfp
FLOAT_ABI := -mfloat-abi=softfp
#-----------------------------------------------------------------------------
# GNU-ARM toolset (NOTE: You need to adjust to your machine)
# see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads
#
ifeq ($(GNU_ARM),)
GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi
endif
# make sure that the GNU-ARM toolset exists...
ifeq ("$(wildcard $(GNU_ARM))","")
$(error GNU_ARM toolset not found. Please adjust the Makefile)
endif
CC := $(GNU_ARM)/bin/arm-none-eabi-gcc
CPP := $(GNU_ARM)/bin/arm-none-eabi-g++
AS := $(GNU_ARM)/bin/arm-none-eabi-as
LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc
BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy
##############################################################################
# Typically, you should not need to change anything below this line
# basic utilities (included in Qtools for Windows), see:
# http://sourceforge.net/projects/qpc/files/Qtools
MKDIR := mkdir
RM := rm
#-----------------------------------------------------------------------------
# build options for various configurations for ARM Cortex-M
#
# combine all the soruces...
C_SRCS += $(QP_SRCS)
ASM_SRCS += $(QP_ASMS)
ifeq (rel, $(CONF)) # Release configuration ..................................
BIN_DIR := rel
ASFLAGS = $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU)
CFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \
-std=c99 -pedantic -Wall -Wextra -W \
-ffunction-sections -fdata-sections \
-O1 $(INCLUDES) $(DEFINES) -DNDEBUG
CPPFLAGS = -c $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
-ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \
-O1 $(INCLUDES) $(DEFINES) -DNDEBUG
else ifeq (spy, $(CONF)) # Spy configuration ................................
BIN_DIR := spy
C_SRCS += $(QS_SRCS)
ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU)
CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \
-std=c99 -pedantic -Wall -Wextra -W \
-ffunction-sections -fdata-sections \
-O $(INCLUDES) $(DEFINES) -DQ_SPY
CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
-ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \
-O $(INCLUDES) $(DEFINES) -DQ_SPY
else # default Debug configuration ..........................................
BIN_DIR := dbg
ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU)
CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \
-std=c99 -pedantic -Wall -Wextra -W \
-ffunction-sections -fdata-sections \
-O $(INCLUDES) $(DEFINES)
CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \
-ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \
-O $(INCLUDES) $(DEFINES)
endif # ......................................................................
LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \
-specs=nosys.specs -specs=nano.specs \
-Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS)
ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS)))
C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS)))
CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS)))
TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin
TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf
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))
# create $(BIN_DIR) if it does not exist
ifeq ("$(wildcard $(BIN_DIR))","")
$(shell $(MKDIR) $(BIN_DIR))
endif
#-----------------------------------------------------------------------------
# rules
#
all: $(TARGET_BIN)
#all: $(TARGET_ELF)
$(TARGET_BIN): $(TARGET_ELF)
$(BIN) -O binary $< $@
$(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT)
$(CC) $(CFLAGS) $(QPC)/include/qstamp.c -o $(BIN_DIR)/qstamp.o
$(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS)
$(BIN_DIR)/%.d : %.c
$(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@
$(BIN_DIR)/%.d : %.cpp
$(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@
$(BIN_DIR)/%.o : %.s
$(AS) $(ASFLAGS) $< -o $@
$(BIN_DIR)/%.o : %.c
$(CC) $(CFLAGS) $< -o $@
$(BIN_DIR)/%.o : %.cpp
$(CPP) $(CPPFLAGS) $< -o $@
# include dependency files only if our goal depends on their existence
ifneq ($(MAKECMDGOALS),clean)
ifneq ($(MAKECMDGOALS),show)
-include $(C_DEPS_EXT) $(CPP_DEPS_EXT)
endif
endif
.PHONY : clean
clean:
-$(RM) $(BIN_DIR)/*.o \
$(BIN_DIR)/*.d \
$(BIN_DIR)/*.bin \
$(BIN_DIR)/*.elf \
$(BIN_DIR)/*.map
show:
@echo PROJECT = $(PROJECT)
@echo CONF = $(CONF)
@echo DEFINES = $(DEFINES)
@echo ASM_FPU = $(ASM_FPU)
@echo ASM_SRCS = $(ASM_SRCS)
@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 CPP_DEPS_EXT = $(CPP_DEPS_EXT)
@echo TARGET_ELF = $(TARGET_ELF)

View File

@ -44,6 +44,24 @@ script (.ld file), which provides a template of the recommended GCC linker
script for QP applications. script for QP applications.
Selecting QXK Exception
=======================
The QXK kernel needs a dedicated exception to return to the thread
context after preemption by a basic thread. The default is to use
the NMI exception for that purpose. However, in case NMI is needed
for some other purpose, the QXK port allows you to select a any,
otherwise unused IRQ for that purpose. To choose a given IRQ, you
need to define the macros QXK_USE_IRQ_NUM and QXK_USE_IRQ_HANDLER.
These macros can be provided on the command-line to the compiler.
For example, for the EFM32 MCU, you might dedicate the IRQ
"CRYPTO_IRQHandler" (see the vector table), with IRQ number 25,
as follows:
QXK_USE_IRQ_HANDLER=CRYPTO_IRQHandler
QXK_USE_IRQ_NUM=25
Startup Code Startup Code
============ ============
The startup code for the EFM32PG1B200F256GM48 MCU used in this project The startup code for the EFM32PG1B200F256GM48 MCU used in this project

View File

@ -41,7 +41,7 @@ MEMORY { /* memory map of Pearl Gecko EFM32PG1B200F256GM48 */
} }
/* The size of the stack used by the application. NOTE: you need to adjust */ /* The size of the stack used by the application. NOTE: you need to adjust */
STACK_SIZE = 1024; STACK_SIZE = 2048;
/* The size of the heap used by the application. NOTE: you need to adjust */ /* The size of the heap used by the application. NOTE: you need to adjust */
HEAP_SIZE = 0; HEAP_SIZE = 0;

View File

@ -1,13 +1,13 @@
::============================================================================ ::============================================================================
:: Batch file to program the flash of EFM32-SLSTK3401A board :: Batch file to program the flash of EFM32-SLSTK3401A board
:: ::
:: NOTE: requires the J-Link commander (JLink.exe) from SEGGER, see: :: NOTE: requires the J-Link commander (JLink.exe) from SEGGER, see:
:: https://www.segger.com/j-link-commander.html :: https://www.segger.com/j-link-commander.html
:: ::
setlocal setlocal
@echo off @echo off
@echo Load a given binary file to the flash of EFM32-SLSTK3401A @echo Load a given binary file to the flash of EFM32-SLSTK3401A
@echo usage: flash bin-file @echo usage: flash bin-file
@echo example: flash dbg\blinky-qk.bin @echo example: flash dbg\blinky-qk.bin
@ -17,7 +17,7 @@ setlocal
:: ::
if [%JLINK%] EQU [] set JLINK=%QTOOLS%\..\JLink if [%JLINK%] EQU [] set JLINK=%QTOOLS%\..\JLink
if not exist "%JLINK%\JLink.exe" ( if not exist "%JLINK%\JLink.exe" (
@echo The JLink tool not found. Please adjust flash.bat @echo The JLink tool not found. Please adjust flash.bat
@goto end @goto end
) )

View File

@ -15,7 +15,7 @@ relative location.
Stack Size and Heap Size Stack Size and Heap Size
------------------------ ------------------------
In this project, the size of the C stack and heap are determined in In this project, the size of the C stack and heap are determined in
the linker script blinky-qk.icf (see the next section). the linker script dpp-qxk.icf (see the next section).
Linker Script Linker Script
@ -26,6 +26,24 @@ application-specific sizes of the Stack and Heap. This file can be edited
from the IAR EWARM IDE via the Project Options/Linker settings. from the IAR EWARM IDE via the Project Options/Linker settings.
Selecting QXK Exception
=======================
The QXK kernel needs a dedicated exception to return to the thread
context after preemption by a basic thread. The default is to use
the NMI exception for that purpose. However, in case NMI is needed
for some other purpose, the QXK port allows you to select a any,
otherwise unused IRQ for that purpose. To choose a given IRQ, you
need to define the macros QXK_USE_IRQ_NUM and QXK_USE_IRQ_HANDLER.
These macros can be provided on the command-line to the compiler.
For example, for the EFM32 MCU, you might dedicate the IRQ
"CRYPTO_IRQHandler" (see the vector table), with IRQ number 25,
as follows:
QXK_USE_IRQ_HANDLER=CRYPTO_IRQHandler
QXK_USE_IRQ_NUM=25
Startup Code Startup Code
============ ============
The startup code for the TM4C123GH6PM MCU used in this project is The startup code for the TM4C123GH6PM MCU used in this project is

View File

@ -215,6 +215,9 @@
<option> <option>
<name>CCDefines</name> <name>CCDefines</name>
<state>EFM32PG1B200F256GM48</state> <state>EFM32PG1B200F256GM48</state>
<state>QXK_USE_IRQ_HANDLER=CRYPTO_IRQHandler</state>
<state>QXK_USE_IRQ_NUM=25</state>
<state>QXK_ON_CONTEXT_SW=1</state>
</option> </option>
<option> <option>
<name>CCPreprocFile</name> <name>CCPreprocFile</name>
@ -3271,255 +3274,6 @@
<name>QP_port</name> <name>QP_port</name>
<file> <file>
<name>$PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qxk\iar\qxk_port.c</name> <name>$PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qxk\iar\qxk_port.c</name>
<configuration>
<name>Debug</name>
<settings>
<name>ICCARM</name>
<data>
<version>37</version>
<wantNonLocal>0</wantNonLocal>
<debug>1</debug>
<option>
<name>CCOptimizationNoSizeConstraints</name>
<state>0</state>
</option>
<option>
<name>CCDefines</name>
<state>EFM32PG1B200F256GM48</state>
<state>QXK_USE_IRQ_NUM=25</state>
<state>QXK_USE_IRQ_HANDLER=CRYPTO_IRQHandler</state>
</option>
<option>
<name>CCPreprocFile</name>
<state>0</state>
</option>
<option>
<name>CCPreprocComments</name>
<state>0</state>
</option>
<option>
<name>CCPreprocLine</name>
<state>0</state>
</option>
<option>
<name>CCListCFile</name>
<state>0</state>
</option>
<option>
<name>CCListCMnemonics</name>
<state>0</state>
</option>
<option>
<name>CCListCMessages</name>
<state>0</state>
</option>
<option>
<name>CCListAssFile</name>
<state>0</state>
</option>
<option>
<name>CCListAssSource</name>
<state>0</state>
</option>
<option>
<name>CCEnableRemarks</name>
<state>0</state>
</option>
<option>
<name>CCDiagSuppress</name>
<state>Pa050</state>
</option>
<option>
<name>CCDiagRemark</name>
<state></state>
</option>
<option>
<name>CCDiagWarning</name>
<state></state>
</option>
<option>
<name>CCDiagError</name>
<state></state>
</option>
<option>
<name>CCObjPrefix</name>
<state>1</state>
</option>
<option>
<name>CCAllowList</name>
<version>1</version>
<state>00000000</state>
</option>
<option>
<name>CCDebugInfo</name>
<state>1</state>
</option>
<option>
<name>IEndianMode</name>
<state>1</state>
</option>
<option>
<name>IProcessor</name>
<state>1</state>
</option>
<option>
<name>IExtraOptionsCheck</name>
<state>0</state>
</option>
<option>
<name>IExtraOptions</name>
<state></state>
</option>
<option>
<name>CCLangConformance</name>
<state>0</state>
</option>
<option>
<name>CCSignedPlainChar</name>
<state>1</state>
</option>
<option>
<name>CCRequirePrototypes</name>
<state>1</state>
</option>
<option>
<name>CCDiagWarnAreErr</name>
<state>0</state>
</option>
<option>
<name>CCCompilerRuntimeInfo</name>
<state>0</state>
</option>
<option>
<name>IFpuProcessor</name>
<state>1</state>
</option>
<option>
<name>OutputFile</name>
<state>$FILE_BNAME$.o</state>
</option>
<option>
<name>CCLibConfigHeader</name>
<state>1</state>
</option>
<option>
<name>PreInclude</name>
<state></state>
</option>
<option>
<name>CCIncludePath2</name>
<state>$PROJ_DIR$\..</state>
<state>$PROJ_DIR$\..\..</state>
<state>$PROJ_DIR$\..\..\..\..\..\include</state>
<state>$PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qxk\iar</state>
<state>$PROJ_DIR$\..\..\..\..\..\3rd_party\CMSIS\Include</state>
<state>$PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b</state>
</option>
<option>
<name>CCStdIncCheck</name>
<state>0</state>
</option>
<option>
<name>CCCodeSection</name>
<state>.text</state>
</option>
<option>
<name>IProcessorMode2</name>
<state>1</state>
</option>
<option>
<name>CCOptLevel</name>
<state>1</state>
</option>
<option>
<name>CCOptStrategy</name>
<version>0</version>
<state>0</state>
</option>
<option>
<name>CCOptLevelSlave</name>
<state>1</state>
</option>
<option>
<name>CCPosIndRopi</name>
<state>0</state>
</option>
<option>
<name>CCPosIndRwpi</name>
<state>0</state>
</option>
<option>
<name>CCPosIndNoDynInit</name>
<state>0</state>
</option>
<option>
<name>IccLang</name>
<state>2</state>
</option>
<option>
<name>IccCDialect</name>
<state>1</state>
</option>
<option>
<name>IccAllowVLA</name>
<state>0</state>
</option>
<option>
<name>IccStaticDestr</name>
<state>0</state>
</option>
<option>
<name>IccCppInlineSemantics</name>
<state>0</state>
</option>
<option>
<name>IccCmsis</name>
<state>1</state>
</option>
<option>
<name>IccFloatSemantics</name>
<state>0</state>
</option>
<option>
<name>CCNoLiteralPool</name>
<state>0</state>
</option>
<option>
<name>CCOptStrategySlave</name>
<version>0</version>
<state>0</state>
</option>
<option>
<name>CCEncSource</name>
<state>0</state>
</option>
<option>
<name>CCEncOutput</name>
<state>0</state>
</option>
<option>
<name>CCEncOutputBom</name>
<state>1</state>
</option>
<option>
<name>CCEncInput</name>
<state>0</state>
</option>
<option>
<name>IccExceptions2</name>
<state>0</state>
</option>
<option>
<name>IccRTTI2</name>
<state>0</state>
</option>
<option>
<name>CCStackProtection</name>
<state>0</state>
</option>
</data>
</settings>
</configuration>
</file> </file>
</group> </group>
<group> <group>

View File

@ -9,7 +9,7 @@ define symbol __ICFEDIT_region_ROM_end__ = 0x0003FFFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__ = 0x20007FFF; define symbol __ICFEDIT_region_RAM_end__ = 0x20007FFF;
/*-Sizes-*/ /*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 1024; define symbol __ICFEDIT_size_cstack__ = 2048;
define symbol __ICFEDIT_size_heap__ = 0; define symbol __ICFEDIT_size_heap__ = 0;
/**** End of ICF editor section. ###ICF###*/ /**** End of ICF editor section. ###ICF###*/
@ -25,5 +25,5 @@ do not initialize { section .noinit };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in ROM_region { readonly }; place in ROM_region { readonly };
place at start of RAM_region {block CSTACK }; place at start of RAM_region {block CSTACK };
place in RAM_region { readwrite, block HEAP }; place in RAM_region { readwrite, block HEAP };

View File

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
* Product: DPP example extened for QXK * Product: DPP example extened for QXK
* Last updated for: @ref qpc_7_0_0 * Last updated for version 7.1.2
* Last updated on 2022-02-17 * Last updated on 2022-09-22
* *
* Q u a n t u m L e a P s * Q u a n t u m L e a P s
* ------------------------ * ------------------------
@ -64,13 +64,13 @@ int main() {
/* start the extended thread */ /* start the extended thread */
Test1_ctor(); /* instantiate the Test1 extended thread */ Test1_ctor(); /* instantiate the Test1 extended thread */
QXTHREAD_START(XT_Test1, /* Thread to start */ QXTHREAD_START(XT_Test1, /* Thread to start */
1U, /* QP priority of the thread */ 1U, /* QF-prio/pre-thre. */
test1QueueSto, /* message queue storage */ test1QueueSto, /* message queue storage */
Q_DIM(test1QueueSto), /* message length [events] */ Q_DIM(test1QueueSto), /* message length [events] */
test1StackSto, /* stack storage */ test1StackSto, /* stack storage */
sizeof(test1StackSto), /* stack size [bytes] */ sizeof(test1StackSto),/* stack size [bytes] */
(void *)0); /* initialization param */ (void *)0); /* initialization param */
/* NOTE: leave priority 2 free for a mutex */ /* NOTE: leave priority 2 free for a mutex */
@ -78,7 +78,7 @@ int main() {
for (uint8_t n = 0U; n < N_PHILO; ++n) { for (uint8_t n = 0U; n < N_PHILO; ++n) {
Philo_ctor(n); /* instantiate Philo[n] AO */ Philo_ctor(n); /* instantiate Philo[n] AO */
QACTIVE_START(AO_Philo[n], /* AO to start */ QACTIVE_START(AO_Philo[n], /* AO to start */
n + 3U, /* QP priority of the AO */ n + 3U, /* QF-prio/pre-thre. */
philoQueueSto[n], /* event queue storage */ philoQueueSto[n], /* event queue storage */
Q_DIM(philoQueueSto[n]), /* queue length [events] */ Q_DIM(philoQueueSto[n]), /* queue length [events] */
(void *)0, /* stack storage (not used) */ (void *)0, /* stack storage (not used) */
@ -89,14 +89,14 @@ int main() {
/* example of prioritizing the Ticker0 active object */ /* example of prioritizing the Ticker0 active object */
QTicker_ctor(&l_ticker0, 0U); /* ticker AO for tick rate 0 */ QTicker_ctor(&l_ticker0, 0U); /* ticker AO for tick rate 0 */
QACTIVE_START(the_Ticker0, QACTIVE_START(the_Ticker0,
N_PHILO + 3U, N_PHILO + 3U, /* QF-prio/pre-thre. */
0, 0U, 0, 0U, (void *)0); 0, 0U, 0, 0U, (void *)0);
/* NOTE: leave priority (N_PHILO + 4) free for mutex */ /* NOTE: leave priority (N_PHILO + 4) free for mutex */
Test2_ctor(); /* instantiate the Test2 extended thread */ Test2_ctor(); /* instantiate the Test2 extended thread */
QXTHREAD_START(XT_Test2, /* Thread to start */ QXTHREAD_START(XT_Test2, /* Thread to start */
N_PHILO + 5U, /* QP priority of the thread */ N_PHILO + 5U, /* QF-prio/pre-thre. */
test2QueueSto, /* message queue storage */ test2QueueSto, /* message queue storage */
Q_DIM(test2QueueSto), /* message length [events] */ Q_DIM(test2QueueSto), /* message length [events] */
test2StackSto, /* stack storage */ test2StackSto, /* stack storage */
@ -107,7 +107,7 @@ int main() {
Table_ctor(); /* instantiate the Table active object */ Table_ctor(); /* instantiate the Table active object */
QACTIVE_START(AO_Table, /* AO to start */ QACTIVE_START(AO_Table, /* AO to start */
N_PHILO + 7U, /* QP priority of the AO */ N_PHILO + 7U, /* QF-prio/pre-thre. */
tableQueueSto, /* event queue storage */ tableQueueSto, /* event queue storage */
Q_DIM(tableQueueSto), /* queue length [events] */ Q_DIM(tableQueueSto), /* queue length [events] */
(void *)0, /* stack storage (not used) */ (void *)0, /* stack storage (not used) */
@ -116,4 +116,3 @@ int main() {
return QF_run(); /* run the QF application */ return QF_run(); /* run the QF application */
} }

View File

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
* Product: DPP example * Product: DPP example
* Last updated for version 6.7.0 * Last updated for version 7.1.1
* Last updated on 2019-12-27 * Last updated on 2022-09-22
* *
* Q u a n t u m L e a P s * Q u a n t u m L e a P s
* ------------------------ * ------------------------
@ -38,8 +38,8 @@
/* local "extended" thread object ..........................................*/ /* local "extended" thread object ..........................................*/
static QXThread l_test1; static QXThread l_test1;
static QXThread l_test2; static QXThread l_test2;
static QXMutex l_mutex;
static QXSemaphore l_sema; static QXSemaphore l_sema;
static QXMutex l_mutex;
/* Thread-Local Storage for the "extended" threads .........................*/ /* Thread-Local Storage for the "extended" threads .........................*/
typedef struct { typedef struct {
@ -61,6 +61,8 @@ QXThread * const XT_Test2 = &l_test2;
static void Thread1_run(QXThread * const me) { static void Thread1_run(QXThread * const me) {
QS_OBJ_DICTIONARY(&l_test1); QS_OBJ_DICTIONARY(&l_test1);
QS_OBJ_DICTIONARY(&l_test1.timeEvt);
QS_OBJ_DICTIONARY(&l_mutex);
me->super.thread = &l_tls1; /* initialize the TLS for Thread1 */ me->super.thread = &l_tls1; /* initialize the TLS for Thread1 */
@ -104,6 +106,8 @@ void Test1_ctor(void) {
static void Thread2_run(QXThread * const me) { static void Thread2_run(QXThread * const me) {
QS_OBJ_DICTIONARY(&l_test2); QS_OBJ_DICTIONARY(&l_test2);
QS_OBJ_DICTIONARY(&l_test2.timeEvt);
QS_OBJ_DICTIONARY(&l_sema);
/* initialize the semaphore before using it /* initialize the semaphore before using it
* NOTE: the semaphore is initialized in the highest-priority thread * NOTE: the semaphore is initialized in the highest-priority thread
@ -120,7 +124,7 @@ static void Thread2_run(QXThread * const me) {
* before any thread runs. * before any thread runs.
*/ */
//QXMutex_init(&l_mutex, 0U); /* priority-ceiling NOT used */ //QXMutex_init(&l_mutex, 0U); /* priority-ceiling NOT used */
QXMutex_init(&l_mutex, N_PHILO + 6U); /*priority-ceiling protocol used*/ QXMutex_init(&l_mutex, N_PHILO + 6U); /* QF-prio./pre-thre. */
me->super.thread = &l_tls2; /* initialize the TLS for Thread2 */ me->super.thread = &l_tls2; /* initialize the TLS for Thread2 */

View File

@ -3,7 +3,7 @@
* Model: dpp.qm * Model: dpp.qm
* File: ${.::table.c} * File: ${.::table.c}
* *
* This code has been generated by QM 5.2.1 <www.state-machine.com/qm>. * This code has been generated by QM 5.2.2 <www.state-machine.com/qm>.
* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. * DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
* *
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
@ -106,6 +106,7 @@ static QState Table_initial(Table * const me, void const * const par) {
QActive_subscribe(&me->super, DONE_SIG); QActive_subscribe(&me->super, DONE_SIG);
QActive_subscribe(&me->super, PAUSE_SIG); QActive_subscribe(&me->super, PAUSE_SIG);
QActive_subscribe(&me->super, SERVE_SIG); QActive_subscribe(&me->super, SERVE_SIG);
QActive_subscribe(&me->super, EAT_SIG); //???
QActive_subscribe(&me->super, TEST_SIG); QActive_subscribe(&me->super, TEST_SIG);
for (uint8_t n = 0U; n < N_PHILO; ++n) { for (uint8_t n = 0U; n < N_PHILO; ++n) {
@ -127,7 +128,7 @@ static QState Table_active(Table * const me, QEvt const * const e) {
switch (e->sig) { switch (e->sig) {
/*${AOs::Table::SM::active::EAT} */ /*${AOs::Table::SM::active::EAT} */
case EAT_SIG: { case EAT_SIG: {
Q_ERROR_ID(60); //???Q_ERROR_ID(60);
status_ = Q_HANDLED(); status_ = Q_HANDLED();
break; break;
} }

View File

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
* Product: DPP example for Windows * Product: DPP example for Windows
* Last updated for version 6.4.0 * Last updated for version 7.1.2
* Last updated on 2019-02-08 * Last updated on 2022-10-06
* *
* Q u a n t u m L e a P s * Q u a n t u m L e a P s
* ------------------------ * ------------------------
@ -70,21 +70,21 @@ int main() {
/* start the active objects... */ /* start the active objects... */
for (n = 0U; n < N_PHILO; ++n) { for (n = 0U; n < N_PHILO; ++n) {
QACTIVE_START(AO_Philo[n], /* AO to start */ QACTIVE_START(AO_Philo[n], /* AO to start */
(uint_fast8_t)(n + 1), /* QP priority of the AO */ n + 1U, /* QF-priority */
philoQueueSto[n], /* event queue storage */ philoQueueSto[n], /* event queue storage */
Q_DIM(philoQueueSto[n]), /* queue length [events] */ Q_DIM(philoQueueSto[n]), /* queue length [events] */
(void *)0, /* stack storage (not used) */ (void *)0, /* stack storage (not used) */
0U, /* size of the stack [bytes] */ 0U, /* size of the stack [bytes] */
(QEvt *)0); /* initialization event */ (void *)0); /* initialization param */
} }
QACTIVE_START(AO_Table, /* AO to start */ QACTIVE_START(AO_Table, /* AO to start */
(uint_fast8_t)(N_PHILO + 1), /* QP priority of the AO */ N_PHILO + 1U, /* QF-priority */
tableQueueSto, /* event queue storage */ tableQueueSto, /* event queue storage */
Q_DIM(tableQueueSto), /* queue length [events] */ Q_DIM(tableQueueSto), /* queue length [events] */
(void *)0, /* stack storage (not used) */ (void *)0, /* stack storage (not used) */
0U, /* size of the stack [bytes] */ 0U, /* size of the stack [bytes] */
(QEvt *)0); /* initialization event */ (void *)0); /* initialization param */
return QF_run(); /* run the QF application */ return QF_run(); /* run the QF application */
} }

View File

@ -1,51 +0,0 @@
About this Example
==================
This directory contains the "DPP" (Dining Philosopher Problem) QP example
application for the EK-TM4C123GXL board (TivaC LauchPad). This directory
contains portable code that should compile with any C compiler for ARM
Cortex-M.
The sub-directories contain code and project files, which are
specific to the particular ARM toolchains, such as ARM (MDK-ARM),
GCC, and IAR.
Please refer to the README files in the sub-directories for specific
instructions how to use and customize the example to your needs.
Support Code for EK-TM4C123GXL Board
====================================
The directory qpc\3rd_party\ek-tm4c123gxl contains the CMSIS-
compliant device code for the TM4C123GH6PM MCU. Please see the README
file in this folder for more details.
QS Software Tracing Instrumentation
===================================
This example provides the "Spy" build configuration, which outputs
the QS (Quantum Spy) software tracing data through UART0, which is
connected to the virtual COM port of the TI Stellaris debugger.
The output is generated at 115200 baud rate.
Here is an example invocation of the QSPY host application to receive
the QS data from EK-TM4C123GXL:
qspy -cCOM1
The actual COM port number might be different on your Windows machine.
Please check the Device Manager to find the COM port number.
Win32 Emulations
================
The sub-directorie win32 and win32-qv provide the emulations of the example
on Windows GUI (with regular Win32 threads and with cooperative QV scheduler,
respectively. These sub-directories contain the Makefiles for the MinGW
toolset and Visual Studio solution files (game-gui.sln) for Visual C++.
The Win32 emulations use exactly the same code as the embedded board and
differ only in the Board Support Package (bsp.c). This example demonstrates
the "dual targeting" development approach, where most of the embedded code
is developed on the desktop machine (Windows), but is intended for a deeply
embedded target (EK-TM4C123GXL here).

View File

@ -3,7 +3,7 @@
* Model: dpp.qm * Model: dpp.qm
* File: ${.::dpp.h} * File: ${.::dpp.h}
* *
* This code has been generated by QM 5.2.1 <www.state-machine.com/qm>. * This code has been generated by QM 5.2.2 <www.state-machine.com/qm>.
* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. * DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
* *
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
@ -81,12 +81,12 @@ void Table_ctor(void);
extern QActive * const AO_Table; extern QActive * const AO_Table;
/*$enddecl${AOs::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ /*$enddecl${AOs::AO_Table} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
#ifdef QXK_H #ifdef QP_INC_QXK_H_
void Test1_ctor(void); void Test1_ctor(void);
extern QXThread * const XT_Test1; extern QXThread * const XT_Test1;
void Test2_ctor(void); void Test2_ctor(void);
extern QXThread * const XT_Test2; extern QXThread * const XT_Test2;
#endif /* QXK_H */ #endif /* QP_INC_QXK_H_ */
#endif /* DPP_H */ #endif /* DPP_H */

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<model version="5.2.1" links="1"> <model version="5.2.2" links="1">
<documentation>Dining Philosopher Problem example</documentation> <documentation>Dining Philosopher Problem example</documentation>
<!--${qpc}--> <!--${qpc}-->
<framework name="qpc"/> <framework name="qpc"/>
@ -431,12 +431,12 @@ $declare(AOs::AO_Philo[N_PHILO])
$declare(AOs::Table_ctor) $declare(AOs::Table_ctor)
$declare(AOs::AO_Table) $declare(AOs::AO_Table)
#ifdef QXK_H #ifdef QP_INC_QXK_H_
void Test1_ctor(void); void Test1_ctor(void);
extern QXThread * const XT_Test1; extern QXThread * const XT_Test1;
void Test2_ctor(void); void Test2_ctor(void);
extern QXThread * const XT_Test2; extern QXThread * const XT_Test2;
#endif /* QXK_H */ #endif /* QP_INC_QXK_H_ */
#endif /* DPP_H */ #endif /* DPP_H */
</text> </text>

View File

@ -3,7 +3,7 @@
* Model: dpp.qm * Model: dpp.qm
* File: ${.::philo.c} * File: ${.::philo.c}
* *
* This code has been generated by QM 5.2.1 <www.state-machine.com/qm>. * This code has been generated by QM 5.2.2 <www.state-machine.com/qm>.
* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. * DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
* *
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later

View File

@ -10,7 +10,7 @@
<aExt>*.s*; *.src; *.a*</aExt> <aExt>*.s*; *.src; *.a*</aExt>
<oExt>*.obj; *.o</oExt> <oExt>*.obj; *.o</oExt>
<lExt>*.lib</lExt> <lExt>*.lib</lExt>
<tExt>*.txt; *.h; *.inc</tExt> <tExt>*.txt; *.h; *.inc; *.md</tExt>
<pExt>*.plm</pExt> <pExt>*.plm</pExt>
<CppX>*.cpp</CppX> <CppX>*.cpp</CppX>
<nMigrate>0</nMigrate> <nMigrate>0</nMigrate>
@ -103,7 +103,7 @@
<bEvRecOn>1</bEvRecOn> <bEvRecOn>1</bEvRecOn>
<bSchkAxf>0</bSchkAxf> <bSchkAxf>0</bSchkAxf>
<bTchkAxf>0</bTchkAxf> <bTchkAxf>0</bTchkAxf>
<nTsel>8</nTsel> <nTsel>19</nTsel>
<sDll></sDll> <sDll></sDll>
<sDllPa></sDllPa> <sDllPa></sDllPa>
<sDlgDll></sDlgDll> <sDlgDll></sDlgDll>

View File

@ -10,7 +10,7 @@
<TargetName>dpp-dbg</TargetName> <TargetName>dpp-dbg</TargetName>
<ToolsetNumber>0x4</ToolsetNumber> <ToolsetNumber>0x4</ToolsetNumber>
<ToolsetName>ARM-ADS</ToolsetName> <ToolsetName>ARM-ADS</ToolsetName>
<pCCUsed>6130001::V6.13.1::.\ARMCLANG</pCCUsed> <pCCUsed>6160000::V6.16::ARMCLANG</pCCUsed>
<uAC6>1</uAC6> <uAC6>1</uAC6>
<TargetOption> <TargetOption>
<TargetCommonOption> <TargetCommonOption>
@ -185,6 +185,7 @@
<uocXRam>0</uocXRam> <uocXRam>0</uocXRam>
<RvdsVP>2</RvdsVP> <RvdsVP>2</RvdsVP>
<RvdsMve>0</RvdsMve> <RvdsMve>0</RvdsMve>
<RvdsCdeCp>0</RvdsCdeCp>
<hadIRAM2>0</hadIRAM2> <hadIRAM2>0</hadIRAM2>
<hadIROM2>0</hadIROM2> <hadIROM2>0</hadIROM2>
<StupSel>8</StupSel> <StupSel>8</StupSel>
@ -312,7 +313,7 @@
</ArmAdsMisc> </ArmAdsMisc>
<Cads> <Cads>
<interw>0</interw> <interw>0</interw>
<Optim>7</Optim> <Optim>1</Optim>
<oTime>0</oTime> <oTime>0</oTime>
<SplitLS>0</SplitLS> <SplitLS>0</SplitLS>
<OneElfS>1</OneElfS> <OneElfS>1</OneElfS>
@ -351,10 +352,10 @@
<NoWarn>0</NoWarn> <NoWarn>0</NoWarn>
<uSurpInc>1</uSurpInc> <uSurpInc>1</uSurpInc>
<useXO>0</useXO> <useXO>0</useXO>
<uClangAs>0</uClangAs> <ClangAsOpt>4</ClangAsOpt>
<VariousControls> <VariousControls>
<MiscControls></MiscControls> <MiscControls></MiscControls>
<Define>Stack_Size=1024 Heap_Size=16</Define> <Define>Stack_Size=2048 Heap_Size=16</Define>
<Undefine></Undefine> <Undefine></Undefine>
<IncludePath></IncludePath> <IncludePath></IncludePath>
</VariousControls> </VariousControls>
@ -600,7 +601,7 @@
<NoWarn>2</NoWarn> <NoWarn>2</NoWarn>
<uSurpInc>2</uSurpInc> <uSurpInc>2</uSurpInc>
<useXO>2</useXO> <useXO>2</useXO>
<uClangAs>2</uClangAs> <ClangAsOpt>0</ClangAsOpt>
<VariousControls> <VariousControls>
<MiscControls></MiscControls> <MiscControls></MiscControls>
<Define></Define> <Define></Define>
@ -814,6 +815,7 @@
<uocXRam>0</uocXRam> <uocXRam>0</uocXRam>
<RvdsVP>2</RvdsVP> <RvdsVP>2</RvdsVP>
<RvdsMve>0</RvdsMve> <RvdsMve>0</RvdsMve>
<RvdsCdeCp>0</RvdsCdeCp>
<hadIRAM2>0</hadIRAM2> <hadIRAM2>0</hadIRAM2>
<hadIROM2>0</hadIROM2> <hadIROM2>0</hadIROM2>
<StupSel>8</StupSel> <StupSel>8</StupSel>
@ -980,10 +982,10 @@
<NoWarn>0</NoWarn> <NoWarn>0</NoWarn>
<uSurpInc>1</uSurpInc> <uSurpInc>1</uSurpInc>
<useXO>0</useXO> <useXO>0</useXO>
<uClangAs>0</uClangAs> <ClangAsOpt>4</ClangAsOpt>
<VariousControls> <VariousControls>
<MiscControls></MiscControls> <MiscControls></MiscControls>
<Define>Stack_Size=1024 Heap_Size=16</Define> <Define>Stack_Size=2048 Heap_Size=16</Define>
<Undefine></Undefine> <Undefine></Undefine>
<IncludePath></IncludePath> <IncludePath></IncludePath>
</VariousControls> </VariousControls>
@ -1229,7 +1231,7 @@
<NoWarn>2</NoWarn> <NoWarn>2</NoWarn>
<uSurpInc>2</uSurpInc> <uSurpInc>2</uSurpInc>
<useXO>2</useXO> <useXO>2</useXO>
<uClangAs>2</uClangAs> <ClangAsOpt>0</ClangAsOpt>
<VariousControls> <VariousControls>
<MiscControls></MiscControls> <MiscControls></MiscControls>
<Define></Define> <Define></Define>
@ -1443,6 +1445,7 @@
<uocXRam>0</uocXRam> <uocXRam>0</uocXRam>
<RvdsVP>2</RvdsVP> <RvdsVP>2</RvdsVP>
<RvdsMve>0</RvdsMve> <RvdsMve>0</RvdsMve>
<RvdsCdeCp>0</RvdsCdeCp>
<hadIRAM2>0</hadIRAM2> <hadIRAM2>0</hadIRAM2>
<hadIROM2>0</hadIROM2> <hadIROM2>0</hadIROM2>
<StupSel>8</StupSel> <StupSel>8</StupSel>
@ -1609,10 +1612,10 @@
<NoWarn>0</NoWarn> <NoWarn>0</NoWarn>
<uSurpInc>1</uSurpInc> <uSurpInc>1</uSurpInc>
<useXO>0</useXO> <useXO>0</useXO>
<uClangAs>0</uClangAs> <ClangAsOpt>4</ClangAsOpt>
<VariousControls> <VariousControls>
<MiscControls></MiscControls> <MiscControls></MiscControls>
<Define>Stack_Size=1024 Heap_Size=16</Define> <Define>Stack_Size=2048 Heap_Size=16</Define>
<Undefine></Undefine> <Undefine></Undefine>
<IncludePath></IncludePath> <IncludePath></IncludePath>
</VariousControls> </VariousControls>

Some files were not shown because too many files have changed in this diff Show More