mirror of
https://github.com/QuantumLeaps/qpc.git
synced 2025-01-14 06:43:19 +08:00
7.3.5-rc.1
Semantic versioning
This commit is contained in:
parent
340b6bbd92
commit
074c0dc3ae
@ -1 +1 @@
|
||||
Subproject commit db8b6155e6931d2c55315dfd55b0e1fac0f96e33
|
||||
Subproject commit 054cd1abe4b4abef5e45f36b1ce8f2aff4575494
|
127
README.md
127
README.md
@ -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>
|
||||
|
2
examples
2
examples
@ -1 +1 @@
|
||||
Subproject commit 5b4edf6f7a1514169427fa42522d823fb31ee37c
|
||||
Subproject commit 5e7c7e64d3a6b1c3fde11cb03252bfb37bbf1149
|
12
include/qp.h
12
include/qp.h
@ -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)
|
||||
|
@ -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_
|
||||
|
@ -150,6 +150,9 @@ extern "C" {
|
||||
//${QP-FuSa::Q_INVARIANT} ....................................................
|
||||
#define Q_INVARIANT(expr_) Q_ASSERT(expr_)
|
||||
|
||||
//${QP-FuSa::Q_INVARIANT_INCRIT} .............................................
|
||||
#define Q_INVARIANT_INCRIT(id_, expr_) Q_ASSERT_INCRIT((id_), (expr_))
|
||||
|
||||
//${QP-FuSa::Q_ASSERT_STATIC} ................................................
|
||||
#define Q_ASSERT_STATIC(expr_) extern char Q_static_assert_[(expr_) ? 1 : -1]
|
||||
|
||||
|
@ -27,8 +27,8 @@
|
||||
// <www.state-machine.com>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2023-12-04
|
||||
//! @version Last updated for: @ref 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...
|
||||
|
@ -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...
|
||||
|
@ -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...
|
||||
|
@ -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_,
|
||||
|
6
ports/lint-plus2/16bit/cpu.lnt
Normal file
6
ports/lint-plus2/16bit/cpu.lnt
Normal file
@ -0,0 +1,6 @@
|
||||
// Size Options for 16bit CPU (e.g., MSP430)
|
||||
-si2 -sl4 -sll8 -ss2 -sw2 -sp2 -sf4 -sd8 -sld8
|
||||
|
||||
// Alignment options for 16bit CPU
|
||||
-ai2 -al2 -all2 -as2 -af4 -ad8 -ald8
|
||||
|
58
ports/lint-plus2/16bit/qs_port.h
Normal file
58
ports/lint-plus2/16bit/qs_port.h
Normal file
@ -0,0 +1,58 @@
|
||||
//============================================================================
|
||||
// QP/C Real-Time Embedded Framework (RTEF)
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
//
|
||||
// This software is dual-licensed under the terms of the open source GNU
|
||||
// General Public License version 3 (or any later version), or alternatively,
|
||||
// under the terms of one of the closed source Quantum Leaps commercial
|
||||
// licenses.
|
||||
//
|
||||
// The terms of the open source GNU General Public License version 3
|
||||
// can be found at: <www.gnu.org/licenses/gpl-3.0>
|
||||
//
|
||||
// The terms of the closed source Quantum Leaps commercial licenses
|
||||
// can be found at: <www.state-machine.com/licensing>
|
||||
//
|
||||
// Redistributions in source code must retain this top-level comment block.
|
||||
// Plagiarizing this software to sidestep the license obligations is illegal.
|
||||
//
|
||||
// Contact information:
|
||||
// <www.state-machine.com>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2023-08-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_
|
47
ports/lint-plus2/16bit/stdint.h
Normal file
47
ports/lint-plus2/16bit/stdint.h
Normal 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_
|
||||
|
3
ports/lint-plus2/32bit/cpu.lnt
Normal file
3
ports/lint-plus2/32bit/cpu.lnt
Normal file
@ -0,0 +1,3 @@
|
||||
// Size Options for 32bit CPU (e.g., ARM Cortex-M)
|
||||
-si4 -sl4 -sll8 -ss2 -sw4 -sp4 -sf4 -sd8 -sld8
|
||||
|
58
ports/lint-plus2/32bit/qs_port.h
Normal file
58
ports/lint-plus2/32bit/qs_port.h
Normal file
@ -0,0 +1,58 @@
|
||||
//============================================================================
|
||||
// QP/C Real-Time Embedded Framework (RTEF)
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
//
|
||||
// This software is dual-licensed under the terms of the open source GNU
|
||||
// General Public License version 3 (or any later version), or alternatively,
|
||||
// under the terms of one of the closed source Quantum Leaps commercial
|
||||
// licenses.
|
||||
//
|
||||
// The terms of the open source GNU General Public License version 3
|
||||
// can be found at: <www.gnu.org/licenses/gpl-3.0>
|
||||
//
|
||||
// The terms of the closed source Quantum Leaps commercial licenses
|
||||
// can be found at: <www.state-machine.com/licensing>
|
||||
//
|
||||
// Redistributions in source code must retain this top-level comment block.
|
||||
// Plagiarizing this software to sidestep the license obligations is illegal.
|
||||
//
|
||||
// Contact information:
|
||||
// <www.state-machine.com>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2023-08-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_
|
47
ports/lint-plus2/32bit/stdint.h
Normal file
47
ports/lint-plus2/32bit/stdint.h
Normal 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_
|
||||
|
21
ports/lint-plus2/au-ds.lnt
Normal file
21
ports/lint-plus2/au-ds.lnt
Normal file
@ -0,0 +1,21 @@
|
||||
// au-ds.lnt -- Author options - Dan Saks
|
||||
|
||||
/*
|
||||
This options file can be used to explicitly activate those
|
||||
checks advocated by Dan Saks in his series of presentations on
|
||||
"C++ Gotchas".
|
||||
|
||||
You can use this file directly when linting your programs as in:
|
||||
|
||||
lin au-ds files
|
||||
|
||||
*/
|
||||
|
||||
+fsc // consider string constants as const char *
|
||||
+e1933 // turn on "virtual call from member detection"
|
||||
|
||||
// The rationale for the following two options are fully described
|
||||
// in Dan Saks' article "const T vs. T const". Visit his web site
|
||||
// at www.dansaks.com and click "Published Articles".
|
||||
//
|
||||
-fqb +e963 // require T const rather than const T
|
70
ports/lint-plus2/make.bat
Normal file
70
ports/lint-plus2/make.bat
Normal file
@ -0,0 +1,70 @@
|
||||
@echo off
|
||||
:: ===========================================================================
|
||||
:: Batch script for linting QP/C with PC-Lint-Plus2
|
||||
:: Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
::
|
||||
:: SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
::
|
||||
:: This software is dual-licensed under the terms of the open source GNU
|
||||
:: General Public License version 3 (or any later version), or alternatively,
|
||||
:: under the terms of one of the closed source Quantum Leaps commercial
|
||||
:: licenses.
|
||||
::
|
||||
:: The terms of the open source GNU General Public License version 3
|
||||
:: can be found at: <www.gnu.org/licenses/gpl-3.0>
|
||||
::
|
||||
:: The terms of the closed source Quantum Leaps commercial licenses
|
||||
:: can be found at: <www.state-machine.com/licensing>
|
||||
::
|
||||
:: Redistributions in source code must retain this top-level comment block.
|
||||
:: Plagiarizing this software to sidestep the license obligations is illegal.
|
||||
::
|
||||
:: Contact information:
|
||||
:: <www.state-machine.com>
|
||||
:: <info@state-machine.com>
|
||||
:: ===========================================================================
|
||||
@setlocal
|
||||
|
||||
:: usage of make.bat
|
||||
@echo Usage: make [16bit] [-u...] files
|
||||
@echo examples:
|
||||
@echo make -uQ_SPY -uQ_UTEST : use 32bit CPU (default) and undefine Q_SPY/Q_UTEST
|
||||
@echo make 16bit -uQ_SPY : use 16bit CPU includes and undefine Q_SPY
|
||||
@echo.
|
||||
|
||||
:: NOTE: adjust to for your installation directory of PC-Lint-Plus
|
||||
@set PCLP=C:\tools\lint-plus2.2-beta\windows
|
||||
@set PCLP_EXE=%PCLP%\pclp64.exe
|
||||
|
||||
if NOT exist "%PCLP%" (
|
||||
@echo The PC-Lint-Plus toolset not found. Please adjust make.bat
|
||||
@goto end
|
||||
)
|
||||
|
||||
:: set the QP/C directory
|
||||
@set 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
|
368
ports/lint-plus2/options.lnt
Normal file
368
ports/lint-plus2/options.lnt
Normal 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_)
|
||||
|
94
ports/lint-plus2/qk/qp_port.h
Normal file
94
ports/lint-plus2/qk/qp_port.h
Normal 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_
|
||||
|
562
ports/lint-plus2/ql-style.lnt
Normal file
562
ports/lint-plus2/ql-style.lnt
Normal 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
427
ports/lint-plus2/qpc.lnt
Normal 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)
|
86
ports/lint-plus2/qv/qp_port.h
Normal file
86
ports/lint-plus2/qv/qp_port.h
Normal 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_
|
||||
|
101
ports/lint-plus2/qxk/qp_port.h
Normal file
101
ports/lint-plus2/qxk/qp_port.h
Normal file
@ -0,0 +1,101 @@
|
||||
//============================================================================
|
||||
// QP/C Real-Time Embedded Framework (RTEF)
|
||||
//
|
||||
// Q u a n t u m L e a P s
|
||||
// ------------------------
|
||||
// Modern Embedded Software
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
//
|
||||
// This software is dual-licensed under the terms of the open source GNU
|
||||
// General Public License version 3 (or any later version), or alternatively,
|
||||
// under the terms of one of the closed source Quantum Leaps commercial
|
||||
// licenses.
|
||||
//
|
||||
// The terms of the open source GNU General Public License version 3
|
||||
// can be found at: <www.gnu.org/licenses/gpl-3.0>
|
||||
//
|
||||
// The terms of the closed source Quantum Leaps commercial licenses
|
||||
// can be found at: <www.state-machine.com/licensing>
|
||||
//
|
||||
// Redistributions in source code must retain this top-level comment block.
|
||||
// Plagiarizing this software to sidestep the license obligations is illegal.
|
||||
//
|
||||
// Contact information:
|
||||
// <www.state-machine.com>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 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
44
ports/lint-plus2/std.lnt
Normal 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
|
30
ports/lint-plus2/stdbool.h
Normal file
30
ports/lint-plus2/stdbool.h
Normal 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_
|
||||
|
@ -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
41
qpc.md5
@ -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
301
qpc.qm
@ -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->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)
|
||||
@ -561,14 +569,9 @@ do {
|
||||
QS_CRIT_EXIT();
|
||||
}
|
||||
#endif // Q_SPY
|
||||
|
||||
--limit;
|
||||
} while ((r == Q_RET_TRAN) && (limit > 0));
|
||||
} while (r == Q_RET_TRAN);
|
||||
|
||||
QF_CRIT_ENTRY();
|
||||
// Loop limit must not be reached.
|
||||
// Too many state nesting levels or likely "malformed" HSM
|
||||
Q_ENSURE_INCRIT(290, limit > 0);
|
||||
|
||||
QS_MEM_SYS();
|
||||
QS_BEGIN_PRE_(QS_QEP_INIT_TRAN, qsId)
|
||||
@ -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))
|
||||
&& (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)
|
||||
@ -623,7 +626,7 @@ QF_CRIT_EXIT();
|
||||
// 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
|
||||
@ -643,11 +646,11 @@ do {
|
||||
r = QHSM_RESERVED_EVT_(s, Q_EMPTY_SIG); // superstate of s
|
||||
}
|
||||
|
||||
--limit;
|
||||
} while ((r == Q_RET_SUPER) && (limit > 0));
|
||||
--ip;
|
||||
} while ((r == Q_RET_SUPER) && (ip > 0));
|
||||
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ASSERT_INCRIT(310, limit > 0);
|
||||
Q_ENSURE_INCRIT(310, ip > 0);
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
if (r >= Q_RET_TRAN) { // regular tran. taken?
|
||||
@ -658,21 +661,21 @@ if (r >= 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) && (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) {
|
||||
@ -689,6 +692,7 @@ if (r >= Q_RET_TRAN) { // regular tran. taken?
|
||||
#endif // Q_SPY
|
||||
|
||||
// execute state entry actions in the desired order...
|
||||
// note: ip is the fixed upper loop bound
|
||||
for (; ip >= 0; --ip) {
|
||||
// enter path[ip]
|
||||
if (QHSM_RESERVED_EVT_(path[ip], Q_ENTRY_SIG)
|
||||
@ -719,6 +723,7 @@ if (r >= Q_RET_TRAN) { // regular tran. taken?
|
||||
// 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;
|
||||
@ -726,14 +731,14 @@ if (r >= Q_RET_TRAN) { // regular tran. taken?
|
||||
(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)
|
||||
@ -812,17 +817,17 @@ me->temp.uint = ~me->state.uint;
|
||||
<parameter name="state" type="QStateHandler const"/>
|
||||
<code>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
|
||||
@ -834,7 +839,7 @@ for (; (r != Q_RET_IGNORED) && (limit > 0); --limit) {
|
||||
}
|
||||
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ENSURE_INCRIT(690, limit > 0);
|
||||
Q_ENSURE_INCRIT(690, lbound > 0);
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
@ -864,6 +869,7 @@ bool isFound = false; // start with the child not found
|
||||
// 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) {
|
||||
@ -874,7 +880,9 @@ do {
|
||||
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;
|
||||
@ -882,10 +890,12 @@ me->super.temp.uint = ~me->super.state.uint;
|
||||
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ASSERT_INCRIT(890, isFound);
|
||||
// NOTE: the following postcondition can only succeed when
|
||||
// (lbound > 0), so no extra check is necessary.
|
||||
Q_ENSURE_INCRIT(890, isFound);
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
return child; // return the child</code>
|
||||
return child;</code>
|
||||
</operation>
|
||||
<!--${QEP::QHsm::tran_}-->
|
||||
<operation name="tran_" type="int_fast8_t" visibility="0x02" properties="0x01">
|
||||
@ -954,6 +964,7 @@ else {
|
||||
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)))
|
||||
@ -970,9 +981,10 @@ else {
|
||||
}
|
||||
}
|
||||
QF_CRIT_ENTRY();
|
||||
// Tran. source must be found within the nesting depth
|
||||
// Too many state nesting levels or "malformed" HSM.
|
||||
Q_ASSERT_INCRIT(510, r != Q_RET_SUPER);
|
||||
// NOTE: The following postcondition succeeds only when
|
||||
// ip < QHSM_MAX_NEST_DEPTH, so no additional check is necessary
|
||||
// too many state nesting levels or "malformed" HSM.
|
||||
Q_ENSURE_INCRIT(510, r != Q_RET_SUPER);
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
// the LCA not found yet?
|
||||
@ -988,6 +1000,7 @@ else {
|
||||
// == target->super->super...
|
||||
iq = ip;
|
||||
r = Q_RET_IGNORED; // indicate that the LCA NOT found
|
||||
// note: iq is the fixed upper loop bound
|
||||
do {
|
||||
if (t == path[iq]) { // is this the LCA?
|
||||
r = Q_RET_HANDLED; // indicate the LCA found
|
||||
@ -1004,7 +1017,7 @@ else {
|
||||
// (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)
|
||||
@ -1028,10 +1041,10 @@ else {
|
||||
}
|
||||
} while (iq >= 0);
|
||||
|
||||
--limit;
|
||||
} while ((r != Q_RET_HANDLED) && (limit > 0));
|
||||
--lbound;
|
||||
} while ((r != Q_RET_HANDLED) && (lbound > 0));
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ASSERT_INCRIT(530, limit > 0);
|
||||
Q_ENSURE_INCRIT(530, lbound > 0);
|
||||
QF_CRIT_EXIT();
|
||||
}
|
||||
}
|
||||
@ -1128,15 +1141,15 @@ QF_CRIT_EXIT();
|
||||
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)
|
||||
@ -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)
|
||||
&& (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)
|
||||
@ -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->stateHandler)(me, e); // call state handler function
|
||||
|
||||
@ -1222,10 +1235,10 @@ do {
|
||||
|
||||
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?
|
||||
@ -1238,7 +1251,7 @@ if (r >= 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->temp.tatbl;
|
||||
@ -1303,11 +1316,11 @@ if (r >= Q_RET_TRAN) { // any kind of tran. taken?
|
||||
}
|
||||
|
||||
t = s; // set target to the current state
|
||||
--limit;
|
||||
} while ((r >= Q_RET_TRAN) && (limit > 0));
|
||||
--lbound;
|
||||
} while ((r >= Q_RET_TRAN) && (lbound > 0));
|
||||
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ASSERT_INCRIT(320, limit > 0);
|
||||
Q_ENSURE_INCRIT(320, lbound > 0);
|
||||
|
||||
QS_MEM_SYS();
|
||||
QS_BEGIN_PRE_(QS_QEP_TRAN, qsId)
|
||||
@ -1383,8 +1396,8 @@ me->temp.uint = ~me->state.uint;
|
||||
<code>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;
|
||||
@ -1396,7 +1409,7 @@ for (; (s != (QMState *)0) && (limit > 0); --limit) {
|
||||
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ENSURE_INCRIT(490, limit > 0);
|
||||
Q_ENSURE_INCRIT(490, lbound > 0);
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
return inState;</code>
|
||||
@ -1410,8 +1423,8 @@ return inState;</code>
|
||||
<code>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;
|
||||
@ -1423,7 +1436,7 @@ for (; (s != (QMState *)0) && (limit > 0); --limit) {
|
||||
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ENSURE_INCRIT(590, limit > 0);
|
||||
Q_ENSURE_INCRIT(590, lbound > 0);
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
return inState;</code>
|
||||
@ -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->super.state.obj;
|
||||
(s != (QMState *)0) && (limit > 0);
|
||||
(s != (QMState *)0) && (lbound > 0);
|
||||
s = s->superstate)
|
||||
{
|
||||
if (s == parent) {
|
||||
@ -1459,17 +1472,17 @@ for (s = me->super.state.obj;
|
||||
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) {
|
||||
@ -1479,12 +1492,14 @@ if (!isFound) { // still not found?
|
||||
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</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 = &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();
|
||||
@ -1558,9 +1574,10 @@ for (; (*a != Q_ACTION_CAST(0)) && (limit > 0); ++a) {
|
||||
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();
|
||||
|
||||
@ -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) && (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
|
||||
@ -1617,7 +1634,7 @@ for (; (s != ts) && (limit > 0); --limit) {
|
||||
}
|
||||
}
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ENSURE_INCRIT(890, limit > 0);
|
||||
Q_ENSURE_INCRIT(890, lbound > 0);
|
||||
QF_CRIT_EXIT();</code>
|
||||
</operation>
|
||||
<!--${QEP::QMsm::enterHistory_}-->
|
||||
@ -2381,7 +2398,7 @@ QF_MEM_SYS();
|
||||
|
||||
#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
|
||||
@ -2522,7 +2539,7 @@ QF_MEM_SYS();
|
||||
|
||||
#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_
|
||||
@ -2679,7 +2696,7 @@ QF_CRIT_ENTRY();
|
||||
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));
|
||||
|
||||
@ -2723,9 +2740,9 @@ if (QPSet_notEmpty(&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(&subscrSet)) { // any subscribers?
|
||||
else {
|
||||
p = 0U; // no more subscribers
|
||||
}
|
||||
} while ((p != 0U) && (limit > 0U));
|
||||
} while ((p != 0U) && (lbound > 0U));
|
||||
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ENSURE_INCRIT(290, p == 0U);
|
||||
// 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
|
||||
@ -2781,7 +2800,7 @@ Q_REQUIRE_INCRIT(300, ((enum_t)Q_USER_SIG <= sig)
|
||||
&& (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));
|
||||
|
||||
@ -2819,7 +2838,7 @@ Q_REQUIRE_INCRIT(400, ((enum_t)Q_USER_SIG <= sig)
|
||||
&& (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));
|
||||
|
||||
@ -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 > 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?
|
||||
@ -3344,7 +3363,7 @@ for (; limit > 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->ctr == 0U) { // time event scheduled for removal?
|
||||
prev->next = e->next;
|
||||
@ -3431,7 +3450,7 @@ for (; limit > 0U; --limit) {
|
||||
QF_MEM_SYS();
|
||||
}
|
||||
|
||||
Q_ENSURE_INCRIT(190, limit > 0U);
|
||||
Q_ENSURE_INCRIT(190, lbound > 0U);
|
||||
QF_MEM_APP();
|
||||
QF_CRIT_EXIT();</code>
|
||||
</operation>
|
||||
@ -3957,14 +3976,14 @@ for (uint_fast32_t size = poolSize - me->blockSize;
|
||||
++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();
|
||||
@ -3998,8 +4017,8 @@ if (me->nFree > (QMPoolCtr)margin) {
|
||||
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?
|
||||
@ -4078,7 +4097,7 @@ fb->next_dis = (uintptr_t)(~Q_UINTPTR_CAST_(fb->next));
|
||||
#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
|
||||
|
||||
@ -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 > 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_(&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)
|
||||
@ -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_())
|
||||
&& (QK_priv_.lockCeil > 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_(&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
|
||||
@ -5291,7 +5310,7 @@ else {
|
||||
// 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?
|
||||
@ -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 <= 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))
|
||||
&& (p == (uint_fast8_t)(~QK_priv_.nextPrio_dis)));
|
||||
Q_REQUIRE_INCRIT(510, (prio_in <= QF_MAX_ACTIVE)
|
||||
@ -5354,7 +5373,7 @@ else {
|
||||
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));
|
||||
}
|
||||
|
||||
@ -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->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
|
||||
@ -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_(&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);
|
||||
@ -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 <= 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_(&QXK_priv_.readySet,
|
||||
&QXK_priv_.readySet_dis));
|
||||
<code>Q_INVARIANT_INCRIT(402, QPSet_verify_(&QXK_priv_.readySet,
|
||||
&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->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_(&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);
|
||||
@ -6926,7 +6947,7 @@ if (me->ao.eQueue.nFree == 0U) {
|
||||
// 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);
|
||||
|
||||
@ -7073,7 +7094,7 @@ if (me->ao.eQueue.nFree == 0U) {
|
||||
}
|
||||
// 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
|
||||
@ -8935,11 +8956,9 @@ $declare1 ${QP-FuSa}
|
||||
#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
|
||||
@ -9678,10 +9697,6 @@ extern char const Q_BUILD_TIME[9];
|
||||
<text>#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
|
||||
@ -9840,10 +9855,6 @@ static inline void QF_psInit(
|
||||
#endif // QP_API_VERSION < 691
|
||||
#endif // QP_API_VERSION < 700
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // QPC_H_</text>
|
||||
</file>
|
||||
</directory>
|
||||
@ -9866,7 +9877,7 @@ static inline void QF_psInit(
|
||||
|
||||
Q_DEFINE_THIS_MODULE("qep_hsm")
|
||||
|
||||
$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 << 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));
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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_
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
37
src/qk/qk.c
37
src/qk/qk.c
@ -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) {
|
||||
|
@ -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));
|
||||
|
||||
|
18
src/qv/qv.c
18
src/qv/qv.c
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user