From 6d29ea66998f4c73ffc2e71cc98937331a942b2b Mon Sep 17 00:00:00 2001 From: MMS Date: Sat, 18 Jan 2025 18:33:14 -0500 Subject: [PATCH] 8.0.2 --- LICENSES/LicenseRef-QL-commercial.txt | 36 +- LICENSES/LicenseRef-QL-dual.qlc | 9 +- README.md | 124 +- examples | 2 +- include/qequeue.h | 86 +- include/qk.h | 140 +- include/qmpool.h | 93 +- include/qp.h | 983 +--- include/qp_pkg.h | 67 +- include/qpc.h | 19 +- include/qs_dummy.h | 13 +- include/qsafe.h | 147 +- include/qstamp.h | 15 +- include/qv.h | 88 +- ports/arm-cm/config/qp_config.h | 28 +- ports/arm-cm/qk/armclang/qk_port.c | 19 +- ports/arm-cm/qk/armclang/qp_port.h | 18 +- ports/arm-cm/qk/armclang/qs_port.h | 41 +- ports/arm-cm/qk/gnu/qk_port.c | 19 +- ports/arm-cm/qk/gnu/qp_port.h | 19 +- ports/arm-cm/qk/gnu/qs_port.h | 41 +- ports/arm-cm/qk/iar/qk_port.c | 18 +- ports/arm-cm/qk/iar/qp_port.h | 19 +- ports/arm-cm/qk/iar/qs_port.h | 41 +- ports/arm-cm/qv/armclang/qp_port.h | 19 +- ports/arm-cm/qv/armclang/qs_port.h | 41 +- ports/arm-cm/qv/armclang/qv_port.c | 19 +- ports/arm-cm/qv/gnu/qp_port.h | 19 +- ports/arm-cm/qv/gnu/qs_port.h | 41 +- ports/arm-cm/qv/gnu/qv_port.c | 19 +- ports/arm-cm/qv/iar/qp_port.h | 19 +- ports/arm-cm/qv/iar/qs_port.h | 41 +- ports/arm-cm/qv/iar/qv_port.c | 19 +- ports/arm-cr/config/qp_config.h | 24 +- ports/arm-cr/qk/gnu/qp_port.h | 24 +- ports/arm-cr/qk/gnu/qs_port.h | 41 +- ports/arm-cr/qk/iar/qp_port.h | 24 +- ports/arm-cr/qk/iar/qs_port.h | 41 +- ports/arm-cr/qk/ti/qp_port.h | 24 +- ports/arm-cr/qk/ti/qs_port.h | 41 +- ports/arm-cr/qv/gnu/qp_port.h | 24 +- ports/arm-cr/qv/gnu/qs_port.h | 41 +- ports/arm-cr/qv/iar/qp_port.h | 24 +- ports/arm-cr/qv/iar/qs_port.h | 41 +- ports/arm-cr/qv/ti/qp_port.h | 24 +- ports/arm-cr/qv/ti/qs_port.h | 41 +- ports/config/qp_config.h | 24 +- ports/embos/qf_port.c | 40 +- ports/embos/qp_port.h | 24 +- ports/embos/qs_port.h | 41 +- ports/freertos/qf_port.c | 502 +- ports/freertos/qp_port.h | 26 +- ports/freertos/qs_port.h | 41 +- ports/msp430/qk/qp_port.h | 24 +- ports/msp430/qk/qs_port.h | 41 +- ports/msp430/qutest/qp_port.h | 58 +- ports/msp430/qutest/qs_port.h | 41 +- ports/msp430/qv/qp_port.h | 24 +- ports/msp430/qv/qs_port.h | 41 +- ports/posix-qv/qf_port.c | 46 +- ports/posix-qv/qp_port.h | 31 +- ports/posix-qv/qs_port.c | 39 +- ports/posix-qv/qs_port.h | 41 +- ports/posix-qv/safe_std.h | 5 - ports/posix/qf_port.c | 32 +- ports/posix/qp_port.h | 24 +- ports/posix/qs_port.c | 39 +- ports/posix/qs_port.h | 41 +- ports/posix/safe_std.h | 5 - ports/qep-only/qp_port.h | 24 +- ports/qep-only/safe_std.h | 5 - ports/qube/qp_port.h | 30 +- ports/qube/qs_port.h | 41 +- ports/qube/qube.c | 46 +- ports/qube/safe_std.h | 5 - ports/risc-v/qv/gnu/qp_port.h | 24 +- ports/risc-v/qv/gnu/qs_port.h | 41 +- ports/threadx/qf_port.c | 40 +- ports/threadx/qp_port.h | 28 +- ports/threadx/qs_port.h | 41 +- ports/uc-os2/qf_port.c | 40 +- ports/uc-os2/qp_port.h | 24 +- ports/uc-os2/qs_port.h | 41 +- ports/win32-qv/qf_port.c | 47 +- ports/win32-qv/qp_port.h | 35 +- ports/win32-qv/qs_port.c | 40 +- ports/win32-qv/qs_port.h | 41 +- ports/win32-qv/qwin_gui.c | 38 +- ports/win32-qv/qwin_gui.h | 38 +- ports/win32-qv/safe_std.h | 5 - ports/win32/qf_port.c | 33 +- ports/win32/qp_port.h | 28 +- ports/win32/qs_port.c | 40 +- ports/win32/qs_port.h | 41 +- ports/win32/qwin_gui.c | 38 +- ports/win32/qwin_gui.h | 38 +- ports/win32/safe_std.h | 5 - qpc.qm | 6895 ------------------------- qpc_8.0.1.sha1 | 161 - qpc_8.0.2.sha1 | 162 + qpc_sha1.bat | 15 +- src/qf/qep_hsm.c | 843 ++- src/qf/qep_msm.c | 502 +- src/qf/qf_act.c | 51 +- src/qf/qf_actq.c | 415 +- src/qf/qf_defer.c | 56 +- src/qf/qf_dyn.c | 153 +- src/qf/qf_mem.c | 206 +- src/qf/qf_ps.c | 112 +- src/qf/qf_qact.c | 76 +- src/qf/qf_qeq.c | 193 +- src/qf/qf_qmact.c | 32 +- src/qf/qf_time.c | 352 +- src/qk/qk.c | 285 +- src/qs/qstamp.c | 36 +- src/qv/qv.c | 136 +- zephyr/qf_port.c | 40 +- zephyr/qp_port.h | 24 +- zephyr/qs_port.h | 41 +- 119 files changed, 3209 insertions(+), 12440 deletions(-) delete mode 100644 qpc.qm delete mode 100644 qpc_8.0.1.sha1 create mode 100644 qpc_8.0.2.sha1 diff --git a/LICENSES/LicenseRef-QL-commercial.txt b/LICENSES/LicenseRef-QL-commercial.txt index 259ff1dbd..3765140be 100644 --- a/LICENSES/LicenseRef-QL-commercial.txt +++ b/LICENSES/LicenseRef-QL-commercial.txt @@ -7,7 +7,7 @@ licenses designed for licensees interested in retaining the proprietary status of their code. The Quantum Leaps commercial licenses expressly supersede the GPL open source -license. This means that when you license the QP/C or QP/C++ Real-Time +license. This means that when you license the QP/C or QP/C++ Real-Time Embedded Frameworks under a Quantum Leaps commercial license, you specifically do not use the software under the open source license and therefore you are not subject to any of its terms. @@ -15,8 +15,8 @@ not subject to any of its terms. Quantum Leaps commercial licensing options are described below: -Single Product License ----------------------- +SPDX-License-Identifier: LicenseRef-QL-Single-Product +----------------------------------------------------- Single Product License allows a given company ("Licensee") to embed the specified type(s) of the QP Real-Time Embedded Framework(s) into one end- product of the Licensee (Single Product). Licensee can distribute/sell an @@ -33,8 +33,8 @@ Volume discounts are offered if several Single Products are licensed at once with one license agreement. -Product Line License --------------------- +SPDX-License-Identifier: LicenseRef-QL-Product-Line +--------------------------------------------------- Product Line License allows a given company ("Licensee") to embed the specified type(s) of the QP Real-Time Embedded Framework(s) into any number of end-products within a family of related products (Product Line). Licensee @@ -44,8 +44,8 @@ Product Line. Product Line License applies to all end-products that do similar functions within the same Product Line. -Any-Product License -------------------- +SPDX-License-Identifier: LicenseRef-QL-Any-Product +-------------------------------------------------- Any-Product License allows a given company ("Licensee") to embed the specified type(s) of the QP Real-Time Embedded Framework(s) into any end- product of that company. The Licensee can distribute/sell an unlimited number @@ -53,8 +53,8 @@ of the products containing the licensed QP framework type(s) (royalty-free licensing). -Site License ------------- +SPDX-License-Identifier: LicenseRef-QL-Site +------------------------------------------- Site-License allows a given company ("Licensee") to embed the specified type(s) of the QP Real-Time Embedded Framework(s) into any end-customer product, as long as the products are designed at a given physical location @@ -64,8 +64,8 @@ designed for development contractors and consultants, who develop embedded software for other companies. -OEM License ------------ +SPDX-License-Identifier: LicenseRef-QL-OEM +------------------------------------------ OEM License allows a given company ("Licensee") to embed the specified type(s) of the QP Real-Time Embedded Framework(s) in any product of that company (Original Equipment Manufacturer) and gives limited sublicensing @@ -74,14 +74,12 @@ affiliates. OEM licenses are customizable to match exactly the specific licensing needs of a given Licensee. -Education License ------------------ -Education License allows a given accredited educational institution -("Licensee") to use and embed the specified type(s) of the QP Real-Time -Embedded Framework(s) in any project completed at that educational -institution. To be eligible for this license, the institution must be -focused mainly on teaching students. The Education Licenses are free -and will be granted liberally upon request. +SPDX-License-Identifier: LicenseRef-QL-Eval +------------------------------------------- +Evaluation License allows a specific company ("Licensee") to temporarily +use the specified type(s) of the QP Real-Time Embedded Framework(s) for +in-house evaluation. This license expressly prohibits any distribution +of the licensed QP software. **** diff --git a/LICENSES/LicenseRef-QL-dual.qlc b/LICENSES/LicenseRef-QL-dual.qlc index 85a39e0d1..029c04bf7 100644 --- a/LICENSES/LicenseRef-QL-dual.qlc +++ b/LICENSES/LicenseRef-QL-dual.qlc @@ -1,6 +1,7 @@ public qpc 2025-12-31 + Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. Q u a n t u m L e a P s @@ -9,9 +10,9 @@ Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial -The QP/C software is dual-licensed under the terms of the open-source GNU -General Public License (GPL) or under the terms of one of the closed- -source Quantum Leaps commercial licenses. +This software is dual-licensed under the terms of the open-source GNU +General Public License (GPL) or, alternatively under the terms of one of +the closed-source Quantum Leaps commercial licenses. Redistributions in source code must retain this top-level comment block. Plagiarizing this software to sidestep the license obligations is illegal. @@ -25,4 +26,4 @@ closed-source distribution. Quantum Leaps contact information: -#2BACD81DCE8ED122C193E4F48A14170D660DFF1E \ No newline at end of file +#1671FF5623AF7CA93973FA6EC044A008F7F65702 \ No newline at end of file diff --git a/README.md b/README.md index da336f164..a08302bb0 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,39 @@ git clone https://github.com/QuantumLeaps/qpc --recurse-submodules --depth 1 Alternatively, you can also download one of the stable [QP/C Releases][QP-Rel]. +# About QP/C Real-Time Embedded Framework +QP/C real-time embedded framework (RTEF) is a lightweight implementation of +the [Active Object (a.k.a. Actor) model of computation][AOmod] specifically +tailored for deeply embedded real-time systems, such as microcontrollers (MCUs). +QP/C is both a software infrastructure for building applications consisting +of Active Objects (Actors) and a runtime environment for executing the Active +Objects in a deterministic, real-time fashion. Additionally, QP/C Framework +supports Hierarchical State Machines with which to specify the behavior of +Active Objects [UML 2.5], [Sutter:10], [ROOM:94]. The QP/C Framework can be +viewed as a modern, asynchronous, and truly event driven real-time operating +system (RTOS). + +## QP Framework Family +QP/C framework is part of the larger QP family consisting of the following +QP editions: + +|QP Edition | Language | API | Safety Functions |Certification Artifacts| Licensing +|:----------|:-----------:|:-----------------|:-------------------|:----------------|:--------- +| QP/C | C (C11) |same as SafeQP/C |Selected Assertions |Req/Arch/Design | [dual][Lic] +| SafeQP/C | C (C11) |same as QP/C |All Safety Functions|Certification Kit| [commercial][Com] +| QP/C++ | C++ (C++17) |same as SafeQP/C++|Selected Assertions |Req/Arch/Design | [dual][Lic] +| SafeQP/C++| C++ (C++17) |same as QP/C++ |All Safety Functions|Certification Kit| [commercial][Com] + +[The documentation](#documentation) of all QP editions includes the +[Requirements][SRS], [Architecture][SAS], and [Design Specifications][SDS], +which are the best source of information about the underlying concepts, +functionality, architecture, and design of the QP Frameworks and the QP +Applications based on the frameworks. + +> **NOTE:** The **SafeQP** frameworks additionally contain **Safety Functions** +required to achieve the higher safety integrity levels and come with much more +extensive [Certification Kits][Cert]. + # Getting Started with QP/C The most recommended way of obtaining QP/C is by downloading the @@ -25,7 +58,7 @@ 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] +- ["QP/C Tutorial"][Tut] describes a series of progressively advanced QP/C example applications. - [Video: "Getting Started with QP Real-Time Embedded Frameworks"][Video] @@ -67,69 +100,11 @@ have been **removed from the open-source GPL distribution**: the active Support Term. Please contact [Quantum Leaps technical support][Sup] to get the complete QP/C framework distribution. -> NOTE: To request **evaluation** of the complete QP/C framework, please contact +> **NOTE:** To request **evaluation** of the complete QP/C framework, please contact Quantum Leaps at: https://www.state-machine.com/contact -# 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] -(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 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 -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][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 -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. - -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 -[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 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/...). - -## Traditional RTOS/OS -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, [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 Documentation + +# Documentation The online HTML documentation for the **latest** version of QP/C is located at: https://www.state-machine.com/qpc @@ -159,20 +134,25 @@ If you like this project, please give it a star (in the upper-right corner of yo [QP]: [QP/C]: [QP/C++]: - [QS/C]: - [QV]: - [QK]: - [QXK]: + [Cert]: [QM]: [QTools]: - [QP-Rel]: - [Active]: - [AO_model]: - [Event]: - [HSM]: [Lic]: + [Com]: [Cust]: [Sup]: [AN]: - [Tutorial]: [Video]: + [QS]: + [QV]: + [QK]: + [QXK]: + [SRS]: + [SAS]: + [SDS]: + [Active]: + [AOmod]: + [Event]: + [HSM]: + [QP-Rel]: + [Tut]: diff --git a/examples b/examples index 81a039237..db9e71378 160000 --- a/examples +++ b/examples @@ -1 +1 @@ -Subproject commit 81a03923724160d56faa0096823c941a3601d68e +Subproject commit db9e713786bebe246df77a664080ab7067021659 diff --git a/include/qequeue.h b/include/qequeue.h index cece51b30..44c933f53 100644 --- a/include/qequeue.h +++ b/include/qequeue.h @@ -1,10 +1,6 @@ -//$file${include::qequeue.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// -// Model: qpc.qm -// File: ${include::qequeue.h} -// -// This code has been generated by QM 7.0.0 . -// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // @@ -14,7 +10,7 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -30,8 +26,7 @@ // Quantum Leaps contact information: // // -// -//$endhead${include::qequeue.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//============================================================================ #ifndef QEQUEUE_H_ #define QEQUEUE_H_ @@ -44,69 +39,23 @@ #elif (QF_EQUEUE_CTR_SIZE == 2U) typedef uint16_t QEQueueCtr; #else - #error "QF_EQUEUE_CTR_SIZE defined incorrectly, expected 1U or 2U" + #error QF_EQUEUE_CTR_SIZE defined incorrectly, expected 1U or 2U #endif -struct QEvt; // forward declartion +struct QEvt; // forward declaration -//$declare${QF::QEQueue} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QF::QEQueue} ............................................................. +//============================================================================ //! @class QEQueue typedef struct QEQueue { -// private: - - //! @private @memberof QEQueue - struct QEvt const * volatile frontEvt; - - //! @private @memberof QEQueue - struct QEvt const * * ring; - - //! @private @memberof QEQueue - QEQueueCtr end; - - //! @private @memberof QEQueue - QEQueueCtr volatile head; - - //! @private @memberof QEQueue - QEQueueCtr volatile tail; - - //! @private @memberof QEQueue - QEQueueCtr volatile nFree; - -#ifndef Q_UNSAFE - //! @private @memberof QEQueue - uintptr_t frontEvt_dis; -#endif // ndef Q_UNSAFE - -#ifndef Q_UNSAFE - //! @private @memberof QEQueue - QEQueueCtr head_dis; -#endif // ndef Q_UNSAFE - -#ifndef Q_UNSAFE - //! @private @memberof QEQueue - QEQueueCtr tail_dis; -#endif // ndef Q_UNSAFE - -#ifndef Q_UNSAFE - //! @private @memberof QEQueue - QEQueueCtr nFree_dis; -#endif // ndef Q_UNSAFE - -#ifndef Q_UNSAFE - //! @private @memberof QEQueue - QEQueueCtr nMin; -#endif // ndef Q_UNSAFE - -// type: + struct QEvt const * volatile frontEvt; //!< @private @memberof QEQueue + struct QEvt const * * ring; //!< @private @memberof QEQueue + QEQueueCtr end; //!< @private @memberof QEQueue + QEQueueCtr volatile head; //!< @private @memberof QEQueue + QEQueueCtr volatile tail; //!< @private @memberof QEQueue + QEQueueCtr volatile nFree; //!< @private @memberof QEQueue + QEQueueCtr nMin; //!< @private @memberof QEQueue } QEQueue; -// dummy static member to force generating 'struct QEQueue {...}' -extern QEQueue * QEQueue_dummy; - -// public: - //! @public @memberof QEQueue void QEQueue_init(QEQueue * const me, struct QEvt const * * const qSto, @@ -134,17 +83,12 @@ static inline QEQueueCtr QEQueue_getNFree(QEQueue const * const me) { //! @public @memberof QEQueue static inline QEQueueCtr QEQueue_getNMin(QEQueue const * const me) { - #ifndef Q_UNSAFE return me->nMin; - #else - return 0U; - #endif } //! @public @memberof QEQueue static inline bool QEQueue_isEmpty(QEQueue const * const me) { return me->frontEvt == (struct QEvt *)0; } -//$enddecl${QF::QEQueue} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #endif // QEQUEUE_H_ diff --git a/include/qk.h b/include/qk.h index e563da80c..af2e6e7e3 100644 --- a/include/qk.h +++ b/include/qk.h @@ -1,10 +1,6 @@ -//$file${include::qk.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// -// Model: qpc.qm -// File: ${include::qk.h} -// -// This code has been generated by QM 7.0.0 . -// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // @@ -14,7 +10,7 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -30,114 +26,60 @@ // Quantum Leaps contact information: // // -// -//$endhead${include::qk.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//============================================================================ #ifndef QK_H_ #define QK_H_ -//$declare${QK::QK} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QK::QK} .................................................................. +//============================================================================ //! @class QK typedef struct QK { //! @cond INTERNAL uint8_t dummy; //! @endcond } QK; -//$enddecl${QK::QK} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -//$declare${QK::QSchedStatus} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QK::QSchedStatus} ........................................................ typedef uint_fast8_t QSchedStatus; -//$enddecl${QK::QSchedStatus} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -//$declare${QK::QK-base} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -//${QK::QK-base::Attr} ....................................................... +//============================================================================ //! @class QK_Attr typedef struct { -// private: - - //! @memberof QK_Attr - QPSet readySet; - - //! @memberof QK_Attr - uint_fast8_t actPrio; - - //! @memberof QK_Attr - uint_fast8_t nextPrio; - - //! @memberof QK_Attr - uint_fast8_t actThre; - - //! @memberof QK_Attr - uint_fast8_t lockCeil; - - //! @memberof QK_Attr - uint_fast8_t intNest; - -#ifndef Q_UNSAFE - //! @memberof QK_Attr - QPSet readySet_dis; -#endif // ndef Q_UNSAFE - -#ifndef Q_UNSAFE - //! @memberof QK_Attr - uint_fast8_t actPrio_dis; -#endif // ndef Q_UNSAFE + QPSet readySet; //!< @memberof QK_Attr + uint_fast8_t actPrio; //!< @memberof QK_Attr + uint_fast8_t nextPrio; //!< @memberof QK_Attr + uint_fast8_t actThre; //!< @memberof QK_Attr + uint_fast8_t lockCeil; //!< @memberof QK_Attr + uint_fast8_t intNest; //!< @memberof QK_Attr +} QK_Attr; -#ifndef Q_UNSAFE - //! @memberof QK_Attr - uint_fast8_t nextPrio_dis; -#endif // ndef Q_UNSAFE +//! @static @private @memberof QK +extern QK_Attr QK_priv_; -#ifndef Q_UNSAFE - //! @memberof QK_Attr - uint_fast8_t actThre_dis; -#endif // ndef Q_UNSAFE +//! @static @private @memberof QK +uint_fast8_t QK_sched_(void); -#ifndef Q_UNSAFE - //! @memberof QK_Attr - uint_fast8_t lockCeil_dis; -#endif // ndef Q_UNSAFE -} QK_Attr; +//! @static @private @memberof QK +uint_fast8_t QK_sched_act_( + QActive const * const act, + uint_fast8_t const pthre_in); -//${QK::QK-base::priv_} ...................................................... //! @static @private @memberof QK -extern QK_Attr QK_priv_; +void QK_activate_(void); -//${QK::QK-base::schedLock} .................................................. //! @static @public @memberof QK QSchedStatus QK_schedLock(uint_fast8_t const ceiling); -//${QK::QK-base::schedUnlock} ................................................ //! @static @public @memberof QK void QK_schedUnlock(QSchedStatus const prevCeil); -//${QK::QK-base::onIdle} ..................................................... //! @static @public @memberof QK void QK_onIdle(void); -//${QK::QK-base::sched_} ..................................................... -//! @static @private @memberof QK -uint_fast8_t QK_sched_(void); - -//${QK::QK-base::activate_} .................................................. -//! @static @private @memberof QK -void QK_activate_(void); -//$enddecl${QK::QK-base} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - //============================================================================ // interface used only for internal implementation, but not in applications #ifdef QP_IMPL -//$declare${QK-impl} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QK-impl::QF_SCHED_STAT_} ................................................. +// scheduler locking for QK... #define QF_SCHED_STAT_ QSchedStatus lockStat_; - -//${QK-impl::QF_SCHED_LOCK_} ................................................. #define QF_SCHED_LOCK_(ceil_) do { \ if (QK_ISR_CONTEXT_()) { \ lockStat_ = 0xFFU; \ @@ -146,62 +88,32 @@ void QK_activate_(void); } \ } while (false) -//${QK-impl::QF_SCHED_UNLOCK_} ............................................... #define QF_SCHED_UNLOCK_() do { \ if (lockStat_ != 0xFFU) { \ QK_schedUnlock(lockStat_); \ } \ } while (false) -//${QK-impl::QACTIVE_EQUEUE_WAIT_} ........................................... +// QActive event queue customization for QK... #define QACTIVE_EQUEUE_WAIT_(me_) ((void)0) - -//${QK-impl::QACTIVE_EQUEUE_SIGNAL_} ......................................... -#ifndef Q_UNSAFE #define QACTIVE_EQUEUE_SIGNAL_(me_) do { \ QPSet_insert(&QK_priv_.readySet, (uint_fast8_t)(me_)->prio); \ - QPSet_update_(&QK_priv_.readySet, &QK_priv_.readySet_dis); \ if (!QK_ISR_CONTEXT_()) { \ if (QK_sched_() != 0U) { \ QK_activate_(); \ } \ } \ } while (false) -#endif // ndef Q_UNSAFE -//${QK-impl::QACTIVE_EQUEUE_SIGNAL_} ......................................... -#ifdef Q_UNSAFE -#define QACTIVE_EQUEUE_SIGNAL_(me_) do { \ - QPSet_insert(&QK_priv_.readySet, (uint_fast8_t)(me_)->prio); \ - if (!QK_ISR_CONTEXT_()) { \ - if (QK_sched_() != 0U) { \ - QK_activate_(); \ - } \ - } \ -} while (false) -#endif // def Q_UNSAFE -//$enddecl${QK-impl} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -//$declare${QF_EPOOL-impl} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QF_EPOOL-impl::QF_EPOOL_TYPE_} ........................................... +// QF event pool customization for QK... #define QF_EPOOL_TYPE_ QMPool - -//${QF_EPOOL-impl::QF_EPOOL_INIT_} ........................................... #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) - -//${QF_EPOOL-impl::QF_EPOOL_EVENT_SIZE_} ..................................... #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) - -//${QF_EPOOL-impl::QF_EPOOL_GET_} ............................................ #define QF_EPOOL_GET_(p_, e_, m_, qsId_) \ ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qsId_))) - -//${QF_EPOOL-impl::QF_EPOOL_PUT_} ............................................ #define QF_EPOOL_PUT_(p_, e_, qsId_) \ (QMPool_put(&(p_), (e_), (qsId_))) -//$enddecl${QF_EPOOL-impl} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #endif // QP_IMPL diff --git a/include/qmpool.h b/include/qmpool.h index 0bae35d24..46d93e6b4 100644 --- a/include/qmpool.h +++ b/include/qmpool.h @@ -1,10 +1,6 @@ -//$file${include::qmpool.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// -// Model: qpc.qm -// File: ${include::qmpool.h} -// -// This code has been generated by QM 7.0.0 . -// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // @@ -14,7 +10,7 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -30,8 +26,7 @@ // Quantum Leaps contact information: // // -// -//$endhead${include::qmpool.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//============================================================================ #ifndef QMPOOL_H_ #define QMPOOL_H_ @@ -42,6 +37,11 @@ #define QF_MPOOL_CTR_SIZE 2U #endif +#define QF_MPOOL_EL(evType_) struct { \ + void * sto_[((sizeof(evType_) - 1U) / sizeof(void *)) + \ + (sizeof(evType_) < (2U * sizeof(void *)) ? 2U : 1U)]; \ +} + #if (QF_MPOOL_SIZ_SIZE == 1U) typedef uint8_t QMPoolSize; #elif (QF_MPOOL_SIZ_SIZE == 2U) @@ -49,7 +49,7 @@ #elif (QF_MPOOL_SIZ_SIZE == 4U) typedef uint32_t QMPoolSize; #else - #error "QF_MPOOL_SIZ_SIZE defined incorrectly, expected 1U, 2U, or 4U" + #error QF_MPOOL_SIZ_SIZE defined incorrectly, expected 1U, 2U, or 4U #endif #if (QF_MPOOL_CTR_SIZE == 1U) @@ -59,73 +59,21 @@ #elif (QF_MPOOL_CTR_SIZE == 4U) typedef uint32_t QMPoolCtr; #else - #error "QF_MPOOL_CTR_SIZE defined incorrectly, expected 1U, 2U, or 4U" + #error QF_MPOOL_CTR_SIZE defined incorrectly, expected 1U, 2U, or 4U #endif -#define QF_MPOOL_EL(evType_) struct { \ - QFreeBlock sto_[((sizeof(evType_) - 1U) / (2U * sizeof(void *))) + 1U]; \ -} - -//$declare${QF::QFreeBlock} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QF::QFreeBlock} .......................................................... -//! @struct QFreeBlock -typedef struct QFreeBlock { -// private: - - //! @private @memberof QFreeBlock - struct QFreeBlock * next; - -#ifndef Q_UNSAFE - //! @private @memberof QFreeBlock - uintptr_t next_dis; -#endif // ndef Q_UNSAFE -} QFreeBlock; -//$enddecl${QF::QFreeBlock} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -//$declare${QF::QMPool} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QF::QMPool} .............................................................. +//============================================================================ //! @class QMPool typedef struct { -// private: - - //! @private @memberof QMPool - QFreeBlock * start; - - //! @private @memberof QMPool - QFreeBlock * end; - - //! @private @memberof QMPool - QFreeBlock * volatile free_head; - - //! @private @memberof QMPool - QMPoolSize blockSize; - - //! @private @memberof QMPool - QMPoolCtr nTot; - - //! @private @memberof QMPool - QMPoolCtr volatile nFree; - -#ifndef Q_UNSAFE - //! @private @memberof QMPool - QMPoolCtr nMin; -#endif // ndef Q_UNSAFE - -#ifndef Q_UNSAFE - //! @private @memberof QMPool - uintptr_t free_head_dis; -#endif // ndef Q_UNSAFE - -#ifndef Q_UNSAFE - //! @private @memberof QMPool - QMPoolCtr nFree_dis; -#endif // ndef Q_UNSAFE + void * * start; //!< @private @memberof QMPool + void * * end; //!< @private @memberof QMPool + void * * volatile freeHead; //!< @private @memberof QMPool + QMPoolSize blockSize; //!< @private @memberof QMPool + QMPoolCtr nTot; //!< @private @memberof QMPool + QMPoolCtr volatile nFree; //!< @private @memberof QMPool + QMPoolCtr nMin; //!< @private @memberof QMPool } QMPool; -// public: - //! @public @memberof QMPool void QMPool_init(QMPool * const me, void * const poolSto, @@ -141,6 +89,5 @@ void * QMPool_get(QMPool * const me, void QMPool_put(QMPool * const me, void * const block, uint_fast8_t const qsId); -//$enddecl${QF::QMPool} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #endif // QMPOOL_H_ diff --git a/include/qp.h b/include/qp.h index 43197a724..b91fd27d4 100644 --- a/include/qp.h +++ b/include/qp.h @@ -1,10 +1,6 @@ -//$file${include::qp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// -// Model: qpc.qm -// File: ${include::qp.h} -// -// This code has been generated by QM 7.0.0 . -// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // @@ -14,7 +10,7 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -30,17 +26,18 @@ // Quantum Leaps contact information: // // -// -//$endhead${include::qp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//============================================================================ #ifndef QP_H_ #define QP_H_ //============================================================================ -#define QP_VERSION_STR "8.0.1" -#define QP_VERSION 801U -#define QP_RELEASE 0x703931CEU +#define QP_VERSION_STR "8.0.2" +#define QP_VERSION 802U +// =802 =250120 +#define QP_RELEASE 0x6AEAB45DU //============================================================================ +// default configuration settings //! @cond INTERNAL #ifndef Q_SIGNAL_SIZE @@ -88,143 +85,72 @@ #endif //! @endcond -//============================================================================ - -//$declare${glob-types} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${glob-types::int_t} ....................................................... -typedef int int_t; -//${glob-types::enum_t} ...................................................... -typedef int enum_t; - -//${glob-types::float32_t} ................................................... -typedef float float32_t; +//============================================================================ +// global types/utilities -//${glob-types::float64_t} ................................................... +typedef int int_t; +typedef int enum_t; +typedef float float32_t; typedef double float64_t; -//$enddecl${glob-types} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -//$declare${QEP} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +#define Q_UNUSED_PAR(par_) ((void)(par_)) +#define Q_DIM(array_) (sizeof(array_) / sizeof((array_)[0U])) +#define Q_UINT2PTR_CAST(type_, uint_) ((type_ *)(uint_)) -//${QEP::QP_versionStr[16]} .................................................. -//! the current QP version number string in ROM, based on #QP_VERSION_STR -extern char const QP_versionStr[16]; +//============================================================================ +extern char const QP_versionStr[24]; -//${QEP::QSignal} ............................................................ +// QSignal type #if (Q_SIGNAL_SIZE == 1U) -typedef uint8_t QSignal; -#endif // (Q_SIGNAL_SIZE == 1U) - -//${QEP::QSignal} ............................................................ -#if (Q_SIGNAL_SIZE == 2U) -typedef uint16_t QSignal; -#endif // (Q_SIGNAL_SIZE == 2U) - -//${QEP::QSignal} ............................................................ -#if (Q_SIGNAL_SIZE == 4U) -typedef uint32_t QSignal; -#endif // (Q_SIGNAL_SIZE == 4U) + typedef uint8_t QSignal; +#elif (Q_SIGNAL_SIZE == 2U) + typedef uint16_t QSignal; +#elif (Q_SIGNAL_SIZE == 4U) + typedef uint32_t QSignal; +#endif -//${QEP::QEvt} ............................................................... +//============================================================================ //! @class QEvt typedef struct QEvt { -// public: - - //! @public @memberof QEvt - QSignal sig; - -// private: - - //! @private @memberof QEvt - uint8_t evtTag_; - - //! @private @memberof QEvt - uint8_t volatile refCtr_; + QSignal sig; //!< @public @memberof QEvt + uint8_t poolNum_; //!< @private @memberof QEvt + uint8_t volatile refCtr_; //!< @private @memberof QEvt } QEvt; -extern QEvt const QEvt_reserved_[4]; - -// public: - +#define QEVT_INITIALIZER(sig_) { (QSignal)(sig_), 0x00U, 0xE0U } //! @public @memberof QEvt static inline void QEvt_ctor(QEvt * const me, enum_t const sig) { - me->sig = (QSignal)sig; - me->evtTag_ = 0x0FU; - me->refCtr_ = 0U; + me->sig = (QSignal)sig; + me->poolNum_ = 0x00U; + me->refCtr_ = 0xE0U; } //! @public @memberof QEvt static inline QEvt * QEvt_init(QEvt * const me, - uint8_t dummy) + uint8_t const dummy) { - (void)dummy; + Q_UNUSED_PAR(dummy); return me; } -// private: - -#ifndef Q_UNSAFE -//! @private @memberof QEvt -static inline bool QEvt_verify_(QEvt const * const me) { - uint8_t rc = me->refCtr_; - return (rc <= 2U*QF_MAX_ACTIVE) - && (((me->evtTag_ ^ rc) & 0x0FU) == 0x0FU); -} -#endif // ndef Q_UNSAFE - -//! @private @memberof QEvt -static inline uint_fast8_t QEvt_getPoolNum_(QEvt const * const me) { - return (uint_fast8_t)(me->evtTag_ >> 4U); -} - -//${QEP::QStateRet} .......................................................... -//! All possible values returned from state/action handlers -//! @note -//! The order of enumeration matters for algorithmic correctness. -enum QStateRet { - // unhandled and need to "bubble up" - Q_RET_SUPER, //!< event passed to superstate to handle - Q_RET_UNHANDLED, //!< event unhandled due to guard - - // handled and do not need to "bubble up" - Q_RET_HANDLED, //!< event handled (internal transition) - Q_RET_IGNORED, //!< event silently ignored (bubbled up to top) - - // entry/exit - Q_RET_ENTRY, //!< state entry action executed - Q_RET_EXIT, //!< state exit action executed - - // no side effects - Q_RET_NULL, //!< return value without any effect - - // transitions need to execute transition-action table in ::QMsm - Q_RET_TRAN, //!< regular transition - Q_RET_TRAN_INIT, //!< initial transition in a state - - // transitions that additionally clobber me->state - Q_RET_TRAN_HIST, //!< transition to history of a given state -}; - -//${QEP::QState} ............................................................. -typedef enum QStateRet QState; +typedef QEvt const * QEvtPtr; -//${QEP::QStateHandler} ...................................................... -typedef QState (* QStateHandler )(void * const me, QEvt const * const e); +#define QEVT_DYNAMIC ((uint8_t)0) +#define Q_EVT_CAST(class_) ((class_ const *)(e)) -//${QEP::QActionHandler} ..................................................... -typedef QState (* QActionHandler )(void * const me); +//============================================================================ +// QEP (hierarchical event processor) types -//${QEP::QXThread} ........................................................... -// forward declaration -struct QXThread; +typedef uint_fast8_t QState; +typedef QState (*QStateHandler)(void * const me, QEvt const * const e); +typedef QState (*QActionHandler)(void * const me); -//${QEP::QXThreadHandler} .................................................... +struct QXThread; // forward declarsation typedef void (* QXThreadHandler )(struct QXThread * const me); -//${QEP::QMState} ............................................................ typedef struct QMState { struct QMState const *superstate; //!< @private @memberof QMState QStateHandler const stateHandler; //!< @private @memberof QMState @@ -233,75 +159,106 @@ typedef struct QMState { QActionHandler const initAction; //!< @private @memberof QMState } QMState; -//${QEP::QMTranActTable} ..................................................... typedef struct QMTranActTable { - QMState const *target; //!< @private @memberof QMTranActTable - QActionHandler const act[1]; //!< @private @memberof QMTranActTable + QMState const *target; //!< @private @memberof QMTranActTable + QActionHandler const act[1]; //!< @private @memberof QMTranActTable } QMTranActTable; -//${QEP::QAsmAttr} ........................................................... union QAsmAttr { - QStateHandler fun; //!< @private @memberof QAsmAttr - QActionHandler act; //!< @private @memberof QAsmAttr - QXThreadHandler thr; //!< @private @memberof QAsmAttr - QMTranActTable const *tatbl; //!< @private @memberof QAsmAttr - struct QMState const *obj; //!< @private @memberof QAsmAttr -#ifndef Q_UNSAFE - uintptr_t uint; //!< @private @memberof QAsmAttr -#endif + QStateHandler fun; //!< @private @memberof QAsmAttr + QActionHandler act; //!< @private @memberof QAsmAttr + QXThreadHandler thr; //!< @private @memberof QAsmAttr + QMTranActTable const *tatbl; //!< @private @memberof QAsmAttr + struct QMState const *obj; //!< @private @memberof QAsmAttr }; -//${QEP::QAsm} ............................................................... +#define Q_STATE_CAST(handler_) ((QStateHandler)(handler_)) +#define Q_ACTION_CAST(action_) ((QActionHandler)(action_)) +#define Q_ACTION_NULL ((QActionHandler)0) + +//============================================================================ //! @class QAsm typedef struct { -// private: + struct QAsmVtable const * vptr; //!< @protected @memberof QAsm + union QAsmAttr state; //!< @protected @memberof QAsm + union QAsmAttr temp; //!< @protected @memberof QAsm +} QAsm; - //! @protected @memberof QAsm - struct QAsmVtable const * vptr; +// All possible values returned from state/action handlers +// NOTE: The ordering is important for algorithmic correctness. +#define Q_RET_SUPER ((QState)0U) +#define Q_RET_UNHANDLED ((QState)1U) -// protected: +// handled and do not need to "bubble up" +#define Q_RET_HANDLED ((QState)2U) +#define Q_RET_IGNORED ((QState)3U) - //! @protected @memberof QAsm - union QAsmAttr state; +// entry/exit +#define Q_RET_ENTRY ((QState)4U) +#define Q_RET_EXIT ((QState)5U) - //! @protected @memberof QAsm - union QAsmAttr temp; -} QAsm; +// no side effects +#define Q_RET_NULL ((QState)6U) + +// transitions need to execute transition-action table in ::QMsm +#define Q_RET_TRAN ((QState)7U) +#define Q_RET_TRAN_INIT ((QState)8U) -// protected: +// transitions that additionally clobber me->state +#define Q_RET_TRAN_HIST ((QState)9U) + +// Reserved signals by the QP-framework. +#define Q_EMPTY_SIG ((QSignal)0U) +#define Q_ENTRY_SIG ((QSignal)1U) +#define Q_EXIT_SIG ((QSignal)2U) +#define Q_INIT_SIG ((QSignal)3U) +#define Q_USER_SIG ((enum_t)4) //! @protected @memberof QAsm -void QAsm_ctor(QAsm * const me); +static inline void QAsm_ctor(QAsm * const me) { + me->vptr = (struct QAsmVtable *)0; + me->state.fun = (QStateHandler)0; + me->temp.fun = (QStateHandler)0; +} -//${QEP::QAsmVtable} ......................................................... struct QAsmVtable { void (*init)(QAsm * const me, void const * const e, uint_fast8_t const qsId); void (*dispatch)(QAsm * const me, QEvt const * const e, uint_fast8_t const qsId); bool (*isIn)(QAsm * const me, QStateHandler const s); - #ifdef Q_SPY QStateHandler (*getStateHandler)(QAsm * const me); #endif // Q_SPY }; -//${QEP::QHsm} ............................................................... +#ifdef Q_SPY + #define QASM_INIT(me_, par_, qsId_) \ + (*((QAsm *)(me_))->vptr->init)((QAsm *)(me_), (par_), (qsId_)) + #define QASM_DISPATCH(me_, e_, qsId_) \ + (*((QAsm *)(me_))->vptr->dispatch)((QAsm *)(me_), (e_), (qsId_)) + #define QASM_IS_IN(me_, state_) \ + (*((QAsm *)(me_))->vptr->isIn)((QAsm *)(me_), (state_)) +#else + #define QASM_INIT(me_, par_, dummy) \ + (*((QAsm *)(me_))->vptr->init)((QAsm *)(me_), (par_), 0U) + #define QASM_DISPATCH(me_, e_, dummy) \ + (*((QAsm *)(me_))->vptr->dispatch)((QAsm *)(me_), (e_), 0U) +#endif // ndef Q_SPY + +#define Q_ASM_UPCAST(ptr_) ((QAsm *)(ptr_)) + +//============================================================================ //! @class QHsm //! @extends QAsm typedef struct { -// protected: - QAsm super; + QAsm super; //!< @protected @memberof QHsm } QHsm; -// protected: - //! @protected @memberof QHsm void QHsm_ctor(QHsm * const me, QStateHandler const initial); -// private: - //! @private @memberof QHsm void QHsm_init_( QAsm * const me, @@ -314,17 +271,19 @@ void QHsm_dispatch_( QEvt const * const e, uint_fast8_t const qsId); +//! @private @memberof QHsm +bool QHsm_isIn_( + QAsm * const me, + QStateHandler const state); + #ifdef Q_SPY //! @private @memberof QHsm QStateHandler QHsm_getStateHandler_(QAsm * const me); #endif // def Q_SPY -// public: - -//! @private @memberof QHsm -bool QHsm_isIn_( - QAsm * const me, - QStateHandler const state); +//! @protected @memberof QHsm +QState QHsm_top(QHsm const * const me, + QEvt const * const e); //! @public @memberof QHsm static inline QStateHandler QHsm_state(QHsm const * const me) { @@ -335,64 +294,53 @@ static inline QStateHandler QHsm_state(QHsm const * const me) { QStateHandler QHsm_childState(QHsm * const me, QStateHandler const parent); -// private: - -//! @private @memberof QHsm -int_fast8_t QHsm_tran_( - QAsm * const me, - QStateHandler * const path, - uint_fast8_t const qsId); - -// protected: +#define Q_HSM_UPCAST(ptr_) ((QHsm *)(ptr_)) -//! @protected @memberof QAsm -QState QHsm_top(QHsm const * const me, - QEvt const * const e); +#define Q_TRAN(target_) \ + ((Q_ASM_UPCAST(me))->temp.fun = Q_STATE_CAST(target_), \ + (QState)Q_RET_TRAN) +#define Q_TRAN_HIST(hist_) \ + ((Q_ASM_UPCAST(me))->temp.fun = (hist_), \ + (QState)Q_RET_TRAN_HIST) +#define Q_SUPER(super_) \ + ((Q_ASM_UPCAST(me))->temp.fun = Q_STATE_CAST(super_), \ + (QState)Q_RET_SUPER) +#define Q_HANDLED() ((QState)Q_RET_HANDLED) +#define Q_UNHANDLED() ((QState)Q_RET_UNHANDLED) -//${QEP::QMsm} ............................................................... +//============================================================================ //! @class QMsm //! @extends QAsm typedef struct { -// protected: - QAsm super; + QAsm super; //!< @protected @memberof QMsm } QMsm; -// protected: - //! @protected @memberof QMsm void QMsm_ctor(QMsm * const me, QStateHandler const initial); -// public: - //! @private @memberof QMsm void QMsm_init_( QAsm * const me, void const * const e, uint_fast8_t const qsId); -// private: - //! @private @memberof QMsm void QMsm_dispatch_( QAsm * const me, QEvt const * const e, uint_fast8_t const qsId); -// public: - -#ifdef Q_SPY -//! @public @memberof QMsm -static inline QStateHandler QMsm_getStateHandler_(QAsm * const me) { - return me->state.obj->stateHandler; -} -#endif // def Q_SPY - //! @private @memberof QMsm bool QMsm_isIn_( QAsm * const me, QStateHandler const state); +#ifdef Q_SPY +//! @public @memberof QMsm +QStateHandler QMsm_getStateHandler_(QAsm * const me); +#endif // def Q_SPY + //! @public @memberof QMsm static inline QMState const * QMsm_stateObj(QMsm const * const me) { return me->super.state.obj; @@ -401,413 +349,177 @@ static inline QMState const * QMsm_stateObj(QMsm const * const me) { //! @public @memberof QMsm QMState const * QMsm_childStateObj(QMsm const * const me, QMState const * const parent); +//============================================================================ +// QEP-macros -// private: - -//! @private @memberof QMsm -QState QMsm_execTatbl_( - QAsm * const me, - QMTranActTable const * const tatbl, - uint_fast8_t const qsId); - -//! @private @memberof QMsm -void QMsm_exitToTranSource_( - QAsm * const me, - QMState const * const cs, - QMState const * const ts, - uint_fast8_t const qsId); - -//! @private @memberof QMsm -QState QMsm_enterHistory_( - QAsm * const me, - QMState const *const hist, - uint_fast8_t const qsId); -//$enddecl${QEP} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -//$declare${QEP-macros} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QEP-macros::QEVT_INITIALIZER} ............................................ -#define QEVT_INITIALIZER(sig_) { (QSignal)(sig_), 0x01U, 0x0EU } - -//${QEP-macros::QEVT_DYNAMIC} ................................................ -#define QEVT_DYNAMIC ((uint8_t)0) - -//${QEP-macros::QASM_INIT} ................................................... -#ifdef Q_SPY -#define QASM_INIT(me_, par_, qsId_) \ - (*((QAsm *)(me_))->vptr->init)((QAsm *)(me_), (par_), (qsId_)) -#endif // def Q_SPY - -//${QEP-macros::QASM_INIT} ................................................... -#ifndef Q_SPY -#define QASM_INIT(me_, par_, dummy) \ - (*((QAsm *)(me_))->vptr->init)((QAsm *)(me_), (par_), 0U) -#endif // ndef Q_SPY - -//${QEP-macros::QASM_DISPATCH} ............................................... -#ifdef Q_SPY -#define QASM_DISPATCH(me_, e_, qsId_) \ - (*((QAsm *)(me_))->vptr->dispatch)((QAsm *)(me_), (e_), (qsId_)) -#endif // def Q_SPY - -//${QEP-macros::QASM_DISPATCH} ............................................... -#ifndef Q_SPY -#define QASM_DISPATCH(me_, e_, dummy) \ - (*((QAsm *)(me_))->vptr->dispatch)((QAsm *)(me_), (e_), 0U) -#endif // ndef Q_SPY - -//${QEP-macros::QASM_IS_IN} .................................................. -#define QASM_IS_IN(me_, state_) \ - (*((QAsm *)(me_))->vptr->isIn)((QAsm *)(me_), (state_)) - -//${QEP-macros::Q_ASM_UPCAST} ................................................ -#define Q_ASM_UPCAST(ptr_) ((QAsm *)(ptr_)) - -//${QEP-macros::Q_HSM_UPCAST} ................................................ -#define Q_HSM_UPCAST(ptr_) ((QHsm *)(ptr_)) - -//${QEP-macros::Q_MSM_UPCAST} ................................................ #define Q_MSM_UPCAST(ptr_) ((QMsm *)(ptr_)) - -//${QEP-macros::Q_EMPTY_SIG} ................................................. -#define Q_EMPTY_SIG ((QSignal)0) - -//${QEP-macros::Q_ENTRY_SIG} ................................................. -#define Q_ENTRY_SIG ((QSignal)1) - -//${QEP-macros::Q_EXIT_SIG} .................................................. -#define Q_EXIT_SIG ((QSignal)2) - -//${QEP-macros::Q_INIT_SIG} .................................................. -#define Q_INIT_SIG ((QSignal)3) - -//${QEP-macros::Q_USER_SIG} .................................................. -#define Q_USER_SIG ((enum_t)4) - -//${QEP-macros::Q_TRAN} ...................................................... -#define Q_TRAN(target_) \ - ((Q_ASM_UPCAST(me))->temp.fun = Q_STATE_CAST(target_), \ - (QState)Q_RET_TRAN) - -//${QEP-macros::Q_TRAN_HIST} ................................................. -#define Q_TRAN_HIST(hist_) \ - ((Q_ASM_UPCAST(me))->temp.fun = (hist_), \ - (QState)Q_RET_TRAN_HIST) - -//${QEP-macros::Q_SUPER} ..................................................... -#define Q_SUPER(super_) \ - ((Q_ASM_UPCAST(me))->temp.fun = Q_STATE_CAST(super_), \ - (QState)Q_RET_SUPER) - -//${QEP-macros::Q_HANDLED} ................................................... -#define Q_HANDLED() ((QState)Q_RET_HANDLED) - -//${QEP-macros::Q_UNHANDLED} ................................................. -#define Q_UNHANDLED() ((QState)Q_RET_UNHANDLED) - -//${QEP-macros::Q_ACTION_NULL} ............................................... -#define Q_ACTION_NULL ((QActionHandler)0) - -//${QEP-macros::Q_EVT_CAST} .................................................. -#define Q_EVT_CAST(class_) ((class_ const *)(e)) - -//${QEP-macros::Q_STATE_CAST} ................................................ -#define Q_STATE_CAST(handler_) ((QStateHandler)(handler_)) - -//${QEP-macros::Q_ACTION_CAST} ............................................... -#define Q_ACTION_CAST(action_) ((QActionHandler)(action_)) - -//${QEP-macros::Q_UNUSED_PAR} ................................................ -#define Q_UNUSED_PAR(par_) ((void)(par_)) - -//${QEP-macros::Q_DIM} ....................................................... -#define Q_DIM(array_) (sizeof(array_) / sizeof((array_)[0U])) - -//${QEP-macros::Q_UINT2PTR_CAST} ............................................. -#define Q_UINT2PTR_CAST(type_, uint_) ((type_ *)(uint_)) - -//${QEP-macros::QM_ENTRY} .................................................... #ifdef Q_SPY -#define QM_ENTRY(state_) \ - ((Q_ASM_UPCAST(me))->temp.obj = (state_), \ - (QState)Q_RET_ENTRY) -#endif // def Q_SPY - -//${QEP-macros::QM_ENTRY} .................................................... -#ifndef Q_SPY -#define QM_ENTRY(dummy) ((QState)Q_RET_ENTRY) + #define QM_ENTRY(state_) \ + ((Q_ASM_UPCAST(me))->temp.obj = (state_), (QState)Q_RET_ENTRY) + #define QM_EXIT(state_) \ + ((Q_ASM_UPCAST(me))->temp.obj = (state_), (QState)Q_RET_EXIT) +#else + #define QM_ENTRY(dummy) ((QState)Q_RET_ENTRY) + #define QM_EXIT(dummy) ((QState)Q_RET_EXIT) #endif // ndef Q_SPY -//${QEP-macros::QM_EXIT} ..................................................... -#ifdef Q_SPY -#define QM_EXIT(state_) \ - ((Q_ASM_UPCAST(me))->temp.obj = (state_), \ - (QState)Q_RET_EXIT) -#endif // def Q_SPY - -//${QEP-macros::QM_EXIT} ..................................................... -#ifndef Q_SPY -#define QM_EXIT(dummy) ((QState)Q_RET_EXIT) -#endif // ndef Q_SPY - -//${QEP-macros::QM_SM_EXIT} .................................................. -#define QM_SM_EXIT(state_) \ - ((Q_ASM_UPCAST(me))->temp.obj = (state_), \ - (QState)Q_RET_EXIT) - -//${QEP-macros::QM_TRAN} ..................................................... #define QM_TRAN(tatbl_) ((Q_ASM_UPCAST(me))->temp.tatbl \ - = (struct QMTranActTable const *)(tatbl_), \ - (QState)Q_RET_TRAN) + = (struct QMTranActTable const *)(tatbl_), (QState)Q_RET_TRAN) -//${QEP-macros::QM_TRAN_INIT} ................................................ #define QM_TRAN_INIT(tatbl_) ((Q_ASM_UPCAST(me))->temp.tatbl \ - = (struct QMTranActTable const *)(tatbl_), \ - (QState)Q_RET_TRAN_INIT) + = (struct QMTranActTable const *)(tatbl_), (QState)Q_RET_TRAN_INIT) -//${QEP-macros::QM_TRAN_HIST} ................................................ #define QM_TRAN_HIST(history_, tatbl_) \ ((((Q_ASM_UPCAST(me))->state.obj = (history_)), \ ((Q_ASM_UPCAST(me))->temp.tatbl = \ - (struct QMTranActTable const *)(tatbl_))), \ - (QState)Q_RET_TRAN_HIST) + (struct QMTranActTable const *)(tatbl_))), (QState)Q_RET_TRAN_HIST) -//${QEP-macros::QM_HANDLED} .................................................. -#define QM_HANDLED() ((QState)Q_RET_HANDLED) - -//${QEP-macros::QM_UNHANDLED} ................................................ +#define QM_HANDLED() ((QState)Q_RET_HANDLED) #define QM_UNHANDLED() ((QState)Q_RET_UNHANDLED) +#define QM_SUPER() ((QState)Q_RET_SUPER) +#define QM_STATE_NULL ((QMState *)0) -//${QEP-macros::QM_SUPER} .................................................... -#define QM_SUPER() ((QState)Q_RET_SUPER) - -//${QEP-macros::QM_STATE_NULL} ............................................... -#define QM_STATE_NULL ((QMState *)0) -//$enddecl${QEP-macros} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -//$declare${QF::types} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +//============================================================================ +// QF (active object framework) types -//${QF::types::QPrioSpec} .................................................... typedef uint16_t QPrioSpec; -//${QF::types::QTimeEvtCtr} .................................................. #if (QF_TIMEEVT_CTR_SIZE == 1U) -typedef uint8_t QTimeEvtCtr; -#endif // (QF_TIMEEVT_CTR_SIZE == 1U) - -//${QF::types::QTimeEvtCtr} .................................................. -#if (QF_TIMEEVT_CTR_SIZE == 2U) -typedef uint16_t QTimeEvtCtr; -#endif // (QF_TIMEEVT_CTR_SIZE == 2U) + typedef uint8_t QTimeEvtCtr; +#elif (QF_TIMEEVT_CTR_SIZE == 2U) + typedef uint16_t QTimeEvtCtr; +#elif (QF_TIMEEVT_CTR_SIZE == 4U) + typedef uint32_t QTimeEvtCtr; +#endif // (QF_TIMEEVT_CTR_SIZE == 4U) -//${QF::types::QTimeEvtCtr} .................................................. -#if (QF_TIMEEVT_CTR_SIZE == 4U) -typedef uint32_t QTimeEvtCtr; -#endif // (QF_TIMEEVT_CTR_SIZE == 4U) - -//${QF::types::QPSetBits} .................................................... #if (QF_MAX_ACTIVE <= 8U) -typedef uint8_t QPSetBits; -#endif // (QF_MAX_ACTIVE <= 8U) - -//${QF::types::QPSetBits} .................................................... -#if (8U < QF_MAX_ACTIVE) && (QF_MAX_ACTIVE <= 16U) -typedef uint16_t QPSetBits; -#endif // (8U < QF_MAX_ACTIVE) && (QF_MAX_ACTIVE <= 16U) + typedef uint8_t QPSetBits; +#elif (8U < QF_MAX_ACTIVE) && (QF_MAX_ACTIVE <= 16U) + typedef uint16_t QPSetBits; +#elif (16U < QF_MAX_ACTIVE) + typedef uint32_t QPSetBits; +#endif // (16U < QF_MAX_ACTIVE) -//${QF::types::QPSetBits} .................................................... -#if (16U < QF_MAX_ACTIVE) -typedef uint32_t QPSetBits; -#endif // (16U < QF_MAX_ACTIVE) - -//${QF::types::QF_LOG2} ...................................................... #ifndef QF_LOG2 -uint_fast8_t QF_LOG2(QPSetBits const bitmask); + uint_fast8_t QF_LOG2(QPSetBits const bitmask); #endif // ndef QF_LOG2 -//${QF::types::QPSet} ........................................................ +//============================================================================ //! @class QPSet typedef struct { -// private: - //! @private @memberof QPSet - QPSetBits bits[((QF_MAX_ACTIVE + (8U*sizeof(QPSetBits))) - 1U)/(8U*sizeof(QPSetBits))]; + QPSetBits bits[((QF_MAX_ACTIVE + (8U*sizeof(QPSetBits))) - 1U) + / (8U*sizeof(QPSetBits))]; } QPSet; -// public: - //! @public @memberof QPSet static inline void QPSet_setEmpty(QPSet * const me) { me->bits[0] = 0U; - #if (QF_MAX_ACTIVE > 32) +#if (QF_MAX_ACTIVE > 32) me->bits[1] = 0U; - #endif +#endif } //! @public @memberof QPSet static inline bool QPSet_isEmpty(QPSet const * const me) { - #if (QF_MAX_ACTIVE <= 32U) +#if (QF_MAX_ACTIVE <= 32U) return (me->bits[0] == 0U); - #else +#else return (me->bits[0] == 0U) ? (me->bits[1] == 0U) : false; - #endif +#endif } //! @public @memberof QPSet static inline bool QPSet_notEmpty(QPSet const * const me) { - #if (QF_MAX_ACTIVE <= 32U) +#if (QF_MAX_ACTIVE <= 32U) return (me->bits[0] != 0U); - #else +#else return (me->bits[0] != 0U) ? true : (me->bits[1] != 0U); - #endif +#endif } //! @public @memberof QPSet static inline bool QPSet_hasElement(QPSet const * const me, uint_fast8_t const n) { - #if (QF_MAX_ACTIVE <= 32U) +#if (QF_MAX_ACTIVE <= 32U) return (me->bits[0] & ((QPSetBits)1U << (n - 1U))) != 0U; - #else +#else return (n <= 32U) ? ((me->bits[0] & ((QPSetBits)1U << (n - 1U))) != 0U) : ((me->bits[1] & ((QPSetBits)1U << (n - 33U))) != 0U); - #endif +#endif } //! @public @memberof QPSet static inline void QPSet_insert(QPSet * const me, uint_fast8_t const n) { - #if (QF_MAX_ACTIVE <= 32U) +#if (QF_MAX_ACTIVE <= 32U) me->bits[0] = (me->bits[0] | ((QPSetBits)1U << (n - 1U))); - #else +#else if (n <= 32U) { me->bits[0] = (me->bits[0] | ((QPSetBits)1U << (n - 1U))); } else { me->bits[1] = (me->bits[1] | ((QPSetBits)1U << (n - 33U))); } - #endif +#endif } //! @public @memberof QPSet static inline void QPSet_remove(QPSet * const me, uint_fast8_t const n) { - #if (QF_MAX_ACTIVE <= 32U) +#if (QF_MAX_ACTIVE <= 32U) me->bits[0] = (me->bits[0] & (QPSetBits)(~((QPSetBits)1U << (n - 1U)))); - #else +#else if (n <= 32U) { (me->bits[0] = (me->bits[0] & ~((QPSetBits)1U << (n - 1U)))); } else { (me->bits[1] = (me->bits[1] & ~((QPSetBits)1U << (n - 33U)))); } - #endif +#endif } //! @public @memberof QPSet static inline uint_fast8_t QPSet_findMax(QPSet const * const me) { - #if (QF_MAX_ACTIVE <= 32U) +#if (QF_MAX_ACTIVE <= 32U) return QF_LOG2(me->bits[0]); - #else +#else return (me->bits[1] != 0U) ? (QF_LOG2(me->bits[1]) + 32U) : (QF_LOG2(me->bits[0])); - #endif -} - -// private: - -#ifndef Q_UNSAFE -//! @private @memberof QPSet -static inline void QPSet_update_(QPSet const * const me, - QPSet * const dis) -{ - dis->bits[0] = ~me->bits[0]; - #if (QF_MAX_ACTIVE > 32U) - dis->bits[1] = ~me->bits[1]; - #endif -} -#endif // ndef Q_UNSAFE - -#ifndef Q_UNSAFE -//! @private @memberof QPSet -static inline bool QPSet_verify_(QPSet const * const me, - QPSet const * const dis) -{ - #if (QF_MAX_ACTIVE <= 32U) - return me->bits[0] == (QPSetBits)(~dis->bits[0]); - #else - return (me->bits[0] == (QPSetBits)(~dis->bits[0])) - && (me->bits[1] == (QPSetBits)(~dis->bits[1])); - #endif +#endif } -#endif // ndef Q_UNSAFE -//${QF::types::QSubscrList} .................................................. //! @struct QSubscrList typedef struct { -// private: - - //! @private @memberof QSubscrList - QPSet set; - -#ifndef Q_UNSAFE - //! @private @memberof QSubscrList - QPSet set_dis; -#endif // ndef Q_UNSAFE + QPSet set; //!< @private @memberof QSubscrList } QSubscrList; -//${QF::types::QEvtPtr} ...................................................... -typedef QEvt const * QEvtPtr; - -//${QF::types::QEQueue} ...................................................... -struct QEQueue; -//$enddecl${QF::types} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -//$declare${QF::QActive} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +struct QEQueue; // forward declaration -//${QF::QActive} ............................................................. +//============================================================================ //! @class QActive //! @extends QAsm typedef struct QActive { -// protected: - QAsm super; - - //! @protected @memberof QActive - uint8_t prio; - - //! @protected @memberof QActive - uint8_t pthre; + QAsm super; //!< @protected @memberof QActive + uint8_t prio; //!< @protected @memberof QActive + uint8_t pthre; //!< @protected @memberof QActive #ifdef QACTIVE_THREAD_TYPE - //! @protected @memberof QActive - QACTIVE_THREAD_TYPE thread; + QACTIVE_THREAD_TYPE thread; //!< @protected @memberof QActive #endif // def QACTIVE_THREAD_TYPE #ifdef QACTIVE_OS_OBJ_TYPE - //! @protected @memberof QActive - QACTIVE_OS_OBJ_TYPE osObject; + QACTIVE_OS_OBJ_TYPE osObject; //!< @protected @memberof QActive #endif // def QACTIVE_OS_OBJ_TYPE #ifdef QACTIVE_EQUEUE_TYPE - //! @protected @memberof QActive - QACTIVE_EQUEUE_TYPE eQueue; + QACTIVE_EQUEUE_TYPE eQueue; //!< @protected @memberof QActive #endif // def QACTIVE_EQUEUE_TYPE - -#ifndef Q_UNSAFE - //! @protected @memberof QActive - uint8_t prio_dis; -#endif // ndef Q_UNSAFE - -#ifndef Q_UNSAFE - //! @protected @memberof QActive - uint8_t pthre_dis; -#endif // ndef Q_UNSAFE - -// private: } QActive; //! @static @private @memberof QActive @@ -819,14 +531,10 @@ extern QSubscrList * QActive_subscrList_; //! @static @private @memberof QActive extern enum_t QActive_maxPubSignal_; -// protected: - //! @protected @memberof QActive void QActive_ctor(QActive * const me, QStateHandler const initial); -// public: - //! @public @memberof QActive void QActive_setAttr(QActive * const me, uint32_t attr1, @@ -841,15 +549,11 @@ void QActive_start(QActive * const me, uint_fast16_t const stkSize, void const * const par); -// protected: - #ifdef QACTIVE_CAN_STOP //! @protected @memberof QActive void QActive_stop(QActive * const me); #endif // def QACTIVE_CAN_STOP -// private: - //! @private @memberof QActive void QActive_register_(QActive * const me); @@ -869,23 +573,17 @@ void QActive_postLIFO_(QActive * const me, //! @private @memberof QActive QEvt const * QActive_get_(QActive * const me); -// public: - //! @static @public @memberof QActive void QActive_psInit( QSubscrList * const subscrSto, enum_t const maxSignal); -// private: - //! @static @private @memberof QActive void QActive_publish_( QEvt const * const e, void const * const sender, uint_fast8_t const qsId); -// protected: - //! @protected @memberof QActive void QActive_subscribe(QActive const * const me, enum_t const sig); @@ -911,79 +609,34 @@ uint_fast16_t QActive_flushDeferred(QActive const * const me, struct QEQueue * const eq, uint_fast16_t const num); -// private: - //! @private @memberof QActive void QActive_evtLoop_(QActive * const me); -//$enddecl${QF::QActive} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -//$declare${QF::QMActive} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -//${QF::QMActive} ............................................................ +//============================================================================ //! @class QMActive //! @extends QActive typedef struct { -// protected: - QActive super; + QActive super; //!< @protected @memberof QMActive } QMActive; -// protected: - //! @protected @memberof QMActive void QMActive_ctor(QMActive * const me, QStateHandler const initial); -//$enddecl${QF::QMActive} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -//$declare${QF::QTimeEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -//${QF::QTimeEvt} ............................................................ +//============================================================================ //! @class QTimeEvt //! @extends QEvt typedef struct QTimeEvt { -// protected: - QEvt super; - -// private: - - //! @private @memberof QTimeEvt - struct QTimeEvt * volatile next; - -#ifndef Q_UNSAFE - //! @private @memberof QTimeEvt - uintptr_t next_dis; -#endif // ndef Q_UNSAFE - - //! @private @memberof QTimeEvt - void * act; - - //! @private @memberof QTimeEvt - QTimeEvtCtr volatile ctr; - -#ifndef Q_UNSAFE - //! @private @memberof QTimeEvt - QTimeEvtCtr ctr_dis; -#endif // ndef Q_UNSAFE - - //! @private @memberof QTimeEvt - QTimeEvtCtr interval; - - //! @private @memberof QTimeEvt - uint8_t tickRate; - - //! @private @memberof QTimeEvt - uint8_t flags; + QEvt super; //!< @protected @memberof QTimeEvt + + struct QTimeEvt * volatile next; //!< @private @memberof QTimeEvt + void * act; //!< @private @memberof QTimeEvt + QTimeEvtCtr volatile ctr; //!< @private @memberof QTimeEvt + QTimeEvtCtr interval; //!< @private @memberof QTimeEvt + uint8_t tickRate; //!< @private @memberof QTimeEvt + uint8_t flags; //!< @private @memberof QTimeEvt } QTimeEvt; -//! @static @private @memberof QTimeEvt -extern QTimeEvt QTimeEvt_timeEvtHead_[QF_MAX_TICK_RATE]; - -#ifndef Q_UNSAFE -//! @static @private @memberof QTimeEvt -extern uintptr_t QTimeEvt_timeEvtHead_dis_[QF_MAX_TICK_RATE]; -#endif // ndef Q_UNSAFE - -// public: - //! @public @memberof QTimeEvt void QTimeEvt_ctorX(QTimeEvt * const me, QActive * const act, @@ -1016,39 +669,36 @@ void QTimeEvt_tick_( uint_fast8_t const tickRate, void const * const sender); -// private: +//! @private @memberof QTimeEvt +QTimeEvt * QTimeEvt_expire_(QTimeEvt * const me, + QTimeEvt * const prev_link, + QActive const * const act, + uint_fast8_t const tickRate); #ifdef Q_UTEST -//! @static @private @memberof QTimeEvt -void QTimeEvt_tick1_( - uint_fast8_t const tickRate, - void const * const sender); + //! @static @private @memberof QTimeEvt + void QTimeEvt_tick1_( + uint_fast8_t const tickRate, + void const * const sender); #endif // def Q_UTEST -// public: - //! @static @public @memberof QTimeEvt bool QTimeEvt_noActive(uint_fast8_t const tickRate); -//$enddecl${QF::QTimeEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -//$declare${QF::QTicker} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +//! @static @private @memberof QTimeEvt +extern QTimeEvt QTimeEvt_timeEvtHead_[QF_MAX_TICK_RATE]; -//${QF::QTicker} ............................................................. +//============================================================================ //! @class QTicker //! @extends QActive typedef struct { -// protected: - QActive super; + QActive super; //!< @protected @memberof QTicker } QTicker; -// public: - //! @public @memberof QTicker void QTicker_ctor(QTicker * const me, uint_fast8_t const tickRate); -// private: - //! @private @memberof QTicker void QTicker_init_( QAsm * const me, @@ -1065,216 +715,127 @@ void QTicker_dispatch_( void QTicker_trig_( QActive * const me, void const * const sender); -//$enddecl${QF::QTicker} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -//$declare${QF::QF-base} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +//============================================================================ +// QF base facilities -//${QF::QF-base::init} ....................................................... //! @static @public @memberof QF void QF_init(void); -//${QF::QF-base::stop} ....................................................... //! @static @public @memberof QF void QF_stop(void); -//${QF::QF-base::run} ........................................................ //! @static @public @memberof QF int_t QF_run(void); -//${QF::QF-base::getQueueMin} ................................................ //! @static @public @memberof QF uint_fast16_t QF_getQueueMin(uint_fast8_t const prio); -//${QF::QF-base::onStartup} .................................................. //! @static @public @memberof QF void QF_onStartup(void); -//${QF::QF-base::onCleanup} .................................................. //! @static @public @memberof QF void QF_onCleanup(void); -//${QF::QF-base::onContextSw} ................................................ #ifdef QF_ON_CONTEXT_SW -//! @static @public @memberof QF -void QF_onContextSw( - QActive * prev, - QActive * next); + //! @static @public @memberof QF + void QF_onContextSw( + QActive * prev, + QActive * next); #endif // def QF_ON_CONTEXT_SW -//$enddecl${QF::QF-base} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -//$declare${QF::QF-dyn} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +#define Q_PRIO(prio_, pthre_) ((QPrioSpec)((prio_) | ((pthre_) << 8U))) +#define QF_NO_MARGIN ((uint_fast16_t)0xFFFFU) + +//============================================================================ +// QF dynamic memory facilities -//${QF::QF-dyn::poolInit} .................................................... //! @static @public @memberof QF void QF_poolInit( void * const poolSto, uint_fast32_t const poolSize, uint_fast16_t const evtSize); -//${QF::QF-dyn::poolGetMaxBlockSize} ......................................... //! @static @public @memberof QF uint_fast16_t QF_poolGetMaxBlockSize(void); -//${QF::QF-dyn::getPoolMin} .................................................. //! @static @public @memberof QF uint_fast16_t QF_getPoolMin(uint_fast8_t const poolNum); -//${QF::QF-dyn::newX_} ....................................................... //! @static @private @memberof QF QEvt * QF_newX_( uint_fast16_t const evtSize, uint_fast16_t const margin, enum_t const sig); -//${QF::QF-dyn::gc} .......................................................... //! @static @public @memberof QF void QF_gc(QEvt const * const e); -//${QF::QF-dyn::newRef_} ..................................................... //! @static @private @memberof QF QEvt const * QF_newRef_( QEvt const * const e, void const * const evtRef); -//${QF::QF-dyn::deleteRef_} .................................................. //! @static @private @memberof QF void QF_deleteRef_(void const * const evtRef); -//${QF::QF-dyn::gcFromISR} ................................................... //! @static @public @memberof QF void QF_gcFromISR(QEvt const * const e); -//$enddecl${QF::QF-dyn} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -//$declare${QF-macros} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -//${QF-macros::QF_NO_MARGIN} ................................................. -#define QF_NO_MARGIN ((uint_fast16_t)0xFFFFU) - -//${QF-macros::Q_PRIO} ....................................................... -#define Q_PRIO(prio_, pthre_) ((QPrioSpec)((prio_) | ((pthre_) << 8U))) - -//${QF-macros::Q_NEW} ........................................................ -#ifndef QEVT_PAR_INIT -#define Q_NEW(evtT_, sig_) ((evtT_ *)QF_newX_((uint_fast16_t)sizeof(evtT_), \ - QF_NO_MARGIN, (enum_t)(sig_))) -#endif // ndef QEVT_PAR_INIT - -//${QF-macros::Q_NEW} ........................................................ -#ifdef QEVT_PAR_INIT -#define Q_NEW(evtT_, sig_, ...) \ - (evtT_##_init((evtT_ *)QF_newX_((uint_fast16_t)sizeof(evtT_), \ - QF_NO_MARGIN, (sig_)), __VA_ARGS__)) -#endif // def QEVT_PAR_INIT - -//${QF-macros::Q_NEW_X} ...................................................... -#ifndef QEVT_PAR_INIT -#define Q_NEW_X(evtT_, margin_, sig_) \ - ((evtT_ *)QF_newX_((uint_fast16_t)sizeof(evtT_), \ - (margin_), (enum_t)(sig_))) -#endif // ndef QEVT_PAR_INIT - -//${QF-macros::Q_NEW_X} ...................................................... #ifdef QEVT_PAR_INIT -#define Q_NEW_X(evtT_, margin_, sig_, ...) \ - (evtT_##_init((evtT_ *)QF_newX_((uint_fast16_t)sizeof(evtT_), \ - (margin_), (sig_)), __VA_ARGS__)) -#endif // def QEVT_PAR_INIT + #define Q_NEW(evtT_, sig_, ...) \ + (evtT_##_init((evtT_ *)QF_newX_((uint_fast16_t)sizeof(evtT_), \ + QF_NO_MARGIN, (sig_)), __VA_ARGS__)) + #define Q_NEW_X(evtT_, margin_, sig_, ...) \ + (evtT_##_init((evtT_ *)QF_newX_((uint_fast16_t)sizeof(evtT_), \ + (margin_), (sig_)), __VA_ARGS__)) +#else + #define Q_NEW(evtT_, sig_) \ + ((evtT_ *)QF_newX_((uint_fast16_t)sizeof(evtT_), \ + QF_NO_MARGIN, (enum_t)(sig_))) + #define Q_NEW_X(evtT_, margin_, sig_) \ + ((evtT_ *)QF_newX_((uint_fast16_t)sizeof(evtT_), \ + (margin_), (enum_t)(sig_))) +#endif // QEVT_PAR_INIT -//${QF-macros::Q_NEW_REF} .................................................... #define Q_NEW_REF(evtRef_, evtT_) \ ((evtRef_) = (evtT_ const *)QF_newRef_(e, (evtRef_))) - -//${QF-macros::Q_DELETE_REF} ................................................. #define Q_DELETE_REF(evtRef_) do { \ QF_deleteRef_((evtRef_)); \ (evtRef_) = (void *)0; \ } while (false) -//${QF-macros::QACTIVE_POST} ................................................. -#ifdef Q_SPY -#define QACTIVE_POST(me_, e_, sender_) \ - ((void)QActive_post_((me_), (e_), QF_NO_MARGIN, (sender_))) -#endif // def Q_SPY - -//${QF-macros::QACTIVE_POST} ................................................. -#ifndef Q_SPY -#define QACTIVE_POST(me_, e_, dummy) \ - ((void)QActive_post_((me_), (e_), QF_NO_MARGIN, (void *)0)) -#endif // ndef Q_SPY - -//${QF-macros::QACTIVE_POST_X} ............................................... -#ifdef Q_SPY -#define QACTIVE_POST_X(me_, e_, margin_, sender_) \ - (QActive_post_((me_), (e_), (margin_), (sender_))) -#endif // def Q_SPY - -//${QF-macros::QACTIVE_POST_X} ............................................... -#ifndef Q_SPY -#define QACTIVE_POST_X(me_, e_, margin_, dummy) \ - (QActive_post_((me_), (e_), (margin_), (void *)0)) -#endif // ndef Q_SPY - -//${QF-macros::QACTIVE_POST_LIFO} ............................................ -#define QACTIVE_POST_LIFO(me_, e_) \ - (QActive_postLIFO_((me_), (e_))) - -//${QF-macros::QACTIVE_PUBLISH} .............................................. #ifdef Q_SPY -#define QACTIVE_PUBLISH(e_, sender_) \ - (QActive_publish_((e_), (void const *)(sender_), (sender_)->prio)) -#endif // def Q_SPY - -//${QF-macros::QACTIVE_PUBLISH} .............................................. -#ifndef Q_SPY -#define QACTIVE_PUBLISH(e_, dummy) (QActive_publish_((e_), (void *)0, 0U)) -#endif // ndef Q_SPY - -//${QF-macros::QTIMEEVT_TICK_X} .............................................. -#ifdef Q_SPY -#define QTIMEEVT_TICK_X(tickRate_, sender_) (QTimeEvt_tick_((tickRate_), (sender_))) -#endif // def Q_SPY - -//${QF-macros::QTIMEEVT_TICK_X} .............................................. -#ifndef Q_SPY -#define QTIMEEVT_TICK_X(tickRate_, dummy) (QTimeEvt_tick_((tickRate_), (void *)0)) + #define QACTIVE_POST(me_, e_, sender_) \ + ((void)QActive_post_((me_), (e_), QF_NO_MARGIN, (sender_))) + #define QACTIVE_POST_X(me_, e_, margin_, sender_) \ + (QActive_post_((me_), (e_), (margin_), (sender_))) + #define QACTIVE_PUBLISH(e_, sender_) \ + (QActive_publish_((e_), (void const *)(sender_), (sender_)->prio)) + #define QTIMEEVT_TICK_X(tickRate_, sender_) (QTimeEvt_tick_((tickRate_), (sender_))) + #define QTICKER_TRIG(ticker_, sender_) (QTicker_trig_((ticker_), (sender_))) +#else + #define QACTIVE_POST(me_, e_, dummy) \ + ((void)QActive_post_((me_), (e_), QF_NO_MARGIN, (void *)0)) + #define QACTIVE_POST_X(me_, e_, margin_, dummy) \ + (QActive_post_((me_), (e_), (margin_), (void *)0)) + #define QACTIVE_PUBLISH(e_, dummy) (QActive_publish_((e_), (void *)0, 0U)) + #define QTIMEEVT_TICK_X(tickRate_, dummy) (QTimeEvt_tick_((tickRate_), (void *)0)) + #define QTICKER_TRIG(ticker_, sender_) (QTicker_trig_((ticker_), (void *)0)) #endif // ndef Q_SPY -//${QF-macros::QTIMEEVT_TICK} ................................................ -#define QTIMEEVT_TICK(sender_) QTIMEEVT_TICK_X(0U, (sender_)) +#define QACTIVE_POST_LIFO(me_, e_) (QActive_postLIFO_((me_), (e_))) +#define QTIMEEVT_TICK(sender_) QTIMEEVT_TICK_X(0U, (sender_)) -//${QF-macros::QTICKER_TRIG} ................................................. -#ifdef Q_SPY -#define QTICKER_TRIG(ticker_, sender_) (QTicker_trig_((ticker_), (sender_))) -#endif // def Q_SPY - -//${QF-macros::QTICKER_TRIG} ................................................. -#ifndef Q_SPY -#define QTICKER_TRIG(ticker_, sender_) (QTicker_trig_((ticker_), (void *)0)) -#endif // ndef Q_SPY - -//${QF-macros::QF_CRIT_EXIT_NOP} ............................................. #ifndef QF_CRIT_EXIT_NOP -#define QF_CRIT_EXIT_NOP() ((void)0) + #define QF_CRIT_EXIT_NOP() ((void)0) #endif // ndef QF_CRIT_EXIT_NOP -//${QF-macros::QF_TICK_X} .................................................... -#define QF_TICK_X(tickRate_, sender_) QTIMEEVT_TICK_X((tickRate_), (sender_)) - -//${QF-macros::QF_TICK} ...................................................... -#define QF_TICK(sender_) QTIMEEVT_TICK(sender_) - -//${QF-macros::QF_PUBLISH} ................................................... -#define QF_PUBLISH(e_, sender_) QACTIVE_PUBLISH((e_), (sender_)) - -//${QF-macros::QF_MEM_SYS} ................................................... -#ifndef QF_MEM_SYS -#define QF_MEM_SYS() ((void)0) -#endif // ndef QF_MEM_SYS +//============================================================================ +// memory protection facilities -//${QF-macros::QF_MEM_APP} ................................................... -#ifndef QF_MEM_APP -#define QF_MEM_APP() ((void)0) -#endif // ndef QF_MEM_APP -//$enddecl${QF-macros} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#ifdef QF_MEM_ISOLATE + #error Memory isolation not supported in this QP edition, need SafeQP +#endif // def QF_MEM_ISOLATE #endif // QP_H_ diff --git a/include/qp_pkg.h b/include/qp_pkg.h index 6e36f6feb..36da3d87d 100644 --- a/include/qp_pkg.h +++ b/include/qp_pkg.h @@ -1,10 +1,6 @@ -//$file${include::qp_pkg.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// -// Model: qpc.qm -// File: ${include::qp_pkg.h} -// -// This code has been generated by QM 7.0.0 . -// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // @@ -14,7 +10,7 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -30,68 +26,49 @@ // Quantum Leaps contact information: // // -// -//$endhead${include::qp_pkg.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//============================================================================ #ifndef QP_PKG_H_ #define QP_PKG_H_ -//$declare${QF::QF-pkg} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +//============================================================================ +#define QACTIVE_CAST_(ptr_) ((QActive *)(ptr_)) +#define Q_PTR2UINT_CAST_(ptr_) ((uintptr_t)(ptr_)) -//${QF::QF-pkg::Attr} ........................................................ -//! @class QF_Attr +//============================================================================ typedef struct { -// private: - #if (QF_MAX_EPOOL > 0U) - //! @private @memberof QF_Attr - QF_EPOOL_TYPE_ ePool_[QF_MAX_EPOOL]; -#endif // (QF_MAX_EPOOL > 0U) - -#if (QF_MAX_EPOOL > 0U) - //! @private @memberof QF_Attr - uint_fast8_t maxPool_; -#endif // (QF_MAX_EPOOL > 0U) - -#if (QF_MAX_EPOOL == 0U) - //! @private @memberof QF_Attr - uint8_t dummy; + QF_EPOOL_TYPE_ ePool_[QF_MAX_EPOOL]; //!< @private @memberof QF_Attr + uint_fast8_t maxPool_; //!< @private @memberof QF_Attr +#else + uint8_t dummy; //!< @private @memberof QF_Attr #endif // (QF_MAX_EPOOL == 0U) } QF_Attr; -//${QF::QF-pkg::priv_} ....................................................... -//! @static @private @memberof QF -extern QF_Attr QF_priv_; +extern QF_Attr QF_priv_; //!< @static @private @memberof QF -//${QF::QF-pkg::bzero_} ...................................................... //! @static @private @memberof QF void QF_bzero_( void * const start, uint_fast16_t const len); -//$enddecl${QF::QF-pkg} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//============================================================================ // Bitmasks are for the QTimeEvt::flags attribute #define QTE_FLAG_IS_LINKED (1U << 7U) #define QTE_FLAG_WAS_DISARMED (1U << 6U) +//============================================================================ //! @private @memberof QEvt -static inline void QEvt_refCtr_inc_(QEvt const *me) { - uint8_t rc = me->refCtr_ + 1U; +static inline void QEvt_refCtr_inc_(QEvt const * const me) { + // NOTE: this function must be called inside a critical section + uint8_t const rc = me->refCtr_ + 1U; ((QEvt *)me)->refCtr_ = rc; // cast away 'const' -#ifndef Q_UNSAFE - ((QEvt *)me)->evtTag_ = (me->evtTag_ & 0xF0U) | ((~rc) & 0x0FU); -#endif // ndef Q_UNSAFE } //! @private @memberof QEvt -static inline void QEvt_refCtr_dec_(QEvt const *me) { - uint8_t rc = me->refCtr_ - 1U; +static inline void QEvt_refCtr_dec_(QEvt const * const me) { + // NOTE: this function must be called inside a critical section + uint8_t const rc = me->refCtr_ - 1U; ((QEvt *)me)->refCtr_ = rc; // cast away 'const' -#ifndef Q_UNSAFE - ((QEvt *)me)->evtTag_ = (me->evtTag_ & 0xF0U) | ((~rc) & 0x0FU); -#endif // ndef Q_UNSAFE } -#define QACTIVE_CAST_(ptr_) ((QActive *)(ptr_)) -#define Q_PTR2UINT_CAST_(ptr_) ((uintptr_t)(ptr_)) - #endif // QP_PKG_H_ diff --git a/include/qpc.h b/include/qpc.h index 8a4816ef6..fde50edb6 100644 --- a/include/qpc.h +++ b/include/qpc.h @@ -1,10 +1,6 @@ -//$file${include::qpc.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// -// Model: qpc.qm -// File: ${include::qpc.h} -// -// This code has been generated by QM 7.0.0 . -// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // @@ -14,7 +10,7 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -30,8 +26,7 @@ // Quantum Leaps contact information: // // -// -//$endhead${include::qpc.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//============================================================================ #ifndef QPC_H_ #define QPC_H_ @@ -141,6 +136,10 @@ static inline void QF_psInit( //! @deprecated instead use: QASM_IS_IN() #define QHsm_isIn(me_, state_) QASM_IS_IN((QAsm *)(me_), (state_)) +#define QF_PUBLISH(e_, sender_) QACTIVE_PUBLISH((e_), (sender_)) +#define QF_TICK_X(tickRate_, sender_) QTIMEEVT_TICK_X((tickRate_), (sender_)) +#define QF_TICK(sender_) QTIMEEVT_TICK(sender_) + #endif // QP_API_VERSION < 800 #endif // QPC_H_ diff --git a/include/qs_dummy.h b/include/qs_dummy.h index b0c3bad3d..bc32addb2 100644 --- a/include/qs_dummy.h +++ b/include/qs_dummy.h @@ -1,5 +1,6 @@ //============================================================================ -// QP/C-Spy software tracing target-resident component +// QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // @@ -7,10 +8,9 @@ // ------------------------ // Modern Embedded Software // -// // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -31,11 +31,11 @@ #define QS_DUMMY_H_ #ifdef Q_SPY - #error "Q_SPY must NOT be defined to include qs_dummy.h" + #error Q_SPY must NOT be defined to include qs_dummy.h #endif #ifdef Q_UTEST - #error "Q_UTEST must NOT be defined to include qs_dummy.h" + #error Q_UTEST must NOT be defined to include qs_dummy.h #endif #define QS_INIT(arg_) ((uint8_t)1U) @@ -158,9 +158,6 @@ void QS_onTestLoop(void); #define QS_CRIT_ENTRY() ((void)0) #define QS_CRIT_EXIT() ((void)0) - #define QS_MEM_SYS() ((void)0) - #define QS_MEM_APP() ((void)0) - #define QS_TR_CRIT_ENTRY() ((void)0) #define QS_TR_CRIT_EXIT() ((void)0) #define QS_TR_ISR_ENTRY(isrnest_, prio_) ((void)0) diff --git a/include/qsafe.h b/include/qsafe.h index f1938364a..df6bf21a7 100644 --- a/include/qsafe.h +++ b/include/qsafe.h @@ -1,10 +1,6 @@ -//$file${include::qsafe.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// -// Model: qpc.qm -// File: ${include::qsafe.h} -// -// This code has been generated by QM 7.0.0 . -// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +//============================================================================ +// SafeQP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // @@ -12,63 +8,51 @@ // ------------------------ // Modern Embedded Software // -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// SPDX-License-Identifier: LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU -// General Public License (GPL) or under the terms of one of the closed- -// source Quantum Leaps commercial licenses. +// This software is licensed under the terms of the Quantum Leaps commercial +// licenses. Please contact Quantum Leaps for more information about the +// available licensing options. // -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// NOTE: -// The GPL does NOT permit the incorporation of this code into proprietary -// programs. Please contact Quantum Leaps for commercial licensing options, -// which expressly supersede the GPL and are designed explicitly for -// closed-source distribution. +// RESTRICTIONS +// You may NOT : +// (a) redistribute, encumber, sell, rent, lease, sublicense, or otherwise +// transfer rights in this software, +// (b) remove or alter any trademark, logo, copyright or other proprietary +// notices, legends, symbols or labels present in this software, +// (c) plagiarize this software to sidestep the licensing obligations. // // Quantum Leaps contact information: // // -// -//$endhead${include::qsafe.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//============================================================================ #ifndef QSAFE_H_ #define QSAFE_H_ -#ifdef __cplusplus -extern "C" { -#endif - // QF-FuSa enabled =========================================================== #ifndef Q_UNSAFE #ifndef QF_CRIT_STAT -#define QF_CRIT_STAT + #define QF_CRIT_STAT #endif #ifndef QF_CRIT_ENTRY -#define QF_CRIT_ENTRY() ((void)0) + #define QF_CRIT_ENTRY() ((void)0) #endif #ifndef QF_CRIT_EXIT -#define QF_CRIT_EXIT() ((void)0) + #define QF_CRIT_EXIT() ((void)0) #endif -//$declare${QP-FuSa::enabled} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QP-FuSa::enabled::Q_DEFINE_THIS_MODULE} .................................. #define Q_DEFINE_THIS_MODULE(name_) \ static char const Q_this_module_[] = name_; -//${QP-FuSa::enabled::Q_ASSERT_INCRIT} ....................................... -#define Q_ASSERT_INCRIT(id_, expr_) \ +#define Q_ASSERT_INCRIT(id_, expr_) \ ((expr_) ? ((void)0) : Q_onError(&Q_this_module_[0], (id_))) -//${QP-FuSa::enabled::Q_ERROR_INCRIT} ........................................ -#define Q_ERROR_INCRIT(id_) \ +#define Q_ERROR_INCRIT(id_) \ (Q_onError(&Q_this_module_[0], (id_))) -//${QP-FuSa::enabled::Q_ASSERT_ID} ........................................... #define Q_ASSERT_ID(id_, expr_) do { \ QF_CRIT_STAT \ QF_CRIT_ENTRY(); \ @@ -76,98 +60,63 @@ extern "C" { QF_CRIT_EXIT(); \ } while (false) -//${QP-FuSa::enabled::Q_ERROR_ID} ............................................ #define Q_ERROR_ID(id_) do { \ QF_CRIT_STAT \ QF_CRIT_ENTRY(); \ Q_onError(&Q_this_module_[0], (id_)); \ QF_CRIT_EXIT(); \ } while (false) -//$enddecl${QP-FuSa::enabled} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // QF-FuSa disabled ========================================================== #else -//$declare${QP-FuSa::disabled} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -//${QP-FuSa::disabled::Q_DEFINE_THIS_MODULE} ................................. #define Q_DEFINE_THIS_MODULE(name_) - -//${QP-FuSa::disabled::Q_ASSERT_INCRIT} ...................................... #define Q_ASSERT_INCRIT(id_, expr_) ((void)0) - -//${QP-FuSa::disabled::Q_ERROR_INCRIT} ....................................... #define Q_ERROR_INCRIT(id_) ((void)0) - -//${QP-FuSa::disabled::Q_ASSERT_ID} .......................................... #define Q_ASSERT_ID(id_, expr_) ((void)0) - -//${QP-FuSa::disabled::Q_ERROR_ID} ........................................... #define Q_ERROR_ID(id_) ((void)0) -//$enddecl${QP-FuSa::disabled} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -#endif - -//============================================================================ -//$declare1${QP-FuSa} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QP-FuSa::Q_DEFINE_THIS_FILE} ............................................. -#define Q_DEFINE_THIS_FILE Q_DEFINE_THIS_MODULE(__FILE__) - -//${QP-FuSa::Q_ASSERT} ....................................................... -#define Q_ASSERT(expr_) Q_ASSERT_ID(__LINE__, (expr_)) -//${QP-FuSa::Q_ERROR} ........................................................ -#define Q_ERROR() Q_ERROR_ID(__LINE__) +#endif // QF-FuSa disabled -//${QP-FuSa::Q_REQUIRE_ID} ................................................... -#define Q_REQUIRE_ID(id_, expr_) Q_ASSERT_ID((id_), (expr_)) - -//${QP-FuSa::Q_REQUIRE} ...................................................... -#define Q_REQUIRE(expr_) Q_ASSERT(expr_) - -//${QP-FuSa::Q_REQUIRE_INCRIT} ............................................... -#define Q_REQUIRE_INCRIT(id_, expr_) Q_ASSERT_INCRIT((id_), (expr_)) - -//${QP-FuSa::Q_ENSURE_ID} .................................................... -#define Q_ENSURE_ID(id_, expr_) Q_ASSERT_ID((id_), (expr_)) - -//${QP-FuSa::Q_ENSURE} ....................................................... -#define Q_ENSURE(expr_) Q_ASSERT(expr_) - -//${QP-FuSa::Q_ENSURE_INCRIT} ................................................ -#define Q_ENSURE_INCRIT(id_, expr_) Q_ASSERT_INCRIT((id_), (expr_)) - -//${QP-FuSa::Q_INVARIANT_ID} ................................................. -#define Q_INVARIANT_ID(id_, expr_) Q_ASSERT_ID((id_), (expr_)) - -//${QP-FuSa::Q_INVARIANT} .................................................... -#define Q_INVARIANT(expr_) Q_ASSERT(expr_) - -//${QP-FuSa::Q_INVARIANT_INCRIT} ............................................. +//============================================================================ +#define Q_DEFINE_THIS_FILE Q_DEFINE_THIS_MODULE(__FILE__) +#define Q_ASSERT(expr_) Q_ASSERT_ID(__LINE__, (expr_)) +#define Q_ERROR() Q_ERROR_ID(__LINE__) +#define Q_REQUIRE_ID(id_, expr_) Q_ASSERT_ID((id_), (expr_)) +#define Q_REQUIRE(expr_) Q_ASSERT(expr_) +#define Q_REQUIRE_INCRIT(id_, expr_) Q_ASSERT_INCRIT((id_), (expr_)) +#define Q_ENSURE_ID(id_, expr_) Q_ASSERT_ID((id_), (expr_)) +#define Q_ENSURE(expr_) Q_ASSERT(expr_) +#define Q_ENSURE_INCRIT(id_, expr_) Q_ASSERT_INCRIT((id_), (expr_)) +#define Q_INVARIANT_ID(id_, expr_) Q_ASSERT_ID((id_), (expr_)) +#define Q_INVARIANT(expr_) Q_ASSERT(expr_) #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] +#ifndef Q_ASSERT_STATIC + #define Q_ASSERT_STATIC(expr_) extern char Q_static_assert_[(expr_) ? 1 : -1] +#endif // ndef Q_ASSERT_STATIC -//${QP-FuSa::Q_NORETURN} ..................................................... #ifndef Q_NORETURN -#define Q_NORETURN _Noreturn void + #define Q_NORETURN _Noreturn void #endif // ndef Q_NORETURN -//${QP-FuSa::int_t} .......................................................... +// Is this header file used outside QP? #ifndef QP_VERSION -typedef int int_t; + #define Q_DIM(array_) (sizeof(array_) / sizeof((array_)[0U])) #endif // ndef QP_VERSION -//${QP-FuSa::Q_onError} ...................................................... -Q_NORETURN Q_onError( - char const * const module, - int_t const id); +//============================================================================ +#ifdef __cplusplus +extern "C" { +#endif -//${QP-FuSa::Q_DIM} .......................................................... #ifndef QP_VERSION -#define Q_DIM(array_) (sizeof(array_) / sizeof((array_)[0U])) + typedef int int_t; #endif // ndef QP_VERSION -//$enddecl${QP-FuSa} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Q_NORETURN Q_onError( + char const * const module, + int_t const id); #ifdef __cplusplus } diff --git a/include/qstamp.h b/include/qstamp.h index 97ebf016d..d9405b05a 100644 --- a/include/qstamp.h +++ b/include/qstamp.h @@ -1,10 +1,6 @@ -//$file${include::qstamp.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// -// Model: qpc.qm -// File: ${include::qstamp.h} -// -// This code has been generated by QM 7.0.0 . -// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // @@ -14,7 +10,7 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -30,8 +26,7 @@ // Quantum Leaps contact information: // // -// -//$endhead${include::qstamp.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//============================================================================ #ifndef QSTAMP_H_ #define QSTAMP_H_ diff --git a/include/qv.h b/include/qv.h index bd308d1dd..085e9cec1 100644 --- a/include/qv.h +++ b/include/qv.h @@ -1,10 +1,6 @@ -//$file${include::qv.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// -// Model: qpc.qm -// File: ${include::qv.h} -// -// This code has been generated by QM 7.0.0 . -// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // @@ -14,7 +10,7 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -30,115 +26,59 @@ // Quantum Leaps contact information: // // -// -//$endhead${include::qv.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//============================================================================ #ifndef QV_H_ #define QV_H_ -//$declare${QV::QV} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QV::QV} .................................................................. +//============================================================================ //! @class QV typedef struct QV { //! @cond INTERNAL uint8_t dummy; //! @endcond } QV; -//$enddecl${QV::QV} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -//$declare${QV::QV-base} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -//${QV::QV-base::Attr} ....................................................... +//============================================================================ //! @class QV_Attr typedef struct { -// private: - - //! @memberof QV_Attr - QPSet readySet; - - //! @memberof QV_Attr - uint_fast8_t schedCeil; - -#ifndef Q_UNSAFE - //! @memberof QV_Attr - QPSet readySet_dis; -#endif // ndef Q_UNSAFE - -#ifndef Q_UNSAFE - //! @memberof QV_Attr - uint_fast8_t schedCeil_dis; -#endif // ndef Q_UNSAFE + QPSet readySet; //!< @private @memberof QV_Attr + uint_fast8_t schedCeil; //!< @private @memberof QV_Attr } QV_Attr; -//${QV::QV-base::priv_} ...................................................... //! @static @private @memberof QV extern QV_Attr QV_priv_; -//${QV::QV-base::schedDisable} ............................................... //! @static @public @memberof QV void QV_schedDisable(uint_fast8_t const ceiling); -//${QV::QV-base::schedEnable} ................................................ //! @static @public @memberof QV void QV_schedEnable(void); -//${QV::QV-base::onIdle} ..................................................... //! @static @public @memberof QV void QV_onIdle(void); -//$enddecl${QV::QV-base} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //============================================================================ // interface used only for internal implementation, but not in applications #ifdef QP_IMPL -//$declare${QV-impl} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QV-impl::QF_SCHED_STAT_} ................................................. +// scheduler locking for QV (not needed)... #define QF_SCHED_STAT_ - -//${QV-impl::QF_SCHED_LOCK_} ................................................. #define QF_SCHED_LOCK_(dummy) ((void)0) +#define QF_SCHED_UNLOCK_() ((void)0) -//${QV-impl::QF_SCHED_UNLOCK_} ............................................... -#define QF_SCHED_UNLOCK_() ((void)0) - -//${QV-impl::QACTIVE_EQUEUE_WAIT_} ........................................... +// QActive event queue customization for QV... #define QACTIVE_EQUEUE_WAIT_(me_) ((void)0) - -//${QV-impl::QACTIVE_EQUEUE_SIGNAL_} ......................................... -#ifndef Q_UNSAFE -#define QACTIVE_EQUEUE_SIGNAL_(me_) \ - QPSet_insert(&QV_priv_.readySet, (uint_fast8_t)(me_)->prio); \ - QPSet_update_(&QV_priv_.readySet, &QV_priv_.readySet_dis) -#endif // ndef Q_UNSAFE - -//${QV-impl::QACTIVE_EQUEUE_SIGNAL_} ......................................... -#ifdef Q_UNSAFE #define QACTIVE_EQUEUE_SIGNAL_(me_) \ QPSet_insert(&QV_priv_.readySet, (uint_fast8_t)(me_)->prio) -#endif // def Q_UNSAFE -//$enddecl${QV-impl} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -//$declare${QF_EPOOL-impl} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -//${QF_EPOOL-impl::QF_EPOOL_TYPE_} ........................................... +// QF event pool customization for QV... #define QF_EPOOL_TYPE_ QMPool - -//${QF_EPOOL-impl::QF_EPOOL_INIT_} ........................................... #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) - -//${QF_EPOOL-impl::QF_EPOOL_EVENT_SIZE_} ..................................... #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) - -//${QF_EPOOL-impl::QF_EPOOL_GET_} ............................................ #define QF_EPOOL_GET_(p_, e_, m_, qsId_) \ ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qsId_))) - -//${QF_EPOOL-impl::QF_EPOOL_PUT_} ............................................ -#define QF_EPOOL_PUT_(p_, e_, qsId_) \ - (QMPool_put(&(p_), (e_), (qsId_))) -//$enddecl${QF_EPOOL-impl} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +#define QF_EPOOL_PUT_(p_, e_, qsId_) (QMPool_put(&(p_), (e_), (qsId_))) #endif // QP_IMPL diff --git a/ports/arm-cm/config/qp_config.h b/ports/arm-cm/config/qp_config.h index 42dcef3c3..e2bf11230 100644 --- a/ports/arm-cm/config/qp_config.h +++ b/ports/arm-cm/config/qp_config.h @@ -1,15 +1,16 @@ //============================================================================ -// QP configuration file (QV/QK/QXK on ARM Cortex-M) +// QP/C configuration file (QV/QK/QXK on ARM Cortex-M) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -17,11 +18,10 @@ // Plagiarizing this software to sidestep the license obligations is illegal. // // NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. // // Quantum Leaps contact information: // @@ -35,9 +35,9 @@ // QP API compatibility version (QP_API_VERSION) // <0=> 0 (Maximum compatibility) // <691=>691 (QP 6.9.1 or newer) -// <734=>7.3.4 (QP 7.3.4 or newer) +// <750=>750 (QP 7.5.0 or newer) // <9999=>9999 (Latest only) -// QP API backwards compatibility with the QP/C API version. +// QP API backwards compatibility with the QP API version. // Lower QP_API_VERSION values enable backwards compatibility // with lower (older) QP API versions. // For example, QP_API_VERSION==691 will enable the compatibility @@ -185,7 +185,7 @@ // // Enable memory isolation (QF_MEM_ISOLATE) -// Memory isolation (requires MPU) +// Memory isolation (supported in SafeQP only, requires MPU) // NOTE: implies QF_ON_CONTEXT_SW. //#define QF_MEM_ISOLATE // @@ -195,11 +195,13 @@ //.......................................................................... // QV/QK/QXK built-in kernels (ARM Cortex-M) +#if (__ARM_ARCH > 6) // Kernel uses critical section based on BASEPRI (QF_USE_BASEPRI) // If not selected, critical section will be based on PRIMASK // NOTE: The BASEPRI threshold can be adjusted in the "Text Editor" mode. //#define QF_USE_BASEPRI 0x3F // +#endif // (__ARM_ARCH > 6) // QK Kernel uses IRQ for return-from-preemption // NOTE: Use "editor mode" to edit QK_USE_IRQ_NUM diff --git a/ports/arm-cm/qk/armclang/qk_port.c b/ports/arm-cm/qk/armclang/qk_port.c index 24b87e02f..b39bf417e 100644 --- a/ports/arm-cm/qk/armclang/qk_port.c +++ b/ports/arm-cm/qk/armclang/qk_port.c @@ -1,14 +1,16 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 +// // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -16,11 +18,10 @@ // Plagiarizing this software to sidestep the license obligations is illegal. // // NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. // // Quantum Leaps contact information: // diff --git a/ports/arm-cm/qk/armclang/qp_port.h b/ports/arm-cm/qk/armclang/qp_port.h index 6ffa552d2..4b1ddddec 100644 --- a/ports/arm-cm/qk/armclang/qp_port.h +++ b/ports/arm-cm/qk/armclang/qp_port.h @@ -1,15 +1,16 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -17,11 +18,10 @@ // Plagiarizing this software to sidestep the license obligations is illegal. // // NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. // // Quantum Leaps contact information: // diff --git a/ports/arm-cm/qk/armclang/qs_port.h b/ports/arm-cm/qk/armclang/qs_port.h index cdb29f7d9..33a953307 100644 --- a/ports/arm-cm/qk/armclang/qs_port.h +++ b/ports/arm-cm/qk/armclang/qs_port.h @@ -1,38 +1,31 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Version 8.0.2 // // 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. +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// The terms of the open source GNU General Public License version 3 -// can be found at: +// SPDX-License-Identifier: LicenseRef-QL-commercial // -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// This software is licensed under the terms of the Quantum Leaps commercial +// licenses. Please contact Quantum Leaps for more information about the +// available licensing options. // -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. +// RESTRICTIONS +// You may NOT : +// (a) redistribute, encumber, sell, rent, lease, sublicense, or otherwise +// transfer rights in this software, +// (b) remove or alter any trademark, logo, copyright or other proprietary +// notices, legends, symbols or labels present in this software, +// (c) plagiarize this software to sidestep the licensing obligations. // -// Contact information: -// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. - #ifndef QS_PORT_H_ #define QS_PORT_H_ diff --git a/ports/arm-cm/qk/gnu/qk_port.c b/ports/arm-cm/qk/gnu/qk_port.c index c65204e99..0bf7e66aa 100644 --- a/ports/arm-cm/qk/gnu/qk_port.c +++ b/ports/arm-cm/qk/gnu/qk_port.c @@ -1,14 +1,16 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 +// // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -16,11 +18,10 @@ // Plagiarizing this software to sidestep the license obligations is illegal. // // NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. // // Quantum Leaps contact information: // diff --git a/ports/arm-cm/qk/gnu/qp_port.h b/ports/arm-cm/qk/gnu/qp_port.h index 23e6491e4..4b1ddddec 100644 --- a/ports/arm-cm/qk/gnu/qp_port.h +++ b/ports/arm-cm/qk/gnu/qp_port.h @@ -1,14 +1,16 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 +// // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -16,11 +18,10 @@ // Plagiarizing this software to sidestep the license obligations is illegal. // // NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. // // Quantum Leaps contact information: // diff --git a/ports/arm-cm/qk/gnu/qs_port.h b/ports/arm-cm/qk/gnu/qs_port.h index cdb29f7d9..33a953307 100644 --- a/ports/arm-cm/qk/gnu/qs_port.h +++ b/ports/arm-cm/qk/gnu/qs_port.h @@ -1,38 +1,31 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Version 8.0.2 // // 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. +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// The terms of the open source GNU General Public License version 3 -// can be found at: +// SPDX-License-Identifier: LicenseRef-QL-commercial // -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// This software is licensed under the terms of the Quantum Leaps commercial +// licenses. Please contact Quantum Leaps for more information about the +// available licensing options. // -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. +// RESTRICTIONS +// You may NOT : +// (a) redistribute, encumber, sell, rent, lease, sublicense, or otherwise +// transfer rights in this software, +// (b) remove or alter any trademark, logo, copyright or other proprietary +// notices, legends, symbols or labels present in this software, +// (c) plagiarize this software to sidestep the licensing obligations. // -// Contact information: -// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. - #ifndef QS_PORT_H_ #define QS_PORT_H_ diff --git a/ports/arm-cm/qk/iar/qk_port.c b/ports/arm-cm/qk/iar/qk_port.c index 5a9a63c28..fb0733d2d 100644 --- a/ports/arm-cm/qk/iar/qk_port.c +++ b/ports/arm-cm/qk/iar/qk_port.c @@ -1,15 +1,16 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -17,11 +18,10 @@ // Plagiarizing this software to sidestep the license obligations is illegal. // // NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. // // Quantum Leaps contact information: // diff --git a/ports/arm-cm/qk/iar/qp_port.h b/ports/arm-cm/qk/iar/qp_port.h index ae9c3046f..0055b8c91 100644 --- a/ports/arm-cm/qk/iar/qp_port.h +++ b/ports/arm-cm/qk/iar/qp_port.h @@ -1,14 +1,16 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 +// // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -16,11 +18,10 @@ // Plagiarizing this software to sidestep the license obligations is illegal. // // NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. // // Quantum Leaps contact information: // diff --git a/ports/arm-cm/qk/iar/qs_port.h b/ports/arm-cm/qk/iar/qs_port.h index cdb29f7d9..33a953307 100644 --- a/ports/arm-cm/qk/iar/qs_port.h +++ b/ports/arm-cm/qk/iar/qs_port.h @@ -1,38 +1,31 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Version 8.0.2 // // 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. +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// The terms of the open source GNU General Public License version 3 -// can be found at: +// SPDX-License-Identifier: LicenseRef-QL-commercial // -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// This software is licensed under the terms of the Quantum Leaps commercial +// licenses. Please contact Quantum Leaps for more information about the +// available licensing options. // -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. +// RESTRICTIONS +// You may NOT : +// (a) redistribute, encumber, sell, rent, lease, sublicense, or otherwise +// transfer rights in this software, +// (b) remove or alter any trademark, logo, copyright or other proprietary +// notices, legends, symbols or labels present in this software, +// (c) plagiarize this software to sidestep the licensing obligations. // -// Contact information: -// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. - #ifndef QS_PORT_H_ #define QS_PORT_H_ diff --git a/ports/arm-cm/qv/armclang/qp_port.h b/ports/arm-cm/qv/armclang/qp_port.h index cd92c9296..1c36db09e 100644 --- a/ports/arm-cm/qv/armclang/qp_port.h +++ b/ports/arm-cm/qv/armclang/qp_port.h @@ -1,14 +1,16 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 +// // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -16,11 +18,10 @@ // Plagiarizing this software to sidestep the license obligations is illegal. // // NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. // // Quantum Leaps contact information: // diff --git a/ports/arm-cm/qv/armclang/qs_port.h b/ports/arm-cm/qv/armclang/qs_port.h index cdb29f7d9..33a953307 100644 --- a/ports/arm-cm/qv/armclang/qs_port.h +++ b/ports/arm-cm/qv/armclang/qs_port.h @@ -1,38 +1,31 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Version 8.0.2 // // 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. +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// The terms of the open source GNU General Public License version 3 -// can be found at: +// SPDX-License-Identifier: LicenseRef-QL-commercial // -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// This software is licensed under the terms of the Quantum Leaps commercial +// licenses. Please contact Quantum Leaps for more information about the +// available licensing options. // -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. +// RESTRICTIONS +// You may NOT : +// (a) redistribute, encumber, sell, rent, lease, sublicense, or otherwise +// transfer rights in this software, +// (b) remove or alter any trademark, logo, copyright or other proprietary +// notices, legends, symbols or labels present in this software, +// (c) plagiarize this software to sidestep the licensing obligations. // -// Contact information: -// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. - #ifndef QS_PORT_H_ #define QS_PORT_H_ diff --git a/ports/arm-cm/qv/armclang/qv_port.c b/ports/arm-cm/qv/armclang/qv_port.c index d30ebd24c..56a03f4eb 100644 --- a/ports/arm-cm/qv/armclang/qv_port.c +++ b/ports/arm-cm/qv/armclang/qv_port.c @@ -1,14 +1,16 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 +// // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -16,11 +18,10 @@ // Plagiarizing this software to sidestep the license obligations is illegal. // // NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. // // Quantum Leaps contact information: // diff --git a/ports/arm-cm/qv/gnu/qp_port.h b/ports/arm-cm/qv/gnu/qp_port.h index cd92c9296..1c36db09e 100644 --- a/ports/arm-cm/qv/gnu/qp_port.h +++ b/ports/arm-cm/qv/gnu/qp_port.h @@ -1,14 +1,16 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 +// // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -16,11 +18,10 @@ // Plagiarizing this software to sidestep the license obligations is illegal. // // NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. // // Quantum Leaps contact information: // diff --git a/ports/arm-cm/qv/gnu/qs_port.h b/ports/arm-cm/qv/gnu/qs_port.h index cdb29f7d9..33a953307 100644 --- a/ports/arm-cm/qv/gnu/qs_port.h +++ b/ports/arm-cm/qv/gnu/qs_port.h @@ -1,38 +1,31 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Version 8.0.2 // // 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. +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// The terms of the open source GNU General Public License version 3 -// can be found at: +// SPDX-License-Identifier: LicenseRef-QL-commercial // -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// This software is licensed under the terms of the Quantum Leaps commercial +// licenses. Please contact Quantum Leaps for more information about the +// available licensing options. // -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. +// RESTRICTIONS +// You may NOT : +// (a) redistribute, encumber, sell, rent, lease, sublicense, or otherwise +// transfer rights in this software, +// (b) remove or alter any trademark, logo, copyright or other proprietary +// notices, legends, symbols or labels present in this software, +// (c) plagiarize this software to sidestep the licensing obligations. // -// Contact information: -// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. - #ifndef QS_PORT_H_ #define QS_PORT_H_ diff --git a/ports/arm-cm/qv/gnu/qv_port.c b/ports/arm-cm/qv/gnu/qv_port.c index 60b7ed2ff..bea7a3de0 100644 --- a/ports/arm-cm/qv/gnu/qv_port.c +++ b/ports/arm-cm/qv/gnu/qv_port.c @@ -1,14 +1,16 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 +// // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -16,11 +18,10 @@ // Plagiarizing this software to sidestep the license obligations is illegal. // // NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. // // Quantum Leaps contact information: // diff --git a/ports/arm-cm/qv/iar/qp_port.h b/ports/arm-cm/qv/iar/qp_port.h index efa8b5014..2e340fb67 100644 --- a/ports/arm-cm/qv/iar/qp_port.h +++ b/ports/arm-cm/qv/iar/qp_port.h @@ -1,14 +1,16 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 +// // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -16,11 +18,10 @@ // Plagiarizing this software to sidestep the license obligations is illegal. // // NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. // // Quantum Leaps contact information: // diff --git a/ports/arm-cm/qv/iar/qs_port.h b/ports/arm-cm/qv/iar/qs_port.h index cdb29f7d9..33a953307 100644 --- a/ports/arm-cm/qv/iar/qs_port.h +++ b/ports/arm-cm/qv/iar/qs_port.h @@ -1,38 +1,31 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Version 8.0.2 // // 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. +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// The terms of the open source GNU General Public License version 3 -// can be found at: +// SPDX-License-Identifier: LicenseRef-QL-commercial // -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// This software is licensed under the terms of the Quantum Leaps commercial +// licenses. Please contact Quantum Leaps for more information about the +// available licensing options. // -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. +// RESTRICTIONS +// You may NOT : +// (a) redistribute, encumber, sell, rent, lease, sublicense, or otherwise +// transfer rights in this software, +// (b) remove or alter any trademark, logo, copyright or other proprietary +// notices, legends, symbols or labels present in this software, +// (c) plagiarize this software to sidestep the licensing obligations. // -// Contact information: -// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. - #ifndef QS_PORT_H_ #define QS_PORT_H_ diff --git a/ports/arm-cm/qv/iar/qv_port.c b/ports/arm-cm/qv/iar/qv_port.c index 129cc18a1..6b627ad1a 100644 --- a/ports/arm-cm/qv/iar/qv_port.c +++ b/ports/arm-cm/qv/iar/qv_port.c @@ -1,14 +1,16 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 +// // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -16,11 +18,10 @@ // Plagiarizing this software to sidestep the license obligations is illegal. // // NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. // // Quantum Leaps contact information: // diff --git a/ports/arm-cr/config/qp_config.h b/ports/arm-cr/config/qp_config.h index b7be8f6af..7eba55f6b 100644 --- a/ports/arm-cr/config/qp_config.h +++ b/ports/arm-cr/config/qp_config.h @@ -1,15 +1,16 @@ //============================================================================ -// QP configuration file (QV/QK/QXK on ARM Cortex-R) +// QP/C configuration file (QV/QK/QXK on ARM Cortex-R) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -17,11 +18,10 @@ // Plagiarizing this software to sidestep the license obligations is illegal. // // NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. // // Quantum Leaps contact information: // @@ -37,7 +37,7 @@ // <691=>691 (QP 6.9.1 or newer) // <734=>7.3.4 (QP 7.3.4 or newer) // <9999=>9999 (Latest only) -// QP API backwards compatibility with the QP/C API version. +// QP API backwards compatibility with the QP API version. // Lower QP_API_VERSION values enable backwards compatibility // with lower (older) QP API versions. // For example, QP_API_VERSION==691 will enable the compatibility @@ -185,7 +185,7 @@ // // Enable memory isolation (QF_MEM_ISOLATE) -// Memory isolation (requires MPU) +// Memory isolation (supported in SafeQP only, requires MPU) // NOTE: implies QF_ON_CONTEXT_SW. //#define QF_MEM_ISOLATE // diff --git a/ports/arm-cr/qk/gnu/qp_port.h b/ports/arm-cr/qk/gnu/qp_port.h index 6ce0735da..7b2c5d511 100644 --- a/ports/arm-cr/qk/gnu/qp_port.h +++ b/ports/arm-cr/qk/gnu/qp_port.h @@ -1,15 +1,16 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -17,22 +18,15 @@ // Plagiarizing this software to sidestep the license obligations is illegal. // // NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. // // Quantum Leaps contact information: // // //============================================================================ -//! @date Last updated on: 2024-11-22 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QP/C port to ARM Cortex-R, preemptive QK kernel, GNU-ARM - #ifndef QP_PORT_H_ #define QP_PORT_H_ diff --git a/ports/arm-cr/qk/gnu/qs_port.h b/ports/arm-cr/qk/gnu/qs_port.h index cdb29f7d9..33a953307 100644 --- a/ports/arm-cr/qk/gnu/qs_port.h +++ b/ports/arm-cr/qk/gnu/qs_port.h @@ -1,38 +1,31 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Version 8.0.2 // // 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. +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// The terms of the open source GNU General Public License version 3 -// can be found at: +// SPDX-License-Identifier: LicenseRef-QL-commercial // -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// This software is licensed under the terms of the Quantum Leaps commercial +// licenses. Please contact Quantum Leaps for more information about the +// available licensing options. // -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. +// RESTRICTIONS +// You may NOT : +// (a) redistribute, encumber, sell, rent, lease, sublicense, or otherwise +// transfer rights in this software, +// (b) remove or alter any trademark, logo, copyright or other proprietary +// notices, legends, symbols or labels present in this software, +// (c) plagiarize this software to sidestep the licensing obligations. // -// Contact information: -// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. - #ifndef QS_PORT_H_ #define QS_PORT_H_ diff --git a/ports/arm-cr/qk/iar/qp_port.h b/ports/arm-cr/qk/iar/qp_port.h index 929621ff4..cecb46ac0 100644 --- a/ports/arm-cr/qk/iar/qp_port.h +++ b/ports/arm-cr/qk/iar/qp_port.h @@ -1,15 +1,16 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -17,22 +18,15 @@ // Plagiarizing this software to sidestep the license obligations is illegal. // // NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. // // Quantum Leaps contact information: // // //============================================================================ -//! @date Last updated on: 2023-09-30 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QP/C port to ARM Cortex-R, preemptive QK kernel, IAR-ARM - #ifndef QP_PORT_H_ #define QP_PORT_H_ diff --git a/ports/arm-cr/qk/iar/qs_port.h b/ports/arm-cr/qk/iar/qs_port.h index cdb29f7d9..33a953307 100644 --- a/ports/arm-cr/qk/iar/qs_port.h +++ b/ports/arm-cr/qk/iar/qs_port.h @@ -1,38 +1,31 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Version 8.0.2 // // 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. +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// The terms of the open source GNU General Public License version 3 -// can be found at: +// SPDX-License-Identifier: LicenseRef-QL-commercial // -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// This software is licensed under the terms of the Quantum Leaps commercial +// licenses. Please contact Quantum Leaps for more information about the +// available licensing options. // -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. +// RESTRICTIONS +// You may NOT : +// (a) redistribute, encumber, sell, rent, lease, sublicense, or otherwise +// transfer rights in this software, +// (b) remove or alter any trademark, logo, copyright or other proprietary +// notices, legends, symbols or labels present in this software, +// (c) plagiarize this software to sidestep the licensing obligations. // -// Contact information: -// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. - #ifndef QS_PORT_H_ #define QS_PORT_H_ diff --git a/ports/arm-cr/qk/ti/qp_port.h b/ports/arm-cr/qk/ti/qp_port.h index 22349b1f2..81c7933d1 100644 --- a/ports/arm-cr/qk/ti/qp_port.h +++ b/ports/arm-cr/qk/ti/qp_port.h @@ -1,15 +1,16 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -17,22 +18,15 @@ // Plagiarizing this software to sidestep the license obligations is illegal. // // NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. // // Quantum Leaps contact information: // // //============================================================================ -//! @date Last updated on: 2023-09-30 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QP/C port to ARM Cortex-R, preemptive QK kernel, TI-ARM - #ifndef QP_PORT_H_ #define QP_PORT_H_ diff --git a/ports/arm-cr/qk/ti/qs_port.h b/ports/arm-cr/qk/ti/qs_port.h index cdb29f7d9..33a953307 100644 --- a/ports/arm-cr/qk/ti/qs_port.h +++ b/ports/arm-cr/qk/ti/qs_port.h @@ -1,38 +1,31 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Version 8.0.2 // // 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. +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// The terms of the open source GNU General Public License version 3 -// can be found at: +// SPDX-License-Identifier: LicenseRef-QL-commercial // -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// This software is licensed under the terms of the Quantum Leaps commercial +// licenses. Please contact Quantum Leaps for more information about the +// available licensing options. // -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. +// RESTRICTIONS +// You may NOT : +// (a) redistribute, encumber, sell, rent, lease, sublicense, or otherwise +// transfer rights in this software, +// (b) remove or alter any trademark, logo, copyright or other proprietary +// notices, legends, symbols or labels present in this software, +// (c) plagiarize this software to sidestep the licensing obligations. // -// Contact information: -// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. - #ifndef QS_PORT_H_ #define QS_PORT_H_ diff --git a/ports/arm-cr/qv/gnu/qp_port.h b/ports/arm-cr/qv/gnu/qp_port.h index 4d565efc2..4d4ea1913 100644 --- a/ports/arm-cr/qv/gnu/qp_port.h +++ b/ports/arm-cr/qv/gnu/qp_port.h @@ -1,15 +1,16 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -17,22 +18,15 @@ // Plagiarizing this software to sidestep the license obligations is illegal. // // NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. // // Quantum Leaps contact information: // // //============================================================================ -//! @date Last updated on: 2024-11-22 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QP/C port to ARM Cortex-R, cooperative QV kernel, GNU-ARM - #ifndef QP_PORT_H_ #define QP_PORT_H_ diff --git a/ports/arm-cr/qv/gnu/qs_port.h b/ports/arm-cr/qv/gnu/qs_port.h index cdb29f7d9..33a953307 100644 --- a/ports/arm-cr/qv/gnu/qs_port.h +++ b/ports/arm-cr/qv/gnu/qs_port.h @@ -1,38 +1,31 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Version 8.0.2 // // 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. +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// The terms of the open source GNU General Public License version 3 -// can be found at: +// SPDX-License-Identifier: LicenseRef-QL-commercial // -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// This software is licensed under the terms of the Quantum Leaps commercial +// licenses. Please contact Quantum Leaps for more information about the +// available licensing options. // -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. +// RESTRICTIONS +// You may NOT : +// (a) redistribute, encumber, sell, rent, lease, sublicense, or otherwise +// transfer rights in this software, +// (b) remove or alter any trademark, logo, copyright or other proprietary +// notices, legends, symbols or labels present in this software, +// (c) plagiarize this software to sidestep the licensing obligations. // -// Contact information: -// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. - #ifndef QS_PORT_H_ #define QS_PORT_H_ diff --git a/ports/arm-cr/qv/iar/qp_port.h b/ports/arm-cr/qv/iar/qp_port.h index 5ae2b458d..86cfb0ea7 100644 --- a/ports/arm-cr/qv/iar/qp_port.h +++ b/ports/arm-cr/qv/iar/qp_port.h @@ -1,15 +1,16 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -17,22 +18,15 @@ // Plagiarizing this software to sidestep the license obligations is illegal. // // NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. // // Quantum Leaps contact information: // // //============================================================================ -//! @date Last updated on: 2023-09-30 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QP/C port to Cortex-R, cooperative QV kernel, IAR-ARM - #ifndef QP_PORT_H_ #define QP_PORT_H_ diff --git a/ports/arm-cr/qv/iar/qs_port.h b/ports/arm-cr/qv/iar/qs_port.h index cdb29f7d9..33a953307 100644 --- a/ports/arm-cr/qv/iar/qs_port.h +++ b/ports/arm-cr/qv/iar/qs_port.h @@ -1,38 +1,31 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Version 8.0.2 // // 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. +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// The terms of the open source GNU General Public License version 3 -// can be found at: +// SPDX-License-Identifier: LicenseRef-QL-commercial // -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// This software is licensed under the terms of the Quantum Leaps commercial +// licenses. Please contact Quantum Leaps for more information about the +// available licensing options. // -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. +// RESTRICTIONS +// You may NOT : +// (a) redistribute, encumber, sell, rent, lease, sublicense, or otherwise +// transfer rights in this software, +// (b) remove or alter any trademark, logo, copyright or other proprietary +// notices, legends, symbols or labels present in this software, +// (c) plagiarize this software to sidestep the licensing obligations. // -// Contact information: -// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. - #ifndef QS_PORT_H_ #define QS_PORT_H_ diff --git a/ports/arm-cr/qv/ti/qp_port.h b/ports/arm-cr/qv/ti/qp_port.h index aa9156e89..fd8e96f56 100644 --- a/ports/arm-cr/qv/ti/qp_port.h +++ b/ports/arm-cr/qv/ti/qp_port.h @@ -1,15 +1,16 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -17,22 +18,15 @@ // Plagiarizing this software to sidestep the license obligations is illegal. // // NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. // // Quantum Leaps contact information: // // //============================================================================ -//! @date Last updated on: 2023-09-30 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QP/C port to ARM Cortex-R, cooperative QV kernel, TI-ARM - #ifndef QP_PORT_H_ #define QP_PORT_H_ diff --git a/ports/arm-cr/qv/ti/qs_port.h b/ports/arm-cr/qv/ti/qs_port.h index cdb29f7d9..33a953307 100644 --- a/ports/arm-cr/qv/ti/qs_port.h +++ b/ports/arm-cr/qv/ti/qs_port.h @@ -1,38 +1,31 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Version 8.0.2 // // 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. +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// The terms of the open source GNU General Public License version 3 -// can be found at: +// SPDX-License-Identifier: LicenseRef-QL-commercial // -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// This software is licensed under the terms of the Quantum Leaps commercial +// licenses. Please contact Quantum Leaps for more information about the +// available licensing options. // -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. +// RESTRICTIONS +// You may NOT : +// (a) redistribute, encumber, sell, rent, lease, sublicense, or otherwise +// transfer rights in this software, +// (b) remove or alter any trademark, logo, copyright or other proprietary +// notices, legends, symbols or labels present in this software, +// (c) plagiarize this software to sidestep the licensing obligations. // -// Contact information: -// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. - #ifndef QS_PORT_H_ #define QS_PORT_H_ diff --git a/ports/config/qp_config.h b/ports/config/qp_config.h index 57af53658..00cef0d87 100644 --- a/ports/config/qp_config.h +++ b/ports/config/qp_config.h @@ -1,15 +1,16 @@ //============================================================================ -// QP configuration file (generic) +// QP/C configuration file (generic) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -17,11 +18,10 @@ // Plagiarizing this software to sidestep the license obligations is illegal. // // NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. // // Quantum Leaps contact information: // @@ -37,7 +37,7 @@ // <691=>691 (QP 6.9.1 or newer) // <734=>7.3.4 (QP 7.3.4 or newer) // <9999=>9999 (Latest only) -// QP API backwards compatibility with the QP/C API version. +// QP API backwards compatibility with the QP API version. // Lower QP_API_VERSION values enable backwards compatibility // with lower (older) QP API versions. // For example, QP_API_VERSION==691 will enable the compatibility @@ -185,7 +185,7 @@ // // Enable memory isolation (QF_MEM_ISOLATE) -// Memory isolation (requires MPU) +// Memory isolation (supported in SafeQP only, requires MPU) // NOTE: implies QF_ON_CONTEXT_SW. //#define QF_MEM_ISOLATE // diff --git a/ports/embos/qf_port.c b/ports/embos/qf_port.c index 56faafddf..28de203ff 100644 --- a/ports/embos/qf_port.c +++ b/ports/embos/qf_port.c @@ -1,4 +1,7 @@ //============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 +// // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s @@ -7,7 +10,7 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -15,22 +18,15 @@ // Plagiarizing this software to sidestep the license obligations is illegal. // // NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. // // Quantum Leaps contact information: // // //============================================================================ -//! @date Last updated on: 2024-09-26 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QF/C port to embOS RTOS kernel, generic C11 compiler -//! #define QP_IMPL // this is QP implementation #include "qp_port.h" // QP port #include "qp_pkg.h" // QP package-scope interface @@ -197,9 +193,6 @@ bool QActive_post_(QActive * const me, QEvt const * const e, QF_CRIT_ENTRY(); Q_REQUIRE_INCRIT(200, e != (QEvt *)0); -#ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(201, QEvt_verify_(e)); -#endif // ndef Q_UNSAFE // the number of free slots available in the queue uint_fast16_t const nFree = @@ -229,12 +222,13 @@ bool QActive_post_(QActive * const me, QEvt const * const e, QS_OBJ_PRE(sender); // the sender object QS_SIG_PRE(e->sig); // the signal of the event QS_OBJ_PRE(me); // this active object (recipient) - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_2U8_PRE(e->poolNum_, e->refCtr_); QS_EQC_PRE((QEQueueCtr)nFree); // # free entries QS_EQC_PRE(0U); // min # free entries (unknown) QS_END_PRE() - if (QEvt_getPoolNum_(e) != 0U) { // is it a pool event? + if (e->poolNum_ != 0U) { // is it a pool event? + Q_ASSERT_INCRIT(205, e->refCtr_ < (2U * QF_MAX_ACTIVE)); QEvt_refCtr_inc_(e); // increment the reference counter } QF_CRIT_EXIT(); @@ -252,7 +246,7 @@ bool QActive_post_(QActive * const me, QEvt const * const e, QS_OBJ_PRE(sender); // the sender object QS_SIG_PRE(e->sig); // the signal of the event QS_OBJ_PRE(me); // this active object (recipient) - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); // pool-Id&ref-Count + QS_2U8_PRE(e->poolNum_, e->refCtr_); // pool-Id&ref-Count QS_EQC_PRE(nFree); // # free entries QS_EQC_PRE(margin); // margin requested QS_END_PRE() @@ -267,20 +261,18 @@ void QActive_postLIFO_(QActive * const me, QEvt const * const e) { QF_CRIT_ENTRY(); Q_REQUIRE_INCRIT(300, e != (QEvt *)0); -#ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(301, QEvt_verify_(e)); -#endif // ndef Q_UNSAFE QS_BEGIN_PRE(QS_QF_ACTIVE_POST_LIFO, me->prio) QS_TIME_PRE(); // timestamp QS_SIG_PRE(e->sig); // the signal of this event QS_OBJ_PRE(me); // this active object - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_2U8_PRE(e->poolNum_, e->refCtr_); QS_EQC_PRE(me->eQueue.maxMsg - me->eQueue.nofMsg); // # free QS_EQC_PRE(0U); // min # free entries (unknown) QS_END_PRE() - if (QEvt_getPoolNum_(e) != 0U) { // is it a pool event? + if (e->poolNum_ != 0U) { // is it a pool event? + Q_ASSERT_INCRIT(305, e->refCtr_ < (2U * QF_MAX_ACTIVE)); QEvt_refCtr_inc_(e); // increment the reference counter } QF_CRIT_EXIT(); @@ -304,7 +296,7 @@ QEvt const *QActive_get_(QActive * const me) { QS_TIME_PRE(); // timestamp QS_SIG_PRE(e->sig); // the signal of this event QS_OBJ_PRE(me); // this active object - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_2U8_PRE(e->poolNum_, e->refCtr_); QS_EQC_PRE((QEQueueCtr)(me->eQueue.maxMsg - me->eQueue.nofMsg)); QS_END_PRE() diff --git a/ports/embos/qp_port.h b/ports/embos/qp_port.h index d07ded2b7..5db993dee 100644 --- a/ports/embos/qp_port.h +++ b/ports/embos/qp_port.h @@ -1,15 +1,16 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -17,22 +18,15 @@ // Plagiarizing this software to sidestep the license obligations is illegal. // // NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. // // Quantum Leaps contact information: // // //============================================================================ -//! @date Last updated on: 2023-09-30 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QP/C port to embOS RTOS (v5), generic C11 compiler - #ifndef QP_PORT_H_ #define QP_PORT_H_ diff --git a/ports/embos/qs_port.h b/ports/embos/qs_port.h index cdb29f7d9..33a953307 100644 --- a/ports/embos/qs_port.h +++ b/ports/embos/qs_port.h @@ -1,38 +1,31 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Version 8.0.2 // // 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. +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// The terms of the open source GNU General Public License version 3 -// can be found at: +// SPDX-License-Identifier: LicenseRef-QL-commercial // -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// This software is licensed under the terms of the Quantum Leaps commercial +// licenses. Please contact Quantum Leaps for more information about the +// available licensing options. // -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. +// RESTRICTIONS +// You may NOT : +// (a) redistribute, encumber, sell, rent, lease, sublicense, or otherwise +// transfer rights in this software, +// (b) remove or alter any trademark, logo, copyright or other proprietary +// notices, legends, symbols or labels present in this software, +// (c) plagiarize this software to sidestep the licensing obligations. // -// Contact information: -// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. - #ifndef QS_PORT_H_ #define QS_PORT_H_ diff --git a/ports/freertos/qf_port.c b/ports/freertos/qf_port.c index 9352f59c8..e1bceffde 100644 --- a/ports/freertos/qf_port.c +++ b/ports/freertos/qf_port.c @@ -1,4 +1,7 @@ //============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 +// // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s @@ -7,7 +10,7 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -15,25 +18,18 @@ // Plagiarizing this software to sidestep the license obligations is illegal. // // NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. // // Quantum Leaps contact information: // // //============================================================================ -//! @date Last updated on: 2024-10-29 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QF/C port to FreeRTOS 10.x, generic C11 compiler - #define QP_IMPL // this is QP implementation #include "qp_port.h" // QP port -#include "qp_pkg.h" // QP package-level interface +#include "qp_pkg.h" // QP package-scope interface #include "qsafe.h" // QP Functional Safety (FuSa) Subsystem #ifdef Q_SPY // QS software tracing enabled? #include "qs_port.h" // QS port @@ -45,11 +41,11 @@ Q_DEFINE_THIS_MODULE("qf_port") #if ( configSUPPORT_STATIC_ALLOCATION == 0 ) -#error "This QP/C port to FreeRTOS requires configSUPPORT_STATIC_ALLOCATION " + #error This QP/C port to FreeRTOS requires configSUPPORT_STATIC_ALLOCATION #endif #if ( configMAX_PRIORITIES < QF_MAX_ACTIVE ) -#error "FreeRTOS configMAX_PRIORITIES must not be less than QF_MAX_ACTIVE" + #error FreeRTOS configMAX_PRIORITIES must not be less than QF_MAX_ACTIVE #endif // Local objects ------------------------------------------------------------- @@ -129,6 +125,7 @@ static void task_function(void *pvParameters) { // FreeRTOS task signature } //............................................................................ +//! @public @memberof QActive void QActive_start(QActive * const me, QPrioSpec const prioSpec, QEvtPtr * const qSto, @@ -174,7 +171,7 @@ void QActive_start(QActive * const me, // The FreeRTOS priority of the AO thread can be specified in two ways: // - // 1. Implictily based on the AO's priority (by the formula specified + // 1. Implicitly based on the AO's priority (by the formula specified // in the macro FREERTOS_TASK_PRIO(), see qp_port.h). This option // is chosen, when the higher-byte of the prioSpec parameter is set // to zero. @@ -188,7 +185,7 @@ void QActive_start(QActive * const me, // so it is the responsibility of the application to ensure that // it is consistent with the AO's priority. An example of // inconsistent setting would be assigning FreeRTOS priorities that - // would result in a different relative priritization of AO's threads + // would result in a different relative prioritization of AO's threads // than indicated by the AO priorities assigned. // UBaseType_t freertos_prio = (prioSpec >> 8U); @@ -241,6 +238,7 @@ void QActive_setAttr(QActive *const me, uint32_t attr1, void const *attr2) { } //============================================================================ +//! @private @memberof QActive bool QActive_post_(QActive * const me, QEvt const * const e, uint_fast16_t const margin, void const * const sender) { @@ -252,46 +250,48 @@ bool QActive_post_(QActive * const me, QEvt const * const e, QF_CRIT_ENTRY(); Q_REQUIRE_INCRIT(200, e != (QEvt *)0); -#ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(201, QEvt_verify_(e)); -#endif // ndef Q_UNSAFE - // the number of free slots available in the queue + // the number of free slots available in the FreeRTOS queue uint_fast16_t const nFree = (uint_fast16_t)FREERTOS_QUEUE_GET_FREE(me); - bool status; + // required margin available? + bool status = false; // assume that event cannot be posted if (margin == QF_NO_MARGIN) { - if (nFree > 0U) { + if (nFree > 0U) { // free entries available in the queue? status = true; // can post } - else { - status = false; // cannot post + else { // no free entries available + // The queue overflows, but QF_NO_MARGIN indicates that + // the "event delivery guarantee" is required. Q_ERROR_INCRIT(210); // must be able to post the event } } - else if (nFree > (QEQueueCtr)margin) { + else if (nFree > (QEQueueCtr)margin) { // enough free entries? status = true; // can post } else { - status = false; // cannot post + // empty } - if (status) { // can post the event? +#if (QF_MAX_EPOOL > 0U) + if (e->poolNum_ != 0U) { // is it a mutable event? + Q_ASSERT_INCRIT(205, e->refCtr_ < (2U * QF_MAX_ACTIVE)); + QEvt_refCtr_inc_(e); // increment the reference counter + } +#endif // (QF_MAX_EPOOL > 0U) + if (status) { // can post the event? QS_BEGIN_PRE(QS_QF_ACTIVE_POST, me->prio) - QS_TIME_PRE(); // timestamp - QS_OBJ_PRE(sender); // the sender object - QS_SIG_PRE(e->sig); // the signal of the event - QS_OBJ_PRE(me); // this active object (recipient) - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(sender); // the sender object + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this active object (recipient) + QS_2U8_PRE(e->poolNum_, e->refCtr_); QS_EQC_PRE((QEQueueCtr)nFree); // # free entries - QS_EQC_PRE(0U); // min # free entries (unknown) + QS_EQC_PRE(0U); // min # free entries (unknown) QS_END_PRE() - if (QEvt_getPoolNum_(e) != 0U) { // is it a pool event? - QEvt_refCtr_inc_(e); // increment the reference counter - } QF_CRIT_EXIT(); BaseType_t err = xQueueSendToBack( @@ -300,49 +300,57 @@ bool QActive_post_(QActive * const me, QEvt const * const e, QF_CRIT_ENTRY(); // posting to the FreeRTOS message queue must succeed, see NOTE3 Q_ASSERT_INCRIT(220, err == pdPASS); + QF_CRIT_EXIT(); #ifdef Q_UNSAFE Q_UNUSED_PAR(err); #endif } - else { // cannot post the event - + else { // event cannot be posted QS_BEGIN_PRE(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) - QS_TIME_PRE(); // timestamp - QS_OBJ_PRE(sender); // the sender object - QS_SIG_PRE(e->sig); // the signal of the event - QS_OBJ_PRE(me); // this active object (recipient) - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); - QS_EQC_PRE(nFree); // # free entries - QS_EQC_PRE(margin); // margin requested + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(sender); // the sender object + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this active object (recipient) + QS_2U8_PRE(e->poolNum_, e->refCtr_); + QS_EQC_PRE(nFree); // # free entries + QS_EQC_PRE(margin); // margin requested QS_END_PRE() + + QF_CRIT_EXIT(); + +#if (QF_MAX_EPOOL > 0U) + QF_gc(e); // recycle the event to avoid a leak +#endif // (QF_MAX_EPOOL > 0U) } - QF_CRIT_EXIT(); return status; } + //............................................................................ void QActive_postLIFO_(QActive * const me, QEvt const * const e) { QF_CRIT_STAT QF_CRIT_ENTRY(); + // the posted event must be be valid (which includes not NULL) Q_REQUIRE_INCRIT(300, e != (QEvt *)0); -#ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(301, QEvt_verify_(e)); -#endif // ndef Q_UNSAFE + +#if (QF_MAX_EPOOL > 0U) + if (e->poolNum_ != 0U) { // is it a mutable event? + Q_ASSERT_INCRIT(305, e->refCtr_ < (2U * QF_MAX_ACTIVE)); + QEvt_refCtr_inc_(e); // increment the reference counter + } +#endif // (QF_MAX_EPOOL > 0U) QS_BEGIN_PRE(QS_QF_ACTIVE_POST_LIFO, me->prio) - QS_TIME_PRE(); // timestamp - QS_SIG_PRE(e->sig); // the signal of this event - QS_OBJ_PRE(me); // this active object - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_TIME_PRE(); // timestamp + QS_SIG_PRE(e->sig); // the signal of this event + QS_OBJ_PRE(me); // this active object + QS_2U8_PRE(e->poolNum_, e->refCtr_); QS_EQC_PRE((QEQueueCtr)FREERTOS_QUEUE_GET_FREE(me)); // # free - QS_EQC_PRE(0U); // min # free entries (unknown) + QS_EQC_PRE(0U); // min # free entries (unknown) QS_END_PRE() - if (QEvt_getPoolNum_(e) != 0U) { // is it a pool event? - QEvt_refCtr_inc_(e); // increment the reference counter - } QF_CRIT_EXIT(); BaseType_t err = xQueueSendToFront( @@ -368,7 +376,7 @@ QEvt const *QActive_get_(QActive * const me) { QS_TIME_PRE(); // timestamp QS_SIG_PRE(e->sig); // the signal of this event QS_OBJ_PRE(me); // this active object - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_2U8_PRE(e->poolNum_, e->refCtr_); QS_EQC_PRE((QEQueueCtr)FREERTOS_QUEUE_GET_FREE(me)); // # free QS_END_PRE() QS_CRIT_EXIT(); @@ -385,75 +393,80 @@ bool QActive_postFromISR_(QActive * const me, QEvt const * const e, { UBaseType_t uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); - Q_REQUIRE_INCRIT(500, e != (QEvt *)0); -#ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(501, QEvt_verify_(e)); -#endif // ndef Q_UNSAFE + Q_REQUIRE_INCRIT(400, e != (QEvt *)0); - // find the number of free slots available in the queue - uint_fast16_t const nFree = (uint_fast16_t)FREERTOS_QUEUE_GET_FREE(me); + // the number of free slots available in the FreeRTOS queue + uint_fast16_t const nFree = + (uint_fast16_t)FREERTOS_QUEUE_GET_FREE(me); - bool status; + // required margin available? + bool status = false; // assume that event cannot be posted if (margin == QF_NO_MARGIN) { - if (nFree > 0U) { + if (nFree > 0U) { // free entries available in the queue? status = true; // can post } - else { - status = false; // cannot post - Q_ERROR_INCRIT(510); // must be able to post the event + else { // no free entries available + // The queue overflows, but QF_NO_MARGIN indicates that + // the "event delivery guarantee" is required. + Q_ERROR_INCRIT(410); // must be able to post the event } } - else if (nFree > margin) { + else if (nFree > (QEQueueCtr)margin) { // enough free entries? status = true; // can post } else { - status = false; // cannot post + // empty } - if (status) { // can post the event? +#if (QF_MAX_EPOOL > 0U) + if (e->poolNum_ != 0U) { // is it a mutable event? + Q_ASSERT_INCRIT(405, e->refCtr_ < (2U * QF_MAX_ACTIVE)); + QEvt_refCtr_inc_(e); // increment the reference counter + } +#endif // (QF_MAX_EPOOL > 0U) + if (status) { // can post the event? QS_BEGIN_PRE(QS_QF_ACTIVE_POST, me->prio) - QS_TIME_PRE(); // timestamp - QS_OBJ_PRE(sender); // the sender object - QS_SIG_PRE(e->sig); // the signal of the event - QS_OBJ_PRE(me); // this active object (recipient) - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr - QS_EQC_PRE(nFree); // # free entries available - QS_EQC_PRE(0U); // min # free entries (unknown) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(sender); // the sender object + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this active object (recipient) + QS_2U8_PRE(e->poolNum_, e->refCtr_); + QS_EQC_PRE((QEQueueCtr)nFree); // # free entries + QS_EQC_PRE(0U); // min # free entries (unknown) QS_END_PRE() - if (QEvt_getPoolNum_(e) != 0U) { // is it a pool event? - QEvt_refCtr_inc_(e); // increment the reference counter - } portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); BaseType_t err = xQueueSendToBackFromISR(me->eQueue, (void const *)&e, pxHigherPriorityTaskWoken); - // posting to the FreeRTOS message queue must succeed uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); - Q_ASSERT_INCRIT(520, err == pdPASS); + // posting to the FreeRTOS message queue must succeed, see NOTE3 + Q_ASSERT_INCRIT(420, err == pdPASS); portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); #ifdef Q_UNSAFE Q_UNUSED_PAR(err); #endif } - else { - + else { // event cannot be posted QS_BEGIN_PRE(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) - QS_TIME_PRE(); // timestamp - QS_OBJ_PRE(sender); // the sender object - QS_SIG_PRE(e->sig); // the signal of the event - QS_OBJ_PRE(me); // this active object (recipient) - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr - QS_EQC_PRE(nFree); // # free entries available - QS_EQC_PRE(margin); // margin requested + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(sender); // the sender object + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this active object (recipient) + QS_2U8_PRE(e->poolNum_, e->refCtr_); + QS_EQC_PRE(nFree); // # free entries + QS_EQC_PRE(margin); // margin requested QS_END_PRE() + portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); +#if (QF_MAX_EPOOL > 0U) QF_gcFromISR(e); // recycle the event to avoid a leak +#endif // (QF_MAX_EPOOL > 0U) } return status; @@ -463,75 +476,90 @@ void QActive_publishFromISR_(QEvt const * const e, BaseType_t * const pxHigherPriorityTaskWoken, void const * const sender) { - Q_REQUIRE_INCRIT(600, e != (QEvt *)0); -#ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(601, QEvt_verify_(e)); -#endif // ndef Q_UNSAFE + Q_REQUIRE_INCRIT(500, e != (QEvt *)0); QSignal const sig = e->sig; UBaseType_t uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); // the published signal must be within the configured range - Q_REQUIRE_INCRIT(610, sig < (QSignal)QActive_maxPubSignal_); - Q_REQUIRE_INCRIT(611, - QPSet_verify_(&QActive_subscrList_[sig].set, - &QActive_subscrList_[sig].set_dis)); + Q_REQUIRE_INCRIT(510, sig < (QSignal)QActive_maxPubSignal_); QS_BEGIN_PRE(QS_QF_PUBLISH, 0U) QS_TIME_PRE(); // the timestamp QS_OBJ_PRE(sender); // the sender object QS_SIG_PRE(sig); // the signal of the event - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_);// pool-Id & ref-Count + QS_2U8_PRE(e->poolNum_, e->refCtr_); QS_END_PRE() - // is it a dynamic event? - if (QEvt_getPoolNum_(e) != 0U) { - // NOTE: The reference counter of a dynamic event is incremented to + // is it a mutable event? + if (e->poolNum_ != 0U) { + // NOTE: The reference counter of a mutable event is incremented to // prevent premature recycling of the event while the multicasting // is still in progress. At the end of the function, the garbage - // collector step (QF_gcFromISR()) decrements the reference counter - // and recycles the event if the counter drops to zero. This covers - // the case when the event was published without any subscribers. + // collector step (QF_gc()) decrements the reference counter and + // recycles the event if the counter drops to zero. This covers the + // case when the event was published without any subscribers. + Q_ASSERT_INCRIT(515, e->refCtr_ < (2U * QF_MAX_ACTIVE)); QEvt_refCtr_inc_(e); } - // make a local, modifiable copy of the subscriber list + // make a local, modifiable copy of the subscriber set QPSet subscrSet = QActive_subscrList_[sig].set; + portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); if (QPSet_notEmpty(&subscrSet)) { // any subscribers? // the highest-prio subscriber uint_fast8_t p = QPSet_findMax(&subscrSet); - // no need to lock the scheduler in the ISR context - do { // loop over all subscribers - // the prio of the AO must be registered with the framework - uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); - Q_ASSERT_INCRIT(620, QActive_registry_[p] != (QActive *)0); - portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); - // QACTIVE_POST_FROM_ISR() asserts if the queue overflows - QACTIVE_POST_FROM_ISR(QActive_registry_[p], e, - pxHigherPriorityTaskWoken, sender); + QActive *a = QActive_registry_[p]; + // the AO must be registered with the framework + Q_ASSERT_INCRIT(520, a != (QActive *)0); + + portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); + + //QF_SCHED_LOCK_(p); // no scheduler locking in FreeRTOS + do { // loop over all subscribers + // QACTIVE_POST() asserts internally if the queue overflows + QACTIVE_POST_FROM_ISR(a, e, pxHigherPriorityTaskWoken, sender); QPSet_remove(&subscrSet, p); // remove the handled subscriber - if (QPSet_notEmpty(&subscrSet)) { // still more subscribers? - p = QPSet_findMax(&subscrSet); // the highest-prio subscriber + if (QPSet_notEmpty(&subscrSet)) { // still more subscribers? + p = QPSet_findMax(&subscrSet); // highest-prio subscriber + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + + a = QActive_registry_[p]; + // the AO must be registered with the framework + Q_ASSERT_INCRIT(530, a != (QActive *)0); + + portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); } else { p = 0U; // no more subscribers } } while (p != 0U); - // no need to unlock the scheduler in the ISR context + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + Q_ASSERT_INCRIT(590, p == 0U); // all subscribers processed + portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); + + //QF_SCHED_UNLOCK_(); // no scheduler locking in FreeRTOS } +#if (QF_MAX_EPOOL > 0U) // The following garbage collection step decrements the reference counter // and recycles the event if the counter drops to zero. This covers both // cases when the event was published with or without any subscribers. QF_gcFromISR(e); +#endif // (QF_MAX_EPOOL > 0U) } + //............................................................................ +//! @private @memberof QTimeEvt void QTimeEvt_tickFromISR_(uint_fast8_t const tickRate, BaseType_t * const pxHigherPriorityTaskWoken, void const * const sender) @@ -542,69 +570,46 @@ void QTimeEvt_tickFromISR_(uint_fast8_t const tickRate, UBaseType_t uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); - Q_REQUIRE_INCRIT(700, tickRate < Q_DIM(QTimeEvt_timeEvtHead_)); + Q_REQUIRE_INCRIT(600, tickRate < Q_DIM(QTimeEvt_timeEvtHead_)); QTimeEvt *prev = &QTimeEvt_timeEvtHead_[tickRate]; +#ifdef Q_SPY QS_BEGIN_PRE(QS_QF_TICK, 0U) ++prev->ctr; QS_TEC_PRE(prev->ctr); // tick ctr QS_U8_PRE(tickRate); // tick rate QS_END_PRE() +#endif // def Q_SPY // scan the linked-list of time events at this rate... - uint_fast8_t lbound = 2U*QF_MAX_ACTIVE; // fixed upper loop bound - for (; lbound > 0U; --lbound) { - Q_ASSERT_INCRIT(710, prev != (QTimeEvt *)0); // sanity check + while (true) { + Q_ASSERT_INCRIT(610, prev != (QTimeEvt *)0); // sanity check QTimeEvt *te = prev->next; // advance down the time evt. list -#ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(711, - Q_PTR2UINT_CAST_(te) == (uintptr_t)~prev->next_dis); -#endif // ndef Q_UNSAFE if (te == (QTimeEvt *)0) { // end of the list? - - // any new time events armed since the last QTimeEvt_tick_()? - if (QTimeEvt_timeEvtHead_[tickRate].act != (void *)0) { -#ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(712, - Q_PTR2UINT_CAST_(QTimeEvt_timeEvtHead_[tickRate].act) - == (uintptr_t)~QTimeEvt_timeEvtHead_dis_[tickRate]); -#endif // ndef Q_UNSAFE - prev->next = QTimeEvt_timeEvtHead_[tickRate].act; - QTimeEvt_timeEvtHead_[tickRate].act = (void *)0; -#ifndef Q_UNSAFE - prev->next_dis = (uintptr_t)~Q_PTR2UINT_CAST_(prev->next); - QTimeEvt_timeEvtHead_dis_[tickRate] = - (uintptr_t)~Q_PTR2UINT_CAST_((void *)0); -#endif // ndef Q_UNSAFE - - te = prev->next; // switch to the new list - } - else { // all currently armed time events are processed + // NO any new time events armed since the last QTimeEvt_tick_()? + if (QTimeEvt_timeEvtHead_[tickRate].act == (void *)0) { break; // terminate the for-loop } + + prev->next = (QTimeEvt*)QTimeEvt_timeEvtHead_[tickRate].act; + QTimeEvt_timeEvtHead_[tickRate].act = (void *)0; + + te = prev->next; // switch to the new list } // the time event 'te' must be valid - Q_ASSERT_INCRIT(720, te != (QTimeEvt *)0); + Q_ASSERT_INCRIT(640, te != (QTimeEvt *)0); - QTimeEvtCtr ctr = te->ctr; -#ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(721, QEvt_verify_(&te->super)); - Q_INVARIANT_INCRIT(722, ctr == (QTimeEvtCtr)~te->ctr_dis); -#endif // ndef Q_UNSAFE + QTimeEvtCtr ctr = te->ctr; // move volatile into temporary if (ctr == 0U) { // time event scheduled for removal? prev->next = te->next; -#ifndef Q_UNSAFE - prev->next_dis = (uintptr_t)~Q_PTR2UINT_CAST_(te->next); -#endif // ndef Q_UNSAFE // mark time event 'te' as NOT linked te->flags &= (uint8_t)(~QTE_FLAG_IS_LINKED & 0xFFU); - // do NOT advance the prev pointer // exit crit. section to reduce latency @@ -612,39 +617,7 @@ void QTimeEvt_tickFromISR_(uint_fast8_t const tickRate, } else if (ctr == 1U) { // is time event about to expire? QActive * const act = (QActive *)te->act; - if (te->interval != 0U) { // periodic time evt? - te->ctr = te->interval; // rearm the time event -#ifndef Q_UNSAFE - te->ctr_dis = (QTimeEvtCtr)~te->interval; -#endif // ndef Q_UNSAFE - prev = te; // advance to this time event - } - else { // one-shot time event: automatically disarm - te->ctr = 0U; - prev->next = te->next; -#ifndef Q_UNSAFE - te->ctr_dis = (QTimeEvtCtr)~0U; - prev->next_dis = (uintptr_t)~Q_PTR2UINT_CAST_(te->next); -#endif // ndef Q_UNSAFE - - // mark time event 'e' as NOT linked - te->flags &= (uint8_t)(~QTE_FLAG_IS_LINKED & 0xFFU); - // do NOT advance the prev pointer - - QS_BEGIN_PRE(QS_QF_TIMEEVT_AUTO_DISARM, act->prio) - QS_OBJ_PRE(te); // this time event object - QS_OBJ_PRE(act); // the target AO - QS_U8_PRE(tickRate); // tick rate - QS_END_PRE() - } - - QS_BEGIN_PRE(QS_QF_TIMEEVT_POST, act->prio) - QS_TIME_PRE(); // timestamp - QS_OBJ_PRE(te); // the time event object - QS_SIG_PRE(te->super.sig);// signal of this time event - QS_OBJ_PRE(act); // the target AO - QS_U8_PRE(tickRate); // tick rate - QS_END_PRE() + prev = QTimeEvt_expire_(te, prev, act, tickRate); portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); @@ -656,10 +629,6 @@ void QTimeEvt_tickFromISR_(uint_fast8_t const tickRate, else { // time event keeps timing out --ctr; // decrement the tick counter te->ctr = ctr; // update the original -#ifndef Q_UNSAFE - te->ctr_dis = (QTimeEvtCtr)~ctr; -#endif // ndef Q_UNSAFE - prev = te; // advance to this time event portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); @@ -668,16 +637,15 @@ void QTimeEvt_tickFromISR_(uint_fast8_t const tickRate, uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); } - Q_ENSURE_INCRIT(890, lbound > 0U); - portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); } + //............................................................................ QEvt *QF_newXFromISR_(uint_fast16_t const evtSize, uint_fast16_t const margin, enum_t const sig) { - // find the pool index that fits the requested event size... - uint_fast8_t poolNum = 0U; // zero-based poolNum initially + // find the pool number that fits the requested event size... + uint8_t poolNum = 0U; // zero-based poolNum initially for (; poolNum < QF_priv_.maxPool_; ++poolNum) { if (evtSize <= QF_EPOOL_EVENT_SIZE_(QF_priv_.ePool_[poolNum])) { break; @@ -688,31 +656,31 @@ QEvt *QF_newXFromISR_(uint_fast16_t const evtSize, // precondition: // - cannot run out of registered pools - Q_REQUIRE_INCRIT(800, poolNum < QF_priv_.maxPool_); + Q_REQUIRE_INCRIT(700, poolNum < QF_priv_.maxPool_); ++poolNum; // convert to 1-based poolNum portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); // get event e (port-dependent)... + QEvt *e; #ifdef Q_SPY - QEvt *e = QMPool_getFromISR(&QF_priv_.ePool_[poolNum - 1U], + e = QMPool_getFromISR(&QF_priv_.ePool_[poolNum - 1U], ((margin != QF_NO_MARGIN) ? margin : 0U), (uint_fast8_t)QS_EP_ID + poolNum); #else - QEvt *e = QMPool_getFromISR(&QF_priv_.ePool_[poolNum - 1U], + e = QMPool_getFromISR(&QF_priv_.ePool_[poolNum - 1U], ((margin != QF_NO_MARGIN) ? margin : 0U), 0U); #endif if (e != (QEvt *)0) { // was e allocated correctly? - e->sig = (QSignal)sig; // set the signal - e->refCtr_ = 0U; // initialize the reference counter to 0 - e->evtTag_ = (uint8_t)((poolNum << 4U) | 0x0FU); + e->sig = (QSignal)sig; // set the signal + e->poolNum_ = poolNum; + e->refCtr_ = 0U; #ifdef Q_SPY uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); - QS_BEGIN_PRE(QS_QF_NEW, - (uint_fast8_t)QS_EP_ID + poolNum) + QS_BEGIN_PRE(QS_QF_NEW, (uint_fast8_t)QS_EP_ID + poolNum) QS_TIME_PRE(); // timestamp QS_EVS_PRE(evtSize); // the size of the event QS_SIG_PRE(sig); // the signal of the event @@ -726,7 +694,7 @@ QEvt *QF_newXFromISR_(uint_fast16_t const evtSize, // This assertion means that the event allocation failed, // and this failure cannot be tolerated. The most frequent // reason is an event leak in the application. - Q_ASSERT_INCRIT(820, margin != QF_NO_MARGIN); + Q_ASSERT_INCRIT(720, margin != QF_NO_MARGIN); QS_BEGIN_PRE(QS_QF_NEW_ATTEMPT, (uint_fast8_t)QS_EP_ID + poolNum) @@ -746,12 +714,9 @@ QEvt *QF_newXFromISR_(uint_fast16_t const evtSize, void QF_gcFromISR(QEvt const * const e) { UBaseType_t uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); - Q_REQUIRE_INCRIT(700, e != (QEvt *)0); -#ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(701, QEvt_verify_(e)); -#endif + Q_REQUIRE_INCRIT(800, e != (QEvt *)0); - uint_fast8_t const poolNum = QEvt_getPoolNum_(e); + uint8_t const poolNum = e->poolNum_; if (poolNum != 0U) { // is it a pool event (mutable)? @@ -764,6 +729,7 @@ void QF_gcFromISR(QEvt const * const e) { QS_2U8_PRE(poolNum, e->refCtr_); QS_END_PRE() + Q_ASSERT_INCRIT(805, e->refCtr_ > 0U); QEvt_refCtr_dec_(e); // decrement the ref counter portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); @@ -778,15 +744,15 @@ void QF_gcFromISR(QEvt const * const e) { QS_END_PRE() // pool number must be in range - Q_ASSERT_INCRIT(710, (poolNum <= QF_priv_.maxPool_) - && (poolNum <= QF_MAX_EPOOL)); - + Q_ASSERT_INCRIT(810, (poolNum <= QF_priv_.maxPool_) + && (poolNum <= QF_MAX_EPOOL)); portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); + // NOTE: casting 'const' away is legit because 'e' is a pool event #ifdef Q_SPY // cast 'const' away in (QEvt *)e is OK because it's a pool event QMPool_putFromISR(&QF_priv_.ePool_[poolNum - 1U], (QEvt *)e, - (uint_fast8_t)QS_EP_ID + QEvt_getPoolNum_(e)); + (uint_fast8_t)QS_EP_ID + e->poolNum_); #else QMPool_putFromISR(&QF_priv_.ePool_[poolNum - 1U], (QEvt *)e, 0U); #endif @@ -800,80 +766,57 @@ void QF_gcFromISR(QEvt const * const e) { void *QMPool_getFromISR(QMPool * const me, uint_fast16_t const margin, uint_fast8_t const qsId) { - #ifndef Q_SPY +#ifndef Q_SPY Q_UNUSED_PAR(qsId); - #endif +#endif UBaseType_t uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); // get volatile into temporaries - QFreeBlock *fb = me->free_head; + void * *pfb = me->freeHead; // pointer to free block QMPoolCtr nFree = me->nFree; - #ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(801, Q_PTR2UINT_CAST_(fb) - == (uintptr_t)~me->free_head_dis); - Q_INVARIANT_INCRIT(802, nFree == (QMPoolCtr)~me->nFree_dis); - #endif // ndef Q_UNSAFE - // have more free blocks than the requested margin? if (nFree > (QMPoolCtr)margin) { - Q_ASSERT_INCRIT(810, fb != (QFreeBlock *)0); - - QFreeBlock * const fb_next = fb->next; // fast temporary + Q_ASSERT_INCRIT(910, pfb != (void**)0); - #ifndef Q_UNSAFE - // the free block must have integrity (duplicate inverse storage) - Q_INVARIANT_INCRIT(811, Q_PTR2UINT_CAST_(fb_next) - == (uintptr_t)~fb->next_dis); - #endif // ndef Q_UNSAFE + void ** const pfb_next = pfb[0]; // fast temporary --nFree; // one less free block if (nFree == 0U) { // is the pool becoming empty? // pool is becoming empty, so the next free block must be NULL - Q_ASSERT_INCRIT(820, fb_next == (QFreeBlock *)0); + Q_ASSERT_INCRIT(920, pfb_next == (void**)0); - me->nFree = 0U; - #ifndef Q_UNSAFE - me->nFree_dis = (QMPoolCtr)~0U; - me->nMin = 0U; // remember that the pool got empty - #endif // ndef Q_UNSAFE + me->nFree = 0U; // no more free blocks + me->nMin = 0U; // remember that the pool got empty } - else { - me->nFree = nFree; - #ifndef Q_UNSAFE - me->nFree_dis = (QMPoolCtr)~nFree; - - // The pool is not empty, so the next free-block pointer - // must be in range. - Q_INVARIANT_INCRIT(830, - (me->start <= fb_next) && (fb_next <= me->end)); - - // is the # free blocks the new minimum so far? - if (me->nMin > nFree) { + else { // the pool is NOT empty + + // the next free-block pointer must be in range + Q_ASSERT_INCRIT(930, + (me->start <= pfb_next) && (pfb_next <= me->end)); + + me->nFree = nFree; // update the original + if (me->nMin > nFree) { // is this the new minimum? me->nMin = nFree; // remember the minimum so far } - #endif // ndef Q_UNSAFE } - me->free_head = fb_next; // set the head to the next free block - #ifndef Q_UNSAFE - me->free_head_dis = (uintptr_t)(~Q_PTR2UINT_CAST_(fb_next)); - #endif // ndef Q_UNSAFE + me->freeHead = pfb_next; // set the head to the next free block + + // change the allocated block contents so that it is different + // than a free block inside the pool. + pfb[0] = &me->end[1]; // invalid location beyond the end QS_BEGIN_PRE(QS_QF_MPOOL_GET, qsId) QS_TIME_PRE(); // timestamp QS_OBJ_PRE(me); // this memory pool - QS_MPC_PRE(nFree); // # of free blocks in the pool - #ifndef Q_UNSAFE + QS_MPC_PRE(nFree); // # free blocks in the pool QS_MPC_PRE(me->nMin); // min # free blocks ever in the pool - #else - QS_MPC_PRE(0U); // min # free blocks (not available) - #endif // ndef Q_UNSAFE QS_END_PRE() } else { // don't have enough free blocks at this point - fb = (QFreeBlock *)0; + pfb = (void**)0; QS_BEGIN_PRE(QS_QF_MPOOL_GET_ATTEMPT, qsId) QS_TIME_PRE(); // timestamp @@ -885,43 +828,32 @@ void *QMPool_getFromISR(QMPool * const me, uint_fast16_t const margin, portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus); - return fb; // return the block or NULL pointer to the caller + return (void *)pfb; // return the block or NULL pointer to the caller } //............................................................................ void QMPool_putFromISR(QMPool * const me, void *block, uint_fast8_t const qsId) { - #ifndef Q_SPY +#ifndef Q_SPY Q_UNUSED_PAR(qsId); - #endif +#endif - QFreeBlock * const fb = (QFreeBlock *)block; + void * * const pfb = (void * *)block; // pointer to free block UBaseType_t uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); // get volatile into temporaries - QFreeBlock *free_head = me->free_head; + void * * const freeHead = me->freeHead; QMPoolCtr nFree = me->nFree; - #ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(901, Q_PTR2UINT_CAST_(free_head) - == (uintptr_t)~me->free_head_dis); - Q_INVARIANT_INCRIT(902, nFree == (QMPoolCtr)~me->nFree_dis); - #endif // ndef Q_UNSAFE - - Q_REQUIRE_INCRIT(910, nFree < me->nTot); - Q_REQUIRE_INCRIT(911, (me->start <= fb) && (fb <= me->end)); + Q_REQUIRE_INCRIT(1000, nFree < me->nTot); + Q_REQUIRE_INCRIT(1010, (me->start <= pfb) && (pfb <= me->end)); ++nFree; // one more free block in this pool - me->free_head = fb; // set as new head of the free list - me->nFree = nFree; - fb->next = free_head; // link into list - #ifndef Q_UNSAFE - me->free_head_dis = (uintptr_t)(~Q_PTR2UINT_CAST_(fb)); - me->nFree_dis = (QMPoolCtr)~nFree; - fb->next_dis = (uintptr_t)(~Q_PTR2UINT_CAST_(free_head)); - #endif + me->freeHead = pfb; // set as new head of the free list + me->nFree = nFree; + pfb[0] = freeHead; // link into the list QS_BEGIN_PRE(QS_QF_MPOOL_PUT, qsId) QS_TIME_PRE(); // timestamp diff --git a/ports/freertos/qp_port.h b/ports/freertos/qp_port.h index 3dd438373..016d174d9 100644 --- a/ports/freertos/qp_port.h +++ b/ports/freertos/qp_port.h @@ -1,15 +1,16 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -17,22 +18,15 @@ // Plagiarizing this software to sidestep the license obligations is illegal. // // NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. // // Quantum Leaps contact information: // // //============================================================================ -//! @date Last updated on: 2023-09-30 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QP/C port to FreeRTOS 10.x, generic C11 compiler - #ifndef QP_PORT_H_ #define QP_PORT_H_ @@ -48,7 +42,7 @@ #define QACTIVE_OS_OBJ_TYPE StaticQueue_t #define QACTIVE_THREAD_TYPE StaticTask_t -// FreeRTOS requires the "FromISR" API in QP/C++ +// FreeRTOS requires the "FromISR" API in QP/C #define QF_ISR_API 1 // QF interrupt disabling/enabling (task level) diff --git a/ports/freertos/qs_port.h b/ports/freertos/qs_port.h index cdb29f7d9..33a953307 100644 --- a/ports/freertos/qs_port.h +++ b/ports/freertos/qs_port.h @@ -1,38 +1,31 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Version 8.0.2 // // 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. +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// The terms of the open source GNU General Public License version 3 -// can be found at: +// SPDX-License-Identifier: LicenseRef-QL-commercial // -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// This software is licensed under the terms of the Quantum Leaps commercial +// licenses. Please contact Quantum Leaps for more information about the +// available licensing options. // -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. +// RESTRICTIONS +// You may NOT : +// (a) redistribute, encumber, sell, rent, lease, sublicense, or otherwise +// transfer rights in this software, +// (b) remove or alter any trademark, logo, copyright or other proprietary +// notices, legends, symbols or labels present in this software, +// (c) plagiarize this software to sidestep the licensing obligations. // -// Contact information: -// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. - #ifndef QS_PORT_H_ #define QS_PORT_H_ diff --git a/ports/msp430/qk/qp_port.h b/ports/msp430/qk/qp_port.h index aac074811..8bf43b807 100644 --- a/ports/msp430/qk/qp_port.h +++ b/ports/msp430/qk/qp_port.h @@ -1,15 +1,16 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -17,22 +18,15 @@ // Plagiarizing this software to sidestep the license obligations is illegal. // // NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. // // Quantum Leaps contact information: // // //============================================================================ -//! @date Last updated on: 2023-09-30 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QP/C port to MSP430, QK kernel, TI, GNU, IAR compilers - #ifndef QP_PORT_H_ #define QP_PORT_H_ diff --git a/ports/msp430/qk/qs_port.h b/ports/msp430/qk/qs_port.h index e8d3f8f5b..5964d7496 100644 --- a/ports/msp430/qk/qs_port.h +++ b/ports/msp430/qk/qs_port.h @@ -1,38 +1,31 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Version 8.0.2 // // 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. +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// The terms of the open source GNU General Public License version 3 -// can be found at: +// SPDX-License-Identifier: LicenseRef-QL-commercial // -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// This software is licensed under the terms of the Quantum Leaps commercial +// licenses. Please contact Quantum Leaps for more information about the +// available licensing options. // -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. +// RESTRICTIONS +// You may NOT : +// (a) redistribute, encumber, sell, rent, lease, sublicense, or otherwise +// transfer rights in this software, +// (b) remove or alter any trademark, logo, copyright or other proprietary +// notices, legends, symbols or labels present in this software, +// (c) plagiarize this software to sidestep the licensing obligations. // -// Contact information: -// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QS/C port to a 16-bit CPU and a generic C99 compiler. - #ifndef QS_PORT_H_ #define QS_PORT_H_ diff --git a/ports/msp430/qutest/qp_port.h b/ports/msp430/qutest/qp_port.h index 1238ed36e..6d484907d 100644 --- a/ports/msp430/qutest/qp_port.h +++ b/ports/msp430/qutest/qp_port.h @@ -1,38 +1,31 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// SPDX-License-Identifier: LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU -// General Public License (GPL) or under the terms of one of the closed- -// source Quantum Leaps commercial licenses. +// This software is licensed under the terms of the Quantum Leaps commercial +// licenses. Please contact Quantum Leaps for more information about the +// available licensing options. // -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// RESTRICTIONS +// You may NOT : +// (a) redistribute, encumber, sell, rent, lease, sublicense, or otherwise +// transfer rights in this software, +// (b) remove or alter any trademark, logo, copyright or other proprietary +// notices, legends, symbols or labels present in this software, +// (c) plagiarize this software to sidestep the licensing obligations. // // Quantum Leaps contact information: // // //============================================================================ -//! @date Last updated on: 2023-09-30 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QP/C "port" for QUTEST on MSP430, generic C11 compiler - #ifndef QP_PORT_H_ #define QP_PORT_H_ @@ -51,8 +44,8 @@ // QActive event queue type #define QACTIVE_EQUEUE_TYPE QEQueue -// QACTIVE_OS_OBJ_TYPE not used in this port -// QACTIVE_THREAD_TYPE not used in this port +// QACTIVE_OS_OBJ_TYPE not used in this port +// QACTIVE_THREAD_TYPE not used in this port // QF interrupt disable/enable #define QF_INT_DISABLE() (++QS_tstPriv_.intLock) @@ -75,10 +68,11 @@ #include "qequeue.h" // QUTest port uses QEQueue event-queue #include "qmpool.h" // QUTest port uses QMPool memory-pool -#include "qp.h" // QP framework +#include "qp.h" // QP platform-independent public interface //============================================================================ // interface used only inside QF implementation, but not in applications + #ifdef QP_IMPL // QUTest scheduler locking (not used) @@ -86,19 +80,13 @@ #define QF_SCHED_LOCK_(dummy) ((void)0) #define QF_SCHED_UNLOCK_() ((void)0) - // native event queue operations + // native QEQueue operations #define QACTIVE_EQUEUE_WAIT_(me_) ((void)0) -#ifndef Q_UNSAFE #define QACTIVE_EQUEUE_SIGNAL_(me_) \ - QPSet_insert(&QS_tstPriv_.readySet, (uint_fast8_t)(me_)->prio); \ - QPSet_update_(&QS_tstPriv_.readySet, &QS_tstPriv_.readySet_dis) -#else - #define QACTIVE_EQUEUE_SIGNAL_(me_) \ - QPSet_insert(&QF_readySet_, (uint_fast8_t)(me_)->prio) -#endif + QPSet_insert(&QS_tstPriv_.readySet, (uint_fast8_t)(me_)->prio) - // native QF event pool operations - #define QF_EPOOL_TYPE_ QMPool + // native QMPool operations + #define QF_EPOOL_TYPE_ QMPool #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) diff --git a/ports/msp430/qutest/qs_port.h b/ports/msp430/qutest/qs_port.h index e8d3f8f5b..5964d7496 100644 --- a/ports/msp430/qutest/qs_port.h +++ b/ports/msp430/qutest/qs_port.h @@ -1,38 +1,31 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Version 8.0.2 // // 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. +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// The terms of the open source GNU General Public License version 3 -// can be found at: +// SPDX-License-Identifier: LicenseRef-QL-commercial // -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// This software is licensed under the terms of the Quantum Leaps commercial +// licenses. Please contact Quantum Leaps for more information about the +// available licensing options. // -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. +// RESTRICTIONS +// You may NOT : +// (a) redistribute, encumber, sell, rent, lease, sublicense, or otherwise +// transfer rights in this software, +// (b) remove or alter any trademark, logo, copyright or other proprietary +// notices, legends, symbols or labels present in this software, +// (c) plagiarize this software to sidestep the licensing obligations. // -// Contact information: -// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QS/C port to a 16-bit CPU and a generic C99 compiler. - #ifndef QS_PORT_H_ #define QS_PORT_H_ diff --git a/ports/msp430/qv/qp_port.h b/ports/msp430/qv/qp_port.h index 533c0e183..beb9e9c77 100644 --- a/ports/msp430/qv/qp_port.h +++ b/ports/msp430/qv/qp_port.h @@ -1,15 +1,16 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -17,22 +18,15 @@ // Plagiarizing this software to sidestep the license obligations is illegal. // // NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. // // Quantum Leaps contact information: // // //============================================================================ -//! @date Last updated on: 2023-09-30 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QP/C port to MSP430, QV kernel, TI, GNU, IAR compilers - #ifndef QP_PORT_H_ #define QP_PORT_H_ diff --git a/ports/msp430/qv/qs_port.h b/ports/msp430/qv/qs_port.h index e8d3f8f5b..5964d7496 100644 --- a/ports/msp430/qv/qs_port.h +++ b/ports/msp430/qv/qs_port.h @@ -1,38 +1,31 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Version 8.0.2 // // 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. +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// The terms of the open source GNU General Public License version 3 -// can be found at: +// SPDX-License-Identifier: LicenseRef-QL-commercial // -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// This software is licensed under the terms of the Quantum Leaps commercial +// licenses. Please contact Quantum Leaps for more information about the +// available licensing options. // -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. +// RESTRICTIONS +// You may NOT : +// (a) redistribute, encumber, sell, rent, lease, sublicense, or otherwise +// transfer rights in this software, +// (b) remove or alter any trademark, logo, copyright or other proprietary +// notices, legends, symbols or labels present in this software, +// (c) plagiarize this software to sidestep the licensing obligations. // -// Contact information: -// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QS/C port to a 16-bit CPU and a generic C99 compiler. - #ifndef QS_PORT_H_ #define QS_PORT_H_ diff --git a/ports/posix-qv/qf_port.c b/ports/posix-qv/qf_port.c index 2c0796bcd..aef8184af 100644 --- a/ports/posix-qv/qf_port.c +++ b/ports/posix-qv/qf_port.c @@ -1,32 +1,32 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) -// Copyright (C) 2005 Quantum Leaps, LLC . +// Version 8.0.2 // -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// 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. +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// The terms of the open source GNU General Public License version 3 -// can be found at: +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// This software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: +// NOTE: +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. +// +// Quantum Leaps contact information: // // //============================================================================ -//! @date Last updated on: 2024-09-18 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QF/C port to POSIX-QV (single-threaded) // expose features from the 2008 POSIX standard (IEEE Standard 1003.1-2008) #define _POSIX_C_SOURCE 200809L @@ -177,9 +177,6 @@ void QF_init(void) { pthread_cond_init(&QF_condVar_, NULL); QPSet_setEmpty(&QF_readySet_); -#ifndef Q_UNSAFE - QPSet_update_(&QF_readySet_, &QF_readySet_dis_); -#endif // lock memory so we're never swapped out to disk //mlockall(MCL_CURRENT | MCL_FUTURE); // un-comment when supported @@ -253,8 +250,6 @@ int QF_run(void) { QS_END_PRE() while (l_isRunning) { - Q_ASSERT_INCRIT(300, QPSet_verify_(&QF_readySet_, &QF_readySet_dis_)); - // find the maximum priority AO ready to run if (QPSet_notEmpty(&QF_readySet_)) { uint_fast8_t p = QPSet_findMax(&QF_readySet_); @@ -272,9 +267,6 @@ int QF_run(void) { QF_CRIT_ENTRY(); if (a->eQueue.frontEvt == (QEvt *)0) { // empty queue? QPSet_remove(&QF_readySet_, p); -#ifndef Q_UNSAFE - QPSet_update_(&QF_readySet_, &QF_readySet_dis_); -#endif } } else { @@ -308,9 +300,6 @@ void QF_stop(void) { // unblock the event-loop so it can terminate QPSet_insert(&QF_readySet_, 1U); -#ifndef Q_UNSAFE - QPSet_update_(&QF_readySet_, &QF_readySet_dis_); -#endif pthread_cond_signal(&QF_condVar_); } //............................................................................ @@ -395,9 +384,6 @@ void QActive_stop(QActive * const me) { QF_CRIT_STAT QF_CRIT_ENTRY(); QPSet_remove(&QF_readySet_, me->prio); -#ifndef Q_UNSAFE - QPSet_update_(&QF_readySet_, &QF_readySet_dis_); -#endif QF_CRIT_EXIT(); QActive_unregister_(me); diff --git a/ports/posix-qv/qp_port.h b/ports/posix-qv/qp_port.h index 25b41f5e0..7c660c90e 100644 --- a/ports/posix-qv/qp_port.h +++ b/ports/posix-qv/qp_port.h @@ -1,15 +1,16 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -17,22 +18,15 @@ // Plagiarizing this software to sidestep the license obligations is illegal. // // NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. // // Quantum Leaps contact information: // // //============================================================================ -//! @date Last updated on: 2023-09-30 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QP/C port to POSIX-QV (single-threaded) with GNU compiler - #ifndef QP_PORT_H_ #define QP_PORT_H_ @@ -91,16 +85,9 @@ void QF_onClockTick(void); // QF event queue customization for POSIX-QV... #define QACTIVE_EQUEUE_WAIT_(me_) ((void)0) -#ifndef Q_UNSAFE #define QACTIVE_EQUEUE_SIGNAL_(me_) \ QPSet_insert(&QF_readySet_, (me_)->prio); \ - QPSet_update_(&QF_readySet_, &QF_readySet_dis_); \ pthread_cond_signal(&QF_condVar_) -#else - #define QACTIVE_EQUEUE_SIGNAL_(me_) \ - QPSet_insert(&QF_readySet_, (me_)->prio); \ - pthread_cond_signal(&QF_condVar_) -#endif // native QF event pool operations #define QF_EPOOL_TYPE_ QMPool diff --git a/ports/posix-qv/qs_port.c b/ports/posix-qv/qs_port.c index b36c4a6b4..b2e2bff1e 100644 --- a/ports/posix-qv/qs_port.c +++ b/ports/posix-qv/qs_port.c @@ -1,38 +1,37 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// Version 8.0.2 // -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// 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. +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// The terms of the open source GNU General Public License version 3 -// can be found at: +// SPDX-License-Identifier: LicenseRef-QL-commercial // -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// This software is licensed under the terms of the Quantum Leaps commercial +// licenses. Please contact Quantum Leaps for more information about the +// available licensing options. // -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. +// RESTRICTIONS +// You may NOT : +// (a) redistribute, encumber, sell, rent, lease, sublicense, or otherwise +// transfer rights in this software, +// (b) remove or alter any trademark, logo, copyright or other proprietary +// notices, legends, symbols or labels present in this software, +// (c) plagiarize this software to sidestep the licensing obligations. // -// Contact information: -// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2024-07-18 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QS/C port to POSIX // expose features from the 2008 POSIX standard (IEEE Standard 1003.1-2008) #define _POSIX_C_SOURCE 200809L #ifndef Q_SPY - #error "Q_SPY must be defined to compile qs_port.c" + #error Q_SPY must be defined to compile qs_port.c #endif // Q_SPY #define QP_IMPL // this is QP implementation diff --git a/ports/posix-qv/qs_port.h b/ports/posix-qv/qs_port.h index 7f0a9ccbc..8db32128f 100644 --- a/ports/posix-qv/qs_port.h +++ b/ports/posix-qv/qs_port.h @@ -1,38 +1,31 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Version 8.0.2 // // 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. +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// The terms of the open source GNU General Public License version 3 -// can be found at: +// SPDX-License-Identifier: LicenseRef-QL-commercial // -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// This software is licensed under the terms of the Quantum Leaps commercial +// licenses. Please contact Quantum Leaps for more information about the +// available licensing options. // -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. +// RESTRICTIONS +// You may NOT : +// (a) redistribute, encumber, sell, rent, lease, sublicense, or otherwise +// transfer rights in this software, +// (b) remove or alter any trademark, logo, copyright or other proprietary +// notices, legends, symbols or labels present in this software, +// (c) plagiarize this software to sidestep the licensing obligations. // -// Contact information: -// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QS/C port to POSIX with GNU - #ifndef QS_PORT_H_ #define QS_PORT_H_ diff --git a/ports/posix-qv/safe_std.h b/ports/posix-qv/safe_std.h index c752662ca..5cd2f0cdb 100644 --- a/ports/posix-qv/safe_std.h +++ b/ports/posix-qv/safe_std.h @@ -22,11 +22,6 @@ // // //============================================================================ -//! @date Last updated on: 2022-07-30 -//! @version Last updated for: @ref qpc_7_1_3 -//! -//! @file -//! @brief "safe" and facilities #ifndef SAFE_STD_H #define SAFE_STD_H diff --git a/ports/posix/qf_port.c b/ports/posix/qf_port.c index 0b5d94f9f..df3de2c7a 100644 --- a/ports/posix/qf_port.c +++ b/ports/posix/qf_port.c @@ -1,32 +1,32 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) -// Copyright (C) 2005 Quantum Leaps, LLC . +// Version 8.0.2 // -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// 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. +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// The terms of the open source GNU General Public License version 3 -// can be found at: +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// This software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: +// NOTE: +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. +// +// Quantum Leaps contact information: // // //============================================================================ -//! @date Last updated on: 2024-09-18 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QF/C port to POSIX (multithreaded with P-threads) // expose features from the 2008 POSIX standard (IEEE Standard 1003.1-2008) #define _POSIX_C_SOURCE 200809L diff --git a/ports/posix/qp_port.h b/ports/posix/qp_port.h index f193d57d8..e67b5e9d9 100644 --- a/ports/posix/qp_port.h +++ b/ports/posix/qp_port.h @@ -1,15 +1,16 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -17,22 +18,15 @@ // Plagiarizing this software to sidestep the license obligations is illegal. // // NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. // // Quantum Leaps contact information: // // //============================================================================ -//! @date Last updated on: 2024-12-12 -//! @version Last updated for: @ref qpc_8_0_1 -//! -//! @file -//! @brief QP/C port to to POSIX (multithreaded with P-threads) - #ifndef QP_PORT_H_ #define QP_PORT_H_ diff --git a/ports/posix/qs_port.c b/ports/posix/qs_port.c index b36c4a6b4..b2e2bff1e 100644 --- a/ports/posix/qs_port.c +++ b/ports/posix/qs_port.c @@ -1,38 +1,37 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// Version 8.0.2 // -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// 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. +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// The terms of the open source GNU General Public License version 3 -// can be found at: +// SPDX-License-Identifier: LicenseRef-QL-commercial // -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// This software is licensed under the terms of the Quantum Leaps commercial +// licenses. Please contact Quantum Leaps for more information about the +// available licensing options. // -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. +// RESTRICTIONS +// You may NOT : +// (a) redistribute, encumber, sell, rent, lease, sublicense, or otherwise +// transfer rights in this software, +// (b) remove or alter any trademark, logo, copyright or other proprietary +// notices, legends, symbols or labels present in this software, +// (c) plagiarize this software to sidestep the licensing obligations. // -// Contact information: -// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2024-07-18 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QS/C port to POSIX // expose features from the 2008 POSIX standard (IEEE Standard 1003.1-2008) #define _POSIX_C_SOURCE 200809L #ifndef Q_SPY - #error "Q_SPY must be defined to compile qs_port.c" + #error Q_SPY must be defined to compile qs_port.c #endif // Q_SPY #define QP_IMPL // this is QP implementation diff --git a/ports/posix/qs_port.h b/ports/posix/qs_port.h index 7f0a9ccbc..8db32128f 100644 --- a/ports/posix/qs_port.h +++ b/ports/posix/qs_port.h @@ -1,38 +1,31 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Version 8.0.2 // // 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. +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// The terms of the open source GNU General Public License version 3 -// can be found at: +// SPDX-License-Identifier: LicenseRef-QL-commercial // -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// This software is licensed under the terms of the Quantum Leaps commercial +// licenses. Please contact Quantum Leaps for more information about the +// available licensing options. // -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. +// RESTRICTIONS +// You may NOT : +// (a) redistribute, encumber, sell, rent, lease, sublicense, or otherwise +// transfer rights in this software, +// (b) remove or alter any trademark, logo, copyright or other proprietary +// notices, legends, symbols or labels present in this software, +// (c) plagiarize this software to sidestep the licensing obligations. // -// Contact information: -// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QS/C port to POSIX with GNU - #ifndef QS_PORT_H_ #define QS_PORT_H_ diff --git a/ports/posix/safe_std.h b/ports/posix/safe_std.h index c752662ca..5cd2f0cdb 100644 --- a/ports/posix/safe_std.h +++ b/ports/posix/safe_std.h @@ -22,11 +22,6 @@ // // //============================================================================ -//! @date Last updated on: 2022-07-30 -//! @version Last updated for: @ref qpc_7_1_3 -//! -//! @file -//! @brief "safe" and facilities #ifndef SAFE_STD_H #define SAFE_STD_H diff --git a/ports/qep-only/qp_port.h b/ports/qep-only/qp_port.h index b8ea5c659..57007aaaa 100644 --- a/ports/qep-only/qp_port.h +++ b/ports/qep-only/qp_port.h @@ -1,15 +1,16 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -17,22 +18,15 @@ // Plagiarizing this software to sidestep the license obligations is illegal. // // NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. // // Quantum Leaps contact information: // // //============================================================================ -//! @date Last updated on: 2023-09-30 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QP/C dummy port - #ifndef QP_PORT_H_ #define QP_PORT_H_ diff --git a/ports/qep-only/safe_std.h b/ports/qep-only/safe_std.h index c752662ca..5cd2f0cdb 100644 --- a/ports/qep-only/safe_std.h +++ b/ports/qep-only/safe_std.h @@ -22,11 +22,6 @@ // // //============================================================================ -//! @date Last updated on: 2022-07-30 -//! @version Last updated for: @ref qpc_7_1_3 -//! -//! @file -//! @brief "safe" and facilities #ifndef SAFE_STD_H #define SAFE_STD_H diff --git a/ports/qube/qp_port.h b/ports/qube/qp_port.h index be36cfa0e..5efcc5aac 100644 --- a/ports/qube/qp_port.h +++ b/ports/qube/qp_port.h @@ -1,15 +1,16 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -17,22 +18,15 @@ // Plagiarizing this software to sidestep the license obligations is illegal. // // NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. // // Quantum Leaps contact information: // // //============================================================================ -//! @date Last updated on: 2023-09-30 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QP/C port for the "Qube" execution harness (Windows, Linux, macOS) - #ifndef QP_PORT_H_ #define QP_PORT_H_ @@ -82,14 +76,8 @@ extern uint_fast8_t QF_intLock_; // native event queue operations #define QACTIVE_EQUEUE_WAIT_(me_) ((void)0) -#ifndef Q_UNSAFE - #define QACTIVE_EQUEUE_SIGNAL_(me_) \ - QPSet_insert(&QF_readySet_, (uint_fast8_t)(me_)->prio); \ - QPSet_update_(&QF_readySet_, &QF_readySet_dis_) -#else #define QACTIVE_EQUEUE_SIGNAL_(me_) \ QPSet_insert(&QF_readySet_, (uint_fast8_t)(me_)->prio) -#endif // native QF event pool operations #define QF_EPOOL_TYPE_ QMPool diff --git a/ports/qube/qs_port.h b/ports/qube/qs_port.h index 19d2b7133..a755c57af 100644 --- a/ports/qube/qs_port.h +++ b/ports/qube/qs_port.h @@ -1,38 +1,31 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Version 8.0.2 // // 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. +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// The terms of the open source GNU General Public License version 3 -// can be found at: +// SPDX-License-Identifier: LicenseRef-QL-commercial // -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// This software is licensed under the terms of the Quantum Leaps commercial +// licenses. Please contact Quantum Leaps for more information about the +// available licensing options. // -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. +// RESTRICTIONS +// You may NOT : +// (a) redistribute, encumber, sell, rent, lease, sublicense, or otherwise +// transfer rights in this software, +// (b) remove or alter any trademark, logo, copyright or other proprietary +// notices, legends, symbols or labels present in this software, +// (c) plagiarize this software to sidestep the licensing obligations. // -// Contact information: -// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QS/C port for the "Qube" execution harness (Windows, Linux, macOS) - #ifndef QS_PORT_H_ #define QS_PORT_H_ diff --git a/ports/qube/qube.c b/ports/qube/qube.c index 582bf30f9..c4743ee32 100644 --- a/ports/qube/qube.c +++ b/ports/qube/qube.c @@ -1,35 +1,34 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// Version 8.0.2 // -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// 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. +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// The terms of the open source GNU General Public License version 3 -// can be found at: +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// This software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: -// +// NOTE: +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. +// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2024-09-18 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief Qube command-line QP execution environment - #ifndef Q_SPY - #error "Q_SPY must be defined to compile qube.c" + #error Q_SPY must be defined to compile qube.c #endif // Q_SPY #define QP_IMPL // this is QP implementation @@ -215,9 +214,6 @@ static void handle_evts(void) { #endif if (a->eQueue.frontEvt == (QEvt*)0) { // empty queue? QPSet_remove(&QF_readySet_, p); -#ifndef Q_UNSAFE - QPSet_update_(&QF_readySet_, &QF_readySet_dis_); -#endif } } } @@ -270,10 +266,6 @@ void QF_init(void) { QF_bzero_(&QF_intLock_, sizeof(QF_intLock_)); QF_bzero_(&QActive_registry_[0], sizeof(QActive_registry_)); -#ifndef Q_UNSAFE - QPSet_update_(&QF_readySet_, &QF_readySet_dis_); -#endif - l_currAO_name[0] = '\0'; fputs(COLOR_APP, stdout); @@ -296,7 +288,6 @@ void QF_onCleanup(void) { int_t QF_run(void) { QS_CRIT_STAT QS_CRIT_ENTRY(); - QS_MEM_SYS(); // function dictionaries for the standard API QS_FUN_DICTIONARY(&QActive_post_); @@ -307,7 +298,6 @@ int_t QF_run(void) { QS_BEGIN_PRE(QS_QF_RUN, 0U) QS_END_PRE() - QS_MEM_APP(); QS_CRIT_EXIT(); handle_evts(); // handle all events posted so far diff --git a/ports/qube/safe_std.h b/ports/qube/safe_std.h index c752662ca..5cd2f0cdb 100644 --- a/ports/qube/safe_std.h +++ b/ports/qube/safe_std.h @@ -22,11 +22,6 @@ // // //============================================================================ -//! @date Last updated on: 2022-07-30 -//! @version Last updated for: @ref qpc_7_1_3 -//! -//! @file -//! @brief "safe" and facilities #ifndef SAFE_STD_H #define SAFE_STD_H diff --git a/ports/risc-v/qv/gnu/qp_port.h b/ports/risc-v/qv/gnu/qp_port.h index 1da79c982..f4fb998d5 100644 --- a/ports/risc-v/qv/gnu/qp_port.h +++ b/ports/risc-v/qv/gnu/qp_port.h @@ -1,15 +1,16 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -17,22 +18,15 @@ // Plagiarizing this software to sidestep the license obligations is illegal. // // NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. // // Quantum Leaps contact information: // // //============================================================================ -//! @date Last updated on: 2023-09-30 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QP/C port to RISC-V, QV kernel, GNU-RISCV compiler - #ifndef QP_PORT_H_ #define QP_PORT_H_ diff --git a/ports/risc-v/qv/gnu/qs_port.h b/ports/risc-v/qv/gnu/qs_port.h index cdb29f7d9..33a953307 100644 --- a/ports/risc-v/qv/gnu/qs_port.h +++ b/ports/risc-v/qv/gnu/qs_port.h @@ -1,38 +1,31 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Version 8.0.2 // // 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. +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// The terms of the open source GNU General Public License version 3 -// can be found at: +// SPDX-License-Identifier: LicenseRef-QL-commercial // -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// This software is licensed under the terms of the Quantum Leaps commercial +// licenses. Please contact Quantum Leaps for more information about the +// available licensing options. // -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. +// RESTRICTIONS +// You may NOT : +// (a) redistribute, encumber, sell, rent, lease, sublicense, or otherwise +// transfer rights in this software, +// (b) remove or alter any trademark, logo, copyright or other proprietary +// notices, legends, symbols or labels present in this software, +// (c) plagiarize this software to sidestep the licensing obligations. // -// Contact information: -// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. - #ifndef QS_PORT_H_ #define QS_PORT_H_ diff --git a/ports/threadx/qf_port.c b/ports/threadx/qf_port.c index b34574e72..db0f085c3 100644 --- a/ports/threadx/qf_port.c +++ b/ports/threadx/qf_port.c @@ -1,4 +1,7 @@ //============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 +// // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s @@ -7,7 +10,7 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -15,22 +18,15 @@ // Plagiarizing this software to sidestep the license obligations is illegal. // // NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. // // Quantum Leaps contact information: // // //============================================================================ -//! @date Last updated on: 2024-09-26 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QF/C, port to ThreadX - #define QP_IMPL // this is QP implementation #include "qp_port.h" // QP port #include "qp_pkg.h" // QP package-scope interface @@ -154,9 +150,6 @@ bool QActive_post_(QActive * const me, QEvt const * const e, QF_CRIT_ENTRY(); Q_REQUIRE_INCRIT(200, e != (QEvt *)0); -#ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(201, QEvt_verify_(e)); -#endif // ndef Q_UNSAFE uint_fast16_t nFree = (uint_fast16_t)me->eQueue.tx_queue_available_storage; @@ -184,12 +177,13 @@ bool QActive_post_(QActive * const me, QEvt const * const e, QS_OBJ_PRE(sender); // the sender object QS_SIG_PRE(e->sig); // the signal of the event QS_OBJ_PRE(me); // this active object (recipient) - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_2U8_PRE(e->poolNum_, e->refCtr_); QS_EQC_PRE(nFree); // # free entries available QS_EQC_PRE(0U); // min # free entries (unknown) QS_END_PRE() - if (QEvt_getPoolNum_(e) != 0U) { // is it a pool event? + if (e->poolNum_ != 0U) { // is it a pool event? + Q_ASSERT_INCRIT(205, e->refCtr_ < (2U * QF_MAX_ACTIVE)); QEvt_refCtr_inc_(e); // increment the reference counter } QF_CRIT_EXIT(); @@ -208,7 +202,7 @@ bool QActive_post_(QActive * const me, QEvt const * const e, QS_OBJ_PRE(sender); // the sender object QS_SIG_PRE(e->sig); // the signal of the event QS_OBJ_PRE(me); // this active object (recipient) - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_2U8_PRE(e->poolNum_, e->refCtr_); QS_EQC_PRE(nFree); // # free entries available QS_EQC_PRE(0U); // min # free entries (unknown) QS_END_PRE() @@ -224,20 +218,18 @@ void QActive_postLIFO_(QActive * const me, QEvt const * const e) { QF_CRIT_ENTRY(); Q_REQUIRE_INCRIT(300, e != (QEvt *)0); -#ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(301, QEvt_verify_(e)); -#endif // ndef Q_UNSAFE QS_BEGIN_PRE(QS_QF_ACTIVE_POST_LIFO, me->prio) QS_TIME_PRE(); // timestamp QS_SIG_PRE(e->sig); // the signal of this event QS_OBJ_PRE(me); // this active object - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_2U8_PRE(e->poolNum_, e->refCtr_); QS_EQC_PRE(me->eQueue.tx_queue_available_storage); // # free QS_EQC_PRE(0U); // min # free entries (unknown) QS_END_PRE() - if (QEvt_getPoolNum_(e) != 0U) { // is it a pool event? + if (e->poolNum_ != 0U) { // is it a pool event? + Q_ASSERT_INCRIT(305, e->refCtr_ < (2U * QF_MAX_ACTIVE)); QEvt_refCtr_inc_(e); // increment the reference counter } QF_CRIT_EXIT(); @@ -262,7 +254,7 @@ QEvt const *QActive_get_(QActive * const me) { QS_TIME_PRE(); // timestamp QS_SIG_PRE(e->sig); // the signal of this event QS_OBJ_PRE(me); // this active object - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_2U8_PRE(e->poolNum_, e->refCtr_); QS_EQC_PRE(me->eQueue.tx_queue_available_storage);// # free QS_END_PRE() QF_CRIT_EXIT(); diff --git a/ports/threadx/qp_port.h b/ports/threadx/qp_port.h index 9a5e2ca60..875cb37b0 100644 --- a/ports/threadx/qp_port.h +++ b/ports/threadx/qp_port.h @@ -1,15 +1,16 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -17,22 +18,15 @@ // Plagiarizing this software to sidestep the license obligations is illegal. // // NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. // // Quantum Leaps contact information: // // //============================================================================ -//! @date Last updated on: 2023-09-30 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QP/C, port to ThreadX, generic C11 compiler - #ifndef QP_PORT_H_ #define QP_PORT_H_ @@ -52,9 +46,9 @@ #define QF_TX_PRIO_OFFSET 2U #ifndef QF_MAX_ACTIVE -#define QF_MAX_ACTIVE (TX_MAX_PRIORITIES - QF_TX_PRIO_OFFSET) + #define QF_MAX_ACTIVE (TX_MAX_PRIORITIES - QF_TX_PRIO_OFFSET) #else -#error "QF_MAX_ACTIVE shouild not be externally defined in QP-ThreadX port" + #error QF_MAX_ACTIVE shouild not be externally defined in QP-ThreadX port #endif // mapping between QF-priority and TX-priority, see NOTE1 diff --git a/ports/threadx/qs_port.h b/ports/threadx/qs_port.h index cdb29f7d9..33a953307 100644 --- a/ports/threadx/qs_port.h +++ b/ports/threadx/qs_port.h @@ -1,38 +1,31 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Version 8.0.2 // // 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. +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// The terms of the open source GNU General Public License version 3 -// can be found at: +// SPDX-License-Identifier: LicenseRef-QL-commercial // -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// This software is licensed under the terms of the Quantum Leaps commercial +// licenses. Please contact Quantum Leaps for more information about the +// available licensing options. // -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. +// RESTRICTIONS +// You may NOT : +// (a) redistribute, encumber, sell, rent, lease, sublicense, or otherwise +// transfer rights in this software, +// (b) remove or alter any trademark, logo, copyright or other proprietary +// notices, legends, symbols or labels present in this software, +// (c) plagiarize this software to sidestep the licensing obligations. // -// Contact information: -// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. - #ifndef QS_PORT_H_ #define QS_PORT_H_ diff --git a/ports/uc-os2/qf_port.c b/ports/uc-os2/qf_port.c index 216c4d839..7f0f47001 100644 --- a/ports/uc-os2/qf_port.c +++ b/ports/uc-os2/qf_port.c @@ -1,4 +1,7 @@ //============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 +// // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s @@ -7,7 +10,7 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -15,22 +18,15 @@ // Plagiarizing this software to sidestep the license obligations is illegal. // // NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. // // Quantum Leaps contact information: // // //============================================================================ -//! @date Last updated on: 2024-09-26 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QP/C port to uC-OS2, generic C11 compiler -//! #define QP_IMPL // this is QP implementation #include "qp_port.h" // QP port #include "qp_pkg.h" // QP package-scope interface @@ -202,9 +198,6 @@ bool QActive_post_(QActive * const me, QEvt const * const e, QF_CRIT_ENTRY(); Q_REQUIRE_INCRIT(200, e != (QEvt *)0); -#ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(201, QEvt_verify_(e)); -#endif uint_fast16_t const nFree = (uint_fast16_t)(((OS_Q_DATA *)me->eQueue)->OSQSize @@ -233,12 +226,13 @@ bool QActive_post_(QActive * const me, QEvt const * const e, QS_OBJ_PRE(sender); // the sender object QS_SIG_PRE(e->sig); // the signal of the event QS_OBJ_PRE(me); // this active object (recipient) - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_2U8_PRE(e->poolNum_, e->refCtr_); QS_EQC_PRE(nFree); // # free entries QS_EQC_PRE(0U); // min # free entries (unknown) QS_END_PRE() - if (QEvt_getPoolNum_(e) != 0U) { // is it a pool event? + if (e->poolNum_ != 0U) { // is it a pool event? + Q_ASSERT_INCRIT(205, e->refCtr_ < (2U * QF_MAX_ACTIVE)); QEvt_refCtr_inc_(e); // increment the reference counter } QF_CRIT_EXIT(); @@ -261,7 +255,7 @@ bool QActive_post_(QActive * const me, QEvt const * const e, QS_OBJ_PRE(sender); // the sender object QS_SIG_PRE(e->sig); // the signal of the event QS_OBJ_PRE(me); // this active object (recipient) - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_2U8_PRE(e->poolNum_, e->refCtr_); QS_EQC_PRE(nFree); // # free entries available QS_EQC_PRE(margin); // margin requested QS_END_PRE() @@ -277,21 +271,19 @@ void QActive_postLIFO_(QActive * const me, QEvt const * const e) { QF_CRIT_ENTRY(); Q_REQUIRE_INCRIT(300, e != (QEvt *)0); -#ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(301, QEvt_verify_(e)); -#endif QS_BEGIN_PRE(QS_QF_ACTIVE_POST_LIFO, me->prio) QS_TIME_PRE(); // timestamp QS_SIG_PRE(e->sig); // the signal of this event QS_OBJ_PRE(me); // this active object - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_2U8_PRE(e->poolNum_, e->refCtr_); QS_EQC_PRE(((OS_Q *)me->eQueue)->OSQSize - ((OS_Q *)me->eQueue)->OSQEntries); // # free entries QS_EQC_PRE(0U); // min # free entries (unknown) QS_END_PRE() - if (QEvt_getPoolNum_(e) != 0U) { // is it a pool event? + if (e->poolNum_ != 0U) { // is it a pool event? + Q_ASSERT_INCRIT(305, e->refCtr_ < (2U * QF_MAX_ACTIVE)); QEvt_refCtr_inc_(e); // increment the reference counter } QF_CRIT_EXIT(); @@ -320,7 +312,7 @@ QEvt const *QActive_get_(QActive * const me) { QS_TIME_PRE(); // timestamp QS_SIG_PRE(e->sig); // the signal of this event QS_OBJ_PRE(me); // this active object - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_2U8_PRE(e->poolNum_, e->refCtr_); QS_EQC_PRE(((OS_Q *)me->eQueue)->OSQSize - ((OS_Q *)me->eQueue)->OSQEntries); // # free entries QS_END_PRE() diff --git a/ports/uc-os2/qp_port.h b/ports/uc-os2/qp_port.h index 268951447..55988768a 100644 --- a/ports/uc-os2/qp_port.h +++ b/ports/uc-os2/qp_port.h @@ -1,15 +1,16 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -17,22 +18,15 @@ // Plagiarizing this software to sidestep the license obligations is illegal. // // NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. // // Quantum Leaps contact information: // // //============================================================================ -//! @date Last updated on: 2023-09-30 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QP/C port to uC-OS2, generic C11 compiler - #ifndef QP_PORT_H_ #define QP_PORT_H_ diff --git a/ports/uc-os2/qs_port.h b/ports/uc-os2/qs_port.h index cdb29f7d9..33a953307 100644 --- a/ports/uc-os2/qs_port.h +++ b/ports/uc-os2/qs_port.h @@ -1,38 +1,31 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Version 8.0.2 // // 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. +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// The terms of the open source GNU General Public License version 3 -// can be found at: +// SPDX-License-Identifier: LicenseRef-QL-commercial // -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// This software is licensed under the terms of the Quantum Leaps commercial +// licenses. Please contact Quantum Leaps for more information about the +// available licensing options. // -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. +// RESTRICTIONS +// You may NOT : +// (a) redistribute, encumber, sell, rent, lease, sublicense, or otherwise +// transfer rights in this software, +// (b) remove or alter any trademark, logo, copyright or other proprietary +// notices, legends, symbols or labels present in this software, +// (c) plagiarize this software to sidestep the licensing obligations. // -// Contact information: -// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. - #ifndef QS_PORT_H_ #define QS_PORT_H_ diff --git a/ports/win32-qv/qf_port.c b/ports/win32-qv/qf_port.c index d5e87cbb1..6538d8a2e 100644 --- a/ports/win32-qv/qf_port.c +++ b/ports/win32-qv/qf_port.c @@ -1,33 +1,32 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) -// Copyright (C) 2005 Quantum Leaps, LLC . +// Version 8.0.2 // -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// 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. +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// The terms of the open source GNU General Public License version 3 -// can be found at: +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// This software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: +// NOTE: +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. +// +// Quantum Leaps contact information: // // //============================================================================ -//! @date Last updated on: 2024-09-19 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QF/C port to Win32-QV (single-threaded) - #define QP_IMPL // this is QP implementation #include "qp_port.h" // QP port #include "qp_pkg.h" // QP package-scope interface @@ -104,9 +103,6 @@ void QF_init(void) { QF_win32Event_ = CreateEvent(NULL, FALSE, FALSE, NULL); QPSet_setEmpty(&QF_readySet_); -#ifndef Q_UNSAFE - QPSet_update_(&QF_readySet_, &QF_readySet_dis_); -#endif QTimeEvt_init(); // initialize QTimeEvts } @@ -140,8 +136,6 @@ int QF_run(void) { QS_END_PRE() while (l_isRunning) { - Q_ASSERT_INCRIT(300, QPSet_verify_(&QF_readySet_, &QF_readySet_dis_)); - // find the maximum priority AO ready to run if (QPSet_notEmpty(&QF_readySet_)) { uint_fast8_t p = QPSet_findMax(&QF_readySet_); @@ -159,9 +153,6 @@ int QF_run(void) { QF_CRIT_ENTRY(); if (a->eQueue.frontEvt == (QEvt *)0) { // empty queue? QPSet_remove(&QF_readySet_, p); -#ifndef Q_UNSAFE - QPSet_update_(&QF_readySet_, &QF_readySet_dis_); -#endif } } else { @@ -191,9 +182,6 @@ void QF_stop(void) { // unblock the event-loop so it can terminate QPSet_insert(&QF_readySet_, 1U); -#ifndef Q_UNSAFE - QPSet_update_(&QF_readySet_, &QF_readySet_dis_); -#endif SetEvent(QF_win32Event_); } //............................................................................ @@ -268,9 +256,6 @@ void QActive_stop(QActive * const me) { QF_CRIT_STAT QF_CRIT_ENTRY(); QPSet_remove(&QF_readySet_, me->prio); -#ifndef Q_UNSAFE - QPSet_update_(&QF_readySet_, &QF_readySet_dis_); -#endif QF_CRIT_EXIT(); QActive_unregister_(me); diff --git a/ports/win32-qv/qp_port.h b/ports/win32-qv/qp_port.h index 19931f230..b0784c2e7 100644 --- a/ports/win32-qv/qp_port.h +++ b/ports/win32-qv/qp_port.h @@ -1,15 +1,16 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -17,22 +18,15 @@ // Plagiarizing this software to sidestep the license obligations is illegal. // // NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. // // Quantum Leaps contact information: // // //============================================================================ -//! @date Last updated on: 2023-09-30 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QP/C port to Win32-QV (single-threaded) with GNU or Visual C/C++ - #ifndef QP_PORT_H_ #define QP_PORT_H_ @@ -54,7 +48,7 @@ #define Q_NORETURN _Noreturn void #endif - // This is the case where QP/C is compiled by the Microsoft Visual C++ + // This is the case where QP is compiled by the Microsoft Visual C++ // compiler in the C++ mode, which can happen when qep_port.h is included // in a C++ module, or the compilation is forced to C++ by the option /TP. // @@ -62,7 +56,7 @@ // and C4610, which warn that default constructors and assignment operators // could not be generated for structures QMState and QMTranActTable. // - // The QP/C source code cannot be changed to avoid these C++ warnings + // The QP source code cannot be changed to avoid these C++ warnings // because the structures QMState and QMTranActTable must remain PODs // (Plain Old Datatypes) to be initializable statically with constant // initializers. @@ -129,16 +123,9 @@ void QF_onClockTick(void); // QF event queue customization for Win32-QV... #define QACTIVE_EQUEUE_WAIT_(me_) ((void)0) -#ifndef Q_UNSAFE #define QACTIVE_EQUEUE_SIGNAL_(me_) \ QPSet_insert(&QF_readySet_, (me_)->prio); \ - QPSet_update_(&QF_readySet_, &QF_readySet_dis_); \ (void)SetEvent(QF_win32Event_) -#else - #define QACTIVE_EQUEUE_SIGNAL_(me_) \ - QPSet_insert(&QF_readySet_, (me_)->prio); \ - (void)SetEvent(QF_win32Event_) -#endif // native QF event pool operations #define QF_EPOOL_TYPE_ QMPool diff --git a/ports/win32-qv/qs_port.c b/ports/win32-qv/qs_port.c index daeee934b..3411e8b2a 100644 --- a/ports/win32-qv/qs_port.c +++ b/ports/win32-qv/qs_port.c @@ -1,35 +1,33 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// Version 8.0.2 // -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// 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. +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// The terms of the open source GNU General Public License version 3 -// can be found at: +// SPDX-License-Identifier: LicenseRef-QL-commercial // -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// This software is licensed under the terms of the Quantum Leaps commercial +// licenses. Please contact Quantum Leaps for more information about the +// available licensing options. // -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. +// RESTRICTIONS +// You may NOT : +// (a) redistribute, encumber, sell, rent, lease, sublicense, or otherwise +// transfer rights in this software, +// (b) remove or alter any trademark, logo, copyright or other proprietary +// notices, legends, symbols or labels present in this software, +// (c) plagiarize this software to sidestep the licensing obligations. // -// Contact information: -// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2024-06-11 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QS/C port for Win32 API - #ifndef Q_SPY - #error "Q_SPY must be defined to compile qs_port.c" + #error Q_SPY must be defined to compile qs_port.c #endif // Q_SPY #define QP_IMPL // this is QP implementation diff --git a/ports/win32-qv/qs_port.h b/ports/win32-qv/qs_port.h index 3454f6040..3a8e64e23 100644 --- a/ports/win32-qv/qs_port.h +++ b/ports/win32-qv/qs_port.h @@ -1,38 +1,31 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Version 8.0.2 // // 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. +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// The terms of the open source GNU General Public License version 3 -// can be found at: +// SPDX-License-Identifier: LicenseRef-QL-commercial // -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// This software is licensed under the terms of the Quantum Leaps commercial +// licenses. Please contact Quantum Leaps for more information about the +// available licensing options. // -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. +// RESTRICTIONS +// You may NOT : +// (a) redistribute, encumber, sell, rent, lease, sublicense, or otherwise +// transfer rights in this software, +// (b) remove or alter any trademark, logo, copyright or other proprietary +// notices, legends, symbols or labels present in this software, +// (c) plagiarize this software to sidestep the licensing obligations. // -// Contact information: -// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QS/C port to Win32 with GNU or Visual C++ compilers - #ifndef QS_PORT_H_ #define QS_PORT_H_ diff --git a/ports/win32-qv/qwin_gui.c b/ports/win32-qv/qwin_gui.c index eb61ece06..ac9ce72a0 100644 --- a/ports/win32-qv/qwin_gui.c +++ b/ports/win32-qv/qwin_gui.c @@ -1,34 +1,32 @@ //============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// QWIN GUI facilities for building realistic embedded front panels +// Version 8.0.2 // -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// 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. +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// The terms of the open source GNU General Public License version 3 -// can be found at: +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// This software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: -// +// NOTE: +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. +// +// Quantum Leaps contact information: +// // //============================================================================ -//! -//! @date Last updated on: 2022-06-12 -//! @version Last updated for: @ref qpc_7_0_1 -//! -//! @file -//! @brief QWIN GUI facilities for building realistic embedded front panels -//! #include "qwin_gui.h" #include diff --git a/ports/win32-qv/qwin_gui.h b/ports/win32-qv/qwin_gui.h index 36a517e58..b1062f126 100644 --- a/ports/win32-qv/qwin_gui.h +++ b/ports/win32-qv/qwin_gui.h @@ -1,34 +1,32 @@ //============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// QWIN GUI facilities for building realistic embedded front panels +// Version 8.0.2 // -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// 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. +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// The terms of the open source GNU General Public License version 3 -// can be found at: +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// This software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: -// +// NOTE: +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. +// +// Quantum Leaps contact information: +// // //============================================================================ -//! -//! @date Last updated on: 2022-06-12 -//! @version Last updated for: @ref qpc_7_0_1 -//! -//! @file -//! @brief QWIN GUI facilities for building realistic embedded front panels -//! #ifndef QWIN_GUI_H #define QWIN_GUI_H diff --git a/ports/win32-qv/safe_std.h b/ports/win32-qv/safe_std.h index c752662ca..5cd2f0cdb 100644 --- a/ports/win32-qv/safe_std.h +++ b/ports/win32-qv/safe_std.h @@ -22,11 +22,6 @@ // // //============================================================================ -//! @date Last updated on: 2022-07-30 -//! @version Last updated for: @ref qpc_7_1_3 -//! -//! @file -//! @brief "safe" and facilities #ifndef SAFE_STD_H #define SAFE_STD_H diff --git a/ports/win32/qf_port.c b/ports/win32/qf_port.c index 0fb7f955e..635f25bce 100644 --- a/ports/win32/qf_port.c +++ b/ports/win32/qf_port.c @@ -1,33 +1,32 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) -// Copyright (C) 2005 Quantum Leaps, LLC . +// Version 8.0.2 // -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// 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. +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// The terms of the open source GNU General Public License version 3 -// can be found at: +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// This software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: +// NOTE: +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. +// +// Quantum Leaps contact information: // // //============================================================================ -//! @date Last updated on: 2024-09-19 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QF/C port to Win32 (multithreaded) - #define QP_IMPL // this is QP implementation #include "qp_port.h" // QP port #include "qp_pkg.h" // QP package-scope interface diff --git a/ports/win32/qp_port.h b/ports/win32/qp_port.h index 01a994f6f..b6058da10 100644 --- a/ports/win32/qp_port.h +++ b/ports/win32/qp_port.h @@ -1,15 +1,16 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -17,22 +18,15 @@ // Plagiarizing this software to sidestep the license obligations is illegal. // // NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. // // Quantum Leaps contact information: // // //============================================================================ -//! @date Last updated on: 2023-09-30 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QP/C port to Win32 (multithreaded) with GNU or Visual C/C++ - #ifndef QP_PORT_H_ #define QP_PORT_H_ @@ -54,7 +48,7 @@ #define Q_NORETURN _Noreturn void #endif - // This is the case where QP/C is compiled by the Microsoft Visual C++ + // This is the case where QP is compiled by the Microsoft Visual C++ // compiler in the C++ mode, which can happen when qep_port.h is included // in a C++ module, or the compilation is forced to C++ by the option /TP. // @@ -62,7 +56,7 @@ // and C4610, which warn that default constructors and assignment operators // could not be generated for structures QMState and QMTranActTable. // - // The QP/C source code cannot be changed to avoid these C++ warnings + // The QP source code cannot be changed to avoid these C++ warnings // because the structures QMState and QMTranActTable must remain PODs // (Plain Old Datatypes) to be initializable statically with constant // initializers. diff --git a/ports/win32/qs_port.c b/ports/win32/qs_port.c index daeee934b..3411e8b2a 100644 --- a/ports/win32/qs_port.c +++ b/ports/win32/qs_port.c @@ -1,35 +1,33 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// Version 8.0.2 // -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// 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. +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// The terms of the open source GNU General Public License version 3 -// can be found at: +// SPDX-License-Identifier: LicenseRef-QL-commercial // -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// This software is licensed under the terms of the Quantum Leaps commercial +// licenses. Please contact Quantum Leaps for more information about the +// available licensing options. // -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. +// RESTRICTIONS +// You may NOT : +// (a) redistribute, encumber, sell, rent, lease, sublicense, or otherwise +// transfer rights in this software, +// (b) remove or alter any trademark, logo, copyright or other proprietary +// notices, legends, symbols or labels present in this software, +// (c) plagiarize this software to sidestep the licensing obligations. // -// Contact information: -// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2024-06-11 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QS/C port for Win32 API - #ifndef Q_SPY - #error "Q_SPY must be defined to compile qs_port.c" + #error Q_SPY must be defined to compile qs_port.c #endif // Q_SPY #define QP_IMPL // this is QP implementation diff --git a/ports/win32/qs_port.h b/ports/win32/qs_port.h index 3454f6040..3a8e64e23 100644 --- a/ports/win32/qs_port.h +++ b/ports/win32/qs_port.h @@ -1,38 +1,31 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Version 8.0.2 // // 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. +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// The terms of the open source GNU General Public License version 3 -// can be found at: +// SPDX-License-Identifier: LicenseRef-QL-commercial // -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// This software is licensed under the terms of the Quantum Leaps commercial +// licenses. Please contact Quantum Leaps for more information about the +// available licensing options. // -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. +// RESTRICTIONS +// You may NOT : +// (a) redistribute, encumber, sell, rent, lease, sublicense, or otherwise +// transfer rights in this software, +// (b) remove or alter any trademark, logo, copyright or other proprietary +// notices, legends, symbols or labels present in this software, +// (c) plagiarize this software to sidestep the licensing obligations. // -// Contact information: -// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QS/C port to Win32 with GNU or Visual C++ compilers - #ifndef QS_PORT_H_ #define QS_PORT_H_ diff --git a/ports/win32/qwin_gui.c b/ports/win32/qwin_gui.c index 5d09ed2d3..ac9ce72a0 100644 --- a/ports/win32/qwin_gui.c +++ b/ports/win32/qwin_gui.c @@ -1,34 +1,32 @@ //============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// QWIN GUI facilities for building realistic embedded front panels +// Version 8.0.2 // -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// 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. +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// The terms of the open source GNU General Public License version 3 -// can be found at: +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// This software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: -// +// NOTE: +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. +// +// Quantum Leaps contact information: +// // //============================================================================ -//! -//! @date Last updated on: 2022-07-30 -//! @version Last updated for: @ref qpc_7_0_1 -//! -//! @file -//! @brief QWIN GUI facilities for building realistic embedded front panels -//! #include "qwin_gui.h" #include diff --git a/ports/win32/qwin_gui.h b/ports/win32/qwin_gui.h index 29b7f76d0..b1062f126 100644 --- a/ports/win32/qwin_gui.h +++ b/ports/win32/qwin_gui.h @@ -1,34 +1,32 @@ //============================================================================ -// QP/C Real-Time Embedded Framework (RTEF) -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// QWIN GUI facilities for building realistic embedded front panels +// Version 8.0.2 // -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// 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. +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// The terms of the open source GNU General Public License version 3 -// can be found at: +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// This software is dual-licensed under the terms of the open-source GNU +// General Public License (GPL) or under the terms of one of the closed- +// source Quantum Leaps commercial licenses. // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // -// Contact information: -// +// NOTE: +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. +// +// Quantum Leaps contact information: +// // //============================================================================ -//! -//! @date Last updated on: 2022-07-30 -//! @version Last updated for: @ref qpc_7_0_1 -//! -//! @file -//! @brief QWIN GUI facilities for building realistic embedded front panels -//! #ifndef QWIN_GUI_H #define QWIN_GUI_H diff --git a/ports/win32/safe_std.h b/ports/win32/safe_std.h index c752662ca..5cd2f0cdb 100644 --- a/ports/win32/safe_std.h +++ b/ports/win32/safe_std.h @@ -22,11 +22,6 @@ // // //============================================================================ -//! @date Last updated on: 2022-07-30 -//! @version Last updated for: @ref qpc_7_1_3 -//! -//! @file -//! @brief "safe" and facilities #ifndef SAFE_STD_H #define SAFE_STD_H diff --git a/qpc.qm b/qpc.qm deleted file mode 100644 index b80938e01..000000000 --- a/qpc.qm +++ /dev/null @@ -1,6895 +0,0 @@ - - - QP/C Real-Time Embedded Framework (RTEF) -This model is used to generate the whole QP/C source code. - -Copyright (c) 2005 Quantum Leaps, LLC. All rights reserved. - - Q u a n t u m L e a P s - ------------------------ - Modern Embedded Software - -SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial - -The QP/C software is dual-licensed under the terms of the open-source GNU -General Public License (GPL) or under the terms of one of the closed- -source Quantum Leaps commercial licenses. - -Redistributions in source code must retain this top-level comment block. -Plagiarizing this software to sidestep the license obligations is illegal. - -NOTE: -The GPL (see <www.gnu.org/licenses/gpl-3.0>) does NOT permit the -incorporation of the QP/C software into proprietary programs. Please -contact Quantum Leaps for commercial licensing options, which expressly -supersede the GPL and are designed explicitly for licensees interested -in using QP/C in closed-source proprietary applications. - -Quantum Leaps contact information: -<www.state-machine.com/licensing> -<info@state-machine.com> - - - public -qpc -2025-12-31 -Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. - - Q u a n t u m L e a P s - ------------------------ - Modern Embedded Software - -SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial - -The QP/C software is dual-licensed under the terms of the open-source GNU -General Public License (GPL) or under the terms of one of the closed- -source Quantum Leaps commercial licenses. - -Redistributions in source code must retain this top-level comment block. -Plagiarizing this software to sidestep the license obligations is illegal. - -NOTE: -The GPL does NOT permit the incorporation of this code into proprietary -programs. Please contact Quantum Leaps for commercial licensing options, -which expressly supersede the GPL and are designed explicitly for -closed-source distribution. - -Quantum Leaps contact information: -<www.state-machine.com/licensing> -<info@state-machine.com> -#2BACD81DCE8ED122C193E4F48A14170D660DFF1E - - - - - - - - - - \ - static char const Q_this_module_[] = name_; - - - - - - - - \ - ((expr_) ? ((void)0) : Q_onError(&Q_this_module_[0], (id_))) - - - - - - \ - (Q_onError(&Q_this_module_[0], (id_))) - - - - - - - - do { \ - QF_CRIT_STAT \ - QF_CRIT_ENTRY(); \ - (expr_) ? ((void)0) : Q_onError(&Q_this_module_[0], (id_)); \ - QF_CRIT_EXIT(); \ -} while (false) - - - - - - do { \ - QF_CRIT_STAT \ - QF_CRIT_ENTRY(); \ - Q_onError(&Q_this_module_[0], (id_)); \ - QF_CRIT_EXIT(); \ -} while (false) - - - - - - - - - - - - - - - - ((void)0) - - - - - - ((void)0) - - - - - - - - ((void)0) - - - - - - ((void)0) - - - - - Q_DEFINE_THIS_MODULE(__FILE__) - - - - - - Q_ASSERT_ID(__LINE__, (expr_)) - - - - Q_ERROR_ID(__LINE__) - - - - - - - - Q_ASSERT_ID((id_), (expr_)) - - - - - - Q_ASSERT(expr_) - - - - - - - - Q_ASSERT_INCRIT((id_), (expr_)) - - - - - - - - Q_ASSERT_ID((id_), (expr_)) - - - - - - Q_ASSERT(expr_) - - - - - - - - Q_ASSERT_INCRIT((id_), (expr_)) - - - - - - - - Q_ASSERT_ID((id_), (expr_)) - - - - - - Q_ASSERT(expr_) - - - - - - - - Q_ASSERT_INCRIT((id_), (expr_)) - - - - - - extern char Q_static_assert_[(expr_) ? 1 : -1] - - - - _Noreturn void - - - - - - - - - - - - - - - (sizeof(array_) / sizeof((array_)[0U])) - - - - - - - - - - - - - - - - - - //! the current QP version number string in ROM, based on #QP_VERSION_STR - = QP_VERSION_STR; - - - - - - - - - - //! @class QEvt - - - //! @public @memberof QEvt - - - - //! @private @memberof QEvt - - - - //! @private @memberof QEvt - - - - = { - QEVT_INITIALIZER(Q_EMPTY_SIG), - QEVT_INITIALIZER(Q_ENTRY_SIG), - QEVT_INITIALIZER(Q_EXIT_SIG), - QEVT_INITIALIZER(Q_INIT_SIG) -}; - - - - //! @public @memberof QEvt - -//! @public @memberof QEvt - - - me->sig = (QSignal)sig; -me->evtTag_ = 0x0FU; -me->refCtr_ = 0U; - - - - //! @public @memberof QEvt - -//! @public @memberof QEvt - - - (void)dummy; -return me; - - - - const - //! @private @memberof QEvt - -//! @private @memberof QEvt - uint8_t rc = me->refCtr_; -return (rc <= 2U*QF_MAX_ACTIVE) - && (((me->evtTag_ ^ rc) & 0x0FU) == 0x0FU); - - - - const - //! @private @memberof QEvt - -//! @private @memberof QEvt - return (uint_fast8_t)(me->evtTag_ >> 4U); - - - - - //! All possible values returned from state/action handlers -//! @note -//! The order of enumeration matters for algorithmic correctness. - { - // unhandled and need to "bubble up" - Q_RET_SUPER, //!< event passed to superstate to handle - Q_RET_UNHANDLED, //!< event unhandled due to guard - - // handled and do not need to "bubble up" - Q_RET_HANDLED, //!< event handled (internal transition) - Q_RET_IGNORED, //!< event silently ignored (bubbled up to top) - - // entry/exit - Q_RET_ENTRY, //!< state entry action executed - Q_RET_EXIT, //!< state exit action executed - - // no side effects - Q_RET_NULL, //!< return value without any effect - - // transitions need to execute transition-action table in ::QMsm - Q_RET_TRAN, //!< regular transition - Q_RET_TRAN_INIT, //!< initial transition in a state - - // transitions that additionally clobber me->state - Q_RET_TRAN_HIST, //!< transition to history of a given state -}; - - - - - - )(void * const me, QEvt const * const e); - - - - )(void * const me); - - - - // forward declaration - - - - )(struct QXThread * const me); - - - - { - struct QMState const *superstate; //!< @private @memberof QMState - QStateHandler const stateHandler; //!< @private @memberof QMState - QActionHandler const entryAction; //!< @private @memberof QMState - QActionHandler const exitAction; //!< @private @memberof QMState - QActionHandler const initAction; //!< @private @memberof QMState -} QMState; - - - - { - QMState const *target; //!< @private @memberof QMTranActTable - QActionHandler const act[1]; //!< @private @memberof QMTranActTable -} QMTranActTable; - - - - { - QStateHandler fun; //!< @private @memberof QAsmAttr - QActionHandler act; //!< @private @memberof QAsmAttr - QXThreadHandler thr; //!< @private @memberof QAsmAttr - QMTranActTable const *tatbl; //!< @private @memberof QAsmAttr - struct QMState const *obj; //!< @private @memberof QAsmAttr -#ifndef Q_UNSAFE - uintptr_t uint; //!< @private @memberof QAsmAttr -#endif -}; - - - - //! @class QAsm - - - //! @protected @memberof QAsm - - - - //! @protected @memberof QAsm - - - - //! @protected @memberof QAsm - - - - //! @protected @memberof QAsm - -//! @protected @memberof QAsm - me->vptr = (QAsmVtable *)0; -me->state.fun = Q_STATE_CAST(0); -me->temp.fun = Q_STATE_CAST(0); - - - - - { - void (*init)(QAsm * const me, void const * const e, - uint_fast8_t const qsId); - void (*dispatch)(QAsm * const me, QEvt const * const e, - uint_fast8_t const qsId); - bool (*isIn)(QAsm * const me, QStateHandler const s); - -#ifdef Q_SPY - QStateHandler (*getStateHandler)(QAsm * const me); -#endif // Q_SPY -}; - - - - //! @class QHsm -//! @extends QAsm - -State machine implementation strategy suitable for -manual coding - - - //! @protected @memberof QHsm - -//! @protected @memberof QHsm - - - static struct QAsmVtable const vtable = { // QAsm virtual table - &QHsm_init_, - &QHsm_dispatch_, - &QHsm_isIn_ -#ifdef Q_SPY - ,&QHsm_getStateHandler_ -#endif -}; -// do not call the QAsm_ctor() here -me->super.vptr = &vtable; -me->super.state.fun = Q_STATE_CAST(&QHsm_top); -me->super.temp.fun = initial; - - - - //! @private @memberof QHsm - -//! @private @memberof QHsm - - - - - - - QF_CRIT_STAT - -QState r; - -// produce QS dictionary for QHsm_top() -#ifdef Q_SPY -QS_CRIT_ENTRY(); -QS_MEM_SYS(); -if ((QS_priv_.flags & 0x01U) == 0U) { - QS_priv_.flags |= 0x01U; - r = Q_RET_HANDLED; -} -else { - r = Q_RET_IGNORED; -} -QS_MEM_APP(); -QS_CRIT_EXIT(); -if (r == Q_RET_HANDLED) { - QS_FUN_DICTIONARY(&QHsm_top); -} -#else -Q_UNUSED_PAR(qsId); -#endif // def Q_SPY - -QStateHandler t = me->state.fun; - -QF_CRIT_ENTRY(); -Q_REQUIRE_INCRIT(200, (me->vptr != (struct QAsmVtable *)0) - && (me->temp.fun != Q_STATE_CAST(0)) - && (t == Q_STATE_CAST(&QHsm_top))); -QF_CRIT_EXIT(); - -// execute the top-most initial tran. -r = (*me->temp.fun)(me, Q_EVT_CAST(QEvt)); - -QF_CRIT_ENTRY(); -// the top-most initial tran. must be taken -Q_ASSERT_INCRIT(210, r == Q_RET_TRAN); - -QS_MEM_SYS(); -QS_BEGIN_PRE(QS_QEP_STATE_INIT, qsId) - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(t); // the source state - QS_FUN_PRE(me->temp.fun); // the target of the initial tran. -QS_END_PRE() -QS_MEM_APP(); - -QF_CRIT_EXIT(); - -// drill down into the state hierarchy with initial transitions... -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(); - // 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) - == Q_RET_HANDLED) - { - QS_STATE_ENTRY_(path[ip], qsId); - } - --ip; - } while (ip >= 0); - - t = path[0]; // current state becomes the new source - - r = QHSM_RESERVED_EVT_(t, Q_INIT_SIG); // execute initial tran. - -#ifdef Q_SPY - if (r == Q_RET_TRAN) { - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_BEGIN_PRE(QS_QEP_STATE_INIT, qsId) - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(t); // the source state - QS_FUN_PRE(me->temp.fun); // the target of the initial tran. - QS_END_PRE() - QS_MEM_APP(); - QS_CRIT_EXIT(); - } -#endif // Q_SPY -} while (r == Q_RET_TRAN); - -QF_CRIT_ENTRY(); - -QS_MEM_SYS(); -QS_BEGIN_PRE(QS_QEP_INIT_TRAN, qsId) - QS_TIME_PRE(); // time stamp - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(t); // the new active state -QS_END_PRE() -QS_MEM_APP(); - -QF_CRIT_EXIT(); - -me->state.fun = t; // change the current active state -#ifndef Q_UNSAFE -me->temp.uint = ~me->state.uint; -#endif - - - - //! @private @memberof QHsm - -//! @private @memberof QHsm - - - - - - - #ifndef Q_SPY -Q_UNUSED_PAR(qsId); -#endif - -QStateHandler s = me->state.fun; -QStateHandler t = s; -QF_CRIT_STAT - -QF_CRIT_ENTRY(); -Q_REQUIRE_INCRIT(300, - (e != (QEvt *)0) - && (s != Q_STATE_CAST(0)) - && (me->state.uint == (uintptr_t)(~me->temp.uint))); -#ifndef Q_UNSAFE -Q_INVARIANT_INCRIT(301, QEvt_verify_(e)); -#endif - -QS_MEM_SYS(); -QS_BEGIN_PRE(QS_QEP_DISPATCH, qsId) - QS_TIME_PRE(); // time stamp - QS_SIG_PRE(e->sig); // the signal of the event - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(s); // the current state -QS_END_PRE() -QS_MEM_APP(); - -QF_CRIT_EXIT(); - -// process the event hierarchically... -QState r; -me->temp.fun = s; -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 - - if (r == Q_RET_UNHANDLED) { // unhandled due to a guard? - - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_BEGIN_PRE(QS_QEP_UNHANDLED, qsId) - QS_SIG_PRE(e->sig); // the signal of the event - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(s); // the current state - QS_END_PRE() - QS_MEM_APP(); - QS_CRIT_EXIT(); - - r = QHSM_RESERVED_EVT_(s, Q_EMPTY_SIG); // superstate of s - } - - --ip; -} while ((r == Q_RET_SUPER) && (ip > 0)); - -QF_CRIT_ENTRY(); -Q_ENSURE_INCRIT(310, ip > 0); -QF_CRIT_EXIT(); - -if (r >= Q_RET_TRAN) { // tran. (regular or history) taken? -#ifdef Q_SPY - if (r == Q_RET_TRAN_HIST) { // tran. to history? - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_BEGIN_PRE(QS_QEP_TRAN_HIST, qsId) - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(s); // tran. to history source - QS_FUN_PRE(me->temp.fun); // tran. to history target - QS_END_PRE() - QS_MEM_APP(); - QS_CRIT_EXIT(); - } -#endif // Q_SPY - - QStateHandler path[QHSM_MAX_NEST_DEPTH_]; - path[0] = me->temp.fun; // tran. target - path[1] = t; // current state - path[2] = s; // tran. source - - // exit current state to tran. source s... - 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); - } - --ip; - } - QF_CRIT_ENTRY(); - Q_ENSURE_INCRIT(320, ip > 0); - QF_CRIT_EXIT(); - - ip = QHsm_tran_(me, path, qsId); // take the tran. - - // 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) - == Q_RET_HANDLED) - { - QS_STATE_ENTRY_(path[ip], qsId); - } - } - t = path[0]; // stick the target into register - me->temp.fun = t; // update the next state - - // drill into the target hierarchy... - while (QHSM_RESERVED_EVT_(t, Q_INIT_SIG) == Q_RET_TRAN) { - - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_BEGIN_PRE(QS_QEP_STATE_INIT, qsId) - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(t); // the source (pseudo)state - QS_FUN_PRE(me->temp.fun); // the target of the tran. - QS_END_PRE() - QS_MEM_APP(); - QS_CRIT_EXIT(); - - ip = 0; - path[0] = me->temp.fun; - - // 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; - // find superstate - (void)QHSM_RESERVED_EVT_(me->temp.fun, Q_EMPTY_SIG); - } - QF_CRIT_ENTRY(); - // 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) - == Q_RET_HANDLED) - { - QS_STATE_ENTRY_(path[ip], qsId); - } - --ip; - } while (ip >= 0); - - t = path[0]; // current state becomes the new source - } - - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_BEGIN_PRE(QS_QEP_TRAN, qsId) - QS_TIME_PRE(); // time stamp - QS_SIG_PRE(e->sig); // the signal of the event - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(s); // the source of the tran. - QS_FUN_PRE(t); // the new active state - QS_END_PRE() - QS_MEM_APP(); - QS_CRIT_EXIT(); -} - -#ifdef Q_SPY -else if (r == Q_RET_HANDLED) { - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_BEGIN_PRE(QS_QEP_INTERN_TRAN, qsId) - QS_TIME_PRE(); // time stamp - QS_SIG_PRE(e->sig); // the signal of the event - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(s); // the source state - QS_END_PRE() - QS_MEM_APP(); - QS_CRIT_EXIT(); -} -else { - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_BEGIN_PRE(QS_QEP_IGNORED, qsId) - QS_TIME_PRE(); // time stamp - QS_SIG_PRE(e->sig); // the signal of the event - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(me->state.fun); // the current state - QS_END_PRE() - QS_MEM_APP(); - QS_CRIT_EXIT(); -} -#endif // Q_SPY - -me->state.fun = t; // change the current active state -#ifndef Q_UNSAFE -me->temp.uint = ~me->state.uint; -#endif - - - - //! @private @memberof QHsm - -//! @private @memberof QHsm - - - return me->state.fun; - - - - //! @private @memberof QHsm - -//! @private @memberof QHsm - - - - - QF_CRIT_STAT -QF_CRIT_ENTRY(); -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 lbound = QHSM_MAX_NEST_DEPTH_ + 1; // fixed upper loop bound -QState r = Q_RET_SUPER; -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 - } - else { - r = QHSM_RESERVED_EVT_(s, Q_EMPTY_SIG); - s = me->temp.fun; - } -} - -QF_CRIT_ENTRY(); -Q_ENSURE_INCRIT(690, lbound > 0); -QF_CRIT_EXIT(); - -#ifndef Q_UNSAFE -me->temp.uint = ~me->state.uint; -#endif - -return inState; // return the status - - - - const - //! @public @memberof QHsm - -//! @public @memberof QHsm - return me->super.state.fun; - - - - //! @public @memberof QHsm - -//! @public @memberof QHsm - - - QStateHandler child = me->super.state.fun; // start with current state -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) { - isFound = true; // child is found - r = Q_RET_IGNORED; // break out of the loop - } - else { - child = me->super.temp.fun; - r = QHSM_RESERVED_EVT_(me->super.temp.fun, Q_EMPTY_SIG); - } - --lbound; -} while ((r != Q_RET_IGNORED) // the top state not reached - && (lbound > 0)); - -#ifndef Q_UNSAFE -me->super.temp.uint = ~me->super.state.uint; -#else -Q_UNUSED_PAR(isFound); -#endif - -QF_CRIT_STAT -QF_CRIT_ENTRY(); -// 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; - - - - //! @private @memberof QHsm - -//! @private @memberof QHsm - - - - - - - #ifndef Q_SPY -Q_UNUSED_PAR(qsId); -#endif - -int_fast8_t ip = -1; // tran. entry path index -QStateHandler t = path[0]; -QStateHandler const s = path[2]; -QF_CRIT_STAT - -// (a) check source==target (tran. to self)... -if (s == t) { - // exit source s - if (QHSM_RESERVED_EVT_(s, Q_EXIT_SIG) == Q_RET_HANDLED) { - QS_STATE_EXIT_(s, qsId); - } - ip = 0; // enter the target -} -else { - // find superstate of target - (void)QHSM_RESERVED_EVT_(t, Q_EMPTY_SIG); - - t = me->temp.fun; - - // (b) check source==target->super... - if (s == t) { - ip = 0; // enter the target - } - else { - // find superstate of src - (void)QHSM_RESERVED_EVT_(s, Q_EMPTY_SIG); - - // (c) check source->super==target->super... - if (me->temp.fun == t) { - // exit source s - if (QHSM_RESERVED_EVT_(s, Q_EXIT_SIG) == Q_RET_HANDLED) { - QS_STATE_EXIT_(s, qsId); - } - ip = 0; // enter the target - } - else { - // (d) check source->super==target... - if (me->temp.fun == path[0]) { - // exit source s - if (QHSM_RESERVED_EVT_(s, Q_EXIT_SIG) == Q_RET_HANDLED) { - QS_STATE_EXIT_(s, qsId); - } - } - else { - // (e) check rest of source==target->super->super.. - // and store the entry path along the way - int_fast8_t iq = 0; // indicate that LCA was found - ip = 1; // enter target and its superstate - path[1] = t; // save the superstate of target - 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))) - { - ++ip; - path[ip] = me->temp.fun; // store the entry path - if (me->temp.fun == s) { // is it the source? - iq = 1; // indicate that the LCA found - --ip; // do not enter the source - r = Q_RET_HANDLED; // terminate the loop - } - else { // it is not the source, keep going up - r = QHSM_RESERVED_EVT_(me->temp.fun, Q_EMPTY_SIG); - } - } - QF_CRIT_ENTRY(); - // 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? - if (iq == 0) { - // exit source s - if (QHSM_RESERVED_EVT_(s, Q_EXIT_SIG) - == Q_RET_HANDLED) - { - QS_STATE_EXIT_(s, qsId); - } - - // (f) check the rest of source->super - // == 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 - ip = iq - 1; // do not enter the LCA - iq = -1; // cause termination of the loop - } - else { - --iq; // try lower superstate of target - } - } while (iq >= 0); - - // the LCA not found yet? - if (r != Q_RET_HANDLED) { - // (g) check each source->super->... - // for each target->super... - r = Q_RET_IGNORED; // keep looping - int_fast8_t lbound = QHSM_MAX_NEST_DEPTH_; - do { - // 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); - } - t = me->temp.fun; // set to super of t - iq = ip; - do { - // is this the LCA? - if (t == path[iq]) { - ip = iq - 1; // do not enter the LCA - iq = -1; // break out of inner loop - r = Q_RET_HANDLED; // break outer loop - } - else { - --iq; - } - } while (iq >= 0); - - --lbound; - } while ((r != Q_RET_HANDLED) && (lbound > 0)); - QF_CRIT_ENTRY(); - Q_ENSURE_INCRIT(530, lbound > 0); - QF_CRIT_EXIT(); - } - } - } - } - } -} -QF_CRIT_ENTRY(); -Q_ENSURE_INCRIT(590, ip < QHSM_MAX_NEST_DEPTH_); -QF_CRIT_EXIT(); -return ip; - - - - const - //! @protected @memberof QAsm - -//! @protected @memberof QAsm - - - Q_UNUSED_PAR(me); -Q_UNUSED_PAR(e); -return Q_RET_IGNORED; // the top state ignores all events - - - - - //! @class QMsm -//! @extends QAsm - -State machine implementation strategy requiring support -of a code generating tool and generally NOT suitable -for manual coding - - - //! @protected @memberof QMsm - -//! @protected @memberof QMsm - - - static struct QAsmVtable const vtable = { // QAsm virtual table - &QMsm_init_, - &QMsm_dispatch_, - &QMsm_isIn_ -#ifdef Q_SPY - ,&QMsm_getStateHandler_ -#endif -}; -// do not call the QAsm_ctor() here -me->super.vptr = &vtable; -me->super.state.obj = &l_msm_top_s; // the current state (top) -me->super.temp.fun = initial; // the initial tran. handler - - - - //! @private @memberof QMsm - -//! @private @memberof QMsm - - - - - - - #ifndef Q_SPY -Q_UNUSED_PAR(qsId); -#endif - -QF_CRIT_STAT -QF_CRIT_ENTRY(); -Q_REQUIRE_INCRIT(200, (me->vptr != (struct QAsmVtable *)0) - && (me->temp.fun != Q_STATE_CAST(0)) - && (me->state.obj == &l_msm_top_s)); -QF_CRIT_EXIT(); - -// execute the top-most initial tran. -QState r = (*me->temp.fun)(me, Q_EVT_CAST(QEvt)); - -QF_CRIT_ENTRY(); -// the top-most initial tran. must be taken -Q_ASSERT_INCRIT(210, r == Q_RET_TRAN_INIT); - -QS_MEM_SYS(); -QS_BEGIN_PRE(QS_QEP_STATE_INIT, qsId) - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(me->state.obj->stateHandler); // source state - QS_FUN_PRE(me->temp.tatbl->target->stateHandler); // target state -QS_END_PRE() -QS_MEM_APP(); - -QF_CRIT_EXIT(); - -// set state to the last tran. target -me->state.obj = me->temp.tatbl->target; - -// drill down into the state hierarchy with initial transitions... -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); - --lbound; -} while ((r >= Q_RET_TRAN_INIT) && (lbound > 0)); - -QF_CRIT_ENTRY(); -Q_ENSURE_INCRIT(290, lbound > 0); - -QS_MEM_SYS(); -QS_BEGIN_PRE(QS_QEP_INIT_TRAN, qsId) - QS_TIME_PRE(); // time stamp - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(me->state.obj->stateHandler); // the new current state -QS_END_PRE() -QS_MEM_APP(); - -QF_CRIT_EXIT(); - -#ifndef Q_UNSAFE -me->temp.uint = ~me->state.uint; -#endif - - - - //! @private @memberof QMsm - -//! @private @memberof QMsm - - - - - - - #ifndef Q_SPY -Q_UNUSED_PAR(qsId); -#endif - -QMState const *s = me->state.obj; // store the current state -QMState const *t = s; - -QF_CRIT_STAT -QF_CRIT_ENTRY(); -Q_REQUIRE_INCRIT(300, - (e != (QEvt *)0) - && (s != (QMState *)0) - && (me->state.uint == (uintptr_t)(~me->temp.uint))); -#ifndef Q_UNSAFE -Q_INVARIANT_INCRIT(301, QEvt_verify_(e)); -#endif - -QS_MEM_SYS(); -QS_BEGIN_PRE(QS_QEP_DISPATCH, qsId) - QS_TIME_PRE(); // time stamp - QS_SIG_PRE(e->sig); // the signal of the event - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(s->stateHandler); // the current state handler -QS_END_PRE() -QS_MEM_APP(); - -QF_CRIT_EXIT(); - -// scan the state hierarchy up to the top state... -QState r; -int_fast8_t lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound -do { - r = (*t->stateHandler)(me, e); // call state handler function - - // event handled? (the most frequent case) - if (r >= Q_RET_HANDLED) { - break; // done scanning the state hierarchy - } - // event unhandled and passed to the superstate? - else if (r == Q_RET_SUPER) { - t = t->superstate; // advance to the superstate - } - else { // event unhandled due to a guard - QF_CRIT_ENTRY(); - // event must be unhandled due to a guard evaluating to 'false' - Q_ASSERT_INCRIT(310, r == Q_RET_UNHANDLED); - - QS_MEM_SYS(); - QS_BEGIN_PRE(QS_QEP_UNHANDLED, qsId) - QS_SIG_PRE(e->sig); // the signal of the event - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(t->stateHandler); // the current state - QS_END_PRE() - QS_MEM_APP(); - - QF_CRIT_EXIT(); - - t = t->superstate; // advance to the superstate - } - --lbound; -} while ((t != (QMState *)0) && (lbound > 0)); -QF_CRIT_ENTRY(); -Q_ENSURE_INCRIT(320, lbound > 0); -QF_CRIT_EXIT(); - -if (r >= Q_RET_TRAN) { // any kind of tran. taken? - QF_CRIT_ENTRY(); - // the tran. source state must not be NULL - Q_ASSERT_INCRIT(330, t != (QMState *)0); - QF_CRIT_EXIT(); - -#ifdef Q_SPY - QMState const * const ts = t; // tran. source for QS tracing -#endif // Q_SPY - struct QMTranActTable const *tatbl; // for saving tran. table - - if (r == Q_RET_TRAN_HIST) { // was it tran. to history? - QMState const * const hist = me->state.obj; // save history - me->state.obj = s; // restore the original state - - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_BEGIN_PRE(QS_QEP_TRAN_HIST, qsId) - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(t->stateHandler); // source state handler - QS_FUN_PRE(hist->stateHandler); // target state handler - QS_END_PRE() - QS_MEM_APP(); - QS_CRIT_EXIT(); - - // save the tran-action table before it gets clobbered - tatbl = me->temp.tatbl; - QMsm_exitToTranSource_(me, s, t, qsId); - (void)QMsm_execTatbl_(me, tatbl, qsId); - r = QMsm_enterHistory_(me, hist, qsId); - s = me->state.obj; - t = s; // set target to the current state - } - - lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound - while ((r >= Q_RET_TRAN) && (lbound > 0)) { - // save the tran-action table before it gets clobbered - tatbl = me->temp.tatbl; - me->temp.obj = (QMState *)0; // clear - QMsm_exitToTranSource_(me, s, t, qsId); - r = QMsm_execTatbl_(me, tatbl, qsId); - s = me->state.obj; - t = s; // set target to the current state - --lbound; - } - - QF_CRIT_ENTRY(); - Q_ENSURE_INCRIT(360, lbound > 0); - - QS_MEM_SYS(); - QS_BEGIN_PRE(QS_QEP_TRAN, qsId) - QS_TIME_PRE(); // time stamp - QS_SIG_PRE(e->sig); // the signal of the event - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(ts->stateHandler); // the tran. source - QS_FUN_PRE(s->stateHandler); // the new active state - QS_END_PRE() - QS_MEM_APP(); - - QF_CRIT_EXIT(); -} - -#ifdef Q_SPY -// was the event handled? -else if (r == Q_RET_HANDLED) { - QF_CRIT_ENTRY(); - // internal tran. source can't be NULL - Q_ASSERT_INCRIT(380, t != (QMState *)0); - - QS_MEM_SYS(); - QS_BEGIN_PRE(QS_QEP_INTERN_TRAN, qsId) - QS_TIME_PRE(); // time stamp - QS_SIG_PRE(e->sig); // the signal of the event - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(t->stateHandler); // the source state - QS_END_PRE() - QS_MEM_APP(); - - QF_CRIT_EXIT(); -} -// event bubbled to the 'top' state? -else if (t == (QMState *)0) { - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_BEGIN_PRE(QS_QEP_IGNORED, qsId) - QS_TIME_PRE(); // time stamp - QS_SIG_PRE(e->sig); // the signal of the event - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(s->stateHandler); // the current state - QS_END_PRE() - QS_MEM_APP(); - QS_CRIT_EXIT(); -} -#endif // Q_SPY -else { - // empty -} - -#ifndef Q_UNSAFE -me->temp.uint = ~me->state.uint; -#endif - - - - //! @public @memberof QMsm - -//! @public @memberof QMsm - - - return me->state.obj->stateHandler; - - - - //! @private @memberof QMsm - -//! @private @memberof QMsm - - - - - bool inState = false; // assume that this SM is not in 'state' - -QMState const *s = me->state.obj; -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; - } - else { - s = s->superstate; // advance to the superstate - } -} - -QF_CRIT_STAT -QF_CRIT_ENTRY(); -Q_ENSURE_INCRIT(490, lbound > 0); -QF_CRIT_EXIT(); - -return inState; - - - - const - //! @public @memberof QMsm - -//! @public @memberof QMsm - return me->super.state.obj; - - - - const - //! @public @memberof QMsm - -//! @public @memberof QMsm - - - QMState const *child = me->super.state.obj; -bool isFound = false; // start with the child not found -QMState const *s; - -int_fast8_t lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound -for (s = me->super.state.obj; - (s != (QMState *)0) && (lbound > 0); - s = s->superstate) -{ - if (s == parent) { - isFound = true; // child is found - break; - } - else { - child = s; - } - --lbound; -} -QF_CRIT_STAT -QF_CRIT_ENTRY(); -Q_ENSURE_INCRIT(680, lbound > 0); -QF_CRIT_EXIT(); - -if (!isFound) { // still not found? - lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound - for (s = me->super.temp.obj; - (s != (QMState *)0) && (lbound > 0); - s = s->superstate) - { - if (s == parent) { - isFound = true; // child is found - break; - } - else { - child = s; - } - --lbound; - } -} - -QF_CRIT_ENTRY(); -// 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 - - - - //! @private @memberof QMsm - -//! @private @memberof QMsm - - - - - - - #ifndef Q_SPY -Q_UNUSED_PAR(qsId); -#endif - -QF_CRIT_STAT -QF_CRIT_ENTRY(); -// precondition: -// - the tran-action table pointer must not be NULL -Q_REQUIRE_INCRIT(700, tatbl != (struct QMTranActTable *)0); -QF_CRIT_EXIT(); - -QState r = Q_RET_NULL; -int_fast8_t lbound = QMSM_MAX_TRAN_LENGTH_; // fixed upper loop bound -QActionHandler const *a = &tatbl->act[0]; -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(); - if (r == Q_RET_ENTRY) { - QS_BEGIN_PRE(QS_QEP_STATE_ENTRY, qsId) - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(me->temp.obj->stateHandler); // entered state - QS_END_PRE() - } - else if (r == Q_RET_EXIT) { - QS_BEGIN_PRE(QS_QEP_STATE_EXIT, qsId) - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(me->temp.obj->stateHandler); // exited state - QS_END_PRE() - } - else if (r == Q_RET_TRAN_INIT) { - QS_BEGIN_PRE(QS_QEP_STATE_INIT, qsId) - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(tatbl->target->stateHandler); // source - QS_FUN_PRE(me->temp.tatbl->target->stateHandler); // target - QS_END_PRE() - } - else { - // empty - } - QS_MEM_APP(); - QS_CRIT_EXIT(); -#endif // Q_SPY -} -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(); - -me->state.obj = (r >= Q_RET_TRAN) - ? me->temp.tatbl->target - : tatbl->target; -return r; - - - - //! @private @memberof QMsm - -//! @private @memberof QMsm - - - - - - - - - #ifndef Q_SPY -Q_UNUSED_PAR(qsId); -#endif - -QF_CRIT_STAT - -// exit states from the current state to the tran. source state -QMState const *s = cs; -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 - (void)(*s->exitAction)(me); - - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_BEGIN_PRE(QS_QEP_STATE_EXIT, qsId) - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(s->stateHandler); // the exited state handler - QS_END_PRE() - QS_MEM_APP(); - QS_CRIT_EXIT(); - } - - s = s->superstate; // advance to the superstate -} -QF_CRIT_ENTRY(); -Q_ENSURE_INCRIT(890, lbound > 0); -QF_CRIT_EXIT(); - - - - //! @private @memberof QMsm - -//! @private @memberof QMsm - - - - - - - #ifndef Q_SPY -Q_UNUSED_PAR(qsId); -#endif - -// record the entry path from current state to history -QMState const *epath[QMSM_MAX_ENTRY_DEPTH_]; -QMState const *s = hist; -int_fast8_t i = 0; // tran. entry path index -while ((s != me->state.obj) && (i < (QMSM_MAX_ENTRY_DEPTH_ - 1))) { - if (s->entryAction != Q_ACTION_CAST(0)) { - epath[i] = s; - ++i; - } - s = s->superstate; -} -QF_CRIT_STAT -QF_CRIT_ENTRY(); -Q_ASSERT_INCRIT(910, s == me->state.obj); -QF_CRIT_EXIT(); - -// retrace the entry path in reverse (desired) order... -while (i > 0) { - --i; - (void)(*epath[i]->entryAction)(me); // run entry action in epath[i] - - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_BEGIN_PRE(QS_QEP_STATE_ENTRY, qsId) - QS_OBJ_PRE(me); - QS_FUN_PRE(epath[i]->stateHandler); // entered state handler - QS_END_PRE() - QS_MEM_APP(); - QS_CRIT_EXIT(); -} - -me->state.obj = hist; // set current state to the tran. target - -// initial tran. present? -QState r; -if (hist->initAction != Q_ACTION_CAST(0)) { - r = (*hist->initAction)(me); // execute the tran. action - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_BEGIN_PRE(QS_QEP_STATE_INIT, qsId) - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(hist->stateHandler); // source - QS_FUN_PRE(me->temp.tatbl->target->stateHandler); // target - QS_END_PRE() - QS_MEM_APP(); - QS_CRIT_EXIT(); -} -else { - r = Q_RET_NULL; -} - -return r; - - - - - - - - - - { (QSignal)(sig_), 0x01U, 0x0EU } - - - - ((uint8_t)0) - - - - - - - - - - \ - (*((QAsm *)(me_))->vptr->init)((QAsm *)(me_), (par_), (qsId_)) - - - - - - - - - - \ - (*((QAsm *)(me_))->vptr->init)((QAsm *)(me_), (par_), 0U) - - - - - - - - - - \ - (*((QAsm *)(me_))->vptr->dispatch)((QAsm *)(me_), (e_), (qsId_)) - - - - - - - - - - \ - (*((QAsm *)(me_))->vptr->dispatch)((QAsm *)(me_), (e_), 0U) - - - - - - - - \ - (*((QAsm *)(me_))->vptr->isIn)((QAsm *)(me_), (state_)) - - - - - - ((QAsm *)(ptr_)) - - - - - - ((QHsm *)(ptr_)) - - - - - - ((QMsm *)(ptr_)) - - - - ((QSignal)0) - - - - ((QSignal)1) - - - - ((QSignal)2) - - - - ((QSignal)3) - - - - ((enum_t)4) - - - - - - \ - ((Q_ASM_UPCAST(me))->temp.fun = Q_STATE_CAST(target_), \ - (QState)Q_RET_TRAN) - - - - - - \ - ((Q_ASM_UPCAST(me))->temp.fun = (hist_), \ - (QState)Q_RET_TRAN_HIST) - - - - - - \ - ((Q_ASM_UPCAST(me))->temp.fun = Q_STATE_CAST(super_), \ - (QState)Q_RET_SUPER) - - - - ((QState)Q_RET_HANDLED) - - - - ((QState)Q_RET_UNHANDLED) - - - - / - ((QActionHandler)0) - - - - - - ((class_ const *)(e)) - - - - - - ((QStateHandler)(handler_)) - - - - - - ((QActionHandler)(action_)) - - - - - - ((void)(par_)) - - - - - - (sizeof(array_) / sizeof((array_)[0U])) - - - - - - - - ((type_ *)(uint_)) - - - - - - \ - ((Q_ASM_UPCAST(me))->temp.obj = (state_), \ - (QState)Q_RET_ENTRY) - - - - - - ((QState)Q_RET_ENTRY) - - - - - - \ - ((Q_ASM_UPCAST(me))->temp.obj = (state_), \ - (QState)Q_RET_EXIT) - - - - - - ((QState)Q_RET_EXIT) - - - - - - \ - ((Q_ASM_UPCAST(me))->temp.obj = (state_), \ - (QState)Q_RET_EXIT) - - - - - - ((Q_ASM_UPCAST(me))->temp.tatbl \ - = (struct QMTranActTable const *)(tatbl_), \ - (QState)Q_RET_TRAN) - - - - - - ((Q_ASM_UPCAST(me))->temp.tatbl \ - = (struct QMTranActTable const *)(tatbl_), \ - (QState)Q_RET_TRAN_INIT) - - - - - - - - \ - ((((Q_ASM_UPCAST(me))->state.obj = (history_)), \ - ((Q_ASM_UPCAST(me))->temp.tatbl = \ - (struct QMTranActTable const *)(tatbl_))), \ - (QState)Q_RET_TRAN_HIST) - - - - ((QState)Q_RET_HANDLED) - - - - ((QState)Q_RET_UNHANDLED) - - - - ((QState)Q_RET_SUPER) - - - - ((QMState *)0) - - - - - - - //! @class QF - { - //! @cond INTERNAL - uint8_t dummy; - //! @endcond -} QV; - - - - - - - - - - - - - - - - - - - - const - - - static uint8_t const log2LUT[16] = { - 0U, 1U, 2U, 2U, 3U, 3U, 3U, 3U, - 4U, 4U, 4U, 4U, 4U, 4U, 4U, 4U -}; -uint_fast8_t n = 0U; -QPSetBits tmp; -QPSetBits x = bitmask; - -#if (QF_MAX_ACTIVE > 16U) -tmp = (x >> 16U); -if (tmp != 0U) { - n += 16U; - x = tmp; -} -#endif -#if (QF_MAX_ACTIVE > 8U) -tmp = (x >> 8U); -if (tmp != 0U) { - n += 8U; - x = tmp; -} -#endif -tmp = (x >> 4U); -if (tmp != 0U) { - n += 4U; - x = tmp; -} -return n + log2LUT[x]; - - - - //! @class QPSet - - - //! @private @memberof QPSet - - - - //! @public @memberof QPSet - -//! @public @memberof QPSet - me->bits[0] = 0U; -#if (QF_MAX_ACTIVE > 32) -me->bits[1] = 0U; -#endif - - - - const - //! @public @memberof QPSet - -//! @public @memberof QPSet - #if (QF_MAX_ACTIVE <= 32U) -return (me->bits[0] == 0U); -#else -return (me->bits[0] == 0U) ? (me->bits[1] == 0U) : false; -#endif - - - - const - //! @public @memberof QPSet - -//! @public @memberof QPSet - #if (QF_MAX_ACTIVE <= 32U) -return (me->bits[0] != 0U); -#else -return (me->bits[0] != 0U) ? true : (me->bits[1] != 0U); -#endif - - - - const - //! @public @memberof QPSet - -//! @public @memberof QPSet - - - #if (QF_MAX_ACTIVE <= 32U) -return (me->bits[0] & ((QPSetBits)1U << (n - 1U))) != 0U; -#else -return (n <= 32U) - ? ((me->bits[0] & ((QPSetBits)1U << (n - 1U))) != 0U) - : ((me->bits[1] & ((QPSetBits)1U << (n - 33U))) != 0U); -#endif - - - - //! @public @memberof QPSet - -//! @public @memberof QPSet - - - #if (QF_MAX_ACTIVE <= 32U) -me->bits[0] = (me->bits[0] | ((QPSetBits)1U << (n - 1U))); -#else -if (n <= 32U) { - me->bits[0] = (me->bits[0] | ((QPSetBits)1U << (n - 1U))); -} -else { - me->bits[1] = (me->bits[1] | ((QPSetBits)1U << (n - 33U))); -} -#endif - - - - //! @public @memberof QPSet - -//! @public @memberof QPSet - - - #if (QF_MAX_ACTIVE <= 32U) -me->bits[0] = (me->bits[0] & (QPSetBits)(~((QPSetBits)1U << (n - 1U)))); -#else -if (n <= 32U) { - (me->bits[0] = (me->bits[0] & ~((QPSetBits)1U << (n - 1U)))); -} -else { - (me->bits[1] = (me->bits[1] & ~((QPSetBits)1U << (n - 33U)))); -} -#endif - - - - const - //! @public @memberof QPSet - -//! @public @memberof QPSet - #if (QF_MAX_ACTIVE <= 32U) -return QF_LOG2(me->bits[0]); -#else -return (me->bits[1] != 0U) - ? (QF_LOG2(me->bits[1]) + 32U) - : (QF_LOG2(me->bits[0])); -#endif - - - - const - //! @private @memberof QPSet - -//! @private @memberof QPSet - - - dis->bits[0] = ~me->bits[0]; -#if (QF_MAX_ACTIVE > 32U) -dis->bits[1] = ~me->bits[1]; -#endif - - - - const - //! @private @memberof QPSet - -//! @private @memberof QPSet - - - #if (QF_MAX_ACTIVE <= 32U) -return me->bits[0] == (QPSetBits)(~dis->bits[0]); -#else -return (me->bits[0] == (QPSetBits)(~dis->bits[0])) - && (me->bits[1] == (QPSetBits)(~dis->bits[1])); -#endif - - - - - //! @struct QSubscrList - - - //! @private @memberof QSubscrList - - - - //! @private @memberof QSubscrList - - - - - - - - - - //! @class QActive -//! @extends QAsm - - - //! @protected @memberof QActive - - - - //! @protected @memberof QActive - - - - //! @protected @memberof QActive - - - - //! @protected @memberof QActive - - - - //! @protected @memberof QActive - - - - //! @protected @memberof QActive - - - - //! @protected @memberof QActive - - - - //! @static @private @memberof QActive - -//! @static @private @memberof QActive - - - - //! @static @private @memberof QActive - - - - //! @static @private @memberof QActive - - - - //! @protected @memberof QActive - -//! @protected @memberof QActive - - - // clear the whole QActive object, so that the framework can start -// correctly even if the startup code fails to clear the uninitialized -// data (as is required by the C Standard). -QF_bzero_(me, sizeof(*me)); - -// NOTE: QActive inherits the abstract QAsm class, but it calls the -// constructor of the QHsm subclass. This is because QActive inherits -// the behavior from the QHsm subclass. -QHsm_ctor((QHsm *)(me), initial); - -// NOTE: this vtable is identical as QHsm, but is provided -// for the QActive subclass to provide a UNIQUE vptr to distinguish -// subclasses of QActive (e.g., in the debugger). -static struct QAsmVtable const vtable = { // QActive virtual table - &QHsm_init_, - &QHsm_dispatch_, - &QHsm_isIn_ -#ifdef Q_SPY - ,&QHsm_getStateHandler_ -#endif -}; -me->super.vptr = &vtable; // hook vptr to QActive vtable - - - - //! @public @memberof QActive - -//! @public @memberof QActive - - - - - - - - //! @public @memberof QActive - -//! @public @memberof QActive - - - - - - - - - - - - - - - - //! @protected @memberof QActive - -//! @protected @memberof QActive - - - - //! @private @memberof QActive - -//! @private @memberof QActive - QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -if (me->pthre == 0U) { // preemption-threshold not defined? - me->pthre = me->prio; // apply the default -} - -#ifndef Q_UNSAFE - -Q_REQUIRE_INCRIT(100, (0U < me->prio) && (me->prio <= QF_MAX_ACTIVE) - && (QActive_registry_[me->prio] == (QActive *)0) - && (me->prio <= me->pthre)); - -uint8_t prev_thre = me->pthre; -uint8_t next_thre = me->pthre; - -uint_fast8_t p; -for (p = (uint_fast8_t)me->prio - 1U; p > 0U; --p) { - if (QActive_registry_[p] != (QActive *)0) { - prev_thre = QActive_registry_[p]->pthre; - break; - } -} -for (p = (uint_fast8_t)me->prio + 1U; p <= QF_MAX_ACTIVE; ++p) { - if (QActive_registry_[p] != (QActive *)0) { - next_thre = QActive_registry_[p]->pthre; - break; - } -} - -Q_ASSERT_INCRIT(190, (prev_thre <= me->pthre) - && (me->pthre <= next_thre)); - -me->prio_dis = (uint8_t)(~me->prio); -me->pthre_dis = (uint8_t)(~me->pthre); - -#endif // Q_UNSAFE - -// register the AO at the QF-prio. -QActive_registry_[me->prio] = me; - -QF_MEM_APP(); -QF_CRIT_EXIT(); - - - - //! @private @memberof QActive - -//! @private @memberof QActive - uint_fast8_t const p = (uint_fast8_t)me->prio; - -QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -Q_REQUIRE_INCRIT(200, (0U < p) && (p <= QF_MAX_ACTIVE) - && (QActive_registry_[p] == me)); -QActive_registry_[p] = (QActive *)0; // free-up the prio. level -me->super.state.fun = Q_STATE_CAST(0); // invalidate the state - -QF_MEM_APP(); -QF_CRIT_EXIT(); - - - - //! @private @memberof QActive - -//! @private @memberof QActive - - - - - - - #ifndef Q_SPY -Q_UNUSED_PAR(sender); -#endif - -#ifdef Q_UTEST // test? -#if (Q_UTEST != 0) // testing QP-stub? -if (me->super.temp.fun == Q_STATE_CAST(0)) { // QActiveDummy? - return QActiveDummy_fakePost_(me, e, margin, sender); -} -#endif // (Q_UTEST != 0) -#endif // def Q_UTEST - -QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -Q_REQUIRE_INCRIT(200, e != (QEvt *)0); - -QEQueueCtr tmp = me->eQueue.nFree; // get volatile into temporary -#ifndef Q_UNSAFE -QEQueueCtr dis = (QEQueueCtr)~me->eQueue.nFree_dis; -Q_INVARIANT_INCRIT(201, (QEvt_verify_(e)) && (tmp == dis)); -#endif // ndef Q_UNSAFE - -// test-probe#1 for faking queue overflow -QS_TEST_PROBE_DEF(&QActive_post_) -QS_TEST_PROBE_ID(1, - tmp = 0U; // fake no free events -) - -// required margin available? -bool status; -if (margin == QF_NO_MARGIN) { - if (tmp > 0U) { // free entries available in the queue? - status = true; // can post - } - else { // no free entries available - status = false; // cannot post - - // The queue overflows, but QF_NO_MARGIN indicates that - // the "event delivery guarantee" is required. - Q_ERROR_INCRIT(210); // must be able to post the event - } -} -else if (tmp > (QEQueueCtr)margin) { // enough free entries? - status = true; // can post -} -else { // the # free entries below the requested margin - status = false; // cannot post, but don't assert -} - -// is it a mutable event? -if (QEvt_getPoolNum_(e) != 0U) { - QEvt_refCtr_inc_(e); // increment the reference counter -} - -if (status) { // can post the event? - --tmp; // one free entry just used up - - me->eQueue.nFree = tmp; // update the original -#ifndef Q_UNSAFE - me->eQueue.nFree_dis = (QEQueueCtr)~tmp; // update the DIS - - if (me->eQueue.nMin > tmp) { - me->eQueue.nMin = tmp; // update minimum so far - } -#endif // ndef Q_UNSAFE - - QS_BEGIN_PRE(QS_QF_ACTIVE_POST, me->prio) - QS_TIME_PRE(); // timestamp - QS_OBJ_PRE(sender); // the sender object - QS_SIG_PRE(e->sig); // the signal of the event - QS_OBJ_PRE(me); // this active object (recipient) - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); - QS_EQC_PRE(tmp); // # free entries -#ifndef Q_UNSAFE - QS_EQC_PRE(me->eQueue.nMin); // min # free entries -#else - QS_EQC_PRE(0U); // min # free entries -#endif - QS_END_PRE() - -#ifdef Q_UTEST - // callback to examine the posted event under the same conditions - // as producing the #QS_QF_ACTIVE_POST trace record, which are: - // the local filter for this AO ('me->prio') is set - if (QS_LOC_CHECK_(me->prio)) { - QF_MEM_APP(); - QF_CRIT_EXIT(); - - QS_onTestPost(sender, me, e, status); - - QF_CRIT_ENTRY(); - QF_MEM_SYS(); - } -#endif // def Q_UTEST - - if (me->eQueue.frontEvt == (QEvt *)0) { // is the queue empty? - me->eQueue.frontEvt = e; // deliver event directly -#ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(211, me->eQueue.frontEvt_dis - == (uintptr_t)~Q_PTR2UINT_CAST_((QEvt *)0)); - me->eQueue.frontEvt_dis = (uintptr_t)~Q_PTR2UINT_CAST_(e); -#endif // ndef Q_UNSAFE - -#ifdef QXK_H_ - if (me->super.state.act == Q_ACTION_CAST(0)) { // eXtended? - QXTHREAD_EQUEUE_SIGNAL_(me); // signal eXtended Thread - } - else { - QACTIVE_EQUEUE_SIGNAL_(me); // signal the Active Object - } -#else - QACTIVE_EQUEUE_SIGNAL_(me); // signal the Active Object -#endif // def QXK_H_ - } - else { // queue was not empty, insert event into the ring-buffer - tmp = me->eQueue.head; // get volatile into temporary -#ifndef Q_UNSAFE - dis = (QEQueueCtr)~me->eQueue.head_dis; - Q_INVARIANT_INCRIT(212, tmp == dis); -#endif // ndef Q_UNSAFE - me->eQueue.ring[tmp] = e; // insert e into buffer - - if (tmp == 0U) { // need to wrap the head? - tmp = me->eQueue.end; - } - --tmp; // advance the head (counter-clockwise) - - me->eQueue.head = tmp; // update the original -#ifndef Q_UNSAFE - me->eQueue.head_dis = (QEQueueCtr)~tmp; -#endif // ndef Q_UNSAFE - } - - QF_MEM_APP(); - QF_CRIT_EXIT(); -} -else { // event cannot be posted - - QS_BEGIN_PRE(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) - QS_TIME_PRE(); // timestamp - QS_OBJ_PRE(sender); // the sender object - QS_SIG_PRE(e->sig); // the signal of the event - QS_OBJ_PRE(me); // this active object (recipient) - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); - QS_EQC_PRE(tmp); // # free entries - QS_EQC_PRE(margin); // margin requested - QS_END_PRE() - -#ifdef Q_UTEST - // callback to examine the posted event under the same conditions - // as producing the #QS_QF_ACTIVE_POST trace record, which are: - // the local filter for this AO ('me->prio') is set - if (QS_LOC_CHECK_(me->prio)) { - QF_MEM_APP(); - QF_CRIT_EXIT(); - - QS_onTestPost(sender, me, e, status); - - QF_CRIT_ENTRY(); - QF_MEM_SYS(); - } -#endif // def Q_USTEST - - QF_MEM_APP(); - QF_CRIT_EXIT(); - -#if (QF_MAX_EPOOL > 0U) - QF_gc(e); // recycle the event to avoid a leak -#endif // (QF_MAX_EPOOL > 0U) -} - -return status; - - - - //! @private @memberof QActive - -//! @private @memberof QActive - - - #ifdef Q_UTEST // test? -#if (Q_UTEST != 0) // testing QP-stub? -if (me->super.temp.fun == Q_STATE_CAST(0)) { // QActiveDummy? - QActiveDummy_fakePostLIFO_(me, e); - return; -} -#endif // (Q_UTEST != 0) -#endif // def Q_UTEST - -QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -// the posted event must be be valid (which includes not NULL) -Q_REQUIRE_INCRIT(300, e != (QEvt *)0); - -QEQueueCtr tmp = me->eQueue.nFree; // get volatile into temporary -#ifndef Q_UNSAFE -QEQueueCtr dis = (QEQueueCtr)~me->eQueue.nFree_dis; -Q_INVARIANT_INCRIT(301, (QEvt_verify_(e)) && (tmp == dis)); -#endif // ndef Q_UNSAFE - -// test-probe#1 for faking queue overflow -QS_TEST_PROBE_DEF(&QActive_postLIFO_) -QS_TEST_PROBE_ID(1, - tmp = 0U; // fake no free events -) - -// The queue must NOT overflow for the LIFO posting policy. -Q_REQUIRE_INCRIT(310, tmp != 0U); - -if (QEvt_getPoolNum_(e) != 0U) { // is it a mutable event? - QEvt_refCtr_inc_(e); // increment the reference counter -} - ---tmp; // one free entry just used up - -me->eQueue.nFree = tmp; // update the original -#ifndef Q_UNSAFE -me->eQueue.nFree_dis = (QEQueueCtr)~tmp; - -if (me->eQueue.nMin > tmp) { - me->eQueue.nMin = tmp; // update minimum so far -} -#endif // ndef Q_UNSAFE - -QS_BEGIN_PRE(QS_QF_ACTIVE_POST_LIFO, me->prio) - QS_TIME_PRE(); // timestamp - QS_SIG_PRE(e->sig); // the signal of this event - QS_OBJ_PRE(me); // this active object - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); - QS_EQC_PRE(tmp); // # free entries -#ifndef Q_UNSAFE - QS_EQC_PRE(me->eQueue.nMin); // min # free entries -#else - QS_EQC_PRE(0U); // min # free entries -#endif -QS_END_PRE() - -#ifdef Q_UTEST -// callback to examine the posted event under the same conditions -// as producing the #QS_QF_ACTIVE_POST trace record, which are: -// the local filter for this AO ('me->prio') is set -if (QS_LOC_CHECK_(me->prio)) { - QF_MEM_APP(); - QF_CRIT_EXIT(); - - QS_onTestPost((QActive *)0, me, e, true); - - QF_CRIT_ENTRY(); - QF_MEM_SYS(); -} -#endif // def Q_UTEST - -QEvt const * const frontEvt = me->eQueue.frontEvt; -me->eQueue.frontEvt = e; // deliver the event directly to the front -#ifndef Q_UNSAFE -me->eQueue.frontEvt_dis = (uintptr_t)~Q_PTR2UINT_CAST_(e); -#endif // ndef Q_UNSAFE - -if (frontEvt != (QEvt *)0) { // was the queue NOT empty? - tmp = me->eQueue.tail; // get volatile into temporary; -#ifndef Q_UNSAFE - dis = (QEQueueCtr)~me->eQueue.tail_dis; - Q_INVARIANT_INCRIT(311, tmp == dis); -#endif // ndef Q_UNSAFE - ++tmp; - if (tmp == me->eQueue.end) { // need to wrap the tail? - tmp = 0U; // wrap around - } - me->eQueue.tail = tmp; -#ifndef Q_UNSAFE - me->eQueue.tail_dis = (QEQueueCtr)~tmp; -#endif // ndef Q_UNSAFE - me->eQueue.ring[tmp] = frontEvt; -} -else { // queue was empty - QACTIVE_EQUEUE_SIGNAL_(me); // signal the event queue -} - -QF_MEM_APP(); -QF_CRIT_EXIT(); - - - - //! @private @memberof QActive - -//! @private @memberof QActive - QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -// wait for event to arrive directly (depends on QP port) -// NOTE: might use assertion-IDs 400-409 -QACTIVE_EQUEUE_WAIT_(me); - -// always remove event from the front -QEvt const * const e = me->eQueue.frontEvt; -QEQueueCtr tmp = me->eQueue.nFree; // get volatile into temporary - -#ifndef Q_UNSAFE -Q_INVARIANT_INCRIT(410, e != (QEvt *)0); // queue must NOT be empty -Q_INVARIANT_INCRIT(411, Q_PTR2UINT_CAST_(e) - == (uintptr_t)~me->eQueue.frontEvt_dis); -QEQueueCtr dis = (QEQueueCtr)~me->eQueue.nFree_dis; -Q_INVARIANT_INCRIT(412, tmp == dis); -#endif // ndef Q_UNSAFE - -++tmp; // one more free event in the queue - -me->eQueue.nFree = tmp; // update the # free -#ifndef Q_UNSAFE -me->eQueue.nFree_dis = (QEQueueCtr)~tmp; -#endif // ndef Q_UNSAFE - -if (tmp <= me->eQueue.end) { // any events in the ring buffer? - - QS_BEGIN_PRE(QS_QF_ACTIVE_GET, me->prio) - QS_TIME_PRE(); // timestamp - QS_SIG_PRE(e->sig); // the signal of this event - QS_OBJ_PRE(me); // this active object - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); - QS_EQC_PRE(tmp); // # free entries - QS_END_PRE() - - // remove event from the tail - tmp = me->eQueue.tail; // get volatile into temporary -#ifndef Q_UNSAFE - dis = (QEQueueCtr)~me->eQueue.tail_dis; - Q_INVARIANT_INCRIT(420, tmp == dis); -#endif // ndef Q_UNSAFE - QEvt const * const frontEvt = me->eQueue.ring[tmp]; -#ifndef Q_UNSAFE - Q_ASSERT_INCRIT(421, frontEvt != (QEvt *)0); - me->eQueue.frontEvt_dis = (uintptr_t)~Q_PTR2UINT_CAST_(frontEvt); -#endif // ndef Q_UNSAFE - me->eQueue.frontEvt = frontEvt; // update the original - - if (tmp == 0U) { // need to wrap the tail? - tmp = me->eQueue.end; - } - --tmp; // advance the tail (counter-clockwise) - - me->eQueue.tail = tmp; // update the original -#ifndef Q_UNSAFE - me->eQueue.tail_dis = (QEQueueCtr)~tmp; -#endif // ndef Q_UNSAFE -} -else { - me->eQueue.frontEvt = (QEvt *)0; // queue becomes empty -#ifndef Q_UNSAFE - me->eQueue.frontEvt_dis = (uintptr_t)~Q_PTR2UINT_CAST_((QEvt *)0); -#endif // ndef Q_UNSAFE - - // all entries in the queue must be free (+1 for fronEvt) - Q_ASSERT_INCRIT(440, tmp == (me->eQueue.end + 1U)); - - QS_BEGIN_PRE(QS_QF_ACTIVE_GET_LAST, me->prio) - QS_TIME_PRE(); // timestamp - QS_SIG_PRE(e->sig); // the signal of this event - QS_OBJ_PRE(me); // this active object - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); - QS_END_PRE() -} - -QF_MEM_APP(); -QF_CRIT_EXIT(); - -return e; - - - - //! @static @public @memberof QActive - -//! @static @public @memberof QActive - - - - - QActive_subscrList_ = subscrSto; -QActive_maxPubSignal_ = maxSignal; - -// initialize the subscriber list -for (enum_t sig = 0; sig < maxSignal; ++sig) { - QPSet_setEmpty(&subscrSto[sig].set); -#ifndef Q_UNSAFE - QPSet_update_(&subscrSto[sig].set, &subscrSto[sig].set_dis); -#endif -} - - - - //! @static @private @memberof QActive - -//! @static @private @memberof QActive - - - - - - - #ifndef Q_SPY -Q_UNUSED_PAR(sender); -Q_UNUSED_PAR(qsId); -#endif - -QSignal const sig = e->sig; - -QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -Q_REQUIRE_INCRIT(200, sig < (QSignal)QActive_maxPubSignal_); -Q_INVARIANT_INCRIT(202, - QPSet_verify_(&QActive_subscrList_[sig].set, - &QActive_subscrList_[sig].set_dis)); - -QS_BEGIN_PRE(QS_QF_PUBLISH, qsId) - QS_TIME_PRE(); // the timestamp - QS_OBJ_PRE(sender); // the sender object - QS_SIG_PRE(sig); // the signal of the event - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); -QS_END_PRE() - -// is it a mutable event? -if (QEvt_getPoolNum_(e) != 0U) { - // NOTE: The reference counter of a mutable event is incremented to - // prevent premature recycling of the event while the multicasting - // is still in progress. At the end of the function, the garbage - // collector step (QF_gc()) decrements the reference counter and - // recycles the event if the counter drops to zero. This covers the - // case when the event was published without any subscribers. - QEvt_refCtr_inc_(e); -} - -// make a local, modifiable copy of the subscriber set -QPSet subscrSet = QActive_subscrList_[sig].set; - -QF_MEM_APP(); -QF_CRIT_EXIT(); - -if (QPSet_notEmpty(&subscrSet)) { // any subscribers? - // highest-prio subscriber - uint_fast8_t p = QPSet_findMax(&subscrSet); - - QF_CRIT_ENTRY(); - QF_MEM_SYS(); - - QActive *a = QActive_registry_[p]; - // the AO must be registered with the framework - Q_ASSERT_INCRIT(210, a != (QActive *)0); - - QF_MEM_APP(); - QF_CRIT_EXIT(); - - QF_SCHED_STAT_ - QF_SCHED_LOCK_(p); // lock the scheduler up to AO's prio - uint_fast8_t lbound = QF_MAX_ACTIVE + 1U; // fixed upper loop bound - do { // loop over all subscribers - --lbound; - - // QACTIVE_POST() asserts internally if the queue overflows - QACTIVE_POST(a, e, sender); - - QPSet_remove(&subscrSet, p); // remove the handled subscriber - if (QPSet_notEmpty(&subscrSet)) { // still more subscribers? - p = QPSet_findMax(&subscrSet); // highest-prio subscriber - - QF_CRIT_ENTRY(); - QF_MEM_SYS(); - - a = QActive_registry_[p]; - // the AO must be registered with the framework - Q_ASSERT_INCRIT(220, a != (QActive *)0); - - QF_MEM_APP(); - QF_CRIT_EXIT(); - } - else { - p = 0U; // no more subscribers - } - } while ((p != 0U) && (lbound > 0U)); - - QF_CRIT_ENTRY(); - // 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 -} - -// The following garbage collection step decrements the reference counter -// and recycles the event if the counter drops to zero. This covers both -// cases when the event was published with or without any subscribers. -#if (QF_MAX_EPOOL > 0U) -QF_gc(e); // recycle the event to avoid a leak -#endif - - - - const - //! @protected @memberof QActive - -//! @protected @memberof QActive - - - uint_fast8_t const p = (uint_fast8_t)me->prio; - -QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -Q_REQUIRE_INCRIT(300, (Q_USER_SIG <= sig) - && (sig < QActive_maxPubSignal_) - && (0U < p) && (p <= QF_MAX_ACTIVE) - && (QActive_registry_[p] == me)); -Q_INVARIANT_INCRIT(302, - QPSet_verify_(&QActive_subscrList_[sig].set, - &QActive_subscrList_[sig].set_dis)); - -QS_BEGIN_PRE(QS_QF_ACTIVE_SUBSCRIBE, p) - QS_TIME_PRE(); // timestamp - QS_SIG_PRE(sig); // the signal of this event - QS_OBJ_PRE(me); // this active object -QS_END_PRE() - -// insert the prio. into the subscriber set -QPSet_insert(&QActive_subscrList_[sig].set, p); -#ifndef Q_UNSAFE -QPSet_update_(&QActive_subscrList_[sig].set, - &QActive_subscrList_[sig].set_dis); -#endif - -QF_MEM_APP(); -QF_CRIT_EXIT(); - - - - const - //! @protected @memberof QActive - -//! @protected @memberof QActive - - - uint_fast8_t const p = (uint_fast8_t)me->prio; - -QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -Q_REQUIRE_INCRIT(400, (Q_USER_SIG <= sig) - && (sig < QActive_maxPubSignal_) - && (0U < p) && (p <= QF_MAX_ACTIVE) - && (QActive_registry_[p] == me)); -Q_INVARIANT_INCRIT(402, - QPSet_verify_(&QActive_subscrList_[sig].set, - &QActive_subscrList_[sig].set_dis)); - -QS_BEGIN_PRE(QS_QF_ACTIVE_UNSUBSCRIBE, p) - QS_TIME_PRE(); // timestamp - QS_SIG_PRE(sig); // the signal of this event - QS_OBJ_PRE(me); // this active object -QS_END_PRE() - -// remove the prio. from the subscriber set -QPSet_remove(&QActive_subscrList_[sig].set, p); -#ifndef Q_UNSAFE -QPSet_update_(&QActive_subscrList_[sig].set, - &QActive_subscrList_[sig].set_dis); -#endif - -QF_MEM_APP(); -QF_CRIT_EXIT(); - - - - const - //! @protected @memberof QActive - -//! @protected @memberof QActive - QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -uint_fast8_t const p = (uint_fast8_t)me->prio; - -Q_REQUIRE_INCRIT(500, (0U < p) && (p <= QF_MAX_ACTIVE) - && (QActive_registry_[p] == me)); -enum_t const maxPubSig = QActive_maxPubSignal_; - -QF_MEM_APP(); -QF_CRIT_EXIT(); - -for (enum_t sig = Q_USER_SIG; sig < maxPubSig; ++sig) { - QF_CRIT_ENTRY(); - QF_MEM_SYS(); - - if (QPSet_hasElement(&QActive_subscrList_[sig].set, p)) { - QPSet_remove(&QActive_subscrList_[sig].set, p); -#ifndef Q_UNSAFE - QPSet_update_(&QActive_subscrList_[sig].set, - &QActive_subscrList_[sig].set_dis); -#endif - QS_BEGIN_PRE(QS_QF_ACTIVE_UNSUBSCRIBE, p) - QS_TIME_PRE(); // timestamp - QS_SIG_PRE(sig); // the signal of this event - QS_OBJ_PRE(me); // this active object - QS_END_PRE() - } - QF_MEM_APP(); - QF_CRIT_EXIT(); - - QF_CRIT_EXIT_NOP(); // prevent merging critical sections -} - - - - const - //! @protected @memberof QActive - -//! @protected @memberof QActive - - - - - bool const status = QEQueue_post(eq, e, 0U, me->prio); - -QS_CRIT_STAT -QS_CRIT_ENTRY(); -QS_MEM_SYS(); -QS_BEGIN_PRE(QS_QF_ACTIVE_DEFER, me->prio) - QS_TIME_PRE(); // time stamp - QS_OBJ_PRE(me); // this active object - QS_OBJ_PRE(eq); // the deferred queue - QS_SIG_PRE(e->sig); // the signal of the event - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); -QS_END_PRE() -QS_MEM_APP(); -QS_CRIT_EXIT(); - -return status; - - - - //! @protected @memberof QActive - -//! @protected @memberof QActive - - - QEvt const * const e = QEQueue_get(eq, me->prio); -QF_CRIT_STAT - -bool recalled; -if (e != (QEvt *)0) { // event available? - QACTIVE_POST_LIFO(me, e); // post it to the front of the AO's queue - - QF_CRIT_ENTRY(); - QF_MEM_SYS(); - - if (QEvt_getPoolNum_(e) != 0U) { // is it a mutable event? - - // after posting to the AO's queue the event must be referenced - // at least twice: once in the deferred event queue (eq->get() - // did NOT decrement the reference counter) and once in the - // AO's event queue. - Q_ASSERT_INCRIT(210, e->refCtr_ >= 2U); - - // we need to decrement the reference counter once, to account - // for removing the event from the deferred event queue. - QEvt_refCtr_dec_(e); // decrement the reference counter - } - - QS_BEGIN_PRE(QS_QF_ACTIVE_RECALL, me->prio) - QS_TIME_PRE(); // time stamp - QS_OBJ_PRE(me); // this active object - QS_OBJ_PRE(eq); // the deferred queue - QS_SIG_PRE(e->sig); // the signal of the event - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); - QS_END_PRE() - - QF_MEM_APP(); - QF_CRIT_EXIT(); - - recalled = true; -} -else { - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - - QS_BEGIN_PRE(QS_QF_ACTIVE_RECALL_ATTEMPT, me->prio) - QS_TIME_PRE(); // time stamp - QS_OBJ_PRE(me); // this active object - QS_OBJ_PRE(eq); // the deferred queue - QS_END_PRE() - - QS_MEM_APP(); - QS_CRIT_EXIT(); - - recalled = false; -} -return recalled; - - - - const - //! @protected @memberof QActive - -//! @protected @memberof QActive - - - - - uint_fast16_t n = 0U; -while (n < num) { - QEvt const * const e = QEQueue_get(eq, me->prio); - if (e != (QEvt *)0) { - ++n; // count one more flushed event -#if (QF_MAX_EPOOL > 0U) - QF_gc(e); // garbage collect -#endif - } - else { - break; - } -} - -return n; - - - - //! @private @memberof QActive - -//! @private @memberof QActive - - - - - //! @class QMActive -//! @extends QActive - - - //! @protected @memberof QMActive - -//! @protected @memberof QMActive - - - // clear the whole QMActive object, so that the framework can start -// correctly even if the startup code fails to clear the uninitialized -// data (as is required by the C Standard). -QF_bzero_(me, sizeof(*me)); - -// NOTE: QActive inherits the QActvie class, but it calls the -// constructor of the QMsm subclass. This is because QMActive inherits -// the behavior from the QMsm subclass. -QMsm_ctor((QMsm *)(me), initial); - -// NOTE: this vtable is identical as QMsm, but is provided -// for the QMActive subclass to provide a UNIQUE vptr to distinguish -// subclasses of QActive (e.g., in the debugger). -static struct QAsmVtable const vtable = { // QMActive virtual table - &QMsm_init_, - &QMsm_dispatch_, - &QMsm_isIn_ -#ifdef Q_SPY - ,&QMsm_getStateHandler_ -#endif -}; -me->super.super.vptr = &vtable; // hook vptr to QMActive vtable - - - - - //! @class QTimeEvt -//! @extends QEvt - - - //! @private @memberof QTimeEvt - - - - //! @private @memberof QTimeEvt - - - - //! @private @memberof QTimeEvt - - - - //! @private @memberof QTimeEvt - - - - //! @private @memberof QTimeEvt - - - - //! @private @memberof QTimeEvt - - - - //! @private @memberof QTimeEvt - - - - //! @private @memberof QTimeEvt - - - - //! @static @private @memberof QTimeEvt - - - - //! @static @private @memberof QTimeEvt - - - - //! @public @memberof QTimeEvt - -//! @public @memberof QTimeEvt - - - - - - - QF_CRIT_STAT -QF_CRIT_ENTRY(); -Q_REQUIRE_INCRIT(300, (sig != 0) - && (tickRate < QF_MAX_TICK_RATE)); -QF_CRIT_EXIT(); - -QEvt_ctor(&me->super, sig); - -me->next = (QTimeEvt *)0; -me->act = act; -me->ctr = 0U; -me->interval = 0U; -me->tickRate = (uint8_t)tickRate; -me->flags = 0U; - -#ifndef Q_UNSAFE -me->next_dis = (uintptr_t)~Q_PTR2UINT_CAST_(me->next); -me->ctr_dis = (QTimeEvtCtr)~me->ctr; -#endif // ndef Q_UNSAFE - - - - //! @public @memberof QTimeEvt - -//! @public @memberof QTimeEvt - - - - - QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -// dynamic range checks -#if (QF_TIMEEVT_CTR_SIZE == 1U) -Q_REQUIRE_INCRIT(400, (nTicks < 0xFFU) && (interval < 0xFFU)); -#elif (QF_TIMEEVT_CTR_SIZE == 2U) -Q_REQUIRE_INCRIT(400, (nTicks < 0xFFFFU) && (interval < 0xFFFFU)); -#endif - -#ifndef Q_UNSAFE -Q_INVARIANT_INCRIT(401, QEvt_verify_(&me->super)); -#endif - -QTimeEvtCtr const ctr = me->ctr; -uint8_t const tickRate = me->tickRate; -#ifdef Q_SPY -uint_fast8_t const qsId = ((QActive *)(me->act))->prio; -#endif - -Q_REQUIRE_INCRIT(410, - (nTicks != 0U) - && (ctr == 0U) - && (me->act != (void *)0) - && (tickRate < (uint_fast8_t)QF_MAX_TICK_RATE)); - -#ifndef Q_UNSAFE -QTimeEvtCtr const dis = (QTimeEvtCtr)~me->ctr_dis; -Q_INVARIANT_INCRIT(411, ctr == dis); -#else -Q_UNUSED_PAR(ctr); -#endif // ndef Q_UNSAFE - -me->ctr = (QTimeEvtCtr)nTicks; -me->interval = (QTimeEvtCtr)interval; -#ifndef Q_UNSAFE -me->ctr_dis = (QTimeEvtCtr)~nTicks; -#endif // ndef Q_UNSAFE - -// is the time event unlinked? -// NOTE: For the duration of a single clock tick of the specified tick -// rate a time event can be disarmed and yet still linked into the list -// because un-linking is performed exclusively in QTimeEvt_tick_(). -if ((me->flags & QTE_FLAG_IS_LINKED) == 0U) { - me->flags |= QTE_FLAG_IS_LINKED; // mark as linked - - // The time event is initially inserted into the separate "freshly - // armed" link list based on QTimeEvt_timeEvtHead_[tickRate].act. - // Only later, inside the QTimeEvt_tick_() function, the "freshly - // armed" list is appended to the main list of armed time events - // based on QTimeEvt_timeEvtHead_[tickRate].next. Again, this is - // to keep any changes to the main list exclusively inside the - // QTimeEvt_tick_(). -#ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(420, - Q_PTR2UINT_CAST_(me->next) == (uintptr_t)~me->next_dis); - Q_INVARIANT_INCRIT(421, - Q_PTR2UINT_CAST_(QTimeEvt_timeEvtHead_[tickRate].act) == - (uintptr_t)(~QTimeEvt_timeEvtHead_dis_[tickRate])); -#endif - me->next = (QTimeEvt *)QTimeEvt_timeEvtHead_[tickRate].act; - QTimeEvt_timeEvtHead_[tickRate].act = me; -#ifndef Q_UNSAFE - me->next_dis = (uintptr_t)~Q_PTR2UINT_CAST_(me->next); - QTimeEvt_timeEvtHead_dis_[tickRate] = (uintptr_t)~Q_PTR2UINT_CAST_(me); -#endif // ndef Q_UNSAFE -} - -QS_BEGIN_PRE(QS_QF_TIMEEVT_ARM, qsId) - QS_TIME_PRE(); // timestamp - QS_OBJ_PRE(me); // this time event object - QS_OBJ_PRE(me->act); // the active object - QS_TEC_PRE(nTicks); // the # ticks - QS_TEC_PRE(interval); // the interval - QS_U8_PRE(tickRate); // tick rate -QS_END_PRE() - -QF_MEM_APP(); -QF_CRIT_EXIT(); - - - - //! @public @memberof QTimeEvt - -//! @public @memberof QTimeEvt - QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -QTimeEvtCtr const ctr = me->ctr; - -#ifndef Q_UNSAFE -Q_INVARIANT_INCRIT(500, QEvt_verify_(&me->super)); -QTimeEvtCtr const dis = (QTimeEvtCtr)~me->ctr_dis; -Q_INVARIANT_INCRIT(501, ctr == dis); -#endif // ndef Q_UNSAFE - -#ifdef Q_SPY -uint_fast8_t const qsId = QACTIVE_CAST_(me->act)->prio; -#endif - -// was the time event actually armed? -bool wasArmed; -if (ctr != 0U) { - wasArmed = true; - me->flags |= QTE_FLAG_WAS_DISARMED; - me->ctr = 0U; // schedule removal from the list -#ifndef Q_UNSAFE - me->ctr_dis = (QTimeEvtCtr)~0U; -#endif // ndef Q_UNSAFE - - QS_BEGIN_PRE(QS_QF_TIMEEVT_DISARM, qsId) - QS_TIME_PRE(); // timestamp - QS_OBJ_PRE(me); // this time event object - QS_OBJ_PRE(me->act); // the target AO - QS_TEC_PRE(ctr); // the # ticks - QS_TEC_PRE(me->interval); // the interval - QS_U8_PRE(me->tickRate); // tick rate - QS_END_PRE() -} -else { // the time event was already disarmed automatically - wasArmed = false; - me->flags &= (uint8_t)(~QTE_FLAG_WAS_DISARMED & 0xFFU); - - QS_BEGIN_PRE(QS_QF_TIMEEVT_DISARM_ATTEMPT, qsId) - QS_TIME_PRE(); // timestamp - QS_OBJ_PRE(me); // this time event object - QS_OBJ_PRE(me->act); // the target AO - QS_U8_PRE(me->tickRate); // tick rate - QS_END_PRE() -} - -QF_MEM_APP(); -QF_CRIT_EXIT(); - -return wasArmed; - - - - //! @public @memberof QTimeEvt - -//! @public @memberof QTimeEvt - - - QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -// dynamic range checks -#if (QF_TIMEEVT_CTR_SIZE == 1U) -Q_REQUIRE_INCRIT(600, nTicks < 0xFFU); -#elif (QF_TIMEEVT_CTR_SIZE == 2U) -Q_REQUIRE_INCRIT(600, nTicks < 0xFFFFU); -#endif - -uint8_t const tickRate = me->tickRate; -QTimeEvtCtr const ctr = me->ctr; - -Q_REQUIRE_INCRIT(600, - (nTicks != 0U) - && (me->act != (void *)0) - && (tickRate < QF_MAX_TICK_RATE)); - -#ifndef Q_UNSAFE -Q_INVARIANT_INCRIT(601, QEvt_verify_(&me->super)); -QTimeEvtCtr const dis = (QTimeEvtCtr)~me->ctr_dis; -Q_INVARIANT_INCRIT(602, ctr == dis); -#endif // ndef Q_UNSAFE - -#ifdef Q_SPY -uint_fast8_t const qsId = ((QActive *)(me->act))->prio; -#endif - -me->ctr = (QTimeEvtCtr)nTicks; -#ifndef Q_UNSAFE -me->ctr_dis = (QTimeEvtCtr)~nTicks; -#endif // ndef Q_UNSAFE - -// was the time evt not running? -bool wasArmed; -if (ctr == 0U) { - wasArmed = false; - - // NOTE: For the duration of a single clock tick of the specified - // tick rate a time event can be disarmed and yet still linked into - // the list, because unlinking is performed exclusively in the - // QTimeEvt_tick_() function. - - // is the time event unlinked? - if ((me->flags & QTE_FLAG_IS_LINKED) == 0U) { - me->flags |= QTE_FLAG_IS_LINKED; // mark as linked - - // The time event is initially inserted into the separate "freshly - // armed" link list based on QTimeEvt_timeEvtHead_[tickRate].act. - // Only later, inside the QTimeEvt_tick_() function, the "freshly - // armed" list is appended to the main list of armed time events - // based on QTimeEvt_timeEvtHead_[tickRate].next. Again, this is - // to keep any changes to the main list exclusively inside - // QTimeEvt_tick_(). -#ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(620, - Q_PTR2UINT_CAST_(me->next) == (uintptr_t)~me->next_dis); - Q_INVARIANT_INCRIT(621, - Q_PTR2UINT_CAST_(QTimeEvt_timeEvtHead_[tickRate].act) == - (uintptr_t)(~QTimeEvt_timeEvtHead_dis_[tickRate])); -#endif - me->next = (QTimeEvt *)QTimeEvt_timeEvtHead_[tickRate].act; - QTimeEvt_timeEvtHead_[tickRate].act = me; -#ifndef Q_UNSAFE - me->next_dis = (uintptr_t)~Q_PTR2UINT_CAST_(me->next); - QTimeEvt_timeEvtHead_dis_[tickRate] = - (uintptr_t)~Q_PTR2UINT_CAST_(me); -#endif // ndef Q_UNSAFE - } -} -else { // the time event was armed - wasArmed = true; -} - -QS_BEGIN_PRE(QS_QF_TIMEEVT_REARM, qsId) - QS_TIME_PRE(); // timestamp - QS_OBJ_PRE(me); // this time event object - QS_OBJ_PRE(me->act); // the target AO - QS_TEC_PRE(nTicks); // the # ticks - QS_TEC_PRE(me->interval); // the interval - QS_2U8_PRE(tickRate, (wasArmed ? 1U : 0U)); -QS_END_PRE() - -QF_MEM_APP(); -QF_CRIT_EXIT(); - -return wasArmed; - - - - //! @public @memberof QTimeEvt - -//! @public @memberof QTimeEvt - QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -bool const wasDisarmed = (me->flags & QTE_FLAG_WAS_DISARMED) != 0U; -me->flags |= QTE_FLAG_WAS_DISARMED; // mark as disarmed - -QF_MEM_APP(); -QF_CRIT_EXIT(); - -return wasDisarmed; - - - - const - //! @public @memberof QTimeEvt - -//! @public @memberof QTimeEvt - QF_CRIT_STAT -QF_CRIT_ENTRY(); -QTimeEvtCtr const ctr = me->ctr; -QF_CRIT_EXIT(); - -return ctr; - - - - //! @static @private @memberof QTimeEvt - -//! @static @private @memberof QTimeEvt - for (uint_fast8_t tickRate = 0U; - tickRate < Q_DIM(QTimeEvt_timeEvtHead_); - ++tickRate) -{ - QTimeEvt_ctorX(&QTimeEvt_timeEvtHead_[tickRate], - (QActive *)0, Q_USER_SIG, tickRate); -#ifndef Q_UNSAFE - QTimeEvt_timeEvtHead_dis_[tickRate] = - (uintptr_t)~Q_PTR2UINT_CAST_(QTimeEvt_timeEvtHead_[tickRate].act); -#endif -} - - - - //! @static @private @memberof QTimeEvt - -//! @static @private @memberof QTimeEvt - - - - - #ifndef Q_SPY -Q_UNUSED_PAR(sender); -#endif - -QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -Q_REQUIRE_INCRIT(800, tickRate < Q_DIM(QTimeEvt_timeEvtHead_)); - -QTimeEvt *prev = &QTimeEvt_timeEvtHead_[tickRate]; - -QS_BEGIN_PRE(QS_QF_TICK, 0U) - ++prev->ctr; - QS_TEC_PRE(prev->ctr); // tick ctr - QS_U8_PRE(tickRate); // tick rate -QS_END_PRE() - -// scan the linked-list of time events at this rate... -uint_fast8_t lbound = 2U*QF_MAX_ACTIVE; // fixed upper loop bound -for (; lbound > 0U; --lbound) { - Q_ASSERT_INCRIT(810, prev != (QTimeEvt *)0); // sanity check - - QTimeEvt *te = prev->next; // advance down the time evt. list -#ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(811, - Q_PTR2UINT_CAST_(te) == (uintptr_t)~prev->next_dis); -#endif // ndef Q_UNSAFE - - if (te == (QTimeEvt *)0) { // end of the list? - - // any new time events armed since the last QTimeEvt_tick_()? - if (QTimeEvt_timeEvtHead_[tickRate].act != (void *)0) { -#ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(812, - Q_PTR2UINT_CAST_(QTimeEvt_timeEvtHead_[tickRate].act) - == (uintptr_t)~QTimeEvt_timeEvtHead_dis_[tickRate]); -#endif // ndef Q_UNSAFE - prev->next = (QTimeEvt*)QTimeEvt_timeEvtHead_[tickRate].act; - QTimeEvt_timeEvtHead_[tickRate].act = (void *)0; -#ifndef Q_UNSAFE - prev->next_dis = (uintptr_t)~Q_PTR2UINT_CAST_(prev->next); - QTimeEvt_timeEvtHead_dis_[tickRate] = - (uintptr_t)~Q_PTR2UINT_CAST_((void *)0); -#endif // ndef Q_UNSAFE - - te = prev->next; // switch to the new list - } - else { // all currently armed time events are processed - break; // terminate the for-loop - } - } - - // the time event 'te' must be valid - Q_ASSERT_INCRIT(820, te != (QTimeEvt *)0); - - QTimeEvtCtr ctr = te->ctr; -#ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(821, QEvt_verify_(&te->super)); - QTimeEvtCtr const dis = (QTimeEvtCtr)~te->ctr_dis; - Q_INVARIANT_INCRIT(822, ctr == dis); -#endif // ndef Q_UNSAFE - - if (ctr == 0U) { // time event scheduled for removal? - prev->next = te->next; -#ifndef Q_UNSAFE - prev->next_dis = (uintptr_t)~Q_PTR2UINT_CAST_(te->next); -#endif // ndef Q_UNSAFE - - // mark time event 'te' as NOT linked - te->flags &= (uint8_t)(~QTE_FLAG_IS_LINKED & 0xFFU); - - // do NOT advance the prev pointer - QF_MEM_APP(); - QF_CRIT_EXIT(); // exit crit. section to reduce latency - - // NOTE: prevent merging critical sections - // In some QF ports the critical section exit takes effect only - // on the next machine instruction. If the next instruction is - // another entry to a critical section, the critical section - // might not be really exited, but rather the two adjacent - // critical sections would be MERGED. The QF_CRIT_EXIT_NOP() - // macro contains minimal code required to prevent such merging - // of critical sections in QF ports, in which it can occur. - QF_CRIT_EXIT_NOP(); - } - else if (ctr == 1U) { // is time event about to expire? - QActive * const act = (QActive *)te->act; - if (te->interval != 0U) { // periodic time evt? - te->ctr = te->interval; // rearm the time event -#ifndef Q_UNSAFE - te->ctr_dis = (QTimeEvtCtr)~te->interval; -#endif // ndef Q_UNSAFE - prev = te; // advance to this time event - } - else { // one-shot time event: automatically disarm - te->ctr = 0U; - prev->next = te->next; -#ifndef Q_UNSAFE - te->ctr_dis = (QTimeEvtCtr)~0U; - prev->next_dis = (uintptr_t)~Q_PTR2UINT_CAST_(te->next); -#endif // ndef Q_UNSAFE - - // mark time event 'te' as NOT linked - te->flags &= (uint8_t)(~QTE_FLAG_IS_LINKED & 0xFFU); - // do NOT advance the prev pointer - - QS_BEGIN_PRE(QS_QF_TIMEEVT_AUTO_DISARM, act->prio) - QS_OBJ_PRE(te); // this time event object - QS_OBJ_PRE(act); // the target AO - QS_U8_PRE(tickRate); // tick rate - QS_END_PRE() - } - - QS_BEGIN_PRE(QS_QF_TIMEEVT_POST, act->prio) - QS_TIME_PRE(); // timestamp - QS_OBJ_PRE(te); // the time event object - QS_SIG_PRE(te->super.sig);// signal of this time event - QS_OBJ_PRE(act); // the target AO - QS_U8_PRE(tickRate); // tick rate - QS_END_PRE() - -#ifdef QXK_H_ - if ((enum_t)te->super.sig < Q_USER_SIG) { - QXThread_timeout_(act); - QF_MEM_APP(); - QF_CRIT_EXIT(); - } - else { - QF_MEM_APP(); - QF_CRIT_EXIT(); // exit crit. section before posting - - // QACTIVE_POST() asserts if the queue overflows - QACTIVE_POST(act, &te->super, sender); - } -#else - QF_MEM_APP(); - QF_CRIT_EXIT(); // exit crit. section before posting - - // QACTIVE_POST() asserts if the queue overflows - QACTIVE_POST(act, &te->super, sender); -#endif - } - else { // time event keeps timing out - --ctr; // decrement the tick counter - te->ctr = ctr; // update the original -#ifndef Q_UNSAFE - te->ctr_dis = (QTimeEvtCtr)~ctr; -#endif // ndef Q_UNSAFE - - prev = te; // advance to this time event - - QF_MEM_APP(); - QF_CRIT_EXIT(); // exit crit. section to reduce latency - - // prevent merging critical sections, see NOTE above - QF_CRIT_EXIT_NOP(); - } - QF_CRIT_ENTRY(); // re-enter crit. section to continue the loop - QF_MEM_SYS(); -} - -Q_ENSURE_INCRIT(890, lbound > 0U); -QF_MEM_APP(); -QF_CRIT_EXIT(); - - - - //! @static @private @memberof QTimeEvt - -//! @static @private @memberof QTimeEvt - - - - - - - - //! @static @public @memberof QTimeEvt - -//! @static @public @memberof QTimeEvt - - - // NOTE: this function must be called *inside* critical section -Q_REQUIRE_INCRIT(900, tickRate < QF_MAX_TICK_RATE); - -bool inactive; - -QF_MEM_SYS(); -if (QTimeEvt_timeEvtHead_[tickRate].next != (QTimeEvt *)0) { - inactive = false; -} -else if ((QTimeEvt_timeEvtHead_[tickRate].act != (void *)0)) { - inactive = false; -} -else { - inactive = true; -} -QF_MEM_APP(); - -return inactive; - - - - - //! @class QTicker -//! @extends QActive - - - //! @public @memberof QTicker - -//! @public @memberof QTicker - - - QActive_ctor(&me->super, Q_STATE_CAST(0)); // superclass' ctor - -static struct QAsmVtable const vtable = { // QTicker virtual table - &QTicker_init_, - &QTicker_dispatch_, - &QHsm_isIn_ -#ifdef Q_SPY - ,&QHsm_getStateHandler_ -#endif -}; -me->super.super.vptr = &vtable; // hook the vptr - -// reuse eQueue.head for tick-rate -me->super.eQueue.head = (QEQueueCtr)tickRate; -#ifndef Q_UNSAFE -me->super.eQueue.head_dis = (QEQueueCtr)~tickRate; -#endif // ndef Q_UNSAFE - - - - //! @private @memberof QTicker - -//! @private @memberof QTicker - - - - - - - Q_UNUSED_PAR(me); -Q_UNUSED_PAR(par); -Q_UNUSED_PAR(qsId); - -QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -QACTIVE_CAST_(me)->eQueue.tail = 0U; -#ifndef Q_UNSAFE -QACTIVE_CAST_(me)->eQueue.tail_dis = (QEQueueCtr)~0U; -#endif // ndef Q_UNSAFE - -QF_MEM_APP(); -QF_CRIT_EXIT(); - - - - //! @private @memberof QTicker - -//! @private @memberof QTicker - - - - - - - Q_UNUSED_PAR(e); -Q_UNUSED_PAR(qsId); - -QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -// get volatile into temporaries -QEQueueCtr nTicks = QACTIVE_CAST_(me)->eQueue.tail; -QEQueueCtr const tickRate = QACTIVE_CAST_(me)->eQueue.head; - -#ifndef Q_UNSAFE -Q_REQUIRE_INCRIT(700, nTicks > 0U); -QEQueueCtr dis = (QEQueueCtr)~QACTIVE_CAST_(me)->eQueue.tail_dis; -Q_INVARIANT_INCRIT(701, nTicks == dis); -dis = (QEQueueCtr)~QACTIVE_CAST_(me)->eQueue.head_dis; -Q_INVARIANT_INCRIT(702, tickRate == dis); -#endif // ndef Q_UNSAFE - -QACTIVE_CAST_(me)->eQueue.tail = 0U; // clear # ticks -#ifndef Q_UNSAFE -QACTIVE_CAST_(me)->eQueue.tail_dis = (QEQueueCtr)~0U; -#endif // ndef Q_UNSAFE - -QF_MEM_APP(); -QF_CRIT_EXIT(); - -for (; nTicks > 0U; --nTicks) { - QTimeEvt_tick_((uint_fast8_t)tickRate, me); -} - - - - //! @private @memberof QTicker - -//! @private @memberof QTicker - - - - - #ifndef Q_SPY -Q_UNUSED_PAR(sender); -#endif - -static QEvt const tickEvt = QEVT_INITIALIZER(0); - -QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -QEQueueCtr nTicks = me->eQueue.tail; // get volatile into temporary - -if (me->eQueue.frontEvt == (QEvt *)0) { // no tick events? -#ifndef Q_UNSAFE - Q_REQUIRE_INCRIT(800, nTicks == 0U); - Q_REQUIRE_INCRIT(801, me->eQueue.nFree == 1U); - Q_INVARIANT_INCRIT(802, me->eQueue.frontEvt_dis - == (uintptr_t)~Q_PTR2UINT_CAST_((QEvt *)0)); - QEQueueCtr dis = (QEQueueCtr)~me->eQueue.nFree_dis; - Q_INVARIANT_INCRIT(803, 1U == dis); - dis = (QEQueueCtr)~me->eQueue.tail_dis; - Q_INVARIANT_INCRIT(804, 0U == dis); -#endif // ndef Q_UNSAFE - - me->eQueue.frontEvt = &tickEvt; // deliver event directly - me->eQueue.nFree = 0U; -#ifndef Q_UNSAFE - me->eQueue.frontEvt_dis = (uintptr_t)~Q_PTR2UINT_CAST_(&tickEvt); - me->eQueue.nFree_dis = (QEQueueCtr)~0U; -#endif // ndef Q_UNSAFE - - QACTIVE_EQUEUE_SIGNAL_(me); // signal the event queue -} -else { -#ifndef Q_UNSAFE - Q_REQUIRE_INCRIT(810, (nTicks > 0U) && (nTicks < 0xFFU)); - Q_REQUIRE_INCRIT(811, me->eQueue.nFree == 0U); - Q_INVARIANT_INCRIT(812, me->eQueue.frontEvt_dis - == (uintptr_t)~Q_PTR2UINT_CAST_(&tickEvt)); - QEQueueCtr dis = (QEQueueCtr)~me->eQueue.nFree_dis; - Q_INVARIANT_INCRIT(813, 0U == dis); - dis = (QEQueueCtr)~me->eQueue.tail_dis; - Q_INVARIANT_INCRIT(814, nTicks == dis); -#endif // ndef Q_UNSAFE -} - -++nTicks; // account for one more tick event - -me->eQueue.tail = nTicks; // update the original -#ifndef Q_UNSAFE -me->eQueue.tail_dis = (QEQueueCtr)~nTicks; -#endif // ndef Q_UNSAFE - -QS_BEGIN_PRE(QS_QF_ACTIVE_POST, me->prio) - QS_TIME_PRE(); // timestamp - QS_OBJ_PRE(sender); // the sender object - QS_SIG_PRE(0U); // the signal of the event - QS_OBJ_PRE(me); // this active object - QS_2U8_PRE(0U, 0U); // poolNum & refCtr - QS_EQC_PRE(0U); // # free entries - QS_EQC_PRE(0U); // min # free entries -QS_END_PRE() - -QF_MEM_APP(); -QF_CRIT_EXIT(); - - - - - //! @class QEQueue - - - //! @private @memberof QEQueue - - - - //! @private @memberof QEQueue - - - - //! @private @memberof QEQueue - - - - //! @private @memberof QEQueue - - - - //! @private @memberof QEQueue - - - - //! @private @memberof QEQueue - - - - //! @private @memberof QEQueue - - - - //! @private @memberof QEQueue - - - - //! @private @memberof QEQueue - - - - //! @private @memberof QEQueue - - - - //! @private @memberof QEQueue - - - - // dummy static member to force generating 'struct QEQueue {...}' - - - - //! @public @memberof QEQueue - -//! @public @memberof QEQueue - - - - - QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -#if (QF_EQUEUE_CTR_SIZE == 1U) -Q_REQUIRE_INCRIT(100, qLen < 0xFFU); -#endif - -me->frontEvt = (QEvt *)0; // no events in the queue -me->ring = qSto; // the beginning of the ring buffer -me->end = (QEQueueCtr)qLen; -if (qLen > 0U) { - me->head = 0U; - me->tail = 0U; -} -me->nFree = (QEQueueCtr)(qLen + 1U); // +1 for frontEvt - -#ifndef Q_UNSAFE -me->frontEvt_dis = (uintptr_t)~Q_PTR2UINT_CAST_(me->frontEvt); -me->head_dis = (QEQueueCtr)~me->head; -me->tail_dis = (QEQueueCtr)~me->tail; -me->nFree_dis = (QEQueueCtr)~me->nFree; -me->nMin = me->nFree; -#endif - -QF_MEM_APP(); -QF_CRIT_EXIT(); - - - - //! @public @memberof QEQueue - -//! @public @memberof QEQueue - - - - - - - #ifndef Q_SPY -Q_UNUSED_PAR(qsId); -#endif - -QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -Q_REQUIRE_INCRIT(200, e != (QEvt *)0); - -QEQueueCtr tmp = me->nFree; // get volatile into temporary - -#ifndef Q_UNSAFE -Q_INVARIANT_INCRIT(201, QEvt_verify_(e)); -QEQueueCtr dis = (QEQueueCtr)~me->nFree_dis; -Q_INVARIANT_INCRIT(202, tmp == dis); -#endif // ndef Q_UNSAFE - -// test-probe#1 for faking queue overflow -QS_TEST_PROBE_DEF(&QEQueue_post) -QS_TEST_PROBE_ID(1, - tmp = 0U; // fake no free events -) - -// required margin available? -bool status; -if (((margin == QF_NO_MARGIN) && (tmp > 0U)) - || (tmp > (QEQueueCtr)margin)) -{ - // is it a mutable event? - if (QEvt_getPoolNum_(e) != 0U) { - QEvt_refCtr_inc_(e); // increment the reference counter - } - - --tmp; // one free entry just used up - - me->nFree = tmp; // update the original -#ifndef Q_UNSAFE - me->nFree_dis = (QEQueueCtr)~tmp; - - if (me->nMin > tmp) { - me->nMin = tmp; // update minimum so far - } -#endif // ndef Q_UNSAFE - - QS_BEGIN_PRE(QS_QF_EQUEUE_POST, qsId) - QS_TIME_PRE(); // timestamp - QS_SIG_PRE(e->sig); // the signal of the event - QS_OBJ_PRE(me); // this queue object - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); - QS_EQC_PRE(tmp); // # free entries -#ifndef Q_UNSAFE - QS_EQC_PRE(me->nMin); // min # free entries -#else - QS_EQC_PRE(0U); // min # free entries -#endif - QS_END_PRE() - - if (me->frontEvt == (QEvt *)0) { // is the queue empty? - me->frontEvt = e; // deliver event directly -#ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(211, me->frontEvt_dis - == (uintptr_t)~Q_PTR2UINT_CAST_((QEvt *)0)); - me->frontEvt_dis = (uintptr_t)~Q_PTR2UINT_CAST_(e); -#endif // ndef Q_UNSAFE - } - else { // queue was not empty, insert event into the ring-buffer - tmp = me->head; // get volatile into temporary -#ifndef Q_UNSAFE - dis = (QEQueueCtr)~me->head_dis; - Q_INVARIANT_INCRIT(212, tmp == dis); -#endif // ndef Q_UNSAFE - me->ring[tmp] = e; // insert e into buffer - - if (tmp == 0U) { // need to wrap the head? - tmp = me->end; - } - --tmp; // advance head (counter-clockwise) - - me->head = tmp; // update the original -#ifndef Q_UNSAFE - me->head_dis = (QEQueueCtr)~tmp; -#endif // ndef Q_UNSAFE - } - status = true; // event posted successfully -} -else { // event cannot be posted - // dropping events must be acceptable - Q_ASSERT_INCRIT(210, margin != QF_NO_MARGIN); - - QS_BEGIN_PRE(QS_QF_EQUEUE_POST_ATTEMPT, qsId) - QS_TIME_PRE(); // timestamp - QS_SIG_PRE(e->sig); // the signal of this event - QS_OBJ_PRE(me); // this queue object - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); - QS_EQC_PRE(tmp); // # free entries - QS_EQC_PRE(margin); // margin requested - QS_END_PRE() - - status = false; // event not posted -} - -QF_MEM_APP(); -QF_CRIT_EXIT(); - -return status; - - - - //! @public @memberof QEQueue - -//! @public @memberof QEQueue - - - - - #ifndef Q_SPY -Q_UNUSED_PAR(qsId); -#endif - -QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -Q_REQUIRE_INCRIT(300, e != (QEvt *)0); - -QEQueueCtr tmp = me->nFree; // get volatile into temporary - -#ifndef Q_UNSAFE -Q_INVARIANT_INCRIT(301, QEvt_verify_(e)); -QEQueueCtr dis = (QEQueueCtr)~me->nFree_dis; -Q_INVARIANT_INCRIT(302, tmp == dis); -#endif // ndef Q_UNSAFE - -// test-probe#1 for faking queue overflow -QS_TEST_PROBE_DEF(&QEQueue_postLIFO) -QS_TEST_PROBE_ID(1, - tmp = 0U; // fake no free events -) - -// must be able to LIFO-post the event -Q_REQUIRE_INCRIT(310, tmp != 0U); - -if (QEvt_getPoolNum_(e) != 0U) { // is it a mutable event? - QEvt_refCtr_inc_(e); // increment the reference counter -} - ---tmp; // one free entry just used up - -me->nFree = tmp; // update the original -#ifndef Q_UNSAFE -me->nFree_dis = (QEQueueCtr)~tmp; - -if (me->nMin > tmp) { - me->nMin = tmp; // update minimum so far -} -#endif // ndef Q_UNSAFE - -QS_BEGIN_PRE(QS_QF_EQUEUE_POST_LIFO, qsId) - QS_TIME_PRE(); // timestamp - QS_SIG_PRE(e->sig); // the signal of this event - QS_OBJ_PRE(me); // this queue object - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); - QS_EQC_PRE(tmp); // # free entries -#ifndef Q_UNSAFE - QS_EQC_PRE(me->nMin); // min # free entries -#else - QS_EQC_PRE(0U); // min # free entries -#endif -QS_END_PRE() - -QEvt const * const frontEvt = me->frontEvt; -me->frontEvt = e; // deliver the event directly to the front -#ifndef Q_UNSAFE -me->frontEvt_dis = (uintptr_t)~Q_PTR2UINT_CAST_(e); -#endif // ndef Q_UNSAFE - -if (frontEvt != (QEvt *)0) { // was the queue NOT empty? - tmp = me->tail; // get volatile into temporary; -#ifndef Q_UNSAFE - dis = (QEQueueCtr)~me->tail_dis; - Q_INVARIANT_INCRIT(311, tmp == dis); -#endif // ndef Q_UNSAFE - ++tmp; - if (tmp == me->end) { // need to wrap the tail? - tmp = 0U; // wrap around - } - me->tail = tmp; -#ifndef Q_UNSAFE - me->tail_dis = (QEQueueCtr)~tmp; -#endif - me->ring[tmp] = frontEvt; -} - -QF_MEM_APP(); -QF_CRIT_EXIT(); - - - - //! @public @memberof QEQueue - -//! @public @memberof QEQueue - - - #ifndef Q_SPY -Q_UNUSED_PAR(qsId); -#endif - -QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -QEvt const * const e = me->frontEvt; // always remove evt from the front -#ifndef Q_UNSAFE -Q_INVARIANT_INCRIT(411, Q_PTR2UINT_CAST_(e) - == (uintptr_t)~me->frontEvt_dis); -#endif // ndef Q_UNSAFE - -if (e != (QEvt *)0) { // was the queue not empty? - QEQueueCtr tmp = me->nFree; // get volatile into temporary -#ifndef Q_UNSAFE - QEQueueCtr const dis = (QEQueueCtr)~me->nFree_dis; - Q_INVARIANT_INCRIT(412, tmp == dis); -#endif // ndef Q_UNSAFE - - ++tmp; // one more free event in the queue - - me->nFree = tmp; // update the # free -#ifndef Q_UNSAFE - me->nFree_dis = (QEQueueCtr)~tmp; -#endif // ndef Q_UNSAFE - - // any events in the ring buffer? - if (tmp <= me->end) { - - QS_BEGIN_PRE(QS_QF_EQUEUE_GET, qsId) - QS_TIME_PRE(); // timestamp - QS_SIG_PRE(e->sig); // the signal of this event - QS_OBJ_PRE(me); // this queue object - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); - QS_EQC_PRE(tmp); // # free entries - QS_END_PRE() - - tmp = me->tail; // get volatile into temporary - QEvt const * const frontEvt = me->ring[tmp]; -#ifndef Q_UNSAFE - Q_ASSERT_INCRIT(421, frontEvt != (QEvt *)0); - me->frontEvt_dis = (uintptr_t)~Q_PTR2UINT_CAST_(frontEvt); -#endif // ndef Q_UNSAFE - me->frontEvt = frontEvt; // update the original - - if (tmp == 0U) { // need to wrap the tail? - tmp = me->end; - } - --tmp; // advance the tail (counter-clockwise) - me->tail = tmp; // update the original -#ifndef Q_UNSAFE - me->tail_dis = (QEQueueCtr)~tmp; -#endif // ndef Q_UNSAFE - } - else { - me->frontEvt = (QEvt *)0; // queue becomes empty -#ifndef Q_UNSAFE - me->frontEvt_dis = (uintptr_t)~Q_PTR2UINT_CAST_((QEvt *)0); -#endif // ndef Q_UNSAFE - - // all entries in the queue must be free (+1 for frontEvt) - Q_INVARIANT_INCRIT(440, tmp == (me->end + 1U)); - - QS_BEGIN_PRE(QS_QF_EQUEUE_GET_LAST, qsId) - QS_TIME_PRE(); // timestamp - QS_SIG_PRE(e->sig); // the signal of this event - QS_OBJ_PRE(me); // this queue object - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); - QS_END_PRE() - } -} - -QF_MEM_APP(); -QF_CRIT_EXIT(); - -return e; - - - - const - //! @public @memberof QEQueue - -//! @public @memberof QEQueue - return me->nFree; - - - - const - //! @public @memberof QEQueue - -//! @public @memberof QEQueue - #ifndef Q_UNSAFE -return me->nMin; -#else -return 0U; -#endif - - - - const - //! @public @memberof QEQueue - -//! @public @memberof QEQueue - return me->frontEvt == (struct QEvt *)0; - - - - - //! @struct QFreeBlock - - - //! @private @memberof QFreeBlock - - - - //! @private @memberof QFreeBlock - - - - - //! @class QMPool - - - //! @private @memberof QMPool - - - - //! @private @memberof QMPool - - - - //! @private @memberof QMPool - - - - //! @private @memberof QMPool - - - - //! @private @memberof QMPool - - - - //! @private @memberof QMPool - - - - //! @private @memberof QMPool - - - - //! @private @memberof QMPool - - - - //! @private @memberof QMPool - - - - //! @public @memberof QMPool - -//! @public @memberof QMPool - - - - - - - QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -Q_REQUIRE_INCRIT(100, poolSto != (void *)0); -Q_REQUIRE_INCRIT(101, poolSize >= (uint_fast32_t)sizeof(QFreeBlock)); -Q_REQUIRE_INCRIT(102, (uint_fast16_t)(blockSize + sizeof(QFreeBlock)) - > blockSize); - -me->free_head = (QFreeBlock *)poolSto; - -// find # free blocks in a memory block, NO DIVISION -me->blockSize = (QMPoolSize)(2U * sizeof(void *)); -uint_fast16_t nblocks = 1U; -while (me->blockSize < (QMPoolSize)blockSize) { - me->blockSize += (QMPoolSize)sizeof(QFreeBlock); - ++nblocks; -} - -// the pool buffer must fit at least one rounded-up block -Q_ASSERT_INCRIT(110, poolSize >= me->blockSize); - -// start at the head of the free list -QFreeBlock *fb = me->free_head; -uint32_t nTot = 1U; // the last block already in the list - -// chain all blocks together in a free-list... -for (uint_fast32_t size = poolSize - me->blockSize; - size >= (uint_fast32_t)me->blockSize; - size -= (uint_fast32_t)me->blockSize) -{ - fb->next = &fb[nblocks]; // point next link to next block -#ifndef Q_UNSAFE - fb->next_dis = (uintptr_t)(~Q_PTR2UINT_CAST_(fb->next)); -#endif - fb = fb->next; // advance to the next block - ++nTot; // one more free block in the pool -} - -// dynamic range check -#if (QF_MPOOL_CTR_SIZE == 1U) -Q_ENSURE_INCRIT(190, nTot < 0xFFU); -#elif (QF_MPOOL_CTR_SIZE == 2U) -Q_ENSURE_INCRIT(190, nTot < 0xFFFFU); -#endif - -fb->next = (QFreeBlock *)0; // the last link points to NULL - -me->nTot = (QMPoolCtr)nTot; -me->nFree = me->nTot; // all blocks are free -me->start = (QFreeBlock *)poolSto; // the original start this pool buffer -me->end = fb; // the last block in this pool - -#ifndef Q_UNSAFE -me->free_head_dis = (uintptr_t)~Q_PTR2UINT_CAST_(me->free_head); -me->nFree_dis = (QMPoolCtr)~me->nFree; -me->nMin = me->nTot; // the minimum # free blocks -fb->next_dis = (uintptr_t)(~Q_PTR2UINT_CAST_(fb->next)); -#endif - -QF_MEM_APP(); -QF_CRIT_EXIT(); - - - - //! @public @memberof QMPool - -//! @public @memberof QMPool - - - - - #ifndef Q_SPY -Q_UNUSED_PAR(qsId); -#endif - -QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -// get volatile into temporaries -QFreeBlock *fb = me->free_head; -QMPoolCtr nFree = me->nFree; - -#ifndef Q_UNSAFE -Q_INVARIANT_INCRIT(301, Q_PTR2UINT_CAST_(fb) - == (uintptr_t)~me->free_head_dis); -QMPoolCtr const dis = (QMPoolCtr)~me->nFree_dis; -Q_INVARIANT_INCRIT(302, nFree == dis); -#endif // ndef Q_UNSAFE - -// have more free blocks than the requested margin? -if (nFree > (QMPoolCtr)margin) { - Q_ASSERT_INCRIT(310, fb != (QFreeBlock *)0); - - QFreeBlock * const fb_next = fb->next; // fast temporary - -#ifndef Q_UNSAFE - // the free block must have integrity (duplicate inverse storage) - Q_INVARIANT_INCRIT(311, Q_PTR2UINT_CAST_(fb_next) - == (uintptr_t)~fb->next_dis); -#endif // ndef Q_UNSAFE - - --nFree; // one less free block - if (nFree == 0U) { // is the pool becoming empty? - // pool is becoming empty, so the next free block must be NULL - Q_ASSERT_INCRIT(320, fb_next == (QFreeBlock *)0); - - me->nFree = 0U; -#ifndef Q_UNSAFE - me->nFree_dis = (QMPoolCtr)~0U; - me->nMin = 0U; // remember that the pool got empty -#endif // ndef Q_UNSAFE - } - else { - me->nFree = nFree; // update the original -#ifndef Q_UNSAFE - me->nFree_dis = (QMPoolCtr)~nFree; - - // The pool is not empty, so the next free-block pointer - // must be in range. - Q_INVARIANT_INCRIT(330, - (me->start <= fb_next) && (fb_next <= me->end)); - - // is the # free blocks the new minimum so far? - if (me->nMin > nFree) { - me->nMin = nFree; // remember the minimum so far - } -#endif // ndef Q_UNSAFE - } - - me->free_head = fb_next; // set the head to the next free block -#ifndef Q_UNSAFE - me->free_head_dis = (uintptr_t)(~Q_PTR2UINT_CAST_(fb_next)); -#endif // ndef Q_UNSAFE - - QS_BEGIN_PRE(QS_QF_MPOOL_GET, qsId) - QS_TIME_PRE(); // timestamp - QS_OBJ_PRE(me); // this memory pool - QS_MPC_PRE(nFree); // # of free blocks in the pool -#ifndef Q_UNSAFE - QS_MPC_PRE(me->nMin); // min # free blocks ever in the pool -#else - QS_MPC_PRE(0U); // min # free blocks (not available) -#endif // ndef Q_UNSAFE - QS_END_PRE() -} -else { // don't have enough free blocks at this point - fb = (QFreeBlock *)0; - - QS_BEGIN_PRE(QS_QF_MPOOL_GET_ATTEMPT, qsId) - QS_TIME_PRE(); // timestamp - QS_OBJ_PRE(me); // this memory pool - QS_MPC_PRE(nFree); // # of free blocks in the pool - QS_MPC_PRE(margin); // the requested margin - QS_END_PRE() -} - -QF_MEM_APP(); -QF_CRIT_EXIT(); - -return fb; // return the block or NULL pointer to the caller - - - - //! @public @memberof QMPool - -//! @public @memberof QMPool - - - - - #ifndef Q_SPY -Q_UNUSED_PAR(qsId); -#endif - -QFreeBlock * const fb = (QFreeBlock *)block; - -QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -// get volatile into temporaries -QFreeBlock * const free_head = me->free_head; -QMPoolCtr nFree = me->nFree; - -#ifndef Q_UNSAFE -Q_INVARIANT_INCRIT(401, Q_PTR2UINT_CAST_(free_head) - == (uintptr_t)~me->free_head_dis); -QMPoolCtr const dis = (QMPoolCtr)~me->nFree_dis; -Q_INVARIANT_INCRIT(402, nFree == dis); - -Q_REQUIRE_INCRIT(410, nFree < me->nTot); -Q_REQUIRE_INCRIT(411, (me->start <= fb) && (fb <= me->end)); - -// the block must not be in the pool already -Q_REQUIRE_INCRIT(412, Q_PTR2UINT_CAST_(fb->next) - != (uintptr_t)~fb->next_dis); -#endif // ndef Q_UNSAFE - -++nFree; // one more free block in this pool - -me->free_head = fb; // set as new head of the free list -me->nFree = nFree; -fb->next = free_head; // link into the list -#ifndef Q_UNSAFE -me->free_head_dis = (uintptr_t)(~Q_PTR2UINT_CAST_(fb)); -me->nFree_dis = (QMPoolCtr)~nFree; -fb->next_dis = (uintptr_t)(~Q_PTR2UINT_CAST_(free_head)); -#endif - -QS_BEGIN_PRE(QS_QF_MPOOL_PUT, qsId) - QS_TIME_PRE(); // timestamp - QS_OBJ_PRE(me); // this memory pool - QS_MPC_PRE(nFree); // the # free blocks in the pool -QS_END_PRE() - -QF_MEM_APP(); -QF_CRIT_EXIT(); - - - - - - - //! @class QF_Attr - - - //! @private @memberof QF_Attr - - - - //! @private @memberof QF_Attr - - - - //! @private @memberof QF_Attr - - - - - //! @static @private @memberof QF - - - - //! @static @private @memberof QF - -//! @static @private @memberof QF - - - - - uint8_t *ptr = (uint8_t *)start; -for (uint_fast16_t n = len; n > 0U; --n) { - *ptr = 0U; - ++ptr; -} - - - - - - - //! @static @public @memberof QF - -//! @static @public @memberof QF - - - - //! @static @public @memberof QF - -//! @static @public @memberof QF - - - - //! @static @public @memberof QF - -//! @static @public @memberof QF - - - - //! @static @public @memberof QF - -//! @static @public @memberof QF - - - QF_CRIT_STAT -QF_CRIT_ENTRY(); -Q_REQUIRE_INCRIT(400, (prio <= QF_MAX_ACTIVE) - && (QActive_registry_[prio] != (QActive *)0)); -#ifndef Q_UNSAFE -uint_fast16_t const min = - (uint_fast16_t)QActive_registry_[prio]->eQueue.nMin; -#else -uint_fast16_t const min = 0U; -#endif -QF_CRIT_EXIT(); - -return min; - - - - //! @static @public @memberof QF - -//! @static @public @memberof QF - - - - //! @static @public @memberof QF - -//! @static @public @memberof QF - - - - //! @static @public @memberof QF - -//! @static @public @memberof QF - - - - - - - - - - - //! @static @public @memberof QF - -//! @static @public @memberof QF - - - - - - - uint_fast8_t const poolNum = QF_priv_.maxPool_; - -// see precondition{qf_dyn,200} and precondition{qf_dyn,201} -QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -Q_REQUIRE_INCRIT(200, poolNum < QF_MAX_EPOOL); -if (poolNum > 0U) { - Q_REQUIRE_INCRIT(201, - QF_EPOOL_EVENT_SIZE_(QF_priv_.ePool_[poolNum - 1U]) < evtSize); -} -QF_priv_.maxPool_ = poolNum + 1U; // one more pool - -QF_MEM_APP(); -QF_CRIT_EXIT(); - -// perform the port-dependent initialization of the event-pool -QF_EPOOL_INIT_(QF_priv_.ePool_[poolNum], poolSto, poolSize, evtSize); - -#ifdef Q_SPY -// generate the object-dictionary entry for the initialized pool -{ - uint8_t obj_name[9] = "EvtPool?"; - obj_name[7] = (uint8_t)((uint8_t)'0' + poolNum + 1U); - QS_obj_dict_pre_(&QF_priv_.ePool_[poolNum], (char const *)obj_name); -} -#endif // Q_SPY - - - - //! @static @public @memberof QF - -//! @static @public @memberof QF - QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); -uint_fast16_t const max_size = - QF_EPOOL_EVENT_SIZE_(QF_priv_.ePool_[QF_priv_.maxPool_ - 1U]); -QF_MEM_APP(); -QF_CRIT_EXIT(); - -return max_size; - - - - //! @static @public @memberof QF - -//! @static @public @memberof QF - - - QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -Q_REQUIRE_INCRIT(400, (poolNum <= QF_MAX_EPOOL) - && (0U < poolNum) && (poolNum <= QF_priv_.maxPool_)); - -#ifndef Q_UNSAFE -uint_fast16_t const min = (uint_fast16_t)QF_priv_.ePool_[poolNum - 1U].nMin; -#else -uint_fast16_t const min = 0U; -#endif - -QF_MEM_APP(); -QF_CRIT_EXIT(); - -return min; - - - - //! @static @private @memberof QF - -//! @static @private @memberof QF - - - - - - - QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -// find the pool id that fits the requested event size... -uint_fast8_t poolNum = 0U; // zero-based poolNum initially -for (; poolNum < QF_priv_.maxPool_; ++poolNum) { - if (evtSize <= QF_EPOOL_EVENT_SIZE_(QF_priv_.ePool_[poolNum])) { - break; - } -} - -// precondition: -// - cannot run out of registered pools -Q_REQUIRE_INCRIT(300, poolNum < QF_priv_.maxPool_); - -++poolNum; // convert to 1-based poolNum - -QF_MEM_APP(); -QF_CRIT_EXIT(); - -// get event e (port-dependent)... -QEvt *e; -#ifdef Q_SPY -QF_EPOOL_GET_(QF_priv_.ePool_[poolNum - 1U], e, - ((margin != QF_NO_MARGIN) ? margin : 0U), - (uint_fast8_t)QS_EP_ID + poolNum); -#else -QF_EPOOL_GET_(QF_priv_.ePool_[poolNum - 1U], e, - ((margin != QF_NO_MARGIN) ? margin : 0U), 0U); -#endif - -if (e != (QEvt *)0) { // was e allocated correctly? - e->sig = (QSignal)sig; // set the signal - e->refCtr_ = 0U; // initialize the reference counter to 0 - e->evtTag_ = (uint8_t)((poolNum << 4U) | 0x0FU); - - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_BEGIN_PRE(QS_QF_NEW, - (uint_fast8_t)QS_EP_ID + poolNum) - QS_TIME_PRE(); // timestamp - QS_EVS_PRE(evtSize); // the size of the event - QS_SIG_PRE(sig); // the signal of the event - QS_END_PRE() - QS_MEM_APP(); - QS_CRIT_EXIT(); -} -else { // event was not allocated - - QF_CRIT_ENTRY(); - // This assertion means that the event allocation failed, - // and this failure cannot be tolerated. The most frequent - // reason is an event leak in the application. - Q_ASSERT_INCRIT(320, margin != QF_NO_MARGIN); - - QS_MEM_SYS(); - QS_BEGIN_PRE(QS_QF_NEW_ATTEMPT, - (uint_fast8_t)QS_EP_ID + poolNum) - QS_TIME_PRE(); // timestamp - QS_EVS_PRE(evtSize); // the size of the event - QS_SIG_PRE(sig); // the signal of the event - QS_END_PRE() - QS_MEM_APP(); - - QF_CRIT_EXIT(); -} - -// the returned event e is guaranteed to be valid (not NULL) -// if we can't tolerate failed allocation -return e; - - - - //! @static @public @memberof QF - -//! @static @public @memberof QF - - - QF_CRIT_STAT -QF_CRIT_ENTRY(); - -Q_REQUIRE_INCRIT(400, e != (QEvt *)0); - -#ifndef Q_UNSAFE -Q_INVARIANT_INCRIT(401, QEvt_verify_(e)); -#endif - -uint_fast8_t const poolNum = QEvt_getPoolNum_(e); - -if (poolNum != 0U) { // is it a pool event (mutable)? - QF_MEM_SYS(); - - if (e->refCtr_ > 1U) { // isn't this the last reference? - - QS_BEGIN_PRE(QS_QF_GC_ATTEMPT, - (uint_fast8_t)QS_EP_ID + poolNum) - QS_TIME_PRE(); // timestamp - QS_SIG_PRE(e->sig); // the signal of the event - QS_2U8_PRE(poolNum, e->refCtr_); - QS_END_PRE() - - QEvt_refCtr_dec_(e); // decrement the ref counter - - QF_MEM_APP(); - QF_CRIT_EXIT(); - } - else { // this is the last reference to this event, recycle it - - QS_BEGIN_PRE(QS_QF_GC, - (uint_fast8_t)QS_EP_ID + poolNum) - QS_TIME_PRE(); // timestamp - QS_SIG_PRE(e->sig); // the signal of the event - QS_2U8_PRE(poolNum, e->refCtr_); - QS_END_PRE() - - // pool number must be in range - Q_ASSERT_INCRIT(410, (poolNum <= QF_priv_.maxPool_) - && (poolNum <= QF_MAX_EPOOL)); - QF_MEM_APP(); - QF_CRIT_EXIT(); - - // NOTE: casting 'const' away is legit because it's a pool event -#ifdef Q_SPY - QF_EPOOL_PUT_(QF_priv_.ePool_[poolNum - 1U], - (QEvt *)e, - (uint_fast8_t)QS_EP_ID + poolNum); -#else - QF_EPOOL_PUT_(QF_priv_.ePool_[poolNum - 1U], - (QEvt *)e, 0U); -#endif - } -} -else { - QF_CRIT_EXIT(); -} - - - - //! @static @private @memberof QF - -//! @static @private @memberof QF - - - - - #ifdef Q_UNSAFE -Q_UNUSED_PAR(evtRef); -#endif - -QF_CRIT_STAT -QF_CRIT_ENTRY(); - -Q_REQUIRE_INCRIT(500, e != (QEvt *)0); -#ifndef Q_UNSAFE -Q_INVARIANT_INCRIT(501, QEvt_verify_(e)); -#endif - -uint_fast8_t const poolNum = QEvt_getPoolNum_(e); -Q_UNUSED_PAR(poolNum); // might be unused - -Q_REQUIRE_INCRIT(510, (poolNum != 0U) - && (evtRef == (void *)0)); - -QEvt_refCtr_inc_(e); // increments the ref counter - -QS_MEM_SYS(); -QS_BEGIN_PRE(QS_QF_NEW_REF, - (uint_fast8_t)QS_EP_ID + poolNum) - QS_TIME_PRE(); // timestamp - QS_SIG_PRE(e->sig); // the signal of the event - QS_2U8_PRE(poolNum, e->refCtr_); -QS_END_PRE() -QS_MEM_APP(); - -QF_CRIT_EXIT(); - -return e; - - - - //! @static @private @memberof QF - -//! @static @private @memberof QF - - - QF_CRIT_STAT -QF_CRIT_ENTRY(); - -QEvt const * const e = (QEvt const *)evtRef; -Q_REQUIRE_INCRIT(600, e != (QEvt *)0); -#ifndef Q_UNSAFE -Q_INVARIANT_INCRIT(601, QEvt_verify_(e)); -#endif // ndef Q_UNSAFE - -#ifdef Q_SPY -uint_fast8_t const poolNum = QEvt_getPoolNum_(e); -QS_MEM_SYS(); -QS_BEGIN_PRE(QS_QF_DELETE_REF, - (uint_fast8_t)QS_EP_ID + poolNum) - QS_TIME_PRE(); // timestamp - QS_SIG_PRE(e->sig); // the signal of the event - QS_2U8_PRE(poolNum, e->refCtr_); -QS_END_PRE() -QS_MEM_APP(); -#endif // def Q_SPY - -QF_CRIT_EXIT(); - -#if (QF_MAX_EPOOL > 0U) -QF_gc(e); // recycle the referenced event -#endif - - - - //! @static @public @memberof QF - -//! @static @public @memberof QF - - - - - - - - - - ((uint_fast16_t)0xFFFFU) - - - - - - - - ((QPrioSpec)((prio_) | ((pthre_) << 8U))) - - - - - - - - ((evtT_ *)QF_newX_((uint_fast16_t)sizeof(evtT_), \ - QF_NO_MARGIN, (enum_t)(sig_))) - - - - - - - - - - \ - (evtT_##_init((evtT_ *)QF_newX_((uint_fast16_t)sizeof(evtT_), \ - QF_NO_MARGIN, (sig_)), __VA_ARGS__)) - - - - - - - - - - \ - ((evtT_ *)QF_newX_((uint_fast16_t)sizeof(evtT_), \ - (margin_), (enum_t)(sig_))) - - - - - - - - - - - - \ - (evtT_##_init((evtT_ *)QF_newX_((uint_fast16_t)sizeof(evtT_), \ - (margin_), (sig_)), __VA_ARGS__)) - - - - - - - - \ - ((evtRef_) = (evtT_ const *)QF_newRef_(e, (evtRef_))) - - - - - - do { \ - QF_deleteRef_((evtRef_)); \ - (evtRef_) = (void *)0; \ -} while (false) - - - - - - - - - - \ - ((void)QActive_post_((me_), (e_), QF_NO_MARGIN, (sender_))) - - - - - - - - - - \ - ((void)QActive_post_((me_), (e_), QF_NO_MARGIN, (void *)0)) - - - - - - - - - - - - \ - (QActive_post_((me_), (e_), (margin_), (sender_))) - - - - - - - - - - - - \ - (QActive_post_((me_), (e_), (margin_), (void *)0)) - - - - - - - - \ - (QActive_postLIFO_((me_), (e_))) - - - - - - - - \ - (QActive_publish_((e_), (void const *)(sender_), (sender_)->prio)) - - - - - - - - (QActive_publish_((e_), (void *)0, 0U)) - - - - - - - - (QTimeEvt_tick_((tickRate_), (sender_))) - - - - - - - - (QTimeEvt_tick_((tickRate_), (void *)0)) - - - - - - QTIMEEVT_TICK_X(0U, (sender_)) - - - - - - - - (QTicker_trig_((ticker_), (sender_))) - - - - - - - - (QTicker_trig_((ticker_), (void *)0)) - - - - ((void)0) - - - - - - - - QTIMEEVT_TICK_X((tickRate_), (sender_)) - - - - - - QTIMEEVT_TICK(sender_) - - - - - - - - QACTIVE_PUBLISH((e_), (sender_)) - - - - ((void)0) - - - - ((void)0) - - - - - - - QMPool - - - - - - - - - - - - \ - (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) - - - - - - ((uint_fast16_t)(p_).blockSize) - - - - - - - - - - - - \ - ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qsId_))) - - - - - - - - - - \ - (QMPool_put(&(p_), (e_), (qsId_))) - - - - - - - //! @class QV - { - //! @cond INTERNAL - uint8_t dummy; - //! @endcond -} QV; - - - - - - //! @class QV_Attr - - - //! @memberof QV_Attr - - - - //! @memberof QV_Attr - - - - //! @memberof QV_Attr - - - - //! @memberof QV_Attr - - - - - //! @static @private @memberof QV - - - - //! @static @public @memberof QV - -//! @static @public @memberof QV - - - QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -Q_INVARIANT_INCRIT(102, QV_priv_.schedCeil - == (uint_fast8_t)(~QV_priv_.schedCeil_dis)); - -if (ceiling > QV_priv_.schedCeil) { // raising the scheduler ceiling? - - QS_BEGIN_PRE(QS_SCHED_LOCK, 0U) - QS_TIME_PRE(); // timestamp - // the previous sched ceiling & new sched ceiling - QS_2U8_PRE((uint8_t)QV_priv_.schedCeil, - (uint8_t)ceiling); - QS_END_PRE() - - QV_priv_.schedCeil = ceiling; -#ifndef Q_UNSAFE - QV_priv_.schedCeil_dis = (uint_fast8_t)(~ceiling); -#endif -} -QF_MEM_APP(); -QF_CRIT_EXIT(); - - - - //! @static @public @memberof QV - -//! @static @public @memberof QV - QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -Q_INVARIANT_INCRIT(202, QV_priv_.schedCeil - == (uint_fast8_t)(~QV_priv_.schedCeil_dis)); - -if (QV_priv_.schedCeil != 0U) { // actually enabling the scheduler? - - QS_BEGIN_PRE(QS_SCHED_UNLOCK, 0U) - QS_TIME_PRE(); // timestamp - // current sched ceiling (old), previous sched ceiling (new) - QS_2U8_PRE((uint8_t)QV_priv_.schedCeil, 0U); - QS_END_PRE() - - QV_priv_.schedCeil = 0U; -#ifndef Q_UNSAFE - QV_priv_.schedCeil_dis = (uint_fast8_t)(~0U); -#endif -} -QF_MEM_APP(); -QF_CRIT_EXIT(); - - - - //! @static @public @memberof QV - -//! @static @public @memberof QV - - - - - - - //! @static @public @memberof QF - -//! @static @public @memberof QF - QF_bzero_(&QF_priv_, sizeof(QF_priv_)); -QF_bzero_(&QV_priv_, sizeof(QV_priv_)); -QF_bzero_(&QActive_registry_[0], sizeof(QActive_registry_)); - -#ifndef Q_UNSAFE -QPSet_update_(&QV_priv_.readySet, &QV_priv_.readySet_dis); -QV_priv_.schedCeil_dis = (uint_fast8_t)(~0U); -#endif - -QTimeEvt_init(); // initialize QTimeEvts - -#ifdef QV_INIT -QV_INIT(); // port-specific initialization of the QV kernel -#endif - - - - //! @static @public @memberof QF - -//! @static @public @memberof QF - QF_onCleanup(); // application-specific cleanup callback -// nothing else to do for the QV kernel - - - - //! @static @public @memberof QF - -//! @static @public @memberof QF - #ifdef Q_SPY -// produce the QS_QF_RUN trace record -QF_INT_DISABLE(); -QF_MEM_SYS(); -QS_beginRec_((uint_fast8_t)QS_QF_RUN); -QS_endRec_(); -QF_MEM_APP(); -QF_INT_ENABLE(); -#endif // Q_SPY - -QF_onStartup(); // application-specific startup callback - -QF_INT_DISABLE(); -QF_MEM_SYS(); - -#ifdef QV_START -QV_START(); // port-specific startup of the QV kernel -#endif - -#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) -uint_fast8_t pprev = 0U; // previously used prio. - -#ifdef QF_ON_CONTEXT_SW -// officially switch to the idle cotext -QF_onContextSw((QActive *)0, (QActive *)0); -#endif // def QF_ON_CONTEXT_SW - -#endif // def (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) - -for (;;) { // QV event loop... - - // check internal integrity (duplicate inverse storage) - Q_INVARIANT_INCRIT(302, QPSet_verify_(&QV_priv_.readySet, - &QV_priv_.readySet_dis)); - // check internal integrity (duplicate inverse storage) - 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) - ? QPSet_findMax(&QV_priv_.readySet) - : 0U); - - if (p > QV_priv_.schedCeil) { // is it above the sched ceiling? - QActive * const a = QActive_registry_[p]; - -#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) - QS_BEGIN_PRE(QS_SCHED_NEXT, p) - QS_TIME_PRE(); // timestamp - QS_2U8_PRE((uint8_t)p, - (uint8_t)pprev); - QS_END_PRE() - -#ifdef QF_ON_CONTEXT_SW - QF_onContextSw(((pprev != 0U) - ? QActive_registry_[pprev] - : (QActive *)0), a); -#endif // QF_ON_CONTEXT_SW - - pprev = p; // update previous prio. -#endif // (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) - - QF_MEM_APP(); - QF_INT_ENABLE(); - - QEvt const * const e = QActive_get_(a); - // NOTE QActive_get_() performs QS_MEM_APP() before return - - // dispatch event (virtual call) - (*a->super.vptr->dispatch)(&a->super, e, p); -#if (QF_MAX_EPOOL > 0U) - QF_gc(e); -#endif - QF_INT_DISABLE(); - QF_MEM_SYS(); - - if (a->eQueue.frontEvt == (QEvt *)0) { // empty queue? - QPSet_remove(&QV_priv_.readySet, p); -#ifndef Q_UNSAFE - QPSet_update_(&QV_priv_.readySet, &QV_priv_.readySet_dis); -#endif - } - } - else { // no AO ready to run --> idle -#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) - if (pprev != 0U) { - QS_BEGIN_PRE(QS_SCHED_IDLE, pprev) - QS_TIME_PRE(); // timestamp - QS_U8_PRE((uint8_t)pprev); // previous prio - QS_END_PRE() - -#ifdef QF_ON_CONTEXT_SW - QF_onContextSw(QActive_registry_[pprev], (QActive *)0); -#endif // QF_ON_CONTEXT_SW - - pprev = 0U; // update previous prio. - } -#endif // (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) - - QF_MEM_APP(); - - // QV_onIdle() must be called with interrupts DISABLED because - // the determination of the idle condition can change at any time - // by an interrupt posting events to a queue. - // - // NOTE: QV_onIdle() MUST enable interrupts internally, ideally - // atomically with putting the CPU into a power-saving mode. - QV_onIdle(); - - QF_INT_DISABLE(); // disable interrupts before looping back - QF_MEM_SYS(); - } -} -#ifdef __GNUC__ // GNU compiler? -return 0; -#endif - - - - - //! QActive active object class customization for QV - - - //! @public @memberof QActive - -//! @public @memberof QActive - - - - - - - - - - - - - Q_UNUSED_PAR(stkSto); // not needed in QV -Q_UNUSED_PAR(stkSize); // not needed in QV - -QF_CRIT_STAT -QF_CRIT_ENTRY(); -Q_REQUIRE_INCRIT(300, stkSto == (void *)0); -QF_CRIT_EXIT(); - -me->prio = (uint8_t)(prioSpec & 0xFFU); // QF-prio. of the AO -me->pthre = 0U; // not used -QActive_register_(me); // make QF aware of this active object - -QEQueue_init(&me->eQueue, qSto, qLen); // init the built-in queue - -// top-most initial tran. (virtual call) -(*me->super.vptr->init)(&me->super, par, me->prio); -QS_FLUSH(); // flush the trace buffer to the host - - - - - - - - - - - - ((void)0) - - - - ((void)0) - - - - - - ((void)0) - - - - - - \ - QPSet_insert(&QV_priv_.readySet, (uint_fast8_t)(me_)->prio); \ - QPSet_update_(&QV_priv_.readySet, &QV_priv_.readySet_dis) - - - - - - \ - QPSet_insert(&QV_priv_.readySet, (uint_fast8_t)(me_)->prio) - - - - - - - //! @class QK - { - //! @cond INTERNAL - uint8_t dummy; - //! @endcond -} QK; - - - - - - - - //! @class QK_Attr - - - //! @memberof QK_Attr - - - - //! @memberof QK_Attr - - - - //! @memberof QK_Attr - - - - //! @memberof QK_Attr - - - - //! @memberof QK_Attr - - - - //! @memberof QK_Attr - - - - //! @memberof QK_Attr - - - - //! @memberof QK_Attr - - - - //! @memberof QK_Attr - - - - //! @memberof QK_Attr - - - - //! @memberof QK_Attr - - - - - //! @static @private @memberof QK - - - - //! @static @public @memberof QK - -//! @static @public @memberof QK - - - QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -Q_REQUIRE_INCRIT(100, !QK_ISR_CONTEXT_()); -Q_INVARIANT_INCRIT(102, QK_priv_.lockCeil - == (uint_fast8_t)(~QK_priv_.lockCeil_dis)); - -// first store the previous lock prio -QSchedStatus stat; -if (ceiling > QK_priv_.lockCeil) { // raising the lock ceiling? - QS_BEGIN_PRE(QS_SCHED_LOCK, QK_priv_.actPrio) - QS_TIME_PRE(); // timestamp - // the previous lock ceiling & new lock ceiling - QS_2U8_PRE((uint8_t)QK_priv_.lockCeil, (uint8_t)ceiling); - QS_END_PRE() - - // previous status of the lock - stat = (QSchedStatus)QK_priv_.lockCeil; - - // new status of the lock - QK_priv_.lockCeil = ceiling; -#ifndef Q_UNSAFE - QK_priv_.lockCeil_dis = (uint_fast8_t)(~ceiling); -#endif -} -else { - stat = 0xFFU; // scheduler not locked -} - -QF_MEM_APP(); -QF_CRIT_EXIT(); - -return stat; // return the status to be saved in a stack variable - - - - //! @static @public @memberof QK - -//! @static @public @memberof QK - - - // has the scheduler been actually locked by the last QK_schedLock()? -if (prevCeil != 0xFFU) { - QF_CRIT_STAT - QF_CRIT_ENTRY(); - QF_MEM_SYS(); - - 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)); - - QS_BEGIN_PRE(QS_SCHED_UNLOCK, QK_priv_.actPrio) - QS_TIME_PRE(); // timestamp - // current lock ceiling (old), previous lock ceiling (new) - QS_2U8_PRE((uint8_t)QK_priv_.lockCeil, (uint8_t)prevCeil); - QS_END_PRE() - - // restore the previous lock ceiling - QK_priv_.lockCeil = prevCeil; -#ifndef Q_UNSAFE - QK_priv_.lockCeil_dis = (uint_fast8_t)(~prevCeil); -#endif - - // find if any AOs should be run after unlocking the scheduler - if (QK_sched_() != 0U) { // preemption needed? - QK_activate_(); // activate any unlocked AOs - } - - QF_MEM_APP(); - QF_CRIT_EXIT(); -} - - - - //! @static @public @memberof QK - -//! @static @public @memberof QK - - - - //! @static @private @memberof QK - -//! @static @private @memberof QK - // NOTE: this function is entered with interrupts DISABLED - -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 -} -else { - // find the highest-prio AO with non-empty event queue - p = QPSet_findMax(&QK_priv_.readySet); - - Q_INVARIANT_INCRIT(412, - QK_priv_.actThre == (uint_fast8_t)(~QK_priv_.actThre_dis)); - - // is the AO's prio. below the active preemption-threshold? - if (p <= QK_priv_.actThre) { - p = 0U; // no activation needed - } - else { - 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_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); -#endif - } - } -} - -return p; - - - - //! @static @private @memberof QK - -//! @static @private @memberof QK - // NOTE: this function is entered with interrupts DISABLED - -uint_fast8_t const prio_in = QK_priv_.actPrio; // save initial prio. -uint_fast8_t p = QK_priv_.nextPrio; // next prio to run - -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) - && (0U < p) && (p <= QF_MAX_ACTIVE)); - -#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) -uint_fast8_t pprev = prio_in; -#endif // QF_ON_CONTEXT_SW || Q_SPY - -QK_priv_.nextPrio = 0U; // clear for the next time -#ifndef Q_UNSAFE -QK_priv_.nextPrio_dis = (uint_fast8_t)(~0U); -#endif - -uint_fast8_t pthre_in; -QActive *a; -if (prio_in == 0U) { // preempting the idle thread? - pthre_in = 0U; -} -else { - a = QActive_registry_[prio_in]; - Q_ASSERT_INCRIT(510, a != (QActive *)0); - - pthre_in = (uint_fast8_t)a->pthre; - Q_INVARIANT_INCRIT(511, pthre_in == - (uint_fast8_t)(~(uint_fast8_t)a->pthre_dis & 0xFFU)); -} - -// loop until no more ready-to-run AOs of higher pthre than the initial -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_INVARIANT_INCRIT(522, pthre == - (uint_fast8_t)(~(uint_fast8_t)a->pthre_dis & 0xFFU)); - - // set new active prio. and preemption-threshold - QK_priv_.actPrio = p; - QK_priv_.actThre = pthre; -#ifndef Q_UNSAFE - QK_priv_.actPrio_dis = (uint_fast8_t)(~p); - QK_priv_.actThre_dis = (uint_fast8_t)(~pthre); -#endif - -#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) - if (p != pprev) { // changing threads? - - QS_BEGIN_PRE(QS_SCHED_NEXT, p) - QS_TIME_PRE(); // timestamp - QS_2U8_PRE(p, // prio. of the scheduled AO - pprev); // previous prio. - QS_END_PRE() - -#ifdef QF_ON_CONTEXT_SW - QF_onContextSw(QActive_registry_[pprev], a); -#endif // QF_ON_CONTEXT_SW - - pprev = p; // update previous prio. - } -#endif // QF_ON_CONTEXT_SW || Q_SPY - - QF_MEM_APP(); - QF_INT_ENABLE(); // unconditionally enable interrupts - - QEvt const * const e = QActive_get_(a); - // NOTE QActive_get_() performs QF_MEM_APP() before return - - // dispatch event (virtual call) - (*a->super.vptr->dispatch)(&a->super, e, p); -#if (QF_MAX_EPOOL > 0U) - QF_gc(e); -#endif - - // determine the next highest-prio. AO ready to run... - QF_INT_DISABLE(); // unconditionally disable interrupts - QF_MEM_SYS(); - - // internal integrity check (duplicate inverse storage) - 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); -#ifndef Q_UNSAFE - QPSet_update_(&QK_priv_.readySet, &QK_priv_.readySet_dis); -#endif - } - - if (QPSet_isEmpty(&QK_priv_.readySet)) { - p = 0U; // no activation needed - } - else { - // find new highest-prio AO ready to run... - p = QPSet_findMax(&QK_priv_.readySet); - - // is the new prio. below the initial preemption-threshold? - if (p <= pthre_in) { - p = 0U; // no activation needed - } - else { - 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) { - p = 0U; // no activation needed - } - else { - Q_ASSERT_INCRIT(550, p <= QF_MAX_ACTIVE); - } - } - } -} while (p != 0U); - -// restore the active prio. and preemption-threshold -QK_priv_.actPrio = prio_in; -QK_priv_.actThre = pthre_in; -#ifndef Q_UNSAFE -QK_priv_.actPrio_dis = (uint_fast8_t)(~QK_priv_.actPrio); -QK_priv_.actThre_dis = (uint_fast8_t)(~QK_priv_.actThre); -#endif - -#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) -if (prio_in != 0U) { // resuming an active object? - a = QActive_registry_[prio_in]; // pointer to preempted AO - - QS_BEGIN_PRE(QS_SCHED_NEXT, prio_in) - QS_TIME_PRE(); // timestamp - // prio. of the resumed AO, previous prio. - QS_2U8_PRE(prio_in, pprev); - QS_END_PRE() -} -else { // resuming prio.==0 --> idle - a = (QActive *)0; // QK idle loop - - QS_BEGIN_PRE(QS_SCHED_IDLE, pprev) - QS_TIME_PRE(); // timestamp - QS_U8_PRE(pprev); // previous prio. - QS_END_PRE() -} - -#ifdef QF_ON_CONTEXT_SW -QF_onContextSw(QActive_registry_[pprev], a); -#endif // QF_ON_CONTEXT_SW - -#endif // QF_ON_CONTEXT_SW || Q_SPY - - - - - - - //! @static @public @memberof QF - -//! @static @public @memberof QF - QF_bzero_(&QF_priv_, sizeof(QF_priv_)); -QF_bzero_(&QK_priv_, sizeof(QK_priv_)); -QF_bzero_(&QActive_registry_[0], sizeof(QActive_registry_)); - -// setup the QK scheduler as initially locked and not running -QK_priv_.lockCeil = (QF_MAX_ACTIVE + 1U); // scheduler locked - -#ifndef Q_UNSAFE -QPSet_update_(&QK_priv_.readySet, &QK_priv_.readySet_dis); -QK_priv_.actPrio_dis = (uint_fast8_t)(~0U); -QK_priv_.nextPrio_dis = (uint_fast8_t)(~0U); -QK_priv_.actThre_dis = (uint_fast8_t)(~0U); -QK_priv_.lockCeil_dis = (uint_fast8_t)(~QK_priv_.lockCeil); -#endif - -QTimeEvt_init(); // initialize QTimeEvts - -#ifdef QK_INIT -QK_INIT(); // port-specific initialization of the QK kernel -#endif - - - - //! @static @public @memberof QF - -//! @static @public @memberof QF - QF_onCleanup(); // application-specific cleanup callback -// nothing else to do for the preemptive QK kernel - - - - //! @static @public @memberof QF - -//! @static @public @memberof QF - #ifdef Q_SPY -// produce the QS_QF_RUN trace record -QF_INT_DISABLE(); -QF_MEM_SYS(); -QS_beginRec_((uint_fast8_t)QS_QF_RUN); -QS_endRec_(); -QF_MEM_APP(); -QF_INT_ENABLE(); -#endif // Q_SPY - -QF_onStartup(); // application-specific startup callback - -QF_INT_DISABLE(); -QF_MEM_SYS(); - -#ifdef QK_START -QK_START(); // port-specific startup of the QK kernel -#endif - -QK_priv_.lockCeil = 0U; // unlock the QK scheduler -#ifndef Q_UNSAFE -QK_priv_.lockCeil_dis = (uint_fast8_t)(~0U); -#endif - -#ifdef QF_ON_CONTEXT_SW -// officially switch to the idle context -QF_onContextSw((QActive *)0, QActive_registry_[QK_priv_.nextPrio]); -#endif - -// activate AOs to process events posted so far -if (QK_sched_() != 0U) { - QK_activate_(); -} - -QF_MEM_APP(); -QF_INT_ENABLE(); - -for (;;) { // QK idle loop... - QK_onIdle(); // application-specific QK on-idle callback -} - -#ifdef __GNUC__ -return 0; -#endif - - - - - // QActive class customization for QK - - - //! @public @memberof QActive - -//! @public @memberof QActive - - - - - - - - - - - - - Q_UNUSED_PAR(stkSto); // not needed in QK -Q_UNUSED_PAR(stkSize); // not needed in QK - -QF_CRIT_STAT -QF_CRIT_ENTRY(); -QF_MEM_SYS(); - -Q_REQUIRE_INCRIT(300, (!QK_ISR_CONTEXT_()) - && (stkSto == (void *)0)); -QF_MEM_APP(); -QF_CRIT_EXIT(); - -me->prio = (uint8_t)(prioSpec & 0xFFU); // QF-prio. of the AO -me->pthre = (uint8_t)(prioSpec >> 8U); // preemption-threshold -QActive_register_(me); // make QF aware of this active object - -QEQueue_init(&me->eQueue, qSto, qLen); // init the built-in queue - -// top-most initial tran. (virtual call) -(*me->super.vptr->init)(&me->super, par, me->prio); -QS_FLUSH(); // flush the trace buffer to the host - -// See if this AO needs to be scheduled if QK is already running -QF_CRIT_ENTRY(); -QF_MEM_SYS(); -if (QK_sched_() != 0U) { // activation needed? - QK_activate_(); -} -QF_MEM_APP(); -QF_CRIT_EXIT(); - - - - - - - - QSchedStatus lockStat_; - - - - - - do { \ - if (QK_ISR_CONTEXT_()) { \ - lockStat_ = 0xFFU; \ - } else { \ - lockStat_ = QK_schedLock((ceil_)); \ - } \ -} while (false) - - - - do { \ - if (lockStat_ != 0xFFU) { \ - QK_schedUnlock(lockStat_); \ - } \ -} while (false) - - - - - - ((void)0) - - - - - - do { \ - QPSet_insert(&QK_priv_.readySet, (uint_fast8_t)(me_)->prio); \ - QPSet_update_(&QK_priv_.readySet, &QK_priv_.readySet_dis); \ - if (!QK_ISR_CONTEXT_()) { \ - if (QK_sched_() != 0U) { \ - QK_activate_(); \ - } \ - } \ -} while (false) - - - - - - do { \ - QPSet_insert(&QK_priv_.readySet, (uint_fast8_t)(me_)->prio); \ - if (!QK_ISR_CONTEXT_()) { \ - if (QK_sched_() != 0U) { \ - QK_activate_(); \ - } \ - } \ -} while (false) - - - - - - - #ifndef QSAFE_H_ -#define QSAFE_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -// QF-FuSa enabled =========================================================== -#ifndef Q_UNSAFE - -#ifndef QF_CRIT_STAT -#define QF_CRIT_STAT -#endif - -#ifndef QF_CRIT_ENTRY -#define QF_CRIT_ENTRY() ((void)0) -#endif - -#ifndef QF_CRIT_EXIT -#define QF_CRIT_EXIT() ((void)0) -#endif - -$declare ${QP-FuSa::enabled} - -// QF-FuSa disabled ========================================================== -#else -$declare ${QP-FuSa::disabled} -#endif - -//============================================================================ -$declare1 ${QP-FuSa} - -#ifdef __cplusplus -} -#endif - -#endif // QSAFE_H_ - - - - #ifndef QP_H_ -#define QP_H_ - -//============================================================================ -#define QP_VERSION_STR "8.0.1" -#define QP_VERSION 801U -#define QP_RELEASE 0x703931CEU - -//============================================================================ -//! @cond INTERNAL - -#ifndef Q_SIGNAL_SIZE -#define Q_SIGNAL_SIZE 2U -#endif - -#ifndef QF_MAX_ACTIVE -#define QF_MAX_ACTIVE 32U -#endif - -#if (QF_MAX_ACTIVE > 64U) -#error QF_MAX_ACTIVE exceeds the maximum of 64U; -#endif - -#ifndef QF_MAX_TICK_RATE -#define QF_MAX_TICK_RATE 1U -#endif - -#if (QF_MAX_TICK_RATE > 15U) -#error QF_MAX_TICK_RATE exceeds the maximum of 15U; -#endif - -#ifndef QF_MAX_EPOOL -#define QF_MAX_EPOOL 3U -#endif - -#if (QF_MAX_EPOOL > 15U) -#error QF_MAX_EPOOL exceeds the maximum of 15U; -#endif - -#ifndef QF_TIMEEVT_CTR_SIZE -#define QF_TIMEEVT_CTR_SIZE 4U -#endif - -#if (QF_TIMEEVT_CTR_SIZE > 4U) -#error QF_TIMEEVT_CTR_SIZE defined incorrectly, expected 1U, 2U, or 4U; -#endif - -#ifndef QF_EVENT_SIZ_SIZE -#define QF_EVENT_SIZ_SIZE 2U -#endif - -#if (QF_EVENT_SIZ_SIZE > 4U) -#error QF_EVENT_SIZ_SIZE defined incorrectly, expected 1U, 2U, or 4U; -#endif - -//! @endcond -//============================================================================ - -$declare ${glob-types} - -$declare ${QEP} - -$declare ${QEP-macros} - -$declare ${QF::types} - -$declare ${QF::QActive} - -$declare ${QF::QMActive} - -$declare ${QF::QTimeEvt} - -$declare ${QF::QTicker} - -$declare ${QF::QF-base} - -$declare ${QF::QF-dyn} - -$declare ${QF-macros} - -#endif // QP_H_ - - - - #ifndef QP_PKG_H_ -#define QP_PKG_H_ - -$declare ${QF::QF-pkg} - -// Bitmasks are for the QTimeEvt::flags attribute -#define QTE_FLAG_IS_LINKED (1U << 7U) -#define QTE_FLAG_WAS_DISARMED (1U << 6U) - -//! @private @memberof QEvt -static inline void QEvt_refCtr_inc_(QEvt const *me) { - uint8_t rc = me->refCtr_ + 1U; - ((QEvt *)me)->refCtr_ = rc; // cast away 'const' -#ifndef Q_UNSAFE - ((QEvt *)me)->evtTag_ = (me->evtTag_ & 0xF0U) | ((~rc) & 0x0FU); -#endif // ndef Q_UNSAFE -} - -//! @private @memberof QEvt -static inline void QEvt_refCtr_dec_(QEvt const *me) { - uint8_t rc = me->refCtr_ - 1U; - ((QEvt *)me)->refCtr_ = rc; // cast away 'const' -#ifndef Q_UNSAFE - ((QEvt *)me)->evtTag_ = (me->evtTag_ & 0xF0U) | ((~rc) & 0x0FU); -#endif // ndef Q_UNSAFE -} - -#define QACTIVE_CAST_(ptr_) ((QActive *)(ptr_)) -#define Q_PTR2UINT_CAST_(ptr_) ((uintptr_t)(ptr_)) - -#endif // QP_PKG_H_ - - - - #ifndef QEQUEUE_H_ -#define QEQUEUE_H_ - -#ifndef QF_EQUEUE_CTR_SIZE - #define QF_EQUEUE_CTR_SIZE 1U -#endif - -#if (QF_EQUEUE_CTR_SIZE == 1U) - typedef uint8_t QEQueueCtr; -#elif (QF_EQUEUE_CTR_SIZE == 2U) - typedef uint16_t QEQueueCtr; -#else - #error "QF_EQUEUE_CTR_SIZE defined incorrectly, expected 1U or 2U" -#endif - -struct QEvt; // forward declartion - -$declare ${QF::QEQueue} - -#endif // QEQUEUE_H_ - - - - #ifndef QMPOOL_H_ -#define QMPOOL_H_ - -#ifndef QF_MPOOL_SIZ_SIZE - #define QF_MPOOL_SIZ_SIZE 2U -#endif -#ifndef QF_MPOOL_CTR_SIZE - #define QF_MPOOL_CTR_SIZE 2U -#endif - -#if (QF_MPOOL_SIZ_SIZE == 1U) - typedef uint8_t QMPoolSize; -#elif (QF_MPOOL_SIZ_SIZE == 2U) - typedef uint16_t QMPoolSize; -#elif (QF_MPOOL_SIZ_SIZE == 4U) - typedef uint32_t QMPoolSize; -#else - #error "QF_MPOOL_SIZ_SIZE defined incorrectly, expected 1U, 2U, or 4U" -#endif - -#if (QF_MPOOL_CTR_SIZE == 1U) - typedef uint8_t QMPoolCtr; -#elif (QF_MPOOL_CTR_SIZE == 2U) - typedef uint16_t QMPoolCtr; -#elif (QF_MPOOL_CTR_SIZE == 4U) - typedef uint32_t QMPoolCtr; -#else - #error "QF_MPOOL_CTR_SIZE defined incorrectly, expected 1U, 2U, or 4U" -#endif - -#define QF_MPOOL_EL(evType_) struct { \ - QFreeBlock sto_[((sizeof(evType_) - 1U) / (2U * sizeof(void *))) + 1U]; \ -} - -$declare ${QF::QFreeBlock} - -$declare ${QF::QMPool} - -#endif // QMPOOL_H_ - - - - #ifndef QV_H_ -#define QV_H_ - -$declare ${QV::QV} - -$declare ${QV::QV-base} - -//============================================================================ -// interface used only for internal implementation, but not in applications -#ifdef QP_IMPL - -$declare ${QV-impl} - -$declare ${QF_EPOOL-impl} - -#endif // QP_IMPL - -#endif // QV_H_ - - - - #ifndef QK_H_ -#define QK_H_ - -$declare ${QK::QK} - -$declare ${QK::QSchedStatus} - -$declare ${QK::QK-base} - -//============================================================================ -// interface used only for internal implementation, but not in applications -#ifdef QP_IMPL - -$declare ${QK-impl} - -$declare ${QF_EPOOL-impl} - -#endif // QP_IMPL - -#endif // QK_H_ - - - - #ifndef QSTAMP_H_ -#define QSTAMP_H_ - -extern char const Q_BUILD_DATE[12]; -extern char const Q_BUILD_TIME[9]; - -#endif // QSTAMP_H_ - - - - #ifndef QPC_H_ -#define QPC_H_ - -#include "qp_port.h" // QP port from the port directory -#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem -#ifdef Q_SPY // software tracing enabled? - #include "qs_port.h" // QS/C port from the port directory -#else - #include "qs_dummy.h" // QS/C dummy interface (inactive) -#endif - -#ifndef QP_API_VERSION - #define QP_API_VERSION 0 -#endif // #ifndef QP_API_VERSION - -// QP API compatibility layer... -//============================================================================ -#if (QP_API_VERSION < 800) - -#define QM_SUPER_SUB(host_) error "submachines no longer supported" -#define QM_TRAN_EP(tatbl_) error "submachines no longer supported" -#define QM_TRAN_XP(xp_, tatbl_) error "submachines no longer supported" - -#ifdef QEVT_DYN_CTOR -//! @deprecated #QEVT_DYN_CTOR, please use #QEVT_PAR_INIT -#define QEVT_PAR_INIT -#endif - -//! @deprecated plain 'char' is no longer forbidden in MISRA-C:2023 -typedef char char_t; - -//! @deprecated Macro for starting an Active Object. -//! Use QActive::QActive_start() instead. -#define QACTIVE_START(me_, prioSpec_, qSto_, qLen_, stkSto_, stkSize_, par_) \ - (QActive_start((QActive *)(me_), (prioSpec_), \ - (qSto_), (qLen_), (stkSto_), (stkSize_), (par_))) - -//! @deprecated Macro for starting an eXtended Thread. -//! Use QXThread::QXThread_start() instead. -#define QXTHREAD_START(me_, prioSpec_, qSto_, qLen_, stkSto_, stkSize_, par_) \ - (QXThread_start((QXThread *)(me_), (prioSpec_), \ - (qSto_), (qLen_), (stkSto_), (stkSize_), (par_))) - -//! @deprecated Assertion failure handler. -//! Use Q_onError() instead. -#define Q_onAssert(module_, id_) Q_onError(module_, id_) - -//! @deprecated #Q_NASSERT preprocessor switch to disable QP assertions -#ifdef Q_NASSERT - - // #Q_UNSAFE now replaces the functionality of Q_NASSERT - #define Q_UNSAFE - - //! @deprecated general purpose assertion with user-specified ID - //! number that **always** evaluates the `expr_` expression. - #define Q_ALLEGE_ID(id_, expr_) ((void)(expr_)) - -#elif defined Q_UNSAFE - - //! @deprecated general purpose assertion with user-specified ID - //! number that **always** evaluates the `expr_` expression. - #define Q_ALLEGE_ID(id_, expr_) ((void)(expr_)) - -#else // QP FuSa Subsystem enabled - - //! @deprecated general purpose assertion with user-specified ID - //! number that **always** evaluates the `expr_` expression. - //! @note - //! The use of this macro is no longer recommended. - #define Q_ALLEGE_ID(id_, expr_) if (!(expr_)) { \ - QF_CRIT_STAT \ - QF_CRIT_ENTRY(); \ - Q_onError(&Q_this_module_[0], (id_)); \ - QF_CRIT_EXIT(); \ - } else ((void)0) - -#endif - -//! @deprecated general purpose assertion without ID number -//! that **always** evaluates the `expr_` expression. -//! Instead of ID number, this macro is based on the standard -//! `__LINE__` macro. -//! -//! @note The use of this macro is no longer recommended. -#define Q_ALLEGE(expr_) Q_ALLEGE_ID(__LINE__, (expr_)) - -//! Static (compile-time) assertion. -//! @deprecated -//! Use Q_ASSERT_STATIC() or better yet `_Static_assert()` instead. -#define Q_ASSERT_COMPILE(expr_) Q_ASSERT_STATIC(expr_) - -//! @static @public @memberof QF -//! @deprecated -static inline void QF_psInit( - QSubscrList * const subscrSto, - enum_t const maxSignal) -{ - QActive_psInit(subscrSto, maxSignal); -} - -//! @deprecated instead use: QASM_INIT() -#define QHSM_INIT(me_, par_, qsId_) QASM_INIT((me_), (par_), (qsId_)) - -//! @deprecated instead use: QASM_DISPATCH() -#define QHSM_DISPATCH(me_, e_, qsId_) QASM_DISPATCH((me_), (e_), (qsId_)) - -//! @deprecated instead use: QASM_IS_IN() -#define QHsm_isIn(me_, state_) QASM_IS_IN((QAsm *)(me_), (state_)) - -#endif // QP_API_VERSION < 800 - -#endif // QPC_H_ - - - - - - - - - #define QP_IMPL // this is QP implementation -#include "qp_port.h" // QP port -#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem -#ifdef Q_SPY // QS software tracing enabled? - #include "qs_port.h" // QS port - #include "qs_pkg.h" // QS facilities for pre-defined trace records -#else - #include "qs_dummy.h" // disable the QS software tracing -#endif // Q_SPY - -Q_DEFINE_THIS_MODULE("qep_hsm") - -$define ${QEP::QP_versionStr[16]} - -//============================================================================ -//! @cond INTERNAL - -$define ${QEP::QEvt::reserved_[4]} - -// helper macro to handle reserved event in an QHsm -#define QHSM_RESERVED_EVT_(state_, sig_) \ - ((*(state_))(me, &QEvt_reserved_[(sig_)])) - -// helper macro to trace state entry -#define QS_STATE_ENTRY_(state_, qsId_) \ - QS_CRIT_ENTRY(); \ - QS_MEM_SYS(); \ - QS_BEGIN_PRE(QS_QEP_STATE_ENTRY, (qsId_)) \ - QS_OBJ_PRE(me); \ - QS_FUN_PRE(state_); \ - QS_END_PRE() \ - QS_MEM_APP(); \ - QS_CRIT_EXIT() - -// helper macro to trace state exit -#define QS_STATE_EXIT_(state_, qsId_) \ - QS_CRIT_ENTRY(); \ - QS_MEM_SYS(); \ - QS_BEGIN_PRE(QS_QEP_STATE_EXIT, (qsId_)) \ - QS_OBJ_PRE(me); \ - QS_FUN_PRE(state_); \ - QS_END_PRE() \ - QS_MEM_APP(); \ - QS_CRIT_EXIT() - -//! @endcond - -enum { - // maximum depth of state nesting in a QHsm (including the top level), - // must be >= 3 - QHSM_MAX_NEST_DEPTH_ = 6 -}; - -$define ${QEP::QHsm} - - - - #define QP_IMPL // this is QP implementation -#include "qp_port.h" // QP port -#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem -#ifdef Q_SPY // QS software tracing enabled? - #include "qs_port.h" // QS port - #include "qs_pkg.h" // QS facilities for pre-defined trace records -#else - #include "qs_dummy.h" // disable the QS software tracing -#endif // Q_SPY - -//============================================================================ -//! @cond INTERNAL - -Q_DEFINE_THIS_MODULE("qep_msm") - -// top-state object for QMsm-style state machines -static struct QMState const l_msm_top_s = { - (struct QMState *)0, - Q_STATE_CAST(0), - Q_ACTION_CAST(0), - Q_ACTION_CAST(0), - Q_ACTION_CAST(0) -}; -//! @endcond - -enum { - // maximum depth of state nesting in a QMsm (including the top level) - QMSM_MAX_NEST_DEPTH_ = 8, - - // maximum length of transition-action array - QMSM_MAX_TRAN_LENGTH_ = 2*QMSM_MAX_NEST_DEPTH_, - - // maximum depth of entry levels in a MSM for tran. to history - QMSM_MAX_ENTRY_DEPTH_ = 4 -}; - -//============================================================================ - -$define ${QEP::QMsm} - - - - #define QP_IMPL // this is QP implementation -#include "qp_port.h" // QP port -#include "qp_pkg.h" // QP package-scope interface -#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem -#ifdef Q_SPY // QS software tracing enabled? - #include "qs_port.h" // QS port - #include "qs_pkg.h" // QS facilities for pre-defined trace records -#else - #include "qs_dummy.h" // disable the QS software tracing -#endif // Q_SPY - -//Q_DEFINE_THIS_MODULE("qf_act") - -$define ${QF::QActive::registry_[QF_MAX_ACTIVE + 1U]} - -$define ${QF::QF-pkg} - -$define ${QF::types::QF_LOG2} - - - - #define QP_IMPL // this is QP implementation -#include "qp_port.h" // QP port -#include "qp_pkg.h" // QP package-scope interface -#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem -#ifdef Q_SPY // QS software tracing enabled? - #include "qs_port.h" // QS port - #include "qs_pkg.h" // QS facilities for pre-defined trace records -#else - #include "qs_dummy.h" // disable the QS software tracing -#endif // Q_SPY - -Q_DEFINE_THIS_MODULE("qf_actq") - -//============================================================================ -$define ${QF::QActive::post_} -$define ${QF::QActive::postLIFO_} -$define ${QF::QActive::get_} - -$define ${QF::QF-base::getQueueMin} -$define ${QF::QTicker} - - - - #define QP_IMPL // this is QP implementation -#include "qp_port.h" // QP port -#include "qp_pkg.h" // QP package-scope interface -#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem -#ifdef Q_SPY // QS software tracing enabled? - #include "qs_port.h" // QS port - #include "qs_pkg.h" // QS facilities for pre-defined trace records -#else - #include "qs_dummy.h" // disable the QS software tracing -#endif // Q_SPY - -Q_DEFINE_THIS_MODULE("qf_defer") - -$define ${QF::QActive::defer} -$define ${QF::QActive::recall} -$define ${QF::QActive::flushDeferred} - - - - #define QP_IMPL // this is QP implementation -#include "qp_port.h" // QP port -#include "qp_pkg.h" // QP package-scope interface -#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem -#ifdef Q_SPY // QS software tracing enabled? - #include "qs_port.h" // QS port - #include "qs_pkg.h" // QS facilities for pre-defined trace records -#else - #include "qs_dummy.h" // disable the QS software tracing -#endif // Q_SPY - -#if (QF_MAX_EPOOL > 0U) // mutable events configured? - -Q_DEFINE_THIS_MODULE("qf_dyn") - -$define ${QF::QF-dyn} - -#endif // (QF_MAX_EPOOL > 0U) mutable events configured - - - - #define QP_IMPL // this is QP implementation -#include "qp_port.h" // QP port -#include "qp_pkg.h" // QP package-scope interface -#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem -#ifdef Q_SPY // QS software tracing enabled? - #include "qs_port.h" // QS port - #include "qs_pkg.h" // QS facilities for pre-defined trace records -#else - #include "qs_dummy.h" // disable the QS software tracing -#endif // Q_SPY - -Q_DEFINE_THIS_MODULE("qf_mem") - -$define ${QF::QMPool} - - - - #define QP_IMPL // this is QP implementation -#include "qp_port.h" // QP port -#include "qp_pkg.h" // QP package-scope interface -#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem -#ifdef Q_SPY // QS software tracing enabled? - #include "qs_port.h" // QS port - #include "qs_pkg.h" // QS facilities for pre-defined trace records -#else - #include "qs_dummy.h" // disable the QS software tracing -#endif // Q_SPY - -Q_DEFINE_THIS_MODULE("qf_qact") - -$define ${QF::QActive::ctor} - -$define ${QF::QActive::register_} - -$define ${QF::QActive::unregister_} - - - - #define QP_IMPL // this is QP implementation -#include "qp_port.h" // QP port -#include "qp_pkg.h" // QP package-scope interface -#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem -#ifdef Q_SPY // QS software tracing enabled? - #include "qs_port.h" // QS port - #include "qs_pkg.h" // QS facilities for pre-defined trace records -#else - #include "qs_dummy.h" // disable the QS software tracing -#endif // Q_SPY - -//Q_DEFINE_THIS_MODULE("qf_qmact") - -$define ${QF::QMActive} - - - - #define QP_IMPL // this is QP implementation -#include "qp_port.h" // QP port -#include "qp_pkg.h" // QP package-scope interface -#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem -#ifdef Q_SPY // QS software tracing enabled? - #include "qs_port.h" // QS port - #include "qs_pkg.h" // QS facilities for pre-defined trace records -#else - #include "qs_dummy.h" // disable the QS software tracing -#endif // Q_SPY - -Q_DEFINE_THIS_MODULE("qf_qeq") - -$define ${QF::QEQueue} - - - - #define QP_IMPL // this is QP implementation -#include "qp_port.h" // QP port -#include "qp_pkg.h" // QP package-scope interface -#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem -#ifdef Q_SPY // QS software tracing enabled? - #include "qs_port.h" // QS port - #include "qs_pkg.h" // QS facilities for pre-defined trace records -#else - #include "qs_dummy.h" // disable the QS software tracing -#endif // Q_SPY - -Q_DEFINE_THIS_MODULE("qf_ps") - -$define ${QF::QActive::subscrList_} - -$define ${QF::QActive::maxPubSignal_} - -$define ${QF::QActive::psInit} - -$define ${QF::QActive::publish_} - -$define ${QF::QActive::subscribe} - -$define ${QF::QActive::unsubscribe} - -$define ${QF::QActive::unsubscribeAll} - - - - #define QP_IMPL // this is QP implementation -#include "qp_port.h" // QP port -#include "qp_pkg.h" // QP package-scope interface -#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem -#ifdef Q_SPY // QS software tracing enabled? - #include "qs_port.h" // QS port - #include "qs_pkg.h" // QS facilities for pre-defined trace records -#else - #include "qs_dummy.h" // disable the QS software tracing -#endif // Q_SPY - -Q_DEFINE_THIS_MODULE("qf_time") - -$define ${QF::QTimeEvt} - - - - - - - #define QP_IMPL // this is QP implementation -#include "qp_port.h" // QP port -#include "qp_pkg.h" // QP package-scope internal interface -#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem -#ifdef Q_SPY // QS software tracing enabled? - #include "qs_port.h" // QS port - #include "qs_pkg.h" // QS facilities for pre-defined trace records -#else - #include "qs_dummy.h" // disable the QS software tracing -#endif // Q_SPY - -// protection against including this source file in a wrong project -#ifndef QV_H_ - #error "Source file included in a project NOT based on the QV kernel" -#endif // QV_H_ - -Q_DEFINE_THIS_MODULE("qv") - -$define ${QV::QV-base} - -$define ${QV::QF-cust} - -$define ${QV::QActive} - - - - - - - #define QP_IMPL // this is QP implementation -#include "qp_port.h" // QP port -#include "qp_pkg.h" // QP package-scope internal interface -#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem -#ifdef Q_SPY // QS software tracing enabled? - #include "qs_port.h" // QS port - #include "qs_pkg.h" // QS facilities for pre-defined trace records -#else - #include "qs_dummy.h" // disable the QS software tracing -#endif // Q_SPY - -// protection against including this source file in a wrong project -#ifndef QK_H_ - #error "Source file included in a project NOT based on the QK kernel" -#endif // QK_H_ - -Q_DEFINE_THIS_MODULE("qk") - -$define ${QK::QK-base} - -$define ${QK::QF-cust} - -$define ${QK::QActive} - - - - - - - #include "qstamp.h" - -char const Q_BUILD_DATE[12] = __DATE__; -char const Q_BUILD_TIME[9] = __TIME__; - - - - diff --git a/qpc_8.0.1.sha1 b/qpc_8.0.1.sha1 deleted file mode 100644 index 3044d24d5..000000000 --- a/qpc_8.0.1.sha1 +++ /dev/null @@ -1,161 +0,0 @@ -e0aae515ebf157d8993bb03747fdc86cd87604f3 *qpc.qm -e3c60b712a27e8f8c11e38711e785ffc4006cda5 *include/qequeue.h -a0d30600da64ec7aaadc6b9bd268c217930c3e60 *include/qk.h -84c8c1036c38f0f1646cc60e4813a7c8fb89f2d2 *include/qmpool.h -7ecec322b0b31b4175596df3a7968424b21f983e *include/qp.h -7a909dd01c0aa3fd7d74b4a4c88b930eeb0b815e *include/qp_pkg.h -0a3323af546e1b2320e6745e8e0effa837abdc53 *include/qpc.h -6796ebe4b41225fa374d751704e7edd2f95e0484 *include/qs.h -5a0c927370d332fc170e84650d980173da2102ae *include/qs_dummy.h -d57d1974f64db7e3bf8a9f4468ee84a42ccd4952 *include/qs_pkg.h -7458d62031562c2517577b258d47249b7b900dd7 *include/qsafe.h -2e0a56edcf460fcd82f6d7277e5fc0876325efeb *include/qstamp.h -d0199c9094039e672d85e9198ccff0d4ed9128cc *include/qv.h -fdfc7f528989ff3934af977ef9a1ee9fc30cd889 *include/qxk.h -5886c3a0831996cfbf7141255efb4e9f5b4d8254 *include/README.md -7f54a0933a9dc2fcaca475919fa0067667ed99ed *src/qf/CMakeLists.txt -6ff32793932a96e1240b2c9dbbc9516faf206fa6 *src/qf/qep_hsm.c -e5d93d4867336209c0d8e74cc4a9add1190b821a *src/qf/qep_msm.c -733bc8bf8e08014c20d8354efb98729857edb4cd *src/qf/qf_act.c -90e27f32bc8862946bfe4c6c376bf03327de25f7 *src/qf/qf_actq.c -8b58d43c5b8fe3b1b846392d1f7d99d5720428d9 *src/qf/qf_defer.c -eba579d6183310d9d0d07a14f28691b41ebaa921 *src/qf/qf_dyn.c -d263e3b91f9e5c61d6a458b5c6023ac68eb07a13 *src/qf/qf_mem.c -47ae6dfca8c983839aa6a58a8afdc819f2d3b1e2 *src/qf/qf_ps.c -2ed707166ca625a684c93147aec772dd568e5d9f *src/qf/qf_qact.c -e6e7dd46ed4ab7fb3ecd781ca29ea141d13f49d9 *src/qf/qf_qeq.c -f975ffcfadfed6856a41587b8275e0ea3bbe63a3 *src/qf/qf_qmact.c -e43dbda05f6fd6cbb8673d8ae5d1f8b183570f29 *src/qf/qf_time.c -878a737efe234f40dc8c9374acc351e510b4da1e *src/qk/CMakeLists.txt -5f092f2dc82962633e8ff32f736baaf04ef4c5da *src/qk/qk.c -68c99a2991d25df7486e57edadaa955b2bda396d *src/qs/CMakeLists.txt -8cb434d345ef98a0915eadd97f7959987d66ff89 *src/qs/qs.c -e8ee51e5776c38f9dfdc06f87ab2b1f00bb45fd4 *src/qs/qs_64bit.c -14e1f08b94f65cc1d043051f829280e7f3ae057a *src/qs/qs_fp.c -4e3d64f109f5f8de67799a190f505d1fa29d622a *src/qs/qs_rx.c -f055d938dd53c9baf7f5e04ad1bc4f4ec40044e9 *src/qs/qstamp.c -afe015fd804a563aedd4080d389ef143a1a9ce40 *src/qs/qutest.c -b1d2def9b8f6cde464170af7682ab0f01f4f40f6 *src/qv/CMakeLists.txt -f77a3c93938c5ff9a37214bdfe1c7c255f9eed6e *src/qv/qv.c -de32deac900990db561238c22e6961e2c3ca4eac *src/qxk/qxk.c -fff73b289cb59e10ae491907e4bb48bbffb90946 *src/qxk/qxk_mutex.c -822dafde2328e17531a8c4df752e8e0b29a6f2c8 *src/qxk/qxk_sema.c -49b36eef14ecffad5583efb1c7b2208cc0fc055d *src/qxk/qxk_xthr.c -09c4447840e6b67c4f6adef68e13013abb87a69e *ports/arm-cm/qk/armclang/qk_port.c -4e8a047094569163fc6826ee33435476b55b8b06 *ports/arm-cm/qk/armclang/qp_port.h -e48b7af7dff7cfe6742abbb4adb0d1b01b2020cb *ports/arm-cm/qk/armclang/qs_port.h -061bb4b5f82fcee28c34441ed22287bcf7b294ab *ports/arm-cm/qk/gnu/qk_port.c -df8f0dfeb5b459c0a0da34584ac6f67c3ddcee99 *ports/arm-cm/qk/gnu/qp_port.h -e48b7af7dff7cfe6742abbb4adb0d1b01b2020cb *ports/arm-cm/qk/gnu/qs_port.h -b3bd86c8a739243aad85abb94e992ed83d3fe2cb *ports/arm-cm/qk/iar/qk_port.c -9b0833336729666744ac35ca42b85d57756ba8fa *ports/arm-cm/qk/iar/qp_port.h -e48b7af7dff7cfe6742abbb4adb0d1b01b2020cb *ports/arm-cm/qk/iar/qs_port.h -0a1f794005df1b7c256f52781928f86cb5dd96f9 *ports/arm-cm/qv/armclang/qp_port.h -e48b7af7dff7cfe6742abbb4adb0d1b01b2020cb *ports/arm-cm/qv/armclang/qs_port.h -050f16532d529cac3c20e990f1df40246b04c9ac *ports/arm-cm/qv/armclang/qv_port.c -0a1f794005df1b7c256f52781928f86cb5dd96f9 *ports/arm-cm/qv/gnu/qp_port.h -e48b7af7dff7cfe6742abbb4adb0d1b01b2020cb *ports/arm-cm/qv/gnu/qs_port.h -c8289ae7c23524d13f4680a839f9088aa9264200 *ports/arm-cm/qv/gnu/qv_port.c -3448a1cff7b1f10239a80e3191953ac018416bfd *ports/arm-cm/qv/iar/qp_port.h -e48b7af7dff7cfe6742abbb4adb0d1b01b2020cb *ports/arm-cm/qv/iar/qs_port.h -a5ffa52d6c2249bd4a3aaca9f8e4d55553aad374 *ports/arm-cm/qv/iar/qv_port.c -030f0e57e8565902d9feaec653b28980dfbb25e2 *ports/arm-cm/qxk/armclang/qp_port.h -e48b7af7dff7cfe6742abbb4adb0d1b01b2020cb *ports/arm-cm/qxk/armclang/qs_port.h -0134e96053a73cf2deab3f8aee2a253464da473d *ports/arm-cm/qxk/armclang/qxk_port.c -7f8806496c7aaa7ee212f00be7a80170d1cfe1c5 *ports/arm-cm/qxk/gnu/qp_port.h -e48b7af7dff7cfe6742abbb4adb0d1b01b2020cb *ports/arm-cm/qxk/gnu/qs_port.h -ddec778d8a73f663a5d959dec0afb2ced792e0ef *ports/arm-cm/qxk/gnu/qxk_port.c -02eee6cc5894c554358c573d7d9e159bb3b3b3a2 *ports/arm-cm/qxk/iar/qp_port.h -e48b7af7dff7cfe6742abbb4adb0d1b01b2020cb *ports/arm-cm/qxk/iar/qs_port.h -624c3bb9e77359cc1fd8e78b6505bd1246a09f7a *ports/arm-cm/qxk/iar/qxk_port.c -663b8e89a0ef61bbdd305984e14f971f889b3592 *ports/arm-cm/qutest/qp_port.h -e48b7af7dff7cfe6742abbb4adb0d1b01b2020cb *ports/arm-cm/qutest/qs_port.h -a53c0064a8650a9b7217259817a60cd67688606a *ports/arm-cr/qk/gnu/qp_port.h -e48b7af7dff7cfe6742abbb4adb0d1b01b2020cb *ports/arm-cr/qk/gnu/qs_port.h -88d3ed754f05c43609ecf52767c270fa438ecd03 *ports/arm-cr/qk/iar/qp_port.h -e48b7af7dff7cfe6742abbb4adb0d1b01b2020cb *ports/arm-cr/qk/iar/qs_port.h -e03d1c780c764e2a323b8423ae5045e226ee98c6 *ports/arm-cr/qk/ti/qp_port.h -e48b7af7dff7cfe6742abbb4adb0d1b01b2020cb *ports/arm-cr/qk/ti/qs_port.h -a5c1f6cbb41d1884a6bfdaf4ccc1c7facb79c8eb *ports/arm-cr/qv/gnu/qp_port.h -e48b7af7dff7cfe6742abbb4adb0d1b01b2020cb *ports/arm-cr/qv/gnu/qs_port.h -da079ffa59b518ead25ed8aed82adc1535fc0280 *ports/arm-cr/qv/iar/qp_port.h -e48b7af7dff7cfe6742abbb4adb0d1b01b2020cb *ports/arm-cr/qv/iar/qs_port.h -b6a6e866be5f4ac5bfc961aee3c466a755b9cd03 *ports/arm-cr/qv/ti/qp_port.h -e48b7af7dff7cfe6742abbb4adb0d1b01b2020cb *ports/arm-cr/qv/ti/qs_port.h -68b3a558e7e3e22477abf917ef5f87f1b424f9e5 *ports/msp430/qk/qp_port.h -a99dfb36c107e6c1b2fcc345792130bbc1ebcc4f *ports/msp430/qk/qs_port.h -39dceae58da3feab8f34e4597d63e72e4f8084e2 *ports/msp430/qv/qp_port.h -a99dfb36c107e6c1b2fcc345792130bbc1ebcc4f *ports/msp430/qv/qs_port.h -1459908255dbdd581cd38bd5ea33a121fce496b7 *ports/msp430/qutest/qp_port.h -a99dfb36c107e6c1b2fcc345792130bbc1ebcc4f *ports/msp430/qutest/qs_port.h -ecc7c04f015684c71bbaca3e351b8f7cbcdcc550 *ports/config/qp_config.h -2ee7f5594f6121705bbc57145175b5c5867e0070 *ports/embos/CMakeLists.txt -7cfd0e233fc7ee4c73cccaa58f769f3643325785 *ports/embos/qf_port.c -a378ac45d230fc61b4462b3cc17a05d018271ea7 *ports/embos/qp_port.h -e48b7af7dff7cfe6742abbb4adb0d1b01b2020cb *ports/embos/qs_port.h -e65838e1764bd6b4eb73025be1e8116ac28247b2 *ports/freertos/CMakeLists.txt -743a22c5deedeca8216fb2109174cc4c81573804 *ports/freertos/qf_port.c -1563d37772cf1cd0bddca356d49ee9805401f2cd *ports/freertos/qp_port.h -e48b7af7dff7cfe6742abbb4adb0d1b01b2020cb *ports/freertos/qs_port.h -a01e1f6d49ce056ac4e130d54ae4724fda2ebf32 *ports/threadx/CMakeLists.txt -be313a1d4350f28274fcb6b0dcdebf5279f40c71 *ports/threadx/qf_port.c -0aeea704b1cfac4e956e14e529dddf7759acde04 *ports/threadx/qp_port.h -e48b7af7dff7cfe6742abbb4adb0d1b01b2020cb *ports/threadx/qs_port.h -847cd324346d1d6c9c81422e99045442edcc7f64 *ports/threadx/README.md -d9b6e1ca7a0215a3e141ae43970781d0f4d0d08f *ports/uc-os2/CMakeLists.txt -30411991988667532a2432a80fa25aff2c451384 *ports/uc-os2/qf_port.c -6223846204fb35ba9c9da56bb7d686fbf19d375c *ports/uc-os2/qp_port.h -e48b7af7dff7cfe6742abbb4adb0d1b01b2020cb *ports/uc-os2/qs_port.h -4a5da9508e2012b2ca3943b87134163e558964cc *ports/qep-only/CMakeLists.txt -cdb7c42a17fb3c5f282a55e08f99678e1cd56c0e *ports/qep-only/qp_port.h -5189dfad3fea0ccb2218958dd3657f4403674b5e *ports/qep-only/safe_std.h -5d7914dfaf44a9c2552afdd5d8de4cfc3ebbc22a *ports/posix/CMakeLists.txt -6b9d862537f4823ca83c81d2e8892da9711a69cd *ports/posix/qf_port.c -78563f44b3d4b7835a75ef9dd3eea00e38f61946 *ports/posix/qp_port.h -51d89a3fa8c7a6c5858f6354ea8cc350e42a9d30 *ports/posix/qs_port.c -d05889780d358bb1fe02ffad1a9414332f5eb300 *ports/posix/qs_port.h -6e33b2e5092d117f58c47b632c59420f382ac39f *ports/posix/README.md -5189dfad3fea0ccb2218958dd3657f4403674b5e *ports/posix/safe_std.h -039b1e4066eb7eeac3233070ad6aa2cd9f6d1c69 *ports/posix-qv/CMakeLists.txt -2b432fddb2bb9a9912db1c0f6e1ceada35323365 *ports/posix-qv/qf_port.c -b73738f7297d6c023012d98c59c901a1e8951f02 *ports/posix-qv/qp_port.h -51d89a3fa8c7a6c5858f6354ea8cc350e42a9d30 *ports/posix-qv/qs_port.c -d05889780d358bb1fe02ffad1a9414332f5eb300 *ports/posix-qv/qs_port.h -ab829eb3deed2bc84b3581610f1664777afd3841 *ports/posix-qv/README.md -5189dfad3fea0ccb2218958dd3657f4403674b5e *ports/posix-qv/safe_std.h -1ecb2095e8de486c8111a420b5511a4ea0cb097c *ports/posix-qutest/CMakeLists.txt -d55172d4bb6959349285a06ca6485f1f1a1b756e *ports/posix-qutest/qp_port.h -d05889780d358bb1fe02ffad1a9414332f5eb300 *ports/posix-qutest/qs_port.h -243941959b1dbf5dfbbe57941104ae202eec57fc *ports/posix-qutest/qutest_port.c -5189dfad3fea0ccb2218958dd3657f4403674b5e *ports/posix-qutest/safe_std.h -cfea17ea9ab718e9e4f506e90c4b2fc8c1fea858 *ports/win32/CMakeLists.txt -a99784fa31b0466af740186bbe96f8d78fc7c17a *ports/win32/qf_port.c -d0b7e944e6df828e040ec146f639e42be2c354d5 *ports/win32/qp_port.h -d86809f52df1ab5be11ed12dfb3b8ef4cb4fd6db *ports/win32/qs_port.c -b1a67eb489d35d71cf6fb40fc8f087906839f1a7 *ports/win32/qs_port.h -8d3500b2b8700f5aa925f7020631d7d1415bd028 *ports/win32/qwin_gui.c -04f62b5f1812de29bfb0619af1fc04ec44256802 *ports/win32/qwin_gui.h -3781ccdce31dea9d08493a801926eb278950786f *ports/win32/README.md -5189dfad3fea0ccb2218958dd3657f4403674b5e *ports/win32/safe_std.h -8d589868e287ceb185b4837064c80d4eed8e1a44 *ports/win32-qv/CMakeLists.txt -d6706afb9a3b11f6aad510f16ec1ed9665b98633 *ports/win32-qv/qf_port.c -20249cc3927858f7d457433e64be963df0baddf7 *ports/win32-qv/qp_port.h -d86809f52df1ab5be11ed12dfb3b8ef4cb4fd6db *ports/win32-qv/qs_port.c -b1a67eb489d35d71cf6fb40fc8f087906839f1a7 *ports/win32-qv/qs_port.h -77d78e462a3ac8fac9c75fd97720500ceb449664 *ports/win32-qv/qwin_gui.c -be15234e51b8fe3c295ff644e84fbc1cfca89257 *ports/win32-qv/qwin_gui.h -b57cec85e2fe5c261270f68acc3ae440802a62bd *ports/win32-qv/README.md -5189dfad3fea0ccb2218958dd3657f4403674b5e *ports/win32-qv/safe_std.h -a04f13d2d9f24ef71d95f997d87f8a3ba9862e45 *ports/win32-qutest/CMakeLists.txt -50be2b5d49345d908290a4660b1bbc5eaeb6b4d6 *ports/win32-qutest/qp_port.h -b1a67eb489d35d71cf6fb40fc8f087906839f1a7 *ports/win32-qutest/qs_port.h -1d850be2190dd03f528405266ba85f81e9ecff53 *ports/win32-qutest/qutest_port.c -5189dfad3fea0ccb2218958dd3657f4403674b5e *ports/win32-qutest/safe_std.h -848a30efa3274ff30fb72059f926fe7963ab2321 *zephyr/CMakeLists.txt -10764710e545dd4d2ce0ddf032711df7f9191937 *zephyr/Kconfig -2eb2a922e18b4760a68151ebee1b6282d20b4692 *zephyr/module.yml -c691294aa02303c2d74c0b4fa62c2296491d1d15 *zephyr/qf_port.c -109c291df50110f185adc17bcdf8becc0a79346c *zephyr/qp-zephyr.jpg -abe4afc842977359a1bb63a76b765aed65b64def *zephyr/qp_port.h -e48b7af7dff7cfe6742abbb4adb0d1b01b2020cb *zephyr/qs_port.h -ab487299b61fea18e2926913048a4498b3bfa4b4 *zephyr/README.md diff --git a/qpc_8.0.2.sha1 b/qpc_8.0.2.sha1 new file mode 100644 index 000000000..1a3b1e855 --- /dev/null +++ b/qpc_8.0.2.sha1 @@ -0,0 +1,162 @@ +66333dd47b999c878440d0419638bfc481dcfa2d *include/qequeue.h +e97955fabb532865a6a15409eef15645d627ed96 *include/qk.h +63aa17cfee22188219be96d8736e4f3d443f4ca9 *include/qmpool.h +c0882e529d8aba6f860d4d9dc353cb4893d6970a *include/qp.h +29d33dd6ee2b03dac725bf50938dd5e6d0655f46 *include/qp_pkg.h +12cb1f8910ec1c4a3a0af5b01deb68bba74b119e *include/qpc.h +1609ca880f322b074eb63767d7c704be26a69769 *include/qs.h +ef92a02258673672dde6ffeaec820ae9ec6a0f95 *include/qs_dummy.h +18b1497a755d0dab5e3fb0e88dd3de4cfdb1aced *include/qs_pkg.h +cf142966637ce4c4ae831017e8a77fb1fe3a678a *include/qsafe.h +5bd2b79056d2c55811b375de3e643425485e1a76 *include/qstamp.h +1fd9c43acda827d86090a8f2e6ab95158351eead *include/qv.h +9dd5c494ccacfe8739857ae50d1a95e57d028650 *include/qxk.h +5886c3a0831996cfbf7141255efb4e9f5b4d8254 *include/README.md +7f54a0933a9dc2fcaca475919fa0067667ed99ed *src/qf/CMakeLists.txt +03ee8c47f280c10c29260c3af745ea145943f6c4 *src/qf/qep_hsm.c +8a1bbf59511c7e4bc048672c869280ebc6e39619 *src/qf/qep_msm.c +e8f7d8dcd8b668b10dfd2b6d8c5e94fc42d6bc02 *src/qf/qf_act.c +402996322cf90d1a256b1a65edc5df189664abfb *src/qf/qf_actq.c +33b348c45cd218a4c7d74acaed1c26e87b3f0d52 *src/qf/qf_defer.c +f1735b336c11049a2e00bb0bc2a518047b2ac1ce *src/qf/qf_dyn.c +7af95508fbcad60e6dc031e33bcbdc803b764ed0 *src/qf/qf_mem.c +27ac315463a0108f4e3c58cbea090ceb8da8bc00 *src/qf/qf_ps.c +96ada1ea4ee23342f79d2b0608d930a829a2790a *src/qf/qf_qact.c +f7e4046dcd5440f375884d743afcbc62289e2e9f *src/qf/qf_qeq.c +d466792e96d60b3ff5e01c7ec858b031888b6cd1 *src/qf/qf_qmact.c +f8aa87ddaa1e6b74196070e7208571a621a9d70e *src/qf/qf_time.c +878a737efe234f40dc8c9374acc351e510b4da1e *src/qk/CMakeLists.txt +cfd0869773fbddeae359b123ba98f335f89d71ce *src/qk/qk.c +68c99a2991d25df7486e57edadaa955b2bda396d *src/qs/CMakeLists.txt +c1257fbf29a2bfbf476fde5dba3e9d53859a932f *src/qs/qs.c +c0ffe200944d4cc3ace073a1028bfccdbb957875 *src/qs/qs_64bit.c +5f18c87dd1774d62a77d2ea586109c4159401d70 *src/qs/qs_fp.c +b052ff2d8dbc40f3c347e2548e74ed582d95e6ef *src/qs/qs_rx.c +b087ea69dfd8c370b9d43d114e3de4caf5d10775 *src/qs/qstamp.c +717bffc3ab94bff47f54c94b2e1f82ff00949b7e *src/qs/qutest.c +b1d2def9b8f6cde464170af7682ab0f01f4f40f6 *src/qv/CMakeLists.txt +7295ed9e23dbde7787caf3e486f839080f6f47b2 *src/qv/qv.c +405f00d17b9e0a04d239c7ed216ed4dabb9b09f6 *src/qxk/qxk.c +353d1aa3b530af4e90c9c07f08cff4ddca9b1929 *src/qxk/qxk_mutex.c +e992d1204cfceac7fce4c3f699f4f77787b8811e *src/qxk/qxk_sema.c +fd29eed9e089ae2a2d65cd9a615fb7b5111debb7 *src/qxk/qxk_xthr.c +0e330d6ac8fb04f3b7dac15dc2edc45ab69005fd *ports/arm-cm/config/qp_config.h +bbd400817341d34b7aba9f31eaf5804d931b5de1 *ports/arm-cm/qk/armclang/qk_port.c +caaf801e9f7bbcc6b8fb3664d58da2df53f53f51 *ports/arm-cm/qk/armclang/qp_port.h +86c87e41ed3ef19e785585e145e95efa50dbec21 *ports/arm-cm/qk/armclang/qs_port.h +9c0cd53ce9ab526113a585c89e0cd25bc6d12236 *ports/arm-cm/qk/gnu/qk_port.c +caaf801e9f7bbcc6b8fb3664d58da2df53f53f51 *ports/arm-cm/qk/gnu/qp_port.h +86c87e41ed3ef19e785585e145e95efa50dbec21 *ports/arm-cm/qk/gnu/qs_port.h +f79b4f199a4c92dd9423921449c52af9b64d633b *ports/arm-cm/qk/iar/qk_port.c +12dca6dbdc7511af283b5d80fb79d6771e54f5bc *ports/arm-cm/qk/iar/qp_port.h +86c87e41ed3ef19e785585e145e95efa50dbec21 *ports/arm-cm/qk/iar/qs_port.h +8cf14894789bb7c99f0f0940340d28becb1a308d *ports/arm-cm/qv/armclang/qp_port.h +86c87e41ed3ef19e785585e145e95efa50dbec21 *ports/arm-cm/qv/armclang/qs_port.h +6c41eeb2fe40fa017f2e3c2a550bd5758b576ab7 *ports/arm-cm/qv/armclang/qv_port.c +8cf14894789bb7c99f0f0940340d28becb1a308d *ports/arm-cm/qv/gnu/qp_port.h +86c87e41ed3ef19e785585e145e95efa50dbec21 *ports/arm-cm/qv/gnu/qs_port.h +905b5063994ea2ff6ce12a1c8d51006789cb3f45 *ports/arm-cm/qv/gnu/qv_port.c +deb66c87f75b5af52d14ab3a2449a9b68b6f1024 *ports/arm-cm/qv/iar/qp_port.h +86c87e41ed3ef19e785585e145e95efa50dbec21 *ports/arm-cm/qv/iar/qs_port.h +efca09f53ba5dee0b7e93947939ef654ed7d4ff6 *ports/arm-cm/qv/iar/qv_port.c +5172ce6e18f7e2083b042b5dc0fcc4b6ce40a403 *ports/arm-cm/qxk/armclang/qp_port.h +86c87e41ed3ef19e785585e145e95efa50dbec21 *ports/arm-cm/qxk/armclang/qs_port.h +60773cce000c3a00c34194aa415c981d60ab4d05 *ports/arm-cm/qxk/armclang/qxk_port.c +5172ce6e18f7e2083b042b5dc0fcc4b6ce40a403 *ports/arm-cm/qxk/gnu/qp_port.h +86c87e41ed3ef19e785585e145e95efa50dbec21 *ports/arm-cm/qxk/gnu/qs_port.h +e24e90e959d8b28e685c08c34f8b487125da4458 *ports/arm-cm/qxk/gnu/qxk_port.c +3cdf8223edd056f5aaa4254eb6de80d73a9de767 *ports/arm-cm/qxk/iar/qp_port.h +86c87e41ed3ef19e785585e145e95efa50dbec21 *ports/arm-cm/qxk/iar/qs_port.h +e3a4f1f86a0fbe2718381dec81f6e57e58ddab07 *ports/arm-cm/qxk/iar/qxk_port.c +9ab1ac34865644e85d5b7a7c19f58e9d64eaef93 *ports/arm-cm/qutest/qp_port.h +86c87e41ed3ef19e785585e145e95efa50dbec21 *ports/arm-cm/qutest/qs_port.h +71a243c9345c2986d896bff1ae756bcde326cdda *ports/arm-cr/config/qp_config.h +219b6c1c437959ebbc2f5e5430d8b86957d67eac *ports/arm-cr/qk/gnu/qp_port.h +86c87e41ed3ef19e785585e145e95efa50dbec21 *ports/arm-cr/qk/gnu/qs_port.h +1663a960814e4a7a8d2db95aa25aab0ff273823d *ports/arm-cr/qk/iar/qp_port.h +86c87e41ed3ef19e785585e145e95efa50dbec21 *ports/arm-cr/qk/iar/qs_port.h +6989b54951445d8797fc98a5e0bb708e1e0a900a *ports/arm-cr/qk/ti/qp_port.h +86c87e41ed3ef19e785585e145e95efa50dbec21 *ports/arm-cr/qk/ti/qs_port.h +3eadaeda538ccb4bf2458bb39d8412ec1191cd99 *ports/arm-cr/qv/gnu/qp_port.h +86c87e41ed3ef19e785585e145e95efa50dbec21 *ports/arm-cr/qv/gnu/qs_port.h +b177a95edac0d8db21ae9fb45a7147ab13943e0d *ports/arm-cr/qv/iar/qp_port.h +86c87e41ed3ef19e785585e145e95efa50dbec21 *ports/arm-cr/qv/iar/qs_port.h +8cbe00552dce187aaa0add875a9b3920ff200e70 *ports/arm-cr/qv/ti/qp_port.h +86c87e41ed3ef19e785585e145e95efa50dbec21 *ports/arm-cr/qv/ti/qs_port.h +bf1e8bde3e5a5ec984d840fdb87c7e7d511fd19d *ports/msp430/qk/qp_port.h +15a126600fca9ca9cdacb1384b6c9b56d46d6cd1 *ports/msp430/qk/qs_port.h +6e1183c72de053848d3c6c4e3e5cd758898b0759 *ports/msp430/qv/qp_port.h +15a126600fca9ca9cdacb1384b6c9b56d46d6cd1 *ports/msp430/qv/qs_port.h +319887535b798cbd799a7201cbd6f86acc597dce *ports/msp430/qutest/qp_port.h +15a126600fca9ca9cdacb1384b6c9b56d46d6cd1 *ports/msp430/qutest/qs_port.h +496eac74a77a1280f07e58aeb20603a89fd8bb60 *ports/config/qp_config.h +2ee7f5594f6121705bbc57145175b5c5867e0070 *ports/embos/CMakeLists.txt +c89b93be587f7adcec43930304c9ae5fde0b4481 *ports/embos/qf_port.c +35807bc606a0334ff45d75ae094468242e1bad05 *ports/embos/qp_port.h +86c87e41ed3ef19e785585e145e95efa50dbec21 *ports/embos/qs_port.h +e65838e1764bd6b4eb73025be1e8116ac28247b2 *ports/freertos/CMakeLists.txt +55387dfccb6f0f2e724c0674635784b85a86595a *ports/freertos/qf_port.c +9ae6e269d706c81aa955a81857e2044a341f3d4f *ports/freertos/qp_port.h +86c87e41ed3ef19e785585e145e95efa50dbec21 *ports/freertos/qs_port.h +a01e1f6d49ce056ac4e130d54ae4724fda2ebf32 *ports/threadx/CMakeLists.txt +e046b9206a2e8d06465b7240d41622a1a79a260e *ports/threadx/qf_port.c +174dcf1ecf745e195647e1c630593528247a501b *ports/threadx/qp_port.h +86c87e41ed3ef19e785585e145e95efa50dbec21 *ports/threadx/qs_port.h +847cd324346d1d6c9c81422e99045442edcc7f64 *ports/threadx/README.md +d9b6e1ca7a0215a3e141ae43970781d0f4d0d08f *ports/uc-os2/CMakeLists.txt +f295018c8808aa09f1033654244140c3297b8f2b *ports/uc-os2/qf_port.c +afd0a40b566c9c0672c18fe95f39e5941b1e2bae *ports/uc-os2/qp_port.h +86c87e41ed3ef19e785585e145e95efa50dbec21 *ports/uc-os2/qs_port.h +4a5da9508e2012b2ca3943b87134163e558964cc *ports/qep-only/CMakeLists.txt +acc6603e5ff3d1bef767c9770a9a80f6dc381898 *ports/qep-only/qp_port.h +54391d2a37ed3bce69e90ccfd8615ca736628c3e *ports/qep-only/safe_std.h +5d7914dfaf44a9c2552afdd5d8de4cfc3ebbc22a *ports/posix/CMakeLists.txt +d2582a682a4ee053994a3b9d623965c7cd98e498 *ports/posix/qf_port.c +ee091d4bef409dd28113d941833ccfba42976422 *ports/posix/qp_port.h +faaa0c0b286f7acc6265ae50f0671afb838563de *ports/posix/qs_port.c +3a91e923b22fa0cfe3ca12d23d0679e132b21b2c *ports/posix/qs_port.h +6e33b2e5092d117f58c47b632c59420f382ac39f *ports/posix/README.md +54391d2a37ed3bce69e90ccfd8615ca736628c3e *ports/posix/safe_std.h +039b1e4066eb7eeac3233070ad6aa2cd9f6d1c69 *ports/posix-qv/CMakeLists.txt +5ca7b69ed61ba195867ca3be818ee1eb8ceab51e *ports/posix-qv/qf_port.c +048b213bc1af84b0e3c29fce3c58e21939c3938d *ports/posix-qv/qp_port.h +faaa0c0b286f7acc6265ae50f0671afb838563de *ports/posix-qv/qs_port.c +3a91e923b22fa0cfe3ca12d23d0679e132b21b2c *ports/posix-qv/qs_port.h +ab829eb3deed2bc84b3581610f1664777afd3841 *ports/posix-qv/README.md +54391d2a37ed3bce69e90ccfd8615ca736628c3e *ports/posix-qv/safe_std.h +1ecb2095e8de486c8111a420b5511a4ea0cb097c *ports/posix-qutest/CMakeLists.txt +5fb0c6b9a07b67d3b74c8b3ca41f03b1dc2dde7d *ports/posix-qutest/qp_port.h +3a91e923b22fa0cfe3ca12d23d0679e132b21b2c *ports/posix-qutest/qs_port.h +18a858d16ae0e769a7993e6dc94bf420f32d49fc *ports/posix-qutest/qutest_port.c +54391d2a37ed3bce69e90ccfd8615ca736628c3e *ports/posix-qutest/safe_std.h +cfea17ea9ab718e9e4f506e90c4b2fc8c1fea858 *ports/win32/CMakeLists.txt +d628226105618402813ee97a58e54bdbb0058c9a *ports/win32/qf_port.c +5dabd3c775276804fc65ed4395385765e0d9ca0f *ports/win32/qp_port.h +c55c3bff64ad2a47691104a6d927914006286f47 *ports/win32/qs_port.c +7109827ba2c76667d61a445d8a22219a9627b28f *ports/win32/qs_port.h +1cde650008ea5d867daa3bc0f4f4ada7365dacba *ports/win32/qwin_gui.c +4c44c6fe98ae54634a7216a885b091c08f9f1735 *ports/win32/qwin_gui.h +3781ccdce31dea9d08493a801926eb278950786f *ports/win32/README.md +54391d2a37ed3bce69e90ccfd8615ca736628c3e *ports/win32/safe_std.h +8d589868e287ceb185b4837064c80d4eed8e1a44 *ports/win32-qv/CMakeLists.txt +6658b9e823fe2a031cd26def2c080f8264cf3e0b *ports/win32-qv/qf_port.c +c02fab4c658ecbb53e86256b84a8f61b7f3e20c9 *ports/win32-qv/qp_port.h +c55c3bff64ad2a47691104a6d927914006286f47 *ports/win32-qv/qs_port.c +7109827ba2c76667d61a445d8a22219a9627b28f *ports/win32-qv/qs_port.h +1cde650008ea5d867daa3bc0f4f4ada7365dacba *ports/win32-qv/qwin_gui.c +4c44c6fe98ae54634a7216a885b091c08f9f1735 *ports/win32-qv/qwin_gui.h +b57cec85e2fe5c261270f68acc3ae440802a62bd *ports/win32-qv/README.md +54391d2a37ed3bce69e90ccfd8615ca736628c3e *ports/win32-qv/safe_std.h +a04f13d2d9f24ef71d95f997d87f8a3ba9862e45 *ports/win32-qutest/CMakeLists.txt +3b580c033d3a0cadc6b2f10fd215d5c30779b3fe *ports/win32-qutest/qp_port.h +7109827ba2c76667d61a445d8a22219a9627b28f *ports/win32-qutest/qs_port.h +30af4a5587b6efdfc7bd914962ba9b8f93c27d6b *ports/win32-qutest/qutest_port.c +54391d2a37ed3bce69e90ccfd8615ca736628c3e *ports/win32-qutest/safe_std.h +848a30efa3274ff30fb72059f926fe7963ab2321 *zephyr/CMakeLists.txt +10764710e545dd4d2ce0ddf032711df7f9191937 *zephyr/Kconfig +2eb2a922e18b4760a68151ebee1b6282d20b4692 *zephyr/module.yml +2dcf544afc6feb5dbb743a39576a96121b49ac2e *zephyr/qf_port.c +109c291df50110f185adc17bcdf8becc0a79346c *zephyr/qp-zephyr.jpg +1bdb624c82e926095052e4629cd1a8f44bce93d3 *zephyr/qp_port.h +86c87e41ed3ef19e785585e145e95efa50dbec21 *zephyr/qs_port.h +ab487299b61fea18e2926913048a4498b3bfa4b4 *zephyr/README.md diff --git a/qpc_sha1.bat b/qpc_sha1.bat index 8d5bf6599..70c8d8141 100644 --- a/qpc_sha1.bat +++ b/qpc_sha1.bat @@ -1,10 +1,10 @@ @setlocal -set VERSION=8.0.1 +set VERSION=8.0.2 :: usage @echo Usage: qpc_sha1 [gen] -@echo examples: +@echo examples of use: @echo qpc_sha1 : check the sha1 sums in the file qpc_%VERSION%.sha1 @echo qpc_sha1 gen : generate the sha1 file qpc_%VERSION%.sha1 @echo. @@ -15,14 +15,15 @@ goto end ) @echo generating qpc_%VERSION%.sha1... -@sha1sum qpc.qm ^ +@sha1sum ^ include/* ^ src/qf/* src/qk/* src/qs/* src/qv/* src/qxk/* ^ - ports/arm-cm/qk/armclang/* ports/arm-cm/qk/config/* ports/arm-cm/qk/gnu/* ports/arm-cm/qk/iar/* ^ - ports/arm-cm/qv/armclang/* ports/arm-cm/qv/config/* ports/arm-cm/qv/gnu/* ports/arm-cm/qv/iar/* ^ - ports/arm-cm/qxk/armclang/* ports/arm-cm/qxk/config/* ports/arm-cm/qxk/gnu/* ports/arm-cm/qxk/iar/* ^ + ports/arm-cm/config/* ^ + ports/arm-cm/qk/armclang/* ports/arm-cm/qk/gnu/* ports/arm-cm/qk/iar/* ^ + ports/arm-cm/qv/armclang/* ports/arm-cm/qv/gnu/* ports/arm-cm/qv/iar/* ^ + ports/arm-cm/qxk/armclang/* ports/arm-cm/qxk/gnu/* ports/arm-cm/qxk/iar/* ^ ports/arm-cm/qutest/* ^ - ports/arm-cr/qk/config/* ^ + ports/arm-cr/config/* ^ ports/arm-cr/qk/gnu/* ports/arm-cr/qk/iar/* ports/arm-cr/qk/ti/* ^ ports/arm-cr/qv/gnu/* ports/arm-cr/qv/iar/* ports/arm-cr/qv/ti/* ^ ports/msp430/qk/* ports/msp430/qv/* ports/msp430/qutest/* ^ diff --git a/src/qf/qep_hsm.c b/src/qf/qep_hsm.c index 69234de57..7c00a945c 100644 --- a/src/qf/qep_hsm.c +++ b/src/qf/qep_hsm.c @@ -1,10 +1,6 @@ -//$file${src::qf::qep_hsm.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// -// Model: qpc.qm -// File: ${src::qf::qep_hsm.c} -// -// This code has been generated by QM 7.0.0 . -// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // @@ -14,7 +10,7 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -30,8 +26,7 @@ // Quantum Leaps contact information: // // -// -//$endhead${src::qf::qep_hsm.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//============================================================================ #define QP_IMPL // this is QP implementation #include "qp_port.h" // QP port #include "qsafe.h" // QP Functional Safety (FuSa) Subsystem @@ -44,70 +39,118 @@ Q_DEFINE_THIS_MODULE("qep_hsm") -//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// Check for the minimum required QP version -#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U)%0x2710U)) -#error qpc version 7.3.0 or higher required -#endif -//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -//$define${QEP::QP_versionStr[16]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QEP::QP_versionStr[16]} .................................................. -char const QP_versionStr[16] = QP_VERSION_STR; -//$enddef${QEP::QP_versionStr[16]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -//============================================================================ -//! @cond INTERNAL +// maximum depth of state nesting in a QHsm (including the top level), +// must be >= 3 +#define QHSM_MAX_NEST_DEPTH_ 6 -//$define${QEP::QEvt::reserved_[4]} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -QEvt const QEvt_reserved_[4] = { +static QEvt const l_reservedEvt_[4] = { QEVT_INITIALIZER(Q_EMPTY_SIG), QEVT_INITIALIZER(Q_ENTRY_SIG), QEVT_INITIALIZER(Q_EXIT_SIG), QEVT_INITIALIZER(Q_INIT_SIG) }; -//$enddef${QEP::QEvt::reserved_[4]} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//============================================================================ +//! @cond INTERNAL -// helper macro to handle reserved event in an QHsm +// internal helper macro to pass a reserved event into the state handler #define QHSM_RESERVED_EVT_(state_, sig_) \ - ((*(state_))(me, &QEvt_reserved_[(sig_)])) - -// helper macro to trace state entry -#define QS_STATE_ENTRY_(state_, qsId_) \ - QS_CRIT_ENTRY(); \ - QS_MEM_SYS(); \ - QS_BEGIN_PRE(QS_QEP_STATE_ENTRY, (qsId_)) \ - QS_OBJ_PRE(me); \ - QS_FUN_PRE(state_); \ - QS_END_PRE() \ - QS_MEM_APP(); \ + ((*(state_))(me, &l_reservedEvt_[(sig_)])) + +#ifdef Q_SPY +// helper macro to trace state action (entry/exit) +#define QS_STATE_ACT_(rec_, state_) \ + QS_CRIT_ENTRY(); \ + QS_BEGIN_PRE((rec_), qsId) \ + QS_OBJ_PRE(me); \ + QS_FUN_PRE(state_); \ + QS_END_PRE() \ + QS_CRIT_EXIT() + +// internal helper macro to top-most init +#define QS_TOP_INIT_(rec_, trg_) \ + QS_CRIT_ENTRY(); \ + QS_BEGIN_PRE((rec_), qsId) \ + QS_TIME_PRE(); \ + QS_OBJ_PRE(me); \ + QS_FUN_PRE(trg_); \ + QS_END_PRE() \ QS_CRIT_EXIT() -// helper macro to trace state exit -#define QS_STATE_EXIT_(state_, qsId_) \ - QS_CRIT_ENTRY(); \ - QS_MEM_SYS(); \ - QS_BEGIN_PRE(QS_QEP_STATE_EXIT, (qsId_)) \ - QS_OBJ_PRE(me); \ - QS_FUN_PRE(state_); \ - QS_END_PRE() \ - QS_MEM_APP(); \ +// internal helper macro to trace transition segment +#define QS_TRAN_SEG_(rec_, src_, trg_) \ + QS_CRIT_ENTRY(); \ + QS_BEGIN_PRE((rec_), qsId) \ + QS_OBJ_PRE(me); \ + QS_FUN_PRE(src_); \ + QS_FUN_PRE(trg_); \ + QS_END_PRE() \ QS_CRIT_EXIT() +// internal helper macro to trace transition action +#define QS_TRAN_ACT_(rec_, state_) \ + QS_CRIT_ENTRY(); \ + QS_BEGIN_PRE((rec_), qsId) \ + QS_SIG_PRE(e->sig); \ + QS_OBJ_PRE(me); \ + QS_FUN_PRE(state_); \ + QS_END_PRE() \ + QS_CRIT_EXIT() + +// internal helper macro to trace transition begin/end +#define QS_TRAN0_(rec_, trg_) \ + QS_CRIT_ENTRY(); \ + QS_BEGIN_PRE((rec_), qsId) \ + QS_TIME_PRE(); \ + QS_SIG_PRE(e->sig); \ + QS_OBJ_PRE(me); \ + QS_FUN_PRE(trg_); \ + QS_END_PRE() \ + QS_CRIT_EXIT() + +// internal helper macro to trace regulsr transition +#define QS_TRAN_END_(rec_, src_, trg_) \ + QS_CRIT_ENTRY(); \ + QS_BEGIN_PRE((rec_), qsId) \ + QS_TIME_PRE(); \ + QS_SIG_PRE(e->sig); \ + QS_OBJ_PRE(me); \ + QS_FUN_PRE(src_); \ + QS_FUN_PRE(trg_); \ + QS_END_PRE() \ + QS_CRIT_EXIT() + +#else +#define QS_STATE_ACT_(rec_, state_) ((void)0) +#define QS_TOP_INIT_(rec_, trg_) ((void)0) +#define QS_TRAN_SEG_(rec_, src_, trg_) ((void)0) +#define QS_TRAN_ACT_(rec_, state_) ((void)0) +#define QS_TRAN0_(rec_, trg_) ((void)0) +#define QS_TRAN_END_(rec_, src_, trg_) ((void)0) +#endif + //! @endcond -enum { - // maximum depth of state nesting in a QHsm (including the top level), - // must be >= 3 - QHSM_MAX_NEST_DEPTH_ = 6 -}; +//! @private @memberof QHsm +static int_fast8_t QHsm_tran_simple_( + QAsm * const me, + QStateHandler * const path, + uint_fast8_t const qsId); -//$define${QEP::QHsm} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +//! @private @memberof QHsm +static int_fast8_t QHsm_tran_complex_( + QAsm * const me, + QStateHandler * const path, + uint_fast8_t const qsId); -//${QEP::QHsm} ............................................................... +//! @private @memberof QHsm +static void QHsm_enter_target_( + QAsm * const me, + QStateHandler * const path, + int_fast8_t const depth, + uint_fast8_t const qsId); -//${QEP::QHsm::ctor} ......................................................... +//............................................................................ //! @protected @memberof QHsm void QHsm_ctor(QHsm * const me, QStateHandler const initial) @@ -116,9 +159,9 @@ void QHsm_ctor(QHsm * const me, &QHsm_init_, &QHsm_dispatch_, &QHsm_isIn_ - #ifdef Q_SPY +#ifdef Q_SPY ,&QHsm_getStateHandler_ - #endif +#endif }; // do not call the QAsm_ctor() here me->super.vptr = &vtable; @@ -126,7 +169,7 @@ void QHsm_ctor(QHsm * const me, me->super.temp.fun = initial; } -//${QEP::QHsm::init_} ........................................................ +//............................................................................ //! @private @memberof QHsm void QHsm_init_( QAsm * const me, @@ -135,27 +178,21 @@ void QHsm_init_( { QF_CRIT_STAT - QState r; - // produce QS dictionary for QHsm_top() - #ifdef Q_SPY +#ifdef Q_SPY QS_CRIT_ENTRY(); - QS_MEM_SYS(); + bool isDone = true; if ((QS_priv_.flags & 0x01U) == 0U) { QS_priv_.flags |= 0x01U; - r = Q_RET_HANDLED; + isDone = false; } - else { - r = Q_RET_IGNORED; - } - QS_MEM_APP(); QS_CRIT_EXIT(); - if (r == Q_RET_HANDLED) { + if (!isDone) { QS_FUN_DICTIONARY(&QHsm_top); } - #else +#else Q_UNUSED_PAR(qsId); - #endif // def Q_SPY +#endif // def Q_SPY QStateHandler t = me->state.fun; @@ -166,101 +203,52 @@ void QHsm_init_( QF_CRIT_EXIT(); // execute the top-most initial tran. - r = (*me->temp.fun)(me, Q_EVT_CAST(QEvt)); + QState const r = (*me->temp.fun)(me, Q_EVT_CAST(QEvt)); QF_CRIT_ENTRY(); // the top-most initial tran. must be taken Q_ASSERT_INCRIT(210, r == Q_RET_TRAN); - - QS_MEM_SYS(); - QS_BEGIN_PRE(QS_QEP_STATE_INIT, qsId) - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(t); // the source state - QS_FUN_PRE(me->temp.fun); // the target of the initial tran. - QS_END_PRE() - QS_MEM_APP(); - QF_CRIT_EXIT(); + QS_TRAN_SEG_(QS_QEP_STATE_INIT, t, me->temp.fun); + // drill down into the state hierarchy with initial transitions... - do { - QStateHandler path[QHSM_MAX_NEST_DEPTH_]; // tran. entry path array - int_fast8_t ip = 0; // tran. entry path index + QStateHandler path[QHSM_MAX_NEST_DEPTH_]; // tran. entry path array + path[0] = me->temp.fun; + (void)QHSM_RESERVED_EVT_(me->temp.fun, Q_EMPTY_SIG); - path[0] = me->temp.fun; + int_fast8_t ip = 1; // tran. entry path index (also the loop bound) + for (; (me->temp.fun != t) && (ip < QHSM_MAX_NEST_DEPTH_); ++ip) { + path[ip] = 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(); - // 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) - == Q_RET_HANDLED) - { - QS_STATE_ENTRY_(path[ip], qsId); - } - --ip; - } while (ip >= 0); - - t = path[0]; // current state becomes the new source - - r = QHSM_RESERVED_EVT_(t, Q_INIT_SIG); // execute initial tran. - - #ifdef Q_SPY - if (r == Q_RET_TRAN) { - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_BEGIN_PRE(QS_QEP_STATE_INIT, qsId) - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(t); // the source state - QS_FUN_PRE(me->temp.fun); // the target of the initial tran. - QS_END_PRE() - QS_MEM_APP(); - QS_CRIT_EXIT(); - } - #endif // Q_SPY - } while (r == Q_RET_TRAN); - + } QF_CRIT_ENTRY(); + // must NOT be too many state nesting levels or "malformed" HSM + Q_ASSERT_INCRIT(220, ip <= QHSM_MAX_NEST_DEPTH_); + QF_CRIT_EXIT(); - QS_MEM_SYS(); - QS_BEGIN_PRE(QS_QEP_INIT_TRAN, qsId) - QS_TIME_PRE(); // time stamp - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(t); // the new active state - QS_END_PRE() - QS_MEM_APP(); + me->temp.fun = path[0]; + QHsm_enter_target_(me, &path[0], ip - 1, qsId); + t = path[0]; - QF_CRIT_EXIT(); + QS_TOP_INIT_(QS_QEP_INIT_TRAN, t); - me->state.fun = t; // change the current active state - #ifndef Q_UNSAFE - me->temp.uint = ~me->state.uint; - #endif + me->state.fun = t; // change the current active state +#ifdef Q_UNSAFE + Q_UNUSED_PAR(r); +#endif } -//${QEP::QHsm::dispatch_} .................................................... +//............................................................................ //! @private @memberof QHsm void QHsm_dispatch_( QAsm * const me, QEvt const * const e, uint_fast8_t const qsId) { - #ifndef Q_SPY +#ifndef Q_SPY Q_UNUSED_PAR(qsId); - #endif +#endif QStateHandler s = me->state.fun; QStateHandler t = s; @@ -269,67 +257,39 @@ void QHsm_dispatch_( QF_CRIT_ENTRY(); Q_REQUIRE_INCRIT(300, (e != (QEvt *)0) - && (s != Q_STATE_CAST(0)) - && (me->state.uint == (uintptr_t)(~me->temp.uint))); - #ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(301, QEvt_verify_(e)); - #endif - - QS_MEM_SYS(); - QS_BEGIN_PRE(QS_QEP_DISPATCH, qsId) - QS_TIME_PRE(); // time stamp - QS_SIG_PRE(e->sig); // the signal of the event - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(s); // the current state - QS_END_PRE() - QS_MEM_APP(); - + && (s != Q_STATE_CAST(0))); QF_CRIT_EXIT(); + QS_TRAN0_(QS_QEP_DISPATCH, s); + + QState r = Q_RET_SUPER; + // process the event hierarchically... - QState r; me->temp.fun = s; - int_fast8_t ip = QHSM_MAX_NEST_DEPTH_; // fixed upper loop bound - do { + int_fast8_t ip = QHSM_MAX_NEST_DEPTH_; + // NOTE: ip is the fixed loop upper bound + for (; ip > 0; --ip) { s = me->temp.fun; r = (*s)(me, e); // invoke state handler s if (r == Q_RET_UNHANDLED) { // unhandled due to a guard? - - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_BEGIN_PRE(QS_QEP_UNHANDLED, qsId) - QS_SIG_PRE(e->sig); // the signal of the event - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(s); // the current state - QS_END_PRE() - QS_MEM_APP(); - QS_CRIT_EXIT(); - + QS_TRAN_ACT_(QS_QEP_UNHANDLED, s); r = QHSM_RESERVED_EVT_(s, Q_EMPTY_SIG); // superstate of s } - - --ip; - } while ((r == Q_RET_SUPER) && (ip > 0)); - + if (r != Q_RET_SUPER) { // event NOT "bubbled up" + break; + } + } QF_CRIT_ENTRY(); - Q_ENSURE_INCRIT(310, ip > 0); + Q_ASSERT_INCRIT(310, ip > 0); QF_CRIT_EXIT(); if (r >= Q_RET_TRAN) { // tran. (regular or history) taken? - #ifdef Q_SPY +#ifdef Q_SPY if (r == Q_RET_TRAN_HIST) { // tran. to history? - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_BEGIN_PRE(QS_QEP_TRAN_HIST, qsId) - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(s); // tran. to history source - QS_FUN_PRE(me->temp.fun); // tran. to history target - QS_END_PRE() - QS_MEM_APP(); - QS_CRIT_EXIT(); + QS_TRAN_SEG_(QS_QEP_TRAN_HIST, s, me->temp.fun); } - #endif // Q_SPY +#endif // Q_SPY QStateHandler path[QHSM_MAX_NEST_DEPTH_]; path[0] = me->temp.fun; // tran. target @@ -337,240 +297,130 @@ void QHsm_dispatch_( path[2] = s; // tran. source // exit current state to tran. source s... - ip = QHSM_MAX_NEST_DEPTH_; // fixed upper loop bound - for (; (t != s) && (ip > 0); t = me->temp.fun) { + while (t != s) { // exit from t if (QHSM_RESERVED_EVT_(t, Q_EXIT_SIG) == Q_RET_HANDLED) { - QS_STATE_EXIT_(t, qsId); + QS_STATE_ACT_(QS_QEP_STATE_EXIT, t); // find superstate of t (void)QHSM_RESERVED_EVT_(t, Q_EMPTY_SIG); } - --ip; - } - QF_CRIT_ENTRY(); - Q_ENSURE_INCRIT(320, ip > 0); - QF_CRIT_EXIT(); - - ip = QHsm_tran_(me, path, qsId); // take the tran. - - // 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) - == Q_RET_HANDLED) - { - QS_STATE_ENTRY_(path[ip], qsId); - } + t = me->temp.fun; } - t = path[0]; // stick the target into register - me->temp.fun = t; // update the next state - - // drill into the target hierarchy... - while (QHSM_RESERVED_EVT_(t, Q_INIT_SIG) == Q_RET_TRAN) { - - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_BEGIN_PRE(QS_QEP_STATE_INIT, qsId) - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(t); // the source (pseudo)state - QS_FUN_PRE(me->temp.fun); // the target of the tran. - QS_END_PRE() - QS_MEM_APP(); - QS_CRIT_EXIT(); - - ip = 0; - path[0] = me->temp.fun; - - // 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; - // find superstate - (void)QHSM_RESERVED_EVT_(me->temp.fun, Q_EMPTY_SIG); - } - QF_CRIT_ENTRY(); - // 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) - == Q_RET_HANDLED) - { - QS_STATE_ENTRY_(path[ip], qsId); - } - --ip; - } while (ip >= 0); - t = path[0]; // current state becomes the new source + // take the tran... + ip = QHsm_tran_simple_(me, &path[0], qsId); + if (ip < -1) { // not a simple tran.? + ip = QHsm_tran_complex_(me, &path[0], qsId); } - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_BEGIN_PRE(QS_QEP_TRAN, qsId) - QS_TIME_PRE(); // time stamp - QS_SIG_PRE(e->sig); // the signal of the event - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(s); // the source of the tran. - QS_FUN_PRE(t); // the new active state - QS_END_PRE() - QS_MEM_APP(); - QS_CRIT_EXIT(); + QHsm_enter_target_(me, &path[0], ip, qsId); + t = path[0]; + QS_TRAN_END_(QS_QEP_TRAN, s, t); } - - #ifdef Q_SPY +#ifdef Q_SPY else if (r == Q_RET_HANDLED) { - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_BEGIN_PRE(QS_QEP_INTERN_TRAN, qsId) - QS_TIME_PRE(); // time stamp - QS_SIG_PRE(e->sig); // the signal of the event - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(s); // the source state - QS_END_PRE() - QS_MEM_APP(); - QS_CRIT_EXIT(); + QS_TRAN0_(QS_QEP_INTERN_TRAN, s); } else { - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_BEGIN_PRE(QS_QEP_IGNORED, qsId) - QS_TIME_PRE(); // time stamp - QS_SIG_PRE(e->sig); // the signal of the event - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(me->state.fun); // the current state - QS_END_PRE() - QS_MEM_APP(); - QS_CRIT_EXIT(); + QS_TRAN0_(QS_QEP_IGNORED, me->state.fun); } - #endif // Q_SPY +#endif // Q_SPY me->state.fun = t; // change the current active state - #ifndef Q_UNSAFE - me->temp.uint = ~me->state.uint; - #endif } -//${QEP::QHsm::getStateHandler_} ............................................. -#ifdef Q_SPY -//! @private @memberof QHsm -QStateHandler QHsm_getStateHandler_(QAsm * const me) { - return me->state.fun; -} -#endif // def Q_SPY - -//${QEP::QHsm::isIn_} ........................................................ +//............................................................................ //! @private @memberof QHsm bool QHsm_isIn_( QAsm * const me, QStateHandler const state) { - QF_CRIT_STAT - QF_CRIT_ENTRY(); - 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 lbound = QHSM_MAX_NEST_DEPTH_ + 1; // fixed upper loop bound QState r = Q_RET_SUPER; - for (; (r != Q_RET_IGNORED) && (lbound > 0); --lbound) { + while (r != Q_RET_IGNORED) { if (s == state) { // do the states match? inState = true; // 'true' means that match found break; // break out of the for-loop } - else { - r = QHSM_RESERVED_EVT_(s, Q_EMPTY_SIG); - s = me->temp.fun; - } + r = QHSM_RESERVED_EVT_(s, Q_EMPTY_SIG); + s = me->temp.fun; } + return inState; // return the status +} - QF_CRIT_ENTRY(); - Q_ENSURE_INCRIT(690, lbound > 0); - QF_CRIT_EXIT(); - - #ifndef Q_UNSAFE - me->temp.uint = ~me->state.uint; - #endif +//............................................................................ +#ifdef Q_SPY +//! @private @memberof QHsm +QStateHandler QHsm_getStateHandler_(QAsm * const me) { + return me->state.fun; +} +#endif // def Q_SPY - return inState; // return the status +//............................................................................ +//! @protected @memberof QHsm +QState QHsm_top(QHsm const * const me, + QEvt const * const e) +{ + Q_UNUSED_PAR(me); + Q_UNUSED_PAR(e); + return Q_RET_IGNORED; // the top state ignores all events } -//${QEP::QHsm::childState} ................................................... +//............................................................................ //! @public @memberof QHsm QStateHandler QHsm_childState(QHsm * const me, QStateHandler const parent) { +#ifndef Q_UNSAFE + bool isFound = false; // assume the child state NOT found +#endif + QStateHandler child = me->super.state.fun; // start with current state - 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? + me->super.temp.fun = child; // establish stable state configuration + QState r = Q_RET_SUPER; + while (r != Q_RET_IGNORED) { + // have the parent of the current child? if (me->super.temp.fun == parent) { - isFound = true; // child is found - r = Q_RET_IGNORED; // break out of the loop - } - else { - child = me->super.temp.fun; - r = QHSM_RESERVED_EVT_(me->super.temp.fun, Q_EMPTY_SIG); +#ifndef Q_UNSAFE + isFound = true; // indicate that child state was found +#endif + break; } - --lbound; - } while ((r != Q_RET_IGNORED) // the top state not reached - && (lbound > 0)); - - #ifndef Q_UNSAFE - me->super.temp.uint = ~me->super.state.uint; - #else - Q_UNUSED_PAR(isFound); - #endif - + child = me->super.temp.fun; + r = QHSM_RESERVED_EVT_(child, Q_EMPTY_SIG); + } QF_CRIT_STAT QF_CRIT_ENTRY(); - // NOTE: the following postcondition can only succeed when - // (lbound > 0), so no extra check is necessary. - Q_ENSURE_INCRIT(890, isFound); + Q_ASSERT_INCRIT(590, isFound); QF_CRIT_EXIT(); return child; } -//${QEP::QHsm::tran_} ........................................................ +//............................................................................ //! @private @memberof QHsm -int_fast8_t QHsm_tran_( +static int_fast8_t QHsm_tran_simple_( QAsm * const me, QStateHandler * const path, uint_fast8_t const qsId) { - #ifndef Q_SPY +#ifndef Q_SPY Q_UNUSED_PAR(qsId); - #endif +#endif - int_fast8_t ip = -1; // tran. entry path index QStateHandler t = path[0]; QStateHandler const s = path[2]; - QF_CRIT_STAT + int_fast8_t ip = 0; // tran. entry path index + QS_CRIT_STAT // (a) check source==target (tran. to self)... if (s == t) { // exit source s if (QHSM_RESERVED_EVT_(s, Q_EXIT_SIG) == Q_RET_HANDLED) { - QS_STATE_EXIT_(s, qsId); + QS_STATE_ACT_(QS_QEP_STATE_EXIT, s); } ip = 0; // enter the target } @@ -592,128 +442,183 @@ int_fast8_t QHsm_tran_( if (me->temp.fun == t) { // exit source s if (QHSM_RESERVED_EVT_(s, Q_EXIT_SIG) == Q_RET_HANDLED) { - QS_STATE_EXIT_(s, qsId); + QS_STATE_ACT_(QS_QEP_STATE_EXIT, s); } ip = 0; // enter the target } - else { - // (d) check source->super==target... - if (me->temp.fun == path[0]) { - // exit source s - if (QHSM_RESERVED_EVT_(s, Q_EXIT_SIG) == Q_RET_HANDLED) { - QS_STATE_EXIT_(s, qsId); - } - } - else { - // (e) check rest of source==target->super->super.. - // and store the entry path along the way - int_fast8_t iq = 0; // indicate that LCA was found - ip = 1; // enter target and its superstate - path[1] = t; // save the superstate of target - 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))) - { - ++ip; - path[ip] = me->temp.fun; // store the entry path - if (me->temp.fun == s) { // is it the source? - iq = 1; // indicate that the LCA found - --ip; // do not enter the source - r = Q_RET_HANDLED; // terminate the loop - } - else { // it is not the source, keep going up - r = QHSM_RESERVED_EVT_(me->temp.fun, Q_EMPTY_SIG); - } - } - QF_CRIT_ENTRY(); - // 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? - if (iq == 0) { - // exit source s - if (QHSM_RESERVED_EVT_(s, Q_EXIT_SIG) - == Q_RET_HANDLED) - { - QS_STATE_EXIT_(s, qsId); - } - - // (f) check the rest of source->super - // == 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 - ip = iq - 1; // do not enter the LCA - iq = -1; // cause termination of the loop - } - else { - --iq; // try lower superstate of target - } - } while (iq >= 0); - - // the LCA not found yet? - if (r != Q_RET_HANDLED) { - // (g) check each source->super->... - // for each target->super... - r = Q_RET_IGNORED; // keep looping - int_fast8_t lbound = QHSM_MAX_NEST_DEPTH_; - do { - // 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); - } - t = me->temp.fun; // set to super of t - iq = ip; - do { - // is this the LCA? - if (t == path[iq]) { - ip = iq - 1; // do not enter the LCA - iq = -1; // break out of inner loop - r = Q_RET_HANDLED; // break outer loop - } - else { - --iq; - } - } while (iq >= 0); - - --lbound; - } while ((r != Q_RET_HANDLED) && (lbound > 0)); - QF_CRIT_ENTRY(); - Q_ENSURE_INCRIT(530, lbound > 0); - QF_CRIT_EXIT(); - } - } + // (d) check source->super==target... + else if (me->temp.fun == path[0]) { + // exit source s + if (QHSM_RESERVED_EVT_(s, Q_EXIT_SIG) == Q_RET_HANDLED) { + QS_STATE_ACT_(QS_QEP_STATE_EXIT, s); } + ip = -1; // do not enter the target + } + else { + path[1] = t; // save the superstate of target + ip = -2; // cause execution of complex tran. } } } + return ip; +} + +//............................................................................ +//! @private @memberof QHsm +static int_fast8_t QHsm_tran_complex_( + QAsm * const me, + QStateHandler * const path, + uint_fast8_t const qsId) +{ +#ifndef Q_SPY + Q_UNUSED_PAR(qsId); +#endif + + // (e) check rest of source==target->super->super.. + // and store the entry path along the way + int_fast8_t iq = 0; // indicate that LCA was found + int_fast8_t ip = 1; // enter target and its superstate + QStateHandler const s = path[2]; // source state + QStateHandler t = me->temp.fun; // source->super + QF_CRIT_STAT + + // 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))) { + ++ip; + path[ip] = me->temp.fun; // store the entry path + if (me->temp.fun == s) { // is it the source? + iq = 1; // indicate that the LCA found + --ip; // do not enter the source + break; // terminate the loop + } + r = QHSM_RESERVED_EVT_(me->temp.fun, Q_EMPTY_SIG); + } QF_CRIT_ENTRY(); - Q_ENSURE_INCRIT(590, ip < QHSM_MAX_NEST_DEPTH_); + Q_INVARIANT_INCRIT(711, ip < (QHSM_MAX_NEST_DEPTH_ - 1)); QF_CRIT_EXIT(); + + // the LCA not found yet? + if (iq == 0) { + + // exit source s +#ifndef Q_SPY + (void)QHSM_RESERVED_EVT_(s, Q_EXIT_SIG); +#else + if (QHSM_RESERVED_EVT_(s, Q_EXIT_SIG) == Q_RET_HANDLED) { + QS_STATE_ACT_(QS_QEP_STATE_EXIT, s); + } +#endif // def Q_SPY + + // (f) check the rest of + // source->super == 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 + ip = iq - 1; // do not enter the LCA + break; // terminate the loop + } + --iq; // try lower superstate of target + } while (iq >= 0); + + if (r != Q_RET_HANDLED) { // the LCA still not found? + // (g) check each source->super->... + // for each target->super... + r = Q_RET_SUPER; // keep looping + while (r != Q_RET_HANDLED) { + // exit from t + if (QHSM_RESERVED_EVT_(t, Q_EXIT_SIG) == Q_RET_HANDLED) { + QS_STATE_ACT_(QS_QEP_STATE_EXIT, t); + // find superstate of t + (void)QHSM_RESERVED_EVT_(t, Q_EMPTY_SIG); + } + t = me->temp.fun; // set to super of t + iq = ip; + do { + if (t == path[iq]) { // is this the LCA? + ip = iq - 1; // do not enter the LCA + r = Q_RET_HANDLED; // break outer loop + break; // terminate the inner loop + } + --iq; // try lower superstate of target + } while (iq >= 0); + } + } + } return ip; } -//${QEP::QHsm::top} .......................................................... -//! @protected @memberof QAsm -QState QHsm_top(QHsm const * const me, - QEvt const * const e) +//............................................................................ +//! @private @memberof QHsm +static void QHsm_enter_target_( + QAsm * const me, + QStateHandler * const path, + int_fast8_t const depth, + uint_fast8_t const qsId) { - Q_UNUSED_PAR(me); - Q_UNUSED_PAR(e); - return Q_RET_IGNORED; // the top state ignores all events +#ifndef Q_SPY + Q_UNUSED_PAR(qsId); +#endif + + QF_CRIT_STAT + + QF_CRIT_ENTRY(); + Q_REQUIRE_INCRIT(800, depth < QHSM_MAX_NEST_DEPTH_); + QF_CRIT_EXIT(); + + int_fast8_t ip = depth; + // 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) + == Q_RET_HANDLED) + { + QS_STATE_ACT_(QS_QEP_STATE_ENTRY, path[ip]); + } + } + QStateHandler t = path[0]; + me->temp.fun = t; // update the next state + + // drill into the target hierarchy... + while (QHSM_RESERVED_EVT_(t, Q_INIT_SIG) == Q_RET_TRAN) { + + QS_TRAN_SEG_(QS_QEP_STATE_INIT, t, me->temp.fun); + + ip = 0; + path[0] = me->temp.fun; + + // 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; + // find superstate + (void)QHSM_RESERVED_EVT_(me->temp.fun, Q_EMPTY_SIG); + } + QF_CRIT_ENTRY(); + // too many state nesting levels or "malformed" HSM + Q_INVARIANT_INCRIT(891, 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) == Q_RET_HANDLED) { + QS_STATE_ACT_(QS_QEP_STATE_ENTRY, path[ip]); + } + --ip; + } while (ip >= 0); + + t = path[0]; // current state becomes the new source + } } -//$enddef${QEP::QHsm} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/qf/qep_msm.c b/src/qf/qep_msm.c index 8c2741320..e7ab9ac5a 100644 --- a/src/qf/qep_msm.c +++ b/src/qf/qep_msm.c @@ -1,10 +1,6 @@ -//$file${src::qf::qep_msm.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// -// Model: qpc.qm -// File: ${src::qf::qep_msm.c} -// -// This code has been generated by QM 7.0.0 . -// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // @@ -14,7 +10,7 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -30,8 +26,7 @@ // Quantum Leaps contact information: // // -// -//$endhead${src::qf::qep_msm.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//============================================================================ #define QP_IMPL // this is QP implementation #include "qp_port.h" // QP port #include "qsafe.h" // QP Functional Safety (FuSa) Subsystem @@ -42,7 +37,11 @@ #include "qs_dummy.h" // disable the QS software tracing #endif // Q_SPY -//============================================================================ +enum { + // maximum depth of entry levels in a MSM for tran. to history + QMSM_MAX_ENTRY_DEPTH_ = 4 +}; + //! @cond INTERNAL Q_DEFINE_THIS_MODULE("qep_msm") @@ -55,32 +54,91 @@ static struct QMState const l_msm_top_s = { Q_ACTION_CAST(0), Q_ACTION_CAST(0) }; -//! @endcond -enum { - // maximum depth of state nesting in a QMsm (including the top level) - QMSM_MAX_NEST_DEPTH_ = 8, +#ifdef Q_SPY +// helper macro to trace state action (entry/exit) +#define QS_STATE_ACT_(rec_, state_) \ + QS_CRIT_ENTRY(); \ + QS_BEGIN_PRE((rec_), qsId) \ + QS_OBJ_PRE(me); \ + QS_FUN_PRE(state_); \ + QS_END_PRE() \ + QS_CRIT_EXIT() + +// internal helper macro to top-most init +#define QS_TOP_INIT_(rec_, trg_) \ + QS_CRIT_ENTRY(); \ + QS_BEGIN_PRE((rec_), qsId) \ + QS_TIME_PRE(); \ + QS_OBJ_PRE(me); \ + QS_FUN_PRE(trg_); \ + QS_END_PRE() \ + QS_CRIT_EXIT() + +// internal helper macro to trace transition segment +#define QS_TRAN_SEG_(rec_, src_, trg_) \ + QS_CRIT_ENTRY(); \ + QS_BEGIN_PRE((rec_), qsId) \ + QS_OBJ_PRE(me); \ + QS_FUN_PRE(src_); \ + QS_FUN_PRE(trg_); \ + QS_END_PRE() \ + QS_CRIT_EXIT() + +// internal helper macro to trace transition begin/end +#define QS_TRAN0_(rec_, trg_) \ + QS_CRIT_ENTRY(); \ + QS_BEGIN_PRE((rec_), qsId) \ + QS_TIME_PRE(); \ + QS_SIG_PRE(e->sig); \ + QS_OBJ_PRE(me); \ + QS_FUN_PRE(trg_); \ + QS_END_PRE() \ + QS_CRIT_EXIT() + +// internal helper macro to trace regular transition +#define QS_TRAN_END_(rec_, src_, trg_) \ + QS_CRIT_ENTRY(); \ + QS_BEGIN_PRE((rec_), qsId) \ + QS_TIME_PRE(); \ + QS_SIG_PRE(e->sig); \ + QS_OBJ_PRE(me); \ + QS_FUN_PRE(src_); \ + QS_FUN_PRE(trg_); \ + QS_END_PRE() \ + QS_CRIT_EXIT() - // maximum length of transition-action array - QMSM_MAX_TRAN_LENGTH_ = 2*QMSM_MAX_NEST_DEPTH_, +#else +#define QS_STATE_ACT_(rec_, state_) ((void)0) +#define QS_TOP_INIT_(rec_, trg_) ((void)0) +#define QS_TRAN_SEG_(rec_, src_, trg_) ((void)0) +#define QS_TRAN0_(rec_, trg_) ((void)0) +#define QS_TRAN_END_(rec_, src_, trg_) ((void)0) +#endif - // maximum depth of entry levels in a MSM for tran. to history - QMSM_MAX_ENTRY_DEPTH_ = 4 -}; +//! @endcond //============================================================================ +//! @private @memberof QMsm +static QState QMsm_execTatbl_( + QAsm * const me, + QMTranActTable const * const tatbl, + uint_fast8_t const qsId); -//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// Check for the minimum required QP version -#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U)%0x2710U)) -#error qpc version 7.3.0 or higher required -#endif -//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -//$define${QEP::QMsm} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +//! @private @memberof QMsm +static void QMsm_exitToTranSource_( + QAsm * const me, + QMState const * const cs, + QMState const * const ts, + uint_fast8_t const qsId); -//${QEP::QMsm} ............................................................... +//! @private @memberof QMsm +static QState QMsm_enterHistory_( + QAsm * const me, + QMState const *const hist, + uint_fast8_t const qsId); -//${QEP::QMsm::ctor} ......................................................... +//............................................................................ //! @protected @memberof QMsm void QMsm_ctor(QMsm * const me, QStateHandler const initial) @@ -89,9 +147,9 @@ void QMsm_ctor(QMsm * const me, &QMsm_init_, &QMsm_dispatch_, &QMsm_isIn_ - #ifdef Q_SPY +#ifdef Q_SPY ,&QMsm_getStateHandler_ - #endif +#endif }; // do not call the QAsm_ctor() here me->super.vptr = &vtable; @@ -99,22 +157,22 @@ void QMsm_ctor(QMsm * const me, me->super.temp.fun = initial; // the initial tran. handler } -//${QEP::QMsm::init_} ........................................................ +//............................................................................ //! @private @memberof QMsm void QMsm_init_( QAsm * const me, void const * const e, uint_fast8_t const qsId) { - #ifndef Q_SPY +#ifndef Q_SPY Q_UNUSED_PAR(qsId); - #endif +#endif QF_CRIT_STAT QF_CRIT_ENTRY(); Q_REQUIRE_INCRIT(200, (me->vptr != (struct QAsmVtable *)0) - && (me->temp.fun != Q_STATE_CAST(0)) - && (me->state.obj == &l_msm_top_s)); + && (me->temp.fun != Q_STATE_CAST(0)) + && (me->state.obj == &l_msm_top_s)); QF_CRIT_EXIT(); // execute the top-most initial tran. @@ -123,56 +181,33 @@ void QMsm_init_( QF_CRIT_ENTRY(); // the top-most initial tran. must be taken Q_ASSERT_INCRIT(210, r == Q_RET_TRAN_INIT); - - QS_MEM_SYS(); - QS_BEGIN_PRE(QS_QEP_STATE_INIT, qsId) - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(me->state.obj->stateHandler); // source state - QS_FUN_PRE(me->temp.tatbl->target->stateHandler); // target state - QS_END_PRE() - QS_MEM_APP(); - QF_CRIT_EXIT(); + QS_TRAN_SEG_(QS_QEP_STATE_INIT, + me->state.obj->stateHandler, me->temp.tatbl->target->stateHandler); + // set state to the last tran. target me->state.obj = me->temp.tatbl->target; // drill down into the state hierarchy with initial transitions... - int_fast8_t lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound - do { + while (r >= Q_RET_TRAN_INIT) { // execute the tran. table r = QMsm_execTatbl_(me, me->temp.tatbl, qsId); - --lbound; - } while ((r >= Q_RET_TRAN_INIT) && (lbound > 0)); - - QF_CRIT_ENTRY(); - Q_ENSURE_INCRIT(290, lbound > 0); - - QS_MEM_SYS(); - QS_BEGIN_PRE(QS_QEP_INIT_TRAN, qsId) - QS_TIME_PRE(); // time stamp - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(me->state.obj->stateHandler); // the new current state - QS_END_PRE() - QS_MEM_APP(); - - QF_CRIT_EXIT(); + } - #ifndef Q_UNSAFE - me->temp.uint = ~me->state.uint; - #endif + QS_TOP_INIT_(QS_QEP_INIT_TRAN, me->state.obj->stateHandler); } -//${QEP::QMsm::dispatch_} .................................................... +//............................................................................ //! @private @memberof QMsm void QMsm_dispatch_( QAsm * const me, QEvt const * const e, uint_fast8_t const qsId) { - #ifndef Q_SPY +#ifndef Q_SPY Q_UNUSED_PAR(qsId); - #endif +#endif QMState const *s = me->state.obj; // store the current state QMState const *t = s; @@ -181,59 +216,32 @@ void QMsm_dispatch_( QF_CRIT_ENTRY(); Q_REQUIRE_INCRIT(300, (e != (QEvt *)0) - && (s != (QMState *)0) - && (me->state.uint == (uintptr_t)(~me->temp.uint))); - #ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(301, QEvt_verify_(e)); - #endif - - QS_MEM_SYS(); - QS_BEGIN_PRE(QS_QEP_DISPATCH, qsId) - QS_TIME_PRE(); // time stamp - QS_SIG_PRE(e->sig); // the signal of the event - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(s->stateHandler); // the current state handler - QS_END_PRE() - QS_MEM_APP(); - + && (s != (QMState *)0)); QF_CRIT_EXIT(); + QS_TRAN0_(QS_QEP_DISPATCH, s->stateHandler); + // scan the state hierarchy up to the top state... - QState r; - int_fast8_t lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound - do { + QState r = Q_RET_SUPER; + while (t != (QMState *)0) { r = (*t->stateHandler)(me, e); // call state handler function - // event handled? (the most frequent case) - if (r >= Q_RET_HANDLED) { + if (r >= Q_RET_HANDLED) { // event handled? (the most frequent case) break; // done scanning the state hierarchy } - // event unhandled and passed to the superstate? - else if (r == Q_RET_SUPER) { - t = t->superstate; // advance to the superstate - } - else { // event unhandled due to a guard - QF_CRIT_ENTRY(); - // event must be unhandled due to a guard evaluating to 'false' - Q_ASSERT_INCRIT(310, r == Q_RET_UNHANDLED); - - QS_MEM_SYS(); +#ifdef Q_SPY + if (r == Q_RET_UNHANDLED) { // event unhandled due to a guard? + QS_CRIT_ENTRY(); QS_BEGIN_PRE(QS_QEP_UNHANDLED, qsId) - QS_SIG_PRE(e->sig); // the signal of the event - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(t->stateHandler); // the current state + QS_SIG_PRE(e->sig); + QS_OBJ_PRE(me); + QS_FUN_PRE(t->stateHandler); QS_END_PRE() - QS_MEM_APP(); - - QF_CRIT_EXIT(); - - t = t->superstate; // advance to the superstate + QS_CRIT_EXIT(); } - --lbound; - } while ((t != (QMState *)0) && (lbound > 0)); - QF_CRIT_ENTRY(); - Q_ENSURE_INCRIT(320, lbound > 0); - QF_CRIT_EXIT(); +#endif + t = t->superstate; // advance to the superstate + } if (r >= Q_RET_TRAN) { // any kind of tran. taken? QF_CRIT_ENTRY(); @@ -241,27 +249,19 @@ void QMsm_dispatch_( Q_ASSERT_INCRIT(330, t != (QMState *)0); QF_CRIT_EXIT(); - #ifdef Q_SPY +#ifdef Q_SPY QMState const * const ts = t; // tran. source for QS tracing - #endif // Q_SPY - struct QMTranActTable const *tatbl; // for saving tran. table +#endif // Q_SPY if (r == Q_RET_TRAN_HIST) { // was it tran. to history? QMState const * const hist = me->state.obj; // save history me->state.obj = s; // restore the original state - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_BEGIN_PRE(QS_QEP_TRAN_HIST, qsId) - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(t->stateHandler); // source state handler - QS_FUN_PRE(hist->stateHandler); // target state handler - QS_END_PRE() - QS_MEM_APP(); - QS_CRIT_EXIT(); + QS_TRAN_SEG_(QS_QEP_TRAN_HIST, + t->stateHandler, hist->stateHandler); // save the tran-action table before it gets clobbered - tatbl = me->temp.tatbl; + struct QMTranActTable const * const tatbl = me->temp.tatbl; QMsm_exitToTranSource_(me, s, t, qsId); (void)QMsm_execTatbl_(me, tatbl, qsId); r = QMsm_enterHistory_(me, hist, qsId); @@ -269,76 +269,37 @@ void QMsm_dispatch_( t = s; // set target to the current state } - lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound - while ((r >= Q_RET_TRAN) && (lbound > 0)) { + while (r >= Q_RET_TRAN) { // save the tran-action table before it gets clobbered - tatbl = me->temp.tatbl; + struct QMTranActTable const * const tatbl = me->temp.tatbl; me->temp.obj = (QMState *)0; // clear QMsm_exitToTranSource_(me, s, t, qsId); r = QMsm_execTatbl_(me, tatbl, qsId); s = me->state.obj; t = s; // set target to the current state - --lbound; } - QF_CRIT_ENTRY(); - Q_ENSURE_INCRIT(360, lbound > 0); - - QS_MEM_SYS(); - QS_BEGIN_PRE(QS_QEP_TRAN, qsId) - QS_TIME_PRE(); // time stamp - QS_SIG_PRE(e->sig); // the signal of the event - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(ts->stateHandler); // the tran. source - QS_FUN_PRE(s->stateHandler); // the new active state - QS_END_PRE() - QS_MEM_APP(); - - QF_CRIT_EXIT(); + QS_TRAN_END_(QS_QEP_TRAN, ts->stateHandler, s->stateHandler); } - - #ifdef Q_SPY - // was the event handled? - else if (r == Q_RET_HANDLED) { +#ifdef Q_SPY + else if (r == Q_RET_HANDLED) { // was the event handled? QF_CRIT_ENTRY(); // internal tran. source can't be NULL Q_ASSERT_INCRIT(380, t != (QMState *)0); - - QS_MEM_SYS(); - QS_BEGIN_PRE(QS_QEP_INTERN_TRAN, qsId) - QS_TIME_PRE(); // time stamp - QS_SIG_PRE(e->sig); // the signal of the event - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(t->stateHandler); // the source state - QS_END_PRE() - QS_MEM_APP(); - QF_CRIT_EXIT(); + + QS_TRAN0_(QS_QEP_INTERN_TRAN, t->stateHandler); } - // event bubbled to the 'top' state? - else if (t == (QMState *)0) { - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_BEGIN_PRE(QS_QEP_IGNORED, qsId) - QS_TIME_PRE(); // time stamp - QS_SIG_PRE(e->sig); // the signal of the event - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(s->stateHandler); // the current state - QS_END_PRE() - QS_MEM_APP(); - QS_CRIT_EXIT(); + else if (t == (QMState *)0) { // event bubbled to the 'top' state? + QS_TRAN0_(QS_QEP_IGNORED, s->stateHandler); } - #endif // Q_SPY +#endif // Q_SPY else { // empty } - - #ifndef Q_UNSAFE - me->temp.uint = ~me->state.uint; - #endif } -//${QEP::QMsm::isIn_} ........................................................ +//............................................................................ //! @private @memberof QMsm bool QMsm_isIn_( QAsm * const me, @@ -347,136 +308,96 @@ bool QMsm_isIn_( bool inState = false; // assume that this SM is not in 'state' QMState const *s = me->state.obj; - int_fast8_t lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound - for (; (s != (QMState *)0) && (lbound > 0); --lbound) { + while (s != (QMState *)0) { if (s->stateHandler == state) { // match found? inState = true; break; } - else { - s = s->superstate; // advance to the superstate - } + s = s->superstate; // advance to the superstate } - QF_CRIT_STAT - QF_CRIT_ENTRY(); - Q_ENSURE_INCRIT(490, lbound > 0); - QF_CRIT_EXIT(); - return inState; } -//${QEP::QMsm::childStateObj} ................................................ +//............................................................................ +#ifdef Q_SPY +//! @public @memberof QMsm +QStateHandler QMsm_getStateHandler_(QAsm * const me) { + return me->state.obj->stateHandler; +} +#endif // def Q_SPY + +//............................................................................ //! @public @memberof QMsm QMState const * QMsm_childStateObj(QMsm const * const me, QMState const * const parent) { - QMState const *child = me->super.state.obj; - bool isFound = false; // start with the child not found - QMState const *s; - - int_fast8_t lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound - for (s = me->super.state.obj; - (s != (QMState *)0) && (lbound > 0); - s = s->superstate) - { + QMState const *s = me->super.state.obj; // start with current state + QMState const *child = s; + bool isFound = false; // assume the child NOT found + + while (s != (QMState *)0) { if (s == parent) { isFound = true; // child is found break; } - else { - child = s; - } - --lbound; + child = s; + s = s->superstate; } QF_CRIT_STAT QF_CRIT_ENTRY(); - Q_ENSURE_INCRIT(680, lbound > 0); + Q_ASSERT_INCRIT(590, isFound); QF_CRIT_EXIT(); - if (!isFound) { // still not found? - lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound - for (s = me->super.temp.obj; - (s != (QMState *)0) && (lbound > 0); - s = s->superstate) - { - if (s == parent) { - isFound = true; // child is found - break; - } - else { - child = s; - } - --lbound; - } - } - - QF_CRIT_ENTRY(); - // NOTE: the following postcondition can only succeed when - // (lbound > 0), so no extra check is necessary. - Q_ENSURE_INCRIT(690, isFound); - QF_CRIT_EXIT(); +#ifdef Q_UNSAFE + Q_UNUSED_PAR(isFound); +#endif return child; // return the child } -//${QEP::QMsm::execTatbl_} ................................................... +//............................................................................ //! @private @memberof QMsm -QState QMsm_execTatbl_( +static QState QMsm_execTatbl_( QAsm * const me, QMTranActTable const * const tatbl, uint_fast8_t const qsId) { - #ifndef Q_SPY +#ifndef Q_SPY Q_UNUSED_PAR(qsId); - #endif +#endif QF_CRIT_STAT QF_CRIT_ENTRY(); // precondition: // - the tran-action table pointer must not be NULL - Q_REQUIRE_INCRIT(700, tatbl != (struct QMTranActTable *)0); + Q_REQUIRE_INCRIT(600, tatbl != (struct QMTranActTable *)0); QF_CRIT_EXIT(); QState r = Q_RET_NULL; - int_fast8_t lbound = QMSM_MAX_TRAN_LENGTH_; // fixed upper loop bound QActionHandler const *a = &tatbl->act[0]; - for (; (*a != Q_ACTION_CAST(0)) && (lbound > 0); ++a) { + while (*a != Q_ACTION_CAST(0)) { r = (*(*a))(me); // call the action through the 'a' pointer - --lbound; - #ifdef Q_SPY - QS_CRIT_ENTRY(); - QS_MEM_SYS(); + ++a; +#ifdef Q_SPY if (r == Q_RET_ENTRY) { - QS_BEGIN_PRE(QS_QEP_STATE_ENTRY, qsId) - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(me->temp.obj->stateHandler); // entered state - QS_END_PRE() + QS_STATE_ACT_(QS_QEP_STATE_ENTRY, me->temp.obj->stateHandler); } else if (r == Q_RET_EXIT) { - QS_BEGIN_PRE(QS_QEP_STATE_EXIT, qsId) - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(me->temp.obj->stateHandler); // exited state - QS_END_PRE() + QS_STATE_ACT_(QS_QEP_STATE_EXIT, me->temp.obj->stateHandler); } else if (r == Q_RET_TRAN_INIT) { - QS_BEGIN_PRE(QS_QEP_STATE_INIT, qsId) - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(tatbl->target->stateHandler); // source - QS_FUN_PRE(me->temp.tatbl->target->stateHandler); // target - QS_END_PRE() + QS_TRAN_SEG_(QS_QEP_STATE_INIT, + tatbl->target->stateHandler, + me->temp.tatbl->target->stateHandler); } else { // empty } - QS_MEM_APP(); - QS_CRIT_EXIT(); - #endif // Q_SPY +#endif // Q_SPY } 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)); + Q_ASSERT_INCRIT(690, *a == Q_ACTION_CAST(0)); QF_CRIT_EXIT(); me->state.obj = (r >= Q_RET_TRAN) @@ -485,62 +406,49 @@ QState QMsm_execTatbl_( return r; } -//${QEP::QMsm::exitToTranSource_} ............................................ +//............................................................................ //! @private @memberof QMsm -void QMsm_exitToTranSource_( +static void QMsm_exitToTranSource_( QAsm * const me, QMState const * const cs, QMState const * const ts, uint_fast8_t const qsId) { - #ifndef Q_SPY +#ifndef Q_SPY Q_UNUSED_PAR(qsId); - #endif - - QF_CRIT_STAT +#endif + QS_CRIT_STAT // exit states from the current state to the tran. source state QMState const *s = cs; - int_fast8_t lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound - for (; (s != ts) && (lbound > 0); --lbound) { + while (s != ts) { // exit action provided in state 's'? if (s->exitAction != Q_ACTION_CAST(0)) { // execute the exit action (void)(*s->exitAction)(me); - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_BEGIN_PRE(QS_QEP_STATE_EXIT, qsId) - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(s->stateHandler); // the exited state handler - QS_END_PRE() - QS_MEM_APP(); - QS_CRIT_EXIT(); + QS_STATE_ACT_(QS_QEP_STATE_EXIT, me->temp.obj->stateHandler); } - s = s->superstate; // advance to the superstate } - QF_CRIT_ENTRY(); - Q_ENSURE_INCRIT(890, lbound > 0); - QF_CRIT_EXIT(); } -//${QEP::QMsm::enterHistory_} ................................................ +//............................................................................ //! @private @memberof QMsm -QState QMsm_enterHistory_( +static QState QMsm_enterHistory_( QAsm * const me, QMState const *const hist, uint_fast8_t const qsId) { - #ifndef Q_SPY +#ifndef Q_SPY Q_UNUSED_PAR(qsId); - #endif +#endif // record the entry path from current state to history QMState const *epath[QMSM_MAX_ENTRY_DEPTH_]; QMState const *s = hist; - int_fast8_t i = 0; // tran. entry path index - while ((s != me->state.obj) && (i < (QMSM_MAX_ENTRY_DEPTH_ - 1))) { + int_fast8_t i = 0; // tran. entry path index & fixed upper loop bound + while ((s != me->state.obj) && (i < QMSM_MAX_ENTRY_DEPTH_)) { if (s->entryAction != Q_ACTION_CAST(0)) { epath[i] = s; ++i; @@ -549,44 +457,28 @@ QState QMsm_enterHistory_( } QF_CRIT_STAT QF_CRIT_ENTRY(); - Q_ASSERT_INCRIT(910, s == me->state.obj); + Q_ASSERT_INCRIT(810, i <= QMSM_MAX_ENTRY_DEPTH_); QF_CRIT_EXIT(); // retrace the entry path in reverse (desired) order... - while (i > 0) { - --i; - (void)(*epath[i]->entryAction)(me); // run entry action in epath[i] - - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_BEGIN_PRE(QS_QEP_STATE_ENTRY, qsId) - QS_OBJ_PRE(me); - QS_FUN_PRE(epath[i]->stateHandler); // entered state handler - QS_END_PRE() - QS_MEM_APP(); - QS_CRIT_EXIT(); + // NOTE: i the fixed upper loop bound + for (i = i - 1; i >= 0; --i) { + // run entry action in epath[i] + (void)(*epath[i]->entryAction)(me); + + QS_STATE_ACT_(QS_QEP_STATE_ENTRY, epath[i]->stateHandler); } me->state.obj = hist; // set current state to the tran. target // initial tran. present? - QState r; + QState r = Q_RET_NULL; if (hist->initAction != Q_ACTION_CAST(0)) { r = (*hist->initAction)(me); // execute the tran. action - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_BEGIN_PRE(QS_QEP_STATE_INIT, qsId) - QS_OBJ_PRE(me); // this state machine object - QS_FUN_PRE(hist->stateHandler); // source - QS_FUN_PRE(me->temp.tatbl->target->stateHandler); // target - QS_END_PRE() - QS_MEM_APP(); - QS_CRIT_EXIT(); - } - else { - r = Q_RET_NULL; - } + QS_TRAN_SEG_(QS_QEP_STATE_INIT, + hist->stateHandler, me->temp.tatbl->target->stateHandler); + } return r; } -//$enddef${QEP::QMsm} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + diff --git a/src/qf/qf_act.c b/src/qf/qf_act.c index fa8525efc..c50f1e5d3 100644 --- a/src/qf/qf_act.c +++ b/src/qf/qf_act.c @@ -1,10 +1,6 @@ -//$file${src::qf::qf_act.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// -// Model: qpc.qm -// File: ${src::qf::qf_act.c} -// -// This code has been generated by QM 7.0.0 . -// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // @@ -14,7 +10,7 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -30,8 +26,7 @@ // Quantum Leaps contact information: // // -// -//$endhead${src::qf::qf_act.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//============================================================================ #define QP_IMPL // this is QP implementation #include "qp_port.h" // QP port #include "qp_pkg.h" // QP package-scope interface @@ -45,23 +40,15 @@ //Q_DEFINE_THIS_MODULE("qf_act") -//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// Check for the minimum required QP version -#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U)%0x2710U)) -#error qpc version 7.3.0 or higher required -#endif -//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -//$define${QF::QActive::registry_[QF_MAX_ACTIVE + 1U]} vvvvvvvvvvvvvvvvvvvvvvv -//! @static @private @memberof QActive -QActive * QActive_registry_[QF_MAX_ACTIVE + 1U]; -//$enddef${QF::QActive::registry_[QF_MAX_ACTIVE + 1U]} ^^^^^^^^^^^^^^^^^^^^^^^ - -//$define${QF::QF-pkg} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +// QP version string embedded in the binary image +char const QP_versionStr[24] = "QP/C " QP_VERSION_STR; -//${QF::QF-pkg::priv_} ....................................................... QF_Attr QF_priv_; -//${QF::QF-pkg::bzero_} ...................................................... +//! @static @private @memberof QActive +QActive * QActive_registry_[QF_MAX_ACTIVE + 1U]; + +//............................................................................ //! @static @private @memberof QF void QF_bzero_( void * const start, @@ -73,11 +60,8 @@ void QF_bzero_( ++ptr; } } -//$enddef${QF::QF-pkg} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -//$define${QF::types::QF_LOG2} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QF::types::QF_LOG2} ...................................................... +//............................................................................ #ifndef QF_LOG2 uint_fast8_t QF_LOG2(QPSetBits const bitmask) { static uint8_t const log2LUT[16] = { @@ -85,23 +69,23 @@ uint_fast8_t QF_LOG2(QPSetBits const bitmask) { 4U, 4U, 4U, 4U, 4U, 4U, 4U, 4U }; uint_fast8_t n = 0U; - QPSetBits tmp; QPSetBits x = bitmask; + QPSetBits tmp; - #if (QF_MAX_ACTIVE > 16U) +#if (QF_MAX_ACTIVE > 16U) tmp = (x >> 16U); if (tmp != 0U) { n += 16U; x = tmp; } - #endif - #if (QF_MAX_ACTIVE > 8U) +#endif +#if (QF_MAX_ACTIVE > 8U) tmp = (x >> 8U); if (tmp != 0U) { n += 8U; x = tmp; } - #endif +#endif tmp = (x >> 4U); if (tmp != 0U) { n += 4U; @@ -110,4 +94,3 @@ uint_fast8_t QF_LOG2(QPSetBits const bitmask) { return n + log2LUT[x]; } #endif // ndef QF_LOG2 -//$enddef${QF::types::QF_LOG2} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/qf/qf_actq.c b/src/qf/qf_actq.c index ec2ad98e6..ff9012201 100644 --- a/src/qf/qf_actq.c +++ b/src/qf/qf_actq.c @@ -1,10 +1,6 @@ -//$file${src::qf::qf_actq.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// -// Model: qpc.qm -// File: ${src::qf::qf_actq.c} -// -// This code has been generated by QM 7.0.0 . -// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // @@ -14,7 +10,7 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -30,8 +26,7 @@ // Quantum Leaps contact information: // // -// -//$endhead${src::qf::qf_actq.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//============================================================================ #define QP_IMPL // this is QP implementation #include "qp_port.h" // QP port #include "qp_pkg.h" // QP package-scope interface @@ -45,317 +40,176 @@ Q_DEFINE_THIS_MODULE("qf_actq") -//============================================================================ -//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// Check for the minimum required QP version -#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U)%0x2710U)) -#error qpc version 7.3.0 or higher required -#endif -//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -//$define${QF::QActive::post_} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +//............................................................................ +//! @private @memberof QActive +static void QActive_postFIFO_(QActive * const me, + QEvt const * const e, + void const * const sender); -//${QF::QActive::post_} ...................................................... +//............................................................................ //! @private @memberof QActive bool QActive_post_(QActive * const me, QEvt const * const e, uint_fast16_t const margin, void const * const sender) { - #ifndef Q_SPY - Q_UNUSED_PAR(sender); - #endif - - #ifdef Q_UTEST // test? - #if (Q_UTEST != 0) // testing QP-stub? +#ifdef Q_UTEST // test? +#if (Q_UTEST != 0) // testing QP-stub? if (me->super.temp.fun == Q_STATE_CAST(0)) { // QActiveDummy? return QActiveDummy_fakePost_(me, e, margin, sender); } - #endif // (Q_UTEST != 0) - #endif // def Q_UTEST +#endif // (Q_UTEST != 0) +#endif // def Q_UTEST QF_CRIT_STAT QF_CRIT_ENTRY(); - QF_MEM_SYS(); Q_REQUIRE_INCRIT(200, e != (QEvt *)0); - QEQueueCtr tmp = me->eQueue.nFree; // get volatile into temporary - #ifndef Q_UNSAFE - QEQueueCtr dis = (QEQueueCtr)~me->eQueue.nFree_dis; - Q_INVARIANT_INCRIT(201, (QEvt_verify_(e)) && (tmp == dis)); - #endif // ndef Q_UNSAFE - - // test-probe#1 for faking queue overflow - QS_TEST_PROBE_DEF(&QActive_post_) - QS_TEST_PROBE_ID(1, - tmp = 0U; // fake no free events - ) + QEQueueCtr const nFree = me->eQueue.nFree; // get volatile into temporary // required margin available? - bool status; + bool status = false; // assume that event cannot be posted if (margin == QF_NO_MARGIN) { - if (tmp > 0U) { // free entries available in the queue? + if (nFree > 0U) { // free entries available in the queue? status = true; // can post } else { // no free entries available - status = false; // cannot post - // The queue overflows, but QF_NO_MARGIN indicates that // the "event delivery guarantee" is required. Q_ERROR_INCRIT(210); // must be able to post the event } } - else if (tmp > (QEQueueCtr)margin) { // enough free entries? + else if (nFree > (QEQueueCtr)margin) { // enough free entries? status = true; // can post } - else { // the # free entries below the requested margin - status = false; // cannot post, but don't assert + else { + // empty } - // is it a mutable event? - if (QEvt_getPoolNum_(e) != 0U) { +#if (QF_MAX_EPOOL > 0U) + if (e->poolNum_ != 0U) { // is it a mutable event? + Q_ASSERT_INCRIT(205, e->refCtr_ < (2U * QF_MAX_ACTIVE)); QEvt_refCtr_inc_(e); // increment the reference counter } +#endif // (QF_MAX_EPOOL > 0U) if (status) { // can post the event? - --tmp; // one free entry just used up - - me->eQueue.nFree = tmp; // update the original - #ifndef Q_UNSAFE - me->eQueue.nFree_dis = (QEQueueCtr)~tmp; // update the DIS - - if (me->eQueue.nMin > tmp) { - me->eQueue.nMin = tmp; // update minimum so far - } - #endif // ndef Q_UNSAFE - - QS_BEGIN_PRE(QS_QF_ACTIVE_POST, me->prio) - QS_TIME_PRE(); // timestamp - QS_OBJ_PRE(sender); // the sender object - QS_SIG_PRE(e->sig); // the signal of the event - QS_OBJ_PRE(me); // this active object (recipient) - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); - QS_EQC_PRE(tmp); // # free entries - #ifndef Q_UNSAFE - QS_EQC_PRE(me->eQueue.nMin); // min # free entries - #else - QS_EQC_PRE(0U); // min # free entries - #endif - QS_END_PRE() - - #ifdef Q_UTEST - // callback to examine the posted event under the same conditions - // as producing the #QS_QF_ACTIVE_POST trace record, which are: - // the local filter for this AO ('me->prio') is set - if (QS_LOC_CHECK_(me->prio)) { - QF_MEM_APP(); - QF_CRIT_EXIT(); - - QS_onTestPost(sender, me, e, status); - - QF_CRIT_ENTRY(); - QF_MEM_SYS(); - } - #endif // def Q_UTEST - - if (me->eQueue.frontEvt == (QEvt *)0) { // is the queue empty? - me->eQueue.frontEvt = e; // deliver event directly - #ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(211, me->eQueue.frontEvt_dis - == (uintptr_t)~Q_PTR2UINT_CAST_((QEvt *)0)); - me->eQueue.frontEvt_dis = (uintptr_t)~Q_PTR2UINT_CAST_(e); - #endif // ndef Q_UNSAFE - - #ifdef QXK_H_ - if (me->super.state.act == Q_ACTION_CAST(0)) { // eXtended? - QXTHREAD_EQUEUE_SIGNAL_(me); // signal eXtended Thread - } - else { - QACTIVE_EQUEUE_SIGNAL_(me); // signal the Active Object - } - #else - QACTIVE_EQUEUE_SIGNAL_(me); // signal the Active Object - #endif // def QXK_H_ - } - else { // queue was not empty, insert event into the ring-buffer - tmp = me->eQueue.head; // get volatile into temporary - #ifndef Q_UNSAFE - dis = (QEQueueCtr)~me->eQueue.head_dis; - Q_INVARIANT_INCRIT(212, tmp == dis); - #endif // ndef Q_UNSAFE - me->eQueue.ring[tmp] = e; // insert e into buffer - - if (tmp == 0U) { // need to wrap the head? - tmp = me->eQueue.end; - } - --tmp; // advance the head (counter-clockwise) - - me->eQueue.head = tmp; // update the original - #ifndef Q_UNSAFE - me->eQueue.head_dis = (QEQueueCtr)~tmp; - #endif // ndef Q_UNSAFE - } - - QF_MEM_APP(); + QActive_postFIFO_(me, e, sender); QF_CRIT_EXIT(); } else { // event cannot be posted - QS_BEGIN_PRE(QS_QF_ACTIVE_POST_ATTEMPT, me->prio) QS_TIME_PRE(); // timestamp QS_OBJ_PRE(sender); // the sender object QS_SIG_PRE(e->sig); // the signal of the event QS_OBJ_PRE(me); // this active object (recipient) - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); - QS_EQC_PRE(tmp); // # free entries + QS_2U8_PRE(e->poolNum_, e->refCtr_); + QS_EQC_PRE(nFree); // # free entries QS_EQC_PRE(margin); // margin requested QS_END_PRE() - #ifdef Q_UTEST - // callback to examine the posted event under the same conditions - // as producing the #QS_QF_ACTIVE_POST trace record, which are: - // the local filter for this AO ('me->prio') is set +#ifdef Q_UTEST if (QS_LOC_CHECK_(me->prio)) { - QF_MEM_APP(); QF_CRIT_EXIT(); - - QS_onTestPost(sender, me, e, status); - + QS_onTestPost(sender, me, e, status); // QUTEst callback QF_CRIT_ENTRY(); - QF_MEM_SYS(); } - #endif // def Q_USTEST +#endif // def Q_USTEST - QF_MEM_APP(); QF_CRIT_EXIT(); - #if (QF_MAX_EPOOL > 0U) +#if (QF_MAX_EPOOL > 0U) QF_gc(e); // recycle the event to avoid a leak - #endif // (QF_MAX_EPOOL > 0U) +#endif // (QF_MAX_EPOOL > 0U) } return status; } -//$enddef${QF::QActive::post_} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -//$define${QF::QActive::postLIFO_} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -//${QF::QActive::postLIFO_} .................................................. +//............................................................................ //! @private @memberof QActive void QActive_postLIFO_(QActive * const me, QEvt const * const e) { - #ifdef Q_UTEST // test? - #if (Q_UTEST != 0) // testing QP-stub? +#ifdef Q_UTEST // test? +#if (Q_UTEST != 0) // testing QP-stub? if (me->super.temp.fun == Q_STATE_CAST(0)) { // QActiveDummy? QActiveDummy_fakePostLIFO_(me, e); return; } - #endif // (Q_UTEST != 0) - #endif // def Q_UTEST +#endif // (Q_UTEST != 0) +#endif // def Q_UTEST QF_CRIT_STAT QF_CRIT_ENTRY(); - QF_MEM_SYS(); // the posted event must be be valid (which includes not NULL) Q_REQUIRE_INCRIT(300, e != (QEvt *)0); QEQueueCtr tmp = me->eQueue.nFree; // get volatile into temporary - #ifndef Q_UNSAFE - QEQueueCtr dis = (QEQueueCtr)~me->eQueue.nFree_dis; - Q_INVARIANT_INCRIT(301, (QEvt_verify_(e)) && (tmp == dis)); - #endif // ndef Q_UNSAFE - - // test-probe#1 for faking queue overflow - QS_TEST_PROBE_DEF(&QActive_postLIFO_) - QS_TEST_PROBE_ID(1, - tmp = 0U; // fake no free events - ) // The queue must NOT overflow for the LIFO posting policy. Q_REQUIRE_INCRIT(310, tmp != 0U); - if (QEvt_getPoolNum_(e) != 0U) { // is it a mutable event? + if (e->poolNum_ != 0U) { // is it a mutable event? + Q_ASSERT_INCRIT(305, e->refCtr_ < (2U * QF_MAX_ACTIVE)); QEvt_refCtr_inc_(e); // increment the reference counter } --tmp; // one free entry just used up me->eQueue.nFree = tmp; // update the original - #ifndef Q_UNSAFE - me->eQueue.nFree_dis = (QEQueueCtr)~tmp; - if (me->eQueue.nMin > tmp) { me->eQueue.nMin = tmp; // update minimum so far } - #endif // ndef Q_UNSAFE QS_BEGIN_PRE(QS_QF_ACTIVE_POST_LIFO, me->prio) QS_TIME_PRE(); // timestamp QS_SIG_PRE(e->sig); // the signal of this event QS_OBJ_PRE(me); // this active object - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_2U8_PRE(e->poolNum_, e->refCtr_); QS_EQC_PRE(tmp); // # free entries - #ifndef Q_UNSAFE QS_EQC_PRE(me->eQueue.nMin); // min # free entries - #else - QS_EQC_PRE(0U); // min # free entries - #endif QS_END_PRE() - #ifdef Q_UTEST +#ifdef Q_UTEST // callback to examine the posted event under the same conditions // as producing the #QS_QF_ACTIVE_POST trace record, which are: // the local filter for this AO ('me->prio') is set if (QS_LOC_CHECK_(me->prio)) { - QF_MEM_APP(); QF_CRIT_EXIT(); QS_onTestPost((QActive *)0, me, e, true); QF_CRIT_ENTRY(); - QF_MEM_SYS(); } - #endif // def Q_UTEST +#endif // def Q_UTEST QEvt const * const frontEvt = me->eQueue.frontEvt; me->eQueue.frontEvt = e; // deliver the event directly to the front - #ifndef Q_UNSAFE - me->eQueue.frontEvt_dis = (uintptr_t)~Q_PTR2UINT_CAST_(e); - #endif // ndef Q_UNSAFE if (frontEvt != (QEvt *)0) { // was the queue NOT empty? tmp = me->eQueue.tail; // get volatile into temporary; - #ifndef Q_UNSAFE - dis = (QEQueueCtr)~me->eQueue.tail_dis; - Q_INVARIANT_INCRIT(311, tmp == dis); - #endif // ndef Q_UNSAFE ++tmp; if (tmp == me->eQueue.end) { // need to wrap the tail? tmp = 0U; // wrap around } me->eQueue.tail = tmp; - #ifndef Q_UNSAFE - me->eQueue.tail_dis = (QEQueueCtr)~tmp; - #endif // ndef Q_UNSAFE me->eQueue.ring[tmp] = frontEvt; } else { // queue was empty QACTIVE_EQUEUE_SIGNAL_(me); // signal the event queue } - QF_MEM_APP(); QF_CRIT_EXIT(); } -//$enddef${QF::QActive::postLIFO_} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -//$define${QF::QActive::get_} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -//${QF::QActive::get_} ....................................................... +//............................................................................ //! @private @memberof QActive QEvt const * QActive_get_(QActive * const me) { QF_CRIT_STAT QF_CRIT_ENTRY(); - QF_MEM_SYS(); // wait for event to arrive directly (depends on QP port) // NOTE: might use assertion-IDs 400-409 @@ -365,20 +219,11 @@ QEvt const * QActive_get_(QActive * const me) { QEvt const * const e = me->eQueue.frontEvt; QEQueueCtr tmp = me->eQueue.nFree; // get volatile into temporary - #ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(410, e != (QEvt *)0); // queue must NOT be empty - Q_INVARIANT_INCRIT(411, Q_PTR2UINT_CAST_(e) - == (uintptr_t)~me->eQueue.frontEvt_dis); - QEQueueCtr dis = (QEQueueCtr)~me->eQueue.nFree_dis; - Q_INVARIANT_INCRIT(412, tmp == dis); - #endif // ndef Q_UNSAFE + Q_REQUIRE_INCRIT(410, e != (QEvt *)0); // queue must NOT be empty ++tmp; // one more free event in the queue me->eQueue.nFree = tmp; // update the # free - #ifndef Q_UNSAFE - me->eQueue.nFree_dis = (QEQueueCtr)~tmp; - #endif // ndef Q_UNSAFE if (tmp <= me->eQueue.end) { // any events in the ring buffer? @@ -386,21 +231,15 @@ QEvt const * QActive_get_(QActive * const me) { QS_TIME_PRE(); // timestamp QS_SIG_PRE(e->sig); // the signal of this event QS_OBJ_PRE(me); // this active object - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_2U8_PRE(e->poolNum_, e->refCtr_); QS_EQC_PRE(tmp); // # free entries QS_END_PRE() // remove event from the tail tmp = me->eQueue.tail; // get volatile into temporary - #ifndef Q_UNSAFE - dis = (QEQueueCtr)~me->eQueue.tail_dis; - Q_INVARIANT_INCRIT(420, tmp == dis); - #endif // ndef Q_UNSAFE QEvt const * const frontEvt = me->eQueue.ring[tmp]; - #ifndef Q_UNSAFE - Q_ASSERT_INCRIT(421, frontEvt != (QEvt *)0); - me->eQueue.frontEvt_dis = (uintptr_t)~Q_PTR2UINT_CAST_(frontEvt); - #endif // ndef Q_UNSAFE + + Q_ASSERT_INCRIT(430, frontEvt != (QEvt *)0); me->eQueue.frontEvt = frontEvt; // update the original if (tmp == 0U) { // need to wrap the tail? @@ -409,15 +248,9 @@ QEvt const * QActive_get_(QActive * const me) { --tmp; // advance the tail (counter-clockwise) me->eQueue.tail = tmp; // update the original - #ifndef Q_UNSAFE - me->eQueue.tail_dis = (QEQueueCtr)~tmp; - #endif // ndef Q_UNSAFE } else { me->eQueue.frontEvt = (QEvt *)0; // queue becomes empty - #ifndef Q_UNSAFE - me->eQueue.frontEvt_dis = (uintptr_t)~Q_PTR2UINT_CAST_((QEvt *)0); - #endif // ndef Q_UNSAFE // all entries in the queue must be free (+1 for fronEvt) Q_ASSERT_INCRIT(440, tmp == (me->eQueue.end + 1U)); @@ -426,42 +259,94 @@ QEvt const * QActive_get_(QActive * const me) { QS_TIME_PRE(); // timestamp QS_SIG_PRE(e->sig); // the signal of this event QS_OBJ_PRE(me); // this active object - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_2U8_PRE(e->poolNum_, e->refCtr_); QS_END_PRE() } - QF_MEM_APP(); QF_CRIT_EXIT(); return e; } -//$enddef${QF::QActive::get_} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -//$define${QF::QF-base::getQueueMin} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv +//............................................................................ +//! @private @memberof QActive +static void QActive_postFIFO_(QActive * const me, + QEvt const * const e, + void const * const sender) +{ + // NOTE: this helper function is called *inside* critical section +#ifndef Q_SPY + Q_UNUSED_PAR(sender); +#endif + + QEQueueCtr tmp = me->eQueue.nFree; // get volatile into temporary + --tmp; // one free entry just used up + + me->eQueue.nFree = tmp; // update the original + if (me->eQueue.nMin > tmp) { + me->eQueue.nMin = tmp; // update minimum so far + } + + QS_BEGIN_PRE(QS_QF_ACTIVE_POST, me->prio) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(sender); // the sender object + QS_SIG_PRE(e->sig); // the signal of the event + QS_OBJ_PRE(me); // this active object (recipient) + QS_2U8_PRE(e->poolNum_, e->refCtr_); + QS_EQC_PRE(tmp); // # free entries + QS_EQC_PRE(me->eQueue.nMin); // min # free entries + QS_END_PRE() -//${QF::QF-base::getQueueMin} ................................................ +#ifdef Q_UTEST + if (QS_LOC_CHECK_(me->prio)) { + QF_CRIT_EXIT(); + QS_onTestPost(sender, me, e, true); // QUTEst callback + QF_CRIT_ENTRY(); + } +#endif // def Q_UTEST + + if (me->eQueue.frontEvt == (QEvt *)0) { // is the queue empty? + me->eQueue.frontEvt = e; // deliver event directly + +#ifdef QXK_H_ + if (me->super.state.act == Q_ACTION_CAST(0)) { // eXtended? + QXTHREAD_EQUEUE_SIGNAL_(me); // signal eXtended Thread + } + else { + QACTIVE_EQUEUE_SIGNAL_(me); // signal the Active Object + } +#else + QACTIVE_EQUEUE_SIGNAL_(me); // signal the Active Object +#endif // def QXK_H_ + } + else { // queue was not empty, insert event into the ring-buffer + tmp = me->eQueue.head; // get volatile into temporary + me->eQueue.ring[tmp] = e; // insert e into buffer + + if (tmp == 0U) { // need to wrap the head? + tmp = me->eQueue.end; + } + --tmp; // advance the head (counter-clockwise) + + me->eQueue.head = tmp; // update the original + } +} + +//============================================================================ //! @static @public @memberof QF uint_fast16_t QF_getQueueMin(uint_fast8_t const prio) { QF_CRIT_STAT QF_CRIT_ENTRY(); - Q_REQUIRE_INCRIT(400, (prio <= QF_MAX_ACTIVE) + Q_REQUIRE_INCRIT(600, (prio <= QF_MAX_ACTIVE) && (QActive_registry_[prio] != (QActive *)0)); - #ifndef Q_UNSAFE uint_fast16_t const min = (uint_fast16_t)QActive_registry_[prio]->eQueue.nMin; - #else - uint_fast16_t const min = 0U; - #endif QF_CRIT_EXIT(); return min; } -//$enddef${QF::QF-base::getQueueMin} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -//$define${QF::QTicker} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -//${QF::QTicker} ............................................................. - -//${QF::QTicker::ctor} ....................................................... +//============================================================================ //! @public @memberof QTicker void QTicker_ctor(QTicker * const me, uint_fast8_t const tickRate) @@ -472,20 +357,17 @@ void QTicker_ctor(QTicker * const me, &QTicker_init_, &QTicker_dispatch_, &QHsm_isIn_ - #ifdef Q_SPY +#ifdef Q_SPY ,&QHsm_getStateHandler_ - #endif +#endif }; me->super.super.vptr = &vtable; // hook the vptr // reuse eQueue.head for tick-rate me->super.eQueue.head = (QEQueueCtr)tickRate; - #ifndef Q_UNSAFE - me->super.eQueue.head_dis = (QEQueueCtr)~tickRate; - #endif // ndef Q_UNSAFE } -//${QF::QTicker::init_} ...................................................... +//............................................................................ //! @private @memberof QTicker void QTicker_init_( QAsm * const me, @@ -498,18 +380,13 @@ void QTicker_init_( QF_CRIT_STAT QF_CRIT_ENTRY(); - QF_MEM_SYS(); QACTIVE_CAST_(me)->eQueue.tail = 0U; - #ifndef Q_UNSAFE - QACTIVE_CAST_(me)->eQueue.tail_dis = (QEQueueCtr)~0U; - #endif // ndef Q_UNSAFE - QF_MEM_APP(); QF_CRIT_EXIT(); } -//${QF::QTicker::dispatch_} .................................................. +//............................................................................ //! @private @memberof QTicker void QTicker_dispatch_( QAsm * const me, @@ -521,26 +398,15 @@ void QTicker_dispatch_( QF_CRIT_STAT QF_CRIT_ENTRY(); - QF_MEM_SYS(); // get volatile into temporaries QEQueueCtr nTicks = QACTIVE_CAST_(me)->eQueue.tail; QEQueueCtr const tickRate = QACTIVE_CAST_(me)->eQueue.head; - #ifndef Q_UNSAFE - Q_REQUIRE_INCRIT(700, nTicks > 0U); - QEQueueCtr dis = (QEQueueCtr)~QACTIVE_CAST_(me)->eQueue.tail_dis; - Q_INVARIANT_INCRIT(701, nTicks == dis); - dis = (QEQueueCtr)~QACTIVE_CAST_(me)->eQueue.head_dis; - Q_INVARIANT_INCRIT(702, tickRate == dis); - #endif // ndef Q_UNSAFE + Q_REQUIRE_INCRIT(800, nTicks > 0U); QACTIVE_CAST_(me)->eQueue.tail = 0U; // clear # ticks - #ifndef Q_UNSAFE - QACTIVE_CAST_(me)->eQueue.tail_dis = (QEQueueCtr)~0U; - #endif // ndef Q_UNSAFE - QF_MEM_APP(); QF_CRIT_EXIT(); for (; nTicks > 0U; --nTicks) { @@ -548,64 +414,41 @@ void QTicker_dispatch_( } } -//${QF::QTicker::trig_} ...................................................... +//............................................................................ //! @private @memberof QTicker void QTicker_trig_( QActive * const me, void const * const sender) { - #ifndef Q_SPY +#ifndef Q_SPY Q_UNUSED_PAR(sender); - #endif +#endif static QEvt const tickEvt = QEVT_INITIALIZER(0); QF_CRIT_STAT QF_CRIT_ENTRY(); - QF_MEM_SYS(); QEQueueCtr nTicks = me->eQueue.tail; // get volatile into temporary if (me->eQueue.frontEvt == (QEvt *)0) { // no tick events? - #ifndef Q_UNSAFE - Q_REQUIRE_INCRIT(800, nTicks == 0U); - Q_REQUIRE_INCRIT(801, me->eQueue.nFree == 1U); - Q_INVARIANT_INCRIT(802, me->eQueue.frontEvt_dis - == (uintptr_t)~Q_PTR2UINT_CAST_((QEvt *)0)); - QEQueueCtr dis = (QEQueueCtr)~me->eQueue.nFree_dis; - Q_INVARIANT_INCRIT(803, 1U == dis); - dis = (QEQueueCtr)~me->eQueue.tail_dis; - Q_INVARIANT_INCRIT(804, 0U == dis); - #endif // ndef Q_UNSAFE + Q_REQUIRE_INCRIT(900, + (me->eQueue.nFree == 1U) + && (nTicks == 0U)); me->eQueue.frontEvt = &tickEvt; // deliver event directly me->eQueue.nFree = 0U; - #ifndef Q_UNSAFE - me->eQueue.frontEvt_dis = (uintptr_t)~Q_PTR2UINT_CAST_(&tickEvt); - me->eQueue.nFree_dis = (QEQueueCtr)~0U; - #endif // ndef Q_UNSAFE QACTIVE_EQUEUE_SIGNAL_(me); // signal the event queue } else { - #ifndef Q_UNSAFE - Q_REQUIRE_INCRIT(810, (nTicks > 0U) && (nTicks < 0xFFU)); - Q_REQUIRE_INCRIT(811, me->eQueue.nFree == 0U); - Q_INVARIANT_INCRIT(812, me->eQueue.frontEvt_dis - == (uintptr_t)~Q_PTR2UINT_CAST_(&tickEvt)); - QEQueueCtr dis = (QEQueueCtr)~me->eQueue.nFree_dis; - Q_INVARIANT_INCRIT(813, 0U == dis); - dis = (QEQueueCtr)~me->eQueue.tail_dis; - Q_INVARIANT_INCRIT(814, nTicks == dis); - #endif // ndef Q_UNSAFE + Q_REQUIRE_INCRIT(910, (nTicks > 0U) && (nTicks < 0xFFU)); + Q_REQUIRE_INCRIT(920, me->eQueue.nFree == 0U); } ++nTicks; // account for one more tick event me->eQueue.tail = nTicks; // update the original - #ifndef Q_UNSAFE - me->eQueue.tail_dis = (QEQueueCtr)~nTicks; - #endif // ndef Q_UNSAFE QS_BEGIN_PRE(QS_QF_ACTIVE_POST, me->prio) QS_TIME_PRE(); // timestamp @@ -617,7 +460,5 @@ void QTicker_trig_( QS_EQC_PRE(0U); // min # free entries QS_END_PRE() - QF_MEM_APP(); QF_CRIT_EXIT(); } -//$enddef${QF::QTicker} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/qf/qf_defer.c b/src/qf/qf_defer.c index 28c0fe681..d6a426caa 100644 --- a/src/qf/qf_defer.c +++ b/src/qf/qf_defer.c @@ -1,10 +1,6 @@ -//$file${src::qf::qf_defer.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// -// Model: qpc.qm -// File: ${src::qf::qf_defer.c} -// -// This code has been generated by QM 7.0.0 . -// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // @@ -14,7 +10,7 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -30,8 +26,7 @@ // Quantum Leaps contact information: // // -// -//$endhead${src::qf::qf_defer.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//============================================================================ #define QP_IMPL // this is QP implementation #include "qp_port.h" // QP port #include "qp_pkg.h" // QP package-scope interface @@ -45,15 +40,7 @@ Q_DEFINE_THIS_MODULE("qf_defer") -//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// Check for the minimum required QP version -#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U)%0x2710U)) -#error qpc version 7.3.0 or higher required -#endif -//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -//$define${QF::QActive::defer} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QF::QActive::defer} ...................................................... +//............................................................................ //! @protected @memberof QActive bool QActive_defer(QActive const * const me, struct QEQueue * const eq, @@ -63,23 +50,19 @@ bool QActive_defer(QActive const * const me, QS_CRIT_STAT QS_CRIT_ENTRY(); - QS_MEM_SYS(); QS_BEGIN_PRE(QS_QF_ACTIVE_DEFER, me->prio) QS_TIME_PRE(); // time stamp QS_OBJ_PRE(me); // this active object QS_OBJ_PRE(eq); // the deferred queue QS_SIG_PRE(e->sig); // the signal of the event - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_2U8_PRE(e->poolNum_, e->refCtr_); QS_END_PRE() - QS_MEM_APP(); QS_CRIT_EXIT(); return status; } -//$enddef${QF::QActive::defer} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -//$define${QF::QActive::recall} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -//${QF::QActive::recall} ..................................................... +//............................................................................ //! @protected @memberof QActive bool QActive_recall(QActive * const me, struct QEQueue * const eq) @@ -87,20 +70,19 @@ bool QActive_recall(QActive * const me, QEvt const * const e = QEQueue_get(eq, me->prio); QF_CRIT_STAT - bool recalled; + bool recalled = false; if (e != (QEvt *)0) { // event available? QACTIVE_POST_LIFO(me, e); // post it to the front of the AO's queue QF_CRIT_ENTRY(); - QF_MEM_SYS(); - if (QEvt_getPoolNum_(e) != 0U) { // is it a mutable event? + if (e->poolNum_ != 0U) { // is it a mutable event? // after posting to the AO's queue the event must be referenced // at least twice: once in the deferred event queue (eq->get() // did NOT decrement the reference counter) and once in the // AO's event queue. - Q_ASSERT_INCRIT(210, e->refCtr_ >= 2U); + Q_ASSERT_INCRIT(205, e->refCtr_ >= 2U); // we need to decrement the reference counter once, to account // for removing the event from the deferred event queue. @@ -112,17 +94,15 @@ bool QActive_recall(QActive * const me, QS_OBJ_PRE(me); // this active object QS_OBJ_PRE(eq); // the deferred queue QS_SIG_PRE(e->sig); // the signal of the event - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_2U8_PRE(e->poolNum_, e->refCtr_); QS_END_PRE() - QF_MEM_APP(); QF_CRIT_EXIT(); recalled = true; } else { QS_CRIT_ENTRY(); - QS_MEM_SYS(); QS_BEGIN_PRE(QS_QF_ACTIVE_RECALL_ATTEMPT, me->prio) QS_TIME_PRE(); // time stamp @@ -130,17 +110,12 @@ bool QActive_recall(QActive * const me, QS_OBJ_PRE(eq); // the deferred queue QS_END_PRE() - QS_MEM_APP(); QS_CRIT_EXIT(); - - recalled = false; } return recalled; } -//$enddef${QF::QActive::recall} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -//$define${QF::QActive::flushDeferred} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -//${QF::QActive::flushDeferred} .............................................. +//............................................................................ //! @protected @memberof QActive uint_fast16_t QActive_flushDeferred(QActive const * const me, struct QEQueue * const eq, @@ -151,9 +126,9 @@ uint_fast16_t QActive_flushDeferred(QActive const * const me, QEvt const * const e = QEQueue_get(eq, me->prio); if (e != (QEvt *)0) { ++n; // count one more flushed event - #if (QF_MAX_EPOOL > 0U) +#if (QF_MAX_EPOOL > 0U) QF_gc(e); // garbage collect - #endif +#endif } else { break; @@ -162,4 +137,3 @@ uint_fast16_t QActive_flushDeferred(QActive const * const me, return n; } -//$enddef${QF::QActive::flushDeferred} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/qf/qf_dyn.c b/src/qf/qf_dyn.c index fc172386a..58212f60b 100644 --- a/src/qf/qf_dyn.c +++ b/src/qf/qf_dyn.c @@ -1,10 +1,6 @@ -//$file${src::qf::qf_dyn.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// -// Model: qpc.qm -// File: ${src::qf::qf_dyn.c} -// -// This code has been generated by QM 7.0.0 . -// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // @@ -14,7 +10,7 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -30,8 +26,7 @@ // Quantum Leaps contact information: // // -// -//$endhead${src::qf::qf_dyn.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//============================================================================ #define QP_IMPL // this is QP implementation #include "qp_port.h" // QP port #include "qp_pkg.h" // QP package-scope interface @@ -47,15 +42,7 @@ Q_DEFINE_THIS_MODULE("qf_dyn") -//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// Check for the minimum required QP version -#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U)%0x2710U)) -#error qpc version 7.3.0 or higher required -#endif -//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -//$define${QF::QF-dyn} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QF::QF-dyn::poolInit} .................................................... +//............................................................................ //! @static @public @memberof QF void QF_poolInit( void * const poolSto, @@ -67,120 +54,105 @@ void QF_poolInit( // see precondition{qf_dyn,200} and precondition{qf_dyn,201} QF_CRIT_STAT QF_CRIT_ENTRY(); - QF_MEM_SYS(); - Q_REQUIRE_INCRIT(200, poolNum < QF_MAX_EPOOL); + Q_REQUIRE_INCRIT(100, poolNum < QF_MAX_EPOOL); if (poolNum > 0U) { - Q_REQUIRE_INCRIT(201, + Q_REQUIRE_INCRIT(110, QF_EPOOL_EVENT_SIZE_(QF_priv_.ePool_[poolNum - 1U]) < evtSize); } QF_priv_.maxPool_ = poolNum + 1U; // one more pool - QF_MEM_APP(); QF_CRIT_EXIT(); // perform the port-dependent initialization of the event-pool QF_EPOOL_INIT_(QF_priv_.ePool_[poolNum], poolSto, poolSize, evtSize); - #ifdef Q_SPY +#ifdef Q_SPY // generate the object-dictionary entry for the initialized pool { uint8_t obj_name[9] = "EvtPool?"; obj_name[7] = (uint8_t)((uint8_t)'0' + poolNum + 1U); QS_obj_dict_pre_(&QF_priv_.ePool_[poolNum], (char const *)obj_name); } - #endif // Q_SPY +#endif // Q_SPY } -//${QF::QF-dyn::poolGetMaxBlockSize} ......................................... +//............................................................................ //! @static @public @memberof QF uint_fast16_t QF_poolGetMaxBlockSize(void) { QF_CRIT_STAT QF_CRIT_ENTRY(); - QF_MEM_SYS(); uint_fast16_t const max_size = QF_EPOOL_EVENT_SIZE_(QF_priv_.ePool_[QF_priv_.maxPool_ - 1U]); - QF_MEM_APP(); QF_CRIT_EXIT(); return max_size; } -//${QF::QF-dyn::getPoolMin} .................................................. +//............................................................................ //! @static @public @memberof QF uint_fast16_t QF_getPoolMin(uint_fast8_t const poolNum) { QF_CRIT_STAT QF_CRIT_ENTRY(); - QF_MEM_SYS(); - Q_REQUIRE_INCRIT(400, (poolNum <= QF_MAX_EPOOL) + Q_REQUIRE_INCRIT(300, (poolNum <= QF_MAX_EPOOL) && (0U < poolNum) && (poolNum <= QF_priv_.maxPool_)); - #ifndef Q_UNSAFE uint_fast16_t const min = (uint_fast16_t)QF_priv_.ePool_[poolNum - 1U].nMin; - #else - uint_fast16_t const min = 0U; - #endif - QF_MEM_APP(); QF_CRIT_EXIT(); return min; } -//${QF::QF-dyn::newX_} ....................................................... +//............................................................................ //! @static @private @memberof QF QEvt * QF_newX_( uint_fast16_t const evtSize, uint_fast16_t const margin, enum_t const sig) { - QF_CRIT_STAT - QF_CRIT_ENTRY(); - QF_MEM_SYS(); - // find the pool id that fits the requested event size... - uint_fast8_t poolNum = 0U; // zero-based poolNum initially + uint8_t poolNum = 0U; // zero-based poolNum initially for (; poolNum < QF_priv_.maxPool_; ++poolNum) { if (evtSize <= QF_EPOOL_EVENT_SIZE_(QF_priv_.ePool_[poolNum])) { break; } } + QF_CRIT_STAT + QF_CRIT_ENTRY(); + // precondition: // - cannot run out of registered pools - Q_REQUIRE_INCRIT(300, poolNum < QF_priv_.maxPool_); + Q_REQUIRE_INCRIT(400, poolNum < QF_priv_.maxPool_); ++poolNum; // convert to 1-based poolNum - QF_MEM_APP(); QF_CRIT_EXIT(); // get event e (port-dependent)... QEvt *e; - #ifdef Q_SPY +#ifdef Q_SPY QF_EPOOL_GET_(QF_priv_.ePool_[poolNum - 1U], e, ((margin != QF_NO_MARGIN) ? margin : 0U), (uint_fast8_t)QS_EP_ID + poolNum); - #else +#else QF_EPOOL_GET_(QF_priv_.ePool_[poolNum - 1U], e, ((margin != QF_NO_MARGIN) ? margin : 0U), 0U); - #endif +#endif if (e != (QEvt *)0) { // was e allocated correctly? - e->sig = (QSignal)sig; // set the signal - e->refCtr_ = 0U; // initialize the reference counter to 0 - e->evtTag_ = (uint8_t)((poolNum << 4U) | 0x0FU); + e->sig = (QSignal)sig; // set the signal + e->poolNum_ = poolNum; + e->refCtr_ = 0U; QS_CRIT_ENTRY(); - QS_MEM_SYS(); - QS_BEGIN_PRE(QS_QF_NEW, - (uint_fast8_t)QS_EP_ID + poolNum) + QS_BEGIN_PRE(QS_QF_NEW, (uint_fast8_t)QS_EP_ID + poolNum) QS_TIME_PRE(); // timestamp QS_EVS_PRE(evtSize); // the size of the event QS_SIG_PRE(sig); // the signal of the event QS_END_PRE() - QS_MEM_APP(); QS_CRIT_EXIT(); } else { // event was not allocated @@ -189,16 +161,14 @@ QEvt * QF_newX_( // This assertion means that the event allocation failed, // and this failure cannot be tolerated. The most frequent // reason is an event leak in the application. - Q_ASSERT_INCRIT(320, margin != QF_NO_MARGIN); + Q_ASSERT_INCRIT(420, margin != QF_NO_MARGIN); - QS_MEM_SYS(); QS_BEGIN_PRE(QS_QF_NEW_ATTEMPT, (uint_fast8_t)QS_EP_ID + poolNum) QS_TIME_PRE(); // timestamp QS_EVS_PRE(evtSize); // the size of the event QS_SIG_PRE(sig); // the signal of the event QS_END_PRE() - QS_MEM_APP(); QF_CRIT_EXIT(); } @@ -208,22 +178,17 @@ QEvt * QF_newX_( return e; } -//${QF::QF-dyn::gc} .......................................................... +//............................................................................ //! @static @public @memberof QF void QF_gc(QEvt const * const e) { QF_CRIT_STAT QF_CRIT_ENTRY(); - Q_REQUIRE_INCRIT(400, e != (QEvt *)0); - - #ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(401, QEvt_verify_(e)); - #endif + Q_REQUIRE_INCRIT(500, e != (QEvt *)0); - uint_fast8_t const poolNum = QEvt_getPoolNum_(e); + uint8_t const poolNum = e->poolNum_; if (poolNum != 0U) { // is it a pool event (mutable)? - QF_MEM_SYS(); if (e->refCtr_ > 1U) { // isn't this the last reference? @@ -234,9 +199,9 @@ void QF_gc(QEvt const * const e) { QS_2U8_PRE(poolNum, e->refCtr_); QS_END_PRE() + Q_ASSERT_INCRIT(505, e->refCtr_ > 0U); QEvt_refCtr_dec_(e); // decrement the ref counter - QF_MEM_APP(); QF_CRIT_EXIT(); } else { // this is the last reference to this event, recycle it @@ -249,20 +214,18 @@ void QF_gc(QEvt const * const e) { QS_END_PRE() // pool number must be in range - Q_ASSERT_INCRIT(410, (poolNum <= QF_priv_.maxPool_) + Q_ASSERT_INCRIT(510, (poolNum <= QF_priv_.maxPool_) && (poolNum <= QF_MAX_EPOOL)); - QF_MEM_APP(); QF_CRIT_EXIT(); - // NOTE: casting 'const' away is legit because it's a pool event - #ifdef Q_SPY - QF_EPOOL_PUT_(QF_priv_.ePool_[poolNum - 1U], - (QEvt *)e, + // NOTE: casting 'const' away is legit because 'e' is a pool event +#ifdef Q_SPY + QF_EPOOL_PUT_(QF_priv_.ePool_[poolNum - 1U], (QEvt *)e, (uint_fast8_t)QS_EP_ID + poolNum); - #else - QF_EPOOL_PUT_(QF_priv_.ePool_[poolNum - 1U], - (QEvt *)e, 0U); - #endif +#else + QF_EPOOL_PUT_(QF_priv_.ePool_[poolNum - 1U], (QEvt *)e, + 0U); +#endif } } else { @@ -270,76 +233,66 @@ void QF_gc(QEvt const * const e) { } } -//${QF::QF-dyn::newRef_} ..................................................... +//............................................................................ //! @static @private @memberof QF QEvt const * QF_newRef_( QEvt const * const e, void const * const evtRef) { - #ifdef Q_UNSAFE +#ifdef Q_UNSAFE Q_UNUSED_PAR(evtRef); - #endif +#endif QF_CRIT_STAT QF_CRIT_ENTRY(); - Q_REQUIRE_INCRIT(500, e != (QEvt *)0); - #ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(501, QEvt_verify_(e)); - #endif + Q_REQUIRE_INCRIT(600, e != (QEvt *)0); - uint_fast8_t const poolNum = QEvt_getPoolNum_(e); + uint_fast8_t const poolNum = e->poolNum_; Q_UNUSED_PAR(poolNum); // might be unused - Q_REQUIRE_INCRIT(510, (poolNum != 0U) + Q_REQUIRE_INCRIT(610, (poolNum != 0U) && (evtRef == (void *)0)); + Q_ASSERT_INCRIT(605, e->refCtr_ < (2U * QF_MAX_ACTIVE)); QEvt_refCtr_inc_(e); // increments the ref counter - QS_MEM_SYS(); QS_BEGIN_PRE(QS_QF_NEW_REF, (uint_fast8_t)QS_EP_ID + poolNum) QS_TIME_PRE(); // timestamp QS_SIG_PRE(e->sig); // the signal of the event QS_2U8_PRE(poolNum, e->refCtr_); QS_END_PRE() - QS_MEM_APP(); QF_CRIT_EXIT(); return e; } -//${QF::QF-dyn::deleteRef_} .................................................. +//............................................................................ //! @static @private @memberof QF void QF_deleteRef_(void const * const evtRef) { QF_CRIT_STAT QF_CRIT_ENTRY(); QEvt const * const e = (QEvt const *)evtRef; - Q_REQUIRE_INCRIT(600, e != (QEvt *)0); - #ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(601, QEvt_verify_(e)); - #endif // ndef Q_UNSAFE + Q_REQUIRE_INCRIT(700, e != (QEvt *)0); - #ifdef Q_SPY - uint_fast8_t const poolNum = QEvt_getPoolNum_(e); - QS_MEM_SYS(); +#ifdef Q_SPY + uint_fast8_t const poolNum = e->poolNum_; QS_BEGIN_PRE(QS_QF_DELETE_REF, (uint_fast8_t)QS_EP_ID + poolNum) QS_TIME_PRE(); // timestamp QS_SIG_PRE(e->sig); // the signal of the event QS_2U8_PRE(poolNum, e->refCtr_); QS_END_PRE() - QS_MEM_APP(); - #endif // def Q_SPY +#endif // def Q_SPY QF_CRIT_EXIT(); - #if (QF_MAX_EPOOL > 0U) +#if (QF_MAX_EPOOL > 0U) QF_gc(e); // recycle the referenced event - #endif +#endif } -//$enddef${QF::QF-dyn} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #endif // (QF_MAX_EPOOL > 0U) mutable events configured diff --git a/src/qf/qf_mem.c b/src/qf/qf_mem.c index fa12c8de6..67a5247da 100644 --- a/src/qf/qf_mem.c +++ b/src/qf/qf_mem.c @@ -1,10 +1,6 @@ -//$file${src::qf::qf_mem.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// -// Model: qpc.qm -// File: ${src::qf::qf_mem.c} -// -// This code has been generated by QM 7.0.0 . -// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // @@ -14,7 +10,7 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -30,32 +26,21 @@ // Quantum Leaps contact information: // // -// -//$endhead${src::qf::qf_mem.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//============================================================================ #define QP_IMPL // this is QP implementation #include "qp_port.h" // QP port #include "qp_pkg.h" // QP package-scope interface #include "qsafe.h" // QP Functional Safety (FuSa) Subsystem #ifdef Q_SPY // QS software tracing enabled? #include "qs_port.h" // QS port - #include "qs_pkg.h" // QS facilities for pre-defined trace records + #include "qs_pkg.h" // QS package-scope internal interface #else #include "qs_dummy.h" // disable the QS software tracing #endif // Q_SPY Q_DEFINE_THIS_MODULE("qf_mem") -//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// Check for the minimum required QP version -#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U)%0x2710U)) -#error qpc version 7.3.0 or higher required -#endif -//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -//$define${QF::QMPool} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QF::QMPool} .............................................................. - -//${QF::QMPool::init} ........................................................ +//............................................................................ //! @public @memberof QMPool void QMPool_init(QMPool * const me, void * const poolSto, @@ -64,28 +49,24 @@ void QMPool_init(QMPool * const me, { QF_CRIT_STAT QF_CRIT_ENTRY(); - QF_MEM_SYS(); Q_REQUIRE_INCRIT(100, poolSto != (void *)0); - Q_REQUIRE_INCRIT(101, poolSize >= (uint_fast32_t)sizeof(QFreeBlock)); - Q_REQUIRE_INCRIT(102, (uint_fast16_t)(blockSize + sizeof(QFreeBlock)) - > blockSize); - me->free_head = (QFreeBlock *)poolSto; + me->freeHead = (void * *)poolSto; - // find # free blocks in a memory block, NO DIVISION + // find # free links in a memory block, see NOTE1 me->blockSize = (QMPoolSize)(2U * sizeof(void *)); - uint_fast16_t nblocks = 1U; + uint_fast16_t inext = 2U; // # index of the next block while (me->blockSize < (QMPoolSize)blockSize) { - me->blockSize += (QMPoolSize)sizeof(QFreeBlock); - ++nblocks; + me->blockSize += (QMPoolSize)sizeof(void *); + ++inext; } // the pool buffer must fit at least one rounded-up block Q_ASSERT_INCRIT(110, poolSize >= me->blockSize); // start at the head of the free list - QFreeBlock *fb = me->free_head; + void * *pfb = me->freeHead; // pointer to free block uint32_t nTot = 1U; // the last block already in the list // chain all blocks together in a free-list... @@ -93,181 +74,127 @@ void QMPool_init(QMPool * const me, size >= (uint_fast32_t)me->blockSize; size -= (uint_fast32_t)me->blockSize) { - fb->next = &fb[nblocks]; // point next link to next block - #ifndef Q_UNSAFE - fb->next_dis = (uintptr_t)(~Q_PTR2UINT_CAST_(fb->next)); - #endif - fb = fb->next; // advance to the next block - ++nTot; // one more free block in the pool + pfb[0] = &pfb[inext]; // set the next link to next free block + pfb = pfb[0]; // advance to the next block + ++nTot; // one more free block in the pool } + pfb[0] = (void * *)0; // the last link points to NULL // dynamic range check - #if (QF_MPOOL_CTR_SIZE == 1U) - Q_ENSURE_INCRIT(190, nTot < 0xFFU); - #elif (QF_MPOOL_CTR_SIZE == 2U) - Q_ENSURE_INCRIT(190, nTot < 0xFFFFU); - #endif - - fb->next = (QFreeBlock *)0; // the last link points to NULL +#if (QF_MPOOL_CTR_SIZE == 1U) + Q_ASSERT_INCRIT(190, nTot < 0xFFU); +#elif (QF_MPOOL_CTR_SIZE == 2U) + Q_ASSERT_INCRIT(190, nTot < 0xFFFFU); +#endif me->nTot = (QMPoolCtr)nTot; - me->nFree = me->nTot; // all blocks are free - me->start = (QFreeBlock *)poolSto; // the original start this pool buffer - me->end = fb; // the last block in this pool - - #ifndef Q_UNSAFE - me->free_head_dis = (uintptr_t)~Q_PTR2UINT_CAST_(me->free_head); - me->nFree_dis = (QMPoolCtr)~me->nFree; - me->nMin = me->nTot; // the minimum # free blocks - fb->next_dis = (uintptr_t)(~Q_PTR2UINT_CAST_(fb->next)); - #endif - - QF_MEM_APP(); + me->nFree = me->nTot; // all blocks are free + me->start = (void * *)poolSto; // the original start this pool buffer + me->end = pfb; // the last block in this pool + me->nMin = me->nTot; // the minimum # free blocks + QF_CRIT_EXIT(); } -//${QF::QMPool::get} ......................................................... +//............................................................................ //! @public @memberof QMPool void * QMPool_get(QMPool * const me, uint_fast16_t const margin, uint_fast8_t const qsId) { - #ifndef Q_SPY +#ifndef Q_SPY Q_UNUSED_PAR(qsId); - #endif +#endif QF_CRIT_STAT QF_CRIT_ENTRY(); - QF_MEM_SYS(); // get volatile into temporaries - QFreeBlock *fb = me->free_head; + void * *pfb = me->freeHead; // pointer to free block QMPoolCtr nFree = me->nFree; - #ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(301, Q_PTR2UINT_CAST_(fb) - == (uintptr_t)~me->free_head_dis); - QMPoolCtr const dis = (QMPoolCtr)~me->nFree_dis; - Q_INVARIANT_INCRIT(302, nFree == dis); - #endif // ndef Q_UNSAFE - // have more free blocks than the requested margin? if (nFree > (QMPoolCtr)margin) { - Q_ASSERT_INCRIT(310, fb != (QFreeBlock *)0); - - QFreeBlock * const fb_next = fb->next; // fast temporary + Q_ASSERT_INCRIT(310, pfb != (void * *)0); - #ifndef Q_UNSAFE - // the free block must have integrity (duplicate inverse storage) - Q_INVARIANT_INCRIT(311, Q_PTR2UINT_CAST_(fb_next) - == (uintptr_t)~fb->next_dis); - #endif // ndef Q_UNSAFE + void * * const pfb_next = pfb[0]; // fast temporary --nFree; // one less free block if (nFree == 0U) { // is the pool becoming empty? // pool is becoming empty, so the next free block must be NULL - Q_ASSERT_INCRIT(320, fb_next == (QFreeBlock *)0); + Q_ASSERT_INCRIT(320, pfb_next == (void * *)0); - me->nFree = 0U; - #ifndef Q_UNSAFE - me->nFree_dis = (QMPoolCtr)~0U; - me->nMin = 0U; // remember that the pool got empty - #endif // ndef Q_UNSAFE + me->nFree = 0U; // no more free blocks + me->nMin = 0U; // remember that the pool got empty } - else { - me->nFree = nFree; // update the original - #ifndef Q_UNSAFE - me->nFree_dis = (QMPoolCtr)~nFree; + else { // the pool is NOT empty - // The pool is not empty, so the next free-block pointer - // must be in range. - Q_INVARIANT_INCRIT(330, - (me->start <= fb_next) && (fb_next <= me->end)); + // the next free-block pointer must be in range + Q_ASSERT_INCRIT(330, + (me->start <= pfb_next) && (pfb_next <= me->end)); - // is the # free blocks the new minimum so far? - if (me->nMin > nFree) { + me->nFree = nFree; // update the original + if (me->nMin > nFree) { // is this the new minimum? me->nMin = nFree; // remember the minimum so far } - #endif // ndef Q_UNSAFE } - me->free_head = fb_next; // set the head to the next free block - #ifndef Q_UNSAFE - me->free_head_dis = (uintptr_t)(~Q_PTR2UINT_CAST_(fb_next)); - #endif // ndef Q_UNSAFE + me->freeHead = pfb_next; // set the head to the next free block + + // change the allocated block contents so that it is different + // than a free block inside the pool. + pfb[0] = &me->end[1]; // invalid location beyond the end QS_BEGIN_PRE(QS_QF_MPOOL_GET, qsId) QS_TIME_PRE(); // timestamp QS_OBJ_PRE(me); // this memory pool - QS_MPC_PRE(nFree); // # of free blocks in the pool - #ifndef Q_UNSAFE + QS_MPC_PRE(nFree); // # free blocks in the pool QS_MPC_PRE(me->nMin); // min # free blocks ever in the pool - #else - QS_MPC_PRE(0U); // min # free blocks (not available) - #endif // ndef Q_UNSAFE QS_END_PRE() } else { // don't have enough free blocks at this point - fb = (QFreeBlock *)0; + pfb = (void * *)0; QS_BEGIN_PRE(QS_QF_MPOOL_GET_ATTEMPT, qsId) QS_TIME_PRE(); // timestamp QS_OBJ_PRE(me); // this memory pool - QS_MPC_PRE(nFree); // # of free blocks in the pool + QS_MPC_PRE(nFree); // # free blocks in the pool QS_MPC_PRE(margin); // the requested margin QS_END_PRE() } - QF_MEM_APP(); QF_CRIT_EXIT(); - return fb; // return the block or NULL pointer to the caller + return (void *)pfb; // return the block or NULL pointer to the caller } -//${QF::QMPool::put} ......................................................... +//............................................................................ //! @public @memberof QMPool void QMPool_put(QMPool * const me, void * const block, uint_fast8_t const qsId) { - #ifndef Q_SPY +#ifndef Q_SPY Q_UNUSED_PAR(qsId); - #endif +#endif - QFreeBlock * const fb = (QFreeBlock *)block; + void * * const pfb = (void * *)block; // pointer to free block QF_CRIT_STAT QF_CRIT_ENTRY(); - QF_MEM_SYS(); // get volatile into temporaries - QFreeBlock * const free_head = me->free_head; + void * * const freeHead = me->freeHead; QMPoolCtr nFree = me->nFree; - #ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(401, Q_PTR2UINT_CAST_(free_head) - == (uintptr_t)~me->free_head_dis); - QMPoolCtr const dis = (QMPoolCtr)~me->nFree_dis; - Q_INVARIANT_INCRIT(402, nFree == dis); - - Q_REQUIRE_INCRIT(410, nFree < me->nTot); - Q_REQUIRE_INCRIT(411, (me->start <= fb) && (fb <= me->end)); - - // the block must not be in the pool already - Q_REQUIRE_INCRIT(412, Q_PTR2UINT_CAST_(fb->next) - != (uintptr_t)~fb->next_dis); - #endif // ndef Q_UNSAFE + Q_REQUIRE_INCRIT(400, nFree < me->nTot); + Q_REQUIRE_INCRIT(410, (me->start <= pfb) && (pfb <= me->end)); ++nFree; // one more free block in this pool - me->free_head = fb; // set as new head of the free list + me->freeHead = pfb; // set as new head of the free list me->nFree = nFree; - fb->next = free_head; // link into the list - #ifndef Q_UNSAFE - me->free_head_dis = (uintptr_t)(~Q_PTR2UINT_CAST_(fb)); - me->nFree_dis = (QMPoolCtr)~nFree; - fb->next_dis = (uintptr_t)(~Q_PTR2UINT_CAST_(free_head)); - #endif + pfb[0] = freeHead; // link into the list QS_BEGIN_PRE(QS_QF_MPOOL_PUT, qsId) QS_TIME_PRE(); // timestamp @@ -275,7 +202,16 @@ void QMPool_put(QMPool * const me, QS_MPC_PRE(nFree); // the # free blocks in the pool QS_END_PRE() - QF_MEM_APP(); QF_CRIT_EXIT(); } -//$enddef${QF::QMPool} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//============================================================================ +// NOTE1: +// The memory buffer for the pool is organized as an array of void* pointers +// (see void * data type). These pointers are used to form a linked-list +// of free blocks in the pool. The first location pfb[0] is the actual link. +// The second location pfb[1] is used in SafeQP as the redundant "duplicate +// storage" for the link at pfb[0]. Even though the "duplicate storage" is NOT +// used in this QP edition, the minimum number of number of void* pointers +// (void * data type) inside a memory block is still kept at 2 to maintain +// the same policy for sizing the memory blocks. diff --git a/src/qf/qf_ps.c b/src/qf/qf_ps.c index ff7ee56a7..17bc92984 100644 --- a/src/qf/qf_ps.c +++ b/src/qf/qf_ps.c @@ -1,10 +1,6 @@ -//$file${src::qf::qf_ps.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// -// Model: qpc.qm -// File: ${src::qf::qf_ps.c} -// -// This code has been generated by QM 7.0.0 . -// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // @@ -14,7 +10,7 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -30,8 +26,7 @@ // Quantum Leaps contact information: // // -// -//$endhead${src::qf::qf_ps.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//============================================================================ #define QP_IMPL // this is QP implementation #include "qp_port.h" // QP port #include "qp_pkg.h" // QP package-scope interface @@ -45,23 +40,10 @@ Q_DEFINE_THIS_MODULE("qf_ps") -//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// Check for the minimum required QP version -#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U)%0x2710U)) -#error qpc version 7.3.0 or higher required -#endif -//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -//$define${QF::QActive::subscrList_} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv QSubscrList * QActive_subscrList_; -//$enddef${QF::QActive::subscrList_} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -//$define${QF::QActive::maxPubSignal_} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv enum_t QActive_maxPubSignal_; -//$enddef${QF::QActive::maxPubSignal_} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -//$define${QF::QActive::psInit} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -//${QF::QActive::psInit} ..................................................... +//............................................................................ //! @static @public @memberof QActive void QActive_psInit( QSubscrList * const subscrSto, @@ -73,60 +55,50 @@ void QActive_psInit( // initialize the subscriber list for (enum_t sig = 0; sig < maxSignal; ++sig) { QPSet_setEmpty(&subscrSto[sig].set); - #ifndef Q_UNSAFE - QPSet_update_(&subscrSto[sig].set, &subscrSto[sig].set_dis); - #endif } } -//$enddef${QF::QActive::psInit} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -//$define${QF::QActive::publish_} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -//${QF::QActive::publish_} ................................................... +//............................................................................ //! @static @private @memberof QActive void QActive_publish_( QEvt const * const e, void const * const sender, uint_fast8_t const qsId) { - #ifndef Q_SPY +#ifndef Q_SPY Q_UNUSED_PAR(sender); Q_UNUSED_PAR(qsId); - #endif +#endif QSignal const sig = e->sig; QF_CRIT_STAT QF_CRIT_ENTRY(); - QF_MEM_SYS(); Q_REQUIRE_INCRIT(200, sig < (QSignal)QActive_maxPubSignal_); - Q_INVARIANT_INCRIT(202, - QPSet_verify_(&QActive_subscrList_[sig].set, - &QActive_subscrList_[sig].set_dis)); QS_BEGIN_PRE(QS_QF_PUBLISH, qsId) QS_TIME_PRE(); // the timestamp QS_OBJ_PRE(sender); // the sender object QS_SIG_PRE(sig); // the signal of the event - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_2U8_PRE(e->poolNum_, e->refCtr_); QS_END_PRE() // is it a mutable event? - if (QEvt_getPoolNum_(e) != 0U) { + if (e->poolNum_ != 0U) { // NOTE: The reference counter of a mutable event is incremented to // prevent premature recycling of the event while the multicasting // is still in progress. At the end of the function, the garbage // collector step (QF_gc()) decrements the reference counter and // recycles the event if the counter drops to zero. This covers the // case when the event was published without any subscribers. + Q_ASSERT_INCRIT(205, e->refCtr_ < (2U * QF_MAX_ACTIVE)); QEvt_refCtr_inc_(e); } // make a local, modifiable copy of the subscriber set QPSet subscrSet = QActive_subscrList_[sig].set; - QF_MEM_APP(); QF_CRIT_EXIT(); if (QPSet_notEmpty(&subscrSet)) { // any subscribers? @@ -134,21 +106,16 @@ void QActive_publish_( uint_fast8_t p = QPSet_findMax(&subscrSet); QF_CRIT_ENTRY(); - QF_MEM_SYS(); QActive *a = QActive_registry_[p]; // the AO must be registered with the framework Q_ASSERT_INCRIT(210, a != (QActive *)0); - QF_MEM_APP(); QF_CRIT_EXIT(); QF_SCHED_STAT_ QF_SCHED_LOCK_(p); // lock the scheduler up to AO's prio - uint_fast8_t lbound = QF_MAX_ACTIVE + 1U; // fixed upper loop bound do { // loop over all subscribers - --lbound; - // QACTIVE_POST() asserts internally if the queue overflows QACTIVE_POST(a, e, sender); @@ -157,41 +124,34 @@ void QActive_publish_( p = QPSet_findMax(&subscrSet); // highest-prio subscriber QF_CRIT_ENTRY(); - QF_MEM_SYS(); a = QActive_registry_[p]; // the AO must be registered with the framework Q_ASSERT_INCRIT(220, a != (QActive *)0); - QF_MEM_APP(); QF_CRIT_EXIT(); } else { p = 0U; // no more subscribers } - } while ((p != 0U) && (lbound > 0U)); + } while (p != 0U); QF_CRIT_ENTRY(); - // 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 + Q_ASSERT_INCRIT(290, p == 0U); // all subscribers processed QF_CRIT_EXIT(); QF_SCHED_UNLOCK_(); // unlock the scheduler } +#if (QF_MAX_EPOOL > 0U) // The following garbage collection step decrements the reference counter // and recycles the event if the counter drops to zero. This covers both // cases when the event was published with or without any subscribers. - #if (QF_MAX_EPOOL > 0U) QF_gc(e); // recycle the event to avoid a leak - #endif +#endif } -//$enddef${QF::QActive::publish_} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -//$define${QF::QActive::subscribe} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -//${QF::QActive::subscribe} .................................................. +//............................................................................ //! @protected @memberof QActive void QActive_subscribe(QActive const * const me, enum_t const sig) @@ -200,15 +160,11 @@ void QActive_subscribe(QActive const * const me, QF_CRIT_STAT QF_CRIT_ENTRY(); - QF_MEM_SYS(); Q_REQUIRE_INCRIT(300, (Q_USER_SIG <= sig) && (sig < QActive_maxPubSignal_) && (0U < p) && (p <= QF_MAX_ACTIVE) && (QActive_registry_[p] == me)); - Q_INVARIANT_INCRIT(302, - QPSet_verify_(&QActive_subscrList_[sig].set, - &QActive_subscrList_[sig].set_dis)); QS_BEGIN_PRE(QS_QF_ACTIVE_SUBSCRIBE, p) QS_TIME_PRE(); // timestamp @@ -218,19 +174,11 @@ void QActive_subscribe(QActive const * const me, // insert the prio. into the subscriber set QPSet_insert(&QActive_subscrList_[sig].set, p); - #ifndef Q_UNSAFE - QPSet_update_(&QActive_subscrList_[sig].set, - &QActive_subscrList_[sig].set_dis); - #endif - QF_MEM_APP(); QF_CRIT_EXIT(); } -//$enddef${QF::QActive::subscribe} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -//$define${QF::QActive::unsubscribe} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QF::QActive::unsubscribe} ................................................ +//............................................................................ //! @protected @memberof QActive void QActive_unsubscribe(QActive const * const me, enum_t const sig) @@ -239,15 +187,11 @@ void QActive_unsubscribe(QActive const * const me, QF_CRIT_STAT QF_CRIT_ENTRY(); - QF_MEM_SYS(); Q_REQUIRE_INCRIT(400, (Q_USER_SIG <= sig) && (sig < QActive_maxPubSignal_) && (0U < p) && (p <= QF_MAX_ACTIVE) && (QActive_registry_[p] == me)); - Q_INVARIANT_INCRIT(402, - QPSet_verify_(&QActive_subscrList_[sig].set, - &QActive_subscrList_[sig].set_dis)); QS_BEGIN_PRE(QS_QF_ACTIVE_UNSUBSCRIBE, p) QS_TIME_PRE(); // timestamp @@ -257,24 +201,15 @@ void QActive_unsubscribe(QActive const * const me, // remove the prio. from the subscriber set QPSet_remove(&QActive_subscrList_[sig].set, p); - #ifndef Q_UNSAFE - QPSet_update_(&QActive_subscrList_[sig].set, - &QActive_subscrList_[sig].set_dis); - #endif - QF_MEM_APP(); QF_CRIT_EXIT(); } -//$enddef${QF::QActive::unsubscribe} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -//$define${QF::QActive::unsubscribeAll} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -//${QF::QActive::unsubscribeAll} ............................................. +//............................................................................ //! @protected @memberof QActive void QActive_unsubscribeAll(QActive const * const me) { QF_CRIT_STAT QF_CRIT_ENTRY(); - QF_MEM_SYS(); uint_fast8_t const p = (uint_fast8_t)me->prio; @@ -282,29 +217,22 @@ void QActive_unsubscribeAll(QActive const * const me) { && (QActive_registry_[p] == me)); enum_t const maxPubSig = QActive_maxPubSignal_; - QF_MEM_APP(); QF_CRIT_EXIT(); for (enum_t sig = Q_USER_SIG; sig < maxPubSig; ++sig) { QF_CRIT_ENTRY(); - QF_MEM_SYS(); if (QPSet_hasElement(&QActive_subscrList_[sig].set, p)) { QPSet_remove(&QActive_subscrList_[sig].set, p); - #ifndef Q_UNSAFE - QPSet_update_(&QActive_subscrList_[sig].set, - &QActive_subscrList_[sig].set_dis); - #endif + QS_BEGIN_PRE(QS_QF_ACTIVE_UNSUBSCRIBE, p) QS_TIME_PRE(); // timestamp QS_SIG_PRE(sig); // the signal of this event QS_OBJ_PRE(me); // this active object QS_END_PRE() } - QF_MEM_APP(); QF_CRIT_EXIT(); QF_CRIT_EXIT_NOP(); // prevent merging critical sections } } -//$enddef${QF::QActive::unsubscribeAll} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/qf/qf_qact.c b/src/qf/qf_qact.c index 24d9f437d..d0b0e4749 100644 --- a/src/qf/qf_qact.c +++ b/src/qf/qf_qact.c @@ -1,10 +1,6 @@ -//$file${src::qf::qf_qact.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// -// Model: qpc.qm -// File: ${src::qf::qf_qact.c} -// -// This code has been generated by QM 7.0.0 . -// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // @@ -14,7 +10,7 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -30,8 +26,7 @@ // Quantum Leaps contact information: // // -// -//$endhead${src::qf::qf_qact.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//============================================================================ #define QP_IMPL // this is QP implementation #include "qp_port.h" // QP port #include "qp_pkg.h" // QP package-scope interface @@ -45,15 +40,7 @@ Q_DEFINE_THIS_MODULE("qf_qact") -//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// Check for the minimum required QP version -#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U)%0x2710U)) -#error qpc version 7.3.0 or higher required -#endif -//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -//$define${QF::QActive::ctor} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QF::QActive::ctor} ....................................................... +//............................................................................ //! @protected @memberof QActive void QActive_ctor(QActive * const me, QStateHandler const initial) @@ -75,83 +62,74 @@ void QActive_ctor(QActive * const me, &QHsm_init_, &QHsm_dispatch_, &QHsm_isIn_ - #ifdef Q_SPY +#ifdef Q_SPY ,&QHsm_getStateHandler_ - #endif +#endif }; me->super.vptr = &vtable; // hook vptr to QActive vtable } -//$enddef${QF::QActive::ctor} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -//$define${QF::QActive::register_} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QF::QActive::register_} .................................................. +//............................................................................ //! @private @memberof QActive void QActive_register_(QActive * const me) { QF_CRIT_STAT QF_CRIT_ENTRY(); - QF_MEM_SYS(); if (me->pthre == 0U) { // preemption-threshold not defined? me->pthre = me->prio; // apply the default } - #ifndef Q_UNSAFE - - Q_REQUIRE_INCRIT(100, (0U < me->prio) && (me->prio <= QF_MAX_ACTIVE) - && (QActive_registry_[me->prio] == (QActive *)0) - && (me->prio <= me->pthre)); +#ifndef Q_UNSAFE + Q_REQUIRE_INCRIT(100, + (0U < me->prio) && (me->prio <= QF_MAX_ACTIVE) + && (QActive_registry_[me->prio] == (QActive *)0) + && (me->prio <= me->pthre)); uint8_t prev_thre = me->pthre; uint8_t next_thre = me->pthre; - uint_fast8_t p; - for (p = (uint_fast8_t)me->prio - 1U; p > 0U; --p) { + for (uint_fast8_t p = (uint_fast8_t)me->prio - 1U; + p > 0U; + --p) + { if (QActive_registry_[p] != (QActive *)0) { prev_thre = QActive_registry_[p]->pthre; break; } } - for (p = (uint_fast8_t)me->prio + 1U; p <= QF_MAX_ACTIVE; ++p) { + for (uint_fast8_t p = (uint_fast8_t)me->prio + 1U; + p <= QF_MAX_ACTIVE; + ++p) + { if (QActive_registry_[p] != (QActive *)0) { next_thre = QActive_registry_[p]->pthre; break; } } - Q_ASSERT_INCRIT(190, (prev_thre <= me->pthre) - && (me->pthre <= next_thre)); - - me->prio_dis = (uint8_t)(~me->prio); - me->pthre_dis = (uint8_t)(~me->pthre); - - #endif // Q_UNSAFE + Q_ASSERT_INCRIT(190, + (prev_thre <= me->pthre) + && (me->pthre <= next_thre)); +#endif // Q_UNSAFE // register the AO at the QF-prio. QActive_registry_[me->prio] = me; - QF_MEM_APP(); QF_CRIT_EXIT(); } -//$enddef${QF::QActive::register_} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -//$define${QF::QActive::unregister_} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -//${QF::QActive::unregister_} ................................................ +//............................................................................ //! @private @memberof QActive void QActive_unregister_(QActive * const me) { uint_fast8_t const p = (uint_fast8_t)me->prio; QF_CRIT_STAT QF_CRIT_ENTRY(); - QF_MEM_SYS(); Q_REQUIRE_INCRIT(200, (0U < p) && (p <= QF_MAX_ACTIVE) && (QActive_registry_[p] == me)); QActive_registry_[p] = (QActive *)0; // free-up the prio. level me->super.state.fun = Q_STATE_CAST(0); // invalidate the state - QF_MEM_APP(); QF_CRIT_EXIT(); } -//$enddef${QF::QActive::unregister_} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/qf/qf_qeq.c b/src/qf/qf_qeq.c index c800f67e9..f98cd7192 100644 --- a/src/qf/qf_qeq.c +++ b/src/qf/qf_qeq.c @@ -1,10 +1,6 @@ -//$file${src::qf::qf_qeq.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// -// Model: qpc.qm -// File: ${src::qf::qf_qeq.c} -// -// This code has been generated by QM 7.0.0 . -// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // @@ -14,7 +10,7 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -30,8 +26,7 @@ // Quantum Leaps contact information: // // -// -//$endhead${src::qf::qf_qeq.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//============================================================================ #define QP_IMPL // this is QP implementation #include "qp_port.h" // QP port #include "qp_pkg.h" // QP package-scope interface @@ -45,17 +40,7 @@ Q_DEFINE_THIS_MODULE("qf_qeq") -//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// Check for the minimum required QP version -#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U)%0x2710U)) -#error qpc version 7.3.0 or higher required -#endif -//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -//$define${QF::QEQueue} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QF::QEQueue} ............................................................. - -//${QF::QEQueue::init} ....................................................... +//............................................................................ //! @public @memberof QEQueue void QEQueue_init(QEQueue * const me, struct QEvt const * * const qSto, @@ -63,11 +48,10 @@ void QEQueue_init(QEQueue * const me, { QF_CRIT_STAT QF_CRIT_ENTRY(); - QF_MEM_SYS(); - #if (QF_EQUEUE_CTR_SIZE == 1U) +#if (QF_EQUEUE_CTR_SIZE == 1U) Q_REQUIRE_INCRIT(100, qLen < 0xFFU); - #endif +#endif me->frontEvt = (QEvt *)0; // no events in the queue me->ring = qSto; // the beginning of the ring buffer @@ -77,98 +61,62 @@ void QEQueue_init(QEQueue * const me, me->tail = 0U; } me->nFree = (QEQueueCtr)(qLen + 1U); // +1 for frontEvt + me->nMin = me->nFree; - #ifndef Q_UNSAFE - me->frontEvt_dis = (uintptr_t)~Q_PTR2UINT_CAST_(me->frontEvt); - me->head_dis = (QEQueueCtr)~me->head; - me->tail_dis = (QEQueueCtr)~me->tail; - me->nFree_dis = (QEQueueCtr)~me->nFree; - me->nMin = me->nFree; - #endif - - QF_MEM_APP(); QF_CRIT_EXIT(); } -//${QF::QEQueue::post} ....................................................... +//............................................................................ //! @public @memberof QEQueue bool QEQueue_post(QEQueue * const me, struct QEvt const * const e, uint_fast16_t const margin, uint_fast8_t const qsId) { - #ifndef Q_SPY +#ifndef Q_SPY Q_UNUSED_PAR(qsId); - #endif +#endif QF_CRIT_STAT QF_CRIT_ENTRY(); - QF_MEM_SYS(); Q_REQUIRE_INCRIT(200, e != (QEvt *)0); QEQueueCtr tmp = me->nFree; // get volatile into temporary - #ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(201, QEvt_verify_(e)); - QEQueueCtr dis = (QEQueueCtr)~me->nFree_dis; - Q_INVARIANT_INCRIT(202, tmp == dis); - #endif // ndef Q_UNSAFE - - // test-probe#1 for faking queue overflow - QS_TEST_PROBE_DEF(&QEQueue_post) - QS_TEST_PROBE_ID(1, - tmp = 0U; // fake no free events - ) - - // required margin available? - bool status; - if (((margin == QF_NO_MARGIN) && (tmp > 0U)) - || (tmp > (QEQueueCtr)margin)) - { + // can the queue accept the event? + bool const status = ((margin == QF_NO_MARGIN) && (tmp > 0U)) + || (tmp > (QEQueueCtr)margin); + if (status) { // is it a mutable event? - if (QEvt_getPoolNum_(e) != 0U) { + if (e->poolNum_ != 0U) { + Q_ASSERT_INCRIT(205, e->refCtr_ < (2U * QF_MAX_ACTIVE)); QEvt_refCtr_inc_(e); // increment the reference counter } --tmp; // one free entry just used up me->nFree = tmp; // update the original - #ifndef Q_UNSAFE - me->nFree_dis = (QEQueueCtr)~tmp; - - if (me->nMin > tmp) { + if (me->nMin > tmp) { // is this the new minimum? me->nMin = tmp; // update minimum so far } - #endif // ndef Q_UNSAFE +#ifdef Q_SPY QS_BEGIN_PRE(QS_QF_EQUEUE_POST, qsId) QS_TIME_PRE(); // timestamp QS_SIG_PRE(e->sig); // the signal of the event QS_OBJ_PRE(me); // this queue object - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_2U8_PRE(e->poolNum_, e->refCtr_); QS_EQC_PRE(tmp); // # free entries - #ifndef Q_UNSAFE QS_EQC_PRE(me->nMin); // min # free entries - #else - QS_EQC_PRE(0U); // min # free entries - #endif QS_END_PRE() +#endif // def Q_SPY if (me->frontEvt == (QEvt *)0) { // is the queue empty? me->frontEvt = e; // deliver event directly - #ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(211, me->frontEvt_dis - == (uintptr_t)~Q_PTR2UINT_CAST_((QEvt *)0)); - me->frontEvt_dis = (uintptr_t)~Q_PTR2UINT_CAST_(e); - #endif // ndef Q_UNSAFE } else { // queue was not empty, insert event into the ring-buffer tmp = me->head; // get volatile into temporary - #ifndef Q_UNSAFE - dis = (QEQueueCtr)~me->head_dis; - Q_INVARIANT_INCRIT(212, tmp == dis); - #endif // ndef Q_UNSAFE me->ring[tmp] = e; // insert e into buffer if (tmp == 0U) { // need to wrap the head? @@ -177,154 +125,106 @@ bool QEQueue_post(QEQueue * const me, --tmp; // advance head (counter-clockwise) me->head = tmp; // update the original - #ifndef Q_UNSAFE - me->head_dis = (QEQueueCtr)~tmp; - #endif // ndef Q_UNSAFE } - status = true; // event posted successfully } else { // event cannot be posted // dropping events must be acceptable - Q_ASSERT_INCRIT(210, margin != QF_NO_MARGIN); + Q_ASSERT_INCRIT(230, margin != QF_NO_MARGIN); +#ifdef Q_SPY QS_BEGIN_PRE(QS_QF_EQUEUE_POST_ATTEMPT, qsId) QS_TIME_PRE(); // timestamp QS_SIG_PRE(e->sig); // the signal of this event QS_OBJ_PRE(me); // this queue object - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_2U8_PRE(e->poolNum_, e->refCtr_); QS_EQC_PRE(tmp); // # free entries QS_EQC_PRE(margin); // margin requested QS_END_PRE() - - status = false; // event not posted +#endif // def Q_SPY } - QF_MEM_APP(); QF_CRIT_EXIT(); return status; } -//${QF::QEQueue::postLIFO} ................................................... +//............................................................................ //! @public @memberof QEQueue void QEQueue_postLIFO(QEQueue * const me, struct QEvt const * const e, uint_fast8_t const qsId) { - #ifndef Q_SPY +#ifndef Q_SPY Q_UNUSED_PAR(qsId); - #endif +#endif QF_CRIT_STAT QF_CRIT_ENTRY(); - QF_MEM_SYS(); Q_REQUIRE_INCRIT(300, e != (QEvt *)0); QEQueueCtr tmp = me->nFree; // get volatile into temporary - #ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(301, QEvt_verify_(e)); - QEQueueCtr dis = (QEQueueCtr)~me->nFree_dis; - Q_INVARIANT_INCRIT(302, tmp == dis); - #endif // ndef Q_UNSAFE - - // test-probe#1 for faking queue overflow - QS_TEST_PROBE_DEF(&QEQueue_postLIFO) - QS_TEST_PROBE_ID(1, - tmp = 0U; // fake no free events - ) - // must be able to LIFO-post the event Q_REQUIRE_INCRIT(310, tmp != 0U); - if (QEvt_getPoolNum_(e) != 0U) { // is it a mutable event? + if (e->poolNum_ != 0U) { // is it a mutable event? + Q_ASSERT_INCRIT(305, e->refCtr_ < (2U * QF_MAX_ACTIVE)); QEvt_refCtr_inc_(e); // increment the reference counter } --tmp; // one free entry just used up me->nFree = tmp; // update the original - #ifndef Q_UNSAFE - me->nFree_dis = (QEQueueCtr)~tmp; - - if (me->nMin > tmp) { + if (me->nMin > tmp) { // is this the new minimum? me->nMin = tmp; // update minimum so far } - #endif // ndef Q_UNSAFE QS_BEGIN_PRE(QS_QF_EQUEUE_POST_LIFO, qsId) QS_TIME_PRE(); // timestamp QS_SIG_PRE(e->sig); // the signal of this event QS_OBJ_PRE(me); // this queue object - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_2U8_PRE(e->poolNum_, e->refCtr_); QS_EQC_PRE(tmp); // # free entries - #ifndef Q_UNSAFE QS_EQC_PRE(me->nMin); // min # free entries - #else - QS_EQC_PRE(0U); // min # free entries - #endif QS_END_PRE() QEvt const * const frontEvt = me->frontEvt; me->frontEvt = e; // deliver the event directly to the front - #ifndef Q_UNSAFE - me->frontEvt_dis = (uintptr_t)~Q_PTR2UINT_CAST_(e); - #endif // ndef Q_UNSAFE if (frontEvt != (QEvt *)0) { // was the queue NOT empty? tmp = me->tail; // get volatile into temporary; - #ifndef Q_UNSAFE - dis = (QEQueueCtr)~me->tail_dis; - Q_INVARIANT_INCRIT(311, tmp == dis); - #endif // ndef Q_UNSAFE ++tmp; if (tmp == me->end) { // need to wrap the tail? tmp = 0U; // wrap around } me->tail = tmp; - #ifndef Q_UNSAFE - me->tail_dis = (QEQueueCtr)~tmp; - #endif me->ring[tmp] = frontEvt; } - QF_MEM_APP(); QF_CRIT_EXIT(); } -//${QF::QEQueue::get} ........................................................ +//............................................................................ //! @public @memberof QEQueue struct QEvt const * QEQueue_get(QEQueue * const me, uint_fast8_t const qsId) { - #ifndef Q_SPY +#ifndef Q_SPY Q_UNUSED_PAR(qsId); - #endif +#endif QF_CRIT_STAT QF_CRIT_ENTRY(); - QF_MEM_SYS(); QEvt const * const e = me->frontEvt; // always remove evt from the front - #ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(411, Q_PTR2UINT_CAST_(e) - == (uintptr_t)~me->frontEvt_dis); - #endif // ndef Q_UNSAFE if (e != (QEvt *)0) { // was the queue not empty? QEQueueCtr tmp = me->nFree; // get volatile into temporary - #ifndef Q_UNSAFE - QEQueueCtr const dis = (QEQueueCtr)~me->nFree_dis; - Q_INVARIANT_INCRIT(412, tmp == dis); - #endif // ndef Q_UNSAFE ++tmp; // one more free event in the queue me->nFree = tmp; // update the # free - #ifndef Q_UNSAFE - me->nFree_dis = (QEQueueCtr)~tmp; - #endif // ndef Q_UNSAFE // any events in the ring buffer? if (tmp <= me->end) { @@ -333,16 +233,15 @@ struct QEvt const * QEQueue_get(QEQueue * const me, QS_TIME_PRE(); // timestamp QS_SIG_PRE(e->sig); // the signal of this event QS_OBJ_PRE(me); // this queue object - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_2U8_PRE(e->poolNum_, e->refCtr_); QS_EQC_PRE(tmp); // # free entries QS_END_PRE() tmp = me->tail; // get volatile into temporary QEvt const * const frontEvt = me->ring[tmp]; - #ifndef Q_UNSAFE - Q_ASSERT_INCRIT(421, frontEvt != (QEvt *)0); - me->frontEvt_dis = (uintptr_t)~Q_PTR2UINT_CAST_(frontEvt); - #endif // ndef Q_UNSAFE + + Q_ASSERT_INCRIT(420, frontEvt != (QEvt *)0); + me->frontEvt = frontEvt; // update the original if (tmp == 0U) { // need to wrap the tail? @@ -350,31 +249,23 @@ struct QEvt const * QEQueue_get(QEQueue * const me, } --tmp; // advance the tail (counter-clockwise) me->tail = tmp; // update the original - #ifndef Q_UNSAFE - me->tail_dis = (QEQueueCtr)~tmp; - #endif // ndef Q_UNSAFE } else { me->frontEvt = (QEvt *)0; // queue becomes empty - #ifndef Q_UNSAFE - me->frontEvt_dis = (uintptr_t)~Q_PTR2UINT_CAST_((QEvt *)0); - #endif // ndef Q_UNSAFE // all entries in the queue must be free (+1 for frontEvt) - Q_INVARIANT_INCRIT(440, tmp == (me->end + 1U)); + Q_ASSERT_INCRIT(440, tmp == (me->end + 1U)); QS_BEGIN_PRE(QS_QF_EQUEUE_GET_LAST, qsId) QS_TIME_PRE(); // timestamp QS_SIG_PRE(e->sig); // the signal of this event QS_OBJ_PRE(me); // this queue object - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_2U8_PRE(e->poolNum_, e->refCtr_); QS_END_PRE() } } - QF_MEM_APP(); QF_CRIT_EXIT(); return e; } -//$enddef${QF::QEQueue} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/qf/qf_qmact.c b/src/qf/qf_qmact.c index 2f7b88618..b1844e8c5 100644 --- a/src/qf/qf_qmact.c +++ b/src/qf/qf_qmact.c @@ -1,10 +1,6 @@ -//$file${src::qf::qf_qmact.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// -// Model: qpc.qm -// File: ${src::qf::qf_qmact.c} -// -// This code has been generated by QM 7.0.0 . -// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // @@ -14,7 +10,7 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -30,8 +26,7 @@ // Quantum Leaps contact information: // // -// -//$endhead${src::qf::qf_qmact.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//============================================================================ #define QP_IMPL // this is QP implementation #include "qp_port.h" // QP port #include "qp_pkg.h" // QP package-scope interface @@ -45,17 +40,7 @@ //Q_DEFINE_THIS_MODULE("qf_qmact") -//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// Check for the minimum required QP version -#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U)%0x2710U)) -#error qpc version 7.3.0 or higher required -#endif -//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -//$define${QF::QMActive} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QF::QMActive} ............................................................ - -//${QF::QMActive::ctor} ...................................................... +//............................................................................ //! @protected @memberof QMActive void QMActive_ctor(QMActive * const me, QStateHandler const initial) @@ -77,10 +62,9 @@ void QMActive_ctor(QMActive * const me, &QMsm_init_, &QMsm_dispatch_, &QMsm_isIn_ - #ifdef Q_SPY +#ifdef Q_SPY ,&QMsm_getStateHandler_ - #endif +#endif }; me->super.super.vptr = &vtable; // hook vptr to QMActive vtable } -//$enddef${QF::QMActive} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/qf/qf_time.c b/src/qf/qf_time.c index 4138c2a3c..0d73b34a0 100644 --- a/src/qf/qf_time.c +++ b/src/qf/qf_time.c @@ -1,10 +1,6 @@ -//$file${src::qf::qf_time.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// -// Model: qpc.qm -// File: ${src::qf::qf_time.c} -// -// This code has been generated by QM 7.0.0 . -// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // @@ -14,7 +10,7 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -30,8 +26,7 @@ // Quantum Leaps contact information: // // -// -//$endhead${src::qf::qf_time.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//============================================================================ #define QP_IMPL // this is QP implementation #include "qp_port.h" // QP port #include "qp_pkg.h" // QP package-scope interface @@ -45,22 +40,10 @@ Q_DEFINE_THIS_MODULE("qf_time") -//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// Check for the minimum required QP version -#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U)%0x2710U)) -#error qpc version 7.3.0 or higher required -#endif -//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -//$define${QF::QTimeEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QF::QTimeEvt} ............................................................ +//............................................................................ QTimeEvt QTimeEvt_timeEvtHead_[QF_MAX_TICK_RATE]; -#ifndef Q_UNSAFE -uintptr_t QTimeEvt_timeEvtHead_dis_[QF_MAX_TICK_RATE]; -#endif // ndef Q_UNSAFE - -//${QF::QTimeEvt::ctorX} ..................................................... +//............................................................................ //! @public @memberof QTimeEvt void QTimeEvt_ctorX(QTimeEvt * const me, QActive * const act, @@ -82,13 +65,10 @@ void QTimeEvt_ctorX(QTimeEvt * const me, me->tickRate = (uint8_t)tickRate; me->flags = 0U; - #ifndef Q_UNSAFE - me->next_dis = (uintptr_t)~Q_PTR2UINT_CAST_(me->next); - me->ctr_dis = (QTimeEvtCtr)~me->ctr; - #endif // ndef Q_UNSAFE + me->super.refCtr_ = 0U; // adjust from the QEvt_ctor((sig) ctor } -//${QF::QTimeEvt::armX} ...................................................... +//............................................................................ //! @public @memberof QTimeEvt void QTimeEvt_armX(QTimeEvt * const me, uint32_t const nTicks, @@ -96,24 +76,19 @@ void QTimeEvt_armX(QTimeEvt * const me, { QF_CRIT_STAT QF_CRIT_ENTRY(); - QF_MEM_SYS(); // dynamic range checks - #if (QF_TIMEEVT_CTR_SIZE == 1U) +#if (QF_TIMEEVT_CTR_SIZE == 1U) Q_REQUIRE_INCRIT(400, (nTicks < 0xFFU) && (interval < 0xFFU)); - #elif (QF_TIMEEVT_CTR_SIZE == 2U) +#elif (QF_TIMEEVT_CTR_SIZE == 2U) Q_REQUIRE_INCRIT(400, (nTicks < 0xFFFFU) && (interval < 0xFFFFU)); - #endif - - #ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(401, QEvt_verify_(&me->super)); - #endif +#endif QTimeEvtCtr const ctr = me->ctr; uint8_t const tickRate = me->tickRate; - #ifdef Q_SPY +#ifdef Q_SPY uint_fast8_t const qsId = ((QActive *)(me->act))->prio; - #endif +#endif // def Q_SPY Q_REQUIRE_INCRIT(410, (nTicks != 0U) @@ -121,18 +96,12 @@ void QTimeEvt_armX(QTimeEvt * const me, && (me->act != (void *)0) && (tickRate < (uint_fast8_t)QF_MAX_TICK_RATE)); - #ifndef Q_UNSAFE - QTimeEvtCtr const dis = (QTimeEvtCtr)~me->ctr_dis; - Q_INVARIANT_INCRIT(411, ctr == dis); - #else +#ifdef Q_UNSAFE Q_UNUSED_PAR(ctr); - #endif // ndef Q_UNSAFE +#endif // ndef Q_UNSAFE me->ctr = (QTimeEvtCtr)nTicks; me->interval = (QTimeEvtCtr)interval; - #ifndef Q_UNSAFE - me->ctr_dis = (QTimeEvtCtr)~nTicks; - #endif // ndef Q_UNSAFE // is the time event unlinked? // NOTE: For the duration of a single clock tick of the specified tick @@ -141,26 +110,14 @@ void QTimeEvt_armX(QTimeEvt * const me, if ((me->flags & QTE_FLAG_IS_LINKED) == 0U) { me->flags |= QTE_FLAG_IS_LINKED; // mark as linked - // The time event is initially inserted into the separate "freshly - // armed" link list based on QTimeEvt_timeEvtHead_[tickRate].act. - // Only later, inside the QTimeEvt_tick_() function, the "freshly - // armed" list is appended to the main list of armed time events - // based on QTimeEvt_timeEvtHead_[tickRate].next. Again, this is - // to keep any changes to the main list exclusively inside the - // QTimeEvt_tick_(). - #ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(420, - Q_PTR2UINT_CAST_(me->next) == (uintptr_t)~me->next_dis); - Q_INVARIANT_INCRIT(421, - Q_PTR2UINT_CAST_(QTimeEvt_timeEvtHead_[tickRate].act) == - (uintptr_t)(~QTimeEvt_timeEvtHead_dis_[tickRate])); - #endif + // The time event is initially inserted into the separate + // "freshly armed" list based on timeEvtHead_[tickRate].act. + // Only later, inside QTimeEvt_tick_(), the "freshly armed" + // list is appended to the main list of armed time events based on + // timeEvtHead_[tickRate].next. Again, this is to keep any + // changes to the main list exclusively inside QTimeEvt_tick_(). me->next = (QTimeEvt *)QTimeEvt_timeEvtHead_[tickRate].act; QTimeEvt_timeEvtHead_[tickRate].act = me; - #ifndef Q_UNSAFE - me->next_dis = (uintptr_t)~Q_PTR2UINT_CAST_(me->next); - QTimeEvt_timeEvtHead_dis_[tickRate] = (uintptr_t)~Q_PTR2UINT_CAST_(me); - #endif // ndef Q_UNSAFE } QS_BEGIN_PRE(QS_QF_TIMEEVT_ARM, qsId) @@ -172,38 +129,27 @@ void QTimeEvt_armX(QTimeEvt * const me, QS_U8_PRE(tickRate); // tick rate QS_END_PRE() - QF_MEM_APP(); QF_CRIT_EXIT(); } -//${QF::QTimeEvt::disarm} .................................................... +//............................................................................ //! @public @memberof QTimeEvt bool QTimeEvt_disarm(QTimeEvt * const me) { QF_CRIT_STAT QF_CRIT_ENTRY(); - QF_MEM_SYS(); QTimeEvtCtr const ctr = me->ctr; - #ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(500, QEvt_verify_(&me->super)); - QTimeEvtCtr const dis = (QTimeEvtCtr)~me->ctr_dis; - Q_INVARIANT_INCRIT(501, ctr == dis); - #endif // ndef Q_UNSAFE - - #ifdef Q_SPY +#ifdef Q_SPY uint_fast8_t const qsId = QACTIVE_CAST_(me->act)->prio; - #endif +#endif // was the time event actually armed? - bool wasArmed; + bool wasArmed = false; if (ctr != 0U) { wasArmed = true; me->flags |= QTE_FLAG_WAS_DISARMED; me->ctr = 0U; // schedule removal from the list - #ifndef Q_UNSAFE - me->ctr_dis = (QTimeEvtCtr)~0U; - #endif // ndef Q_UNSAFE QS_BEGIN_PRE(QS_QF_TIMEEVT_DISARM, qsId) QS_TIME_PRE(); // timestamp @@ -215,7 +161,6 @@ bool QTimeEvt_disarm(QTimeEvt * const me) { QS_END_PRE() } else { // the time event was already disarmed automatically - wasArmed = false; me->flags &= (uint8_t)(~QTE_FLAG_WAS_DISARMED & 0xFFU); QS_BEGIN_PRE(QS_QF_TIMEEVT_DISARM_ATTEMPT, qsId) @@ -226,56 +171,43 @@ bool QTimeEvt_disarm(QTimeEvt * const me) { QS_END_PRE() } - QF_MEM_APP(); QF_CRIT_EXIT(); return wasArmed; } -//${QF::QTimeEvt::rearm} ..................................................... +//............................................................................ //! @public @memberof QTimeEvt bool QTimeEvt_rearm(QTimeEvt * const me, uint32_t const nTicks) { QF_CRIT_STAT QF_CRIT_ENTRY(); - QF_MEM_SYS(); // dynamic range checks - #if (QF_TIMEEVT_CTR_SIZE == 1U) +#if (QF_TIMEEVT_CTR_SIZE == 1U) Q_REQUIRE_INCRIT(600, nTicks < 0xFFU); - #elif (QF_TIMEEVT_CTR_SIZE == 2U) +#elif (QF_TIMEEVT_CTR_SIZE == 2U) Q_REQUIRE_INCRIT(600, nTicks < 0xFFFFU); - #endif +#endif uint8_t const tickRate = me->tickRate; QTimeEvtCtr const ctr = me->ctr; - Q_REQUIRE_INCRIT(600, + Q_REQUIRE_INCRIT(610, (nTicks != 0U) && (me->act != (void *)0) && (tickRate < QF_MAX_TICK_RATE)); - #ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(601, QEvt_verify_(&me->super)); - QTimeEvtCtr const dis = (QTimeEvtCtr)~me->ctr_dis; - Q_INVARIANT_INCRIT(602, ctr == dis); - #endif // ndef Q_UNSAFE - - #ifdef Q_SPY +#ifdef Q_SPY uint_fast8_t const qsId = ((QActive *)(me->act))->prio; - #endif +#endif me->ctr = (QTimeEvtCtr)nTicks; - #ifndef Q_UNSAFE - me->ctr_dis = (QTimeEvtCtr)~nTicks; - #endif // ndef Q_UNSAFE // was the time evt not running? - bool wasArmed; + bool wasArmed = false; if (ctr == 0U) { - wasArmed = false; - // NOTE: For the duration of a single clock tick of the specified // tick rate a time event can be disarmed and yet still linked into // the list, because unlinking is performed exclusively in the @@ -285,27 +217,14 @@ bool QTimeEvt_rearm(QTimeEvt * const me, if ((me->flags & QTE_FLAG_IS_LINKED) == 0U) { me->flags |= QTE_FLAG_IS_LINKED; // mark as linked - // The time event is initially inserted into the separate "freshly - // armed" link list based on QTimeEvt_timeEvtHead_[tickRate].act. - // Only later, inside the QTimeEvt_tick_() function, the "freshly - // armed" list is appended to the main list of armed time events - // based on QTimeEvt_timeEvtHead_[tickRate].next. Again, this is - // to keep any changes to the main list exclusively inside - // QTimeEvt_tick_(). - #ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(620, - Q_PTR2UINT_CAST_(me->next) == (uintptr_t)~me->next_dis); - Q_INVARIANT_INCRIT(621, - Q_PTR2UINT_CAST_(QTimeEvt_timeEvtHead_[tickRate].act) == - (uintptr_t)(~QTimeEvt_timeEvtHead_dis_[tickRate])); - #endif + // The time event is initially inserted into the separate + // "freshly armed" list based on timeEvtHead_[tickRate].act. + // Only later, inside QTimeEvt_tick_(), the "freshly armed" + // list is appended to the main list of armed time events based on + // timeEvtHead_[tickRate].next. Again, this is to keep any + // changes to the main list exclusively inside QTimeEvt_tick()_. me->next = (QTimeEvt *)QTimeEvt_timeEvtHead_[tickRate].act; QTimeEvt_timeEvtHead_[tickRate].act = me; - #ifndef Q_UNSAFE - me->next_dis = (uintptr_t)~Q_PTR2UINT_CAST_(me->next); - QTimeEvt_timeEvtHead_dis_[tickRate] = - (uintptr_t)~Q_PTR2UINT_CAST_(me); - #endif // ndef Q_UNSAFE } } else { // the time event was armed @@ -321,29 +240,26 @@ bool QTimeEvt_rearm(QTimeEvt * const me, QS_2U8_PRE(tickRate, (wasArmed ? 1U : 0U)); QS_END_PRE() - QF_MEM_APP(); QF_CRIT_EXIT(); return wasArmed; } -//${QF::QTimeEvt::wasDisarmed} ............................................... +//............................................................................ //! @public @memberof QTimeEvt bool QTimeEvt_wasDisarmed(QTimeEvt * const me) { QF_CRIT_STAT QF_CRIT_ENTRY(); - QF_MEM_SYS(); bool const wasDisarmed = (me->flags & QTE_FLAG_WAS_DISARMED) != 0U; me->flags |= QTE_FLAG_WAS_DISARMED; // mark as disarmed - QF_MEM_APP(); QF_CRIT_EXIT(); return wasDisarmed; } -//${QF::QTimeEvt::currCtr} ................................................... +//............................................................................ //! @public @memberof QTimeEvt QTimeEvtCtr QTimeEvt_currCtr(QTimeEvt const * const me) { QF_CRIT_STAT @@ -354,7 +270,7 @@ QTimeEvtCtr QTimeEvt_currCtr(QTimeEvt const * const me) { return ctr; } -//${QF::QTimeEvt::init} ...................................................... +//............................................................................ //! @static @private @memberof QTimeEvt void QTimeEvt_init(void) { for (uint_fast8_t tickRate = 0U; @@ -363,206 +279,160 @@ void QTimeEvt_init(void) { { QTimeEvt_ctorX(&QTimeEvt_timeEvtHead_[tickRate], (QActive *)0, Q_USER_SIG, tickRate); - #ifndef Q_UNSAFE - QTimeEvt_timeEvtHead_dis_[tickRate] = - (uintptr_t)~Q_PTR2UINT_CAST_(QTimeEvt_timeEvtHead_[tickRate].act); - #endif } } -//${QF::QTimeEvt::tick_} ..................................................... +//............................................................................ //! @static @private @memberof QTimeEvt void QTimeEvt_tick_( uint_fast8_t const tickRate, void const * const sender) { - #ifndef Q_SPY +#ifndef Q_SPY Q_UNUSED_PAR(sender); - #endif +#endif QF_CRIT_STAT QF_CRIT_ENTRY(); - QF_MEM_SYS(); Q_REQUIRE_INCRIT(800, tickRate < Q_DIM(QTimeEvt_timeEvtHead_)); QTimeEvt *prev = &QTimeEvt_timeEvtHead_[tickRate]; +#ifdef Q_SPY QS_BEGIN_PRE(QS_QF_TICK, 0U) ++prev->ctr; QS_TEC_PRE(prev->ctr); // tick ctr QS_U8_PRE(tickRate); // tick rate QS_END_PRE() +#endif // def Q_SPY // scan the linked-list of time events at this rate... - uint_fast8_t lbound = 2U*QF_MAX_ACTIVE; // fixed upper loop bound - for (; lbound > 0U; --lbound) { + while (true) { Q_ASSERT_INCRIT(810, prev != (QTimeEvt *)0); // sanity check QTimeEvt *te = prev->next; // advance down the time evt. list - #ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(811, - Q_PTR2UINT_CAST_(te) == (uintptr_t)~prev->next_dis); - #endif // ndef Q_UNSAFE if (te == (QTimeEvt *)0) { // end of the list? - - // any new time events armed since the last QTimeEvt_tick_()? - if (QTimeEvt_timeEvtHead_[tickRate].act != (void *)0) { - #ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(812, - Q_PTR2UINT_CAST_(QTimeEvt_timeEvtHead_[tickRate].act) - == (uintptr_t)~QTimeEvt_timeEvtHead_dis_[tickRate]); - #endif // ndef Q_UNSAFE - prev->next = (QTimeEvt*)QTimeEvt_timeEvtHead_[tickRate].act; - QTimeEvt_timeEvtHead_[tickRate].act = (void *)0; - #ifndef Q_UNSAFE - prev->next_dis = (uintptr_t)~Q_PTR2UINT_CAST_(prev->next); - QTimeEvt_timeEvtHead_dis_[tickRate] = - (uintptr_t)~Q_PTR2UINT_CAST_((void *)0); - #endif // ndef Q_UNSAFE - - te = prev->next; // switch to the new list - } - else { // all currently armed time events are processed - break; // terminate the for-loop + // NO any new time events armed since the last QTimeEvt_tick_()? + if (QTimeEvt_timeEvtHead_[tickRate].act == (void *)0) { + break; // terminate the while-loop } + + prev->next = (QTimeEvt*)QTimeEvt_timeEvtHead_[tickRate].act; + QTimeEvt_timeEvtHead_[tickRate].act = (void *)0; + + te = prev->next; // switch to the new list } // the time event 'te' must be valid - Q_ASSERT_INCRIT(820, te != (QTimeEvt *)0); + Q_ASSERT_INCRIT(840, te != (QTimeEvt *)0); - QTimeEvtCtr ctr = te->ctr; - #ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(821, QEvt_verify_(&te->super)); - QTimeEvtCtr const dis = (QTimeEvtCtr)~te->ctr_dis; - Q_INVARIANT_INCRIT(822, ctr == dis); - #endif // ndef Q_UNSAFE + QTimeEvtCtr ctr = te->ctr; // move volatile into temporary if (ctr == 0U) { // time event scheduled for removal? prev->next = te->next; - #ifndef Q_UNSAFE - prev->next_dis = (uintptr_t)~Q_PTR2UINT_CAST_(te->next); - #endif // ndef Q_UNSAFE // mark time event 'te' as NOT linked te->flags &= (uint8_t)(~QTE_FLAG_IS_LINKED & 0xFFU); - // do NOT advance the prev pointer - QF_MEM_APP(); QF_CRIT_EXIT(); // exit crit. section to reduce latency - - // NOTE: prevent merging critical sections - // In some QF ports the critical section exit takes effect only - // on the next machine instruction. If the next instruction is - // another entry to a critical section, the critical section - // might not be really exited, but rather the two adjacent - // critical sections would be MERGED. The QF_CRIT_EXIT_NOP() - // macro contains minimal code required to prevent such merging - // of critical sections in QF ports, in which it can occur. - QF_CRIT_EXIT_NOP(); } else if (ctr == 1U) { // is time event about to expire? QActive * const act = (QActive *)te->act; - if (te->interval != 0U) { // periodic time evt? - te->ctr = te->interval; // rearm the time event - #ifndef Q_UNSAFE - te->ctr_dis = (QTimeEvtCtr)~te->interval; - #endif // ndef Q_UNSAFE - prev = te; // advance to this time event - } - else { // one-shot time event: automatically disarm - te->ctr = 0U; - prev->next = te->next; - #ifndef Q_UNSAFE - te->ctr_dis = (QTimeEvtCtr)~0U; - prev->next_dis = (uintptr_t)~Q_PTR2UINT_CAST_(te->next); - #endif // ndef Q_UNSAFE - - // mark time event 'te' as NOT linked - te->flags &= (uint8_t)(~QTE_FLAG_IS_LINKED & 0xFFU); - // do NOT advance the prev pointer - - QS_BEGIN_PRE(QS_QF_TIMEEVT_AUTO_DISARM, act->prio) - QS_OBJ_PRE(te); // this time event object - QS_OBJ_PRE(act); // the target AO - QS_U8_PRE(tickRate); // tick rate - QS_END_PRE() - } + prev = QTimeEvt_expire_(te, prev, act, tickRate); - QS_BEGIN_PRE(QS_QF_TIMEEVT_POST, act->prio) - QS_TIME_PRE(); // timestamp - QS_OBJ_PRE(te); // the time event object - QS_SIG_PRE(te->super.sig);// signal of this time event - QS_OBJ_PRE(act); // the target AO - QS_U8_PRE(tickRate); // tick rate - QS_END_PRE() - - #ifdef QXK_H_ +#ifdef QXK_H_ if ((enum_t)te->super.sig < Q_USER_SIG) { QXThread_timeout_(act); - QF_MEM_APP(); QF_CRIT_EXIT(); } else { - QF_MEM_APP(); QF_CRIT_EXIT(); // exit crit. section before posting // QACTIVE_POST() asserts if the queue overflows QACTIVE_POST(act, &te->super, sender); } - #else - QF_MEM_APP(); +#else // not QXK QF_CRIT_EXIT(); // exit crit. section before posting // QACTIVE_POST() asserts if the queue overflows QACTIVE_POST(act, &te->super, sender); - #endif +#endif } else { // time event keeps timing out --ctr; // decrement the tick counter te->ctr = ctr; // update the original - #ifndef Q_UNSAFE - te->ctr_dis = (QTimeEvtCtr)~ctr; - #endif // ndef Q_UNSAFE prev = te; // advance to this time event - - QF_MEM_APP(); QF_CRIT_EXIT(); // exit crit. section to reduce latency - - // prevent merging critical sections, see NOTE above - QF_CRIT_EXIT_NOP(); } QF_CRIT_ENTRY(); // re-enter crit. section to continue the loop - QF_MEM_SYS(); } - - Q_ENSURE_INCRIT(890, lbound > 0U); - QF_MEM_APP(); QF_CRIT_EXIT(); } -//${QF::QTimeEvt::noActive} .................................................. +//............................................................................ //! @static @public @memberof QTimeEvt bool QTimeEvt_noActive(uint_fast8_t const tickRate) { // NOTE: this function must be called *inside* critical section Q_REQUIRE_INCRIT(900, tickRate < QF_MAX_TICK_RATE); - bool inactive; + bool inactive = false; - QF_MEM_SYS(); if (QTimeEvt_timeEvtHead_[tickRate].next != (QTimeEvt *)0) { - inactive = false; + // empty } else if ((QTimeEvt_timeEvtHead_[tickRate].act != (void *)0)) { - inactive = false; + // empty } else { inactive = true; } - QF_MEM_APP(); return inactive; } -//$enddef${QF::QTimeEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +//............................................................................ +//! @private @memberof QTimeEvt +QTimeEvt * QTimeEvt_expire_(QTimeEvt * const me, + QTimeEvt * const prev_link, + QActive const * const act, + uint_fast8_t const tickRate) +{ + // NOTE: this helper function is called *inside* critical section +#ifndef Q_SPY + Q_UNUSED_PAR(act); + Q_UNUSED_PAR(tickRate); +#endif + + QTimeEvt *prev = prev_link; + if (me->interval != 0U) { // periodic time evt? + me->ctr = me->interval; // rearm the time event + prev = me; // advance to this time event + } + else { // one-shot time event: automatically disarm + me->ctr = 0U; + prev->next = me->next; + + // mark this time event as NOT linked + me->flags &= (uint8_t)(~QTE_FLAG_IS_LINKED & 0xFFU); + // do NOT advance the prev pointer + + QS_BEGIN_PRE(QS_QF_TIMEEVT_AUTO_DISARM, act->prio) + QS_OBJ_PRE(me); // this time event object + QS_OBJ_PRE(act); // the target AO + QS_U8_PRE(tickRate); // tick rate + QS_END_PRE() + } + + QS_BEGIN_PRE(QS_QF_TIMEEVT_POST, act->prio) + QS_TIME_PRE(); // timestamp + QS_OBJ_PRE(me); // the time event object + QS_SIG_PRE(me->super.sig);// signal of this time event + QS_OBJ_PRE(act); // the target AO + QS_U8_PRE(tickRate); // tick rate + QS_END_PRE() + + return prev; +} diff --git a/src/qk/qk.c b/src/qk/qk.c index db312d25c..7765bf00a 100644 --- a/src/qk/qk.c +++ b/src/qk/qk.c @@ -1,10 +1,6 @@ -//$file${src::qk::qk.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// -// Model: qpc.qm -// File: ${src::qk::qk.c} -// -// This code has been generated by QM 7.0.0 . -// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // @@ -14,7 +10,7 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -30,8 +26,7 @@ // Quantum Leaps contact information: // // -// -//$endhead${src::qk::qk.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//============================================================================ #define QP_IMPL // this is QP implementation #include "qp_port.h" // QP port #include "qp_pkg.h" // QP package-scope internal interface @@ -45,35 +40,24 @@ // protection against including this source file in a wrong project #ifndef QK_H_ - #error "Source file included in a project NOT based on the QK kernel" + #error Source file included in a project NOT based on the QK kernel #endif // QK_H_ Q_DEFINE_THIS_MODULE("qk") -//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// Check for the minimum required QP version -#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U)%0x2710U)) -#error qpc version 7.3.0 or higher required -#endif -//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -//$define${QK::QK-base} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QK::QK-base::priv_} ...................................................... +//............................................................................ QK_Attr QK_priv_; -//${QK::QK-base::schedLock} .................................................. +//............................................................................ //! @static @public @memberof QK QSchedStatus QK_schedLock(uint_fast8_t const ceiling) { QF_CRIT_STAT QF_CRIT_ENTRY(); - QF_MEM_SYS(); Q_REQUIRE_INCRIT(100, !QK_ISR_CONTEXT_()); - Q_INVARIANT_INCRIT(102, QK_priv_.lockCeil - == (uint_fast8_t)(~QK_priv_.lockCeil_dis)); // first store the previous lock prio - QSchedStatus stat; + QSchedStatus stat = 0xFFU; // assume scheduler NOT locked if (ceiling > QK_priv_.lockCeil) { // raising the lock ceiling? QS_BEGIN_PRE(QS_SCHED_LOCK, QK_priv_.actPrio) QS_TIME_PRE(); // timestamp @@ -86,34 +70,22 @@ QSchedStatus QK_schedLock(uint_fast8_t const ceiling) { // new status of the lock QK_priv_.lockCeil = ceiling; - #ifndef Q_UNSAFE - QK_priv_.lockCeil_dis = (uint_fast8_t)(~ceiling); - #endif } - else { - stat = 0xFFU; // scheduler not locked - } - - QF_MEM_APP(); QF_CRIT_EXIT(); return stat; // return the status to be saved in a stack variable } -//${QK::QK-base::schedUnlock} ................................................ +//............................................................................ //! @static @public @memberof QK void QK_schedUnlock(QSchedStatus const prevCeil) { // has the scheduler been actually locked by the last QK_schedLock()? if (prevCeil != 0xFFU) { QF_CRIT_STAT QF_CRIT_ENTRY(); - QF_MEM_SYS(); - Q_INVARIANT_INCRIT(202, QK_priv_.lockCeil - == (uint_fast8_t)(~QK_priv_.lockCeil_dis)); - Q_REQUIRE_INCRIT(210, (!QK_ISR_CONTEXT_()) + Q_REQUIRE_INCRIT(200, (!QK_ISR_CONTEXT_()) && (QK_priv_.lockCeil > prevCeil)); - QS_BEGIN_PRE(QS_SCHED_UNLOCK, QK_priv_.actPrio) QS_TIME_PRE(); // timestamp // current lock ceiling (old), previous lock ceiling (new) @@ -122,57 +94,37 @@ void QK_schedUnlock(QSchedStatus const prevCeil) { // restore the previous lock ceiling QK_priv_.lockCeil = prevCeil; - #ifndef Q_UNSAFE - QK_priv_.lockCeil_dis = (uint_fast8_t)(~prevCeil); - #endif // find if any AOs should be run after unlocking the scheduler if (QK_sched_() != 0U) { // preemption needed? QK_activate_(); // activate any unlocked AOs } - QF_MEM_APP(); QF_CRIT_EXIT(); } } -//${QK::QK-base::sched_} ..................................................... +//............................................................................ //! @static @private @memberof QK uint_fast8_t QK_sched_(void) { // NOTE: this function is entered with interrupts DISABLED - 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 - } - else { + uint_fast8_t p = 0U; // assume NO activation needed + if (QPSet_notEmpty(&QK_priv_.readySet)) { // find the highest-prio AO with non-empty event queue p = QPSet_findMax(&QK_priv_.readySet); - Q_INVARIANT_INCRIT(412, - QK_priv_.actThre == (uint_fast8_t)(~QK_priv_.actThre_dis)); - // is the AO's prio. below the active preemption-threshold? if (p <= QK_priv_.actThre) { p = 0U; // no activation needed } else { - 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_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); - #endif } } } @@ -180,7 +132,43 @@ uint_fast8_t QK_sched_(void) { return p; } -//${QK::QK-base::activate_} .................................................. +//............................................................................ +//! @static @private @memberof QK +uint_fast8_t QK_sched_act_( + QActive const * const act, + uint_fast8_t const pthre_in) +{ + // NOTE: this function is entered with interrupts DISABLED + + uint_fast8_t p = act->prio; + if (act->eQueue.frontEvt == (QEvt *)0) { // empty queue? + QPSet_remove(&QK_priv_.readySet, p); + } + + if (QPSet_isEmpty(&QK_priv_.readySet)) { + p = 0U; // no activation needed + } + else { + // find new highest-prio AO ready to run... + p = QPSet_findMax(&QK_priv_.readySet); + // NOTE: p is guaranteed to be <= QF_MAX_ACTIVE + + // is the new prio. below the initial preemption-threshold? + if (p <= pthre_in) { + p = 0U; // no activation needed + } + else { + // is the AO's prio. below the lock preemption-threshold? + if (p <= QK_priv_.lockCeil) { + p = 0U; // no activation needed + } + } + } + + return p; +} + +//............................................................................ //! @static @private @memberof QK void QK_activate_(void) { // NOTE: this function is entered with interrupts DISABLED @@ -188,52 +176,34 @@ 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_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) + Q_REQUIRE_INCRIT(500, (prio_in <= QF_MAX_ACTIVE) && (0U < p) && (p <= QF_MAX_ACTIVE)); - #if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) +#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) uint_fast8_t pprev = prio_in; - #endif // QF_ON_CONTEXT_SW || Q_SPY +#endif // QF_ON_CONTEXT_SW || Q_SPY QK_priv_.nextPrio = 0U; // clear for the next time - #ifndef Q_UNSAFE - QK_priv_.nextPrio_dis = (uint_fast8_t)(~0U); - #endif - - uint_fast8_t pthre_in; - QActive *a; - if (prio_in == 0U) { // preempting the idle thread? - pthre_in = 0U; - } - else { - a = QActive_registry_[prio_in]; + + uint_fast8_t pthre_in = 0U; // assume preempting the idle thread + if (prio_in != 0U) { // preempting NOT the idle thread + QActive const * const a = QActive_registry_[prio_in]; Q_ASSERT_INCRIT(510, a != (QActive *)0); pthre_in = (uint_fast8_t)a->pthre; - Q_INVARIANT_INCRIT(511, pthre_in == - (uint_fast8_t)(~(uint_fast8_t)a->pthre_dis & 0xFFU)); } // loop until no more ready-to-run AOs of higher pthre than the initial do { - a = QActive_registry_[p]; // obtain the pointer to the AO + QActive * const a = QActive_registry_[p]; Q_ASSERT_INCRIT(520, a != (QActive *)0); // the AO must be registered uint_fast8_t const pthre = (uint_fast8_t)a->pthre; - Q_INVARIANT_INCRIT(522, pthre == - (uint_fast8_t)(~(uint_fast8_t)a->pthre_dis & 0xFFU)); // set new active prio. and preemption-threshold QK_priv_.actPrio = p; QK_priv_.actThre = pthre; - #ifndef Q_UNSAFE - QK_priv_.actPrio_dis = (uint_fast8_t)(~p); - QK_priv_.actThre_dis = (uint_fast8_t)(~pthre); - #endif - #if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) +#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) if (p != pprev) { // changing threads? QS_BEGIN_PRE(QS_SCHED_NEXT, p) @@ -242,105 +212,61 @@ void QK_activate_(void) { pprev); // previous prio. QS_END_PRE() - #ifdef QF_ON_CONTEXT_SW +#ifdef QF_ON_CONTEXT_SW QF_onContextSw(QActive_registry_[pprev], a); - #endif // QF_ON_CONTEXT_SW +#endif // QF_ON_CONTEXT_SW pprev = p; // update previous prio. } - #endif // QF_ON_CONTEXT_SW || Q_SPY +#endif // QF_ON_CONTEXT_SW || Q_SPY - QF_MEM_APP(); QF_INT_ENABLE(); // unconditionally enable interrupts QEvt const * const e = QActive_get_(a); - // NOTE QActive_get_() performs QF_MEM_APP() before return // dispatch event (virtual call) (*a->super.vptr->dispatch)(&a->super, e, p); - #if (QF_MAX_EPOOL > 0U) +#if (QF_MAX_EPOOL > 0U) QF_gc(e); - #endif +#endif // determine the next highest-prio. AO ready to run... QF_INT_DISABLE(); // unconditionally disable interrupts - QF_MEM_SYS(); - - // internal integrity check (duplicate inverse storage) - Q_INVARIANT_INCRIT(532, QPSet_verify_(&QK_priv_.readySet, - &QK_priv_.readySet_dis)); + p = QK_sched_act_(a, pthre_in); // schedule next AO - if (a->eQueue.frontEvt == (QEvt *)0) { // empty queue? - QPSet_remove(&QK_priv_.readySet, p); - #ifndef Q_UNSAFE - QPSet_update_(&QK_priv_.readySet, &QK_priv_.readySet_dis); - #endif - } - - if (QPSet_isEmpty(&QK_priv_.readySet)) { - p = 0U; // no activation needed - } - else { - // find new highest-prio AO ready to run... - p = QPSet_findMax(&QK_priv_.readySet); - - // is the new prio. below the initial preemption-threshold? - if (p <= pthre_in) { - p = 0U; // no activation needed - } - else { - 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) { - p = 0U; // no activation needed - } - else { - Q_ASSERT_INCRIT(550, p <= QF_MAX_ACTIVE); - } - } - } } while (p != 0U); // restore the active prio. and preemption-threshold QK_priv_.actPrio = prio_in; QK_priv_.actThre = pthre_in; - #ifndef Q_UNSAFE - QK_priv_.actPrio_dis = (uint_fast8_t)(~QK_priv_.actPrio); - QK_priv_.actThre_dis = (uint_fast8_t)(~QK_priv_.actThre); - #endif - #if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) +#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) if (prio_in != 0U) { // resuming an active object? - a = QActive_registry_[prio_in]; // pointer to preempted AO - QS_BEGIN_PRE(QS_SCHED_NEXT, prio_in) QS_TIME_PRE(); // timestamp // prio. of the resumed AO, previous prio. QS_2U8_PRE(prio_in, pprev); QS_END_PRE() + +#ifdef QF_ON_CONTEXT_SW + QF_onContextSw(QActive_registry_[pprev], + QActive_registry_[prio_in]); +#endif // QF_ON_CONTEXT_SW } else { // resuming prio.==0 --> idle - a = (QActive *)0; // QK idle loop - QS_BEGIN_PRE(QS_SCHED_IDLE, pprev) QS_TIME_PRE(); // timestamp QS_U8_PRE(pprev); // previous prio. QS_END_PRE() - } - - #ifdef QF_ON_CONTEXT_SW - QF_onContextSw(QActive_registry_[pprev], a); - #endif // QF_ON_CONTEXT_SW - #endif // QF_ON_CONTEXT_SW || Q_SPY +#ifdef QF_ON_CONTEXT_SW + QF_onContextSw(QActive_registry_[pprev], (QActive *)0); +#endif // QF_ON_CONTEXT_SW + } +#endif // QF_ON_CONTEXT_SW || Q_SPY } -//$enddef${QK::QK-base} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -//$define${QK::QF-cust} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -//${QK::QF-cust::init} ....................................................... +//............................................................................ //! @static @public @memberof QF void QF_init(void) { QF_bzero_(&QF_priv_, sizeof(QF_priv_)); @@ -350,83 +276,63 @@ void QF_init(void) { // setup the QK scheduler as initially locked and not running QK_priv_.lockCeil = (QF_MAX_ACTIVE + 1U); // scheduler locked - #ifndef Q_UNSAFE - QPSet_update_(&QK_priv_.readySet, &QK_priv_.readySet_dis); - QK_priv_.actPrio_dis = (uint_fast8_t)(~0U); - QK_priv_.nextPrio_dis = (uint_fast8_t)(~0U); - QK_priv_.actThre_dis = (uint_fast8_t)(~0U); - QK_priv_.lockCeil_dis = (uint_fast8_t)(~QK_priv_.lockCeil); - #endif - QTimeEvt_init(); // initialize QTimeEvts - #ifdef QK_INIT +#ifdef QK_INIT QK_INIT(); // port-specific initialization of the QK kernel - #endif +#endif } -//${QK::QF-cust::stop} ....................................................... +//............................................................................ //! @static @public @memberof QF void QF_stop(void) { QF_onCleanup(); // application-specific cleanup callback // nothing else to do for the preemptive QK kernel } -//${QK::QF-cust::run} ........................................................ +//............................................................................ //! @static @public @memberof QF int_t QF_run(void) { - #ifdef Q_SPY +#ifdef Q_SPY // produce the QS_QF_RUN trace record QF_INT_DISABLE(); - QF_MEM_SYS(); QS_beginRec_((uint_fast8_t)QS_QF_RUN); QS_endRec_(); - QF_MEM_APP(); QF_INT_ENABLE(); - #endif // Q_SPY +#endif // Q_SPY QF_onStartup(); // application-specific startup callback QF_INT_DISABLE(); - QF_MEM_SYS(); - #ifdef QK_START +#ifdef QK_START QK_START(); // port-specific startup of the QK kernel - #endif +#endif QK_priv_.lockCeil = 0U; // unlock the QK scheduler - #ifndef Q_UNSAFE - QK_priv_.lockCeil_dis = (uint_fast8_t)(~0U); - #endif - #ifdef QF_ON_CONTEXT_SW +#ifdef QF_ON_CONTEXT_SW // officially switch to the idle context QF_onContextSw((QActive *)0, QActive_registry_[QK_priv_.nextPrio]); - #endif +#endif // activate AOs to process events posted so far if (QK_sched_() != 0U) { QK_activate_(); } - QF_MEM_APP(); QF_INT_ENABLE(); for (;;) { // QK idle loop... QK_onIdle(); // application-specific QK on-idle callback } - #ifdef __GNUC__ +#ifdef __GNUC__ return 0; - #endif +#endif } -//$enddef${QK::QF-cust} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -//$define${QK::QActive} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QK::QActive} ............................................................. -//${QK::QActive::start} ...................................................... +//............................................................................ //! @public @memberof QActive void QActive_start(QActive * const me, QPrioSpec const prioSpec, @@ -441,11 +347,9 @@ void QActive_start(QActive * const me, QF_CRIT_STAT QF_CRIT_ENTRY(); - QF_MEM_SYS(); - Q_REQUIRE_INCRIT(300, (!QK_ISR_CONTEXT_()) - && (stkSto == (void *)0)); - QF_MEM_APP(); + Q_REQUIRE_INCRIT(300, (me->super.vptr != (struct QAsmVtable *)0) + && (stkSto == (void *)0)); QF_CRIT_EXIT(); me->prio = (uint8_t)(prioSpec & 0xFFU); // QF-prio. of the AO @@ -460,11 +364,8 @@ void QActive_start(QActive * const me, // See if this AO needs to be scheduled if QK is already running QF_CRIT_ENTRY(); - QF_MEM_SYS(); if (QK_sched_() != 0U) { // activation needed? QK_activate_(); } - QF_MEM_APP(); QF_CRIT_EXIT(); } -//$enddef${QK::QActive} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/qs/qstamp.c b/src/qs/qstamp.c index 1137aa809..8877e4a6b 100644 --- a/src/qs/qstamp.c +++ b/src/qs/qstamp.c @@ -1,10 +1,6 @@ -//$file${src::qs::qstamp.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// -// Model: qpc.qm -// File: ${src::qs::qstamp.c} -// -// This code has been generated by QM 7.0.0 . -// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // @@ -12,26 +8,24 @@ // ------------------------ // Modern Embedded Software // -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// SPDX-License-Identifier: LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU -// General Public License (GPL) or under the terms of one of the closed- -// source Quantum Leaps commercial licenses. +// This software is licensed under the terms of the Quantum Leaps commercial +// licenses. Please contact Quantum Leaps for more information about the +// available licensing options. // -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. -// -// NOTE: -// The GPL does NOT permit the incorporation of this code into proprietary -// programs. Please contact Quantum Leaps for commercial licensing options, -// which expressly supersede the GPL and are designed explicitly for -// closed-source distribution. +// RESTRICTIONS +// You may NOT : +// (a) redistribute, encumber, sell, rent, lease, sublicense, or otherwise +// transfer rights in this software, +// (b) remove or alter any trademark, logo, copyright or other proprietary +// notices, legends, symbols or labels present in this software, +// (c) plagiarize this software to sidestep the licensing obligations. // // Quantum Leaps contact information: // // -// -//$endhead${src::qs::qstamp.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//============================================================================ #include "qstamp.h" char const Q_BUILD_DATE[12] = __DATE__; diff --git a/src/qv/qv.c b/src/qv/qv.c index 710a0043f..a3cc76aec 100644 --- a/src/qv/qv.c +++ b/src/qv/qv.c @@ -1,10 +1,6 @@ -//$file${src::qv::qv.c} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// -// Model: qpc.qm -// File: ${src::qv::qv.c} -// -// This code has been generated by QM 7.0.0 . -// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. +//============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // @@ -14,7 +10,7 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -30,8 +26,7 @@ // Quantum Leaps contact information: // // -// -//$endhead${src::qv::qv.c} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +//============================================================================ #define QP_IMPL // this is QP implementation #include "qp_port.h" // QP port #include "qp_pkg.h" // QP package-scope internal interface @@ -45,31 +40,19 @@ // protection against including this source file in a wrong project #ifndef QV_H_ - #error "Source file included in a project NOT based on the QV kernel" + #error Source file included in a project NOT based on the QV kernel #endif // QV_H_ Q_DEFINE_THIS_MODULE("qv") -//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -// Check for the minimum required QP version -#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U)%0x2710U)) -#error qpc version 7.3.0 or higher required -#endif -//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -//$define${QV::QV-base} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QV::QV-base::priv_} ...................................................... +//............................................................................ QV_Attr QV_priv_; -//${QV::QV-base::schedDisable} ............................................... +//............................................................................ //! @static @public @memberof QV void QV_schedDisable(uint_fast8_t const ceiling) { QF_CRIT_STAT QF_CRIT_ENTRY(); - QF_MEM_SYS(); - - Q_INVARIANT_INCRIT(102, QV_priv_.schedCeil - == (uint_fast8_t)(~QV_priv_.schedCeil_dis)); if (ceiling > QV_priv_.schedCeil) { // raising the scheduler ceiling? @@ -81,23 +64,15 @@ void QV_schedDisable(uint_fast8_t const ceiling) { QS_END_PRE() QV_priv_.schedCeil = ceiling; - #ifndef Q_UNSAFE - QV_priv_.schedCeil_dis = (uint_fast8_t)(~ceiling); - #endif } - QF_MEM_APP(); QF_CRIT_EXIT(); } -//${QV::QV-base::schedEnable} ................................................ +//............................................................................ //! @static @public @memberof QV void QV_schedEnable(void) { QF_CRIT_STAT QF_CRIT_ENTRY(); - QF_MEM_SYS(); - - Q_INVARIANT_INCRIT(202, QV_priv_.schedCeil - == (uint_fast8_t)(~QV_priv_.schedCeil_dis)); if (QV_priv_.schedCeil != 0U) { // actually enabling the scheduler? @@ -108,84 +83,61 @@ void QV_schedEnable(void) { QS_END_PRE() QV_priv_.schedCeil = 0U; - #ifndef Q_UNSAFE - QV_priv_.schedCeil_dis = (uint_fast8_t)(~0U); - #endif } - QF_MEM_APP(); QF_CRIT_EXIT(); } -//$enddef${QV::QV-base} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -//$define${QV::QF-cust} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv -//${QV::QF-cust::init} ....................................................... +//............................................................................ //! @static @public @memberof QF void QF_init(void) { QF_bzero_(&QF_priv_, sizeof(QF_priv_)); QF_bzero_(&QV_priv_, sizeof(QV_priv_)); QF_bzero_(&QActive_registry_[0], sizeof(QActive_registry_)); - #ifndef Q_UNSAFE - QPSet_update_(&QV_priv_.readySet, &QV_priv_.readySet_dis); - QV_priv_.schedCeil_dis = (uint_fast8_t)(~0U); - #endif - QTimeEvt_init(); // initialize QTimeEvts - #ifdef QV_INIT +#ifdef QV_INIT QV_INIT(); // port-specific initialization of the QV kernel - #endif +#endif } -//${QV::QF-cust::stop} ....................................................... +//............................................................................ //! @static @public @memberof QF void QF_stop(void) { QF_onCleanup(); // application-specific cleanup callback // nothing else to do for the QV kernel } -//${QV::QF-cust::run} ........................................................ +//............................................................................ //! @static @public @memberof QF int_t QF_run(void) { - #ifdef Q_SPY +#ifdef Q_SPY // produce the QS_QF_RUN trace record QF_INT_DISABLE(); - QF_MEM_SYS(); QS_beginRec_((uint_fast8_t)QS_QF_RUN); QS_endRec_(); - QF_MEM_APP(); QF_INT_ENABLE(); - #endif // Q_SPY +#endif // Q_SPY QF_onStartup(); // application-specific startup callback QF_INT_DISABLE(); - QF_MEM_SYS(); - #ifdef QV_START +#ifdef QV_START QV_START(); // port-specific startup of the QV kernel - #endif +#endif - #if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) +#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) uint_fast8_t pprev = 0U; // previously used prio. - #ifdef QF_ON_CONTEXT_SW +#ifdef QF_ON_CONTEXT_SW // officially switch to the idle cotext QF_onContextSw((QActive *)0, (QActive *)0); - #endif // def QF_ON_CONTEXT_SW +#endif // def QF_ON_CONTEXT_SW - #endif // def (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) +#endif // (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) for (;;) { // QV event loop... - - // check internal integrity (duplicate inverse storage) - Q_INVARIANT_INCRIT(302, QPSet_verify_(&QV_priv_.readySet, - &QV_priv_.readySet_dis)); - // check internal integrity (duplicate inverse storage) - 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) ? QPSet_findMax(&QV_priv_.readySet) @@ -194,60 +146,52 @@ int_t QF_run(void) { if (p > QV_priv_.schedCeil) { // is it above the sched ceiling? QActive * const a = QActive_registry_[p]; - #if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) +#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) QS_BEGIN_PRE(QS_SCHED_NEXT, p) QS_TIME_PRE(); // timestamp QS_2U8_PRE((uint8_t)p, (uint8_t)pprev); QS_END_PRE() - #ifdef QF_ON_CONTEXT_SW +#ifdef QF_ON_CONTEXT_SW QF_onContextSw(((pprev != 0U) ? QActive_registry_[pprev] : (QActive *)0), a); - #endif // QF_ON_CONTEXT_SW +#endif // QF_ON_CONTEXT_SW pprev = p; // update previous prio. - #endif // (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) +#endif // (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) - QF_MEM_APP(); QF_INT_ENABLE(); QEvt const * const e = QActive_get_(a); - // NOTE QActive_get_() performs QS_MEM_APP() before return // dispatch event (virtual call) (*a->super.vptr->dispatch)(&a->super, e, p); - #if (QF_MAX_EPOOL > 0U) +#if (QF_MAX_EPOOL > 0U) QF_gc(e); - #endif +#endif QF_INT_DISABLE(); - QF_MEM_SYS(); if (a->eQueue.frontEvt == (QEvt *)0) { // empty queue? QPSet_remove(&QV_priv_.readySet, p); - #ifndef Q_UNSAFE - QPSet_update_(&QV_priv_.readySet, &QV_priv_.readySet_dis); - #endif } } else { // no AO ready to run --> idle - #if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) +#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) if (pprev != 0U) { QS_BEGIN_PRE(QS_SCHED_IDLE, pprev) QS_TIME_PRE(); // timestamp QS_U8_PRE((uint8_t)pprev); // previous prio QS_END_PRE() - #ifdef QF_ON_CONTEXT_SW +#ifdef QF_ON_CONTEXT_SW QF_onContextSw(QActive_registry_[pprev], (QActive *)0); - #endif // QF_ON_CONTEXT_SW +#endif // QF_ON_CONTEXT_SW pprev = 0U; // update previous prio. } - #endif // (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) - - QF_MEM_APP(); +#endif // (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) // QV_onIdle() must be called with interrupts DISABLED because // the determination of the idle condition can change at any time @@ -258,20 +202,14 @@ int_t QF_run(void) { QV_onIdle(); QF_INT_DISABLE(); // disable interrupts before looping back - QF_MEM_SYS(); } } - #ifdef __GNUC__ // GNU compiler? +#ifdef __GNUC__ // GNU compiler? return 0; - #endif +#endif } -//$enddef${QV::QF-cust} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -//$define${QV::QActive} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - -//${QV::QActive} ............................................................. -//${QV::QActive::start} ...................................................... +//============================================================================ //! @public @memberof QActive void QActive_start(QActive * const me, QPrioSpec const prioSpec, @@ -286,7 +224,8 @@ void QActive_start(QActive * const me, QF_CRIT_STAT QF_CRIT_ENTRY(); - Q_REQUIRE_INCRIT(300, stkSto == (void *)0); + Q_REQUIRE_INCRIT(300, (me->super.vptr != (struct QAsmVtable *)0) + && (stkSto == (void *)0)); QF_CRIT_EXIT(); me->prio = (uint8_t)(prioSpec & 0xFFU); // QF-prio. of the AO @@ -299,4 +238,3 @@ void QActive_start(QActive * const me, (*me->super.vptr->init)(&me->super, par, me->prio); QS_FLUSH(); // flush the trace buffer to the host } -//$enddef${QV::QActive} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/zephyr/qf_port.c b/zephyr/qf_port.c index ec4c24b24..6b5e1fbbc 100644 --- a/zephyr/qf_port.c +++ b/zephyr/qf_port.c @@ -1,4 +1,7 @@ //============================================================================ +// QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 +// // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // // Q u a n t u m L e a P s @@ -7,7 +10,7 @@ // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -15,22 +18,15 @@ // Plagiarizing this software to sidestep the license obligations is illegal. // // NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. // // Quantum Leaps contact information: // // //============================================================================ -//! @date Last updated on: 2024-09-26 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QF/C port to Zephyr RTOS (v 3.1.99) - #define QP_IMPL // this is QP implementation #include "qp_port.h" // QP port #include "qp_pkg.h" // QP package-scope interface @@ -194,9 +190,6 @@ bool QActive_post_(QActive * const me, QEvt const * const e, QF_CRIT_ENTRY(); Q_REQUIRE_INCRIT(200, e != (QEvt *)0); -#ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(201, QEvt_verify_(e)); -#endif // ndef Q_UNSAFE // NOTE: k_msgq_num_free_get() can be safely called from crit-section uint_fast16_t nFree = (uint_fast16_t)k_msgq_num_free_get(&me->eQueue); @@ -225,12 +218,13 @@ bool QActive_post_(QActive * const me, QEvt const * const e, QS_OBJ_PRE(sender); // the sender object QS_SIG_PRE(e->sig); // the signal of the event QS_OBJ_PRE(me); // this active object (recipient) - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_);// pool-Id & ref-Count + QS_2U8_PRE(e->poolNum_, e->refCtr_);// pool-Id & ref-Count QS_EQC_PRE(nFree); // # free entries available QS_EQC_PRE(0U); // min # free entries (unknown) QS_END_PRE() - if (QEvt_getPoolNum_(e) != 0U) { // is it a pool event? + if (e->poolNum_ != 0U) { // is it a pool event? + Q_ASSERT_INCRIT(205, e->refCtr_ < (2U * QF_MAX_ACTIVE)); QEvt_refCtr_inc_(e); // increment the reference counter } @@ -251,7 +245,7 @@ bool QActive_post_(QActive * const me, QEvt const * const e, QS_OBJ_PRE(sender); // the sender object QS_SIG_PRE(e->sig); // the signal of the event QS_OBJ_PRE(me); // this active object (recipient) - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_2U8_PRE(e->poolNum_, e->refCtr_); QS_EQC_PRE(nFree); // # free entries available QS_EQC_PRE(0U); // min # free entries (unknown) QS_END_PRE() @@ -266,20 +260,18 @@ void QActive_postLIFO_(QActive * const me, QEvt const * const e) { QF_CRIT_ENTRY(); Q_REQUIRE_INCRIT(300, e != (QEvt *)0); -#ifndef Q_UNSAFE - Q_INVARIANT_INCRIT(301, QEvt_verify_(e)); -#endif // ndef Q_UNSAFE QS_BEGIN_PRE(QS_QF_ACTIVE_POST_LIFO, me->prio) QS_TIME_PRE(); // timestamp QS_SIG_PRE(e->sig); // the signal of this event QS_OBJ_PRE(me); // this active object - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_2U8_PRE(e->poolNum_, e->refCtr_); QS_EQC_PRE(k_msgq_num_free_get(&me->eQueue)); // # free entries QS_EQC_PRE(0U); // min # free entries (unknown) QS_END_PRE() - if (QEvt_getPoolNum_(e) != 0U) { // is it a pool event? + if (e->poolNum_ != 0U) { // is it a pool event? + Q_ASSERT_INCRIT(305, e->refCtr_ < (2U * QF_MAX_ACTIVE)); QEvt_refCtr_inc_(e); // increment the reference counter } @@ -314,7 +306,7 @@ QEvt const *QActive_get_(QActive * const me) { QS_TIME_PRE(); // timestamp QS_SIG_PRE(e->sig); // the signal of this event QS_OBJ_PRE(me); // this active object - QS_2U8_PRE(QEvt_getPoolNum_(e), e->refCtr_); + QS_2U8_PRE(e->poolNum_, e->refCtr_); QS_EQC_PRE(k_msgq_num_free_get(&me->eQueue));// # free entries QS_END_PRE() diff --git a/zephyr/qp_port.h b/zephyr/qp_port.h index c6e7e65f4..f7cceb3b8 100644 --- a/zephyr/qp_port.h +++ b/zephyr/qp_port.h @@ -1,15 +1,16 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) +// Version 8.0.2 // // Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. // -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// The QP/C software is dual-licensed under the terms of the open-source GNU +// This software is dual-licensed under the terms of the open-source GNU // General Public License (GPL) or under the terms of one of the closed- // source Quantum Leaps commercial licenses. // @@ -17,22 +18,15 @@ // Plagiarizing this software to sidestep the license obligations is illegal. // // NOTE: -// The GPL (see ) does NOT permit the -// incorporation of the QP/C software into proprietary programs. Please -// contact Quantum Leaps for commercial licensing options, which expressly -// supersede the GPL and are designed explicitly for licensees interested -// in using QP/C in closed-source proprietary applications. +// The GPL does NOT permit the incorporation of this code into proprietary +// programs. Please contact Quantum Leaps for commercial licensing options, +// which expressly supersede the GPL and are designed explicitly for +// closed-source distribution. // // Quantum Leaps contact information: // // //============================================================================ -//! @date Last updated on: 2023-09-30 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QP/C port to Zephyr RTOS - #ifndef QP_PORT_H_ #define QP_PORT_H_ diff --git a/zephyr/qs_port.h b/zephyr/qs_port.h index cdb29f7d9..33a953307 100644 --- a/zephyr/qs_port.h +++ b/zephyr/qs_port.h @@ -1,38 +1,31 @@ //============================================================================ // QP/C Real-Time Embedded Framework (RTEF) -// -// Q u a n t u m L e a P s -// ------------------------ -// Modern Embedded Software +// Version 8.0.2 // // 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. +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software // -// The terms of the open source GNU General Public License version 3 -// can be found at: +// SPDX-License-Identifier: LicenseRef-QL-commercial // -// The terms of the closed source Quantum Leaps commercial licenses -// can be found at: +// This software is licensed under the terms of the Quantum Leaps commercial +// licenses. Please contact Quantum Leaps for more information about the +// available licensing options. // -// Redistributions in source code must retain this top-level comment block. -// Plagiarizing this software to sidestep the license obligations is illegal. +// RESTRICTIONS +// You may NOT : +// (a) redistribute, encumber, sell, rent, lease, sublicense, or otherwise +// transfer rights in this software, +// (b) remove or alter any trademark, logo, copyright or other proprietary +// notices, legends, symbols or labels present in this software, +// (c) plagiarize this software to sidestep the licensing obligations. // -// Contact information: -// +// Quantum Leaps contact information: +// // //============================================================================ -//! @date Last updated on: 2024-06-06 -//! @version Last updated for: @ref qpc_8_0_0 -//! -//! @file -//! @brief QS/C port to a 32-bit CPU and a generic C99 compiler. - #ifndef QS_PORT_H_ #define QS_PORT_H_