7.3.5-rc.1

Semantic versioning
This commit is contained in:
MMS 2024-04-24 09:12:56 -04:00
parent 340b6bbd92
commit 074c0dc3ae
41 changed files with 2490 additions and 654 deletions

@ -1 +1 @@
Subproject commit db8b6155e6931d2c55315dfd55b0e1fac0f96e33
Subproject commit 054cd1abe4b4abef5e45f36b1ce8f2aff4575494

127
README.md
View File

@ -13,16 +13,16 @@ it is recommended that you clone this repo like that:
git clone https://github.com/QuantumLeaps/qpc --recurse-submodules --depth 1
```
Alternatively, you can also download the latest
[QP/C Release](https://github.com/QuantumLeaps/qpc/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]
@ -34,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/qpc
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?
@ -126,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/qpc/releases>
[Active]: <https://www.state-machine.com/qpc/srs-qp_ao.html>
[AO_model]: <https://www.state-machine.com/qpc/srs-qp_ao.html#srs-qp_ao-model>
[Event]: <https://www.state-machine.com/qpc/srs-qp_evt.html>
[HSM]: <https://www.state-machine.com/qpc/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/qpc/gs_tut.html>
[Video]: <https://youtu.be/O7ER6_VqIH0>
[Video]: <https://youtu.be/O7ER6_VqIH0>

@ -1 +1 @@
Subproject commit 5b4edf6f7a1514169427fa42522d823fb31ee37c
Subproject commit 5e7c7e64d3a6b1c3fde11cb03252bfb37bbf1149

View File

@ -44,11 +44,9 @@
#define QP_H_
//============================================================================
#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
@ -117,9 +115,9 @@ typedef double float64_t;
//$declare${QEP} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
//${QEP::QP_versionStr[8]} ...................................................
//${QEP::QP_versionStr[16]} ..................................................
//! the current QP version number string in ROM, based on #QP_VERSION_STR
extern char const QP_versionStr[8];
extern char const QP_versionStr[16];
//${QEP::QSignal} ............................................................
#if (Q_SIGNAL_SIZE == 1U)

View File

@ -43,10 +43,6 @@
#ifndef QPC_H_
#define QPC_H_
#ifdef __cplusplus
extern "C" {
#endif
//============================================================================
#include "qp_port.h" // QP port from the port directory
#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem
@ -205,8 +201,4 @@ static inline void QF_psInit(
#endif // QP_API_VERSION < 691
#endif // QP_API_VERSION < 700
#ifdef __cplusplus
}
#endif
#endif // QPC_H_

View File

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

View File

@ -27,8 +27,8 @@
// <www.state-machine.com>
// <info@state-machine.com>
//============================================================================
//! @date Last updated on: 2023-12-04
//! @version Last updated for: @ref qpc_7_3_1
//! @date Last updated on: 2024-05-28
//! @version Last updated for: @ref qpc_7_3_5
//!
//! @file
//! @brief QXK/C port to ARM Cortex-M, ARM-CLANG
@ -376,10 +376,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)?
@ -489,7 +489,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...
@ -508,19 +508,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
@ -529,6 +528,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 >>>>>>>>>>>>>>>>>>>>>>>>>
@ -591,7 +594,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
@ -744,7 +747,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...

View File

@ -27,8 +27,8 @@
// <www.state-machine.com>
// <info@state-machine.com>
//============================================================================
//! @date Last updated on: 2024-01-30
//! @version Last updated for: @ref qpc_7_3_3
//! @date Last updated on: 2024-05-28
//! @version Last updated for: @ref qpc_7_3_5
//!
//! @file
//! @brief QXK/C port to ARM Cortex-M, GNU-ARM
@ -381,10 +381,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)?
@ -494,7 +494,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...
@ -513,19 +513,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
@ -534,6 +533,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 >>>>>>>>>>>>>>>>>>>>>>>>>
@ -596,7 +599,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
@ -749,7 +752,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...

View File

@ -27,8 +27,8 @@
// <www.state-machine.com>
// <info@state-machine.com>
//============================================================================
//! @date Last updated on: 2023-12-10
//! @version Last updated for: @ref qpc_7_3_1
//! @date Last updated on: 2024-05-28
//! @version Last updated for: @ref qpc_7_3_5
//!
//! @file
//! @brief QXK/C port to ARM Cortex-M, IAR-ARM
@ -48,11 +48,11 @@
// make sure that the offsets match the QXK declaration in "qxk.h"
_Static_assert(QXK_CURR == offsetof(QXK_Attr, curr),
"QXK_Attr.curr at unexpected offset");
"QXK_Attr.curr at unexpected offset");
_Static_assert(QXK_NEXT == offsetof(QXK_Attr, next),
"QXK_Attr.next at unexpected offset");
"QXK_Attr.next at unexpected offset");
_Static_assert(QXK_ACT_PRIO == offsetof(QXK_Attr, actPrio),
"QXK_Attr.actPrio at unexpected offset");
"QXK_Attr.actPrio at unexpected offset");
// offsets within struct QActive; NOTE: keep in synch with "qp.h" !!!
#define QACTIVE_PRIO 12
@ -380,10 +380,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)?
@ -493,7 +493,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...
@ -512,19 +512,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
@ -533,6 +532,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 >>>>>>>>>>>>>>>>>>>>>>>>>
@ -595,7 +598,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
@ -748,7 +751,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...

View File

@ -22,8 +22,8 @@
// <www.state-machine.com>
// <info@state-machine.com>
//============================================================================
//! @date Last updated on: 2023-12-12
//! @version Last updated for version: 7.3.1
//! @date Last updated on: 2024-05-14
//! @version Last updated for version: 7.3.4
//!
//! @file
//! @brief PC-Lint-Plus option file for linting QP/C source code
@ -44,7 +44,7 @@
au-misra4.lnt // MISRA-C:2023 (MC4) compliance
// customized BARR-C:2018 style guidelines
au-barr.lnt // BARR-C:2018 style guidelines
au-barr.lnt // BARR-C:2018 style guidelines
-e8505 // suppress [Rule 6.1e] function contains uppercase letters
-e8511 // suppress [Rule 7.1f] variable contains uppercase letters
-e8512 // suppress [Rule 7.1j] global variable should have 'g' prefix
@ -58,10 +58,7 @@ au-barr.lnt // BARR-C:2018 style guidelines
-e8522 // suppress [Rule 8.6a] variable should appear on RHS of '==' operator
au-ds.lnt // Dan Saks recommendations
// size/alignment options
cpu.lnt // for the chosen CPU
cpu.lnt // size/alignment options for the chosen CPU
// defined macros (might be undefined on command-line with -u<macro>)
-dQ_SPY
@ -69,7 +66,7 @@ cpu.lnt // for the chosen CPU
//============================================================================
// QP/C options for QP/C Applications
qpc.lnt // QP/C options
qpc.lnt // QP/C options
//============================================================================
// additional suppression rules for building QP/C source code...
@ -112,8 +109,9 @@ qpc.lnt // QP/C options
QF_CRIT_EXIT,
Q_ASSERT_INCRIT,
Q_REQUIRE_INCRIT,
Q_ERROR_INCRIT,
Q_ENSURE_INCRIT,
Q_INVARIANT_INCRIT,
Q_ERROR_INCRIT,
QF_SCHED_LOCK_,
QF_SCHED_UNLOCK_,
QF_ISR_CONTEXT_,

View 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

View 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-16
//! @version Last updated for: @ref qpc_7_3_0
//!
//! @file
//! @brief QS/C port to a 16-bit CPU and a generic C11 compiler.
//! @description
//! This is an example of a QP/C port with the documentation for the
//! configuration macros and includes.
//!
#ifndef QS_PORT_H_
#define QS_PORT_H_
// 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.h"
// *before* "qs.h".
#ifndef QP_PORT_H_
#include "qp_port.h" // use QS with QP
#endif
#include "qs.h" // QS platform-independent public interface
#endif // QS_PORT_H_

View File

@ -0,0 +1,47 @@
//! @file
//! @brief Selected exact-width and fast minimum-width integer types
//! for 16-bit CPU architecture (e.g., MSP430).
//!
//! @description
//! This header is part of the ANSI C99 standard library to define the
//! standard exact-width integer types (see C99 Section 7.18.1.1).
//! If the compiler does not provide the stdint.h header file, you can
//! either create one in the QP port directory, or you can typedef the
//! 8 exact-width integer types directly in the qep_port.h header file.
//!
//! @note The version included in the QP documentation contains only the 8
//! exact-width types and 6 fast minimum-width types actually used in QP.
//! The actual definition of the integer types is platform dependent.
#ifndef STDINT_H_
#define STDINT_H_
//lint -save
//lint -e9093 M3:R21.2(R) name matches a pattern reserved to the compiler
//lint -e586 B18:R5.2(b) keyword 'short'/'long' is deprecated
// Exact-width types. WG14/N843 C99 Standard, Section 7.18.1.1
typedef signed char int8_t; //!< exact-width 8-bit signed int
typedef signed int int16_t; //!< exact-width 16-bit signed int
typedef signed long int int32_t; //!< exact-width 32-bit signed int
typedef signed long long int64_t; //!< exact-width 64-bit signed int
typedef unsigned char uint8_t; //!< exact-width 8-bit unsigned int
typedef unsigned int uint16_t; //!< exact-width 16-bit unsigned int
typedef unsigned long int uint32_t; //!< exact-width 32-bit unsigned int
typedef unsigned long long uint64_t; //!< exact-width 64-bit unsigned int
// Fastest minimum-width types. WG14/N843 C99 Standard, Section 7.18.1.3
typedef signed int int_fast8_t; //!< fast at-least 8-bit signed int
typedef unsigned int uint_fast8_t; //!< fast at-least 8-bit unsigned int
typedef signed int int_fast16_t; //!< fast at-least 16-bit signed int
typedef unsigned int uint_fast16_t; //!< fast at-least 16-bit unsigned int
typedef signed long int_fast32_t; //!< fast at-least 32-bit signed int
typedef unsigned long uint_fast32_t; //!< fast at-least 32-bit unsigned int
// unsigned integer type capable of holding a pointer to void.
typedef unsigned uintptr_t; //!< unsigned int capable of holding void*
//lint -restore
#endif // STDINT_H_

View File

@ -0,0 +1,3 @@
// Size Options for 32bit CPU (e.g., ARM Cortex-M)
-si4 -sl4 -sll8 -ss2 -sw4 -sp4 -sf4 -sd8 -sld8

View 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-16
//! @version Last updated for: @ref qpc_7_3_0
//!
//! @file
//! @brief QS/C port to a 32-bit CPU and a generic C11 compiler.
//! @description
//! This is an example of a QP/C port with the documentation for the
//! configuration macros and includes.
//!
#ifndef QS_PORT_H_
#define QS_PORT_H_
// 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.h"
// *before* "qs.h".
#ifndef QP_PORT_H_
#include "qp_port.h" // use QS with QP
#endif
#include "qs.h" // QS platform-independent public interface
#endif // QS_PORT_H_

View File

@ -0,0 +1,47 @@
//! @file
//! @brief Selected exact-width and fast minimum-width integer types
//! for 32-bit CPU architecture (e.g., ARM Cortex-M).
//!
//! @description
//! This header is part of the ANSI C99 standard library to define the
//! standard exact-width integer types (see C99 Section 7.18.1.1).
//! If the compiler does not provide the stdint.h header file, you can
//! either create one in the QP port directory, or you can typedef the
//! 8 exact-width integer types directly in the qep_port.h header file.
//!
//! @note The version included in the QP documentation contains only the 8
//! exact-width types and 6 fast minimum-width types actually used in QP.
//! The actual definition of the integer types is platform dependent.
#ifndef STDINT_H_
#define STDINT_H_
//lint -save
//lint -e9093 M3:R21.2(R) name matches a pattern reserved to the compiler
//lint -e586 B18:R5.2(b) keyword 'short'/'long' is deprecated
// Exact-width types. WG14/N843 C99 Standard, Section 7.18.1.1
typedef signed char int8_t; //!< exact-width 8-bit signed int
typedef signed short int16_t; //!< exact-width 16-bit signed int
typedef signed int int32_t; //!< exact-width 32-bit signed int
typedef signed long long int64_t; //!< exact-width 64-bit signed int
typedef unsigned char uint8_t; //!< exact-width 8-bit unsigned int
typedef unsigned short uint16_t; //!< exact-width 16-bit unsigned int
typedef unsigned int uint32_t; //!< exact-width 32-bit unsigned int
typedef unsigned long long uint64_t; //!< exact-width 64-bit unsigned int
// Fastest minimum-width types. WG14/N843 C99 Standard, Section 7.18.1.3
typedef signed int int_fast8_t; //!< fast at-least 8-bit signed int
typedef unsigned int uint_fast8_t; //!< fast at-least 8-bit unsigned int
typedef signed int int_fast16_t; //!< fast at-least 16-bit signed int
typedef unsigned int uint_fast16_t; //!< fast at-least 16-bit unsigned int
typedef signed long int_fast32_t; //!< fast at-least 32-bit signed int
typedef unsigned long uint_fast32_t; //!< fast at-least 32-bit unsigned int
// unsigned integer type capable of holding a pointer to void.
typedef unsigned uintptr_t; //!< unsigned int capable of holding void*
//lint -restore
#endif // STDINT_H_

View 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

70
ports/lint-plus2/make.bat Normal file
View 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 QPC=..\..
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\*.c
%PCLP_EXE% -os(lint_qv.log) std.lnt %LINTFLAGS% -iqv ..\..\src\qv\*.c
%PCLP_EXE% -os(lint_qk.log) std.lnt %LINTFLAGS% -iqk ..\..\src\qk\*.c
%PCLP_EXE% -os(lint_qxk.log) std.lnt %LINTFLAGS% -iqxk ..\..\src\qxk\*.c
%PCLP_EXE% -os(lint_qs.log) std.lnt %LINTFLAGS% -iqv ..\..\src\qs\*.c
:end
@endlocal

View File

@ -0,0 +1,368 @@
//============================================================================
// 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-14
//! @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%QPC%/include // QP/C public includes
// standards
// language standard...
au-misra3.lnt // MISRA-C:2023 (MC4) compliance
au-misra3-amd1.lnt // MISRA-C:2023 (MC4) compliance
au-misra3-amd2.lnt // MISRA-C:2023 (MC4) compliance
au-misra3-amd3.lnt // MISRA-C:2023 (MC4) compliance
au-misra3-amd4.lnt // MISRA-C:2023 (MC4) compliance
// customized BARR-C:2018 style guidelines
au-barr.lnt // BARR-C:2018 style guidelines
-e8505 // suppress [Rule 6.1e] function contains uppercase letters
-e8511 // suppress [Rule 7.1f] variable contains uppercase letters
-e8512 // suppress [Rule 7.1j] global variable should have 'g' prefix
-e8510 // suppress [Rule 7.1e] variable contains less than 3 characters
-e8513 // suppress [Rule 7.1k] variable should have 'pp' prefix
-e8514 // suppress [Rule 7.1l] variable should have 'p' prefix
-e8515 // suppress [Rule 7.1m] boolean variable should have 'b' prefix
-e8526 // suppress [Rule 5.1a] typedef name should consist of lowercase letters
-e8527 // suppress [Rule 5.1a] typedef name should end with '_t' suffix
-e9209 // suppress [Rule 5.2c] plain char data used with prohibited operator &
-e8522 // suppress [Rule 8.6a] variable should appear on RHS of '==' operator
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 QP/C Applications
qpc.lnt // QP/C options
//============================================================================
// additional suppression rules for building QP/C source code...
// QEP -----------------------------------------------------------------------
//! M4-D4.9(A) function-like macro
//! @tr{DVP-QP-MC4-D04_09A}
-esym(9026,
QACTIVE_CAST_)
//! M4-D4.9(A) function-like macro
//! @tr{DVP-QP-MC4-D04_09B}
-esym(9026,
QHSM_RESERVED_EVT_,
QS_STATE_ENTRY_,
QS_STATE_EXIT_)
//! M4-R11.5(A) conversion from pointer to void to other pointer
//! @tr{DVR-QP-MC4-R11_05}
-emacro(9079,
Q_EVT_CAST)
//! M4-R8.13(A) parameter of function could be pointer to const
//! @tr{DVR-QP-MC4-R08_13}
-efunc(818,
QMsm_isIn_)
// QF ------------------------------------------------------------------------
//! M4-D4.8(A) complete definition is unnecessary in this translation unit
//! @tr{DVP-QP-MC4-D04_08}
-efile(9045,
-qp_pkg.h)
//! M4-D4.9(A) function-like macro
//! @tr{DVP-QP-MC4-D04_09A}
-esym(9026,
QF_CRIT_ENTRY,
QF_CRIT_EXIT,
Q_ASSERT_INCRIT,
Q_REQUIRE_INCRIT,
Q_ENSURE_INCRIT,
Q_INVARIANT_INCRIT,
Q_ERROR_INCRIT,
QF_SCHED_LOCK_,
QF_SCHED_UNLOCK_,
QF_ISR_CONTEXT_,
QF_MPOOL_EL,
Q_UINTPTR_CAST_)
//! M4-R8.13(A) parameter of function could be pointer to const
//! @tr{DVR-QP-MC4-R08_13}
-efunc(818,
QActive_start_)
//! M4-R11.3(R) cast from pointer to object type
//! @tr{DVP-QP-MC4-R11_03B}
-emacro(9087,
QACTIVE_CAST_)
//! M4-R11.3(R) cast from pointer to object type
//! @tr{DVP-QP-MC4-R11_03B}
-efunc(9087,
QActive_ctor,
QMActive_ctor)
//! M4-R11.4(A) conversion between object pointer type and integer type
//! @tr{DVR-QP-MC4-R11_04}
-emacro(9078,
Q_UINTPTR_CAST_)
//! M4-R11.5(A) conversion from pointer to void to other pointer type
//! @tr{DVR-QP-MC4-R11_05}
-emacro(9079,
QACTIVE_CAST_,
QF_EPOOL_GET_)
-efunc(9079,
QF_bzero_,
QF_deleteRef_,
QMPool_get,
QMPool_put,
QMPool_init,
QTimeEvt_tick_,
QTimeEvt_armX,
QTimeEvt_rearm)
//! M4-R11.8(R) cast drops const qualifier
//! @tr{DVR-QP-MC4-R11_08}
-emacro(9005,
QACTIVE_CAST_)
-efunc(9005,
QEvt_refCtr_inc_,
QEvt_refCtr_dec_,
QF_gc)
//! M4-R15.5(A) return statement before end of function
//! @tr{DVP-QS-MC4-R15_05}
-efunc(904,
QActive_post_,
QActive_postLIFO_)
//! M4-R18.3(R) relational operator <= applied to pointers
//! @tr{DVR-QP-MC4-R18_03}
-efunc(946,
QMPool_get,
QMPool_put)
//! definition of macro ends in semicolon
//! @tr{DVR-QP-PCLP-823}
-esym(823,
QF_CRIT_STAT,
QF_SCHED_STAT_)
//! suspicious pointer-to-pointer conversion (area too small)
//! @tr{DVP-QP-PCLP-826}
-emacro(826,
QACTIVE_CAST_)
// QV ------------------------------------------------------------------------
// QK ------------------------------------------------------------------------
//! M4-D4.9(A) function-like macro
//! @tr{DVP-QP-MC4-D04_09A}
-esym(9026,
QK_ISR_CONTEXT_,
QK_ISR_ENTRY,
QK_ISR_EXIT)
// QXK -----------------------------------------------------------------------
//! M4-D4.9(A) function-like macro
//! @tr{DVP-QP-MC4-D04_09A}
-esym(9026,
QXK_ISR_CONTEXT_,
QXK_CONTEXT_SWITCH_,
QXK_PTR_CAST_,
QXTHREAD_CAST_,
QXTHREAD_EQUEUE_SIGNAL_)
//! M4-R11.3(R) cast from pointer to object type
//! @tr{DVP-QP-MC4-R11_03B}
-emacro(9087,
QXTHREAD_CAST_)
//! M4-R11.3(R) cast from pointer to object type
//! @tr{DVR-QP-MC4-R11_03C}
-emacro(9087,
QXK_PTR_CAST_)
//! M4-R11.5(A) conversion from pointer to void to other pointer type
//! @tr{DVR-QP-MC4-R11_05}
-emacro(9079,
QXK_PTR_CAST_)
//! MC3-R8.13(A) could be pointer to const
//! @tr{DVR-QP-MC4-R08_13}
-efunc(818,
QXThread_init_,
QXThread_dispatch_,
QXThread_postLIFO_)
//! @tr{DVP-QP-PCLP-826}
-emacro(826,
QXK_PTR_CAST_,
QXTHREAD_CAST_)
//! cast increases required alignment from 2 to 4
//! @tr{DVR-QP-PCLP-2445}
-emacro(2445,
QXK_PTR_CAST_)
// QS ------------------------------------------------------------------------
// the following options are needed only when Q_SPY is defined...
//! M4-D4.9(A) function-like macro
//! @tr{DVP-QS-MC4-D04_09A}
-esym(9026,
QS_INSERT_BYTE_,
QS_INSERT_ESC_BYTE_,
QS_RX_TRAN_,
QS_CRIT_ENTRY,
QS_CRIT_EXIT)
//! M4-R8.13(A) parameter ... of function could be pointer to const
//! @tr{DVR-QS-MC4-R08_13}
-efunc(818,
QHsmDummy_init_,
QHsmDummy_dispatch_,
QActiveDummy_start_,
QActiveDummy_init_,
QActiveDummy_dispatch_)
//! M4-R11.1(R) conversion between pointer to function and differing type
//! @tr{DVP-QS-MC4-R11_01}
-emacro(9074,
QS_FUN_PRE_)
-efunc(9074,
QS_getTestProbe_)
//! M4-R11.3(R) cast from pointer to object type
//! @tr{DVR-QS-MC4-R11_03C}
-efile(9087,
-qs_rx.c,
-qutest.c)
//! M4-R11.4(A) conversion between object pointer type and integer type
//! @tr{DVR-QS-MC4-R11_04}
-emacro(9078,
QS_OBJ_PRE_,
QS_FUN_PRE_)
-efunc(9078,
QS_rxHandleGoodFrame_,
QS_getTestProbe_)
//! M4-R11.5(A) conversion from pointer to void to other pointer type
//! @tr{DVR-QS-MC4-R11_05}
-efile(9079,
-qs_rx.c,
-qutest.c)
//! M4-R11.6(R) explicit cast from integer to 'void *'
//! @tr{DVR-QS-MC4-R11_06}
-emacro(923,
QS_OBJ_PRE_,
QS_FUN_PRE_)
-efunc(923,
QS_rxHandleGoodFrame_,
QS_getTestProbe_)
//! M4-R14.3(R) boolean condition for 'if' always evaluates to 'false'
//! @tr{DVR-QS-MC4-R14_03}
-emacro(774,
QS_BEGIN_PRE_)
//! M4-R19.2(A) union declared
//! @tr{DVR-QS-MC4-R19_02}
-efunc(9018,
QS_target_info_pre_,
QS_f32_fmt_,
QS_f64_fmt_)
//! constant value used in Boolean context (left operand to || operator)
//! @tr{DVR-QS-PCLP-506}
-emacro(506,
QS_BEGIN_PRE_)
//! excessive shift value (precision 0 shifted right by ...)
//! @tr{DVR-QS-PCLP-572}
-emacro(572,
QS_BEGIN_PRE_)
//! union initialization
//! @tr{DVR-QS-PCLP-708}
-efunc(708,
QS_f64_fmt_)
//! union member not referenced
//! @tr{DVR-QS-PCLP-754}
-esym(754,
Variant::aFlt,
AFltVar::prio,
*U32Rep::u32)
//! Constant expression evaluates to 0 in 'binary' operation '>>'
//! @tr{DVR-QS-PCLP-778}
-emacro(778,
QS_BEGIN_PRE_)
//! suspicious pointer-to-pointer conversion (area too small)
//! @tr{DVR-QS-PCLP-818}
-efile(826,
-qs_rx.c,
-qutest.c)
//! definition of macro ends in semicolon
//! @tr{DVR-QS-PCLP-823}
-esym(823,
QS_CRIT_STAT,
QS_BEGIN_PRE_)
//! the right operand to << always evaluates to 0
//! @tr{DVR-QS-PCLP-845}
-emacro(845,
QS_BEGIN_PRE_)
//! cast increases required alignment
//! @tr{DVP-QS-PCLP-2445}
-efunc(2445,
QS_rxHandleGoodFrame_,
QS_rxPoke_)

View File

@ -0,0 +1,94 @@
//============================================================================
// 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: 2024-05-01
//! @version Last updated for: @ref qpc_7_3_4
//!
//! @file
//! @brief QP/C "port" to PC-Lint-Plus, QK kernel, generic C99
#ifndef QP_PORT_H_
#define QP_PORT_H_
#include <stdint.h> // Exact-width types. WG14/N843 C99 Standard
#include <stdbool.h> // Boolean type. WG14/N843 C99 Standard
#ifdef QP_CONFIG
#include "qp_config.h" // external QP configuration
#endif
// no-return function specifier (C11 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 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() ((void)0)
// Define the ISR exit sequence
#define QK_ISR_EXIT() do { \
QF_INT_DISABLE(); \
if (QK_sched_() != 0U) { \
*Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 28U);\
} \
QF_INT_ENABLE(); \
} while (false)
void intDisable(void);
void intEnable(void);
uint32_t critEntry(void);
void critExit(uint32_t stat);
uint32_t QK_get_IPSR(void);
// include files -------------------------------------------------------------
#include "qequeue.h" // QK kernel uses the native QP event queue
#include "qmpool.h" // QK kernel uses the native QP memory pool
#include "qp.h" // QP framework
#include "qk.h" // QK kernel
#endif // QP_PORT_H_

View File

@ -0,0 +1,562 @@
// ---------------------------------------------------------------------------
// Copyright Gimpel Software LLC 2019. All rights reserved.
//
// This file is provided by Gimpel Software LLC (https://www.gimpel.com) for
// use with PC-lint Plus. Redistribution is permitted but any redistribution
// must preserve this notice and, if the redistributed file has been modified,
// provide notice that the file has been modified from the original.
// ---------------------------------------------------------------------------
// Adapted by Quantum Leaps from au-barr.lnt
//
// ql-style.lnt.lnt -- Author options - Quantum-Leaps:2018
//
// This options file contains options to help enforce the
// checks advocated by the Quantum Leaps Coding Standard
// https://barrgroup.com/Embedded-Systems/Books/Embedded-C-Coding-Standard
//========== GENERAL RULES ==========
// 1.2 Line Widths
/* not currently supported */
// 1.3 Braces
/* 9012 - body should be a compound statement */
+e9012
-append(9012,[BARR-C:2018 Rule 1.3a])
// 1.4 Parentheses
/* 9050 - dependence placed on precedence */
+e9050
-append(9050,[BARR-C:2018 Rule 1.4a])
/* 9097 - unparenthesized argument to sizeof */
+e9097
-append(9097,[BARR-C:2018 Rule 1.4a])
/* 821 - right hand side of assignment not parenthesized */
+e821
-append(821,[BARR-C:2018 Rule 1.4a])
/* 834 - operator op1 followed by operator op2 could be confusing */
+e834
-append(834,[BARR-C:2018 Rule 1.4a])
/* 9240 - left/right side of logical operator is not a primary expression */
+e9240
-append(9240,[BARR-C:2018 Rule 1.4b])
// 1.5 Common Abbreviations
/* not currently supported */
// 1.6 Casts
/* not currently supported */
// 1.7 Keywords to Avoid
/* 586 - keyword is deprecated */
-deprecate(keyword, auto,[BARR-C:2018 Rule 1.7a])
-deprecate(keyword, register,[BARR-C:2018 Rule 1.7b])
-deprecate(keyword, continue,[BARR-C:2018 Rule 1.7d])
/* 801 - goto statement used */
+e801
-append(801,[BARR-C:2018 Rule 1.7c])
/* 9041 - goto appears in block which is not nested in block containing label */
+e9041
-append(9041,[BARR-C:2018 Rule 1.7c])
/* 9064 - goto references earlier label */
+e9064
-append(9064,[BARR-C:2018 Rule 1.7c])
// 1.8 Keywords to Frequent
/* 765 - external symbol could be made static */
+e765
-append(765,[BARR-C:2018 Rule 1.8a])
/* 818 - parameter of function could be pointer to const */
+e818
-append(818,[BARR-C:2018 Rule 1.8b])
/* 843 - static storage duration variable could be made const */
+e843
-append(843,[BARR-C:2018 Rule 1.8b])
/* 844 - static storage duration variable could be made pointer to const */
+e844
-append(844,[BARR-C:2018 Rule 1.8b])
/* 952 - parameter of function could be const */
+e952
-append(952,[BARR-C:2018 Rule 1.8b])
/* 953 - local variable could be const */
+e953
-append(953,[BARR-C:2018 Rule 1.8b])
/* 954 - local variable could be pointer to const */
+e954
-append(954,[BARR-C:2018 Rule 1.8b])
/* 2765 - reference to variable which is neither atomic nor volatile sig_atomic_t within signal handler */
+e2765
-append(2765,[BARR-C:2018 Rule 1.8c])
//========== COMMENTS ==========
// 2.1 Acceptable Formats
/* 427 - C++ comment continued via back-slash */
+e427
-append(427,[BARR-C:2018 Rule 2.1b])
/* 602 - nested block comment */
+e602
-append(602,[BARR-C:2018 Rule 2.1b])
/* 9059 - C comment contains C++ comment */
+e9059
-append(9059,[BARR-C:2018 Rule 2.1b])
// 9259 - C comment contains '://' sequence
+e9259
-append(9259,[BARR-C:2018 Rule 2.1b])
/* 9066 - C++ comment contains C comment */
+e9066
-append(9066,[BARR-C:2018 Rule 2.1b])
// 2.2 Locations and Comments
/* not statically checkable */
//========== WHITE SPACE RULES ==========
// 3.1 Spaces
/* not currently supported */
// 3.2 Alignment
/* not currently supported */
// 3.3 Black Lines
/* 783 - line does not end with a newline */
+e783
-append(783,[BARR-C:2018 Rule 3.3c])
// 3.4 Indentation
/* 525 - unexpected negative indentation */
+e525
-append(525,[BARR-C:2018 Rule 3.4a])
/* 539 - unexpected positive indentation */
+e539
-append(539,[BARR-C:2018 Rule 3.4a])
/* 725 - unexpected lack of indentation */
+e725
-append(725,[BARR-C:2018 Rule 3.4a])
// 3.5 Tabs
/* not currently supported */
// 3.6 Non-Printing Characters
/* not currently supported */
//========== MODULE RULES ==========
// 4.1 Naming Conventions
/* 8517 - module does not end with '.c' */
-hook(module_open, -cond(!('%[file_name]' ~ '[.]c$'),
+message(8517, "module '%[file_name]' should have '.c' extension")))
+e8517
-append(8517,[BARR-C:2018 Rule 4.1b])
/* 8518 - header does not end with '.h' */
-hook(header_open, -cond(!('%[file_name]' ~ '[.]h$'),
+message(8517, "header '%[file_name]' should have '.h' extension")))
+e8518
-append(8518,[BARR-C:2018 Rule 4.1b])
/* 8519 - 'main' function defined in file that does not contain the word 'main' */
-hook(func_decl, -cond('%[qual_name]' == 'main' && %[is_definition] && !('%[file]' ~ 'main'),
+message(8519, "main function defined in file '%[file]' which does not have the word 'main' in its name")))
+e8519
-append(8519,[BARR-C:2018 Rule 4.1d])
// 4.2 Header Files
/* 451 - header file repeatedly included but has no header guard */
+e451
-append(451,[BARR-C:2018 Rule 4.2b])
/* 967 - header file does not have a standard include guard */
+e967
-append(967,[BARR-C:2018 Rule 4.2b])
/* 9107 - header cannot be included in more than one translation unit because of the definition of symbol */
+e9107
-append(9107,[BARR-C:2018 Rule 4.2c])
/* 755 - global macro not referenced */
+e755
-append(755,[BARR-C:2018 Rule 4.2c])
/* 756 - global typedef not referenced */
+e756
-append(756,[BARR-C:2018 Rule 4.2c])
/* 757 - global declarator not referenced */
+e757
-append(757,[BARR-C:2018 Rule 4.2c])
/* 758 - global tag not referenced */
+e758
-append(758,[BARR-C:2018 Rule 4.2c])
/* 759 - header declaration for symbol could be moved from header to module */
+e759
-append(759,[BARR-C:2018 Rule 4.2c])
/* 768 - global field not referenced */
+e768
-append(768,[BARR-C:2018 Rule 4.2c])
/* 769 - global enumeration constant not referenced */
+e769
-append(769,[BARR-C:2018 Rule 4.2c])
// 4.3 Source Files
/* 9019 - declaration of symbol before #include */
-append(9019,[BARR-C:2018 Rule 4.3b])
/* 8520 - #include used with absolute path */
-hook(header_open, -cond('%[file_name]' ~ '^([[:alpha:]]:)?[/\\\\]',
+message(8520, "#include directive uses absolute path to include file '%[file_name]'")))
+e8520
-append(8520,[BARR-C:2018 Rule 4.3d])
/* 8521 - #include used to include module file */
-hook(header_open, -cond('%[file_name]' ~ '[.]c$',
+message(8521, "#include directive used to include module file '%[file_name]'")))
+e8521
-append(8521,[BARR-C:2018 Rule 4.3f])
// 4.4 File Templates
/* not statically checkable */
//========== DATA TYPE RULES ==========
/* 8528 - non-anonymous struct/union/enum declared outside of typedef */
-hook(record_decl, -cond(%[is_freestanding] && !%[is_anonymous],
+message(8528, "non-anonymous struct/union declared outside of a typedef")))
-hook(enum_decl, -cond(%[is_freestanding] && '%[name]' != '',
+message(8528, "non-anonymous enum declared outside of a typedef")))
+e8528
-append(8528,[BARR-C:2018 Rule 5.1b])
// 5.2 Fixed-Width Integers
/* 586 - keyword/type is deprecated */
+e586
-deprecate(type,signed char,[BARR-C:2018 Rule 5.2a])
-deprecate(type,unsigned char,[BARR-C:2018 Rule 5.2a])
-deprecate(type,signed short,[BARR-C:2018 Rule 5.2a])
-deprecate(type,unsigned short,[BARR-C:2018 Rule 5.2a])
-deprecate(type,signed int,[BARR-C:2018 Rule 5.2a])
-deprecate(type,unsigned int,[BARR-C:2018 Rule 5.2a])
-deprecate(type,signed long,[BARR-C:2018 Rule 5.2a])
-deprecate(type,unsigned long,[BARR-C:2018 Rule 5.2a])
-deprecate(type,signed long long,[BARR-C:2018 Rule 5.2a])
-deprecate(type,unsigned long long,[BARR-C:2018 Rule 5.2a])
-deprecate(keyword, short,[BARR-C:2018 Rule 5.2b])
-deprecate(keyword, long,[BARR-C:2018 Rule 5.2b])
// 5.3 Signed and Unsigned Integers
/* 9420 - bitfield does not have unsigned type */
+e9420
-append(9420,[BARR-C:2018 Rule 5.3a])
/* 9130 - bitwise operator applied to signed underlying type */
+e9130
-append(9130,[BARR-C:2018 Rule 5.3b])
/* 570 - negative value loses sign during implicit conversion */
+e570
-append(570,[BARR-C:2018 Rule 5.3c])
/* 713 - implicit conversion from unsigned to signed may lose precision */
+e713
-append(713,[BARR-C:2018 Rule 5.3c])
/* 8524 - combining signed and unsigned types with operator op1 */
-hook(binary_expr, -cond(%[walk_lhs_expr{false}.walk_type.is_integer] &&
%[walk_rhs_expr{false}.walk_type.is_integer] &&
!%[walk_lhs_expr.walk_past_paren_imp.walk_type.is_enumeral] &&
!%[walk_rhs_expr.walk_past_paren_imp.walk_type.is_enumeral] &&
!%[walk_lhs_expr.walk_past_paren_imp.walk_type.is_boolean] &&
!%[walk_rhs_expr.walk_past_paren_imp.walk_type.is_boolean] &&
'%[walk_lhs_expr.walk_past_paren_imp.walk_type.is_unsigned_int_enum]' !=
'%[walk_rhs_expr.walk_past_paren_imp.walk_type.is_unsigned_int_enum]',
+message(8524, "combining signed and unsigned types with operator '%[opcode]'")))
+e8524
-append(8524,[BARR-C:2018 Rule 5.3c])
// 5.4 Floating Point
/* 586 - type is deprecated */
-deprecate(type,float,[BARR-C:2018 Rule 5.4b])
-deprecate(type,double,[BARR-C:2018 Rule 5.4b])
-deprecate(type,long double,[BARR-C:2018 Rule 5.4b])
/* 777 - testing floating point values for equality */
+e777
-append(777,[BARR-C:2018 Rule 5.4b])
/* 9252 - testing floating point for equality using exact value */
+e9252
-append(9252,[BARR-C:2018 Rule 5.4b])
// 5.5 Structures and Unions
/* not currently supported */
// 5.6 Booleans
/* 8523 - cast to boolean */
-hook(cast_expr, -cond(%[is_cstyle_cast] && %[walk_type.is_boolean],
+message(8523, "cast to boolean")))
+e8523
-append(8523,[BARR-C:2018 Rule 5.6b])
//========== PROCEDURE RULES ==========
// 6.1 Naming Conventions
/* 8501 - function has name that matches a keyword in C or C++ */
-hook(func_decl, -cond('%[name]' ~ '^(?P<keyword>alignas|alignof|and|and_eq|asm|auto|bitand|bitor|bool|break|case|catch|char|char8_t|char16_t|char32_t|class|compl|concept|const|consteval|constexpr|const_cast|continue|co_await|co_return|co_yield|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|false|float|for|friend|goto|if|inline|int|long|mutable|namespace|new|noexcept|not|not_eq|nullptr|operator|or|or_eq|private|protected|public|register|reinterpret_cast|requires|restrict|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|true|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while|xor|xor_eq|_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local)$', +message(8501, "function '%[name]' matches the name of a C/C++ keyword")))
+e8501
-append(8501,[BARR-C:2018 Rule 6.1a])
/* 8502 - function has same name as standard library function */
-hook(func_decl, -cond('%[name]' ~ '^(?:abort|abs|acos|acosf|acosh|acoshf|acoshl|acosl|asctime|asin|asinf|asinh|asinhf|asinhl|asinl|assert|atan|atan2|atan2f|atan2l|atanf|atanh|atanhf|atanhl|atanl|atexit|atof|atoi|atol|atoll|bsearch|btowc|cabs|cabsf|cabsl|cacos|cacosf|cacosh|cacoshf|cacoshl|cacosl|calloc|carg|cargf|cargl|casin|casinf|casinh|casinhf|casinhl|casinl|catan|catanf|catanh|catanhf|catanhl|catanl|cbrt|cbrtf|cbrtl|ccos|ccosf|ccosh|ccoshf|ccoshl|ccosl|ceil|ceilf|ceill|cexp|cexpf|cexpl|cimag|cimagf|cimagl|clearerr|clock|clog|clogf|clogl|conj|conjf|conjl|copysign|copysignf|copysignl|cos|cosf|cosh|coshf|coshl|cosl|cpow|cpowf|cpowl|cproj|cprojf|cprojl|creal|crealf|creall|csin|csinf|csinh|csinhf|csinhl|csinl|csqrt|csqrtf|csqrtl|ctan|ctanf|ctanh|ctanhf|ctanhl|ctanl|ctime|difftime|div|erf|erfc|erfcf|erfcl|erff|erfl|exit|_Exit|exp|exp2|exp2f|exp2l|expf|expl|expm1|expm1f|expm1l|fabs|fabsf|fabsl|fclose|fdim|fdimf|fdiml|feclearexcept|fegetenv|fegetexceptflag|fegetround|feholdexcept|feof|feraiseexcept|ferror|fesetenv|fesetexceptflag|fesetround|fetestexcept|feupdateenv|fflush|fgetc|fgetpos|fgets|fgetwc|fgetws|floor|floorf|floorl|fma|fmaf|fmal|fmax|fmaxf|fmaxl|fmin|fminf|fminl|fmod|fmodf|fmodl|fopen|fpclassify|fprintf|fputc|fputs|fputwc|fputws|fread|free|freopen|frexp|frexpf|frexpl|fscanf|fseek|fsetpos|ftell|fwide|fwprintf|fwrite|fwscanf|getc|getchar|getenv|gets|getwc|getwchar|gmtime|hypot|hypotf|hypotl|ilogb|ilogbf|ilogbl|imaxabs|imaxdiv|isalnum|isalpha|isblank|iscntrl|isdigit|isfinite|isgraph|isgreater|isgreaterequal|isinf|isless|islessequal|islessgreater|islower|isnan|isnormal|isprint|ispunct|isspace|isunordered|isupper|iswalnum|iswalpha|iswblank|iswcntrl|iswctype|iswdigit|iswgraph|iswlower|iswprint|iswpunct|iswspace|iswupper|iswxdigit|isxdigit|labs|ldexp|ldexpf|ldexpl|ldiv|lgamma|lgammaf|lgammal|llabs|lldiv|llrint|llrintf|llrintl|llround|llroundf|llroundl|localeconv|localtime|log|log10|log10f|log10l|log1p|log1pf|log1pl|log2|log2f|log2l|logb|logbf|logbl|logf|logl|longjmp|lrint|lrintf|lrintl|lround|lroundf|lroundl|malloc|mblen|mbrlen|mbrtowc|mbsinit|mbsrtowcs|mbstowcs|mbtowc|memchr|memcmp|memcpy|memmove|memset|mktime|modf|modff|modfl|nan|nanf|nanl|nearbyint|nearbyintf|nearbyintl|nextafter|nextafterf|nextafterl|nexttoward|nexttowardf|nexttowardl|perror|pow|powf|powl|printf|putc|putchar|puts|putwc|putwchar|qsort|raise|rand|realloc|remainder|remainderf|remainderl|remove|remquo|remquof|remquol|rename|rewind|rint|rintf|rintl|round|roundf|roundl|scalbln|scalblnf|scalblnl|scalbn|scalbnf|scalbnl|scanf|setbuf|setjmp|setlocale|setvbuf|signal|signbit|sin|sinf|sinh|sinhf|sinhl|sinl|snprintf|sprintf|sqrt|sqrtf|sqrtl|srand|sscanf|strcat|strchr|strcmp|strcoll|strcpy|strcspn|strerror|strftime|strlen|strncat|strncmp|strncpy|strpbrk|strrchr|strspn|strstr|strtod|strtof|strtoimax|strtok|strtol|strtold|strtoll|strtoul|strtoull|strtoumax|strxfrm|swprintf|swscanf|system|tan|tanf|tanh|tanhf|tanhl|tanl|tgamma|tgammaf|tgammal|time|tmpfile|tmpnam|tolower|toupper|towctrans|towlower|towupper|trunc|truncf|truncl|ungetc|ungetwc|va_arg|va_copy|va_end|va_start|vfprintf|vfscanf|vfwprintf|vfwscanf|vprintf|vscanf|vsnprintf|vsprintf|vsscanf|vswprintf|vswscanf|vwprintf|vwscanf|wcrtomb|wcscat|wcschr|wcscmp|wcscoll|wcscpy|wcscspn|wcsftime|wcslen|wcsncat|wcsncmp|wcsncpy|wcspbrk|wcsrchr|wcsrtombs|wcsspn|wcsstr|wcstod|wcstof|wcstoimax|wcstok|wcstol|wcstold|wcstoll|wcstombs|wcstoul|wcstoull|wcstoumax|wcsxfrm|wctob|wctomb|wctrans|wctype|wmemchr|wmemcmp|wmemcpy|wmemmove|wmemset|wprintf|wscanf)$', +message(8502, "function '%[name]' matches the name of a standard library function")))
+e8502
-append(8502,[BARR-C:2018 Rule 6.1b])
/* 8503 - function has name that begins with an underscore */
-hook(func_decl, -cond('%[name]' ~ '^_', +message(8503, "function '%[name]' begins with an underscore")))
+e8503
-append(8503,[BARR-C:2018 Rule 6.1c])
/* 8504 - function name is longer than 31 characters */
-hook(func_decl, -cond('%[name]' ~ '.{32,}', +message(8504, "function '%[name]' is longer than 31 characters")))
+e8504
-append(8504,[BARR-C:2018 Rule 6.1d])
/* 8506 - macro name contains lowercase letter(s) */
-hook(macro_define, -cond(!%[is_builtin] && '%[name]' ~ '[[:lower:]]', +message(8506, "macro '%[name]' contains lowercase letters")))
+e8506
-append(8506,[BARR-C:2018 Rule 6.1f])
// 6.2 Functions
/* 904 - return statement before end of function */
+e904
-append(904,[BARR-C:2018 Rule 6.2c])
/* 937 - old-style function declaration for function */
+e937
-append(937,[BARR-C:2018 Rule 6.2f])
/* 957 - function defined without a prototype in scope */
+e957
-append(957,[BARR-C:2018 Rule 6.2f])
/* 832 - parameter not explicitly declared, int assumed */
+e832
-append(832,[BARR-C:2018 Rule 6.2f])
// 6.3 Function-Like Macros
/* 9026 - function-like macro defined */
+e9026
-append(9026,[BARR-C:2018 Rule 6.3a])
/* 665 - unparenthesized parameter in macro is passed an expression */
+e665
-append(665,[BARR-C:2018 Rule 6.3b])
/* 666 - expression with side effects passed to repeated parameter */
+e666
-append(666,[BARR-C:2018 Rule 6.3b])
/* 773 - expression-like macro not parenthesized */
+e773
-append(773,[BARR-C:2018 Rule 6.3b])
/* 9022 - unparenthesized macro parameter in definition of macro */
+e9022
-append(9022,[BARR-C:2018 Rule 6.3b])
// 6.4 Threads of Execution
/* not currently supported */
// 6.5 Interrupt Service Routines
/* not currently supported */
//========== VARIABLES ==========
// 7.1 Naming Conventions
/* 8507 - variable has name that matches a keyword in C or C++ */
-hook(var_decl, -cond('%[name]' ~ '^(?P<keyword>alignas|alignof|and|and_eq|asm|auto|bitand|bitor|bool|break|case|catch|char|char8_t|char16_t|char32_t|class|compl|concept|const|consteval|constexpr|const_cast|continue|co_await|co_return|co_yield|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|false|float|for|fortran|friend|goto|if|inline|int|interrupt|long|mutable|namespace|new|noexcept|not|not_eq|nullptr|operator|or|or_eq|private|protected|public|register|reinterpret_cast|requires|restrict|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|true|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while|xor|xor_eq|_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local)$', +message(8507, "variable '%[name]' matches the name of a C/C++ keyword")))
+e8507
-append(8507,[BARR-C:2018 Rule 7.1a])
/* 8525 - variable has same name as standard library variable */
-hook(var_decl, -cond('%[name]' ~ '^(?:errno|stderr|stdin|stdout)$',
+message(8525, "variale '%[name]' matches the same name of a standard library variable")))
+e8525
-append(8525,[BARR-C:2018 Rule 7.1b])
/* 8508 - variable has name that begins with an underscore */
-hook(var_decl, -cond('%[name]' ~ '^_', +message(8508, "variable '%[name]' begins with an underscore")))
+e8508
-append(8508,[BARR-C:2018 Rule 7.1c])
/* 8509 - variable name is longer than 31 characters */
-hook(var_decl, -cond('%[name]' ~ '.{32,}', +message(8509, "variable '%[name]' is longer than 31 characters")))
+e8509
-append(8509,[BARR-C:2018 Rule 6.1d])
// 7.2 Initialization
/* 530 - likely using an uninitialized value */
+e530
-append(530,[BARR-C:2018 Rule 7.2a])
/* 603 - argument to parameter of type pointer to const may be a pointer to uninitialized memory */
+e603
-append(603,[BARR-C:2018 Rule 7.2a])
/* 644 - potentially using an uninitialized value */
+e644
-append(644,[BARR-C:2018 Rule 7.2a])
/* 708 - union initialization */
+e708
-append(708,[BARR-C:2018 Rule 7.2a])
/* 727 - static local symbol not explicitly initialized */
+e727
-append(727,[BARR-C:2018 Rule 7.2a])
/* 728 - file scope static variable not explicitly initialized */
+e728
-append(728,[BARR-C:2018 Rule 7.2a])
/* 729 - external variable not explicitly initialized */
+e729
-append(729,[BARR-C:2018 Rule 7.2a])
/* 738 - address of static local symbol not explicitly initialized before passed to a function */
+e738
-append(738,[BARR-C:2018 Rule 7.2a])
/* 784 - nul character truncated from string */
+e784
-append(784,[BARR-C:2018 Rule 7.2a])
/* 785 - too few initializers for aggregate */
+e785
-append(785,[BARR-C:2018 Rule 7.2a])
//========== STATEMENT RULES ==========
// 8.1 Variable Declarations
/* 9146 - multiple declarators in a declaration */
+e9146
-append(9146,[BARR-C:2018 Rule 8.1a])
// 8.2 Conditional Statements
/* 720 - boolean test of assignment */
+e720
-append(720,[BARR-C:2018 Rule 8.2c])
/* 820 - boolean test of parenthesized assignment */
+e820
-append(820,[BARR-C:2018 Rule 8.2c])
/* 9013 - no 'else' at end of 'if ... else if' chain */
+e9013
-append(9013,[BARR-C:2018 Rule 8.2d])
// 8.3 Switch Statements
/* 9014 - switch without default */
+e9014
-append(9014,[BARR-C:2018 Rule 8.3b])
/* 616 - control flow falls through to next case without an intervening comment */
+e616
-append(616,[BARR-C:2018 Rule 8.3c])
// 8.4 Loops
/* 850 - for statement index variable modified in body */
+e850
-append(850,[BARR-C:2018 Rule 8.4b])
/* 716 - infinite loop via while */
+e716
-append(716,[BARR-C:2018 Rule 8.4c])
// 8.5 Jumps
/* 9041 - goto appears in block which is not nested in block containing label */
+e9041
-append(9041,[BARR-C:2018 Rule 8.5a])
/* 9064 - goto references earlier label */
+e9064
-append(9064,[BARR-C:2018 Rule 8.5a])
/* 586 - function/macro is deprecated */
-deprecate(function,abort,[BARR-C:2018 Rule 8.5b])
-deprecate(function,exit,[BARR-C:2018 Rule 8.5b])
-deprecate(function,longjmp,[BARR-C:2018 Rule 8.5b])
-deprecate(macro,setjmp,[BARR-C:2018 Rule 8.5b])
// 8.6 Equivalence Test
/* 8522 - variable should appear on RHS of '==' operator */
-hook(binary_expr, -cond('%[opcode]' == '==' &&
'%[walk_lhs_expr.walk_past_paren_cast.set_msg_loc.is_decl_ref_expr]' == 'true' &&
'%[walk_rhs_expr.is_constant_expr]' == 'true',
+message(8522, "variable '%[walk_lhs_expr.walk_past_paren_cast.walk_decl.qual_name]' should appear on RHS of '==' operator")))
+e8522
-append(8522,[BARR-C:2018 Rule 8.6a])

427
ports/lint-plus2/qpc.lnt Normal file
View File

@ -0,0 +1,427 @@
//============================================================================
// 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-12-12
//! @version Last updated for version: 7.3.1
//!
//! @file
//! @brief PC-Lint-Plus option file for analysing both **QP/C**
//! and **QP/C Applications**
// C Language Standard
-std=c99 // apply the C99 Language Standard
//! M4-D4.8(A) complete definition is unnecessary in this translation unit
//! @tr{DVP-QP-MC4-D04_08}
-efile(9045,
-qp.h,
-qequeue.h,
-qmpool.h,
-qv.h,
-qk.h,
-qxk.h,
-qs.h)
// Functional Safety (FuSa) System --------------------------------------------
// "no return" semantics for error/failure callbacks
-sem(Q_onError, r_no)
-sem(assert_failed, r_no)
//! M4-D4.9(A) function-like macro
//! @tr{DVP-QP-MC4-D04_09A} (false-positive)
-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)
//! PCLP definition of macro ends in semicolon
//! @tr{DVP-QP-PCLP-823}
-esym(823,
Q_DEFINE_THIS_MODULE,
Q_DEFINE_THIS_FILE)
//! BARR-C(R1.8b) parameter of function could be const
-efunc(952,
Q_onError
)
// QEP -----------------------------------------------------------------------
//! M4-D4.9(A) function-like macro
//! @tr{DVP-QP-MC4-D04_09A} (false-positive)
-esym(9026,
Q_UNUSED_PAR,
Q_TRAN,
Q_TRAN_HIST,
Q_SUPER,
Q_HANDLED,
Q_UNHANDLED,
Q_IGNORED,
Q_ASM_UPCAST,
Q_HSM_UPCAST,
Q_MSM_UPCAST,
Q_EVT_CAST,
QEVT_INITIALIZER,
Q_UINT2PTR_CAST,
Q_STATE_CAST,
Q_ACTION_CAST,
QASM_INIT,
QASM_DISPATCH,
QASM_IS_IN)
//! M4-D4.9(A) function-like macro
//! @tr{DVP-QP-MC4-D04_09B} (correct identification)
-esym(9026,
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,
QMSM_INIT,
QMSM_DISPATCH)
//! M4-R11.1(R) conversion between pointer to function type
//! @tr{DVP-QP-MC4-R11_01}
-emacro(9074,
Q_STATE_CAST,
Q_ACTION_CAST,
Q_TRAN,
Q_TRAN_HIST,
Q_SUPER,
QM_ENTRY,
QM_EXIT,
QM_SM_EXIT,
QM_TRAN,
QM_TRAN_INIT,
QM_TRAN_HIST,
QM_TRAN_EP,
QM_TRAN_XP)
//! M4-R11.3(R) cast from pointer to pointer (upcast)
//! @tr{DVP-QP-MC4-R11_03A}
-emacro(9087,
Q_ASM_UPCAST,
Q_HSM_UPCAST,
Q_MSM_UPCAST,
QM_TRAN,
QM_TRAN_EP,
QM_TRAN_INIT)
//! M4-R11.3(R) cast from pointer to pointer (downcast)
//! @tr{DVP-QP-MC4-R11_03B}
-emacro(9087,
Q_EVT_CAST)
//! M4-R12.3(A) comma operator used
//! @tr{DVP-QP-MC4-R12_03}
-emacro(9008,
Q_SUPER,
Q_TRAN,
Q_TRAN_HIST,
QM_ENTRY,
QM_EXIT,
QM_SUPER_SUB,
QM_TRAN,
QM_TRAN_INIT,
QM_TRAN_EP,
QM_TRAN_XP,
QM_SM_EXIT,
QM_SUPER_SUB)
//! M4-R13.4(A) result of assignment used in left operand to ',' operator
//! @tr{DVP-QP-MC4-R13_04}
-emacro(9084,
Q_SUPER,
Q_TRAN,
QM_ENTRY,
QM_EXIT,
QM_TRAN,
QM_TRAN_INIT,
QM_TRAN_HIST,
QM_TRAN_EP,
QM_TRAN_XP,
QM_SM_EXIT,
QM_SUPER_SUB)
//! M4-R19.2(A) union declared
//! @tr{DVP-QP-MC4-R19_02}
-esym(9018,
QAsmAttr)
//! '<symbol>' not referenced in QM-style state machines
//! @tr{DVP-QP-PCLP-754}
-esym(754,
*(anonymous struct)::act,
*(anonymous struct)::target)
//! suspicious pointer-to-pointer conversion (area too small)
//! @tr{DVP-QP-PCLP-826}
-emacro(826,
Q_EVT_CAST)
// deprecated QEP facilities...
-deprecate( type, QFsm, QP/C API pre 5.4.x)
-deprecate( function, QFsm_ctor, QP/C API pre 5.4.x)
-deprecate( function, QF_onIdle, QP/C API pre 5.4.x)
-deprecate( macro, Q_IGNORED, QP/C API pre 5.4.x)
-deprecate( macro, QMSM_INIT, QP/C API pre 5.8.x)
-deprecate( macro, QMSM_DISPATCH, QP/C API pre 5.8.x)
// QF ------------------------------------------------------------------------
//! M4-D4.9(A) function-like macro
//! @tr{DVP-QP-MC4-D04_09B}
-esym(9026,
QF_INT_DISABLE,
QF_INT_ENABLE,
Q_PRIO,
QF_LOG2,
Q_NEW,
Q_NEW_X,
Q_NEW_REF,
Q_DELETE_REF,
QF_PUBLISH,
QF_CRIT_ENTRY,
QF_CRIT_EXIT,
QF_CRIT_EXIT_NOP,
QF_MEM_SYS,
QF_MEM_APP,
QF_MPOOL_EL,
QF_LOG2,
QF_EPOOL_INIT_,
QF_EPOOL_EVENT_SIZE_,
QF_EPOOL_GET_,
QF_EPOOL_PUT_,
QF_PTR_INC_,
QACTIVE_START,
QACTIVE_POST,
QACTIVE_POST_X,
QACTIVE_POST_LIFO,
QACTIVE_PUBLISH,
QACTIVE_EQUEUE_WAIT_,
QACTIVE_EQUEUE_SIGNAL_,
QACTIVE_EQUEUE_ONEMPTY_,
QTIMEEVT_TICK,
QTIMEEVT_TICK_X,
QTICKER_TRIG,
QF_TICK,
QF_TICK_X)
//! M4-R11.3(R) cast to pointer to different object type (upcast)
//! @tr{DVP-QP-MC4-R11_03A}
-emacro(9087,
QACTIVE_POST,
QACTIVE_POST_LIFO)
//! M4-R11.3(R) cast to pointer to different object type (downcast)
//! @tr{DVP-QP-MC4-R11_03B}
-emacro(9087,
Q_NEW,
Q_NEW_X)
//! suspicious pointer-to-pointer conversion (area too small)
//! @tr{DVP-QP-PCLP-826}
-emacro(826,
QACTIVE_POST,
QACTIVE_POST_X,
QACTIVE_POST_LIFO,
Q_NEW,
Q_NEW_X)
// deprecated QF facilities...
-deprecate( macro,QTimeEvt_ctor, QP/C API pre 5.8.x)
-deprecate( macro,QTimeEvt_postIn, QP/C API pre 5.8.x)
-deprecate( macro,QTimeEvt_postEvery, QP/C API pre 5.8.x)
// QV ------------------------------------------------------------------------
//! M4-D4.9(A) function-like macro
//! @tr{DVP-QP-MC4-D04_09A}
-esym(9026,
QV_CPU_SLEEP)
// QK ------------------------------------------------------------------------
// M4-D4.9(A) function-like macro
//! @tr{DVP-QP-MC4-D04_09A}
-esym(9026,
QK_ISR_ENTRY,
QK_ISR_EXIT,
QK_ISR_CONTEXT_)
// QXK -----------------------------------------------------------------------
//! M4-D4.9(A) function-like macro
//! @tr{DVP-QP-MC4-D04_09A}
-esym(9026,
QXK_ISR_ENTRY,
QXK_ISR_EXIT,
QXK_TLS,
QXTHREAD_START,
QXTHREAD_POST_X)
// deprecated QXK facilities...
-deprecate( macro, Q_XTHREAD_CAST, QP/C API pre 6.7.x)
// QS ------------------------------------------------------------------------
//! M4-D4.9(A) function-like macro
//! @tr{DVP-QS-MC4-D04_09A}
-esym(9026,
QS_INIT,
QS_EXIT,
QS_DUMP,
QS_RESET,
QS_GLB_FILTER,
QS_LOC_FILTER,
QS_FILTER_ON,
QS_FILTER_OFF,
QS_FILTER_SM_OBJ,
QS_FILTER_AO_OBJ,
QS_FILTER_MP_OBJ,
QS_FILTER_EQ_OBJ,
QS_FILTER_TE_OBJ,
QS_FILTER_AP_OBJ,
QS_GET_BYTE,
QS_GET_BLOCK,
QS_BEGIN,
QS_BEGIN_ID,
QS_END,
QS_BEGIN_INCRIT,
QS_END_INCRIT,
QS_TR_CRIT_ENTRY,
QS_TR_CRIT_EXIT,
QS_TR_ISR_ENTRY,
QS_TR_ISR_EXIT,
QS_ONLY,
QS_REC_DONE,
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_SIG,
QS_ENUM,
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)
//! M4-D4.9(A) function-like macro
//! @tr{DVP-QS-MC4-D04_09A}
-esym(9026,
QS_CRIT_ENTRY,
QS_CRIT_EXIT,
QS_MEM_SYS,
QS_MEM_APP,
QS_GLB_CHECK_,
QS_LOC_CHECK_,
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_)
//! M4-R11.1(R) conversion between pointer to function type
//! @tr{DVP-QS-MC4-R11_01}
-emacro(9074,
QS_FUN_DICTIONARY,
QS_TEST_PROBE_DEF)
// M4-R15.5(A) return statement before end of function
//! @tr{DVP-QS-MC4-R15_05}
-emacro(904,
QS_TEST_PROBE)
//! M4-R19.2(A) union declared
//! @tr{DVR-QS-MC4-R19_02}
-esym(9018,
Variant)
//! M4-R20.10(A) stringize operator
//! @tr{DVP-QS-MC4-R20_10}
-esym(9024,
QS_OBJ_DICTIONARY,
QS_OBJ_ARR_DICTIONARY,
QS_FUN_DICTIONARY,
QS_SIG_DICTIONARY,
QS_USR_DICTIONARY,
QS_ENUM_DICTIONARY)
//! implicit conversion of enum to integral type 'int'
//! @tr{DVP-QS-PCLP-641}
-emacro(641,
QS_SIG_DICTIONARY)
//! definition of macro ends in semicolon
//! @tr{DVP-QS-PCLP-823}
-esym(823,
QS_TEST_PROBE_DEF)

View File

@ -0,0 +1,86 @@
//============================================================================
// 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: 2024-05-01
//! @version Last updated for: @ref qpc_7_3_4
//!
//! @file
//! @brief QP/C "port" to PC-Lint-Plus, QV kernel, generic C99
#ifndef QP_PORT_H_
#define QP_PORT_H_
#include <stdint.h> // Exact-width types. WG14/N843 C99 Standard
#include <stdbool.h> // Boolean type. WG14/N843 C99 Standard
#ifdef QP_CONFIG
#include "qp_config.h" // external QP configuration
#endif
// no-return function specifier (C11 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 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)
void intDisable(void);
void intEnable(void);
uint32_t critEntry(void);
void critExit(uint32_t stat);
// include files -------------------------------------------------------------
#include "qequeue.h" // QV kernel uses the native QP event queue
#include "qmpool.h" // QV kernel uses the native QP memory pool
#include "qp.h" // QP framework
#include "qv.h" // QV kernel
#endif // QP_PORT_H_

View 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: 2024-05-01
//! @version Last updated for: @ref qpc_7_3_4
//!
//! @file
//! @brief QP/C "port" to PC-Lint-Plus, QXK kernel, generic C99
#ifndef QP_PORT_H_
#define QP_PORT_H_
#include <stdint.h> // Exact-width types. WG14/N843 C99 Standard
#include <stdbool.h> // Boolean type. WG14/N843 C99 Standard
#ifdef QP_CONFIG
#include "qp_config.h" // external QP configuration
#endif
// no-return function specifier (C11 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 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() ((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())
void intDisable(void);
void intEnable(void);
uint32_t critEntry(void);
void critExit(uint32_t stat);
uint32_t QXK_get_IPSR(void);
void QXK_trigPendSV(void);
// include files -------------------------------------------------------------
#include "qequeue.h" // QXK kernel uses the native QP event queue
#include "qmpool.h" // QXK kernel uses the native QP memory pool
#include "qp.h" // QP framework
#include "qxk.h" // QXK kernel
#endif // QP_PORT_H_

44
ports/lint-plus2/std.lnt Normal file
View File

@ -0,0 +1,44 @@
//============================================================================
// 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-06-06
//! @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
-width(120,4) // break lines after 99 characters with 4 characters indent
+flm // make sure no foreign includes change the format
-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() // output a summary of all produced messages
// globally suppress the following warnings:
-e546 // explicitly taking address of function
-e717 // monocarpic do-while used to group statements

View File

@ -0,0 +1,30 @@
//! @file
//! @brief Boolean type and constansts. WG14/N843 C99 Standard, Section 7.16
//!
//! @description
//! This header is part of the ANSI C99 standard library to define the
//! standard Boolean type as well as the 'true' and 'false' constansts.
#ifndef STDBOOL_H_
#define STDBOOL_H_
//lint -save
//lint -e9071 M3-R21.1(r), defined macro is reserved to the compiler
//lint -e9093 the name is reserved to the compiler
//lint -emacro(8523, false, true) cast to boolean
#ifndef __cplusplus
typedef _Bool bool; //!< standard Boolean data type
//! standard 'false' constant
#define false ((bool)0)
//! standard 'true' constant
#define true ((bool)1)
#endif // !__cplusplus
//lint -restore
#endif // STDBOOL_H_

View File

@ -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
QPC := ../..
# QP port used in this project
QP_PORT_DIR := .
# list of all source directories used by this project
VPATH = \
$(QPC)/src/qf \
$(QPC)/src/qs \
$(QP_PORT_DIR)
# list of all include directories needed by this project
INCLUDES = \
-I$(QPC)/include \
-I$(QPC)/src \
-I$(QP_PORT_DIR)
#-----------------------------------------------------------------------------
# files
#
# C source files
C_SRCS := \
qep_hsm.c \
qep_msm.c \
qf_act.c \
qf_actq.c \
qf_defer.c \
qf_dyn.c \
qf_mem.c \
qf_ps.c \
qf_qact.c \
qf_qeq.c \
qf_qmact.c \
qf_time.c \
qwin_gui.c \
qf_port.c
C_QS_SRCS := \
qs.c \
qs_rx.c \
qs_fp.c \
qs_64bit.c \
qs_port.c
# C++ source files
CPP_SRCS :=
# 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=c11 -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=c11 -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=c11 -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)

41
qpc.md5
View File

@ -1,51 +1,51 @@
93ecf23cf720e5728920c20ee8d973e6 *qpc.qm
4d275cf16910927c20f700d54e13435e *qpc.qm
f71fdc0261b7d7e1693f7cf92b269fc0 *include/qequeue.h
57b1efebccde23a26f9d11e822ec379f *include/qk.h
807f80a7a39be52083010803f76b4f05 *include/qmpool.h
48125adc82b65fdfa09dfbddd2621ec3 *include/qp.h
e8f2c2b5f22fedb0e344ea8aa3f71055 *include/qp.h
e7b6c999b10d91f5c1adf1fde500e452 *include/qp_pkg.h
78847559ac0addc557e6984c6cb93474 *include/qpc.h
2ae619716b9a6c948ba2b3431d00c03b *include/qpc.h
2f2ed281e63d5803738ab0c92a77171f *include/qs.h
66f8bd1303a72346f52fbcccfd363586 *include/qs_dummy.h
fad2d5ccd173e6374f4bce243709eef7 *include/qs_pkg.h
c33f022827668e991f2b9f212493036e *include/qsafe.h
f59bf88705afe5b0acc999f8b47a6745 *include/qsafe.h
990a963045e6485091658b0eea0a9dbd *include/qstamp.h
431c6e320c14f0b02dbc78e2d49f6431 *include/qv.h
7845e9391f7a94311fd849da56abd8a1 *include/qxk.h
a25152f319178420b5b5140ca51ea4ae *src/qf/CMakeLists.txt
1c4dad5956b62c793eb9b92e2043bdf7 *src/qf/qep_hsm.c
25374a80a064e6f7199e19285543f2fd *src/qf/qep_msm.c
b4ade402584ddb981fe5967e1a4418c7 *src/qf/qep_hsm.c
72756ebffc4809e6b934b8189170852f *src/qf/qep_msm.c
762cba96738f7e3fe4ebd66659542b30 *src/qf/qf_act.c
78ad6e00669d2888ceef6e6d84e83e55 *src/qf/qf_actq.c
091c7f1f25217df387119df63ee51dd1 *src/qf/qf_actq.c
858f4abf264ab69734b4df56b0bfa739 *src/qf/qf_defer.c
3f25992d60f701951f0d20c1c2e3ad5a *src/qf/qf_dyn.c
bc3e5d7fcb172fee6881f993160502eb *src/qf/qf_mem.c
4642cd0eaf88ca3012439bb95a43d8b8 *src/qf/qf_ps.c
29309e868460c232ef237a666b6d02b4 *src/qf/qf_dyn.c
83aff99fd71e3383f700d3dd5b712c4e *src/qf/qf_mem.c
e090893c0f33678c6bf267c637c6cb48 *src/qf/qf_ps.c
5a1d0999864f48a688d34e9273868e8b *src/qf/qf_qact.c
a34020507dc261f49eaaaf2062dcb81d *src/qf/qf_qeq.c
f9867335faa23f0b57c921c8882e7a52 *src/qf/qf_qmact.c
b0531b1989555c6b7d128e112f4f3c39 *src/qf/qf_time.c
d457172637ab14cf42f99071bc7b8e7a *src/qf/qf_time.c
ccd28413fc3a093ca99b03854cf7439b *src/qk/CMakeLists.txt
aa27bde6715639754f8857a46c344442 *src/qk/qk.c
af0330a6f55fe4cffc70f27fa95baebc *src/qk/qk.c
27c155798720d7fb3b2f9cc38e311393 *src/qs/CMakeLists.txt
e045ce8b2fc053d068ec3eb10c9f65bf *src/qs/qs.c
274720fa9a3b5015951b39a6159f6773 *src/qs/qs.c
9091ffd15f7ec791076091bb17eec5fc *src/qs/qs_64bit.c
730d9bea159722e5d2c225e01b5c7875 *src/qs/qs_fp.c
60453f6d2b1f915e6e477cca68cb7fee *src/qs/qs_rx.c
80a31dfc0e24839342fe193779401e7b *src/qs/qstamp.c
53ab2ae396c90e41045b019cdfea21b5 *src/qs/qutest.c
cf8fa24441cb9577288f73bdb4effbff *src/qv/CMakeLists.txt
bb08eae11dacb60099c7ff7a7b3700b3 *src/qv/qv.c
a428b106b6a95c80077a156ebe764622 *src/qv/qv.c
3a9240f29676dea5ce3df8fed587ae52 *src/qxk/CMakeLists.txt
8d2e28ffb1c8c670924de4c987fb35df *src/qxk/qxk.c
f65131e2a680cc2f419f43437e1f873a *src/qxk/qxk_mutex.c
a2ea8a8890449cf7686988c5e6631148 *src/qxk/qxk.c
c098be23217a3aa757bc2e2d96ace49a *src/qxk/qxk_mutex.c
214032bca5ddd45690cf3ca67f9f86c3 *src/qxk/qxk_sema.c
c72e1cc89263ebda9462ca6fb8b04326 *src/qxk/qxk_xthr.c
74f494c8854313253a4353f649e707ae *ports/lint-plus/au-barr.lnt
2a8fea61bccbe5e8c7536a29f2ec8e98 *ports/lint-plus/au-ds.lnt
115b283af0eeeae9fdbd91836710e228 *ports/lint-plus/au-misra4.lnt
63418574679007d8ec13815cbff46f84 *ports/lint-plus/au-ql-c99.lnt
33eef33bdbf5a1bc7922d469ec57b2d8 *ports/lint-plus/options.lnt
be52f283a42b5b277097b5984181f204 *ports/lint-plus/options.lnt
02803e47d485980bdabc4a5d271288bd *ports/lint-plus/ql-style.lnt
7780e1ccc98afe4077689e31c639a862 *ports/lint-plus/qpc.lnt
ecca2c20a6e0dc29a1f62aeb500ed165 *ports/lint-plus/std.lnt
@ -71,14 +71,14 @@ f6c251ec335af215b842ff2ef686e93f *ports/arm-cm/qv/iar/qs_port.h
867217f77f0c6cdb0a82a964a7027510 *ports/arm-cm/qv/iar/qv_port.c
40058ac0609321670e6e7816670e97af *ports/arm-cm/qxk/armclang/qp_port.h
f6c251ec335af215b842ff2ef686e93f *ports/arm-cm/qxk/armclang/qs_port.h
666a153de8cd8b7747531199d1bcbde1 *ports/arm-cm/qxk/armclang/qxk_port.c
157999f7597ee32773fcfc13e7ef61fd *ports/arm-cm/qxk/armclang/qxk_port.c
31c4cd8ad90ea6517df1d4054033fe03 *ports/arm-cm/qxk/config/qp_config.h
35ec850c15f42e2eab924d06bf2d4165 *ports/arm-cm/qxk/gnu/qp_port.h
a0699895649b5d644e4068794b0e94dc *ports/arm-cm/qxk/gnu/qs_port.h
d31561dc804f1394bc19ef218bd491f9 *ports/arm-cm/qxk/gnu/qxk_port.c
9bc69ca01a321ce71216552af9493b60 *ports/arm-cm/qxk/gnu/qxk_port.c
9145c3ae665b20e224bd91406668754c *ports/arm-cm/qxk/iar/qp_port.h
f6c251ec335af215b842ff2ef686e93f *ports/arm-cm/qxk/iar/qs_port.h
9ac3d417ea66352f7ab8dd724e448ff5 *ports/arm-cm/qxk/iar/qxk_port.c
6a047634910a10c3c2bc82f28551b5aa *ports/arm-cm/qxk/iar/qxk_port.c
b08b183d0275dbf6b55c46b94523a1a2 *ports/arm-cm/qutest/qp_port.h
c755db99d10db142bcb98018f55e2b7a *ports/arm-cm/qutest/qs_port.h
829261756c701d26e742005c59cd25f7 *ports/arm-cr/qk/config/qp_config.h
@ -148,7 +148,6 @@ f26311a1912e214477781255c7c71834 *ports/posix-qv/safe_std.h
a7e763528627d662501e8a28ca6321c1 *ports/posix-qutest/qutest_port.c
f26311a1912e214477781255c7c71834 *ports/posix-qutest/safe_std.h
5fa44dffb653cecb1d9ea41d154ce852 *ports/win32/CMakeLists.txt
cd0040a8cc2c6051b2f8ea42f798d601 *ports/win32/Makefile
20fc7e8b39e32f53aca8e3f08e372957 *ports/win32/qf_port.c
dddd41fe592d8832b95179820de552d2 *ports/win32/qp_port.h
a46c047f83877a192b2de24f27238770 *ports/win32/qs_port.c

301
qpc.qm
View File

@ -186,6 +186,14 @@ Contact information:
<parameter name="expr_" type="bool"/>
<code>Q_ASSERT(expr_)</code>
</operation>
<!--${QP-FuSa::Q_INVARIANT_INCRIT}-->
<operation name="Q_INVARIANT_INCRIT" type="void" visibility="0x03" properties="0x00">
<!--${QP-FuSa::Q_INVARIANT_INCR~::id_}-->
<parameter name="id_" type="int"/>
<!--${QP-FuSa::Q_INVARIANT_INCR~::expr_}-->
<parameter name="expr_" type="bool"/>
<code>Q_ASSERT_INCRIT((id_), (expr_))</code>
</operation>
<!--${QP-FuSa::Q_ASSERT_STATIC}-->
<operation name="Q_ASSERT_STATIC" type="void" visibility="0x03" properties="0x00">
<!--${QP-FuSa::Q_ASSERT_STATIC::expr_}-->
@ -225,8 +233,8 @@ Contact information:
</package>
<!--${QEP}-->
<package name="QEP" stereotype="0x05">
<!--${QEP::QP_versionStr[8]}-->
<attribute name="QP_versionStr[8]" type="char const" visibility="0x00" properties="0x00">
<!--${QEP::QP_versionStr[16]}-->
<attribute name="QP_versionStr[16]" type="char const" visibility="0x00" properties="0x00">
<documentation>//! the current QP version number string in ROM, based on #QP_VERSION_STR</documentation>
<code>= QP_VERSION_STR;</code>
</attribute>
@ -513,27 +521,27 @@ QS_MEM_APP();
QF_CRIT_EXIT();
// drill down into the state hierarchy with initial transitions...
int_fast8_t limit = QHSM_MAX_NEST_DEPTH_; // loop hard limit
do {
QStateHandler path[QHSM_MAX_NEST_DEPTH_]; // tran entry path array
int_fast8_t ip = 0; // tran entry path index
path[0] = me-&gt;temp.fun;
(void)QHSM_RESERVED_EVT_(me-&gt;temp.fun, Q_EMPTY_SIG);
// note: ip is the fixed upper loop bound
while ((me-&gt;temp.fun != t) &amp;&amp; (ip &lt; (QHSM_MAX_NEST_DEPTH_ - 1))) {
++ip;
path[ip] = me-&gt;temp.fun;
(void)QHSM_RESERVED_EVT_(me-&gt;temp.fun, Q_EMPTY_SIG);
}
QF_CRIT_ENTRY();
// The initial transition source state must be reached
// Too many state nesting levels or &quot;malformed&quot; HSM.
Q_ASSERT_INCRIT(220, me-&gt;temp.fun == t);
// too many state nesting levels or &quot;malformed&quot; HSM
Q_ENSURE_INCRIT(220, ip &lt; QHSM_MAX_NEST_DEPTH_);
QF_CRIT_EXIT();
me-&gt;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)
@ -561,14 +569,9 @@ do {
QS_CRIT_EXIT();
}
#endif // Q_SPY
--limit;
} while ((r == Q_RET_TRAN) &amp;&amp; (limit &gt; 0));
} while (r == Q_RET_TRAN);
QF_CRIT_ENTRY();
// Loop limit must not be reached.
// Too many state nesting levels or likely &quot;malformed&quot; HSM
Q_ENSURE_INCRIT(290, limit &gt; 0);
QS_MEM_SYS();
QS_BEGIN_PRE_(QS_QEP_INIT_TRAN, qsId)
@ -605,9 +608,9 @@ QStateHandler t = s;
QF_CRIT_STAT
QF_CRIT_ENTRY();
Q_REQUIRE_INCRIT(300, (s != Q_STATE_CAST(0))
Q_REQUIRE_INCRIT(300, QEvt_verify_(e));
Q_INVARIANT_INCRIT(302, (s != Q_STATE_CAST(0))
&amp;&amp; (me-&gt;state.uint == (uintptr_t)(~me-&gt;temp.uint)));
Q_REQUIRE_INCRIT(302, QEvt_verify_(e));
QS_MEM_SYS();
QS_BEGIN_PRE_(QS_QEP_DISPATCH, qsId)
@ -623,7 +626,7 @@ QF_CRIT_EXIT();
// process the event hierarchically...
QState r;
me-&gt;temp.fun = s;
int_fast8_t limit = QHSM_MAX_NEST_DEPTH_; // loop hard limit
int_fast8_t ip = QHSM_MAX_NEST_DEPTH_; // fixed upper loop bound
do {
s = me-&gt;temp.fun;
r = (*s)(me, e); // invoke state handler s
@ -643,11 +646,11 @@ do {
r = QHSM_RESERVED_EVT_(s, Q_EMPTY_SIG); // superstate of s
}
--limit;
} while ((r == Q_RET_SUPER) &amp;&amp; (limit &gt; 0));
--ip;
} while ((r == Q_RET_SUPER) &amp;&amp; (ip &gt; 0));
QF_CRIT_ENTRY();
Q_ASSERT_INCRIT(310, limit &gt; 0);
Q_ENSURE_INCRIT(310, ip &gt; 0);
QF_CRIT_EXIT();
if (r &gt;= Q_RET_TRAN) { // regular tran. taken?
@ -658,21 +661,21 @@ if (r &gt;= Q_RET_TRAN) { // regular tran. taken?
path[2] = s; // tran. source
// exit current state to tran. source s...
limit = QHSM_MAX_NEST_DEPTH_; // loop hard limit
for (; (t != s) &amp;&amp; (limit &gt; 0); t = me-&gt;temp.fun) {
ip = QHSM_MAX_NEST_DEPTH_; // fixed upper loop bound
for (; (t != s) &amp;&amp; (ip &gt; 0); t = me-&gt;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
(void)QHSM_RESERVED_EVT_(t, Q_EMPTY_SIG);
}
--limit;
--ip;
}
QF_CRIT_ENTRY();
Q_ASSERT_INCRIT(320, limit &gt; 0);
Q_ENSURE_INCRIT(320, ip &gt; 0);
QF_CRIT_EXIT();
int_fast8_t ip = QHsm_tran_(me, path, qsId); // take the tran.
ip = QHsm_tran_(me, path, qsId); // take the tran.
#ifdef Q_SPY
if (r == Q_RET_TRAN_HIST) {
@ -689,6 +692,7 @@ if (r &gt;= 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 &gt;= 0; --ip) {
// enter path[ip]
if (QHSM_RESERVED_EVT_(path[ip], Q_ENTRY_SIG)
@ -719,6 +723,7 @@ if (r &gt;= Q_RET_TRAN) { // regular tran. taken?
// find superstate
(void)QHSM_RESERVED_EVT_(me-&gt;temp.fun, Q_EMPTY_SIG);
// note: ip is the fixed upper loop bound
while ((me-&gt;temp.fun != t) &amp;&amp; (ip &lt; (QHSM_MAX_NEST_DEPTH_ - 1))) {
++ip;
path[ip] = me-&gt;temp.fun;
@ -726,14 +731,14 @@ if (r &gt;= Q_RET_TRAN) { // regular tran. taken?
(void)QHSM_RESERVED_EVT_(me-&gt;temp.fun, Q_EMPTY_SIG);
}
QF_CRIT_ENTRY();
// The initial transition source state must be reached.
// Too many state nesting levels or &quot;malformed&quot; HSM.
Q_ASSERT_INCRIT(330, me-&gt;temp.fun == t);
// too many state nesting levels or &quot;malformed&quot; HSM
Q_ENSURE_INCRIT(330, ip &lt; QHSM_MAX_NEST_DEPTH_);
QF_CRIT_EXIT();
me-&gt;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)
@ -812,17 +817,17 @@ me-&gt;temp.uint = ~me-&gt;state.uint;
<parameter name="state" type="QStateHandler const"/>
<code>QF_CRIT_STAT
QF_CRIT_ENTRY();
Q_REQUIRE_INCRIT(602, me-&gt;state.uint
== (uintptr_t)(~me-&gt;temp.uint));
Q_INVARIANT_INCRIT(602, me-&gt;state.uint
== (uintptr_t)(~me-&gt;temp.uint));
QF_CRIT_EXIT();
bool inState = false; // assume that this HSM is not in 'state'
// scan the state hierarchy bottom-up
QStateHandler s = me-&gt;state.fun;
int_fast8_t limit = QHSM_MAX_NEST_DEPTH_ + 1; // loop hard limit
int_fast8_t lbound = QHSM_MAX_NEST_DEPTH_ + 1; // fixed upper loop bound
QState r = Q_RET_SUPER;
for (; (r != Q_RET_IGNORED) &amp;&amp; (limit &gt; 0); --limit) {
for (; (r != Q_RET_IGNORED) &amp;&amp; (lbound &gt; 0); --lbound) {
if (s == state) { // do the states match?
inState = true; // 'true' means that match found
break; // break out of the for-loop
@ -834,7 +839,7 @@ for (; (r != Q_RET_IGNORED) &amp;&amp; (limit &gt; 0); --limit) {
}
QF_CRIT_ENTRY();
Q_ENSURE_INCRIT(690, limit &gt; 0);
Q_ENSURE_INCRIT(690, lbound &gt; 0);
QF_CRIT_EXIT();
#ifndef Q_UNSAFE
@ -864,6 +869,7 @@ bool isFound = false; // start with the child not found
// establish stable state configuration
me-&gt;super.temp.fun = child;
QState r;
int_fast8_t lbound = QHSM_MAX_NEST_DEPTH_; // fixed upper loop bound
do {
// is this the parent of the current child?
if (me-&gt;super.temp.fun == parent) {
@ -874,7 +880,9 @@ do {
child = me-&gt;super.temp.fun;
r = QHSM_RESERVED_EVT_(me-&gt;super.temp.fun, Q_EMPTY_SIG);
}
} while (r != Q_RET_IGNORED); // the top state not reached
--lbound;
} while ((r != Q_RET_IGNORED) // the top state not reached
&amp;&amp; (lbound &gt; 0));
#ifndef Q_UNSAFE
me-&gt;super.temp.uint = ~me-&gt;super.state.uint;
@ -882,10 +890,12 @@ me-&gt;super.temp.uint = ~me-&gt;super.state.uint;
QF_CRIT_STAT
QF_CRIT_ENTRY();
Q_ASSERT_INCRIT(890, isFound);
// NOTE: the following postcondition can only succeed when
// (lbound &gt; 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::tran_}-->
<operation name="tran_" type="int_fast8_t" visibility="0x02" properties="0x01">
@ -954,6 +964,7 @@ else {
t = me-&gt;temp.fun; // save source-&gt;super
// find target-&gt;super-&gt;super...
// note: ip is the fixed upper loop bound
QState r = QHSM_RESERVED_EVT_(path[1], Q_EMPTY_SIG);
while ((r == Q_RET_SUPER)
&amp;&amp; (ip &lt; (QHSM_MAX_NEST_DEPTH_ - 1)))
@ -970,9 +981,10 @@ else {
}
}
QF_CRIT_ENTRY();
// Tran. source must be found within the nesting depth
// Too many state nesting levels or &quot;malformed&quot; HSM.
Q_ASSERT_INCRIT(510, r != Q_RET_SUPER);
// NOTE: The following postcondition succeeds only when
// ip &lt; QHSM_MAX_NEST_DEPTH, so no additional check is necessary
// too many state nesting levels or &quot;malformed&quot; HSM.
Q_ENSURE_INCRIT(510, r != Q_RET_SUPER);
QF_CRIT_EXIT();
// the LCA not found yet?
@ -988,6 +1000,7 @@ else {
// == target-&gt;super-&gt;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
@ -1004,7 +1017,7 @@ else {
// (g) check each source-&gt;super-&gt;...
// for each target-&gt;super...
r = Q_RET_IGNORED; // keep looping
int_fast8_t limit = QHSM_MAX_NEST_DEPTH_;
int_fast8_t lbound = QHSM_MAX_NEST_DEPTH_;
do {
// exit from t
if (QHSM_RESERVED_EVT_(t, Q_EXIT_SIG)
@ -1028,10 +1041,10 @@ else {
}
} while (iq &gt;= 0);
--limit;
} while ((r != Q_RET_HANDLED) &amp;&amp; (limit &gt; 0));
--lbound;
} while ((r != Q_RET_HANDLED) &amp;&amp; (lbound &gt; 0));
QF_CRIT_ENTRY();
Q_ASSERT_INCRIT(530, limit &gt; 0);
Q_ENSURE_INCRIT(530, lbound &gt; 0);
QF_CRIT_EXIT();
}
}
@ -1128,15 +1141,15 @@ QF_CRIT_EXIT();
me-&gt;state.obj = me-&gt;temp.tatbl-&gt;target;
// drill down into the state hierarchy with initial transitions...
int_fast8_t limit = QMSM_MAX_NEST_DEPTH_; // loop hard limit
int_fast8_t lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound
do {
// execute the tran. table
r = QMsm_execTatbl_(me, me-&gt;temp.tatbl, qsId);
--limit;
} while ((r &gt;= Q_RET_TRAN_INIT) &amp;&amp; (limit &gt; 0));
--lbound;
} while ((r &gt;= Q_RET_TRAN_INIT) &amp;&amp; (lbound &gt; 0));
QF_CRIT_ENTRY();
Q_ENSURE_INCRIT(290, limit &gt; 0);
Q_ENSURE_INCRIT(290, lbound &gt; 0);
QS_MEM_SYS();
QS_BEGIN_PRE_(QS_QEP_INIT_TRAN, qsId)
@ -1172,9 +1185,9 @@ QMState const *t = s;
QF_CRIT_STAT
QF_CRIT_ENTRY();
Q_REQUIRE_INCRIT(300, (s != (QMState *)0)
Q_REQUIRE_INCRIT(300, QEvt_verify_(e));
Q_INVARIANT_INCRIT(302, (s != (QMState *)0)
&amp;&amp; (me-&gt;state.uint == (uintptr_t)(~me-&gt;temp.uint)));
Q_REQUIRE_INCRIT(302, QEvt_verify_(e));
QS_MEM_SYS();
QS_BEGIN_PRE_(QS_QEP_DISPATCH, qsId)
@ -1189,7 +1202,7 @@ QF_CRIT_EXIT();
// scan the state hierarchy up to the top state...
QState r;
int_fast8_t limit = QMSM_MAX_NEST_DEPTH_; // loop hard limit
int_fast8_t lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound
do {
r = (*t-&gt;stateHandler)(me, e); // call state handler function
@ -1222,10 +1235,10 @@ do {
t = t-&gt;superstate; // advance to the superstate
}
--limit;
} while ((t != (QMState *)0) &amp;&amp; (limit &gt; 0));
--lbound;
} while ((t != (QMState *)0) &amp;&amp; (lbound &gt; 0));
QF_CRIT_ENTRY();
Q_ASSERT_INCRIT(310, limit &gt; 0);
Q_ENSURE_INCRIT(310, lbound &gt; 0);
QF_CRIT_EXIT();
if (r &gt;= Q_RET_TRAN) { // any kind of tran. taken?
@ -1238,7 +1251,7 @@ if (r &gt;= Q_RET_TRAN) { // any kind of tran. taken?
QF_CRIT_EXIT();
#endif // Q_SPY
limit = QMSM_MAX_NEST_DEPTH_; // loop hard limit
lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound
do {
// save the tran-action table before it gets clobbered
struct QMTranActTable const * const tatbl = me-&gt;temp.tatbl;
@ -1303,11 +1316,11 @@ if (r &gt;= Q_RET_TRAN) { // any kind of tran. taken?
}
t = s; // set target to the current state
--limit;
} while ((r &gt;= Q_RET_TRAN) &amp;&amp; (limit &gt; 0));
--lbound;
} while ((r &gt;= Q_RET_TRAN) &amp;&amp; (lbound &gt; 0));
QF_CRIT_ENTRY();
Q_ASSERT_INCRIT(320, limit &gt; 0);
Q_ENSURE_INCRIT(320, lbound &gt; 0);
QS_MEM_SYS();
QS_BEGIN_PRE_(QS_QEP_TRAN, qsId)
@ -1383,8 +1396,8 @@ me-&gt;temp.uint = ~me-&gt;state.uint;
<code>bool inState = false; // assume that this SM is not in 'state'
QMState const *s = me-&gt;state.obj;
int_fast8_t limit = QMSM_MAX_NEST_DEPTH_; // loop hard limit
for (; (s != (QMState *)0) &amp;&amp; (limit &gt; 0); --limit) {
int_fast8_t lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound
for (; (s != (QMState *)0) &amp;&amp; (lbound &gt; 0); --lbound) {
if (s-&gt;stateHandler == state) { // match found?
inState = true;
break;
@ -1396,7 +1409,7 @@ for (; (s != (QMState *)0) &amp;&amp; (limit &gt; 0); --limit) {
QF_CRIT_STAT
QF_CRIT_ENTRY();
Q_ENSURE_INCRIT(490, limit &gt; 0);
Q_ENSURE_INCRIT(490, lbound &gt; 0);
QF_CRIT_EXIT();
return inState;</code>
@ -1410,8 +1423,8 @@ return inState;</code>
<code>bool inState = false; // assume that this SM is not in 'state'
QMState const *s = me-&gt;super.state.obj;
int_fast8_t limit = QMSM_MAX_NEST_DEPTH_; // loop hard limit
for (; (s != (QMState *)0) &amp;&amp; (limit &gt; 0); --limit) {
int_fast8_t lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound
for (; (s != (QMState *)0) &amp;&amp; (lbound &gt; 0); --lbound) {
if (s == stateObj) { // match found?
inState = true;
break;
@ -1423,7 +1436,7 @@ for (; (s != (QMState *)0) &amp;&amp; (limit &gt; 0); --limit) {
QF_CRIT_STAT
QF_CRIT_ENTRY();
Q_ENSURE_INCRIT(590, limit &gt; 0);
Q_ENSURE_INCRIT(590, lbound &gt; 0);
QF_CRIT_EXIT();
return inState;</code>
@ -1447,9 +1460,9 @@ return inState;</code>
bool isFound = false; // start with the child not found
QMState const *s;
int_fast8_t limit = QMSM_MAX_NEST_DEPTH_; // loop hard limit
int_fast8_t lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound
for (s = me-&gt;super.state.obj;
(s != (QMState *)0) &amp;&amp; (limit &gt; 0);
(s != (QMState *)0) &amp;&amp; (lbound &gt; 0);
s = s-&gt;superstate)
{
if (s == parent) {
@ -1459,17 +1472,17 @@ for (s = me-&gt;super.state.obj;
else {
child = s;
}
--limit;
--lbound;
}
QF_CRIT_STAT
QF_CRIT_ENTRY();
Q_ASSERT_INCRIT(610, limit &gt; 0);
Q_ENSURE_INCRIT(610, lbound &gt; 0);
QF_CRIT_EXIT();
if (!isFound) { // still not found?
limit = QMSM_MAX_NEST_DEPTH_; // loop hard limit
lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound
for (s = me-&gt;super.temp.obj;
(s != (QMState *)0) &amp;&amp; (limit &gt; 0);
(s != (QMState *)0) &amp;&amp; (lbound &gt; 0);
s = s-&gt;superstate)
{
if (s == parent) {
@ -1479,12 +1492,14 @@ if (!isFound) { // still not found?
else {
child = s;
}
--limit;
--lbound;
}
}
QF_CRIT_ENTRY();
Q_ENSURE_INCRIT(690, isFound &amp;&amp; (limit &gt; 0));
// NOTE: the following postcondition can only succeed when
// (lbound &gt; 0), so no extra check is necessary.
Q_ENSURE_INCRIT(690, isFound);
QF_CRIT_EXIT();
return child; // return the child</code>
@ -1512,10 +1527,11 @@ Q_REQUIRE_INCRIT(700, tatbl != (struct QMTranActTable *)0);
QF_CRIT_EXIT();
QState r = Q_RET_NULL;
int_fast8_t limit = QMSM_MAX_TRAN_LENGTH_; // loop hard limit
int_fast8_t lbound = QMSM_MAX_TRAN_LENGTH_; // fixed upper loop bound
QActionHandler const *a = &amp;tatbl-&gt;act[0];
for (; (*a != Q_ACTION_CAST(0)) &amp;&amp; (limit &gt; 0); ++a) {
for (; (*a != Q_ACTION_CAST(0)) &amp;&amp; (lbound &gt; 0); ++a) {
r = (*(*a))(me); // call the action through the 'a' pointer
--lbound;
#ifdef Q_SPY
QS_CRIT_ENTRY();
QS_MEM_SYS();
@ -1558,9 +1574,10 @@ for (; (*a != Q_ACTION_CAST(0)) &amp;&amp; (limit &gt; 0); ++a) {
QS_MEM_APP();
QS_CRIT_EXIT();
#endif // Q_SPY
--limit;
}
QF_CRIT_ENTRY();
// NOTE: the following postcondition can only succeed when
// (lbound &gt; 0), so no extra check is necessary.
Q_ENSURE_INCRIT(790, *a == Q_ACTION_CAST(0));
QF_CRIT_EXIT();
@ -1590,8 +1607,8 @@ QF_CRIT_STAT
// exit states from the current state to the tran. source state
QMState const *s = cs;
int_fast8_t limit = QMSM_MAX_NEST_DEPTH_; // loop hard limit
for (; (s != ts) &amp;&amp; (limit &gt; 0); --limit) {
int_fast8_t lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound
for (; (s != ts) &amp;&amp; (lbound &gt; 0); --lbound) {
// exit action provided in state 's'?
if (s-&gt;exitAction != Q_ACTION_CAST(0)) {
// execute the exit action
@ -1617,7 +1634,7 @@ for (; (s != ts) &amp;&amp; (limit &gt; 0); --limit) {
}
}
QF_CRIT_ENTRY();
Q_ENSURE_INCRIT(890, limit &gt; 0);
Q_ENSURE_INCRIT(890, lbound &gt; 0);
QF_CRIT_EXIT();</code>
</operation>
<!--${QEP::QMsm::enterHistory_}-->
@ -2381,7 +2398,7 @@ QF_MEM_SYS();
#ifndef Q_UNSAFE
uint8_t const pcopy = (uint8_t)(~me-&gt;prio_dis);
Q_REQUIRE_INCRIT(102, (QEvt_verify_(e)) &amp;&amp; (me-&gt;prio == pcopy));
Q_INVARIANT_INCRIT(102, (QEvt_verify_(e)) &amp;&amp; (me-&gt;prio == pcopy));
#endif
QEQueueCtr nFree = me-&gt;eQueue.nFree; // get volatile into temporary
@ -2522,7 +2539,7 @@ QF_MEM_SYS();
#ifndef Q_UNSAFE
uint8_t const pcopy = (uint8_t)(~me-&gt;prio_dis);
Q_REQUIRE_INCRIT(202, (QEvt_verify_(e)) &amp;&amp; (me-&gt;prio == pcopy));
Q_INVARIANT_INCRIT(202, (QEvt_verify_(e)) &amp;&amp; (me-&gt;prio == pcopy));
#endif
#ifdef QXK_H_
@ -2679,7 +2696,7 @@ QF_CRIT_ENTRY();
QF_MEM_SYS();
Q_REQUIRE_INCRIT(200, sig &lt; (QSignal)QActive_maxPubSignal_);
Q_REQUIRE_INCRIT(202,
Q_INVARIANT_INCRIT(202,
QPSet_verify_(&amp;QActive_subscrList_[sig].set,
&amp;QActive_subscrList_[sig].set_dis));
@ -2723,9 +2740,9 @@ if (QPSet_notEmpty(&amp;subscrSet)) { // any subscribers?
QF_SCHED_STAT_
QF_SCHED_LOCK_(p); // lock the scheduler up to AO's prio
uint_fast8_t limit = QF_MAX_ACTIVE + 1U;
uint_fast8_t lbound = QF_MAX_ACTIVE + 1U; // fixed upper loop bound
do { // loop over all subscribers
--limit;
--lbound;
// QACTIVE_POST() asserts internally if the queue overflows
QACTIVE_POST(a, e, sender);
@ -2747,10 +2764,12 @@ if (QPSet_notEmpty(&amp;subscrSet)) { // any subscribers?
else {
p = 0U; // no more subscribers
}
} while ((p != 0U) &amp;&amp; (limit &gt; 0U));
} while ((p != 0U) &amp;&amp; (lbound &gt; 0U));
QF_CRIT_ENTRY();
Q_ENSURE_INCRIT(290, p == 0U);
// NOTE: the following postcondition can only succeed when
// (lbound &gt; 0), so no extra check for lbound is necessary.
Q_ENSURE_INCRIT(290, p == 0U); // all subscribers processed
QF_CRIT_EXIT();
QF_SCHED_UNLOCK_(); // unlock the scheduler
@ -2781,7 +2800,7 @@ Q_REQUIRE_INCRIT(300, ((enum_t)Q_USER_SIG &lt;= sig)
&amp;&amp; (sig &lt; QActive_maxPubSignal_)
&amp;&amp; (0U &lt; p) &amp;&amp; (p &lt;= QF_MAX_ACTIVE)
&amp;&amp; (QActive_registry_[p] == me));
Q_REQUIRE_INCRIT(302,
Q_INVARIANT_INCRIT(302,
QPSet_verify_(&amp;QActive_subscrList_[sig].set,
&amp;QActive_subscrList_[sig].set_dis));
@ -2819,7 +2838,7 @@ Q_REQUIRE_INCRIT(400, ((enum_t)Q_USER_SIG &lt;= sig)
&amp;&amp; (sig &lt; QActive_maxPubSignal_)
&amp;&amp; (0U &lt; p) &amp;&amp; (p &lt;= QF_MAX_ACTIVE)
&amp;&amp; (QActive_registry_[p] == me));
Q_REQUIRE_INCRIT(402,
Q_INVARIANT_INCRIT(402,
QPSet_verify_(&amp;QActive_subscrList_[sig].set,
&amp;QActive_subscrList_[sig].set_dis));
@ -3323,8 +3342,8 @@ QS_BEGIN_PRE_(QS_QF_TICK, 0U)
QS_END_PRE_()
// scan the linked-list of time events at this rate...
uint_fast8_t limit = 2U*QF_MAX_ACTIVE; // loop hard limit
for (; limit &gt; 0U; --limit) {
uint_fast8_t lbound = 2U*QF_MAX_ACTIVE; // fixed upper loop bound
for (; lbound &gt; 0U; --lbound) {
QTimeEvt *e = prev-&gt;next; // advance down the time evt. list
if (e == (QTimeEvt *)0) { // end of the list?
@ -3344,7 +3363,7 @@ for (; limit &gt; 0U; --limit) {
}
// the time event 'e' must be valid
Q_ASSERT_INCRIT(112, QEvt_verify_(Q_EVT_CAST(QEvt)));
Q_INVARIANT_INCRIT(112, QEvt_verify_(Q_EVT_CAST(QEvt)));
if (e-&gt;ctr == 0U) { // time event scheduled for removal?
prev-&gt;next = e-&gt;next;
@ -3431,7 +3450,7 @@ for (; limit &gt; 0U; --limit) {
QF_MEM_SYS();
}
Q_ENSURE_INCRIT(190, limit &gt; 0U);
Q_ENSURE_INCRIT(190, lbound &gt; 0U);
QF_MEM_APP();
QF_CRIT_EXIT();</code>
</operation>
@ -3957,14 +3976,14 @@ for (uint_fast32_t size = poolSize - me-&gt;blockSize;
++me-&gt;nTot; // one more free block in the pool
}
fb-&gt;next = (QFreeBlock *)0; // the last link points to NULL
fb-&gt;next = (QFreeBlock *)0; // the last link points to NULL
#ifndef Q_UNSAFE
fb-&gt;next_dis = (uintptr_t)(~Q_UINTPTR_CAST_(fb-&gt;next));
#endif
me-&gt;nFree = me-&gt;nTot; // all blocks are free
me-&gt;nMin = me-&gt;nTot; // the minimum # free blocks
me-&gt;start = poolSto; // the original start this pool buffer
me-&gt;start = (QFreeBlock *)poolSto; // the original start this pool buffer
me-&gt;end = fb; // the last block in this pool
QF_MEM_APP();
@ -3998,8 +4017,8 @@ if (me-&gt;nFree &gt; (QMPoolCtr)margin) {
QFreeBlock * const fb_next = fb-&gt;next; // fast temporary
// the free block must have integrity (duplicate inverse storage)
Q_ASSERT_INCRIT(302, Q_UINTPTR_CAST_(fb_next)
== (uintptr_t)~fb-&gt;next_dis);
Q_INVARIANT_INCRIT(302, Q_UINTPTR_CAST_(fb_next)
== (uintptr_t)~fb-&gt;next_dis);
--me-&gt;nFree; // one less free block
if (me-&gt;nFree == 0U) { // is the pool becoming empty?
@ -4078,7 +4097,7 @@ fb-&gt;next_dis = (uintptr_t)(~Q_UINTPTR_CAST_(fb-&gt;next));
#endif
// set as new head of the free list
me-&gt;free_head = block;
me-&gt;free_head = fb;
++me-&gt;nFree; // one more free block in this pool
@ -4360,7 +4379,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));
uint_fast8_t const poolNum = QEvt_getPoolNum_(e);
@ -4427,7 +4446,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));
uint_fast8_t const poolNum = QEvt_getPoolNum_(e);
@ -4456,11 +4475,11 @@ return e;</code>
//! @static @private @memberof QF</documentation>
<!--${QF::QF-dyn::deleteRef_::evtRef}-->
<parameter name="evtRef" type="void const * const"/>
<code>QEvt const * const e = evtRef;
<code>QEvt const * const e = (QEvt const *)evtRef;
QF_CRIT_STAT
QF_CRIT_ENTRY();
Q_REQUIRE_INCRIT(602, QEvt_verify_(e));
Q_INVARIANT_INCRIT(602, QEvt_verify_(e));
#ifdef Q_SPY
uint_fast8_t const poolNum = QEvt_getPoolNum_(e);
@ -4835,8 +4854,8 @@ QF_gc(e); // recycle the referenced event
QF_CRIT_ENTRY();
QF_MEM_SYS();
Q_ASSERT_INCRIT(102, QV_priv_.schedCeil
== (uint_fast8_t)(~QV_priv_.schedCeil_dis));
Q_INVARIANT_INCRIT(102, QV_priv_.schedCeil
== (uint_fast8_t)(~QV_priv_.schedCeil_dis));
if (ceiling &gt; QV_priv_.schedCeil) { // raising the scheduler ceiling?
@ -4864,8 +4883,8 @@ QF_CRIT_EXIT();</code>
QF_CRIT_ENTRY();
QF_MEM_SYS();
Q_ASSERT_INCRIT(202, QV_priv_.schedCeil
== (uint_fast8_t)(~QV_priv_.schedCeil_dis));
Q_INVARIANT_INCRIT(202, QV_priv_.schedCeil
== (uint_fast8_t)(~QV_priv_.schedCeil_dis));
if (QV_priv_.schedCeil != 0U) { // actually enabling the scheduler?
@ -4924,7 +4943,7 @@ QV_INIT(); // port-specific initialization of the QV kernel
//! @static @public @memberof QF</documentation>
<code>QF_onCleanup(); // application-specific cleanup callback
// nothing else to do for the cooperative QV kernel</code>
// nothing else to do for the QV kernel</code>
</operation>
<!--${QV::QF-cust::run}-->
<operation name="run" type="int_t" visibility="0x00" properties="0x01">
@ -4957,11 +4976,11 @@ uint_fast8_t pprev = 0U; // previously used prio.
for (;;) { // QV event loop...
// check internal integrity (duplicate inverse storage)
Q_ASSERT_INCRIT(302, QPSet_verify_(&amp;QV_priv_.readySet,
&amp;QV_priv_.readySet_dis));
Q_INVARIANT_INCRIT(302, QPSet_verify_(&amp;QV_priv_.readySet,
&amp;QV_priv_.readySet_dis));
// check internal integrity (duplicate inverse storage)
Q_ASSERT_INCRIT(303, QV_priv_.schedCeil
== (uint_fast8_t)(~QV_priv_.schedCeil_dis));
Q_INVARIANT_INCRIT(303, QV_priv_.schedCeil
== (uint_fast8_t)(~QV_priv_.schedCeil_dis));
// find the maximum prio. AO ready to run
uint_fast8_t const p = (QPSet_notEmpty(&amp;QV_priv_.readySet)
@ -5199,8 +5218,8 @@ QF_CRIT_ENTRY();
QF_MEM_SYS();
Q_REQUIRE_INCRIT(100, !QK_ISR_CONTEXT_());
Q_REQUIRE_INCRIT(102, QK_priv_.lockCeil
== (uint_fast8_t)(~QK_priv_.lockCeil_dis));
Q_INVARIANT_INCRIT(102, QK_priv_.lockCeil
== (uint_fast8_t)(~QK_priv_.lockCeil_dis));
// first store the previous lock prio
QSchedStatus stat;
@ -5242,8 +5261,8 @@ if (prevCeil != 0xFFU) {
QF_CRIT_ENTRY();
QF_MEM_SYS();
Q_REQUIRE_INCRIT(202, QK_priv_.lockCeil
== (uint_fast8_t)(~QK_priv_.lockCeil_dis));
Q_INVARIANT_INCRIT(202, QK_priv_.lockCeil
== (uint_fast8_t)(~QK_priv_.lockCeil_dis));
Q_REQUIRE_INCRIT(210, (!QK_ISR_CONTEXT_())
&amp;&amp; (QK_priv_.lockCeil &gt; prevCeil));
@ -5281,8 +5300,8 @@ if (prevCeil != 0xFFU) {
//! @static @private @memberof QK</documentation>
<code>// NOTE: this function is entered with interrupts DISABLED
Q_REQUIRE_INCRIT(402, QPSet_verify_(&amp;QK_priv_.readySet,
&amp;QK_priv_.readySet_dis));
Q_INVARIANT_INCRIT(402, QPSet_verify_(&amp;QK_priv_.readySet,
&amp;QK_priv_.readySet_dis));
uint_fast8_t p;
if (QPSet_isEmpty(&amp;QK_priv_.readySet)) {
p = 0U; // no activation needed
@ -5291,7 +5310,7 @@ else {
// find the highest-prio AO with non-empty event queue
p = QPSet_findMax(&amp;QK_priv_.readySet);
Q_ASSERT_INCRIT(412,
Q_INVARIANT_INCRIT(412,
QK_priv_.actThre == (uint_fast8_t)(~QK_priv_.actThre_dis));
// is the AO's prio. below the active preemption-threshold?
@ -5299,16 +5318,16 @@ else {
p = 0U; // no activation needed
}
else {
Q_ASSERT_INCRIT(422, QK_priv_.lockCeil
== (uint_fast8_t)(~QK_priv_.lockCeil_dis));
Q_INVARIANT_INCRIT(422, QK_priv_.lockCeil
== (uint_fast8_t)(~QK_priv_.lockCeil_dis));
// is the AO's prio. below the lock-ceiling?
if (p &lt;= QK_priv_.lockCeil) {
p = 0U; // no activation needed
}
else {
Q_ASSERT_INCRIT(432, QK_priv_.nextPrio
== (uint_fast8_t)(~QK_priv_.nextPrio_dis));
Q_INVARIANT_INCRIT(432, QK_priv_.nextPrio
== (uint_fast8_t)(~QK_priv_.nextPrio_dis));
QK_priv_.nextPrio = p; // next AO to run
#ifndef Q_UNSAFE
QK_priv_.nextPrio_dis = (uint_fast8_t)(~QK_priv_.nextPrio);
@ -5329,7 +5348,7 @@ return p;</code>
uint_fast8_t const prio_in = QK_priv_.actPrio; // save initial prio.
uint_fast8_t p = QK_priv_.nextPrio; // next prio to run
Q_REQUIRE_INCRIT(502,
Q_INVARIANT_INCRIT(502,
(prio_in == (uint_fast8_t)(~QK_priv_.actPrio_dis))
&amp;&amp; (p == (uint_fast8_t)(~QK_priv_.nextPrio_dis)));
Q_REQUIRE_INCRIT(510, (prio_in &lt;= QF_MAX_ACTIVE)
@ -5354,7 +5373,7 @@ else {
Q_ASSERT_INCRIT(510, a != (QActive *)0);
pthre_in = (uint_fast8_t)a-&gt;pthre;
Q_ASSERT_INCRIT(511, pthre_in ==
Q_INVARIANT_INCRIT(511, pthre_in ==
(uint_fast8_t)(~(uint_fast8_t)a-&gt;pthre_dis &amp; 0xFFU));
}
@ -5363,7 +5382,7 @@ do {
a = QActive_registry_[p]; // obtain the pointer to the AO
Q_ASSERT_INCRIT(520, a != (QActive *)0); // the AO must be registered
uint_fast8_t const pthre = (uint_fast8_t)a-&gt;pthre;
Q_ASSERT_INCRIT(522, pthre ==
Q_INVARIANT_INCRIT(522, pthre ==
(uint_fast8_t)(~(uint_fast8_t)a-&gt;pthre_dis &amp; 0xFFU));
// set new active prio. and preemption-threshold
@ -5391,6 +5410,7 @@ do {
}
#endif // QF_ON_CONTEXT_SW || Q_SPY
QF_MEM_APP();
QF_INT_ENABLE(); // unconditionally enable interrupts
QEvt const * const e = QActive_get_(a);
@ -5407,8 +5427,8 @@ do {
QF_MEM_SYS();
// internal integrity check (duplicate inverse storage)
Q_ASSERT_INCRIT(532, QPSet_verify_(&amp;QK_priv_.readySet,
&amp;QK_priv_.readySet_dis));
Q_INVARIANT_INCRIT(532, QPSet_verify_(&amp;QK_priv_.readySet,
&amp;QK_priv_.readySet_dis));
if (a-&gt;eQueue.frontEvt == (QEvt *)0) { // empty queue?
QPSet_remove(&amp;QK_priv_.readySet, p);
@ -5429,8 +5449,8 @@ do {
p = 0U; // no activation needed
}
else {
Q_ASSERT_INCRIT(542, QK_priv_.lockCeil
== (uint_fast8_t)(~QK_priv_.lockCeil_dis));
Q_INVARIANT_INCRIT(542, QK_priv_.lockCeil
== (uint_fast8_t)(~QK_priv_.lockCeil_dis));
// is the AO's prio. below the lock preemption-threshold?
if (p &lt;= QK_priv_.lockCeil) {
@ -5849,8 +5869,8 @@ return curr;</code>
<documentation>//! @static @private @memberof QXK
//! @static @private @memberof QXK</documentation>
<code>Q_REQUIRE_INCRIT(402, QPSet_verify_(&amp;QXK_priv_.readySet,
&amp;QXK_priv_.readySet_dis));
<code>Q_INVARIANT_INCRIT(402, QPSet_verify_(&amp;QXK_priv_.readySet,
&amp;QXK_priv_.readySet_dis));
QActive const * const curr = QXK_priv_.curr;
uint_fast8_t p;
@ -5926,6 +5946,7 @@ uint_fast8_t p = (uint_fast8_t)next-&gt;prio;
do {
QXK_priv_.actPrio = p; // next active prio
QF_MEM_APP();
QF_INT_ENABLE(); // unconditionally enable interrupts
QEvt const * const e = QActive_get_(next);
@ -5941,8 +5962,8 @@ do {
QF_MEM_SYS();
// check internal integrity (duplicate inverse storage)
Q_ASSERT_INCRIT(502, QPSet_verify_(&amp;QXK_priv_.readySet,
&amp;QXK_priv_.readySet_dis));
Q_INVARIANT_INCRIT(502, QPSet_verify_(&amp;QXK_priv_.readySet,
&amp;QXK_priv_.readySet_dis));
if (next-&gt;eQueue.frontEvt == (QEvt *)0) { // empty queue?
QPSet_remove(&amp;QXK_priv_.readySet, p);
@ -6926,7 +6947,7 @@ if (me-&gt;ao.eQueue.nFree == 0U) {
// is the mutex locked by this thread already (nested locking)?
else if (me-&gt;ao.osObject == &amp;curr-&gt;super) {
// 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, me-&gt;ao.eQueue.nFree &lt; 0xFFU);
@ -7073,7 +7094,7 @@ if (me-&gt;ao.eQueue.nFree == 0U) {
}
// is the mutex locked by this thread already (nested locking)?
else if (me-&gt;ao.osObject == curr) {
// the nesting level must not exceed the specified limit
// the nesting level must not exceed the specified bound
Q_ASSERT_INCRIT(320, me-&gt;ao.eQueue.nFree &lt; 0xFFU);
++me-&gt;ao.eQueue.nFree; // lock one more level
@ -8935,11 +8956,9 @@ $declare1 ${QP-FuSa}
#define QP_H_
//============================================================================
#define QP_VERSION 733U
#define QP_VERSION_STR &quot;7.3.3&quot;
//! Encrypted current QP release (7.3.3) and date (2024-03-01)
#define QP_RELEASE 0x70C4F752U
#define QP_VERSION_STR &quot;7.3.5-rc.1&quot;
#define QP_VERSION 735U
#define QP_RELEASE 0x70A1DEF0U
//============================================================================
//! @cond INTERNAL
@ -9678,10 +9697,6 @@ extern char const Q_BUILD_TIME[9];
<text>#ifndef QPC_H_
#define QPC_H_
#ifdef __cplusplus
extern &quot;C&quot; {
#endif
//============================================================================
#include &quot;qp_port.h&quot; // QP port from the port directory
#include &quot;qsafe.h&quot; // QP Functional Safety (FuSa) Subsystem
@ -9840,10 +9855,6 @@ static inline void QF_psInit(
#endif // QP_API_VERSION &lt; 691
#endif // QP_API_VERSION &lt; 700
#ifdef __cplusplus
}
#endif
#endif // QPC_H_</text>
</file>
</directory>
@ -9866,7 +9877,7 @@ static inline void QF_psInit(
Q_DEFINE_THIS_MODULE(&quot;qep_hsm&quot;)
$define ${QEP::QP_versionStr[8]}
$define ${QEP::QP_versionStr[16]}
//============================================================================
//! @cond INTERNAL
@ -11094,7 +11105,7 @@ void QS_target_info_pre_(uint8_t const isReset) {
QS_U8_PRE_(QS_OBJ_PTR_SIZE | (QS_FUN_PTR_SIZE &lt;&lt; 4U));
QS_U8_PRE_(QS_TIME_SIZE);
// send the limits...
// send the bounds...
QS_U8_PRE_(QF_MAX_ACTIVE);
QS_U8_PRE_(QF_MAX_EPOOL | (QF_MAX_TICK_RATE &lt;&lt; 4U));

View File

@ -60,11 +60,11 @@ Q_DEFINE_THIS_MODULE("qep_hsm")
#endif
//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//$define${QEP::QP_versionStr[8]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
//$define${QEP::QP_versionStr[16]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
//${QEP::QP_versionStr[8]} ...................................................
char const QP_versionStr[8] = QP_VERSION_STR;
//$enddef${QEP::QP_versionStr[8]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//${QEP::QP_versionStr[16]} ..................................................
char const QP_versionStr[16] = QP_VERSION_STR;
//$enddef${QEP::QP_versionStr[16]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//============================================================================
//! @cond INTERNAL
@ -188,27 +188,27 @@ void QHsm_init_(
QF_CRIT_EXIT();
// drill down into the state hierarchy with initial transitions...
int_fast8_t limit = QHSM_MAX_NEST_DEPTH_; // loop hard limit
do {
QStateHandler path[QHSM_MAX_NEST_DEPTH_]; // tran entry path array
int_fast8_t ip = 0; // tran entry path index
path[0] = me->temp.fun;
(void)QHSM_RESERVED_EVT_(me->temp.fun, Q_EMPTY_SIG);
// note: ip is the fixed upper loop bound
while ((me->temp.fun != t) && (ip < (QHSM_MAX_NEST_DEPTH_ - 1))) {
++ip;
path[ip] = me->temp.fun;
(void)QHSM_RESERVED_EVT_(me->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, me->temp.fun == t);
// too many state nesting levels or "malformed" HSM
Q_ENSURE_INCRIT(220, ip < QHSM_MAX_NEST_DEPTH_);
QF_CRIT_EXIT();
me->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)
@ -236,14 +236,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)
@ -277,9 +272,9 @@ void QHsm_dispatch_(
QF_CRIT_STAT
QF_CRIT_ENTRY();
Q_REQUIRE_INCRIT(300, (s != Q_STATE_CAST(0))
Q_REQUIRE_INCRIT(300, QEvt_verify_(e));
Q_INVARIANT_INCRIT(302, (s != Q_STATE_CAST(0))
&& (me->state.uint == (uintptr_t)(~me->temp.uint)));
Q_REQUIRE_INCRIT(302, QEvt_verify_(e));
QS_MEM_SYS();
QS_BEGIN_PRE_(QS_QEP_DISPATCH, qsId)
@ -295,7 +290,7 @@ void QHsm_dispatch_(
// process the event hierarchically...
QState r;
me->temp.fun = s;
int_fast8_t limit = QHSM_MAX_NEST_DEPTH_; // loop hard limit
int_fast8_t ip = QHSM_MAX_NEST_DEPTH_; // fixed upper loop bound
do {
s = me->temp.fun;
r = (*s)(me, e); // invoke state handler s
@ -315,11 +310,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?
@ -330,21 +325,21 @@ void QHsm_dispatch_(
path[2] = s; // tran. source
// exit current state to tran. source s...
limit = QHSM_MAX_NEST_DEPTH_; // loop hard limit
for (; (t != s) && (limit > 0); t = me->temp.fun) {
ip = QHSM_MAX_NEST_DEPTH_; // fixed upper loop bound
for (; (t != s) && (ip > 0); t = me->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
(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();
int_fast8_t ip = QHsm_tran_(me, path, qsId); // take the tran.
ip = QHsm_tran_(me, path, qsId); // take the tran.
#ifdef Q_SPY
if (r == Q_RET_TRAN_HIST) {
@ -361,6 +356,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)
@ -391,6 +387,7 @@ void QHsm_dispatch_(
// find superstate
(void)QHSM_RESERVED_EVT_(me->temp.fun, Q_EMPTY_SIG);
// note: ip is the fixed upper loop bound
while ((me->temp.fun != t) && (ip < (QHSM_MAX_NEST_DEPTH_ - 1))) {
++ip;
path[ip] = me->temp.fun;
@ -398,14 +395,14 @@ void QHsm_dispatch_(
(void)QHSM_RESERVED_EVT_(me->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, me->temp.fun == t);
// too many state nesting levels or "malformed" HSM
Q_ENSURE_INCRIT(330, ip < QHSM_MAX_NEST_DEPTH_);
QF_CRIT_EXIT();
me->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)
@ -481,17 +478,17 @@ bool QHsm_isIn_(
{
QF_CRIT_STAT
QF_CRIT_ENTRY();
Q_REQUIRE_INCRIT(602, me->state.uint
== (uintptr_t)(~me->temp.uint));
Q_INVARIANT_INCRIT(602, me->state.uint
== (uintptr_t)(~me->temp.uint));
QF_CRIT_EXIT();
bool inState = false; // assume that this HSM is not in 'state'
// scan the state hierarchy bottom-up
QStateHandler s = me->state.fun;
int_fast8_t limit = QHSM_MAX_NEST_DEPTH_ + 1; // loop hard limit
int_fast8_t lbound = QHSM_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
@ -503,7 +500,7 @@ bool QHsm_isIn_(
}
QF_CRIT_ENTRY();
Q_ENSURE_INCRIT(690, limit > 0);
Q_ENSURE_INCRIT(690, lbound > 0);
QF_CRIT_EXIT();
#ifndef Q_UNSAFE
@ -524,6 +521,7 @@ QStateHandler QHsm_childState(QHsm * const me,
// establish stable state configuration
me->super.temp.fun = child;
QState r;
int_fast8_t lbound = QHSM_MAX_NEST_DEPTH_; // fixed upper loop bound
do {
// is this the parent of the current child?
if (me->super.temp.fun == parent) {
@ -534,7 +532,9 @@ QStateHandler QHsm_childState(QHsm * const me,
child = me->super.temp.fun;
r = QHSM_RESERVED_EVT_(me->super.temp.fun, Q_EMPTY_SIG);
}
} while (r != Q_RET_IGNORED); // the top state not reached
--lbound;
} while ((r != Q_RET_IGNORED) // the top state not reached
&& (lbound > 0));
#ifndef Q_UNSAFE
me->super.temp.uint = ~me->super.state.uint;
@ -542,10 +542,12 @@ QStateHandler QHsm_childState(QHsm * const me,
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::tran_} ........................................................
@ -611,6 +613,7 @@ int_fast8_t QHsm_tran_(
t = me->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 < (QHSM_MAX_NEST_DEPTH_ - 1)))
@ -627,9 +630,10 @@ int_fast8_t QHsm_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?
@ -645,6 +649,7 @@ int_fast8_t QHsm_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
@ -661,7 +666,7 @@ int_fast8_t QHsm_tran_(
// (g) check each source->super->...
// for each target->super...
r = Q_RET_IGNORED; // keep looping
int_fast8_t limit = QHSM_MAX_NEST_DEPTH_;
int_fast8_t lbound = QHSM_MAX_NEST_DEPTH_;
do {
// exit from t
if (QHSM_RESERVED_EVT_(t, Q_EXIT_SIG)
@ -685,10 +690,10 @@ int_fast8_t QHsm_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_ENSURE_INCRIT(530, lbound > 0);
QF_CRIT_EXIT();
}
}

View File

@ -148,15 +148,15 @@ void QMsm_init_(
me->state.obj = me->temp.tatbl->target;
// drill down into the state hierarchy with initial transitions...
int_fast8_t limit = QMSM_MAX_NEST_DEPTH_; // loop hard limit
int_fast8_t lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound
do {
// execute the tran. table
r = QMsm_execTatbl_(me, me->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)
@ -189,9 +189,9 @@ void QMsm_dispatch_(
QF_CRIT_STAT
QF_CRIT_ENTRY();
Q_REQUIRE_INCRIT(300, (s != (QMState *)0)
Q_REQUIRE_INCRIT(300, QEvt_verify_(e));
Q_INVARIANT_INCRIT(302, (s != (QMState *)0)
&& (me->state.uint == (uintptr_t)(~me->temp.uint)));
Q_REQUIRE_INCRIT(302, QEvt_verify_(e));
QS_MEM_SYS();
QS_BEGIN_PRE_(QS_QEP_DISPATCH, qsId)
@ -206,7 +206,7 @@ void QMsm_dispatch_(
// scan the state hierarchy up to the top state...
QState r;
int_fast8_t limit = QMSM_MAX_NEST_DEPTH_; // loop hard limit
int_fast8_t lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound
do {
r = (*t->stateHandler)(me, e); // call state handler function
@ -239,10 +239,10 @@ void QMsm_dispatch_(
t = t->superstate; // advance to the superstate
}
--limit;
} while ((t != (QMState *)0) && (limit > 0));
--lbound;
} while ((t != (QMState *)0) && (lbound > 0));
QF_CRIT_ENTRY();
Q_ASSERT_INCRIT(310, limit > 0);
Q_ENSURE_INCRIT(310, lbound > 0);
QF_CRIT_EXIT();
if (r >= Q_RET_TRAN) { // any kind of tran. taken?
@ -255,7 +255,7 @@ void QMsm_dispatch_(
QF_CRIT_EXIT();
#endif // Q_SPY
limit = QMSM_MAX_NEST_DEPTH_; // loop hard limit
lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound
do {
// save the tran-action table before it gets clobbered
struct QMTranActTable const * const tatbl = me->temp.tatbl;
@ -320,11 +320,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_ENSURE_INCRIT(320, lbound > 0);
QS_MEM_SYS();
QS_BEGIN_PRE_(QS_QEP_TRAN, qsId)
@ -389,8 +389,8 @@ bool QMsm_isIn_(
bool inState = false; // assume that this SM is not in 'state'
QMState const *s = me->state.obj;
int_fast8_t limit = QMSM_MAX_NEST_DEPTH_; // loop hard limit
for (; (s != (QMState *)0) && (limit > 0); --limit) {
int_fast8_t lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound
for (; (s != (QMState *)0) && (lbound > 0); --lbound) {
if (s->stateHandler == state) { // match found?
inState = true;
break;
@ -402,7 +402,7 @@ bool QMsm_isIn_(
QF_CRIT_STAT
QF_CRIT_ENTRY();
Q_ENSURE_INCRIT(490, limit > 0);
Q_ENSURE_INCRIT(490, lbound > 0);
QF_CRIT_EXIT();
return inState;
@ -415,8 +415,8 @@ bool QMsm_isInState(QMsm const * const me,
bool inState = false; // assume that this SM is not in 'state'
QMState const *s = me->super.state.obj;
int_fast8_t limit = QMSM_MAX_NEST_DEPTH_; // loop hard limit
for (; (s != (QMState *)0) && (limit > 0); --limit) {
int_fast8_t lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound
for (; (s != (QMState *)0) && (lbound > 0); --lbound) {
if (s == stateObj) { // match found?
inState = true;
break;
@ -428,7 +428,7 @@ bool QMsm_isInState(QMsm const * const me,
QF_CRIT_STAT
QF_CRIT_ENTRY();
Q_ENSURE_INCRIT(590, limit > 0);
Q_ENSURE_INCRIT(590, lbound > 0);
QF_CRIT_EXIT();
return inState;
@ -443,9 +443,9 @@ QMState const * QMsm_childStateObj(QMsm const * const me,
bool isFound = false; // start with the child not found
QMState const *s;
int_fast8_t limit = QMSM_MAX_NEST_DEPTH_; // loop hard limit
int_fast8_t lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound
for (s = me->super.state.obj;
(s != (QMState *)0) && (limit > 0);
(s != (QMState *)0) && (lbound > 0);
s = s->superstate)
{
if (s == parent) {
@ -455,17 +455,17 @@ QMState const * QMsm_childStateObj(QMsm const * const me,
else {
child = s;
}
--limit;
--lbound;
}
QF_CRIT_STAT
QF_CRIT_ENTRY();
Q_ASSERT_INCRIT(610, limit > 0);
Q_ENSURE_INCRIT(610, lbound > 0);
QF_CRIT_EXIT();
if (!isFound) { // still not found?
limit = QMSM_MAX_NEST_DEPTH_; // loop hard limit
lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound
for (s = me->super.temp.obj;
(s != (QMState *)0) && (limit > 0);
(s != (QMState *)0) && (lbound > 0);
s = s->superstate)
{
if (s == parent) {
@ -475,12 +475,14 @@ QMState const * QMsm_childStateObj(QMsm const * const me,
else {
child = s;
}
--limit;
--lbound;
}
}
QF_CRIT_ENTRY();
Q_ENSURE_INCRIT(690, isFound && (limit > 0));
// NOTE: the following postcondition can only succeed when
// (lbound > 0), so no extra check is necessary.
Q_ENSURE_INCRIT(690, isFound);
QF_CRIT_EXIT();
return child; // return the child
@ -505,10 +507,11 @@ QState QMsm_execTatbl_(
QF_CRIT_EXIT();
QState r = Q_RET_NULL;
int_fast8_t limit = QMSM_MAX_TRAN_LENGTH_; // loop hard limit
int_fast8_t lbound = QMSM_MAX_TRAN_LENGTH_; // fixed upper loop bound
QActionHandler const *a = &tatbl->act[0];
for (; (*a != Q_ACTION_CAST(0)) && (limit > 0); ++a) {
for (; (*a != Q_ACTION_CAST(0)) && (lbound > 0); ++a) {
r = (*(*a))(me); // call the action through the 'a' pointer
--lbound;
#ifdef Q_SPY
QS_CRIT_ENTRY();
QS_MEM_SYS();
@ -551,9 +554,10 @@ QState QMsm_execTatbl_(
QS_MEM_APP();
QS_CRIT_EXIT();
#endif // Q_SPY
--limit;
}
QF_CRIT_ENTRY();
// NOTE: the following postcondition can only succeed when
// (lbound > 0), so no extra check is necessary.
Q_ENSURE_INCRIT(790, *a == Q_ACTION_CAST(0));
QF_CRIT_EXIT();
@ -579,8 +583,8 @@ void QMsm_exitToTranSource_(
// exit states from the current state to the tran. source state
QMState const *s = cs;
int_fast8_t limit = QMSM_MAX_NEST_DEPTH_; // loop hard limit
for (; (s != ts) && (limit > 0); --limit) {
int_fast8_t lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound
for (; (s != ts) && (lbound > 0); --lbound) {
// exit action provided in state 's'?
if (s->exitAction != Q_ACTION_CAST(0)) {
// execute the exit action
@ -606,7 +610,7 @@ void QMsm_exitToTranSource_(
}
}
QF_CRIT_ENTRY();
Q_ENSURE_INCRIT(890, limit > 0);
Q_ENSURE_INCRIT(890, lbound > 0);
QF_CRIT_EXIT();
}

View File

@ -88,7 +88,7 @@ bool QActive_post_(QActive * const me,
#ifndef Q_UNSAFE
uint8_t const pcopy = (uint8_t)(~me->prio_dis);
Q_REQUIRE_INCRIT(102, (QEvt_verify_(e)) && (me->prio == pcopy));
Q_INVARIANT_INCRIT(102, (QEvt_verify_(e)) && (me->prio == pcopy));
#endif
QEQueueCtr nFree = me->eQueue.nFree; // get volatile into temporary
@ -230,7 +230,7 @@ void QActive_postLIFO_(QActive * const me,
#ifndef Q_UNSAFE
uint8_t const pcopy = (uint8_t)(~me->prio_dis);
Q_REQUIRE_INCRIT(202, (QEvt_verify_(e)) && (me->prio == pcopy));
Q_INVARIANT_INCRIT(202, (QEvt_verify_(e)) && (me->prio == pcopy));
#endif
#ifdef QXK_H_

View File

@ -218,7 +218,7 @@ QEvt * QF_newX_(
void QF_gc(QEvt const * const e) {
QF_CRIT_STAT
QF_CRIT_ENTRY();
Q_REQUIRE_INCRIT(402, QEvt_verify_(e));
Q_INVARIANT_INCRIT(402, QEvt_verify_(e));
uint_fast8_t const poolNum = QEvt_getPoolNum_(e);
@ -283,7 +283,7 @@ QEvt const * QF_newRef_(
QF_CRIT_STAT
QF_CRIT_ENTRY();
Q_REQUIRE_INCRIT(502, QEvt_verify_(e));
Q_INVARIANT_INCRIT(502, QEvt_verify_(e));
uint_fast8_t const poolNum = QEvt_getPoolNum_(e);
@ -309,11 +309,11 @@ QEvt const * QF_newRef_(
//${QF::QF-dyn::deleteRef_} ..................................................
//! @static @private @memberof QF
void QF_deleteRef_(void const * const evtRef) {
QEvt const * const e = evtRef;
QEvt const * const e = (QEvt const *)evtRef;
QF_CRIT_STAT
QF_CRIT_ENTRY();
Q_REQUIRE_INCRIT(602, QEvt_verify_(e));
Q_INVARIANT_INCRIT(602, QEvt_verify_(e));
#ifdef Q_SPY
uint_fast8_t const poolNum = QEvt_getPoolNum_(e);

View File

@ -109,14 +109,14 @@ void QMPool_init(QMPool * const me,
++me->nTot; // one more free block in the pool
}
fb->next = (QFreeBlock *)0; // the last link points to NULL
fb->next = (QFreeBlock *)0; // the last link points to NULL
#ifndef Q_UNSAFE
fb->next_dis = (uintptr_t)(~Q_UINTPTR_CAST_(fb->next));
#endif
me->nFree = me->nTot; // all blocks are free
me->nMin = me->nTot; // the minimum # free blocks
me->start = poolSto; // the original start this pool buffer
me->start = (QFreeBlock *)poolSto; // the original start this pool buffer
me->end = fb; // the last block in this pool
QF_MEM_APP();
@ -148,8 +148,8 @@ void * QMPool_get(QMPool * const me,
QFreeBlock * const fb_next = fb->next; // fast temporary
// the free block must have integrity (duplicate inverse storage)
Q_ASSERT_INCRIT(302, Q_UINTPTR_CAST_(fb_next)
== (uintptr_t)~fb->next_dis);
Q_INVARIANT_INCRIT(302, Q_UINTPTR_CAST_(fb_next)
== (uintptr_t)~fb->next_dis);
--me->nFree; // one less free block
if (me->nFree == 0U) { // is the pool becoming empty?
@ -226,7 +226,7 @@ void QMPool_put(QMPool * const me,
#endif
// set as new head of the free list
me->free_head = block;
me->free_head = fb;
++me->nFree; // one more free block in this pool

View File

@ -110,7 +110,7 @@ void QActive_publish_(
QF_MEM_SYS();
Q_REQUIRE_INCRIT(200, sig < (QSignal)QActive_maxPubSignal_);
Q_REQUIRE_INCRIT(202,
Q_INVARIANT_INCRIT(202,
QPSet_verify_(&QActive_subscrList_[sig].set,
&QActive_subscrList_[sig].set_dis));
@ -154,9 +154,9 @@ void QActive_publish_(
QF_SCHED_STAT_
QF_SCHED_LOCK_(p); // lock the scheduler up to AO's prio
uint_fast8_t limit = QF_MAX_ACTIVE + 1U;
uint_fast8_t lbound = QF_MAX_ACTIVE + 1U; // fixed upper loop bound
do { // loop over all subscribers
--limit;
--lbound;
// QACTIVE_POST() asserts internally if the queue overflows
QACTIVE_POST(a, e, sender);
@ -178,10 +178,12 @@ 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);
// NOTE: the following postcondition can only succeed when
// (lbound > 0), so no extra check for lbound is necessary.
Q_ENSURE_INCRIT(290, p == 0U); // all subscribers processed
QF_CRIT_EXIT();
QF_SCHED_UNLOCK_(); // unlock the scheduler
@ -213,7 +215,7 @@ void QActive_subscribe(QActive const * const me,
&& (sig < QActive_maxPubSignal_)
&& (0U < p) && (p <= QF_MAX_ACTIVE)
&& (QActive_registry_[p] == me));
Q_REQUIRE_INCRIT(302,
Q_INVARIANT_INCRIT(302,
QPSet_verify_(&QActive_subscrList_[sig].set,
&QActive_subscrList_[sig].set_dis));
@ -252,7 +254,7 @@ void QActive_unsubscribe(QActive const * const me,
&& (sig < QActive_maxPubSignal_)
&& (0U < p) && (p <= QF_MAX_ACTIVE)
&& (QActive_registry_[p] == me));
Q_REQUIRE_INCRIT(402,
Q_INVARIANT_INCRIT(402,
QPSet_verify_(&QActive_subscrList_[sig].set,
&QActive_subscrList_[sig].set_dis));

View File

@ -316,8 +316,8 @@ void QTimeEvt_tick_(
QS_END_PRE_()
// scan the linked-list of time events at this rate...
uint_fast8_t limit = 2U*QF_MAX_ACTIVE; // loop hard limit
for (; limit > 0U; --limit) {
uint_fast8_t lbound = 2U*QF_MAX_ACTIVE; // fixed upper loop bound
for (; lbound > 0U; --lbound) {
QTimeEvt *e = prev->next; // advance down the time evt. list
if (e == (QTimeEvt *)0) { // end of the list?
@ -337,7 +337,7 @@ void QTimeEvt_tick_(
}
// the time event 'e' must be valid
Q_ASSERT_INCRIT(112, QEvt_verify_(Q_EVT_CAST(QEvt)));
Q_INVARIANT_INCRIT(112, QEvt_verify_(Q_EVT_CAST(QEvt)));
if (e->ctr == 0U) { // time event scheduled for removal?
prev->next = e->next;
@ -424,7 +424,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();
}

View File

@ -78,8 +78,8 @@ QSchedStatus QK_schedLock(uint_fast8_t const ceiling) {
QF_MEM_SYS();
Q_REQUIRE_INCRIT(100, !QK_ISR_CONTEXT_());
Q_REQUIRE_INCRIT(102, QK_priv_.lockCeil
== (uint_fast8_t)(~QK_priv_.lockCeil_dis));
Q_INVARIANT_INCRIT(102, QK_priv_.lockCeil
== (uint_fast8_t)(~QK_priv_.lockCeil_dis));
// first store the previous lock prio
QSchedStatus stat;
@ -118,8 +118,8 @@ void QK_schedUnlock(QSchedStatus const prevCeil) {
QF_CRIT_ENTRY();
QF_MEM_SYS();
Q_REQUIRE_INCRIT(202, QK_priv_.lockCeil
== (uint_fast8_t)(~QK_priv_.lockCeil_dis));
Q_INVARIANT_INCRIT(202, QK_priv_.lockCeil
== (uint_fast8_t)(~QK_priv_.lockCeil_dis));
Q_REQUIRE_INCRIT(210, (!QK_ISR_CONTEXT_())
&& (QK_priv_.lockCeil > prevCeil));
@ -150,8 +150,8 @@ void QK_schedUnlock(QSchedStatus const prevCeil) {
uint_fast8_t QK_sched_(void) {
// NOTE: this function is entered with interrupts DISABLED
Q_REQUIRE_INCRIT(402, QPSet_verify_(&QK_priv_.readySet,
&QK_priv_.readySet_dis));
Q_INVARIANT_INCRIT(402, QPSet_verify_(&QK_priv_.readySet,
&QK_priv_.readySet_dis));
uint_fast8_t p;
if (QPSet_isEmpty(&QK_priv_.readySet)) {
p = 0U; // no activation needed
@ -160,7 +160,7 @@ uint_fast8_t QK_sched_(void) {
// find the highest-prio AO with non-empty event queue
p = QPSet_findMax(&QK_priv_.readySet);
Q_ASSERT_INCRIT(412,
Q_INVARIANT_INCRIT(412,
QK_priv_.actThre == (uint_fast8_t)(~QK_priv_.actThre_dis));
// is the AO's prio. below the active preemption-threshold?
@ -168,16 +168,16 @@ uint_fast8_t QK_sched_(void) {
p = 0U; // no activation needed
}
else {
Q_ASSERT_INCRIT(422, QK_priv_.lockCeil
== (uint_fast8_t)(~QK_priv_.lockCeil_dis));
Q_INVARIANT_INCRIT(422, QK_priv_.lockCeil
== (uint_fast8_t)(~QK_priv_.lockCeil_dis));
// is the AO's prio. below the lock-ceiling?
if (p <= QK_priv_.lockCeil) {
p = 0U; // no activation needed
}
else {
Q_ASSERT_INCRIT(432, QK_priv_.nextPrio
== (uint_fast8_t)(~QK_priv_.nextPrio_dis));
Q_INVARIANT_INCRIT(432, QK_priv_.nextPrio
== (uint_fast8_t)(~QK_priv_.nextPrio_dis));
QK_priv_.nextPrio = p; // next AO to run
#ifndef Q_UNSAFE
QK_priv_.nextPrio_dis = (uint_fast8_t)(~QK_priv_.nextPrio);
@ -197,7 +197,7 @@ void QK_activate_(void) {
uint_fast8_t const prio_in = QK_priv_.actPrio; // save initial prio.
uint_fast8_t p = QK_priv_.nextPrio; // next prio to run
Q_REQUIRE_INCRIT(502,
Q_INVARIANT_INCRIT(502,
(prio_in == (uint_fast8_t)(~QK_priv_.actPrio_dis))
&& (p == (uint_fast8_t)(~QK_priv_.nextPrio_dis)));
Q_REQUIRE_INCRIT(510, (prio_in <= QF_MAX_ACTIVE)
@ -222,7 +222,7 @@ void QK_activate_(void) {
Q_ASSERT_INCRIT(510, a != (QActive *)0);
pthre_in = (uint_fast8_t)a->pthre;
Q_ASSERT_INCRIT(511, pthre_in ==
Q_INVARIANT_INCRIT(511, pthre_in ==
(uint_fast8_t)(~(uint_fast8_t)a->pthre_dis & 0xFFU));
}
@ -231,7 +231,7 @@ void QK_activate_(void) {
a = QActive_registry_[p]; // obtain the pointer to the AO
Q_ASSERT_INCRIT(520, a != (QActive *)0); // the AO must be registered
uint_fast8_t const pthre = (uint_fast8_t)a->pthre;
Q_ASSERT_INCRIT(522, pthre ==
Q_INVARIANT_INCRIT(522, pthre ==
(uint_fast8_t)(~(uint_fast8_t)a->pthre_dis & 0xFFU));
// set new active prio. and preemption-threshold
@ -259,6 +259,7 @@ void QK_activate_(void) {
}
#endif // QF_ON_CONTEXT_SW || Q_SPY
QF_MEM_APP();
QF_INT_ENABLE(); // unconditionally enable interrupts
QEvt const * const e = QActive_get_(a);
@ -275,8 +276,8 @@ void QK_activate_(void) {
QF_MEM_SYS();
// internal integrity check (duplicate inverse storage)
Q_ASSERT_INCRIT(532, QPSet_verify_(&QK_priv_.readySet,
&QK_priv_.readySet_dis));
Q_INVARIANT_INCRIT(532, QPSet_verify_(&QK_priv_.readySet,
&QK_priv_.readySet_dis));
if (a->eQueue.frontEvt == (QEvt *)0) { // empty queue?
QPSet_remove(&QK_priv_.readySet, p);
@ -297,8 +298,8 @@ void QK_activate_(void) {
p = 0U; // no activation needed
}
else {
Q_ASSERT_INCRIT(542, QK_priv_.lockCeil
== (uint_fast8_t)(~QK_priv_.lockCeil_dis));
Q_INVARIANT_INCRIT(542, QK_priv_.lockCeil
== (uint_fast8_t)(~QK_priv_.lockCeil_dis));
// is the AO's prio. below the lock preemption-threshold?
if (p <= QK_priv_.lockCeil) {

View File

@ -919,7 +919,7 @@ void QS_target_info_pre_(uint8_t const isReset) {
QS_U8_PRE_(QS_OBJ_PTR_SIZE | (QS_FUN_PTR_SIZE << 4U));
QS_U8_PRE_(QS_TIME_SIZE);
// send the limits...
// send the bounds...
QS_U8_PRE_(QF_MAX_ACTIVE);
QS_U8_PRE_(QF_MAX_EPOOL | (QF_MAX_TICK_RATE << 4U));

View File

@ -77,8 +77,8 @@ void QV_schedDisable(uint_fast8_t const ceiling) {
QF_CRIT_ENTRY();
QF_MEM_SYS();
Q_ASSERT_INCRIT(102, QV_priv_.schedCeil
== (uint_fast8_t)(~QV_priv_.schedCeil_dis));
Q_INVARIANT_INCRIT(102, QV_priv_.schedCeil
== (uint_fast8_t)(~QV_priv_.schedCeil_dis));
if (ceiling > QV_priv_.schedCeil) { // raising the scheduler ceiling?
@ -105,8 +105,8 @@ void QV_schedEnable(void) {
QF_CRIT_ENTRY();
QF_MEM_SYS();
Q_ASSERT_INCRIT(202, QV_priv_.schedCeil
== (uint_fast8_t)(~QV_priv_.schedCeil_dis));
Q_INVARIANT_INCRIT(202, QV_priv_.schedCeil
== (uint_fast8_t)(~QV_priv_.schedCeil_dis));
if (QV_priv_.schedCeil != 0U) { // actually enabling the scheduler?
@ -157,7 +157,7 @@ void QF_init(void) {
//! @static @public @memberof QF
void QF_stop(void) {
QF_onCleanup(); // application-specific cleanup callback
// nothing else to do for the cooperative QV kernel
// nothing else to do for the QV kernel
}
//${QV::QF-cust::run} ........................................................
@ -189,11 +189,11 @@ int_t QF_run(void) {
for (;;) { // QV event loop...
// check internal integrity (duplicate inverse storage)
Q_ASSERT_INCRIT(302, QPSet_verify_(&QV_priv_.readySet,
&QV_priv_.readySet_dis));
Q_INVARIANT_INCRIT(302, QPSet_verify_(&QV_priv_.readySet,
&QV_priv_.readySet_dis));
// check internal integrity (duplicate inverse storage)
Q_ASSERT_INCRIT(303, QV_priv_.schedCeil
== (uint_fast8_t)(~QV_priv_.schedCeil_dis));
Q_INVARIANT_INCRIT(303, QV_priv_.schedCeil
== (uint_fast8_t)(~QV_priv_.schedCeil_dis));
// find the maximum prio. AO ready to run
uint_fast8_t const p = (QPSet_notEmpty(&QV_priv_.readySet)

View File

@ -166,8 +166,8 @@ QActive * QXK_current(void) {
//${QXK::QXK-base::sched_} ...................................................
//! @static @private @memberof QXK
uint_fast8_t QXK_sched_(void) {
Q_REQUIRE_INCRIT(402, QPSet_verify_(&QXK_priv_.readySet,
&QXK_priv_.readySet_dis));
Q_INVARIANT_INCRIT(402, QPSet_verify_(&QXK_priv_.readySet,
&QXK_priv_.readySet_dis));
QActive const * const curr = QXK_priv_.curr;
uint_fast8_t p;
@ -242,6 +242,7 @@ void QXK_activate_(void) {
do {
QXK_priv_.actPrio = p; // next active prio
QF_MEM_APP();
QF_INT_ENABLE(); // unconditionally enable interrupts
QEvt const * const e = QActive_get_(next);
@ -257,8 +258,8 @@ void QXK_activate_(void) {
QF_MEM_SYS();
// check internal integrity (duplicate inverse storage)
Q_ASSERT_INCRIT(502, QPSet_verify_(&QXK_priv_.readySet,
&QXK_priv_.readySet_dis));
Q_INVARIANT_INCRIT(502, QPSet_verify_(&QXK_priv_.readySet,
&QXK_priv_.readySet_dis));
if (next->eQueue.frontEvt == (QEvt *)0) { // empty queue?
QPSet_remove(&QXK_priv_.readySet, p);

View File

@ -163,7 +163,7 @@ bool QXMutex_lock(QXMutex * const me,
// is the mutex locked by this thread already (nested locking)?
else if (me->ao.osObject == &curr->super) {
// 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, me->ao.eQueue.nFree < 0xFFU);
@ -309,7 +309,7 @@ bool QXMutex_tryLock(QXMutex * const me) {
}
// is the mutex locked by this thread already (nested locking)?
else if (me->ao.osObject == curr) {
// the nesting level must not exceed the specified limit
// the nesting level must not exceed the specified bound
Q_ASSERT_INCRIT(320, me->ao.eQueue.nFree < 0xFFU);
++me->ao.eQueue.nFree; // lock one more level