mirror of
https://github.com/QuantumLeaps/qpcpp.git
synced 2025-01-14 05:42:57 +08:00
7.3.5-rc.1
Semantic versioning
This commit is contained in:
parent
10441f7a03
commit
4028ad2dd6
@ -1 +1 @@
|
||||
Subproject commit db8b6155e6931d2c55315dfd55b0e1fac0f96e33
|
||||
Subproject commit 054cd1abe4b4abef5e45f36b1ce8f2aff4575494
|
130
README.md
130
README.md
@ -4,26 +4,25 @@
|
||||
|
||||
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/QuantumLeaps/qpcpp)](https://github.com/QuantumLeaps/qpcpp/releases/latest)
|
||||
|
||||
|
||||
View QP/C++ Revision History at: https://www.state-machine.com/qpcpp/history.html
|
||||
|
||||
> **NOTE:** If you're interested in the latest QP/C++ version from GitHub,
|
||||
it is highly recommended that you clone this repo like that:
|
||||
it is recommended that you clone this repo like that:
|
||||
|
||||
```
|
||||
git clone https://github.com/QuantumLeaps/qpcpp --recurse-submodules --depth 1
|
||||
```
|
||||
|
||||
Alternatively, you can also download the latest
|
||||
[QP/C++ Release](https://github.com/QuantumLeaps/qpcpp/releases).
|
||||
Alternatively, you can also download one of the stable
|
||||
[QP/C++ Releases][QP-Rel].
|
||||
|
||||
|
||||
# Getting Started with QP/C++
|
||||
The most recommended way of obtaining QP/C++ is by downloading the
|
||||
[QP-bundle](https://www.state-machine.com/#Downloads), which includes QP/C++
|
||||
as well as the QM modeling tool and the QTools collection. The main advantage of
|
||||
obtaining QP/C++ bundled together like that is that you get all components,
|
||||
tools and examples ready to go.
|
||||
as well as the [QM modeling tool][QM] and the [QTools collection][QTools].
|
||||
The main advantage of obtaining QP/C++ bundled together like that is
|
||||
that you get all components, tools and examples ready to go.
|
||||
|
||||
### Getting Started Resources
|
||||
- ["QP/C++ Tutorial"][Tutorial]
|
||||
@ -35,82 +34,96 @@ provides instructions on how to download, install, and get started with QP.
|
||||
- [AppNote: "Getting Started with QP Real-Time Embedded Frameworks"][AN]
|
||||
contains also a tutorial, in which you build a simple "Blinky" application.
|
||||
|
||||
## Licensing
|
||||
The QP frameworks (QP/C and QP/C++) are licensed under the
|
||||
[dual licensing model](https://www.state-machine.com/licensing), with
|
||||
the following licensing options:
|
||||
|
||||
1. [Open-source licensing](https://www.state-machine.com/licensing#Open) under the
|
||||
[GNU General Public License (GPLv3)](https://www.gnu.org/licenses/gpl-3.0.en.html).
|
||||
|
||||
> NOTE: GPL requires that all modifications to the original code
|
||||
as well as your application code (Derivative Works as defined in the
|
||||
Copyright Law) must also be released under the terms of the GPL
|
||||
open source license.
|
||||
|
||||
2. [Closed-source licensing](https://www.state-machine.com/licensing#Closed) under one of
|
||||
[Quantum Leaps commercial licenses](https://www.state-machine.com/licensing#Commercial),
|
||||
which are specifically designed for users interested in retaining the
|
||||
proprietary status of their code.
|
||||
|
||||
> NOTE: If your company has a policy forbidding open source in your product,
|
||||
all QP frameworks can be licensed commercially, in which case you don't use
|
||||
any open source license and you do not violate your policy.
|
||||
|
||||
|
||||
# About QP/C++
|
||||
QP/C++ (Quantum Platform in C++) is a lightweight, open source
|
||||
[Real-Time Embedded Framework (RTEF)][RTEF] for building modern embedded
|
||||
software as systems of asynchronous, event-driven [active objects][Active]
|
||||
software as systems of asynchronous, event-driven [Active Objects][Active]
|
||||
(actors). The [QP/C++] framework is a member of a [QP] family consisting of
|
||||
[QP/C] and [QP/C++] frameworks, which are strictly quality controlled,
|
||||
thoroughly documented, and [commercially licensable][Lic].
|
||||
|
||||
## Safer Model of Concurrency
|
||||
The [QP] framework family is based on the [Active Object][Active] (**actor**)
|
||||
design pattern, which inherently supports and automatically enforces the
|
||||
following best practices of concurrent programming:
|
||||
The [QP] framework family implements the
|
||||
[Active Object model of computation][AO_model], which is **inherently safer**
|
||||
than the traditional "shared state concurrency" based on explicit mutual
|
||||
exclusion and managing RTOS threads by blocking. The Active Object model
|
||||
supports and automatically enforces the following best practices
|
||||
of concurrent programming:
|
||||
|
||||
- Keep data isolated and bound to active objects' threads. Threads should
|
||||
- Keep data isolated and bound to Active Objects' threads. Threads should
|
||||
hide (**encapsulate**) their private data and other resources, and not
|
||||
share them with the rest of the system.
|
||||
|
||||
- Communicate among active object threads **asynchronously** via event
|
||||
objects. Using asynchronous events keeps the threads running truly
|
||||
- Communicate among Active Object threads **asynchronously** via [Event
|
||||
objects][Event]. Using asynchronous events keeps the threads running truly
|
||||
independently, **without blocking** on each other.
|
||||
|
||||
- Active object threads should spend their lifetime responding to incoming
|
||||
- Active Object threads should spend their lifetime responding to incoming
|
||||
events, so their mainline should consist of an **event-loop** that handles
|
||||
events one at a time (to completion), thus avoiding any concurrency hazards
|
||||
within an active object thread itself.
|
||||
within an Active Object thread itself.
|
||||
|
||||
This architecture is generally **safer**, more responsive and easier to
|
||||
understand and maintain than the shared-state concurrency of a conventional
|
||||
RTOS. It also provides higher level of abstraction and the *correct*
|
||||
abstractions to effectively apply **modeling** and **code generation** to
|
||||
deeply embedded real-time systems.
|
||||
This architecture also provides higher level of abstraction and the *correct*
|
||||
abstractions to effectively apply [Hierarchical State Machines][HSM],
|
||||
**modeling** and **code generation** to deeply embedded real-time systems.
|
||||
|
||||
## Hierarchical State Machines
|
||||
The behavior of active objects is specified in QP/C++ by means of
|
||||
The behavior of Active Objects is specified in QP/C++ by means of
|
||||
[Hierarchical State Machines][HSM] (UML statecharts). The framework
|
||||
supports manual coding of UML state machines in C as well as automatic
|
||||
**code generation** by means of the free [QM modeling tool][QM].
|
||||
|
||||
## Built-in Real-Time Kernels
|
||||
The QP/C++ framework can run on 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 QV kernel, the
|
||||
preemptive non-blocking QK kernel, and the preemptive, blocking QXK kernel
|
||||
that provides all the features you might expect from a traditional RTOS.
|
||||
Native QP ports and ready-to-use examples are provided for major CPUs, such
|
||||
as ARM Cortex-M (M0/M0+/M3/M4/M7).
|
||||
The QP/C++ framework can run on standalone on single-chip microcontrollers,
|
||||
without any traditional RTOS. The framework contains a selection of
|
||||
**built-in real-time kernels**, such as the [non-preemptive QV kernel][QV],
|
||||
the [preemptive non-blocking QK kernel][QK], and the preemptive,
|
||||
[dual-mode QXK kernel][QXK] that provides all the features you might expect
|
||||
from a traditional RTOS. Native QP ports and ready-to-use examples are provided
|
||||
for major CPUs, such as ARM Cortex-M (M0/M0+/M3/M4/M7/M23/M33/M85).
|
||||
|
||||
## Traditional RTOS/OS
|
||||
QP/C++ can also work with a traditional RTOS, such as ThreadX, FreeRTOS, embOS,
|
||||
uC/OS-II and TI-RTOS, as well as with (embedded) Linux (POSIX) and Windows.
|
||||
QP/C++ can also work with a traditional RTOS, such as ThreadX, embOS, FreeRTOS,
|
||||
uC/OS-II and Zephyr, as well as with (embedded) Linux (POSIX) and Windows.
|
||||
|
||||
## Popularity and Maturity
|
||||
With 20 years of continuous development, over [350 commercial licensees][Cust],
|
||||
and many times more open source users worldwide, the QP<EFBFBD> frameworks are the
|
||||
With 20 years of continuous development, [400+ commercial licensees][Cust],
|
||||
and many times more open source users worldwide, the QP frameworks are the
|
||||
most popular such offering on the market. They power countless electronic
|
||||
products ranging from implantable medical devices to complex weapon systems.
|
||||
|
||||
|
||||
# QP/C++ Licensing
|
||||
QP/C++ is licensed under the sustainable [dual licensing model][Lic],
|
||||
in which both the open source software distribution mechanism and
|
||||
traditional closed source software distribution models are combined.
|
||||
|
||||
> **NOTE:** If your company has a policy forbidding open source in your
|
||||
product, all QP frameworks can be [licensed commercially][Lic], in which case
|
||||
you don't use any open source license and you do not violate your policy.
|
||||
|
||||
|
||||
# QP/C++ Documentation
|
||||
The online HTML documentation for the **latest** version of QP/C++ is located
|
||||
at: https://www.state-machine.com/qpcpp
|
||||
|
||||
The offline HTML documentation for **this** particular version of QP/C++
|
||||
is located in the sub-folder [html](html). To view the offline documentation,
|
||||
open the file [html/index.html](html/index.html) in your web browser.
|
||||
is located in the sub-folder [html](html) (included in the [QP/C++ releases][QP-Rel]).
|
||||
To view the offline documentation, open the file [html/index.html](html/index.html)
|
||||
in your web browser.
|
||||
|
||||
|
||||
# How to Get Help?
|
||||
@ -127,16 +140,19 @@ If you like this project, please give it a star (in the upper-right corner of yo
|
||||
|
||||
![GitHub star](https://www.state-machine.com/img/github-star.jpg)
|
||||
|
||||
|
||||
[RTEF]: <https://www.state-machine.com/rtef>
|
||||
[QP]: <https://www.state-machine.com/products/qp>
|
||||
[QP/C]: <https://www.state-machine.com/qpc>
|
||||
[QP/C++]: <https://www.state-machine.com/qpcpp>
|
||||
[QM]: <https://www.state-machine.com/products/qm>
|
||||
[Active]: <https://www.state-machine.com/active-object>
|
||||
[HSM]: <https://www.state-machine.com/fsm#HSM>
|
||||
[Lic]: <https://www.state-machine.com/licensing>
|
||||
[Cust]: <https://www.state-machine.com/customers>
|
||||
[AN]: <https://www.state-machine.com/doc/AN_Getting_Started_with_QP.pdf>
|
||||
[RTEF]: <https://www.state-machine.com/rtef>
|
||||
[QP]: <https://www.state-machine.com/products/qp>
|
||||
[QP/C]: <https://github.com/QuantumLeaps/qpc>
|
||||
[QP/C++]: <https://github.com/QuantumLeaps/qpcpp>
|
||||
[QM]: <https://github.com/QuantumLeaps/qm>
|
||||
[QTools]: <https://github.com/QuantumLeaps/qtools>
|
||||
[QP-Rel]: <https://github.com/QuantumLeaps/qpcpp/releases>
|
||||
[Active]: <https://www.state-machine.com/qpcpp/srs-qp_ao.html>
|
||||
[AO_model]: <https://www.state-machine.com/qpcpp/srs-qp_ao.html#srs-qp_ao-model>
|
||||
[Event]: <https://www.state-machine.com/qpcpp/srs-qp_evt.html>
|
||||
[HSM]: <https://www.state-machine.com/qpcpp/srs-qp_sm.html>
|
||||
[Lic]: <https://www.state-machine.com/licensing>
|
||||
[Cust]: <https://www.state-machine.com/customers>
|
||||
[AN]: <https://www.state-machine.com/doc/AN_Getting_Started_with_QP.pdf>
|
||||
[Tutorial]: <https://www.state-machine.com/qpcpp/gs_tut.html>
|
||||
[Video]: <https://youtu.be/O7ER6_VqIH0>
|
||||
[Video]: <https://youtu.be/O7ER6_VqIH0>
|
||||
|
2
examples
2
examples
@ -1 +1 @@
|
||||
Subproject commit a4becf08ed700750fce0bfea22a8968349330e55
|
||||
Subproject commit 4c76095e91087b69c97ce5e602690210a97893af
|
@ -93,10 +93,6 @@ public:
|
||||
m_nFree(0U),
|
||||
m_nMin(0U)
|
||||
{}
|
||||
|
||||
#ifdef Q_XTOR
|
||||
~QEQueue();
|
||||
#endif // def Q_XTOR
|
||||
void init(
|
||||
QEvt const * qSto[],
|
||||
std::uint_fast16_t const qLen) noexcept;
|
||||
|
@ -118,10 +118,6 @@ public:
|
||||
m_nFree(0U),
|
||||
m_nMin(0U)
|
||||
{}
|
||||
|
||||
#ifdef Q_XTOR
|
||||
~QMPool();
|
||||
#endif // def Q_XTOR
|
||||
void init(
|
||||
void * const poolSto,
|
||||
std::uint_fast32_t const poolSize,
|
||||
|
@ -44,11 +44,9 @@
|
||||
#define QP_HPP_
|
||||
|
||||
//============================================================================
|
||||
#define QP_VERSION 733U
|
||||
#define QP_VERSION_STR "7.3.3"
|
||||
|
||||
//! Encrypted current QP release (7.3.3) and date (2024-03-01)
|
||||
#define QP_RELEASE 0x70C4F752U
|
||||
#define QP_VERSION_STR "7.3.5-rc.1"
|
||||
#define QP_VERSION 735U
|
||||
#define QP_RELEASE 0x70A1DEF0U
|
||||
|
||||
//============================================================================
|
||||
//! @cond INTERNAL
|
||||
@ -970,10 +968,6 @@ public:
|
||||
QActive * const act,
|
||||
QSignal const sig,
|
||||
std::uint_fast8_t const tickRate = 0U) noexcept;
|
||||
|
||||
#ifdef Q_XTOR
|
||||
~QTimeEvt();
|
||||
#endif // def Q_XTOR
|
||||
void armX(
|
||||
QTimeEvtCtr const nTicks,
|
||||
QTimeEvtCtr const interval = 0U) noexcept;
|
||||
|
@ -3,7 +3,7 @@
|
||||
// Model: qpc.qm
|
||||
// File: ${include::qsafe.h}
|
||||
//
|
||||
// This code has been generated by QM 5.3.0 <www.state-machine.com/qm>.
|
||||
// This code has been generated by QM 6.1.1 <www.state-machine.com/qm>.
|
||||
// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
|
||||
//
|
||||
// This code is covered by the following QP license:
|
||||
@ -150,6 +150,9 @@ extern "C" {
|
||||
//${QP-FuSa::Q_INVARIANT} ....................................................
|
||||
#define Q_INVARIANT(expr_) Q_ASSERT(expr_)
|
||||
|
||||
//${QP-FuSa::Q_INVARIANT_INCRIT} .............................................
|
||||
#define Q_INVARIANT_INCRIT(id_, expr_) Q_ASSERT_INCRIT((id_), (expr_))
|
||||
|
||||
//${QP-FuSa::Q_ASSERT_STATIC} ................................................
|
||||
#define Q_ASSERT_STATIC(expr_) extern char Q_static_assert_[(expr_) ? 1 : -1]
|
||||
|
||||
|
@ -27,8 +27,8 @@
|
||||
// <www.state-machine.com>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2023-12-04
|
||||
//! @version Last updated for: @ref qpcpp_7_3_1
|
||||
//! @date Last updated on: 2024-05-28
|
||||
//! @version Last updated for: @ref qpcpp_7_3_5
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QXK/C++ port to ARM Cortex-M, ARM-CLANG
|
||||
@ -385,10 +385,10 @@ __asm volatile (
|
||||
" MOVS r1,#1 \n"
|
||||
" LSLS r1,r1,#27 \n" // r1 := (1 << 27) (UNPENDSVSET bit)
|
||||
" LDR r2,=" STRINGIFY(SCB_ICSR) "\n" // Interrupt Control and State
|
||||
" STR r1,[r2] \n" // ICSR[27] := 1 (unpend PendSV)
|
||||
" STR r1,[r2] \n" // ICSR[27] := 1 (un-pend PendSV)
|
||||
|
||||
// Check QXK_priv_.next, which contains the pointer to the next thread
|
||||
// to run, which is set in QXK_ISR_EXIT(). This pointer must not be NULL.
|
||||
// to run, which is set in QXK_ISR_EXIT(). Return if QXK_priv_.next == 0
|
||||
" LDR r3,=QXK_priv_ \n"
|
||||
" LDR r0,[r3,#" STRINGIFY(QXK_NEXT) "]\n" // r1 := QXK_priv_.next
|
||||
" CMP r0,#0 \n" // is (QXK_priv_.next == 0)?
|
||||
@ -498,7 +498,7 @@ __asm volatile (
|
||||
" MOV lr,r2 \n" // make sure MSP is used
|
||||
#else // ARMv7-M or higher
|
||||
#ifdef __ARM_FP //--------- if VFP available...
|
||||
" POP {r0,lr} \n" // restore alighner and EXC_RETURN into lr
|
||||
" POP {r0,lr} \n" // restore aligner and EXC_RETURN into lr
|
||||
" DSB \n" // ARM Erratum 838869
|
||||
" TST lr,#(1 << 4) \n" // is it return to the VFP exception frame?
|
||||
" IT EQ \n" // if EXC_RETURN[4] is zero...
|
||||
@ -517,19 +517,18 @@ __asm volatile (
|
||||
" BCC PendSV_activate \n" // if (next->prio > actPrio) activate the next AO
|
||||
|
||||
// otherwise no activation needed...
|
||||
" MOVS r0,#0 \n"
|
||||
" STR r0,[r3,#" STRINGIFY(QXK_CURR) "]\n" // QXK_priv_.curr := 0
|
||||
" STR r0,[r3,#" STRINGIFY(QXK_NEXT) "]\n" // QXK_priv_.next := 0
|
||||
" MOVS r2,#0 \n"
|
||||
" STR r2,[r3,#" STRINGIFY(QXK_CURR) "]\n" // QXK_priv_.curr := 0
|
||||
" STR r2,[r3,#" STRINGIFY(QXK_NEXT) "]\n" // QXK_priv_.next := 0
|
||||
|
||||
" PUSH {r0,lr} \n" // save the aligner + EXC_RETURN
|
||||
#if defined(Q_SPY) || defined(QF_ON_CONTEXT_SW)
|
||||
// r0 is still 0 (parameter next) for QXK_contextSw_()
|
||||
" CMP r0,#0 \n" // r0 == QXK_priv_.next->prio
|
||||
" BEQ PendSV_idle \n" // if (QXK_priv_.next->prio != 0)
|
||||
" MOV r0,r12 \n" // r0 := parameter 'next' for QXK_contextSw_()
|
||||
"PendSV_idle: \n"
|
||||
" LDR r3,=QXK_contextSw_ \n"
|
||||
" BLX r3 \n" // call QXK_contextSw_()
|
||||
#ifdef QF_MEM_ISOLATE
|
||||
" LDR r3,=QF_onMemApp \n"
|
||||
" BLX r3 \n" // call QF_onMemApp()
|
||||
#endif
|
||||
#endif // defined(Q_SPY) || defined(QF_ON_CONTEXT_SW)
|
||||
" B PendSV_return1 \n" // skip over saving aligner + EXC_RETURN
|
||||
|
||||
@ -538,6 +537,10 @@ __asm volatile (
|
||||
" PUSH {r0,lr} \n" // save the aligner + EXC_RETURN
|
||||
|
||||
"PendSV_return1: \n"
|
||||
#ifdef QF_MEM_ISOLATE
|
||||
" LDR r3,=QF_onMemApp \n"
|
||||
" BLX r3 \n" // call QF_onMemApp()
|
||||
#endif
|
||||
" LDR r0,=QF_int_enable_ \n"
|
||||
" BLX r0 \n" // call QF_int_enable_()
|
||||
//>>>>>>>>>>>>>>>>>>>>>>>> CRITICAL SECTION END >>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
@ -600,7 +603,7 @@ __asm volatile (
|
||||
|
||||
" PUSH {r0-r2,lr} \n" // save next, osObject, EXC_RETURN
|
||||
#if defined(Q_SPY) || defined(QF_ON_CONTEXT_SW)
|
||||
" MOV r0,r12 \n" // parameter next
|
||||
" MOV r0,r12 \n" // r0 := parameter 'next' for QXK_contextSw_()
|
||||
" LDR r3,=QXK_contextSw_ \n"
|
||||
" BLX r3 \n" // call QXK_contextSw_()
|
||||
#ifdef QF_MEM_ISOLATE
|
||||
@ -753,7 +756,7 @@ __asm volatile (
|
||||
" ADD sp,sp,#(8*4) \n" // remove one 8-register exception frame
|
||||
|
||||
#ifdef __ARM_FP //--------- if VFP available...
|
||||
" POP {r0,lr} \n" // restore alighner and EXC_RETURN into lr
|
||||
" POP {r0,lr} \n" // restore aligher and EXC_RETURN into lr
|
||||
" DSB \n" // ARM Erratum 838869
|
||||
" TST lr,#(1 << 4) \n" // is it return to the VFP exception frame?
|
||||
" IT EQ \n" // if EXC_RETURN[4] is zero...
|
||||
|
@ -27,8 +27,8 @@
|
||||
// <www.state-machine.com>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-01-30
|
||||
//! @version Last updated for: @ref qpcpp_7_3_3
|
||||
//! @date Last updated on: 2024-05-28
|
||||
//! @version Last updated for: @ref qpcpp_7_3_5
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QXK/C++ port to ARM Cortex-M, GNU-ARM
|
||||
@ -390,10 +390,10 @@ __asm volatile (
|
||||
" MOV r1,#1 \n"
|
||||
" LSL r1,r1,#27 \n" // r1 := (1 << 27) (UNPENDSVSET bit)
|
||||
" LDR r2,=" STRINGIFY(SCB_ICSR) "\n" // Interrupt Control and State
|
||||
" STR r1,[r2] \n" // ICSR[27] := 1 (unpend PendSV)
|
||||
" STR r1,[r2] \n" // ICSR[27] := 1 (un-pend PendSV)
|
||||
|
||||
// Check QXK_priv_.next, which contains the pointer to the next thread
|
||||
// to run, which is set in QXK_ISR_EXIT(). This pointer must not be NULL.
|
||||
// to run, which is set in QXK_ISR_EXIT(). Return if QXK_priv_.next == 0
|
||||
" LDR r3,=QXK_priv_ \n"
|
||||
" LDR r0,[r3,#" STRINGIFY(QXK_NEXT) "]\n" // r1 := QXK_priv_.next
|
||||
" CMP r0,#0 \n" // is (QXK_priv_.next == 0)?
|
||||
@ -503,7 +503,7 @@ __asm volatile (
|
||||
" MOV lr,r2 \n" // make sure MSP is used
|
||||
#else // ARMv7-M or higher
|
||||
#ifdef __ARM_FP //--------- if VFP available...
|
||||
" POP {r0,lr} \n" // restore alighner and EXC_RETURN into lr
|
||||
" POP {r0,lr} \n" // restore aligner and EXC_RETURN into lr
|
||||
" DSB \n" // ARM Erratum 838869
|
||||
" TST lr,#(1 << 4) \n" // is it return to the VFP exception frame?
|
||||
" IT EQ \n" // if EXC_RETURN[4] is zero...
|
||||
@ -522,19 +522,18 @@ __asm volatile (
|
||||
" BCC PendSV_activate \n" // if (next->prio > actPrio) activate the next AO
|
||||
|
||||
// otherwise no activation needed...
|
||||
" MOV r0,#0 \n"
|
||||
" STR r0,[r3,#" STRINGIFY(QXK_CURR) "]\n" // QXK_priv_.curr := 0
|
||||
" STR r0,[r3,#" STRINGIFY(QXK_NEXT) "]\n" // QXK_priv_.next := 0
|
||||
" MOV r2,#0 \n"
|
||||
" STR r2,[r3,#" STRINGIFY(QXK_CURR) "]\n" // QXK_priv_.curr := 0
|
||||
" STR r2,[r3,#" STRINGIFY(QXK_NEXT) "]\n" // QXK_priv_.next := 0
|
||||
|
||||
" PUSH {r0,lr} \n" // save the aligner + EXC_RETURN
|
||||
#if defined(Q_SPY) || defined(QF_ON_CONTEXT_SW)
|
||||
// r0 is still 0 (parameter next) for QXK_contextSw_()
|
||||
" CMP r0,#0 \n" // r0 == QXK_priv_.next->prio
|
||||
" BEQ PendSV_idle \n" // if (QXK_priv_.next->prio != 0)
|
||||
" MOV r0,r12 \n" // r0 := parameter 'next' for QXK_contextSw_()
|
||||
"PendSV_idle: \n"
|
||||
" LDR r3,=QXK_contextSw_ \n"
|
||||
" BLX r3 \n" // call QXK_contextSw_()
|
||||
#ifdef QF_MEM_ISOLATE
|
||||
" LDR r3,=QF_onMemApp \n"
|
||||
" BLX r3 \n" // call QF_onMemApp()
|
||||
#endif
|
||||
#endif // defined(Q_SPY) || defined(QF_ON_CONTEXT_SW)
|
||||
" B PendSV_return1 \n" // skip over saving aligner + EXC_RETURN
|
||||
|
||||
@ -543,6 +542,10 @@ __asm volatile (
|
||||
" PUSH {r0,lr} \n" // save the aligner + EXC_RETURN
|
||||
|
||||
"PendSV_return1: \n"
|
||||
#ifdef QF_MEM_ISOLATE
|
||||
" LDR r3,=QF_onMemApp \n"
|
||||
" BLX r3 \n" // call QF_onMemApp()
|
||||
#endif
|
||||
" LDR r0,=QF_int_enable_ \n"
|
||||
" BLX r0 \n" // call QF_int_enable_()
|
||||
//>>>>>>>>>>>>>>>>>>>>>>>> CRITICAL SECTION END >>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
@ -605,7 +608,7 @@ __asm volatile (
|
||||
|
||||
" PUSH {r0-r2,lr} \n" // save next, osObject, EXC_RETURN
|
||||
#if defined(Q_SPY) || defined(QF_ON_CONTEXT_SW)
|
||||
" MOV r0,r12 \n" // parameter next
|
||||
" MOV r0,r12 \n" // r0 := parameter 'next' for QXK_contextSw_()
|
||||
" LDR r3,=QXK_contextSw_ \n"
|
||||
" BLX r3 \n" // call QXK_contextSw_()
|
||||
#ifdef QF_MEM_ISOLATE
|
||||
@ -758,7 +761,7 @@ __asm volatile (
|
||||
" ADD sp,sp,#(8*4) \n" // remove one 8-register exception frame
|
||||
|
||||
#ifdef __ARM_FP //--------- if VFP available...
|
||||
" POP {r0,lr} \n" // restore alighner and EXC_RETURN into lr
|
||||
" POP {r0,lr} \n" // restore aligher and EXC_RETURN into lr
|
||||
" DSB \n" // ARM Erratum 838869
|
||||
" TST lr,#(1 << 4) \n" // is it return to the VFP exception frame?
|
||||
" IT EQ \n" // if EXC_RETURN[4] is zero...
|
||||
|
@ -27,8 +27,8 @@
|
||||
// <www.state-machine.com>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2023-12-10
|
||||
//! @version Last updated for: @ref qpcpp_7_3_1
|
||||
//! @date Last updated on: 2024-05-28
|
||||
//! @version Last updated for: @ref qpcpp_7_3_5
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QXK/C++ port to ARM Cortex-M, IAR-ARM
|
||||
@ -389,10 +389,10 @@ __asm volatile (
|
||||
" MOVS r1,#1 \n"
|
||||
" LSLS r1,r1,#27 \n" // r1 := (1 << 27) (UNPENDSVSET bit)
|
||||
" LDR r2,=" STRINGIFY(SCB_ICSR) "\n" // Interrupt Control and State
|
||||
" STR r1,[r2] \n" // ICSR[27] := 1 (unpend PendSV)
|
||||
" STR r1,[r2] \n" // ICSR[27] := 1 (un-pend PendSV)
|
||||
|
||||
// Check QXK_priv_.next, which contains the pointer to the next thread
|
||||
// to run, which is set in QXK_ISR_EXIT(). This pointer must not be NULL.
|
||||
// to run, which is set in QXK_ISR_EXIT(). Return if QXK_priv_.next == 0
|
||||
" LDR r3,=QXK_priv_ \n"
|
||||
" LDR r0,[r3,#" STRINGIFY(QXK_NEXT) "]\n" // r1 := QXK_priv_.next
|
||||
" CMP r0,#0 \n" // is (QXK_priv_.next == 0)?
|
||||
@ -502,7 +502,7 @@ __asm volatile (
|
||||
" MOV lr,r2 \n" // make sure MSP is used
|
||||
#else // ARMv7-M or higher
|
||||
#ifdef __ARM_FP //--------- if VFP available...
|
||||
" POP {r0,lr} \n" // restore alighner and EXC_RETURN into lr
|
||||
" POP {r0,lr} \n" // restore aligner and EXC_RETURN into lr
|
||||
" DSB \n" // ARM Erratum 838869
|
||||
" TST lr,#(1 << 4) \n" // is it return to the VFP exception frame?
|
||||
" IT EQ \n" // if EXC_RETURN[4] is zero...
|
||||
@ -521,19 +521,18 @@ __asm volatile (
|
||||
" BCC PendSV_activate \n" // if (next->prio > actPrio) activate the next AO
|
||||
|
||||
// otherwise no activation needed...
|
||||
" MOVS r0,#0 \n"
|
||||
" STR r0,[r3,#" STRINGIFY(QXK_CURR) "]\n" // QXK_priv_.curr := 0
|
||||
" STR r0,[r3,#" STRINGIFY(QXK_NEXT) "]\n" // QXK_priv_.next := 0
|
||||
" MOVS r2,#0 \n"
|
||||
" STR r2,[r3,#" STRINGIFY(QXK_CURR) "]\n" // QXK_priv_.curr := 0
|
||||
" STR r2,[r3,#" STRINGIFY(QXK_NEXT) "]\n" // QXK_priv_.next := 0
|
||||
|
||||
" PUSH {r0,lr} \n" // save the aligner + EXC_RETURN
|
||||
#if defined(Q_SPY) || defined(QF_ON_CONTEXT_SW)
|
||||
// r0 is still 0 (parameter next) for QXK_contextSw_()
|
||||
" CMP r0,#0 \n" // r0 == QXK_priv_.next->prio
|
||||
" BEQ PendSV_idle \n" // if (QXK_priv_.next->prio != 0)
|
||||
" MOV r0,r12 \n" // r0 := parameter 'next' for QXK_contextSw_()
|
||||
"PendSV_idle: \n"
|
||||
" LDR r3,=QXK_contextSw_ \n"
|
||||
" BLX r3 \n" // call QXK_contextSw_()
|
||||
#ifdef QF_MEM_ISOLATE
|
||||
" LDR r3,=QF_onMemApp \n"
|
||||
" BLX r3 \n" // call QF_onMemApp()
|
||||
#endif
|
||||
#endif // defined(Q_SPY) || defined(QF_ON_CONTEXT_SW)
|
||||
" B PendSV_return1 \n" // skip over saving aligner + EXC_RETURN
|
||||
|
||||
@ -542,6 +541,10 @@ __asm volatile (
|
||||
" PUSH {r0,lr} \n" // save the aligner + EXC_RETURN
|
||||
|
||||
"PendSV_return1: \n"
|
||||
#ifdef QF_MEM_ISOLATE
|
||||
" LDR r3,=QF_onMemApp \n"
|
||||
" BLX r3 \n" // call QF_onMemApp()
|
||||
#endif
|
||||
" LDR r0,=QF_int_enable_ \n"
|
||||
" BLX r0 \n" // call QF_int_enable_()
|
||||
//>>>>>>>>>>>>>>>>>>>>>>>> CRITICAL SECTION END >>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
@ -604,7 +607,7 @@ __asm volatile (
|
||||
|
||||
" PUSH {r0-r2,lr} \n" // save next, osObject, EXC_RETURN
|
||||
#if defined(Q_SPY) || defined(QF_ON_CONTEXT_SW)
|
||||
" MOV r0,r12 \n" // parameter next
|
||||
" MOV r0,r12 \n" // r0 := parameter 'next' for QXK_contextSw_()
|
||||
" LDR r3,=QXK_contextSw_ \n"
|
||||
" BLX r3 \n" // call QXK_contextSw_()
|
||||
#ifdef QF_MEM_ISOLATE
|
||||
@ -757,7 +760,7 @@ __asm volatile (
|
||||
" ADD sp,sp,#(8*4) \n" // remove one 8-register exception frame
|
||||
|
||||
#ifdef __ARM_FP //--------- if VFP available...
|
||||
" POP {r0,lr} \n" // restore alighner and EXC_RETURN into lr
|
||||
" POP {r0,lr} \n" // restore aligher and EXC_RETURN into lr
|
||||
" DSB \n" // ARM Erratum 838869
|
||||
" TST lr,#(1 << 4) \n" // is it return to the VFP exception frame?
|
||||
" IT EQ \n" // if EXC_RETURN[4] is zero...
|
||||
|
@ -22,17 +22,18 @@
|
||||
// <www.state-machine.com>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-02-19
|
||||
//! @version Last updated for: @ref qpcpp_7_3_0
|
||||
//! @date Last updated on: 2024-05-01
|
||||
//! @version Last updated for version: 7.3.4
|
||||
//!
|
||||
//! @file
|
||||
//! @brief PC-Lint-Plus option file for linting QP/C++ source code
|
||||
|
||||
//============================================================================
|
||||
// general options
|
||||
-unit_check // perform only subset check (suppresses Global Wrapup)
|
||||
-max_threads=1 // suppress message "no '-max_threads=N' option"
|
||||
//-vf // print names of all source files (for debugging linting)
|
||||
-unit_check // perform only subset check (suppresses Global Wrapup)
|
||||
-max_threads=1 // suppress message "no '-max_threads=N' option"
|
||||
++efreeze(686) // never suppress (see PC-Lint-Plus in Safety-Critical)
|
||||
//-vf // print names of all source files (for debugging linting)
|
||||
|
||||
// include directories
|
||||
-i. // QP/C++ port includes (see also qk/ and qv/)
|
||||
@ -40,12 +41,8 @@
|
||||
|
||||
// standards
|
||||
au-autosar.lnt // AUTOSAR:C++14
|
||||
au-ds.lnt // Dan Saks recommendations
|
||||
au-ql-cpp11.lnt // Quantum Leaps coding standard for C++11
|
||||
|
||||
|
||||
// size/alignment options
|
||||
cpu.lnt // for the chosen CPU
|
||||
au-ds.lnt // Dan Saks recommendations
|
||||
cpu.lnt // size/alignment options for the chosen CPU
|
||||
|
||||
// defined macros (might be undefined on command-line with -u<macro>)
|
||||
-dQ_SPY
|
||||
@ -83,6 +80,7 @@ qpcpp.lnt // QP/C++ options
|
||||
Q_ASSERT_INCRIT,
|
||||
Q_REQUIRE_INCRIT,
|
||||
Q_ENSURE_INCRIT,
|
||||
Q_INVARIANT_INCRIT,
|
||||
Q_ERROR_INCRIT)
|
||||
|
||||
//! M4-D4.9(A) function-like macro
|
||||
|
6
ports/lint-plus2/16bit/cpu.lnt
Normal file
6
ports/lint-plus2/16bit/cpu.lnt
Normal file
@ -0,0 +1,6 @@
|
||||
// Size Options for 16bit CPU (e.g., MSP430)
|
||||
-si2 -sl4 -sll8 -ss2 -sw2 -sp2 -sf4 -sd8 -sld8
|
||||
|
||||
// Alignment options for 16bit CPU
|
||||
-ai2 -al2 -all2 -as2 -af4 -ad8 -ald8
|
||||
|
39
ports/lint-plus2/16bit/cstdint
Normal file
39
ports/lint-plus2/16bit/cstdint
Normal file
@ -0,0 +1,39 @@
|
||||
/// @file cstdint
|
||||
/// This is an emulation of a Standard C++ Library header for 16bit CPUs,
|
||||
/// like MSP430.
|
||||
|
||||
#ifndef _GLIBCXX_CSTDINT
|
||||
#define _GLIBCXX_CSTDINT
|
||||
|
||||
//lint -save
|
||||
//lint -e9093 AUTOSAR:M17-0-2 the name ... is reserved to the compiler
|
||||
//lint -e9145 AUTOSAR:M7-3-6 9145: using declaration in header
|
||||
|
||||
namespace std {
|
||||
|
||||
using int8_t = signed char; //!< exact-width 8-bit signed int
|
||||
using int16_t = signed int; //!< exact-width 16-bit signed int
|
||||
using int32_t = signed long int; //!< exact-width 32-bit signed int
|
||||
using int64_t = signed long long; //!< exact-width 64-bit signed int
|
||||
|
||||
using uint8_t = unsigned char; //!< exact-width 8-bit unsigned int
|
||||
using uint16_t = unsigned int; //!< exact-width 16-bit unsigned int
|
||||
using uint32_t = unsigned long int; //!< exact-width 32-bit unsigned int
|
||||
using uint64_t = unsigned long long; //!< exact-width 64-bit unsigned int
|
||||
|
||||
// Fastest minimum-width types. WG14/N843 C99 Standard, Section 7.18.1.3
|
||||
using int_fast8_t = signed int; //!< fast at-least 8-bit signed int
|
||||
using uint_fast8_t = unsigned int; //!< fast at-least 8-bit unsigned int
|
||||
using int_fast16_t = signed int; //!< fast at-least 16-bit signed int
|
||||
using uint_fast16_t = unsigned int; //!< fast at-least 16-bit unsigned int
|
||||
using int_fast32_t = signed long; //!< fast at-least 32-bit signed int
|
||||
using uint_fast32_t = unsigned long; //!< fast at-least 32-bit unsigned int
|
||||
|
||||
// unsigned integer type capable of holding a pointer to void.
|
||||
using uintptr_t = unsigned; //!< unsigned int capable of holding void*
|
||||
|
||||
} // namespace std
|
||||
|
||||
//lint -restore
|
||||
|
||||
#endif // _GLIBCXX_CSTDINT
|
58
ports/lint-plus2/16bit/qs_port.hpp
Normal file
58
ports/lint-plus2/16bit/qs_port.hpp
Normal file
@ -0,0 +1,58 @@
|
||||
//============================================================================
|
||||
// QP/C++ Real-Time Embedded Framework (RTEF)
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
//
|
||||
// This software is dual-licensed under the terms of the open source GNU
|
||||
// General Public License version 3 (or any later version), or alternatively,
|
||||
// under the terms of one of the closed source Quantum Leaps commercial
|
||||
// licenses.
|
||||
//
|
||||
// The terms of the open source GNU General Public License version 3
|
||||
// can be found at: <www.gnu.org/licenses/gpl-3.0>
|
||||
//
|
||||
// The terms of the closed source Quantum Leaps commercial licenses
|
||||
// can be found at: <www.state-machine.com/licensing>
|
||||
//
|
||||
// Redistributions in source code must retain this top-level comment block.
|
||||
// Plagiarizing this software to sidestep the license obligations is illegal.
|
||||
//
|
||||
// Contact information:
|
||||
// <www.state-machine.com>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2023-08-17
|
||||
//! @version Last updated for: @ref qpcpp_7_3_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QS/C++ port to a 32-bit CPU, generic C++ compiler
|
||||
//! @description
|
||||
//! This is an example QP/C++ port with the documentation for the main
|
||||
//! items, such as configuration macros, functions, and includes.
|
||||
|
||||
#ifndef QS_PORT_HPP_
|
||||
#define QS_PORT_HPP_
|
||||
|
||||
// QS time-stamp size in bytes
|
||||
#define QS_TIME_SIZE 4U
|
||||
|
||||
// object pointer size in bytes
|
||||
#define QS_OBJ_PTR_SIZE 2U
|
||||
|
||||
// function pointer size in bytes
|
||||
#define QS_FUN_PTR_SIZE 2U
|
||||
|
||||
//============================================================================
|
||||
// NOTE: QS might be used with or without other QP components, in which case
|
||||
// the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(),
|
||||
// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used with
|
||||
// the other QP component, by simply including "qp_port.hpp" *before* "qs.hpp".
|
||||
//
|
||||
#ifndef QP_PORT_HPP_
|
||||
#include "qp_port.hpp" // use QS with QP
|
||||
#endif
|
||||
|
||||
#include "qs.hpp" // QS platform-independent public interface
|
||||
|
||||
#endif // QS_PORT_HPP_
|
3
ports/lint-plus2/32bit/cpu.lnt
Normal file
3
ports/lint-plus2/32bit/cpu.lnt
Normal file
@ -0,0 +1,3 @@
|
||||
// Size Options for 32bit CPU (e.g., ARM Cortex-M)
|
||||
-si4 -sl4 -sll8 -ss2 -sw4 -sp4 -sf4 -sd8 -sld8
|
||||
|
39
ports/lint-plus2/32bit/cstdint
Normal file
39
ports/lint-plus2/32bit/cstdint
Normal file
@ -0,0 +1,39 @@
|
||||
/// @file cstdint
|
||||
/// This is an emulation of a Standard C++ Library header for 32bit CPUs,
|
||||
/// like ARM Cortex-M.
|
||||
|
||||
#ifndef _GLIBCXX_CSTDINT
|
||||
#define _GLIBCXX_CSTDINT
|
||||
|
||||
//lint -save
|
||||
//lint -e9093 AUTOSAR:M17-0-2 the name ... is reserved to the compiler
|
||||
//lint -e9145 AUTOSAR:M7-3-6 9145: using declaration in header
|
||||
|
||||
namespace std {
|
||||
|
||||
using int8_t = signed char; //!< exact-width 8-bit signed int
|
||||
using int16_t = signed short; //!< exact-width 16-bit signed int
|
||||
using int32_t = signed long; //!< exact-width 32-bit signed int
|
||||
using int64_t = signed long long; //!< exact-width 64-bit signed int
|
||||
|
||||
using uint8_t = unsigned char; //!< exact-width 8-bit unsigned int
|
||||
using uint16_t = unsigned short; //!< exact-width 16-bit unsigned int
|
||||
using uint32_t = unsigned long; //!< exact-width 32-bit unsigned int
|
||||
using uint64_t = unsigned long long; //!< exact-width 64-bit unsigned int
|
||||
|
||||
// Fastest minimum-width types. WG14/N843 C99 Standard, Section 7.18.1.3
|
||||
using int_fast8_t = signed int; //!< fast at-least 8-bit signed int
|
||||
using uint_fast8_t = unsigned int; //!< fast at-least 8-bit unsigned int
|
||||
using int_fast16_t = signed int; //!< fast at-least 16-bit signed int
|
||||
using uint_fast16_t = unsigned int; //!< fast at-least 16-bit unsigned int
|
||||
using int_fast32_t = signed long; //!< fast at-least 32-bit signed int
|
||||
using uint_fast32_t = unsigned long; //!< fast at-least 32-bit unsigned int
|
||||
|
||||
// unsigned integer type capable of holding a pointer to void.
|
||||
using uintptr_t = unsigned; //!< unsigned int capable of holding void*
|
||||
|
||||
} // namespace std
|
||||
|
||||
//lint -restore
|
||||
|
||||
#endif // _GLIBCXX_CSTDINT
|
61
ports/lint-plus2/32bit/qs_port.hpp
Normal file
61
ports/lint-plus2/32bit/qs_port.hpp
Normal file
@ -0,0 +1,61 @@
|
||||
//============================================================================
|
||||
// QP/C++ Real-Time Embedded Framework (RTEF)
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
//
|
||||
// This software is dual-licensed under the terms of the open source GNU
|
||||
// General Public License version 3 (or any later version), or alternatively,
|
||||
// under the terms of one of the closed source Quantum Leaps commercial
|
||||
// licenses.
|
||||
//
|
||||
// The terms of the open source GNU General Public License version 3
|
||||
// can be found at: <www.gnu.org/licenses/gpl-3.0>
|
||||
//
|
||||
// The terms of the closed source Quantum Leaps commercial licenses
|
||||
// can be found at: <www.state-machine.com/licensing>
|
||||
//
|
||||
// Redistributions in source code must retain this top-level comment block.
|
||||
// Plagiarizing this software to sidestep the license obligations is illegal.
|
||||
//
|
||||
// Contact information:
|
||||
// <www.state-machine.com>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2023-08-17
|
||||
//! @version Last updated for: @ref qpcpp_7_3_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QS/C++ port to a 32-bit CPU, generic C++ compiler
|
||||
//! @description
|
||||
//! This is an example QP/C++ port with the documentation for the main
|
||||
//! items, such as configuration macros, functions, and includes.
|
||||
|
||||
#ifndef QS_PORT_HPP_
|
||||
#define QS_PORT_HPP_
|
||||
|
||||
//! QS buffer counter size in bytes
|
||||
#define QS_CTR_SIZE 2U
|
||||
|
||||
//! QS time-stamp size in bytes
|
||||
#define QS_TIME_SIZE 4U
|
||||
|
||||
//! object pointer size in bytes
|
||||
#define QS_OBJ_PTR_SIZE 4U
|
||||
|
||||
//! function pointer size in bytes
|
||||
#define QS_FUN_PTR_SIZE 4U
|
||||
|
||||
//============================================================================
|
||||
// NOTE: QS might be used with or without other QP components, in which case
|
||||
// the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(),
|
||||
// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used with
|
||||
// the other QP component, by simply including "qp_port.hpp" *before* "qs.hpp".
|
||||
//
|
||||
#ifndef QP_PORT_HPP_
|
||||
#include "qp_port.hpp" // use QS with QP
|
||||
#endif
|
||||
|
||||
#include "qs.hpp" // QS platform-independent public interface
|
||||
|
||||
#endif // QS_PORT_HPP_
|
21
ports/lint-plus2/au-ds.lnt
Normal file
21
ports/lint-plus2/au-ds.lnt
Normal file
@ -0,0 +1,21 @@
|
||||
// au-ds.lnt -- Author options - Dan Saks
|
||||
|
||||
/*
|
||||
This options file can be used to explicitly activate those
|
||||
checks advocated by Dan Saks in his series of presentations on
|
||||
"C++ Gotchas".
|
||||
|
||||
You can use this file directly when linting your programs as in:
|
||||
|
||||
lin au-ds files
|
||||
|
||||
*/
|
||||
|
||||
+fsc // consider string constants as const char *
|
||||
+e1933 // turn on "virtual call from member detection"
|
||||
|
||||
// The rationale for the following two options are fully described
|
||||
// in Dan Saks' article "const T vs. T const". Visit his web site
|
||||
// at www.dansaks.com and click "Published Articles".
|
||||
//
|
||||
-fqb +e963 // require T const rather than const T
|
42
ports/lint-plus2/cstddef
Normal file
42
ports/lint-plus2/cstddef
Normal file
@ -0,0 +1,42 @@
|
||||
#ifndef _CSTDDEF_
|
||||
#define _CSTDDEF_
|
||||
|
||||
//lint -save
|
||||
//lint -e9093 the name is reserved to the compiler
|
||||
//lint -e9141 global declaration of symbol 'operator new'
|
||||
//lint -e9215 unnamed parameter for 'non-virtual' function 'operator new'
|
||||
|
||||
namespace std {
|
||||
using ptrdiff_t = unsigned int;
|
||||
using size_t = unsigned int;
|
||||
using max_align_t = unsigned int;
|
||||
using nullptr_t = decltype(nullptr);
|
||||
|
||||
enum class byte : unsigned char {};
|
||||
|
||||
// byte type operations
|
||||
template<class IntType>
|
||||
constexpr byte& operator<<=(byte& b, IntType shift) noexcept;
|
||||
template<class IntType>
|
||||
constexpr byte operator<<(byte b, IntType shift) noexcept;
|
||||
template<class IntType>
|
||||
constexpr byte& operator>>=(byte& b, IntType shift) noexcept;
|
||||
template<class IntType>
|
||||
constexpr byte operator>>(byte b, IntType shift) noexcept;
|
||||
constexpr byte& operator|=(byte& l, byte r) noexcept;
|
||||
constexpr byte operator|(byte l, byte r) noexcept;
|
||||
constexpr byte& operator&=(byte& l, byte r) noexcept;
|
||||
constexpr byte operator&(byte l, byte r) noexcept;
|
||||
constexpr byte& operator^=(byte& l, byte r) noexcept;
|
||||
constexpr byte operator^(byte l, byte r) noexcept;
|
||||
constexpr byte operator~(byte b) noexcept;
|
||||
template<class IntType>
|
||||
constexpr IntType to_integer(byte b) noexcept;
|
||||
}
|
||||
|
||||
#define NULL nullptr
|
||||
//#define offsetof(type, member) ...
|
||||
|
||||
//lint -restore
|
||||
|
||||
#endif // _CSTDDEF_
|
70
ports/lint-plus2/make.bat
Normal file
70
ports/lint-plus2/make.bat
Normal file
@ -0,0 +1,70 @@
|
||||
@echo off
|
||||
:: ===========================================================================
|
||||
:: Batch script for linting QP/C with PC-Lint-Plus2
|
||||
:: Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
::
|
||||
:: SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
::
|
||||
:: This software is dual-licensed under the terms of the open source GNU
|
||||
:: General Public License version 3 (or any later version), or alternatively,
|
||||
:: under the terms of one of the closed source Quantum Leaps commercial
|
||||
:: licenses.
|
||||
::
|
||||
:: The terms of the open source GNU General Public License version 3
|
||||
:: can be found at: <www.gnu.org/licenses/gpl-3.0>
|
||||
::
|
||||
:: The terms of the closed source Quantum Leaps commercial licenses
|
||||
:: can be found at: <www.state-machine.com/licensing>
|
||||
::
|
||||
:: Redistributions in source code must retain this top-level comment block.
|
||||
:: Plagiarizing this software to sidestep the license obligations is illegal.
|
||||
::
|
||||
:: Contact information:
|
||||
:: <www.state-machine.com>
|
||||
:: <info@state-machine.com>
|
||||
:: ===========================================================================
|
||||
@setlocal
|
||||
|
||||
:: usage of make.bat
|
||||
@echo Usage: make [16bit] [-u...] files
|
||||
@echo examples:
|
||||
@echo make -uQ_SPY -uQ_UTEST : use 32bit CPU (default) and undefine Q_SPY/Q_UTEST
|
||||
@echo make 16bit -uQ_SPY : use 16bit CPU includes and undefine Q_SPY
|
||||
@echo.
|
||||
|
||||
:: NOTE: adjust to for your installation directory of PC-Lint-Plus
|
||||
@set PCLP=C:\tools\lint-plus2.2-beta\windows
|
||||
@set PCLP_EXE=%PCLP%\pclp64.exe
|
||||
|
||||
if NOT exist "%PCLP%" (
|
||||
@echo The PC-Lint-Plus toolset not found. Please adjust make.bat
|
||||
@goto end
|
||||
)
|
||||
|
||||
:: set the QP/C++ directory
|
||||
set QPCPP=..\..
|
||||
|
||||
if "%1"=="16bit" (
|
||||
set LINTFLAGS=-i16bit options.lnt %1 %2 %3 %4
|
||||
@echo 16bit CPU
|
||||
) else (
|
||||
set LINTFLAGS=-i32bit options.lnt %1 %2 %3 %4
|
||||
@echo 32bit CPU default
|
||||
)
|
||||
|
||||
:: cleanup
|
||||
@del *.log
|
||||
|
||||
:: linting -------------------------------------------------------------------
|
||||
%PCLP_EXE% -os(lint_qf.log) std.lnt %LINTFLAGS% -iqv ..\..\src\qf\*.cpp
|
||||
|
||||
%PCLP_EXE% -os(lint_qv.log) std.lnt %LINTFLAGS% -iqv ..\..\src\qv\*.cpp
|
||||
|
||||
%PCLP_EXE% -os(lint_qk.log) std.lnt %LINTFLAGS% -iqk ..\..\src\qk\*.cpp
|
||||
|
||||
%PCLP_EXE% -os(lint_qxk.log) std.lnt %LINTFLAGS% -iqxk ..\..\src\qxk\*.cpp
|
||||
|
||||
%PCLP_EXE% -os(lint_qs.log) std.lnt %LINTFLAGS% -iqv ..\..\src\qs\*.cpp
|
||||
|
||||
:end
|
||||
@endlocal
|
406
ports/lint-plus2/options.lnt
Normal file
406
ports/lint-plus2/options.lnt
Normal file
@ -0,0 +1,406 @@
|
||||
//============================================================================
|
||||
// QP/C Real-Time Embedded Framework (RTEF)
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
//
|
||||
// This software is dual-licensed under the terms of the open source GNU
|
||||
// General Public License version 3 (or any later version), or alternatively,
|
||||
// under the terms of one of the closed source Quantum Leaps commercial
|
||||
// licenses.
|
||||
//
|
||||
// The terms of the open source GNU General Public License version 3
|
||||
// can be found at: <www.gnu.org/licenses/gpl-3.0>
|
||||
//
|
||||
// The terms of the closed source Quantum Leaps commercial licenses
|
||||
// can be found at: <www.state-machine.com/licensing>
|
||||
//
|
||||
// Redistributions in source code must retain this top-level comment block.
|
||||
// Plagiarizing this software to sidestep the license obligations is illegal.
|
||||
//
|
||||
// Contact information:
|
||||
// <www.state-machine.com>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-05-01
|
||||
//! @version Last updated for version: 7.3.4
|
||||
//!
|
||||
//! @file
|
||||
//! @brief PC-Lint-Plus option file for linting QP/C++ source code
|
||||
|
||||
//============================================================================
|
||||
// general options
|
||||
-unit_check // perform only subset check (suppresses Global Wrapup)
|
||||
-max_threads=1 // suppress message "no '-max_threads=N' option"
|
||||
++efreeze(686) // never suppress (see PC-Lint-Plus in Safety-Critical)
|
||||
//-vf // print names of all source files (for debugging linting)
|
||||
|
||||
// include directories
|
||||
-i%PCLP%/lnt // PC-Lint-Plus standard .lnt files
|
||||
-i. // QP/C++ port includes (see also qk/ and qv/)
|
||||
-i%QPCPP%/include // QP/C++ public includes
|
||||
|
||||
// standards
|
||||
au-autosar.lnt // AUTOSAR:C++14
|
||||
au-ds.lnt // Dan Saks recommendations
|
||||
cpu.lnt // size/alignment options for the chosen CPU
|
||||
|
||||
// defined macros (might be undefined on command-line with -u<macro>)
|
||||
-dQ_SPY
|
||||
-dQ_UTEST
|
||||
|
||||
//============================================================================
|
||||
// QP/C++ options for clients
|
||||
qpcpp.lnt // QP/C++ options
|
||||
|
||||
//============================================================================
|
||||
// additional suppression rules for building QP/C source code...
|
||||
|
||||
// general suppression for now...
|
||||
|
||||
// preprocessor directive ... is deprecated. [AUTOSAR Rule A16-0-1]
|
||||
-e586
|
||||
|
||||
// preprocessor directive encountered in conditionally excluded region
|
||||
// [AUTOSAR Rule A16-0-1], [AUTOSAR Rule A16-6-1]
|
||||
-e886
|
||||
|
||||
// friend ... in class
|
||||
-e9435
|
||||
|
||||
// symbol ... has array type
|
||||
-e9436
|
||||
|
||||
// enum ... is not a scoped enumeration [AUTOSAR Rule A7-2-3]
|
||||
-e9419
|
||||
|
||||
// QEP -----------------------------------------------------------------------
|
||||
|
||||
//! MC++R16-0-4 function-like macro ???
|
||||
-esym(9026,
|
||||
Q_ASSERT_INCRIT,
|
||||
Q_REQUIRE_INCRIT,
|
||||
Q_ENSURE_INCRIT,
|
||||
Q_INVARIANT_INCRIT,
|
||||
Q_ERROR_INCRIT)
|
||||
|
||||
//! M4-D4.9(A) function-like macro
|
||||
//! @tr{DVP-QP-MC4-D04_09B}
|
||||
-esym(9026,
|
||||
QHSM_RESERVED_EVT_,
|
||||
QS_STATE_ENTRY_,
|
||||
QS_STATE_EXIT_)
|
||||
|
||||
// implicit conversion of enum 'QP::QAsm::QStateRet' to integral type
|
||||
-esym(641,
|
||||
QP::QAsm::QStateRet)
|
||||
|
||||
// MC++R7-1-2 parameter of function could be pointer to const
|
||||
-esym(818,
|
||||
QP::QHsm::top)
|
||||
|
||||
// QF ------------------------------------------------------------------------
|
||||
|
||||
// MC++R16-0-4 function-like macro
|
||||
-esym(9026,
|
||||
QF_CRIT_ENTRY,
|
||||
QF_CRIT_EXIT,
|
||||
QF_MEM_SYS,
|
||||
QF_MEM_APP,
|
||||
QF_CONST_CAST_,
|
||||
QF_SCHED_LOCK_,
|
||||
QF_SCHED_UNLOCK_,
|
||||
QF_PTR_RANGE_,
|
||||
QF_MPOOL_EL,
|
||||
Q_ACTION_CAST,
|
||||
QTICKER_CAST_)
|
||||
|
||||
// MC++R16-0-4 function-like macro
|
||||
-esym(9026,
|
||||
QACTIVE_EQUEUE_WAIT_,
|
||||
QACTIVE_EQUEUE_SIGNAL_,
|
||||
QF_EPOOL_INIT_,
|
||||
QF_EPOOL_EVENT_SIZE_,
|
||||
QF_EPOOL_GET_,
|
||||
QF_EPOOL_PUT_)
|
||||
|
||||
// MC++R10-0-6 unparenthesized macro parameter in definition of macro
|
||||
-esym(9022,
|
||||
QF_CONST_CAST_)
|
||||
|
||||
// [AUTOSAR Rule A5-2-3] cast drops const qualifier
|
||||
-emacro(9005,
|
||||
QF_CONST_CAST_)
|
||||
|
||||
// M3-R11.3(r) cast from pointer to object type
|
||||
-emacro(9087,
|
||||
QTICKER_CAST_)
|
||||
|
||||
// suspicious pointer-to-pointer conversion (area too small)
|
||||
-emacro(826,
|
||||
QTICKER_CAST_)
|
||||
|
||||
// AC++M5-2-9 casting from pointer type to integer type
|
||||
-emacro(9091,
|
||||
Q_UINTPTR_CAST_)
|
||||
|
||||
// [AC++M12-1-1] non-static data member not initialized by ctor
|
||||
-esym(1401,
|
||||
QP::QEvt::*,
|
||||
QP::QActive::*)
|
||||
|
||||
// definition of macro ends in semi-colon
|
||||
-esym(823,
|
||||
QF_SCHED_STAT_)
|
||||
|
||||
// MC++5-2-8 conversion from integer type (0) to pointer type
|
||||
-emacro(9010,
|
||||
Q_ACTION_CAST)
|
||||
|
||||
|
||||
// M3-R11.8(r) cast drops const qualifier
|
||||
-emacro(9005,
|
||||
QF_EPOOL_PUT_)
|
||||
|
||||
// M3-D11.5(a) conversion from pointer to void to other pointer type
|
||||
-efunc(9079,
|
||||
QF_bzero)
|
||||
|
||||
// M3-R17.8(a) function parameter modified
|
||||
-efunc(9044,
|
||||
QF_LOG2,
|
||||
QMPool_init)
|
||||
|
||||
// M3-R18.1(r) potential out of bounds pointer access
|
||||
-emacro(661,
|
||||
QF_EPOOL_EVENT_SIZE_)
|
||||
|
||||
// AR-M5-2-8 conversion from pointer to void to other pointer type
|
||||
-emacro(9079,
|
||||
QF_EPOOL_GET_)
|
||||
|
||||
// M3-R18.3(r) relational operator <= applied to pointers
|
||||
-emacro(946,
|
||||
QF_PTR_RANGE_)
|
||||
|
||||
// M3-R8.13(a) parameter of function could be pointer to const
|
||||
-efunc(818,
|
||||
QP::QActive::start,
|
||||
QP::QTicker::postLIFO)
|
||||
|
||||
// MC++R0-1-1 statement is unreachable due to unconditional transfer
|
||||
// of control (assertion)
|
||||
//-efunc(527,
|
||||
// QP::QMActive::isIn,
|
||||
// QP::QMActive::state,
|
||||
// QP::QMActive::childState)
|
||||
|
||||
// MC++R7-1-1 parameter of function could be declared const
|
||||
-esym(952,
|
||||
QP::QEQueue::init)
|
||||
|
||||
// AC++M5-2-3: downcast of polymorphic type
|
||||
-efunc(9171,
|
||||
QP::QActive::post_,
|
||||
QP::QActive::postLIFO)
|
||||
|
||||
// BARR-C:2018 R 6.2c return statement before end of function
|
||||
-efunc(904,
|
||||
QP::QActive::post_,
|
||||
QP::QActive::postLIFO)
|
||||
|
||||
// [AC++M5-2-2]: casting from base class to derived class (QP::QActiveDummy)
|
||||
-efunc(1939,
|
||||
QP::QActive::post_,
|
||||
QP::QActive::postLIFO)
|
||||
|
||||
// PCLP-1731: public virtual function (in a class without virtual destructor)
|
||||
-esym(1731,
|
||||
QP::QTicker::*)
|
||||
|
||||
// PCLP-1933: call to unqualified virtual function from non-static member function
|
||||
-efunc(1933,
|
||||
QP::QActive::start)
|
||||
|
||||
// PCLP-9079:
|
||||
-efunc(9079,
|
||||
QP::QF::bzero_,
|
||||
QP::QTimeEvt::armX,
|
||||
QP::QTimeEvt::disarm,
|
||||
QP::QTimeEvt::rearm,
|
||||
QP::QMPool::init,
|
||||
QP::QMPool::get,
|
||||
QP::QMPool::put)
|
||||
|
||||
|
||||
// QV ------------------------------------------------------------------------
|
||||
// MC++R16-0-4 function-like macro
|
||||
-esym(9026,
|
||||
QV_CPU_SLEEP)
|
||||
|
||||
|
||||
// QK ------------------------------------------------------------------------
|
||||
|
||||
// MC++R16-0-4 function-like macro
|
||||
-esym(9026,
|
||||
QK_ISR_CONTEXT_,
|
||||
QK_ISR_ENTRY,
|
||||
QK_ISR_EXIT)
|
||||
|
||||
|
||||
// QXK -----------------------------------------------------------------------
|
||||
// MC++R16-0-4 function-like macro
|
||||
-esym(9026,
|
||||
QXK_ISR_CONTEXT_,
|
||||
QXK_CONTEXT_SWITCH_,
|
||||
QXK_PTR_CAST_,
|
||||
QXTHREAD_CAST_,
|
||||
QXTHREAD_EQUEUE_SIGNAL_)
|
||||
|
||||
// MC++R10-0-6 unparenthesized macro parameter in definition of macro
|
||||
-esym(9022,
|
||||
QXK_PTR_CAST_)
|
||||
|
||||
// MC++R5-2-7 pointer type converted to unrelated pointer
|
||||
-emacro(9176,
|
||||
Q_STATE_CAST)
|
||||
|
||||
// M3-R11.3(r) cast to pointer to different object type
|
||||
//-emacro(9087,
|
||||
// QXK_PTR_CAST_,
|
||||
// QXTHREAD_CAST_)
|
||||
|
||||
// MC++R5-2-7 pointer type converted to unrelated pointer type
|
||||
-emacro(9176,
|
||||
QXK_PTR_CAST_)
|
||||
|
||||
// MC++R5-2-3 downcast of polymorphic type ... to type ...
|
||||
-emacro(9171,
|
||||
QXK_PTR_CAST_)
|
||||
|
||||
// casting from base class 'QP::QActive' to derived class
|
||||
-emacro(1939,
|
||||
QXK_PTR_CAST_)
|
||||
|
||||
// suspicious pointer-to-pointer conversion (area too small)
|
||||
-emacro(826,
|
||||
QXK_PTR_CAST_,
|
||||
QXTHREAD_CAST_)
|
||||
|
||||
|
||||
// QS ------------------------------------------------------------------------
|
||||
// the following options are needed only when Q_SPY is defined
|
||||
|
||||
// MC++R16-0-4 function-like macro
|
||||
-esym(9026,
|
||||
QS_CRIT_ENTRY,
|
||||
QS_CRIT_EXIT,
|
||||
QS_MEM_SYS,
|
||||
QS_MEM_APP,
|
||||
QS_PTR_AT_,
|
||||
QS_PTR_INC_,
|
||||
QS_INSERT_BYTE_,
|
||||
QS_INSERT_ESC_BYTE_,
|
||||
QS_REC_NUM_)
|
||||
|
||||
// M3-R14.3(r) boolean condition for 'if' always evaluates to 'false'
|
||||
-emacro(774,,
|
||||
QS_INSERT_BYTE_,
|
||||
QS_INSERT_ESC_BYTE_,
|
||||
QS_BEGIN_PRE_,
|
||||
QS_BEGIN_PRE_)
|
||||
|
||||
// the right operand to << always evaluates to 0
|
||||
-emacro(845,
|
||||
QS_BEGIN_PRE_,
|
||||
QS_BEGIN_PRE_)
|
||||
|
||||
// excessive shift value (precision 3 shifted right by 3)
|
||||
-emacro(572,
|
||||
QS_BEGIN_PRE_,
|
||||
QS_BEGIN_PRE_)
|
||||
|
||||
// constant expression evaluates to 0 in 'binary' operation '>>'
|
||||
-emacro(778,
|
||||
QS_BEGIN_PRE_,
|
||||
QS_BEGIN_PRE_)
|
||||
|
||||
// constant value used in Boolean context
|
||||
-emacro(506,
|
||||
QS_BEGIN_PRE_,
|
||||
QS_BEGIN_PRE_)
|
||||
|
||||
// bitwise operator '>>' applied to signed underlying type [AS-M5-0-21]
|
||||
-emacro(9130,
|
||||
QS_BEGIN_PRE_,
|
||||
QS_BEGIN_PRE_)
|
||||
|
||||
// use of c-style cast to void [AS-A5-2-2]
|
||||
-emacro(1954,
|
||||
QS_END_PRE_)
|
||||
|
||||
// MC++R0-1-9 operator == always evaluates to true
|
||||
-emacro(948,
|
||||
QS_BEGIN_PRE_)
|
||||
|
||||
// MC++R0-1-1, MC++R0-1-2, MC++R0-1-9
|
||||
// left operand to '||' always evaluates to 'true'
|
||||
-emacro(944,
|
||||
QS_BEGIN_PRE_)
|
||||
|
||||
// MC++R5-2-9 casting from pointer type to integer type
|
||||
-emacro(9091,
|
||||
QS_OBJ_PRE_,
|
||||
QS_FUN_PRE_)
|
||||
|
||||
// M3-R11.6(r) explicit cast from 'void *volatile' to 'uint32_t'
|
||||
//-emacro(923,
|
||||
// QS_OBJ_PRE_,
|
||||
// QS_FUN_PRE_)
|
||||
|
||||
// M3-R11.1(4) conversion between pointer to function and differing type
|
||||
//-emacro(9074,
|
||||
// QS_FUN_PRE_)
|
||||
|
||||
// definition of macro ends in semi-colon
|
||||
-esym(823,
|
||||
QS_CRIT_STAT,
|
||||
QS_BEGIN_PRE_)
|
||||
|
||||
// union initialization
|
||||
-efunc(708,
|
||||
QS_f64_fmt_)
|
||||
|
||||
// M3-R19.2(a) union declared
|
||||
-efunc(9018,
|
||||
QS_f32_fmt_,
|
||||
QS_f64_fmt_)
|
||||
|
||||
// MC++R10-0-6 unparenthesized macro parameter in definition of macro
|
||||
-esym(9022,
|
||||
QS_TEST_PROBE,
|
||||
QS_TEST_PROBE_ID)
|
||||
|
||||
// AR M5-0-10 the result of the ~ operator applied to an object with an
|
||||
// underlying type of 'unsigned char' must be cast to 'unsigned char'
|
||||
// in this context
|
||||
-efunc(9126,
|
||||
QP::QS::glbFilter_,
|
||||
QP::QS::locFilter_)
|
||||
|
||||
// don't report problems within QS_target_info_() function
|
||||
-efunc(9130,
|
||||
QP::QS_target_info_)
|
||||
-efunc(9114,
|
||||
QP::QS_target_info_)
|
||||
-efunc(9117,
|
||||
QP::QS_target_info_)
|
||||
-efunc(9125,
|
||||
QP::QS_target_info_)
|
||||
-efunc(9112,
|
||||
QP::QS_target_info_)
|
||||
-efunc(9128,
|
||||
QP::QS_target_info_)
|
||||
-efunc(737,
|
||||
QP::QS_target_info_)
|
||||
|
101
ports/lint-plus2/qk/qp_port.hpp
Normal file
101
ports/lint-plus2/qk/qp_port.hpp
Normal file
@ -0,0 +1,101 @@
|
||||
//============================================================================
|
||||
// QP/C++ Real-Time Embedded Framework (RTEF)
|
||||
//
|
||||
// Q u a n t u m L e a P s
|
||||
// ------------------------
|
||||
// Modern Embedded Software
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
//
|
||||
// This software is dual-licensed under the terms of the open source GNU
|
||||
// General Public License version 3 (or any later version), or alternatively,
|
||||
// under the terms of one of the closed source Quantum Leaps commercial
|
||||
// licenses.
|
||||
//
|
||||
// The terms of the open source GNU General Public License version 3
|
||||
// can be found at: <www.gnu.org/licenses/gpl-3.0>
|
||||
//
|
||||
// The terms of the closed source Quantum Leaps commercial licenses
|
||||
// can be found at: <www.state-machine.com/licensing>
|
||||
//
|
||||
// Redistributions in source code must retain this top-level comment block.
|
||||
// Plagiarizing this software to sidestep the license obligations is illegal.
|
||||
//
|
||||
// Contact information:
|
||||
// <www.state-machine.com>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2023-09-07
|
||||
//! @version Last updated for: @ref qpcpp_7_3_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QP/C++ port for QK kernel, Generic C++11
|
||||
|
||||
#ifndef QP_PORT_HPP_
|
||||
#define QP_PORT_HPP_
|
||||
|
||||
#include <cstdint> // Exact-width types. C++11 Standard
|
||||
|
||||
#ifdef QP_CONFIG
|
||||
#include "qp_config.hpp" // external QP configuration
|
||||
#endif
|
||||
|
||||
// no-return function specifier (C++11 Standard)
|
||||
#define Q_NORETURN [[ noreturn ]] void
|
||||
|
||||
// QF configuration for QK -- data members of the QActive class...
|
||||
|
||||
// QK event-queue used for AOs
|
||||
#define QACTIVE_EQUEUE_TYPE QEQueue
|
||||
|
||||
// QF "thread" type used to store the MPU settings in the AO
|
||||
#define QACTIVE_THREAD_TYPE void const *
|
||||
|
||||
// interrupt disabling mechanism
|
||||
#define QF_INT_DISABLE() intDisable()
|
||||
#define QF_INT_ENABLE() intEnable()
|
||||
|
||||
// QF critical section mechanism
|
||||
#define QF_CRIT_STAT std::uint32_t crit_stat_;
|
||||
#define QF_CRIT_ENTRY() (crit_stat_ = critEntry())
|
||||
#define QF_CRIT_EXIT() critExit(crit_stat_)
|
||||
|
||||
// Check if the code executes in the ISR context
|
||||
#define QK_ISR_CONTEXT_() (QK_get_IPSR() != 0U)
|
||||
|
||||
// Define the ISR entry sequence
|
||||
#define QK_ISR_ENTRY() (static_cast<void>(0))
|
||||
|
||||
// Define the ISR exit sequence
|
||||
#define QK_ISR_EXIT() \
|
||||
do { \
|
||||
QF_INT_DISABLE(); \
|
||||
--QK_priv_.intNest; \
|
||||
if (QK_priv_.intNest == 0U) { \
|
||||
if (QK_sched_() != 0U) { \
|
||||
QK_activate_(); \
|
||||
} \
|
||||
} \
|
||||
QF_INT_ENABLE(); \
|
||||
} while (false)
|
||||
|
||||
extern "C" {
|
||||
|
||||
void intDisable(void);
|
||||
void intEnable(void);
|
||||
std::uint32_t critEntry(void);
|
||||
void critExit(std::uint32_t stat);
|
||||
std::uint32_t QK_get_IPSR(void);
|
||||
|
||||
} // extern "C"
|
||||
|
||||
// include files -------------------------------------------------------------
|
||||
#include "qequeue.hpp" // QK kernel uses the native QP event queue
|
||||
#include "qmpool.hpp" // QK kernel uses the native QP memory pool
|
||||
#include "qp.hpp" // QP framework
|
||||
#include "qk.hpp" // QK kernel
|
||||
|
||||
#endif // QP_PORT_HPP_
|
||||
|
459
ports/lint-plus2/qpcpp.lnt
Normal file
459
ports/lint-plus2/qpcpp.lnt
Normal file
@ -0,0 +1,459 @@
|
||||
//============================================================================
|
||||
// QP/C++ Real-Time Embedded Framework (RTEF)
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
//
|
||||
// This software is dual-licensed under the terms of the open source GNU
|
||||
// General Public License version 3 (or any later version), or alternatively,
|
||||
// under the terms of one of the closed source Quantum Leaps commercial
|
||||
// licenses.
|
||||
//
|
||||
// The terms of the open source GNU General Public License version 3
|
||||
// can be found at: <www.gnu.org/licenses/gpl-3.0>
|
||||
//
|
||||
// The terms of the closed source Quantum Leaps commercial licenses
|
||||
// can be found at: <www.state-machine.com/licensing>
|
||||
//
|
||||
// Redistributions in source code must retain this top-level comment block.
|
||||
// Plagiarizing this software to sidestep the license obligations is illegal.
|
||||
//
|
||||
// Contact information:
|
||||
// <www.state-machine.com>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-02-18
|
||||
//! @version Last updated for version: 7.3.3
|
||||
//!
|
||||
//! @file
|
||||
//! @brief PC-Lint-Plus option file for linting QP/C++ __Applications__
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// globally suppress the following warnings:
|
||||
-e546 // explicitly taking address of function
|
||||
-e717 // monocarpic do-while used to group statements
|
||||
-e1756 // variable has 'static' storage duration and non-POD type
|
||||
-e3412 // class has virtual functions but non-virtual destructor
|
||||
|
||||
// Assertions ----------------------------------------------------------------
|
||||
|
||||
// give Q_onError() the semantics of "exit"
|
||||
-function(exit,
|
||||
Q_onError)
|
||||
|
||||
// C-style array type [AUTOSAR Rule A18-1-1]
|
||||
-esym(9436,
|
||||
QP::versionStr)
|
||||
|
||||
// AC++M16-3-2 function-like macro
|
||||
-esym(9026,
|
||||
Q_DEFINE_THIS_MODULE,
|
||||
Q_ASSERT_STATIC,
|
||||
Q_ASSERT,
|
||||
Q_ASSERT_ID,
|
||||
Q_ERROR,
|
||||
Q_ERROR_ID,
|
||||
Q_REQUIRE,
|
||||
Q_REQUIRE_ID,
|
||||
Q_ENSURE,
|
||||
Q_ENSURE_ID,
|
||||
Q_INVARIANT,
|
||||
Q_INVARIANT_ID,
|
||||
Q_DIM)
|
||||
|
||||
// use of c-style cast to void [AS-A5-2-2]
|
||||
-emacro(1954,
|
||||
Q_ASSERT,
|
||||
Q_ASSERT_ID,
|
||||
Q_ERROR,
|
||||
Q_ERROR_ID,
|
||||
Q_REQUIRE,
|
||||
Q_REQUIRE_ID,
|
||||
Q_ENSURE,
|
||||
Q_ENSURE_ID,
|
||||
Q_INVARIANT,
|
||||
Q_INVARIANT_ID,
|
||||
Q_ASSERT_INCRIT)
|
||||
|
||||
// MC++R10-0-6 unparenthesized macro parameter in definition of macro
|
||||
-esym(9022,
|
||||
Q_DEFINE_THIS_FILE,
|
||||
Q_DEFINE_THIS_MODULE)
|
||||
|
||||
// definition of macro ends in semi-colon
|
||||
-esym(823,
|
||||
Q_DEFINE_THIS_FILE,
|
||||
Q_DEFINE_THIS_MODULE)
|
||||
|
||||
// AC++M16-3-2 function-like macro
|
||||
-esym(9026,
|
||||
Q_UNUSED_PAR,
|
||||
Q_DIM,
|
||||
Q_UINT2PTR_CAST,
|
||||
Q_UINTPTR_CAST_)
|
||||
|
||||
// MC++R5-2-4 use of c-style cast
|
||||
-emacro(1924,
|
||||
Q_ASSERT,
|
||||
Q_ASSERT_ID,
|
||||
Q_ERROR,
|
||||
Q_ERROR_ID)
|
||||
|
||||
|
||||
// QEP -----------------------------------------------------------------------
|
||||
|
||||
// MC++R7-3-1 global declaration of symbol
|
||||
-esym(9141,
|
||||
char_t,
|
||||
int_t,
|
||||
enum_t,
|
||||
float32_t,
|
||||
float64_t)
|
||||
|
||||
// AUTOSAR Rule A3-3-2 non-private data member within a non-POD structure
|
||||
// NOTE: public access needed for extern "C" functions
|
||||
-esym(9150,
|
||||
QP::QAsmAttr::*,
|
||||
QP::QAsm::*)
|
||||
|
||||
// AC++M16-3-2 function-like macro
|
||||
-esym(9026,
|
||||
INIT,
|
||||
DISPATCH,
|
||||
Q_STATE_DECL,
|
||||
Q_STATE_DEF,
|
||||
QM_STATE_DECL,
|
||||
QM_STATE_DEF,
|
||||
QM_SM_STATE_DECL,
|
||||
QM_ACTION_DECL,
|
||||
QM_ACTION_DEF,
|
||||
QHSM_INIT,
|
||||
QHSM_DISPATCH,
|
||||
Q_TRAN,
|
||||
Q_TRAN_HIST,
|
||||
Q_SUPER,
|
||||
Q_HANDLED,
|
||||
Q_UNHANDLED,
|
||||
QM_ENTRY,
|
||||
QM_EXIT,
|
||||
QM_SM_EXIT,
|
||||
QM_TRAN,
|
||||
QM_TRAN_INIT,
|
||||
QM_TRAN_HIST,
|
||||
QM_TRAN_EP,
|
||||
QM_TRAN_XP,
|
||||
QM_SUPER,
|
||||
QM_SUPER_SUB,
|
||||
QM_HANDLED,
|
||||
QM_UNHANDLED,
|
||||
Q_HSM_UPCAST,
|
||||
Q_EVT_CAST,
|
||||
Q_STATE_CAST,
|
||||
Q_UINT2PTR_CAST)
|
||||
|
||||
// MC++R5-2-8 conversion from pointer to other pointer type
|
||||
-emacro(9079,
|
||||
Q_EVT_CAST)
|
||||
|
||||
// MC++R5-2-2 casting from base class 'QP::QEvt' to derived class
|
||||
-emacro(1939,
|
||||
Q_EVT_CAST)
|
||||
|
||||
// MC++R10-0-6 unparenthesized macro parameter 'class_' in definition of macro
|
||||
-esym(9022,
|
||||
Q_EVT_CAST,
|
||||
Q_UINT2PTR_CAST,
|
||||
Q_STATE_DECL,
|
||||
Q_STATE_DEF,
|
||||
QM_STATE_DECL,
|
||||
QM_STATE_DEF,
|
||||
QM_SM_STATE_DECL,
|
||||
QM_ACTION_DECL,
|
||||
QM_ACTION_DEF,
|
||||
QEP_TRIG_,
|
||||
QEP_ENTER_,
|
||||
QEP_EXIT_)
|
||||
|
||||
// MC++16-3-1 multiple use of stringize/pasting operators in definition of macro
|
||||
-esym(9023,
|
||||
Q_STATE_DECL,
|
||||
Q_STATE_DEF,
|
||||
QM_STATE_DECL,
|
||||
QM_STATE_DEF,
|
||||
QM_SM_STATE_DECL,
|
||||
QM_ACTION_DEF)
|
||||
|
||||
// AC++M16-3-2 stringize operator used in definition of function-like macro
|
||||
-esym(9024,
|
||||
Q_STATE_DECL,
|
||||
Q_STATE_DEF,
|
||||
QM_STATE_DECL,
|
||||
QM_STATE_DEF,
|
||||
QM_SM_STATE_DECL,
|
||||
QM_ACTION_DECL,
|
||||
QM_ACTION_DEF)
|
||||
|
||||
// MC++R5-2-8 conversion from pointer to void to other pointer type
|
||||
-emacro(9079,
|
||||
Q_STATE_DEF,
|
||||
QM_STATE_DEF,
|
||||
QM_ACTION_DEF)
|
||||
|
||||
// MC++R9-3-3 member function could be made const
|
||||
-emacro(1762,
|
||||
Q_STATE_DEF,
|
||||
QM_STATE_DEF)
|
||||
|
||||
// MC++9-5-1 union declared
|
||||
-esym(9018,
|
||||
QP::QAsmAttr)
|
||||
|
||||
// MC++5-2-8 conversion from integer type (0) to pointer type
|
||||
-emacro(9010,
|
||||
Q_STATE_CAST)
|
||||
|
||||
// public virtual function 'QP::QHsm::...'
|
||||
-esym(1731,
|
||||
QP::QHsm::*,
|
||||
QP::QMsm::*)
|
||||
|
||||
|
||||
// QF ------------------------------------------------------------------------
|
||||
|
||||
// AUTOSAR Rule A3-3-2 non-private data member within a non-POD structure
|
||||
// NOTE: public access needed for extern "C" functions
|
||||
-esym(9150,
|
||||
QP::QF::QF_Attr::*)
|
||||
|
||||
// AC++M16-3-2 function-like macro
|
||||
-esym(9026,
|
||||
POST,
|
||||
POST_X,
|
||||
PUBLISH,
|
||||
TICK_X,
|
||||
TICK,
|
||||
TRIG,
|
||||
QF_INT_DISABLE,
|
||||
QF_INT_ENABLE,
|
||||
QF_CRIT_EXIT_NOP,
|
||||
QF_LOG2,
|
||||
Q_PRIO,
|
||||
Q_NEW,
|
||||
Q_NEW_X,
|
||||
Q_NEW_REF,
|
||||
Q_DELETE_REF,
|
||||
QF_INT_DISABLE,
|
||||
QF_INT_ENABLE,
|
||||
QF_MPOOL_EL)
|
||||
|
||||
// MC++R0-3-2 ignoring return value of function
|
||||
-emacro(534,
|
||||
POST)
|
||||
|
||||
// [AUTOSAR Rule M17-0-2] the name xxx is reserved to the compiler
|
||||
-esym(9093,
|
||||
remove) // QPrioSet::remove()
|
||||
|
||||
// MC++R5-2-7 pointer type converted to unrelated pointer type
|
||||
-emacro(9176,
|
||||
QF_QMACTIVE_TO_QMSM_CAST_,
|
||||
QF_QMACTIVE_TO_QMSM_CONST_CAST_)
|
||||
|
||||
// MC++R5-2-2 casting from base class 'QP::QEvt' to derived class
|
||||
-emacro(1939,
|
||||
Q_NEW,
|
||||
Q_NEW_X)
|
||||
|
||||
// MC++R10-0-6 unparenthesized macro parameter in definition of macro
|
||||
-esym(9022,
|
||||
Q_NEW,
|
||||
Q_NEW_X,
|
||||
Q_NEW_REF)
|
||||
|
||||
|
||||
// QK ------------------------------------------------------------------------
|
||||
|
||||
// AC++M16-3-2 function-like macro
|
||||
-esym(9026,
|
||||
QK_ISR_ENTRY,
|
||||
QK_ISR_EXIT)
|
||||
|
||||
// AC++M7-3-1 global declaration of symbol
|
||||
-esym(9141,
|
||||
QK_Attr)
|
||||
|
||||
// MC++R11-0-1 non-private data member within a non-POD structure
|
||||
// NOTE: public access needed for extern "C" functions
|
||||
-esym(9150,
|
||||
QK_Attr::*)
|
||||
|
||||
|
||||
// QXK -----------------------------------------------------------------------
|
||||
// MC++R16-0-4 function-like macro
|
||||
-esym(9026,
|
||||
QXK_ISR_ENTRY,
|
||||
QXK_ISR_EXIT,
|
||||
QXK_TLS)
|
||||
|
||||
// MC++R7-3-1 global declaration of symbol
|
||||
-esym(9141,
|
||||
QXK_Attr)
|
||||
|
||||
// MC++R10-0-6 unparenthesized macro parameter in definition of macro
|
||||
-esym(9022,
|
||||
QXK_TLS)
|
||||
|
||||
// MC++R5-2-8 conversion from pointer to void to other pointer type
|
||||
-emacro(9079,
|
||||
QXK_PTR_CAST_)
|
||||
|
||||
// MC++R5-2-2 casting from base class to derived class
|
||||
-emacro(1939,
|
||||
QXTHREAD_CAST_)
|
||||
|
||||
// MC++R5-2-3 downcast of polymorphic type
|
||||
-emacro(9171,
|
||||
QXTHREAD_CAST_)
|
||||
|
||||
// [AUTOSAR Rule M17-0-2] the name 'signal' is reserved to the compiler
|
||||
-esym(9093,
|
||||
signal)
|
||||
|
||||
// public virtual function 'QP::QXThread::...'
|
||||
-esym(1731,
|
||||
QP::QXThread::*)
|
||||
|
||||
// [AUTOSAR Rule M8-4-2] parameter of function has different name than
|
||||
// overridden function
|
||||
-esym(9272,
|
||||
QP::QXMutex::init*)
|
||||
|
||||
// function xxx matches the name of a standard library function
|
||||
-esym(8502,
|
||||
signal) // QXSemaphore::signal()
|
||||
|
||||
|
||||
// QS ------------------------------------------------------------------------
|
||||
|
||||
// AC++M16-3-2 function-like macro
|
||||
-esym(9026,
|
||||
QS_INIT,
|
||||
QS_EXIT,
|
||||
QS_DUMP,
|
||||
QS_RESET,
|
||||
QS_GLB_FILTER,
|
||||
QS_LOC_FILTER,
|
||||
QS_FILTER_AP_OBJ,
|
||||
QS_GET_BYTE,
|
||||
QS_GET_BLOCK,
|
||||
QS_BEGIN_ID,
|
||||
QS_END,
|
||||
QS_BEGIN_INCRIT,
|
||||
QS_END_INCRIT,
|
||||
QS_QF_CRIT_ENTRY,
|
||||
QS_QF_CRIT_EXIT,
|
||||
QS_QF_ISR_ENTRY,
|
||||
QS_QF_ISR_EXIT,
|
||||
QS_ONLY,
|
||||
QS_I8,
|
||||
QS_U8,
|
||||
QS_I16,
|
||||
QS_U16,
|
||||
QS_I32,
|
||||
QS_I64,
|
||||
QS_U32,
|
||||
QS_F32,
|
||||
QS_F64,
|
||||
QS_U64,
|
||||
QS_U32_HEX,
|
||||
QS_STR,
|
||||
QS_OBJ,
|
||||
QS_FUN,
|
||||
QS_SIG_DICTIONARY,
|
||||
QS_OBJ_DICTIONARY,
|
||||
QS_OBJ_ARR_DICTIONARY,
|
||||
QS_FUN_DICTIONARY,
|
||||
QS_USR_DICTIONARY,
|
||||
QS_ENUM_DICTIONARY,
|
||||
QS_ASSERTION,
|
||||
QS_FLUSH,
|
||||
QS_MEM,
|
||||
QS_ENUM,
|
||||
QS_SIG,
|
||||
QS_PTR_AT_,
|
||||
QS_RX_PUT,
|
||||
QS_OUTPUT,
|
||||
QS_RX_INPUT,
|
||||
QS_TEST_PAUSE,
|
||||
QS_TEST_PROBE_DEF,
|
||||
QS_TEST_PROBE,
|
||||
QS_TEST_PROBE_ID)
|
||||
|
||||
// AC++M16-3-2 function-like macro
|
||||
-esym(9026,
|
||||
QS_GLB_CHECK_,
|
||||
QS_LOC_CHECK_,
|
||||
QS_BEGIN_PRE_,
|
||||
QS_END_PRE_,
|
||||
QS_BEGIN_PRE_,
|
||||
QS_END_PRE_,
|
||||
QS_U8_PRE_,
|
||||
QS_2U8_PRE_,
|
||||
QS_U16_PRE_,
|
||||
QS_U32_PRE_,
|
||||
QS_STR_PRE_,
|
||||
QS_TIME_PRE_,
|
||||
QS_SIG_PRE_,
|
||||
QS_EVS_PRE_,
|
||||
QS_OBJ_PRE_,
|
||||
QS_FUN_PRE_,
|
||||
QS_EQC_PRE_,
|
||||
QS_MPC_PRE_,
|
||||
QS_MPS_PRE_,
|
||||
QS_TEC_PRE_)
|
||||
|
||||
// AC++M16-3-2 function-like macro
|
||||
-esym(9026,
|
||||
QS_REC_DONE)
|
||||
|
||||
// definition of macro ends in semi-colon
|
||||
-esym(823,
|
||||
QS_TEST_PROBE_DEF)
|
||||
|
||||
// M3-R11.1(r) conversion between pointer to function type
|
||||
-emacro(9074,
|
||||
QS_FUN_DICTIONARY,
|
||||
QS_TEST_PROBE_DEF)
|
||||
|
||||
// AC++M16-3-2 stringize operator used in definition of function-like macro
|
||||
-esym(9024,
|
||||
QS_OBJ_DICTIONARY,
|
||||
QS_OBJ_ARR_DICTIONARY,
|
||||
QS_FUN_DICTIONARY,
|
||||
QS_SIG_DICTIONARY,
|
||||
QS_USR_DICTIONARY,
|
||||
QS_ENUM_DICTIONARY)
|
||||
|
||||
// M3-R10.3(r) cannot assign enum to different essential type
|
||||
-emacro(9034,
|
||||
QS_SIG_DICTIONARY)
|
||||
|
||||
// implicit conversion of enum to integral type 'int'
|
||||
-emacro(641,
|
||||
QS_SIG_DICTIONARY)
|
||||
|
||||
// MC++R11-0-1 non-private data member within a non-POD structure
|
||||
-esym(9150,
|
||||
QP::QEvt::*,
|
||||
QP::QActive::*,
|
||||
QP::QF::Attr::*,
|
||||
QP::QS::QSrxPriv::*)
|
||||
|
||||
// MC++9-5-1 union declared
|
||||
-esym(9018,
|
||||
F32Rep,
|
||||
F64Rep,
|
||||
U32Rep,
|
||||
TCast,
|
||||
QP::QS::RxAttr::Variant)
|
||||
|
89
ports/lint-plus2/qv/qp_port.hpp
Normal file
89
ports/lint-plus2/qv/qp_port.hpp
Normal file
@ -0,0 +1,89 @@
|
||||
//============================================================================
|
||||
// QP/C++ Real-Time Embedded Framework (RTEF)
|
||||
//
|
||||
// Q u a n t u m L e a P s
|
||||
// ------------------------
|
||||
// Modern Embedded Software
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
//
|
||||
// This software is dual-licensed under the terms of the open source GNU
|
||||
// General Public License version 3 (or any later version), or alternatively,
|
||||
// under the terms of one of the closed source Quantum Leaps commercial
|
||||
// licenses.
|
||||
//
|
||||
// The terms of the open source GNU General Public License version 3
|
||||
// can be found at: <www.gnu.org/licenses/gpl-3.0>
|
||||
//
|
||||
// The terms of the closed source Quantum Leaps commercial licenses
|
||||
// can be found at: <www.state-machine.com/licensing>
|
||||
//
|
||||
// Redistributions in source code must retain this top-level comment block.
|
||||
// Plagiarizing this software to sidestep the license obligations is illegal.
|
||||
//
|
||||
// Contact information:
|
||||
// <www.state-machine.com>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2023-09-07
|
||||
//! @version Last updated for: @ref qpcpp_7_3_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QP/C++ port for QV kernel, Generic C++
|
||||
|
||||
#ifndef QP_PORT_HPP_
|
||||
#define QP_PORT_HPP_
|
||||
|
||||
#include <cstdint> // Exact-width types. C++11 Standard
|
||||
|
||||
#ifdef QP_CONFIG
|
||||
#include "qp_config.hpp" // external QP configuration
|
||||
#endif
|
||||
|
||||
// no-return function specifier (C++11 Standard)
|
||||
#define Q_NORETURN [[ noreturn ]] void
|
||||
|
||||
// QF configuration for QV -- data members of the QActive class...
|
||||
|
||||
// QV event-queue used for AOs
|
||||
#define QACTIVE_EQUEUE_TYPE QEQueue
|
||||
|
||||
// QF "thread" type used to store the MPU settings in the AO
|
||||
#define QACTIVE_THREAD_TYPE void const *
|
||||
|
||||
// interrupt disabling mechanism
|
||||
#define QF_INT_DISABLE() intDisable()
|
||||
#define QF_INT_ENABLE() intEnable()
|
||||
|
||||
// QF critical section mechanism
|
||||
#define QF_CRIT_STAT std::uint32_t crit_stat_;
|
||||
#define QF_CRIT_ENTRY() (crit_stat_ = critEntry())
|
||||
#define QF_CRIT_EXIT() critExit(crit_stat_)
|
||||
|
||||
#define QV_CPU_SLEEP() \
|
||||
do { \
|
||||
__disable_interrupt(); \
|
||||
QF_INT_ENABLE(); \
|
||||
__WFI(); \
|
||||
__enable_interrupt(); \
|
||||
} while (false)
|
||||
|
||||
extern "C" {
|
||||
|
||||
void intDisable(void);
|
||||
void intEnable(void);
|
||||
std::uint32_t critEntry(void);
|
||||
void critExit(std::uint32_t stat);
|
||||
|
||||
} // extern "C"
|
||||
|
||||
// include files -------------------------------------------------------------
|
||||
#include "qequeue.hpp" // QV kernel uses the native QP event queue
|
||||
#include "qmpool.hpp" // QV kernel uses the native QP memory pool
|
||||
#include "qp.hpp" // QP framework
|
||||
#include "qv.hpp" // QV kernel
|
||||
|
||||
#endif // QP_PORT_HPP_
|
||||
|
104
ports/lint-plus2/qxk/qp_port.hpp
Normal file
104
ports/lint-plus2/qxk/qp_port.hpp
Normal file
@ -0,0 +1,104 @@
|
||||
//============================================================================
|
||||
// QP/C++ Real-Time Embedded Framework (RTEF)
|
||||
//
|
||||
// Q u a n t u m L e a P s
|
||||
// ------------------------
|
||||
// Modern Embedded Software
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
//
|
||||
// This software is dual-licensed under the terms of the open source GNU
|
||||
// General Public License version 3 (or any later version), or alternatively,
|
||||
// under the terms of one of the closed source Quantum Leaps commercial
|
||||
// licenses.
|
||||
//
|
||||
// The terms of the open source GNU General Public License version 3
|
||||
// can be found at: <www.gnu.org/licenses/gpl-3.0>
|
||||
//
|
||||
// The terms of the closed source Quantum Leaps commercial licenses
|
||||
// can be found at: <www.state-machine.com/licensing>
|
||||
//
|
||||
// Redistributions in source code must retain this top-level comment block.
|
||||
// Plagiarizing this software to sidestep the license obligations is illegal.
|
||||
//
|
||||
// Contact information:
|
||||
// <www.state-machine.com>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2023-09-07
|
||||
//! @version Last updated for: @ref qpcpp_7_3_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QP/C++ port for QXK kernel, Generic C++
|
||||
|
||||
#ifndef QP_PORT_HPP_
|
||||
#define QP_PORT_HPP_
|
||||
|
||||
#include <cstdint> // Exact-width types. C++11 Standard
|
||||
|
||||
#ifdef QP_CONFIG
|
||||
#include "qp_config.hpp" // external QP configuration
|
||||
#endif
|
||||
|
||||
// no-return function specifier (C++11 Standard)
|
||||
#define Q_NORETURN [[ noreturn ]] void
|
||||
|
||||
// QF configuration for QXK -- data members of the QActive class...
|
||||
|
||||
// QXK event-queue type used for AOs and eXtended threads.
|
||||
#define QACTIVE_EQUEUE_TYPE QEQueue
|
||||
|
||||
// QXK OS-Object type used for the private stack pointer for eXtended threads.
|
||||
// (The private stack pointer is NULL for basic-threads).
|
||||
#define QACTIVE_OS_OBJ_TYPE void*
|
||||
|
||||
// QF "thread" type used to store the MPU settings in the AO
|
||||
#define QACTIVE_THREAD_TYPE void const *
|
||||
|
||||
// interrupt disabling mechanism
|
||||
#define QF_INT_DISABLE() intDisable()
|
||||
#define QF_INT_ENABLE() intEnable()
|
||||
|
||||
// QF critical section mechanism
|
||||
#define QF_CRIT_STAT std::uint32_t crit_stat_;
|
||||
#define QF_CRIT_ENTRY() (crit_stat_ = critEntry())
|
||||
#define QF_CRIT_EXIT() critExit(crit_stat_)
|
||||
|
||||
// Check if the code executes in the ISR context
|
||||
#define QXK_ISR_CONTEXT_() (QXK_get_IPSR() != 0U)
|
||||
|
||||
// Define the ISR entry sequence
|
||||
#define QXK_ISR_ENTRY() (static_cast<void>(0))
|
||||
|
||||
// Define the ISR exit sequence
|
||||
#define QXK_ISR_EXIT() do { \
|
||||
QF_INT_DISABLE(); \
|
||||
if (QXK_sched_() != 0U) { \
|
||||
*Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 28U);\
|
||||
} \
|
||||
QF_INT_ENABLE(); \
|
||||
} while (false)
|
||||
|
||||
#define QXK_CONTEXT_SWITCH_() (QXK_trigPendSV())
|
||||
|
||||
extern "C" {
|
||||
|
||||
void intDisable(void);
|
||||
void intEnable(void);
|
||||
std::uint32_t critEntry(void);
|
||||
void critExit(std::uint32_t stat);
|
||||
std::uint32_t QXK_get_IPSR(void);
|
||||
void QXK_trigPendSV(void);
|
||||
|
||||
} // extern "C"
|
||||
|
||||
// include files -------------------------------------------------------------
|
||||
#include "qequeue.hpp" // QK kernel uses the native QP event queue
|
||||
#include "qmpool.hpp" // QK kernel uses the native QP memory pool
|
||||
#include "qp.hpp" // QP framework
|
||||
#include "qxk.hpp" // QXK kernel
|
||||
|
||||
#endif // QP_PORT_HPP_
|
||||
|
45
ports/lint-plus2/std.lnt
Normal file
45
ports/lint-plus2/std.lnt
Normal file
@ -0,0 +1,45 @@
|
||||
//============================================================================
|
||||
// QP/C++ Real-Time Embedded Framework (RTEF)
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
//
|
||||
// This software is dual-licensed under the terms of the open source GNU
|
||||
// General Public License version 3 (or any later version), or alternatively,
|
||||
// under the terms of one of the closed source Quantum Leaps commercial
|
||||
// licenses.
|
||||
//
|
||||
// The terms of the open source GNU General Public License version 3
|
||||
// can be found at: <www.gnu.org/licenses/gpl-3.0>
|
||||
//
|
||||
// The terms of the closed source Quantum Leaps commercial licenses
|
||||
// can be found at: <www.state-machine.com/licensing>
|
||||
//
|
||||
// Redistributions in source code must retain this top-level comment block.
|
||||
// Plagiarizing this software to sidestep the license obligations is illegal.
|
||||
//
|
||||
// Contact information:
|
||||
// <www.state-machine.com>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2023-08-08
|
||||
//! @version Last updated for version: 7.3.0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief PC-Lint-Plus standard option file
|
||||
|
||||
// message formatting options...
|
||||
-hF1 // output: a single line
|
||||
+ffn // use full path names
|
||||
//-"format=%(\q%f\q %l %C%) %t %n: %m"
|
||||
//-width(0,0) // do not break lines
|
||||
-width(120,4) // break lines after 99 characters with 4 characters indent
|
||||
+flm // make sure no foreign includes change the format
|
||||
|
||||
+rw(inline, entry)
|
||||
|
||||
-zero(99) // don't stop because of warnings
|
||||
-passes(2) // make two passes (for better error messages)
|
||||
-restore_at_end // don't let -e<nn> options bleed to other files
|
||||
-summary() // produce a summary of all produced messages
|
||||
|
@ -1,226 +0,0 @@
|
||||
##############################################################################
|
||||
# QP/C++ Real-Time Embedded Framework (RTEF)
|
||||
#
|
||||
# Q u a n t u m L e a P s
|
||||
# ------------------------
|
||||
# Modern Embedded Software
|
||||
#
|
||||
# Copyright (C) 2005 Quantum Leaps, LLC, <state-machine.com>.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
#
|
||||
# This software is dual-licensed under the terms of the open source GNU
|
||||
# General Public License version 3 (or any later version), or alternatively,
|
||||
# under the terms of one of the closed source Quantum Leaps commercial
|
||||
# licenses.
|
||||
#
|
||||
# The terms of the open source GNU General Public License version 3
|
||||
# can be found at: <www.gnu.org/licenses/gpl-3.0>
|
||||
#
|
||||
# The terms of the closed source Quantum Leaps commercial licenses
|
||||
# can be found at: <www.state-machine.com/licensing>
|
||||
#
|
||||
# Redistributions in source code must retain this top-level comment block.
|
||||
# Plagiarizing this software to sidestep the license obligations is illegal.
|
||||
#
|
||||
# Contact information:
|
||||
# <www.state-machine.com>
|
||||
# <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://github.com/QuantumLeaps/qtools
|
||||
#
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# project name:
|
||||
#
|
||||
PROJECT := qp
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# project directories:
|
||||
#
|
||||
|
||||
# location of the QP/C++ framework
|
||||
QPCPP := ../..
|
||||
|
||||
# QP port used in this project
|
||||
QP_PORT_DIR := .
|
||||
|
||||
# list of all source directories used by this project
|
||||
VPATH = \
|
||||
$(QPCPP)/src/qf \
|
||||
$(QPCPP)/src/qs \
|
||||
$(QP_PORT_DIR)
|
||||
|
||||
# list of all include directories needed by this project
|
||||
INCLUDES = \
|
||||
-I$(QPCPP)/include \
|
||||
-I$(QPCPP)/src \
|
||||
-I$(QP_PORT_DIR)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# files
|
||||
#
|
||||
|
||||
# C source files
|
||||
C_SRCS := \
|
||||
qwin_gui.c
|
||||
|
||||
# C++ source files
|
||||
CPP_SRCS := \
|
||||
qep_hsm.cpp \
|
||||
qep_msm.cpp \
|
||||
qf_actq.cpp \
|
||||
qf_defer.cpp \
|
||||
qf_dyn.cpp \
|
||||
qf_mem.cpp \
|
||||
qf_ps.cpp \
|
||||
qf_qact.cpp \
|
||||
qf_qeq.cpp \
|
||||
qf_qmact.cpp \
|
||||
qf_time.cpp \
|
||||
qf_port.cpp
|
||||
|
||||
# C++ QS source files
|
||||
CPP_QS_SRCS := \
|
||||
qs.cpp \
|
||||
qs_rx.cpp \
|
||||
qs_fp.cpp \
|
||||
qs_64bit.cpp \
|
||||
qs_port.cpp
|
||||
|
||||
# defines:
|
||||
DEFINES := -DQWIN_GUI -DQP_API_VERSION=9999
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# MinGW toolset (NOTE: assumed to be on your PATH)
|
||||
#
|
||||
# NOTE:
|
||||
# MinGW toolset is included in the Qtools collection for Windows, see:
|
||||
# https://github.com/QuantumLeaps/qtools
|
||||
|
||||
CC := gcc
|
||||
CPP := g++
|
||||
LIB := ar
|
||||
|
||||
|
||||
##############################################################################
|
||||
# Typically, you should not need to change anything below this line
|
||||
|
||||
# basic utilities (included in Qtools for Windows), see:
|
||||
# https://github.com/QuantumLeaps/qtools
|
||||
|
||||
MKDIR := mkdir
|
||||
RM := rm
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# build options for various configurations
|
||||
#
|
||||
|
||||
LIBFLAGS := rs
|
||||
|
||||
ifeq (rel, $(CONF)) # Release configuration .................................
|
||||
|
||||
BIN_DIR := rel
|
||||
|
||||
# gcc options:
|
||||
CFLAGS := -c -O3 -fno-pie -std=c99 -pedantic -Wall -Wextra -W \
|
||||
$(INCLUDES) $(DEFINES) -DNDEBUG
|
||||
|
||||
CPPFLAGS := -c -O3 -fno-pie -std=c++11 -pedantic -Wall -Wextra \
|
||||
-fno-rtti -fno-exceptions \
|
||||
$(INCLUDES) $(DEFINES) -DNDEBUG
|
||||
|
||||
else ifeq (spy, $(CONF)) # Spy configuration ................................
|
||||
|
||||
BIN_DIR := spy
|
||||
|
||||
# add the QS sources...
|
||||
C_SRCS += $(C_QS_SRCS)
|
||||
|
||||
# gcc options:
|
||||
CFLAGS := -c -g -O -fno-pie -std=c99 -pedantic -Wall -Wextra -W \
|
||||
$(INCLUDES) $(DEFINES) -DQ_SPY
|
||||
|
||||
CPPFLAGS := -c -g -O -fno-pie -std=c++11 -pedantic -Wall -Wextra \
|
||||
-fno-rtti -fno-exceptions \
|
||||
$(INCLUDES) $(DEFINES) -DQ_SPY
|
||||
|
||||
else # default Debug configuration .........................................
|
||||
|
||||
BIN_DIR := dbg
|
||||
|
||||
# gcc options:
|
||||
CFLAGS := -c -g -O -fno-pie -std=c99 -pedantic -Wall -Wextra -W \
|
||||
$(INCLUDES) $(DEFINES)
|
||||
|
||||
CPPFLAGS := -c -g -O -fno-pie -std=c++11 -pedantic -Wall -Wextra \
|
||||
-fno-rtti -fno-exceptions \
|
||||
$(INCLUDES) $(DEFINES)
|
||||
|
||||
endif
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS)))
|
||||
CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS)))
|
||||
|
||||
TARGET_LIB := $(BIN_DIR)/lib$(PROJECT).a
|
||||
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_LIB)
|
||||
-$(RM) $(BIN_DIR)/*.o
|
||||
|
||||
$(TARGET_LIB) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT)
|
||||
$(LIB) $(LIBFLAGS) $@ $^
|
||||
|
||||
$(BIN_DIR)/%.o : %.c
|
||||
$(CC) $(CFLAGS) $< -o $@
|
||||
|
||||
$(BIN_DIR)/%.o : %.cpp
|
||||
$(CPP) $(CPPFLAGS) $< -o $@
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# the clean target
|
||||
#
|
||||
.PHONY : clean
|
||||
clean:
|
||||
-$(RM) $(BIN_DIR)/*.o $(TARGET_LIB)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# the show target for debugging
|
||||
#
|
||||
show:
|
||||
@echo PROJECT = $(PROJECT)
|
||||
@echo CONF = $(CONF)
|
||||
@echo TARGET_LIB = $(TARGET_LIB)
|
||||
@echo C_SRCS = $(C_SRCS)
|
||||
@echo CPP_SRCS = $(CPP_SRCS)
|
||||
@echo C_OBJS_EXT = $(C_OBJS_EXT)
|
||||
@echo C_DEPS_EXT = $(C_DEPS_EXT)
|
||||
@echo CPP_OBJS_EXT = $(CPP_OBJS_EXT)
|
||||
@echo CPP_DEPS_EXT = $(CPP_DEPS_EXT)
|
43
qpcpp.md5
43
qpcpp.md5
@ -1,51 +1,51 @@
|
||||
27d2d0d96374af4853a6a31a25ac3ef8 *qpcpp.qm
|
||||
da3f0e1d1bc147b9e5ee801bc1fdd130 *include/qequeue.hpp
|
||||
0c7051849804080425142a71b1e9b13b *qpcpp.qm
|
||||
2c7717f261e842ae0449a321d3c50f3e *include/qequeue.hpp
|
||||
fe1ff6084ff592ca8d14a6efffec296c *include/qk.hpp
|
||||
ebf2cb455c1471c2248bbde4b90ce634 *include/qmpool.hpp
|
||||
344c0ecb3d7f5645a5f4e75aea7956ac *include/qp.hpp
|
||||
0cf7c36bbbca2e0ebfe61347e9e572e5 *include/qmpool.hpp
|
||||
1290aa2707d23ea765a131a4c30d7ce9 *include/qp.hpp
|
||||
61c7a3aa8cb265f478915f39b7fae9cc *include/qp_pkg.hpp
|
||||
81e2fed348f03200d00b4d7c4473826f *include/qpcpp.hpp
|
||||
be2da5d56117fd172f12c8b6589f6402 *include/qs.hpp
|
||||
d59808009be96849963572ffcbf9dceb *include/qs_dummy.hpp
|
||||
db4013ceefb33498f5d38e15d0cb9323 *include/qs_pkg.hpp
|
||||
2a36b08d4f3ec92da6ae6f7c18ad83ca *include/qsafe.h
|
||||
f59bf88705afe5b0acc999f8b47a6745 *include/qsafe.h
|
||||
e66cf5dd191fb0e7c1f8660fb477b860 *include/qstamp.hpp
|
||||
d42a19307ba3c0c5b890431767f35b42 *include/qv.hpp
|
||||
c0bc33e3823dde00803a301c4b85637d *include/qxk.hpp
|
||||
ccc88dc7734a312ee0e33c437db7f3eb *src/qf/CMakeLists.txt
|
||||
88c84e634597fafced2012faea838750 *src/qf/qep_hsm.cpp
|
||||
becbd953c6da010daddf4907784e9766 *src/qf/qep_msm.cpp
|
||||
43c0ce7d29c9dd18691899c883b3f5eb *src/qf/qep_hsm.cpp
|
||||
dec4234285d4efd40b3ae6f680bc7179 *src/qf/qep_msm.cpp
|
||||
8b5c1ece58069ed5582864fd2dc58167 *src/qf/qf_act.cpp
|
||||
8fca896aa3dee712f6c844a0f31c130e *src/qf/qf_actq.cpp
|
||||
eba1e6d624f4b1c7c82b2f98ef3e9198 *src/qf/qf_actq.cpp
|
||||
39b02b596faa57abfa96b0f7c3f7fb82 *src/qf/qf_defer.cpp
|
||||
069220fa20ca5bd9e0ddfcb2f4f8f0ba *src/qf/qf_dyn.cpp
|
||||
0d3572af3a2acbf7144b27be35fa018a *src/qf/qf_mem.cpp
|
||||
40218fcd6cbb521f2c8ae5f7c0d5c04e *src/qf/qf_ps.cpp
|
||||
7b797a3a69836d0aba3c600130606f01 *src/qf/qf_dyn.cpp
|
||||
f23875214b4c4c905bdb0567d900b36b *src/qf/qf_mem.cpp
|
||||
37cfa5b9419f1e00608267ff29fbc1a8 *src/qf/qf_ps.cpp
|
||||
19cf8976578a43e93bfbb51dbe932b6c *src/qf/qf_qact.cpp
|
||||
46f954811c55e933e016bb36ab22adcd *src/qf/qf_qeq.cpp
|
||||
816dc7182f4014539f6f5304782ddb7b *src/qf/qf_qmact.cpp
|
||||
c49e1c15e6d6e035668d910c8d13a684 *src/qf/qf_time.cpp
|
||||
c551aafbf9ecba93cfdb12f81fbfba61 *src/qf/qf_time.cpp
|
||||
4dc7ca60248f4c13034e6f2481c7663d *src/qk/CMakeLists.txt
|
||||
5670063d7e71927b7d5c98a6db38c351 *src/qk/qk.cpp
|
||||
1a314e2a9fba927f6648772121790c5f *src/qk/qk.cpp
|
||||
2557d617414f8cbdcbfeaab619d296bb *src/qs/CMakeLists.txt
|
||||
ecdd6f0f0a7dc56d8bb0c769e67b48fc *src/qs/qs.cpp
|
||||
bd1870c2a952b47ef613cc67406aca80 *src/qs/qs.cpp
|
||||
a2ca20b2332d025067645839e4b25711 *src/qs/qs_64bit.cpp
|
||||
8f6551c7786fdbb106c3d1bc7824c060 *src/qs/qs_fp.cpp
|
||||
4af89f114491668f7a26af694ff11993 *src/qs/qs_rx.cpp
|
||||
2655cd10d009075b71a84368fb6bf4d4 *src/qs/qstamp.cpp
|
||||
180d454ecdbd08f522ff9a9c299de5df *src/qs/qutest.cpp
|
||||
cf2fae9b29aab50c5cd69d7d519cb0db *src/qv/CMakeLists.txt
|
||||
80b65ecb456e0a8efaaa14f7f30aac81 *src/qv/qv.cpp
|
||||
abfb725ec432f1f56b72e2be4c62e9d3 *src/qv/qv.cpp
|
||||
3c916b7d6a6ce58963153f51801858df *src/qxk/CMakeLists.txt
|
||||
9a0b0803b84b7c4cf0fe1e34187371f8 *src/qxk/qxk.cpp
|
||||
efe0395b16911eaff880649a9968d6a3 *src/qxk/qxk_mutex.cpp
|
||||
7fed39c66ef913b79b82116b54af21de *src/qxk/qxk.cpp
|
||||
309a3f6772f0cadfa8e50b545852b995 *src/qxk/qxk_mutex.cpp
|
||||
ce5ff1926bd91dd8683e0232d3e1d471 *src/qxk/qxk_sema.cpp
|
||||
78ec1d0d6aa9efbdc8b3d09e6deea40e *src/qxk/qxk_xthr.cpp
|
||||
bf56a383eb7dafafa408d6219b585b40 *ports/lint-plus/au-autosar.lnt
|
||||
e3e3f3000f9a80a446255ef52f3a6299 *ports/lint-plus/au-autosar19.lnt
|
||||
2a8fea61bccbe5e8c7536a29f2ec8e98 *ports/lint-plus/au-ds.lnt
|
||||
ede719cdbc201d14586a3f11e77ced26 *ports/lint-plus/au-ql-cpp11.lnt
|
||||
dddbecd55afec10d85006f7787e40c7d *ports/lint-plus/options.lnt
|
||||
3935c8cc585d08999ba9fb9055cc3705 *ports/lint-plus/options.lnt
|
||||
00e7bc0ddabc998469615ac2ff9d79f1 *ports/lint-plus/qpcpp.lnt
|
||||
5f789348dba099c2055f737ba756faac *ports/lint-plus/std.lnt
|
||||
1f3d9dfbf71077abbdb9f27c96879101 *ports/arm-cm/qk/armclang/qk_port.cpp
|
||||
@ -70,14 +70,14 @@ c6227ba01b71184c9e03ee6c8137ffc2 *ports/arm-cm/qk/gnu/qp_port.hpp
|
||||
fed596b153b928c8631e2712361049af *ports/arm-cm/qv/iar/qv_port.cpp
|
||||
fbab3cb88a019df3a12ee56a4a6f90b2 *ports/arm-cm/qxk/armclang/qp_port.hpp
|
||||
91a3b66c3f12a98bef48b00640ed5e6d *ports/arm-cm/qxk/armclang/qs_port.hpp
|
||||
347f34d732e241dda4ba56133ce89993 *ports/arm-cm/qxk/armclang/qxk_port.cpp
|
||||
3e6878ba5e8df9ed733edf9f2da2ae9e *ports/arm-cm/qxk/armclang/qxk_port.cpp
|
||||
e219623c0ac1ee0fcb24d9b2245e406e *ports/arm-cm/qxk/config/qp_config.hpp
|
||||
246d7b72e2f0c1e3ba6e699740dbe390 *ports/arm-cm/qxk/gnu/qp_port.hpp
|
||||
91a3b66c3f12a98bef48b00640ed5e6d *ports/arm-cm/qxk/gnu/qs_port.hpp
|
||||
1a120fbd8eabd3ee8f36fa9965120147 *ports/arm-cm/qxk/gnu/qxk_port.cpp
|
||||
f12841a5d59075aa3e1e9cfb683c4b98 *ports/arm-cm/qxk/gnu/qxk_port.cpp
|
||||
55b897c657e225d775cf6121d6278585 *ports/arm-cm/qxk/iar/qp_port.hpp
|
||||
91a3b66c3f12a98bef48b00640ed5e6d *ports/arm-cm/qxk/iar/qs_port.hpp
|
||||
01d7a7198b209b43e49df8df5ca8ea2b *ports/arm-cm/qxk/iar/qxk_port.cpp
|
||||
bcb7406483cc9280c2b05113f6078cb6 *ports/arm-cm/qxk/iar/qxk_port.cpp
|
||||
0f3ac7def7c330e85912d95527c94ebc *ports/arm-cm/qutest/qp_port.hpp
|
||||
4c0ab6f6ad804f0bd70f146d53a1d197 *ports/arm-cm/qutest/qs_port.hpp
|
||||
a595b03768298546cd9dff7f4e8876f7 *ports/arm-cr/qk/config/qp_config.hpp
|
||||
@ -148,7 +148,6 @@ e898e8f446a8fcfd84b5092144b21ef3 *ports/posix-qutest/qs_port.hpp
|
||||
0ac7e3d28e684d07baacdcd0d3e65c4a *ports/posix-qutest/README.md
|
||||
7955fc33c291eb6b8ebabaae0d6bd0da *ports/posix-qutest/safe_std.h
|
||||
84541985a09da4e23055531452d74a02 *ports/win32/CMakeLists.txt
|
||||
ccec9e69c078e6b6889b7cba2e6195dd *ports/win32/Makefile
|
||||
b98e9825ffcbd8178145207316bf7910 *ports/win32/qf_port.cpp
|
||||
fc5a9085222501f994b6d517d6624a52 *ports/win32/qp_port.hpp
|
||||
b53aafe66b369a2e54344c792e481c1c *ports/win32/qs_port.cpp
|
||||
|
247
qpcpp.qm
247
qpcpp.qm
@ -472,27 +472,27 @@ QS_MEM_APP();
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
// drill down into the state hierarchy with initial transitions...
|
||||
std::int_fast8_t limit = MAX_NEST_DEPTH_; // loop hard limit
|
||||
do {
|
||||
QStateHandler path[MAX_NEST_DEPTH_]; // tran entry path array
|
||||
std::int_fast8_t ip = 0; // tran entry path index
|
||||
|
||||
path[0] = m_temp.fun;
|
||||
static_cast<void>(QHSM_RESERVED_EVT_(m_temp.fun, Q_EMPTY_SIG));
|
||||
while (m_temp.fun != t) {
|
||||
// note: ip is here the fixed upper loop bound
|
||||
while ((m_temp.fun != t) && (ip < (MAX_NEST_DEPTH_ - 1))) {
|
||||
++ip;
|
||||
path[ip] = m_temp.fun;
|
||||
static_cast<void>(QHSM_RESERVED_EVT_(m_temp.fun, Q_EMPTY_SIG));
|
||||
}
|
||||
QF_CRIT_ENTRY();
|
||||
// The initial transition source state must be reached
|
||||
// Too many state nesting levels or "malformed" HSM.
|
||||
Q_ASSERT_INCRIT(220, m_temp.fun == t);
|
||||
// too many state nesting levels or "malformed" HSM
|
||||
Q_ENSURE_INCRIT(220, ip < MAX_NEST_DEPTH_);
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
m_temp.fun = path[0];
|
||||
|
||||
// retrace the entry path in reverse (desired) order...
|
||||
// note: ip is the fixed upper loop bound
|
||||
do {
|
||||
// enter path[ip]
|
||||
if (QHSM_RESERVED_EVT_(path[ip], Q_ENTRY_SIG)
|
||||
@ -520,14 +520,9 @@ do {
|
||||
QS_CRIT_EXIT();
|
||||
}
|
||||
#endif // Q_SPY
|
||||
|
||||
--limit;
|
||||
} while ((r == Q_RET_TRAN) && (limit > 0));
|
||||
} while (r == Q_RET_TRAN);
|
||||
|
||||
QF_CRIT_ENTRY();
|
||||
// Loop limit must not be reached.
|
||||
// Too many state nesting levels or likely "malformed" HSM
|
||||
Q_ENSURE_INCRIT(290, limit > 0);
|
||||
|
||||
QS_MEM_SYS();
|
||||
QS_BEGIN_PRE_(QS_QEP_INIT_TRAN, qsId)
|
||||
@ -567,9 +562,9 @@ QStateHandler t = s;
|
||||
QF_CRIT_STAT
|
||||
|
||||
QF_CRIT_ENTRY();
|
||||
Q_REQUIRE_INCRIT(300, (s != Q_STATE_CAST(0))
|
||||
Q_INVARIANT_INCRIT(302, (s != Q_STATE_CAST(0))
|
||||
&& (m_state.uint == static_cast<std::uintptr_t>(~m_temp.uint)));
|
||||
Q_REQUIRE_INCRIT(302, QEvt::verify_(e));
|
||||
Q_INVARIANT_INCRIT(303, QEvt::verify_(e));
|
||||
|
||||
QS_MEM_SYS();
|
||||
QS_BEGIN_PRE_(QS_QEP_DISPATCH, qsId)
|
||||
@ -585,7 +580,7 @@ QF_CRIT_EXIT();
|
||||
// process the event hierarchically...
|
||||
QState r;
|
||||
m_temp.fun = s;
|
||||
std::int_fast8_t limit = MAX_NEST_DEPTH_; // loop hard limit
|
||||
std::int_fast8_t ip = MAX_NEST_DEPTH_; // fixed upper loop bound
|
||||
do {
|
||||
s = m_temp.fun;
|
||||
r = (*s)(this, e); // invoke state handler s
|
||||
@ -605,11 +600,11 @@ do {
|
||||
r = QHSM_RESERVED_EVT_(s, Q_EMPTY_SIG); // superstate of s
|
||||
}
|
||||
|
||||
--limit;
|
||||
} while ((r == Q_RET_SUPER) && (limit > 0));
|
||||
--ip;
|
||||
} while ((r == Q_RET_SUPER) && (ip > 0));
|
||||
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ASSERT_INCRIT(310, limit > 0);
|
||||
Q_ENSURE_INCRIT(310, ip > 0);
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
if (r >= Q_RET_TRAN) { // regular tran. taken?
|
||||
@ -620,21 +615,21 @@ if (r >= Q_RET_TRAN) { // regular tran. taken?
|
||||
path[2] = s; // tran. source
|
||||
|
||||
// exit current state to tran. source s...
|
||||
limit = MAX_NEST_DEPTH_; // loop hard limit
|
||||
for (; (t != s) && (limit > 0); t = m_temp.fun) {
|
||||
ip = MAX_NEST_DEPTH_; // fixed upper loop bound
|
||||
for (; (t != s) && (ip > 0); t = m_temp.fun) {
|
||||
// exit from t
|
||||
if (QHSM_RESERVED_EVT_(t, Q_EXIT_SIG) == Q_RET_HANDLED) {
|
||||
QS_STATE_EXIT_(t, qsId);
|
||||
// find superstate of t
|
||||
static_cast<void>(QHSM_RESERVED_EVT_(t, Q_EMPTY_SIG));
|
||||
}
|
||||
--limit;
|
||||
--ip;
|
||||
}
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ASSERT_INCRIT(320, limit > 0);
|
||||
Q_ENSURE_INCRIT(320, ip > 0);
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
std::int_fast8_t ip = hsm_tran(path, qsId); // take the tran.
|
||||
ip = hsm_tran(path, qsId); // take the tran.
|
||||
|
||||
#ifdef Q_SPY
|
||||
if (r == Q_RET_TRAN_HIST) {
|
||||
@ -651,6 +646,7 @@ if (r >= Q_RET_TRAN) { // regular tran. taken?
|
||||
#endif // Q_SPY
|
||||
|
||||
// execute state entry actions in the desired order...
|
||||
// note: ip is the fixed upper loop bound
|
||||
for (; ip >= 0; --ip) {
|
||||
// enter path[ip]
|
||||
if (QHSM_RESERVED_EVT_(path[ip], Q_ENTRY_SIG)
|
||||
@ -681,6 +677,7 @@ if (r >= Q_RET_TRAN) { // regular tran. taken?
|
||||
// find superstate
|
||||
static_cast<void>(QHSM_RESERVED_EVT_(m_temp.fun, Q_EMPTY_SIG));
|
||||
|
||||
// note: ip is the fixed upper loop bound
|
||||
while ((m_temp.fun != t) && (ip < (MAX_NEST_DEPTH_ - 1))) {
|
||||
++ip;
|
||||
path[ip] = m_temp.fun;
|
||||
@ -689,14 +686,14 @@ if (r >= Q_RET_TRAN) { // regular tran. taken?
|
||||
QHSM_RESERVED_EVT_(m_temp.fun, Q_EMPTY_SIG));
|
||||
}
|
||||
QF_CRIT_ENTRY();
|
||||
// The initial transition source state must be reached.
|
||||
// Too many state nesting levels or "malformed" HSM.
|
||||
Q_ASSERT_INCRIT(330, m_temp.fun == t);
|
||||
// too many state nesting levels or "malformed" HSM
|
||||
Q_ENSURE_INCRIT(330, ip < MAX_NEST_DEPTH_);
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
m_temp.fun = path[0];
|
||||
|
||||
// retrace the entry path in reverse (correct) order...
|
||||
// note: ip is the fixed upper loop bound
|
||||
do {
|
||||
// enter path[ip]
|
||||
if (QHSM_RESERVED_EVT_(path[ip], Q_ENTRY_SIG)
|
||||
@ -762,17 +759,17 @@ m_temp.uint = ~m_state.uint;
|
||||
<parameter name="state" type="QStateHandler const"/>
|
||||
<code>QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
Q_REQUIRE_INCRIT(602, m_state.uint
|
||||
== static_cast<std::uintptr_t>(~m_temp.uint));
|
||||
Q_INVARIANT_INCRIT(602, m_state.uint
|
||||
== static_cast<std::uintptr_t>(~m_temp.uint));
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
bool inState = false; // assume that this HSM is not in 'state'
|
||||
|
||||
// scan the state hierarchy bottom-up
|
||||
QStateHandler s = m_state.fun;
|
||||
std::int_fast8_t limit = MAX_NEST_DEPTH_ + 1; // loop hard limit
|
||||
std::int_fast8_t lbound = MAX_NEST_DEPTH_ + 1; // fixed upper loop bound
|
||||
QState r = Q_RET_SUPER;
|
||||
for (; (r != Q_RET_IGNORED) && (limit > 0); --limit) {
|
||||
for (; (r != Q_RET_IGNORED) && (lbound > 0); --lbound) {
|
||||
if (s == state) { // do the states match?
|
||||
inState = true; // 'true' means that match found
|
||||
break; // break out of the for-loop
|
||||
@ -784,7 +781,7 @@ for (; (r != Q_RET_IGNORED) && (limit > 0); --limit) {
|
||||
}
|
||||
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ENSURE_INCRIT(690, limit > 0);
|
||||
Q_ENSURE_INCRIT(690, lbound > 0);
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
@ -798,12 +795,13 @@ return inState; // return the status</code>
|
||||
<specifiers>noexcept</specifiers>
|
||||
<!--${QEP::QHsm::childState::parent}-->
|
||||
<parameter name="parent" type="QStateHandler const"/>
|
||||
<code>QStateHandler child = m_state.fun; // start with the current state
|
||||
<code>QStateHandler child = m_state.fun; // start with current state
|
||||
bool isFound = false; // start with the child not found
|
||||
|
||||
// establish stable state configuration
|
||||
m_temp.fun = child;
|
||||
QState r;
|
||||
std::int_fast8_t lbound = MAX_NEST_DEPTH_; // fixed upper loop bound
|
||||
do {
|
||||
// is this the parent of the current child?
|
||||
if (m_temp.fun == parent) {
|
||||
@ -814,7 +812,9 @@ do {
|
||||
child = m_temp.fun;
|
||||
r = QHSM_RESERVED_EVT_(m_temp.fun, Q_EMPTY_SIG);
|
||||
}
|
||||
} while (r != Q_RET_IGNORED); // QHsm::top() state not reached
|
||||
--lbound;
|
||||
} while ((r != Q_RET_IGNORED) // QHsm::top() state not reached
|
||||
&& (lbound > 0));
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
m_temp.uint = ~m_state.uint;
|
||||
@ -822,10 +822,12 @@ m_temp.uint = ~m_state.uint;
|
||||
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ASSERT_INCRIT(890, isFound);
|
||||
// NOTE: the following postcondition can only succeed when
|
||||
// (lbound > 0), so no extra check is necessary.
|
||||
Q_ENSURE_INCRIT(890, isFound);
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
return child; // return the child</code>
|
||||
return child;</code>
|
||||
</operation>
|
||||
<!--${QEP::QHsm::getStateHandler}-->
|
||||
<operation name="getStateHandler?def Q_SPY" type="QStateHandler" visibility="0x00" properties="0x06">
|
||||
@ -894,6 +896,7 @@ else {
|
||||
t = m_temp.fun; // save source->super
|
||||
|
||||
// find target->super->super...
|
||||
// note: ip is the fixed upper loop bound
|
||||
QState r = QHSM_RESERVED_EVT_(path[1], Q_EMPTY_SIG);
|
||||
while ((r == Q_RET_SUPER)
|
||||
&& (ip < (MAX_NEST_DEPTH_ - 1)))
|
||||
@ -910,9 +913,10 @@ else {
|
||||
}
|
||||
}
|
||||
QF_CRIT_ENTRY();
|
||||
// Tran. source must be found within the nesting depth
|
||||
// Too many state nesting levels or "malformed" HSM.
|
||||
Q_ASSERT_INCRIT(510, r != Q_RET_SUPER);
|
||||
// NOTE: The following postcondition succeeds only when
|
||||
// ip < QHSM_MAX_NEST_DEPTH, so no additional check is necessary
|
||||
// too many state nesting levels or "malformed" HSM.
|
||||
Q_ENSURE_INCRIT(510, r != Q_RET_SUPER);
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
// the LCA not found yet?
|
||||
@ -928,6 +932,7 @@ else {
|
||||
// == target->super->super...
|
||||
iq = ip;
|
||||
r = Q_RET_IGNORED; // indicate that the LCA NOT found
|
||||
// note: iq is the fixed upper loop bound
|
||||
do {
|
||||
if (t == path[iq]) { // is this the LCA?
|
||||
r = Q_RET_HANDLED; // indicate the LCA found
|
||||
@ -944,7 +949,7 @@ else {
|
||||
// (g) check each source->super->...
|
||||
// for each target->super...
|
||||
r = Q_RET_IGNORED; // keep looping
|
||||
std::int_fast8_t limit = MAX_NEST_DEPTH_;
|
||||
std::int_fast8_t lbound = MAX_NEST_DEPTH_;
|
||||
do {
|
||||
// exit from t
|
||||
if (QHSM_RESERVED_EVT_(t, Q_EXIT_SIG)
|
||||
@ -969,10 +974,10 @@ else {
|
||||
}
|
||||
} while (iq >= 0);
|
||||
|
||||
--limit;
|
||||
} while ((r != Q_RET_HANDLED) && (limit > 0));
|
||||
--lbound;
|
||||
} while ((r != Q_RET_HANDLED) && (lbound > 0));
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ASSERT_INCRIT(530, limit > 0);
|
||||
Q_ASSERT_INCRIT(530, lbound > 0);
|
||||
QF_CRIT_EXIT();
|
||||
}
|
||||
}
|
||||
@ -1037,15 +1042,15 @@ QF_CRIT_EXIT();
|
||||
m_state.obj = m_temp.tatbl->target;
|
||||
|
||||
// drill down into the state hierarchy with initial transitions...
|
||||
std::int_fast8_t limit = MAX_NEST_DEPTH_; // loop hard limit
|
||||
std::int_fast8_t lbound = MAX_NEST_DEPTH_; // fixed upper loop bound
|
||||
do {
|
||||
// execute the tran. table
|
||||
r = execTatbl_(m_temp.tatbl, qsId);
|
||||
--limit;
|
||||
} while ((r >= Q_RET_TRAN_INIT) && (limit > 0));
|
||||
--lbound;
|
||||
} while ((r >= Q_RET_TRAN_INIT) && (lbound > 0));
|
||||
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ENSURE_INCRIT(290, limit > 0);
|
||||
Q_ENSURE_INCRIT(290, lbound > 0);
|
||||
|
||||
QS_MEM_SYS();
|
||||
QS_BEGIN_PRE_(QS_QEP_INIT_TRAN, qsId)
|
||||
@ -1084,9 +1089,9 @@ QMState const *t = s;
|
||||
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
Q_REQUIRE_INCRIT(300, (s != nullptr)
|
||||
Q_INVARIANT_INCRIT(300, (s != nullptr)
|
||||
&& (m_state.uint == static_cast<std::uintptr_t>(~m_temp.uint)));
|
||||
Q_REQUIRE_INCRIT(302, QEvt::verify_(e));
|
||||
Q_INVARIANT_INCRIT(302, QEvt::verify_(e));
|
||||
|
||||
QS_MEM_SYS();
|
||||
QS_BEGIN_PRE_(QS_QEP_DISPATCH, qsId)
|
||||
@ -1101,7 +1106,7 @@ QF_CRIT_EXIT();
|
||||
|
||||
// scan the state hierarchy up to the top state...
|
||||
QState r;
|
||||
std::int_fast8_t limit = MAX_NEST_DEPTH_; // loop hard limit
|
||||
std::int_fast8_t lbound = MAX_NEST_DEPTH_; // fixed upper loop bound
|
||||
do {
|
||||
r = (*t->stateHandler)(this, e); // call state handler function
|
||||
|
||||
@ -1134,10 +1139,10 @@ do {
|
||||
|
||||
t = t->superstate; // advance to the superstate
|
||||
}
|
||||
--limit;
|
||||
} while ((t != nullptr) && (limit > 0));
|
||||
--lbound;
|
||||
} while ((t != nullptr) && (lbound > 0));
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ASSERT_INCRIT(310, limit > 0);
|
||||
Q_ASSERT_INCRIT(310, lbound > 0);
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
if (r >= Q_RET_TRAN) { // any kind of tran. taken?
|
||||
@ -1150,7 +1155,7 @@ if (r >= Q_RET_TRAN) { // any kind of tran. taken?
|
||||
QF_CRIT_EXIT();
|
||||
#endif // Q_SPY
|
||||
|
||||
limit = MAX_NEST_DEPTH_; // loop hard limit
|
||||
lbound = MAX_NEST_DEPTH_; // fixed upper loop bound
|
||||
do {
|
||||
// save the tran-action table before it gets clobbered
|
||||
QMTranActTable const * const tatbl = m_temp.tatbl;
|
||||
@ -1217,11 +1222,11 @@ if (r >= Q_RET_TRAN) { // any kind of tran. taken?
|
||||
}
|
||||
|
||||
t = s; // set target to the current state
|
||||
--limit;
|
||||
} while ((r >= Q_RET_TRAN) && (limit > 0));
|
||||
--lbound;
|
||||
} while ((r >= Q_RET_TRAN) && (lbound > 0));
|
||||
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ASSERT_INCRIT(320, limit > 0);
|
||||
Q_ASSERT_INCRIT(320, lbound > 0);
|
||||
|
||||
QS_MEM_SYS();
|
||||
QS_BEGIN_PRE_(QS_QEP_TRAN, qsId)
|
||||
@ -1289,8 +1294,8 @@ m_temp.uint = ~m_state.uint;
|
||||
<code>bool inState = false; // assume that this SM is not in 'state'
|
||||
|
||||
QMState const *s = m_state.obj;
|
||||
std::int_fast8_t limit = MAX_NEST_DEPTH_; // loop hard limit
|
||||
for (; (s != nullptr) && (limit > 0); --limit) {
|
||||
std::int_fast8_t lbound = MAX_NEST_DEPTH_; // fixed upper loop bound
|
||||
for (; (s != nullptr) && (lbound > 0); --lbound) {
|
||||
if (s->stateHandler == state) { // match found?
|
||||
inState = true;
|
||||
break;
|
||||
@ -1302,7 +1307,7 @@ for (; (s != nullptr) && (limit > 0); --limit) {
|
||||
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ENSURE_INCRIT(490, limit > 0);
|
||||
Q_ENSURE_INCRIT(490, lbound > 0);
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
return inState;</code>
|
||||
@ -1316,8 +1321,8 @@ return inState;</code>
|
||||
<code>bool inState = false; // assume that this SM is not in 'state'
|
||||
|
||||
QMState const *s = m_state.obj;
|
||||
std::int_fast8_t limit = MAX_NEST_DEPTH_; // loop hard limit
|
||||
for (; (s != nullptr) && (limit > 0); --limit) {
|
||||
std::int_fast8_t lbound = MAX_NEST_DEPTH_; // fixed upper loop bound
|
||||
for (; (s != nullptr) && (lbound > 0); --lbound) {
|
||||
if (s == stateObj) { // match found?
|
||||
inState = true;
|
||||
break;
|
||||
@ -1329,7 +1334,7 @@ for (; (s != nullptr) && (limit > 0); --limit) {
|
||||
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ENSURE_INCRIT(590, limit > 0);
|
||||
Q_ENSURE_INCRIT(590, lbound > 0);
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
return inState;</code>
|
||||
@ -1343,9 +1348,9 @@ return inState;</code>
|
||||
bool isFound = false; // start with the child not found
|
||||
QMState const *s;
|
||||
|
||||
std::int_fast8_t limit = MAX_NEST_DEPTH_; // loop hard limit
|
||||
std::int_fast8_t lbound = MAX_NEST_DEPTH_; // fixed upper loop bound
|
||||
for (s = m_state.obj;
|
||||
(s != nullptr) && (limit > 0);
|
||||
(s != nullptr) && (lbound > 0);
|
||||
s = s->superstate)
|
||||
{
|
||||
if (s == parent) {
|
||||
@ -1355,17 +1360,17 @@ for (s = m_state.obj;
|
||||
else {
|
||||
child = s;
|
||||
}
|
||||
--limit;
|
||||
--lbound;
|
||||
}
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ASSERT_INCRIT(610, limit > 0);
|
||||
Q_ASSERT_INCRIT(610, lbound > 0);
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
if (!isFound) { // still not found?
|
||||
limit = MAX_NEST_DEPTH_; // loop hard limit
|
||||
lbound = MAX_NEST_DEPTH_; // fixed upper loop bound
|
||||
for (s = m_temp.obj;
|
||||
(s != nullptr) && (limit > 0);
|
||||
(s != nullptr) && (lbound > 0);
|
||||
s = s->superstate)
|
||||
{
|
||||
if (s == parent) {
|
||||
@ -1375,12 +1380,12 @@ if (!isFound) { // still not found?
|
||||
else {
|
||||
child = s;
|
||||
}
|
||||
--limit;
|
||||
--lbound;
|
||||
}
|
||||
}
|
||||
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ENSURE_INCRIT(690, isFound && (limit > 0));
|
||||
Q_ENSURE_INCRIT(690, isFound && (lbound > 0));
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
return child; // return the child</code>
|
||||
@ -1403,9 +1408,9 @@ Q_REQUIRE_INCRIT(700, tatbl != nullptr);
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
QState r = Q_RET_NULL;
|
||||
std::int_fast8_t limit = MAX_TRAN_LENGTH_; // loop hard limit
|
||||
std::int_fast8_t lbound = MAX_TRAN_LENGTH_; // fixed upper loop bound
|
||||
QActionHandler const *a = &tatbl->act[0];
|
||||
for (; (*a != nullptr) && (limit > 0); ++a) {
|
||||
for (; (*a != nullptr) && (lbound > 0); ++a) {
|
||||
r = (*(*a))(this); // call the action through the 'a' pointer
|
||||
#ifdef Q_SPY
|
||||
QS_CRIT_ENTRY();
|
||||
@ -1449,7 +1454,7 @@ for (; (*a != nullptr) && (limit > 0); ++a) {
|
||||
QS_MEM_APP();
|
||||
QS_CRIT_EXIT();
|
||||
#endif // Q_SPY
|
||||
--limit;
|
||||
--lbound;
|
||||
}
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ENSURE_INCRIT(790, *a == nullptr);
|
||||
@ -1476,8 +1481,8 @@ QF_CRIT_STAT
|
||||
|
||||
// exit states from the current state to the tran. source state
|
||||
QMState const *s = cs;
|
||||
std::int_fast8_t limit = MAX_NEST_DEPTH_; // loop hard limit
|
||||
for (; (s != ts) && (limit > 0); --limit) {
|
||||
std::int_fast8_t lbound = MAX_NEST_DEPTH_; // fixed upper loop bound
|
||||
for (; (s != ts) && (lbound > 0); --lbound) {
|
||||
// exit action provided in state 's'?
|
||||
if (s->exitAction != nullptr) {
|
||||
// execute the exit action
|
||||
@ -1503,7 +1508,7 @@ for (; (s != ts) && (limit > 0); --limit) {
|
||||
}
|
||||
}
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ENSURE_INCRIT(890, limit > 0);
|
||||
Q_ENSURE_INCRIT(890, lbound > 0);
|
||||
QF_CRIT_EXIT();</code>
|
||||
</operation>
|
||||
<!--${QEP::QMsm::enterHistory_}-->
|
||||
@ -2161,7 +2166,7 @@ QF_MEM_SYS();
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
std::uint8_t const pcopy = static_cast<std::uint8_t>(~m_prio_dis);
|
||||
Q_REQUIRE_INCRIT(102, (QEvt::verify_(e)) && (m_prio == pcopy));
|
||||
Q_INVARIANT_INCRIT(102, (QEvt::verify_(e)) && (m_prio == pcopy));
|
||||
#endif
|
||||
|
||||
QEQueueCtr nFree = m_eQueue.m_nFree; // get volatile into temporary
|
||||
@ -2300,7 +2305,7 @@ QF_MEM_SYS();
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
std::uint8_t const pcopy = static_cast<std::uint8_t>(~m_prio_dis);
|
||||
Q_REQUIRE_INCRIT(202, (QEvt::verify_(e)) && (m_prio == pcopy));
|
||||
Q_INVARIANT_INCRIT(202, (QEvt::verify_(e)) && (m_prio == pcopy));
|
||||
#endif
|
||||
|
||||
#ifdef QXK_HPP_
|
||||
@ -2466,7 +2471,7 @@ QF_CRIT_ENTRY();
|
||||
QF_MEM_SYS();
|
||||
|
||||
Q_REQUIRE_INCRIT(200, sig < static_cast<QSignal>(maxPubSignal_));
|
||||
Q_REQUIRE_INCRIT(202,
|
||||
Q_INVARIANT_INCRIT(202,
|
||||
subscrList_[sig].m_set.verify_(&subscrList_[sig].m_set_dis));
|
||||
|
||||
QS_BEGIN_PRE_(QS_QF_PUBLISH, qsId)
|
||||
@ -2509,9 +2514,9 @@ if (subscrSet.notEmpty()) { // any subscribers?
|
||||
|
||||
QF_SCHED_STAT_
|
||||
QF_SCHED_LOCK_(p); // lock the scheduler up to AO's prio
|
||||
std::uint_fast8_t limit = QF_MAX_ACTIVE + 1U;
|
||||
std::uint_fast8_t lbound = QF_MAX_ACTIVE + 1U;
|
||||
do { // loop over all subscribers
|
||||
--limit;
|
||||
--lbound;
|
||||
|
||||
// POST() asserts internally if the queue overflows
|
||||
a->POST(e, sender);
|
||||
@ -2533,7 +2538,7 @@ if (subscrSet.notEmpty()) { // any subscribers?
|
||||
else {
|
||||
p = 0U; // no more subscribers
|
||||
}
|
||||
} while ((p != 0U) && (limit > 0U));
|
||||
} while ((p != 0U) && (lbound > 0U));
|
||||
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ENSURE_INCRIT(290, p == 0U);
|
||||
@ -2564,7 +2569,7 @@ Q_REQUIRE_INCRIT(300, (Q_USER_SIG <= sig)
|
||||
&& (sig < maxPubSignal_)
|
||||
&& (0U < p) && (p <= QF_MAX_ACTIVE)
|
||||
&& (registry_[p] == this));
|
||||
Q_REQUIRE_INCRIT(302,
|
||||
Q_INVARIANT_INCRIT(302,
|
||||
subscrList_[sig].m_set.verify_(&subscrList_[sig].m_set_dis));
|
||||
|
||||
QS_BEGIN_PRE_(QS_QF_ACTIVE_SUBSCRIBE, m_prio)
|
||||
@ -2597,7 +2602,7 @@ Q_REQUIRE_INCRIT(400, (Q_USER_SIG <= sig)
|
||||
&& (sig < maxPubSignal_)
|
||||
&& (0U < p) && (p <= QF_MAX_ACTIVE)
|
||||
&& (registry_[p] == this));
|
||||
Q_REQUIRE_INCRIT(402,
|
||||
Q_INVARIANT_INCRIT(402,
|
||||
subscrList_[sig].m_set.verify_(&subscrList_[sig].m_set_dis));
|
||||
|
||||
QS_BEGIN_PRE_(QS_QF_ACTIVE_UNSUBSCRIBE, m_prio)
|
||||
@ -2929,8 +2934,6 @@ QF_CRIT_EXIT();
|
||||
// reused to hold the tickRate as well as other information
|
||||
refCtr_ = static_cast<std::uint8_t>(tickRate);</code>
|
||||
</operation>
|
||||
<!--${QF::QTimeEvt::~QTimeEvt}-->
|
||||
<operation name="~QTimeEvt?def Q_XTOR" type="" visibility="0x00" properties="0x00"/>
|
||||
<!--${QF::QTimeEvt::armX}-->
|
||||
<operation name="armX" type="void" visibility="0x00" properties="0x00">
|
||||
<specifiers>noexcept</specifiers>
|
||||
@ -3159,8 +3162,8 @@ QS_BEGIN_PRE_(QS_QF_TICK, 0U)
|
||||
QS_END_PRE_()
|
||||
|
||||
// scan the linked-list of time events at this rate...
|
||||
std::uint_fast8_t limit = 2U*QF_MAX_ACTIVE; // loop hard limit
|
||||
for (; limit > 0U; --limit) {
|
||||
std::uint_fast8_t lbound = 2U*QF_MAX_ACTIVE; // fixed upper loop bound
|
||||
for (; lbound > 0U; --lbound) {
|
||||
QTimeEvt *e = prev->m_next; // advance down the time evt. list
|
||||
|
||||
if (e == nullptr) { // end of the list?
|
||||
@ -3180,7 +3183,7 @@ for (; limit > 0U; --limit) {
|
||||
}
|
||||
|
||||
// the time event 'e' must be valid
|
||||
Q_ASSERT_INCRIT(112, QEvt::verify_(e));
|
||||
Q_INVARIANT_INCRIT(112, QEvt::verify_(e));
|
||||
|
||||
if (e->m_ctr == 0U) { // time event scheduled for removal?
|
||||
prev->m_next = e->m_next;
|
||||
@ -3269,7 +3272,7 @@ for (; limit > 0U; --limit) {
|
||||
QF_MEM_SYS();
|
||||
}
|
||||
|
||||
Q_ENSURE_INCRIT(190, limit > 0U);
|
||||
Q_ENSURE_INCRIT(190, lbound > 0U);
|
||||
QF_MEM_APP();
|
||||
QF_CRIT_EXIT();</code>
|
||||
</operation>
|
||||
@ -3489,8 +3492,6 @@ QF_CRIT_EXIT();</code>
|
||||
m_nFree(0U),
|
||||
m_nMin(0U)</code>
|
||||
</operation>
|
||||
<!--${QF::QEQueue::~QEQueue}-->
|
||||
<operation name="~QEQueue?def Q_XTOR" type="" visibility="0x00" properties="0x00"/>
|
||||
<!--${QF::QEQueue::init}-->
|
||||
<operation name="init" type="void" visibility="0x00" properties="0x00">
|
||||
<specifiers>noexcept</specifiers>
|
||||
@ -3760,8 +3761,6 @@ return e;</code>
|
||||
m_nFree(0U),
|
||||
m_nMin(0U)</code>
|
||||
</operation>
|
||||
<!--${QF::QMPool::~QMPool}-->
|
||||
<operation name="~QMPool?def Q_XTOR" type="" visibility="0x00" properties="0x00"/>
|
||||
<!--${QF::QMPool::init}-->
|
||||
<operation name="init" type="void" visibility="0x00" properties="0x00">
|
||||
<specifiers>noexcept</specifiers>
|
||||
@ -3850,8 +3849,8 @@ if (m_nFree > static_cast<QMPoolCtr>(margin)) {
|
||||
QFreeBlock * const fb_next = fb->m_next;
|
||||
|
||||
// the free block must have integrity (duplicate inverse storage)
|
||||
Q_ASSERT_INCRIT(302, Q_UINTPTR_CAST_(fb_next)
|
||||
== static_cast<std::uintptr_t>(~fb->m_next_dis));
|
||||
Q_INVARIANT_INCRIT(302, Q_UINTPTR_CAST_(fb_next)
|
||||
== static_cast<std::uintptr_t>(~fb->m_next_dis));
|
||||
|
||||
m_nFree = (m_nFree - 1U); // one free block less
|
||||
if (m_nFree == 0U) { // is the pool becoming empty?
|
||||
@ -3929,7 +3928,7 @@ fb->m_next_dis = static_cast<std::uintptr_t>(
|
||||
#endif
|
||||
|
||||
// set as new head of the free list
|
||||
m_free_head = static_cast<QFreeBlock *>(block);
|
||||
m_free_head = fb;
|
||||
|
||||
m_nFree = m_nFree + 1U; // one more free block in this pool
|
||||
|
||||
@ -4234,7 +4233,7 @@ return e;</code>
|
||||
<parameter name="e" type="QEvt const * const"/>
|
||||
<code>QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
Q_REQUIRE_INCRIT(402, QEvt::verify_(e));
|
||||
Q_INVARIANT_INCRIT(402, QEvt::verify_(e));
|
||||
|
||||
std::uint_fast8_t const poolNum = e->getPoolNum_();
|
||||
|
||||
@ -4299,7 +4298,7 @@ Q_UNUSED_PAR(evtRef);
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
|
||||
Q_REQUIRE_INCRIT(502, QEvt::verify_(e));
|
||||
Q_INVARIANT_INCRIT(502, QEvt::verify_(e));
|
||||
|
||||
std::uint_fast8_t const poolNum = e->getPoolNum_();
|
||||
|
||||
@ -4330,7 +4329,7 @@ return e;</code>
|
||||
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
Q_REQUIRE_INCRIT(602, QEvt::verify_(e));
|
||||
Q_INVARIANT_INCRIT(602, QEvt::verify_(e));
|
||||
|
||||
#ifdef Q_SPY
|
||||
std::uint_fast8_t const poolNum = e->getPoolNum_();
|
||||
@ -4632,7 +4631,7 @@ gc(evtRef); // recycle the referenced event
|
||||
QF_CRIT_ENTRY();
|
||||
QF_MEM_SYS();
|
||||
|
||||
Q_ASSERT_INCRIT(102, priv_.schedCeil
|
||||
Q_INVARIANT_INCRIT(102, priv_.schedCeil
|
||||
== static_cast<std::uint_fast8_t>(~priv_.schedCeil_dis));
|
||||
|
||||
if (ceiling > priv_.schedCeil) { // raising the scheduler ceiling?
|
||||
@ -4658,7 +4657,7 @@ QF_CRIT_EXIT();</code>
|
||||
QF_CRIT_ENTRY();
|
||||
QF_MEM_SYS();
|
||||
|
||||
Q_ASSERT_INCRIT(202, priv_.schedCeil
|
||||
Q_INVARIANT_INCRIT(202, priv_.schedCeil
|
||||
== static_cast<std::uint_fast8_t>(~priv_.schedCeil_dis));
|
||||
|
||||
if (priv_.schedCeil != 0U) { // actually enabling the scheduler?
|
||||
@ -4730,10 +4729,10 @@ std::uint_fast8_t pprev = 0U; // previous prio.
|
||||
for (;;) { // QV event loop...
|
||||
|
||||
// check internal integrity (duplicate inverse storage)
|
||||
Q_ASSERT_INCRIT(302,
|
||||
Q_INVARIANT_INCRIT(302,
|
||||
QV::priv_.readySet.verify_(&QV::priv_.readySet_dis));
|
||||
// check internal integrity (duplicate inverse storage)
|
||||
Q_ASSERT_INCRIT(303, QV::priv_.schedCeil
|
||||
Q_INVARIANT_INCRIT(303, QV::priv_.schedCeil
|
||||
== static_cast<std::uint_fast8_t>(~QV::priv_.schedCeil_dis));
|
||||
|
||||
// find the maximum prio. AO ready to run
|
||||
@ -4908,7 +4907,7 @@ QF_CRIT_ENTRY();
|
||||
QF_MEM_SYS();
|
||||
|
||||
Q_REQUIRE_INCRIT(100, !QK_ISR_CONTEXT_());
|
||||
Q_REQUIRE_INCRIT(102, QK_priv_.lockCeil
|
||||
Q_INVARIANT_INCRIT(102, QK_priv_.lockCeil
|
||||
== static_cast<std::uint_fast8_t>(~QK_priv_.lockCeil_dis));
|
||||
|
||||
// first store the previous lock prio
|
||||
@ -4950,7 +4949,7 @@ if (prevCeil != 0xFFU) {
|
||||
QF_CRIT_ENTRY();
|
||||
QF_MEM_SYS();
|
||||
|
||||
Q_REQUIRE_INCRIT(202, QK_priv_.lockCeil
|
||||
Q_INVARIANT_INCRIT(202, QK_priv_.lockCeil
|
||||
== static_cast<std::uint_fast8_t>(~QK_priv_.lockCeil_dis));
|
||||
Q_REQUIRE_INCRIT(210, (!QK_ISR_CONTEXT_())
|
||||
&& (QK_priv_.lockCeil > prevCeil));
|
||||
@ -5134,7 +5133,7 @@ QF_CRIT_EXIT();</code>
|
||||
<specifiers>noexcept</specifiers>
|
||||
<code>// NOTE: this function is entered with interrupts DISABLED
|
||||
|
||||
Q_REQUIRE_INCRIT(402,
|
||||
Q_INVARIANT_INCRIT(402,
|
||||
QK_priv_.readySet.verify_(&QK_priv_.readySet_dis));
|
||||
|
||||
std::uint_fast8_t p;
|
||||
@ -5145,7 +5144,7 @@ else {
|
||||
// find the highest-prio AO with non-empty event queue
|
||||
p = QK_priv_.readySet.findMax();
|
||||
|
||||
Q_ASSERT_INCRIT(412, QK_priv_.actThre
|
||||
Q_INVARIANT_INCRIT(412, QK_priv_.actThre
|
||||
== static_cast<std::uint_fast8_t>(~QK_priv_.actThre_dis));
|
||||
|
||||
// is the AO's prio. below the active preemption-threshold?
|
||||
@ -5153,7 +5152,7 @@ else {
|
||||
p = 0U; // no activation needed
|
||||
}
|
||||
else {
|
||||
Q_ASSERT_INCRIT(422, QK_priv_.lockCeil
|
||||
Q_INVARIANT_INCRIT(422, QK_priv_.lockCeil
|
||||
== static_cast<std::uint_fast8_t>(~QK_priv_.lockCeil_dis));
|
||||
|
||||
// is the AO's prio. below the lock-ceiling?
|
||||
@ -5161,7 +5160,7 @@ else {
|
||||
p = 0U; // no activation needed
|
||||
}
|
||||
else {
|
||||
Q_ASSERT_INCRIT(432, QK_priv_.nextPrio
|
||||
Q_INVARIANT_INCRIT(432, QK_priv_.nextPrio
|
||||
== static_cast<std::uint_fast8_t>(~QK_priv_.nextPrio_dis));
|
||||
QK_priv_.nextPrio = p; // next AO to run
|
||||
#ifndef Q_UNSAFE
|
||||
@ -5182,7 +5181,7 @@ return p;</code>
|
||||
std::uint_fast8_t const prio_in = QK_priv_.actPrio; // save initial prio.
|
||||
std::uint_fast8_t p = QK_priv_.nextPrio; // next prio to run
|
||||
|
||||
Q_REQUIRE_INCRIT(502,
|
||||
Q_INVARIANT_INCRIT(502,
|
||||
(prio_in == static_cast<std::uint_fast8_t>(~QK_priv_.actPrio_dis))
|
||||
&& (p == static_cast<std::uint_fast8_t>(~QK_priv_.nextPrio_dis)));
|
||||
Q_REQUIRE_INCRIT(510, (prio_in <= QF_MAX_ACTIVE)
|
||||
@ -5207,7 +5206,7 @@ else {
|
||||
Q_ASSERT_INCRIT(510, a != nullptr);
|
||||
|
||||
pthre_in = static_cast<std::uint_fast8_t>(a->getPThre());
|
||||
Q_ASSERT_INCRIT(511, pthre_in == static_cast<std::uint_fast8_t>(
|
||||
Q_INVARIANT_INCRIT(511, pthre_in == static_cast<std::uint_fast8_t>(
|
||||
~static_cast<std::uint_fast8_t>(a->m_pthre_dis) & 0xFFU));
|
||||
}
|
||||
|
||||
@ -5217,7 +5216,7 @@ do {
|
||||
Q_ASSERT_INCRIT(520, a != nullptr); // the AO must be registered
|
||||
std::uint_fast8_t const pthre
|
||||
= static_cast<std::uint_fast8_t>(a->getPThre());
|
||||
Q_ASSERT_INCRIT(522, pthre == static_cast<std::uint_fast8_t>(
|
||||
Q_INVARIANT_INCRIT(522, pthre == static_cast<std::uint_fast8_t>(
|
||||
~static_cast<std::uint_fast8_t>(a->m_pthre_dis) & 0xFFU));
|
||||
|
||||
// set new active prio. and preemption-threshold
|
||||
@ -5245,6 +5244,7 @@ do {
|
||||
}
|
||||
#endif // QF_ON_CONTEXT_SW || Q_SPY
|
||||
|
||||
QF_MEM_APP();
|
||||
QF_INT_ENABLE(); // unconditionally enable interrupts
|
||||
|
||||
QP::QEvt const * const e = a->get_();
|
||||
@ -5261,7 +5261,7 @@ do {
|
||||
QF_MEM_SYS();
|
||||
|
||||
// internal integrity check (duplicate inverse storage)
|
||||
Q_ASSERT_INCRIT(532,
|
||||
Q_INVARIANT_INCRIT(532,
|
||||
QK_priv_.readySet.verify_(&QK_priv_.readySet_dis));
|
||||
|
||||
if (a->getEQueue().isEmpty()) { // empty queue?
|
||||
@ -5283,7 +5283,7 @@ do {
|
||||
p = 0U; // no activation needed
|
||||
}
|
||||
else {
|
||||
Q_ASSERT_INCRIT(542,
|
||||
Q_INVARIANT_INCRIT(542,
|
||||
QK_priv_.lockCeil == ~QK_priv_.lockCeil_dis);
|
||||
|
||||
// is the AO's prio. below the lock preemption-threshold?
|
||||
@ -6176,7 +6176,7 @@ if (m_ao.m_eQueue.m_nFree == 0U) {
|
||||
// is the mutex locked by this thread already (nested locking)?
|
||||
else if (m_ao.m_osObject == curr) {
|
||||
|
||||
// the nesting level beyond the arbitrary but high limit
|
||||
// the nesting level beyond the arbitrary but high bound
|
||||
// most likely means cyclic or recursive locking of a mutex.
|
||||
Q_ASSERT_INCRIT(220, m_ao.m_eQueue.m_nFree < 0xFFU);
|
||||
|
||||
@ -6323,7 +6323,7 @@ if (m_ao.m_eQueue.m_nFree == 0U) {
|
||||
}
|
||||
// is the mutex locked by this thread already (nested locking)?
|
||||
else if (m_ao.m_osObject == curr) {
|
||||
// the nesting level must not exceed the specified limit
|
||||
// the nesting level must not exceed the specified bound
|
||||
Q_ASSERT_INCRIT(320, m_ao.m_eQueue.m_nFree < 0xFFU);
|
||||
|
||||
// lock one more level
|
||||
@ -6677,7 +6677,7 @@ else { // starting QXThread
|
||||
<!--${QXK-extern-C::QXK_sched_}-->
|
||||
<operation name="QXK_sched_" type="std::uint_fast8_t" visibility="0x00" properties="0x00">
|
||||
<specifiers>noexcept</specifiers>
|
||||
<code>Q_REQUIRE_INCRIT(402,
|
||||
<code>Q_INVARIANT_INCRIT(402,
|
||||
QXK_priv_.readySet.verify_(&QXK_priv_.readySet_dis));
|
||||
|
||||
std::uint_fast8_t p;
|
||||
@ -6756,6 +6756,7 @@ std::uint_fast8_t p = next->getPrio();
|
||||
do {
|
||||
QXK_priv_.actPrio = p; // next active prio
|
||||
|
||||
QF_MEM_APP();
|
||||
QF_INT_ENABLE(); // unconditionally enable interrupts
|
||||
|
||||
QP::QEvt const * const e = next->get_();
|
||||
@ -6771,7 +6772,7 @@ do {
|
||||
QF_MEM_SYS();
|
||||
|
||||
// check internal integrity (duplicate inverse storage)
|
||||
Q_ASSERT_INCRIT(502,
|
||||
Q_INVARIANT_INCRIT(502,
|
||||
QXK_priv_.readySet.verify_(&QXK_priv_.readySet_dis));
|
||||
|
||||
if (next->getEQueue().isEmpty()) { // empty queue?
|
||||
@ -8454,11 +8455,9 @@ if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qsId_)) { \
|
||||
#define QP_HPP_
|
||||
|
||||
//============================================================================
|
||||
#define QP_VERSION 733U
|
||||
#define QP_VERSION_STR "7.3.3"
|
||||
|
||||
//! Encrypted current QP release (7.3.3) and date (2024-03-01)
|
||||
#define QP_RELEASE 0x70C4F752U
|
||||
#define QP_VERSION_STR "7.3.5-rc.1"
|
||||
#define QP_VERSION 735U
|
||||
#define QP_RELEASE 0x70A1DEF0U
|
||||
|
||||
//============================================================================
|
||||
//! @cond INTERNAL
|
||||
@ -10871,7 +10870,7 @@ void target_info_pre_(std::uint8_t const isReset) {
|
||||
QS::u8_raw_(QS_OBJ_PTR_SIZE | (QS_FUN_PTR_SIZE << 4U));
|
||||
QS::u8_raw_(QS_TIME_SIZE);
|
||||
|
||||
// send the limits...
|
||||
// send the bounds...
|
||||
QS::u8_raw_(QF_MAX_ACTIVE);
|
||||
QS::u8_raw_(QF_MAX_EPOOL | (QF_MAX_TICK_RATE << 4U));
|
||||
|
||||
|
@ -172,27 +172,27 @@ void QHsm::init(
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
// drill down into the state hierarchy with initial transitions...
|
||||
std::int_fast8_t limit = MAX_NEST_DEPTH_; // loop hard limit
|
||||
do {
|
||||
QStateHandler path[MAX_NEST_DEPTH_]; // tran entry path array
|
||||
std::int_fast8_t ip = 0; // tran entry path index
|
||||
|
||||
path[0] = m_temp.fun;
|
||||
static_cast<void>(QHSM_RESERVED_EVT_(m_temp.fun, Q_EMPTY_SIG));
|
||||
while (m_temp.fun != t) {
|
||||
// note: ip is here the fixed upper loop bound
|
||||
while ((m_temp.fun != t) && (ip < (MAX_NEST_DEPTH_ - 1))) {
|
||||
++ip;
|
||||
path[ip] = m_temp.fun;
|
||||
static_cast<void>(QHSM_RESERVED_EVT_(m_temp.fun, Q_EMPTY_SIG));
|
||||
}
|
||||
QF_CRIT_ENTRY();
|
||||
// The initial transition source state must be reached
|
||||
// Too many state nesting levels or "malformed" HSM.
|
||||
Q_ASSERT_INCRIT(220, m_temp.fun == t);
|
||||
// too many state nesting levels or "malformed" HSM
|
||||
Q_ENSURE_INCRIT(220, ip < MAX_NEST_DEPTH_);
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
m_temp.fun = path[0];
|
||||
|
||||
// retrace the entry path in reverse (desired) order...
|
||||
// note: ip is the fixed upper loop bound
|
||||
do {
|
||||
// enter path[ip]
|
||||
if (QHSM_RESERVED_EVT_(path[ip], Q_ENTRY_SIG)
|
||||
@ -220,14 +220,9 @@ void QHsm::init(
|
||||
QS_CRIT_EXIT();
|
||||
}
|
||||
#endif // Q_SPY
|
||||
|
||||
--limit;
|
||||
} while ((r == Q_RET_TRAN) && (limit > 0));
|
||||
} while (r == Q_RET_TRAN);
|
||||
|
||||
QF_CRIT_ENTRY();
|
||||
// Loop limit must not be reached.
|
||||
// Too many state nesting levels or likely "malformed" HSM
|
||||
Q_ENSURE_INCRIT(290, limit > 0);
|
||||
|
||||
QS_MEM_SYS();
|
||||
QS_BEGIN_PRE_(QS_QEP_INIT_TRAN, qsId)
|
||||
@ -259,9 +254,9 @@ void QHsm::dispatch(
|
||||
QF_CRIT_STAT
|
||||
|
||||
QF_CRIT_ENTRY();
|
||||
Q_REQUIRE_INCRIT(300, (s != Q_STATE_CAST(0))
|
||||
Q_INVARIANT_INCRIT(302, (s != Q_STATE_CAST(0))
|
||||
&& (m_state.uint == static_cast<std::uintptr_t>(~m_temp.uint)));
|
||||
Q_REQUIRE_INCRIT(302, QEvt::verify_(e));
|
||||
Q_INVARIANT_INCRIT(303, QEvt::verify_(e));
|
||||
|
||||
QS_MEM_SYS();
|
||||
QS_BEGIN_PRE_(QS_QEP_DISPATCH, qsId)
|
||||
@ -277,7 +272,7 @@ void QHsm::dispatch(
|
||||
// process the event hierarchically...
|
||||
QState r;
|
||||
m_temp.fun = s;
|
||||
std::int_fast8_t limit = MAX_NEST_DEPTH_; // loop hard limit
|
||||
std::int_fast8_t ip = MAX_NEST_DEPTH_; // fixed upper loop bound
|
||||
do {
|
||||
s = m_temp.fun;
|
||||
r = (*s)(this, e); // invoke state handler s
|
||||
@ -297,11 +292,11 @@ void QHsm::dispatch(
|
||||
r = QHSM_RESERVED_EVT_(s, Q_EMPTY_SIG); // superstate of s
|
||||
}
|
||||
|
||||
--limit;
|
||||
} while ((r == Q_RET_SUPER) && (limit > 0));
|
||||
--ip;
|
||||
} while ((r == Q_RET_SUPER) && (ip > 0));
|
||||
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ASSERT_INCRIT(310, limit > 0);
|
||||
Q_ENSURE_INCRIT(310, ip > 0);
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
if (r >= Q_RET_TRAN) { // regular tran. taken?
|
||||
@ -312,21 +307,21 @@ void QHsm::dispatch(
|
||||
path[2] = s; // tran. source
|
||||
|
||||
// exit current state to tran. source s...
|
||||
limit = MAX_NEST_DEPTH_; // loop hard limit
|
||||
for (; (t != s) && (limit > 0); t = m_temp.fun) {
|
||||
ip = MAX_NEST_DEPTH_; // fixed upper loop bound
|
||||
for (; (t != s) && (ip > 0); t = m_temp.fun) {
|
||||
// exit from t
|
||||
if (QHSM_RESERVED_EVT_(t, Q_EXIT_SIG) == Q_RET_HANDLED) {
|
||||
QS_STATE_EXIT_(t, qsId);
|
||||
// find superstate of t
|
||||
static_cast<void>(QHSM_RESERVED_EVT_(t, Q_EMPTY_SIG));
|
||||
}
|
||||
--limit;
|
||||
--ip;
|
||||
}
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ASSERT_INCRIT(320, limit > 0);
|
||||
Q_ENSURE_INCRIT(320, ip > 0);
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
std::int_fast8_t ip = hsm_tran(path, qsId); // take the tran.
|
||||
ip = hsm_tran(path, qsId); // take the tran.
|
||||
|
||||
#ifdef Q_SPY
|
||||
if (r == Q_RET_TRAN_HIST) {
|
||||
@ -343,6 +338,7 @@ void QHsm::dispatch(
|
||||
#endif // Q_SPY
|
||||
|
||||
// execute state entry actions in the desired order...
|
||||
// note: ip is the fixed upper loop bound
|
||||
for (; ip >= 0; --ip) {
|
||||
// enter path[ip]
|
||||
if (QHSM_RESERVED_EVT_(path[ip], Q_ENTRY_SIG)
|
||||
@ -373,6 +369,7 @@ void QHsm::dispatch(
|
||||
// find superstate
|
||||
static_cast<void>(QHSM_RESERVED_EVT_(m_temp.fun, Q_EMPTY_SIG));
|
||||
|
||||
// note: ip is the fixed upper loop bound
|
||||
while ((m_temp.fun != t) && (ip < (MAX_NEST_DEPTH_ - 1))) {
|
||||
++ip;
|
||||
path[ip] = m_temp.fun;
|
||||
@ -381,14 +378,14 @@ void QHsm::dispatch(
|
||||
QHSM_RESERVED_EVT_(m_temp.fun, Q_EMPTY_SIG));
|
||||
}
|
||||
QF_CRIT_ENTRY();
|
||||
// The initial transition source state must be reached.
|
||||
// Too many state nesting levels or "malformed" HSM.
|
||||
Q_ASSERT_INCRIT(330, m_temp.fun == t);
|
||||
// too many state nesting levels or "malformed" HSM
|
||||
Q_ENSURE_INCRIT(330, ip < MAX_NEST_DEPTH_);
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
m_temp.fun = path[0];
|
||||
|
||||
// retrace the entry path in reverse (correct) order...
|
||||
// note: ip is the fixed upper loop bound
|
||||
do {
|
||||
// enter path[ip]
|
||||
if (QHSM_RESERVED_EVT_(path[ip], Q_ENTRY_SIG)
|
||||
@ -452,17 +449,17 @@ void QHsm::dispatch(
|
||||
bool QHsm::isIn(QStateHandler const state) noexcept {
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
Q_REQUIRE_INCRIT(602, m_state.uint
|
||||
== static_cast<std::uintptr_t>(~m_temp.uint));
|
||||
Q_INVARIANT_INCRIT(602, m_state.uint
|
||||
== static_cast<std::uintptr_t>(~m_temp.uint));
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
bool inState = false; // assume that this HSM is not in 'state'
|
||||
|
||||
// scan the state hierarchy bottom-up
|
||||
QStateHandler s = m_state.fun;
|
||||
std::int_fast8_t limit = MAX_NEST_DEPTH_ + 1; // loop hard limit
|
||||
std::int_fast8_t lbound = MAX_NEST_DEPTH_ + 1; // fixed upper loop bound
|
||||
QState r = Q_RET_SUPER;
|
||||
for (; (r != Q_RET_IGNORED) && (limit > 0); --limit) {
|
||||
for (; (r != Q_RET_IGNORED) && (lbound > 0); --lbound) {
|
||||
if (s == state) { // do the states match?
|
||||
inState = true; // 'true' means that match found
|
||||
break; // break out of the for-loop
|
||||
@ -474,7 +471,7 @@ bool QHsm::isIn(QStateHandler const state) noexcept {
|
||||
}
|
||||
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ENSURE_INCRIT(690, limit > 0);
|
||||
Q_ENSURE_INCRIT(690, lbound > 0);
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
@ -486,12 +483,13 @@ bool QHsm::isIn(QStateHandler const state) noexcept {
|
||||
|
||||
//${QEP::QHsm::childState} ...................................................
|
||||
QStateHandler QHsm::childState(QStateHandler const parent) noexcept {
|
||||
QStateHandler child = m_state.fun; // start with the current state
|
||||
QStateHandler child = m_state.fun; // start with current state
|
||||
bool isFound = false; // start with the child not found
|
||||
|
||||
// establish stable state configuration
|
||||
m_temp.fun = child;
|
||||
QState r;
|
||||
std::int_fast8_t lbound = MAX_NEST_DEPTH_; // fixed upper loop bound
|
||||
do {
|
||||
// is this the parent of the current child?
|
||||
if (m_temp.fun == parent) {
|
||||
@ -502,7 +500,9 @@ QStateHandler QHsm::childState(QStateHandler const parent) noexcept {
|
||||
child = m_temp.fun;
|
||||
r = QHSM_RESERVED_EVT_(m_temp.fun, Q_EMPTY_SIG);
|
||||
}
|
||||
} while (r != Q_RET_IGNORED); // QHsm::top() state not reached
|
||||
--lbound;
|
||||
} while ((r != Q_RET_IGNORED) // QHsm::top() state not reached
|
||||
&& (lbound > 0));
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
m_temp.uint = ~m_state.uint;
|
||||
@ -510,10 +510,12 @@ QStateHandler QHsm::childState(QStateHandler const parent) noexcept {
|
||||
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ASSERT_INCRIT(890, isFound);
|
||||
// NOTE: the following postcondition can only succeed when
|
||||
// (lbound > 0), so no extra check is necessary.
|
||||
Q_ENSURE_INCRIT(890, isFound);
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
return child; // return the child
|
||||
return child;
|
||||
}
|
||||
|
||||
//${QEP::QHsm::hsm_tran} .....................................................
|
||||
@ -577,6 +579,7 @@ std::int_fast8_t QHsm::hsm_tran(
|
||||
t = m_temp.fun; // save source->super
|
||||
|
||||
// find target->super->super...
|
||||
// note: ip is the fixed upper loop bound
|
||||
QState r = QHSM_RESERVED_EVT_(path[1], Q_EMPTY_SIG);
|
||||
while ((r == Q_RET_SUPER)
|
||||
&& (ip < (MAX_NEST_DEPTH_ - 1)))
|
||||
@ -593,9 +596,10 @@ std::int_fast8_t QHsm::hsm_tran(
|
||||
}
|
||||
}
|
||||
QF_CRIT_ENTRY();
|
||||
// Tran. source must be found within the nesting depth
|
||||
// Too many state nesting levels or "malformed" HSM.
|
||||
Q_ASSERT_INCRIT(510, r != Q_RET_SUPER);
|
||||
// NOTE: The following postcondition succeeds only when
|
||||
// ip < QHSM_MAX_NEST_DEPTH, so no additional check is necessary
|
||||
// too many state nesting levels or "malformed" HSM.
|
||||
Q_ENSURE_INCRIT(510, r != Q_RET_SUPER);
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
// the LCA not found yet?
|
||||
@ -611,6 +615,7 @@ std::int_fast8_t QHsm::hsm_tran(
|
||||
// == target->super->super...
|
||||
iq = ip;
|
||||
r = Q_RET_IGNORED; // indicate that the LCA NOT found
|
||||
// note: iq is the fixed upper loop bound
|
||||
do {
|
||||
if (t == path[iq]) { // is this the LCA?
|
||||
r = Q_RET_HANDLED; // indicate the LCA found
|
||||
@ -627,7 +632,7 @@ std::int_fast8_t QHsm::hsm_tran(
|
||||
// (g) check each source->super->...
|
||||
// for each target->super...
|
||||
r = Q_RET_IGNORED; // keep looping
|
||||
std::int_fast8_t limit = MAX_NEST_DEPTH_;
|
||||
std::int_fast8_t lbound = MAX_NEST_DEPTH_;
|
||||
do {
|
||||
// exit from t
|
||||
if (QHSM_RESERVED_EVT_(t, Q_EXIT_SIG)
|
||||
@ -652,10 +657,10 @@ std::int_fast8_t QHsm::hsm_tran(
|
||||
}
|
||||
} while (iq >= 0);
|
||||
|
||||
--limit;
|
||||
} while ((r != Q_RET_HANDLED) && (limit > 0));
|
||||
--lbound;
|
||||
} while ((r != Q_RET_HANDLED) && (lbound > 0));
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ASSERT_INCRIT(530, limit > 0);
|
||||
Q_ASSERT_INCRIT(530, lbound > 0);
|
||||
QF_CRIT_EXIT();
|
||||
}
|
||||
}
|
||||
|
@ -138,15 +138,15 @@ void QMsm::init(
|
||||
m_state.obj = m_temp.tatbl->target;
|
||||
|
||||
// drill down into the state hierarchy with initial transitions...
|
||||
std::int_fast8_t limit = MAX_NEST_DEPTH_; // loop hard limit
|
||||
std::int_fast8_t lbound = MAX_NEST_DEPTH_; // fixed upper loop bound
|
||||
do {
|
||||
// execute the tran. table
|
||||
r = execTatbl_(m_temp.tatbl, qsId);
|
||||
--limit;
|
||||
} while ((r >= Q_RET_TRAN_INIT) && (limit > 0));
|
||||
--lbound;
|
||||
} while ((r >= Q_RET_TRAN_INIT) && (lbound > 0));
|
||||
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ENSURE_INCRIT(290, limit > 0);
|
||||
Q_ENSURE_INCRIT(290, lbound > 0);
|
||||
|
||||
QS_MEM_SYS();
|
||||
QS_BEGIN_PRE_(QS_QEP_INIT_TRAN, qsId)
|
||||
@ -177,9 +177,9 @@ void QMsm::dispatch(
|
||||
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
Q_REQUIRE_INCRIT(300, (s != nullptr)
|
||||
Q_INVARIANT_INCRIT(300, (s != nullptr)
|
||||
&& (m_state.uint == static_cast<std::uintptr_t>(~m_temp.uint)));
|
||||
Q_REQUIRE_INCRIT(302, QEvt::verify_(e));
|
||||
Q_INVARIANT_INCRIT(302, QEvt::verify_(e));
|
||||
|
||||
QS_MEM_SYS();
|
||||
QS_BEGIN_PRE_(QS_QEP_DISPATCH, qsId)
|
||||
@ -194,7 +194,7 @@ void QMsm::dispatch(
|
||||
|
||||
// scan the state hierarchy up to the top state...
|
||||
QState r;
|
||||
std::int_fast8_t limit = MAX_NEST_DEPTH_; // loop hard limit
|
||||
std::int_fast8_t lbound = MAX_NEST_DEPTH_; // fixed upper loop bound
|
||||
do {
|
||||
r = (*t->stateHandler)(this, e); // call state handler function
|
||||
|
||||
@ -227,10 +227,10 @@ void QMsm::dispatch(
|
||||
|
||||
t = t->superstate; // advance to the superstate
|
||||
}
|
||||
--limit;
|
||||
} while ((t != nullptr) && (limit > 0));
|
||||
--lbound;
|
||||
} while ((t != nullptr) && (lbound > 0));
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ASSERT_INCRIT(310, limit > 0);
|
||||
Q_ASSERT_INCRIT(310, lbound > 0);
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
if (r >= Q_RET_TRAN) { // any kind of tran. taken?
|
||||
@ -243,7 +243,7 @@ void QMsm::dispatch(
|
||||
QF_CRIT_EXIT();
|
||||
#endif // Q_SPY
|
||||
|
||||
limit = MAX_NEST_DEPTH_; // loop hard limit
|
||||
lbound = MAX_NEST_DEPTH_; // fixed upper loop bound
|
||||
do {
|
||||
// save the tran-action table before it gets clobbered
|
||||
QMTranActTable const * const tatbl = m_temp.tatbl;
|
||||
@ -310,11 +310,11 @@ void QMsm::dispatch(
|
||||
}
|
||||
|
||||
t = s; // set target to the current state
|
||||
--limit;
|
||||
} while ((r >= Q_RET_TRAN) && (limit > 0));
|
||||
--lbound;
|
||||
} while ((r >= Q_RET_TRAN) && (lbound > 0));
|
||||
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ASSERT_INCRIT(320, limit > 0);
|
||||
Q_ASSERT_INCRIT(320, lbound > 0);
|
||||
|
||||
QS_MEM_SYS();
|
||||
QS_BEGIN_PRE_(QS_QEP_TRAN, qsId)
|
||||
@ -375,8 +375,8 @@ bool QMsm::isIn(QStateHandler const state) noexcept {
|
||||
bool inState = false; // assume that this SM is not in 'state'
|
||||
|
||||
QMState const *s = m_state.obj;
|
||||
std::int_fast8_t limit = MAX_NEST_DEPTH_; // loop hard limit
|
||||
for (; (s != nullptr) && (limit > 0); --limit) {
|
||||
std::int_fast8_t lbound = MAX_NEST_DEPTH_; // fixed upper loop bound
|
||||
for (; (s != nullptr) && (lbound > 0); --lbound) {
|
||||
if (s->stateHandler == state) { // match found?
|
||||
inState = true;
|
||||
break;
|
||||
@ -388,7 +388,7 @@ bool QMsm::isIn(QStateHandler const state) noexcept {
|
||||
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ENSURE_INCRIT(490, limit > 0);
|
||||
Q_ENSURE_INCRIT(490, lbound > 0);
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
return inState;
|
||||
@ -399,8 +399,8 @@ bool QMsm::isInState(QMState const * const stateObj) const noexcept {
|
||||
bool inState = false; // assume that this SM is not in 'state'
|
||||
|
||||
QMState const *s = m_state.obj;
|
||||
std::int_fast8_t limit = MAX_NEST_DEPTH_; // loop hard limit
|
||||
for (; (s != nullptr) && (limit > 0); --limit) {
|
||||
std::int_fast8_t lbound = MAX_NEST_DEPTH_; // fixed upper loop bound
|
||||
for (; (s != nullptr) && (lbound > 0); --lbound) {
|
||||
if (s == stateObj) { // match found?
|
||||
inState = true;
|
||||
break;
|
||||
@ -412,7 +412,7 @@ bool QMsm::isInState(QMState const * const stateObj) const noexcept {
|
||||
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ENSURE_INCRIT(590, limit > 0);
|
||||
Q_ENSURE_INCRIT(590, lbound > 0);
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
return inState;
|
||||
@ -424,9 +424,9 @@ QMState const * QMsm::childStateObj(QMState const * const parent) const noexcept
|
||||
bool isFound = false; // start with the child not found
|
||||
QMState const *s;
|
||||
|
||||
std::int_fast8_t limit = MAX_NEST_DEPTH_; // loop hard limit
|
||||
std::int_fast8_t lbound = MAX_NEST_DEPTH_; // fixed upper loop bound
|
||||
for (s = m_state.obj;
|
||||
(s != nullptr) && (limit > 0);
|
||||
(s != nullptr) && (lbound > 0);
|
||||
s = s->superstate)
|
||||
{
|
||||
if (s == parent) {
|
||||
@ -436,17 +436,17 @@ QMState const * QMsm::childStateObj(QMState const * const parent) const noexcept
|
||||
else {
|
||||
child = s;
|
||||
}
|
||||
--limit;
|
||||
--lbound;
|
||||
}
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ASSERT_INCRIT(610, limit > 0);
|
||||
Q_ASSERT_INCRIT(610, lbound > 0);
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
if (!isFound) { // still not found?
|
||||
limit = MAX_NEST_DEPTH_; // loop hard limit
|
||||
lbound = MAX_NEST_DEPTH_; // fixed upper loop bound
|
||||
for (s = m_temp.obj;
|
||||
(s != nullptr) && (limit > 0);
|
||||
(s != nullptr) && (lbound > 0);
|
||||
s = s->superstate)
|
||||
{
|
||||
if (s == parent) {
|
||||
@ -456,12 +456,12 @@ QMState const * QMsm::childStateObj(QMState const * const parent) const noexcept
|
||||
else {
|
||||
child = s;
|
||||
}
|
||||
--limit;
|
||||
--lbound;
|
||||
}
|
||||
}
|
||||
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ENSURE_INCRIT(690, isFound && (limit > 0));
|
||||
Q_ENSURE_INCRIT(690, isFound && (lbound > 0));
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
return child; // return the child
|
||||
@ -484,9 +484,9 @@ QState QMsm::execTatbl_(
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
QState r = Q_RET_NULL;
|
||||
std::int_fast8_t limit = MAX_TRAN_LENGTH_; // loop hard limit
|
||||
std::int_fast8_t lbound = MAX_TRAN_LENGTH_; // fixed upper loop bound
|
||||
QActionHandler const *a = &tatbl->act[0];
|
||||
for (; (*a != nullptr) && (limit > 0); ++a) {
|
||||
for (; (*a != nullptr) && (lbound > 0); ++a) {
|
||||
r = (*(*a))(this); // call the action through the 'a' pointer
|
||||
#ifdef Q_SPY
|
||||
QS_CRIT_ENTRY();
|
||||
@ -530,7 +530,7 @@ QState QMsm::execTatbl_(
|
||||
QS_MEM_APP();
|
||||
QS_CRIT_EXIT();
|
||||
#endif // Q_SPY
|
||||
--limit;
|
||||
--lbound;
|
||||
}
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ENSURE_INCRIT(790, *a == nullptr);
|
||||
@ -556,8 +556,8 @@ void QMsm::exitToTranSource_(
|
||||
|
||||
// exit states from the current state to the tran. source state
|
||||
QMState const *s = cs;
|
||||
std::int_fast8_t limit = MAX_NEST_DEPTH_; // loop hard limit
|
||||
for (; (s != ts) && (limit > 0); --limit) {
|
||||
std::int_fast8_t lbound = MAX_NEST_DEPTH_; // fixed upper loop bound
|
||||
for (; (s != ts) && (lbound > 0); --lbound) {
|
||||
// exit action provided in state 's'?
|
||||
if (s->exitAction != nullptr) {
|
||||
// execute the exit action
|
||||
@ -583,7 +583,7 @@ void QMsm::exitToTranSource_(
|
||||
}
|
||||
}
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ENSURE_INCRIT(890, limit > 0);
|
||||
Q_ENSURE_INCRIT(890, lbound > 0);
|
||||
QF_CRIT_EXIT();
|
||||
}
|
||||
|
||||
|
@ -91,7 +91,7 @@ bool QActive::post_(
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
std::uint8_t const pcopy = static_cast<std::uint8_t>(~m_prio_dis);
|
||||
Q_REQUIRE_INCRIT(102, (QEvt::verify_(e)) && (m_prio == pcopy));
|
||||
Q_INVARIANT_INCRIT(102, (QEvt::verify_(e)) && (m_prio == pcopy));
|
||||
#endif
|
||||
|
||||
QEQueueCtr nFree = m_eQueue.m_nFree; // get volatile into temporary
|
||||
@ -234,7 +234,7 @@ void QActive::postLIFO(QEvt const * const e) noexcept {
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
std::uint8_t const pcopy = static_cast<std::uint8_t>(~m_prio_dis);
|
||||
Q_REQUIRE_INCRIT(202, (QEvt::verify_(e)) && (m_prio == pcopy));
|
||||
Q_INVARIANT_INCRIT(202, (QEvt::verify_(e)) && (m_prio == pcopy));
|
||||
#endif
|
||||
|
||||
#ifdef QXK_HPP_
|
||||
|
@ -236,7 +236,7 @@ QEvt * newX_(
|
||||
void gc(QEvt const * const e) noexcept {
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
Q_REQUIRE_INCRIT(402, QEvt::verify_(e));
|
||||
Q_INVARIANT_INCRIT(402, QEvt::verify_(e));
|
||||
|
||||
std::uint_fast8_t const poolNum = e->getPoolNum_();
|
||||
|
||||
@ -300,7 +300,7 @@ QEvt const * newRef_(
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
|
||||
Q_REQUIRE_INCRIT(502, QEvt::verify_(e));
|
||||
Q_INVARIANT_INCRIT(502, QEvt::verify_(e));
|
||||
|
||||
std::uint_fast8_t const poolNum = e->getPoolNum_();
|
||||
|
||||
@ -329,7 +329,7 @@ void deleteRef_(QEvt const * const evtRef) noexcept {
|
||||
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
Q_REQUIRE_INCRIT(602, QEvt::verify_(e));
|
||||
Q_INVARIANT_INCRIT(602, QEvt::verify_(e));
|
||||
|
||||
#ifdef Q_SPY
|
||||
std::uint_fast8_t const poolNum = e->getPoolNum_();
|
||||
|
@ -152,8 +152,8 @@ void * QMPool::get(
|
||||
QFreeBlock * const fb_next = fb->m_next;
|
||||
|
||||
// the free block must have integrity (duplicate inverse storage)
|
||||
Q_ASSERT_INCRIT(302, Q_UINTPTR_CAST_(fb_next)
|
||||
== static_cast<std::uintptr_t>(~fb->m_next_dis));
|
||||
Q_INVARIANT_INCRIT(302, Q_UINTPTR_CAST_(fb_next)
|
||||
== static_cast<std::uintptr_t>(~fb->m_next_dis));
|
||||
|
||||
m_nFree = (m_nFree - 1U); // one free block less
|
||||
if (m_nFree == 0U) { // is the pool becoming empty?
|
||||
@ -230,7 +230,7 @@ void QMPool::put(
|
||||
#endif
|
||||
|
||||
// set as new head of the free list
|
||||
m_free_head = static_cast<QFreeBlock *>(block);
|
||||
m_free_head = fb;
|
||||
|
||||
m_nFree = m_nFree + 1U; // one more free block in this pool
|
||||
|
||||
|
@ -121,7 +121,7 @@ void QActive::publish_(
|
||||
QF_MEM_SYS();
|
||||
|
||||
Q_REQUIRE_INCRIT(200, sig < static_cast<QSignal>(maxPubSignal_));
|
||||
Q_REQUIRE_INCRIT(202,
|
||||
Q_INVARIANT_INCRIT(202,
|
||||
subscrList_[sig].m_set.verify_(&subscrList_[sig].m_set_dis));
|
||||
|
||||
QS_BEGIN_PRE_(QS_QF_PUBLISH, qsId)
|
||||
@ -164,9 +164,9 @@ void QActive::publish_(
|
||||
|
||||
QF_SCHED_STAT_
|
||||
QF_SCHED_LOCK_(p); // lock the scheduler up to AO's prio
|
||||
std::uint_fast8_t limit = QF_MAX_ACTIVE + 1U;
|
||||
std::uint_fast8_t lbound = QF_MAX_ACTIVE + 1U;
|
||||
do { // loop over all subscribers
|
||||
--limit;
|
||||
--lbound;
|
||||
|
||||
// POST() asserts internally if the queue overflows
|
||||
a->POST(e, sender);
|
||||
@ -188,7 +188,7 @@ void QActive::publish_(
|
||||
else {
|
||||
p = 0U; // no more subscribers
|
||||
}
|
||||
} while ((p != 0U) && (limit > 0U));
|
||||
} while ((p != 0U) && (lbound > 0U));
|
||||
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ENSURE_INCRIT(290, p == 0U);
|
||||
@ -223,7 +223,7 @@ void QActive::subscribe(enum_t const sig) const noexcept {
|
||||
&& (sig < maxPubSignal_)
|
||||
&& (0U < p) && (p <= QF_MAX_ACTIVE)
|
||||
&& (registry_[p] == this));
|
||||
Q_REQUIRE_INCRIT(302,
|
||||
Q_INVARIANT_INCRIT(302,
|
||||
subscrList_[sig].m_set.verify_(&subscrList_[sig].m_set_dis));
|
||||
|
||||
QS_BEGIN_PRE_(QS_QF_ACTIVE_SUBSCRIBE, m_prio)
|
||||
@ -260,7 +260,7 @@ void QActive::unsubscribe(enum_t const sig) const noexcept {
|
||||
&& (sig < maxPubSignal_)
|
||||
&& (0U < p) && (p <= QF_MAX_ACTIVE)
|
||||
&& (registry_[p] == this));
|
||||
Q_REQUIRE_INCRIT(402,
|
||||
Q_INVARIANT_INCRIT(402,
|
||||
subscrList_[sig].m_set.verify_(&subscrList_[sig].m_set_dis));
|
||||
|
||||
QS_BEGIN_PRE_(QS_QF_ACTIVE_UNSUBSCRIBE, m_prio)
|
||||
|
@ -300,8 +300,8 @@ void QTimeEvt::tick(
|
||||
QS_END_PRE_()
|
||||
|
||||
// scan the linked-list of time events at this rate...
|
||||
std::uint_fast8_t limit = 2U*QF_MAX_ACTIVE; // loop hard limit
|
||||
for (; limit > 0U; --limit) {
|
||||
std::uint_fast8_t lbound = 2U*QF_MAX_ACTIVE; // fixed upper loop bound
|
||||
for (; lbound > 0U; --lbound) {
|
||||
QTimeEvt *e = prev->m_next; // advance down the time evt. list
|
||||
|
||||
if (e == nullptr) { // end of the list?
|
||||
@ -321,7 +321,7 @@ void QTimeEvt::tick(
|
||||
}
|
||||
|
||||
// the time event 'e' must be valid
|
||||
Q_ASSERT_INCRIT(112, QEvt::verify_(e));
|
||||
Q_INVARIANT_INCRIT(112, QEvt::verify_(e));
|
||||
|
||||
if (e->m_ctr == 0U) { // time event scheduled for removal?
|
||||
prev->m_next = e->m_next;
|
||||
@ -410,7 +410,7 @@ void QTimeEvt::tick(
|
||||
QF_MEM_SYS();
|
||||
}
|
||||
|
||||
Q_ENSURE_INCRIT(190, limit > 0U);
|
||||
Q_ENSURE_INCRIT(190, lbound > 0U);
|
||||
QF_MEM_APP();
|
||||
QF_CRIT_EXIT();
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ QSchedStatus schedLock(std::uint_fast8_t const ceiling) noexcept {
|
||||
QF_MEM_SYS();
|
||||
|
||||
Q_REQUIRE_INCRIT(100, !QK_ISR_CONTEXT_());
|
||||
Q_REQUIRE_INCRIT(102, QK_priv_.lockCeil
|
||||
Q_INVARIANT_INCRIT(102, QK_priv_.lockCeil
|
||||
== static_cast<std::uint_fast8_t>(~QK_priv_.lockCeil_dis));
|
||||
|
||||
// first store the previous lock prio
|
||||
@ -119,7 +119,7 @@ void schedUnlock(QSchedStatus const prevCeil) noexcept {
|
||||
QF_CRIT_ENTRY();
|
||||
QF_MEM_SYS();
|
||||
|
||||
Q_REQUIRE_INCRIT(202, QK_priv_.lockCeil
|
||||
Q_INVARIANT_INCRIT(202, QK_priv_.lockCeil
|
||||
== static_cast<std::uint_fast8_t>(~QK_priv_.lockCeil_dis));
|
||||
Q_REQUIRE_INCRIT(210, (!QK_ISR_CONTEXT_())
|
||||
&& (QK_priv_.lockCeil > prevCeil));
|
||||
@ -161,7 +161,7 @@ QK_Attr QK_priv_;
|
||||
std::uint_fast8_t QK_sched_() noexcept {
|
||||
// NOTE: this function is entered with interrupts DISABLED
|
||||
|
||||
Q_REQUIRE_INCRIT(402,
|
||||
Q_INVARIANT_INCRIT(402,
|
||||
QK_priv_.readySet.verify_(&QK_priv_.readySet_dis));
|
||||
|
||||
std::uint_fast8_t p;
|
||||
@ -172,7 +172,7 @@ std::uint_fast8_t QK_sched_() noexcept {
|
||||
// find the highest-prio AO with non-empty event queue
|
||||
p = QK_priv_.readySet.findMax();
|
||||
|
||||
Q_ASSERT_INCRIT(412, QK_priv_.actThre
|
||||
Q_INVARIANT_INCRIT(412, QK_priv_.actThre
|
||||
== static_cast<std::uint_fast8_t>(~QK_priv_.actThre_dis));
|
||||
|
||||
// is the AO's prio. below the active preemption-threshold?
|
||||
@ -180,7 +180,7 @@ std::uint_fast8_t QK_sched_() noexcept {
|
||||
p = 0U; // no activation needed
|
||||
}
|
||||
else {
|
||||
Q_ASSERT_INCRIT(422, QK_priv_.lockCeil
|
||||
Q_INVARIANT_INCRIT(422, QK_priv_.lockCeil
|
||||
== static_cast<std::uint_fast8_t>(~QK_priv_.lockCeil_dis));
|
||||
|
||||
// is the AO's prio. below the lock-ceiling?
|
||||
@ -188,7 +188,7 @@ std::uint_fast8_t QK_sched_() noexcept {
|
||||
p = 0U; // no activation needed
|
||||
}
|
||||
else {
|
||||
Q_ASSERT_INCRIT(432, QK_priv_.nextPrio
|
||||
Q_INVARIANT_INCRIT(432, QK_priv_.nextPrio
|
||||
== static_cast<std::uint_fast8_t>(~QK_priv_.nextPrio_dis));
|
||||
QK_priv_.nextPrio = p; // next AO to run
|
||||
#ifndef Q_UNSAFE
|
||||
@ -209,7 +209,7 @@ void QK_activate_() noexcept {
|
||||
std::uint_fast8_t const prio_in = QK_priv_.actPrio; // save initial prio.
|
||||
std::uint_fast8_t p = QK_priv_.nextPrio; // next prio to run
|
||||
|
||||
Q_REQUIRE_INCRIT(502,
|
||||
Q_INVARIANT_INCRIT(502,
|
||||
(prio_in == static_cast<std::uint_fast8_t>(~QK_priv_.actPrio_dis))
|
||||
&& (p == static_cast<std::uint_fast8_t>(~QK_priv_.nextPrio_dis)));
|
||||
Q_REQUIRE_INCRIT(510, (prio_in <= QF_MAX_ACTIVE)
|
||||
@ -234,7 +234,7 @@ void QK_activate_() noexcept {
|
||||
Q_ASSERT_INCRIT(510, a != nullptr);
|
||||
|
||||
pthre_in = static_cast<std::uint_fast8_t>(a->getPThre());
|
||||
Q_ASSERT_INCRIT(511, pthre_in == static_cast<std::uint_fast8_t>(
|
||||
Q_INVARIANT_INCRIT(511, pthre_in == static_cast<std::uint_fast8_t>(
|
||||
~static_cast<std::uint_fast8_t>(a->m_pthre_dis) & 0xFFU));
|
||||
}
|
||||
|
||||
@ -244,7 +244,7 @@ void QK_activate_() noexcept {
|
||||
Q_ASSERT_INCRIT(520, a != nullptr); // the AO must be registered
|
||||
std::uint_fast8_t const pthre
|
||||
= static_cast<std::uint_fast8_t>(a->getPThre());
|
||||
Q_ASSERT_INCRIT(522, pthre == static_cast<std::uint_fast8_t>(
|
||||
Q_INVARIANT_INCRIT(522, pthre == static_cast<std::uint_fast8_t>(
|
||||
~static_cast<std::uint_fast8_t>(a->m_pthre_dis) & 0xFFU));
|
||||
|
||||
// set new active prio. and preemption-threshold
|
||||
@ -272,6 +272,7 @@ void QK_activate_() noexcept {
|
||||
}
|
||||
#endif // QF_ON_CONTEXT_SW || Q_SPY
|
||||
|
||||
QF_MEM_APP();
|
||||
QF_INT_ENABLE(); // unconditionally enable interrupts
|
||||
|
||||
QP::QEvt const * const e = a->get_();
|
||||
@ -288,7 +289,7 @@ void QK_activate_() noexcept {
|
||||
QF_MEM_SYS();
|
||||
|
||||
// internal integrity check (duplicate inverse storage)
|
||||
Q_ASSERT_INCRIT(532,
|
||||
Q_INVARIANT_INCRIT(532,
|
||||
QK_priv_.readySet.verify_(&QK_priv_.readySet_dis));
|
||||
|
||||
if (a->getEQueue().isEmpty()) { // empty queue?
|
||||
@ -310,7 +311,7 @@ void QK_activate_() noexcept {
|
||||
p = 0U; // no activation needed
|
||||
}
|
||||
else {
|
||||
Q_ASSERT_INCRIT(542,
|
||||
Q_INVARIANT_INCRIT(542,
|
||||
QK_priv_.lockCeil == ~QK_priv_.lockCeil_dis);
|
||||
|
||||
// is the AO's prio. below the lock preemption-threshold?
|
||||
|
@ -998,7 +998,7 @@ void target_info_pre_(std::uint8_t const isReset) {
|
||||
QS::u8_raw_(QS_OBJ_PTR_SIZE | (QS_FUN_PTR_SIZE << 4U));
|
||||
QS::u8_raw_(QS_TIME_SIZE);
|
||||
|
||||
// send the limits...
|
||||
// send the bounds...
|
||||
QS::u8_raw_(QF_MAX_ACTIVE);
|
||||
QS::u8_raw_(QF_MAX_EPOOL | (QF_MAX_TICK_RATE << 4U));
|
||||
|
||||
|
@ -81,7 +81,7 @@ void schedDisable(std::uint_fast8_t const ceiling) {
|
||||
QF_CRIT_ENTRY();
|
||||
QF_MEM_SYS();
|
||||
|
||||
Q_ASSERT_INCRIT(102, priv_.schedCeil
|
||||
Q_INVARIANT_INCRIT(102, priv_.schedCeil
|
||||
== static_cast<std::uint_fast8_t>(~priv_.schedCeil_dis));
|
||||
|
||||
if (ceiling > priv_.schedCeil) { // raising the scheduler ceiling?
|
||||
@ -108,7 +108,7 @@ void schedEnable() {
|
||||
QF_CRIT_ENTRY();
|
||||
QF_MEM_SYS();
|
||||
|
||||
Q_ASSERT_INCRIT(202, priv_.schedCeil
|
||||
Q_INVARIANT_INCRIT(202, priv_.schedCeil
|
||||
== static_cast<std::uint_fast8_t>(~priv_.schedCeil_dis));
|
||||
|
||||
if (priv_.schedCeil != 0U) { // actually enabling the scheduler?
|
||||
@ -186,10 +186,10 @@ int_t run() {
|
||||
for (;;) { // QV event loop...
|
||||
|
||||
// check internal integrity (duplicate inverse storage)
|
||||
Q_ASSERT_INCRIT(302,
|
||||
Q_INVARIANT_INCRIT(302,
|
||||
QV::priv_.readySet.verify_(&QV::priv_.readySet_dis));
|
||||
// check internal integrity (duplicate inverse storage)
|
||||
Q_ASSERT_INCRIT(303, QV::priv_.schedCeil
|
||||
Q_INVARIANT_INCRIT(303, QV::priv_.schedCeil
|
||||
== static_cast<std::uint_fast8_t>(~QV::priv_.schedCeil_dis));
|
||||
|
||||
// find the maximum prio. AO ready to run
|
||||
|
@ -175,7 +175,7 @@ QXK_Attr QXK_priv_;
|
||||
|
||||
//${QXK-extern-C::QXK_sched_} ................................................
|
||||
std::uint_fast8_t QXK_sched_() noexcept {
|
||||
Q_REQUIRE_INCRIT(402,
|
||||
Q_INVARIANT_INCRIT(402,
|
||||
QXK_priv_.readySet.verify_(&QXK_priv_.readySet_dis));
|
||||
|
||||
std::uint_fast8_t p;
|
||||
@ -254,6 +254,7 @@ void QXK_activate_() noexcept {
|
||||
do {
|
||||
QXK_priv_.actPrio = p; // next active prio
|
||||
|
||||
QF_MEM_APP();
|
||||
QF_INT_ENABLE(); // unconditionally enable interrupts
|
||||
|
||||
QP::QEvt const * const e = next->get_();
|
||||
@ -269,7 +270,7 @@ void QXK_activate_() noexcept {
|
||||
QF_MEM_SYS();
|
||||
|
||||
// check internal integrity (duplicate inverse storage)
|
||||
Q_ASSERT_INCRIT(502,
|
||||
Q_INVARIANT_INCRIT(502,
|
||||
QXK_priv_.readySet.verify_(&QXK_priv_.readySet_dis));
|
||||
|
||||
if (next->getEQueue().isEmpty()) { // empty queue?
|
||||
|
@ -165,7 +165,7 @@ bool QXMutex::lock(QTimeEvtCtr const nTicks) noexcept {
|
||||
// is the mutex locked by this thread already (nested locking)?
|
||||
else if (m_ao.m_osObject == curr) {
|
||||
|
||||
// the nesting level beyond the arbitrary but high limit
|
||||
// the nesting level beyond the arbitrary but high bound
|
||||
// most likely means cyclic or recursive locking of a mutex.
|
||||
Q_ASSERT_INCRIT(220, m_ao.m_eQueue.m_nFree < 0xFFU);
|
||||
|
||||
@ -312,7 +312,7 @@ bool QXMutex::tryLock() noexcept {
|
||||
}
|
||||
// is the mutex locked by this thread already (nested locking)?
|
||||
else if (m_ao.m_osObject == curr) {
|
||||
// the nesting level must not exceed the specified limit
|
||||
// the nesting level must not exceed the specified bound
|
||||
Q_ASSERT_INCRIT(320, m_ao.m_eQueue.m_nFree < 0xFFU);
|
||||
|
||||
// lock one more level
|
||||
|
Loading…
x
Reference in New Issue
Block a user