mirror of
https://github.com/QuantumLeaps/qpcpp.git
synced 2025-01-28 06:02:56 +08:00
8.0.2
This commit is contained in:
parent
2b1661fdce
commit
df116c8410
@ -9,8 +9,8 @@ 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-
|
||||
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.
|
||||
@ -25,4 +25,4 @@ closed-source distribution.
|
||||
Quantum Leaps contact information:
|
||||
<www.state-machine.com/licensing>
|
||||
<info@state-machine.com>
|
||||
#48B37CF39D4FD9DE279250B31FD388AFD0BE9B40
|
||||
#E73B85325051C864FE0E4C672EF7577CB16A80DA
|
122
README.md
122
README.md
@ -16,6 +16,39 @@ git clone https://github.com/QuantumLeaps/qpcpp --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/qpcpp
|
||||
|
||||
@ -159,20 +134,25 @@ If you like this project, please give it a star (in the upper-right corner of yo
|
||||
[QP]: <https://www.state-machine.com/products/qp>
|
||||
[QP/C]: <https://github.com/QuantumLeaps/qpc>
|
||||
[QP/C++]: <https://github.com/QuantumLeaps/qpcpp>
|
||||
[QS/C++]: <https://www.state-machine.com/qpcpp/srs-qp_qs.html>
|
||||
[QV]: <https://www.state-machine.com/qpcpp/srs-qp_qv.html>
|
||||
[QK]: <https://www.state-machine.com/qpcpp/srs-qp_qk.html>
|
||||
[QXK]: <https://www.state-machine.com/qpcpp/srs-qp_qxk.html>
|
||||
[Cert]: <https://www.state-machine.com/products/qp#CERT>
|
||||
[QM]: <https://github.com/QuantumLeaps/qm>
|
||||
[QTools]: <https://github.com/QuantumLeaps/qtools>
|
||||
[QP-Rel]: <https://github.com/QuantumLeaps/qpcpp/releases>
|
||||
[Active]: <https://www.state-machine.com/qpcpp/srs-qp_ao.html>
|
||||
[AO_model]: <https://www.state-machine.com/qpcpp/srs-qp_ao.html#srs-qp_ao-model>
|
||||
[Event]: <https://www.state-machine.com/qpcpp/srs-qp_evt.html>
|
||||
[HSM]: <https://www.state-machine.com/qpcpp/srs-qp_sm.html>
|
||||
[Lic]: <https://www.state-machine.com/licensing>
|
||||
[Com]: <https://www.state-machine.com/licensing#Commercial>
|
||||
[Cust]: <https://www.state-machine.com/customers>
|
||||
[Sup]: <mailto:support@state-machine.com>
|
||||
[AN]: <https://www.state-machine.com/doc/AN_Getting_Started_with_QP.pdf>
|
||||
[Tutorial]: <https://www.state-machine.com/qpcpp/gs_tut.html>
|
||||
[Video]: <https://youtu.be/O7ER6_VqIH0>
|
||||
[QS]: <https://www.state-machine.com/qpcpp/srs-qp_qs.html>
|
||||
[QV]: <https://www.state-machine.com/qpcpp/srs-qp_qv.html>
|
||||
[QK]: <https://www.state-machine.com/qpcpp/srs-qp_qk.html>
|
||||
[QXK]: <https://www.state-machine.com/qpcpp/srs-qp_qxk.html>
|
||||
[SRS]: <https://www.state-machine.com/qpcpp/srs-qp.html>
|
||||
[SAS]: <https://www.state-machine.com/qpcpp/sas-qp.html>
|
||||
[SDS]: <https://www.state-machine.com/qpcpp/sds-qp.html>
|
||||
[Active]: <https://www.state-machine.com/qpcpp/srs-qp_ao.html>
|
||||
[AOmod]: <https://www.state-machine.com/qpcpp/srs-qp_ao.html#srs-qp_ao-model>
|
||||
[Event]: <https://www.state-machine.com/qpcpp/srs-qp_evt.html>
|
||||
[HSM]: <https://www.state-machine.com/qpcpp/srs-qp_sm.html>
|
||||
[Tut]: <https://www.state-machine.com/qpcpp/gs_tut.html>
|
||||
[QP-Rel]: <https://github.com/QuantumLeaps/qpcpp/releases>
|
||||
|
2
examples
2
examples
@ -1 +1 @@
|
||||
Subproject commit 01aad80e4c6f69089ecf7ddc328cad2870505a6e
|
||||
Subproject commit f8e601d60a88d04bd49e01bb725efd6e13131c1a
|
@ -1,10 +1,6 @@
|
||||
//$file${include::qequeue.hpp} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
//
|
||||
// Model: qpcpp.qm
|
||||
// File: ${include::qequeue.hpp}
|
||||
//
|
||||
// This code has been generated by QM 7.0.0 <www.state-machine.com/qm>.
|
||||
// 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,8 +10,8 @@
|
||||
//
|
||||
// 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-
|
||||
// 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.
|
||||
@ -30,8 +26,7 @@
|
||||
// Quantum Leaps contact information:
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//
|
||||
//$endhead${include::qequeue.hpp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//============================================================================
|
||||
#ifndef QEQUEUE_HPP_
|
||||
#define QEQUEUE_HPP_
|
||||
|
||||
@ -46,17 +41,16 @@ namespace QP {
|
||||
#elif (QF_EQUEUE_CTR_SIZE == 2U)
|
||||
using QEQueueCtr = std::uint16_t;
|
||||
#else
|
||||
#error "QF_EQUEUE_CTR_SIZE defined incorrectly, expected 1U or 2U"
|
||||
#error QF_EQUEUE_CTR_SIZE defined incorrectly, expected 1U or 2U
|
||||
#endif
|
||||
|
||||
class QEvt; // forward declaration
|
||||
|
||||
} // namespace QP
|
||||
|
||||
//$declare${QF::QEQueue} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
//============================================================================
|
||||
namespace QP {
|
||||
|
||||
//${QF::QEQueue} .............................................................
|
||||
class QEQueue {
|
||||
private:
|
||||
QEvt const * volatile m_frontEvt;
|
||||
@ -65,22 +59,6 @@ private:
|
||||
QEQueueCtr volatile m_head;
|
||||
QEQueueCtr volatile m_tail;
|
||||
QEQueueCtr volatile m_nFree;
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
std::uintptr_t m_frontEvt_dis;
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
QEQueueCtr m_head_dis;
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
QEQueueCtr m_tail_dis;
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
QEQueueCtr m_nFree_dis;
|
||||
#endif // ndef Q_UNSAFE
|
||||
QEQueueCtr m_nMin;
|
||||
|
||||
// friends...
|
||||
@ -97,16 +75,10 @@ public:
|
||||
m_head(0U),
|
||||
m_tail(0U),
|
||||
m_nFree(0U),
|
||||
#ifndef Q_UNSAFE
|
||||
m_frontEvt_dis(static_cast<std::uintptr_t>(~0U)),
|
||||
m_head_dis(static_cast<QEQueueCtr>(~0U)),
|
||||
m_tail_dis(static_cast<QEQueueCtr>(~0U)),
|
||||
m_nFree_dis(static_cast<QEQueueCtr>(~0U)),
|
||||
#endif
|
||||
m_nMin(0U)
|
||||
{}
|
||||
void init(
|
||||
QEvt const * qSto[],
|
||||
QEvt const * * const qSto,
|
||||
std::uint_fast16_t const qLen) noexcept;
|
||||
bool post(
|
||||
QEvt const * const e,
|
||||
@ -120,11 +92,7 @@ public:
|
||||
return m_nFree;
|
||||
}
|
||||
QEQueueCtr getNMin() const noexcept {
|
||||
#ifndef Q_UNSAFE
|
||||
return m_nMin;
|
||||
#else
|
||||
return 0U;
|
||||
#endif
|
||||
}
|
||||
bool isEmpty() const noexcept {
|
||||
return m_frontEvt == nullptr;
|
||||
@ -133,9 +101,11 @@ public:
|
||||
private:
|
||||
QEQueue(QEQueue const & other) = delete;
|
||||
QEQueue & operator=(QEQueue const & other) = delete;
|
||||
void postFIFO_(
|
||||
QEvt const * const e,
|
||||
void const * const sender);
|
||||
}; // class QEQueue
|
||||
|
||||
} // namespace QP
|
||||
//$enddecl${QF::QEQueue} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
#endif // QEQUEUE_HPP_
|
||||
|
121
include/qk.hpp
121
include/qk.hpp
@ -1,10 +1,6 @@
|
||||
//$file${include::qk.hpp} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
//
|
||||
// Model: qpcpp.qm
|
||||
// File: ${include::qk.hpp}
|
||||
//
|
||||
// This code has been generated by QM 7.0.0 <www.state-machine.com/qm>.
|
||||
// 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,8 +10,8 @@
|
||||
//
|
||||
// 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-
|
||||
// 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.
|
||||
@ -30,41 +26,19 @@
|
||||
// Quantum Leaps contact information:
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//
|
||||
//$endhead${include::qk.hpp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//============================================================================
|
||||
#ifndef QK_HPP_
|
||||
#define QK_HPP_
|
||||
|
||||
//$declare${QK::QSchedStatus} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
namespace QP {
|
||||
|
||||
//${QK::QSchedStatus} ........................................................
|
||||
using QSchedStatus = std::uint_fast8_t;
|
||||
|
||||
} // namespace QP
|
||||
//$enddecl${QK::QSchedStatus} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
//$declare${QK::QK-base} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
namespace QP {
|
||||
namespace QK {
|
||||
|
||||
//${QK::QK-base::schedLock} ..................................................
|
||||
QSchedStatus schedLock(std::uint_fast8_t const ceiling) noexcept;
|
||||
|
||||
//${QK::QK-base::schedUnlock} ................................................
|
||||
void schedUnlock(QSchedStatus const prevCeil) noexcept;
|
||||
|
||||
//${QK::QK-base::onIdle} .....................................................
|
||||
void onIdle();
|
||||
|
||||
} // namespace QK
|
||||
} // namespace QP
|
||||
//$enddecl${QK::QK-base} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
//============================================================================
|
||||
extern "C" {
|
||||
//$declare${QK-extern-C} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
|
||||
//${QK-extern-C::QK_Attr} ....................................................
|
||||
class QK_Attr {
|
||||
public:
|
||||
QP::QPSet readySet;
|
||||
@ -73,49 +47,37 @@ public:
|
||||
std::uint_fast8_t actThre;
|
||||
std::uint_fast8_t lockCeil;
|
||||
std::uint_fast8_t intNest;
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
QP::QPSet readySet_dis;
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
std::uint_fast8_t actPrio_dis;
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
std::uint_fast8_t nextPrio_dis;
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
std::uint_fast8_t actThre_dis;
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
std::uint_fast8_t lockCeil_dis;
|
||||
#endif // ndef Q_UNSAFE
|
||||
}; // class QK_Attr
|
||||
|
||||
//${QK-extern-C::QK_priv_} ...................................................
|
||||
extern QK_Attr QK_priv_;
|
||||
|
||||
//${QK-extern-C::QK_sched_} ..................................................
|
||||
std::uint_fast8_t QK_sched_() noexcept;
|
||||
|
||||
//${QK-extern-C::QK_activate_} ...............................................
|
||||
std::uint_fast8_t QK_sched_act_(
|
||||
QP::QActive const * const act,
|
||||
std::uint_fast8_t const pthre_in) noexcept;
|
||||
|
||||
void QK_activate_() noexcept;
|
||||
//$enddecl${QK-extern-C} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
} // extern "C"
|
||||
|
||||
//============================================================================
|
||||
namespace QP {
|
||||
namespace QK {
|
||||
|
||||
QSchedStatus schedLock(std::uint_fast8_t const ceiling) noexcept;
|
||||
void schedUnlock(QSchedStatus const prevCeil) noexcept;
|
||||
void onIdle();
|
||||
|
||||
} // namespace QK
|
||||
} // namespace QP
|
||||
|
||||
//============================================================================
|
||||
// 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; \
|
||||
@ -124,32 +86,14 @@ void QK_activate_() noexcept;
|
||||
} \
|
||||
} 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_) (static_cast<void>(0))
|
||||
|
||||
//${QK-impl::QACTIVE_EQUEUE_SIGNAL_} .........................................
|
||||
#ifndef Q_UNSAFE
|
||||
#define QACTIVE_EQUEUE_SIGNAL_(me_) do { \
|
||||
QK_priv_.readySet.insert( \
|
||||
static_cast<std::uint_fast8_t>((me_)->m_prio)); \
|
||||
QK_priv_.readySet.update_(&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 { \
|
||||
QK_priv_.readySet.insert( \
|
||||
static_cast<std::uint_fast8_t>((me_)->m_prio)); \
|
||||
@ -159,28 +103,15 @@ void QK_activate_() noexcept;
|
||||
} \
|
||||
} \
|
||||
} 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_) \
|
||||
(p_).init((poolSto_), (poolSize_), (evtSize_))
|
||||
|
||||
//${QF_EPOOL-impl::QF_EPOOL_EVENT_SIZE_} .....................................
|
||||
#define QF_EPOOL_EVENT_SIZE_(p_) ((p_).getBlockSize())
|
||||
|
||||
//${QF_EPOOL-impl::QF_EPOOL_GET_} ............................................
|
||||
#define QF_EPOOL_GET_(p_, e_, m_, qsId_) \
|
||||
((e_) = static_cast<QEvt *>((p_).get((m_), (qsId_))))
|
||||
|
||||
//${QF_EPOOL-impl::QF_EPOOL_PUT_} ............................................
|
||||
#define QF_EPOOL_PUT_(p_, e_, qsId_) ((p_).put((e_), (qsId_)))
|
||||
//$enddecl${QF_EPOOL-impl} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
#endif // QP_IMPL
|
||||
|
||||
|
@ -1,10 +1,6 @@
|
||||
//$file${include::qmpool.hpp} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
//
|
||||
// Model: qpcpp.qm
|
||||
// File: ${include::qmpool.hpp}
|
||||
//
|
||||
// This code has been generated by QM 7.0.0 <www.state-machine.com/qm>.
|
||||
// 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,8 +10,8 @@
|
||||
//
|
||||
// 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-
|
||||
// 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.
|
||||
@ -30,8 +26,7 @@
|
||||
// Quantum Leaps contact information:
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//
|
||||
//$endhead${include::qmpool.hpp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//============================================================================
|
||||
#ifndef QMPOOL_HPP_
|
||||
#define QMPOOL_HPP_
|
||||
|
||||
@ -42,6 +37,12 @@
|
||||
#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)]; \
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
namespace QP {
|
||||
|
||||
#if (QF_MPOOL_SIZ_SIZE == 1U)
|
||||
@ -51,7 +52,7 @@ namespace QP {
|
||||
#elif (QF_MPOOL_SIZ_SIZE == 4U)
|
||||
using QMPoolSize = std::uint32_t;
|
||||
#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)
|
||||
@ -61,54 +62,22 @@ namespace QP {
|
||||
#elif (QF_MPOOL_CTR_SIZE == 4U)
|
||||
using QMPoolCtr = std::uint32_t;
|
||||
#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
|
||||
|
||||
} // namespace QP
|
||||
|
||||
#define QF_MPOOL_EL(evType_) struct { \
|
||||
QP::QFreeBlock sto_[((sizeof(evType_) - 1U) / (2U * sizeof(void *))) + 1U]; \
|
||||
}
|
||||
|
||||
//$declare${QF::QFreeBlock} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
namespace QP {
|
||||
|
||||
//${QF::QFreeBlock} ..........................................................
|
||||
class QFreeBlock {
|
||||
private:
|
||||
QFreeBlock * m_next;
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
std::uintptr_t m_next_dis;
|
||||
#endif // ndef Q_UNSAFE
|
||||
friend class QMPool;
|
||||
}; // class QFreeBlock
|
||||
|
||||
} // namespace QP
|
||||
//$enddecl${QF::QFreeBlock} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
//$declare${QF::QMPool} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
namespace QP {
|
||||
|
||||
//${QF::QMPool} ..............................................................
|
||||
//============================================================================
|
||||
class QMPool {
|
||||
private:
|
||||
QFreeBlock * m_start;
|
||||
QFreeBlock * m_end;
|
||||
QFreeBlock * volatile m_free_head;
|
||||
void * * m_start;
|
||||
void * * m_end;
|
||||
void * * volatile m_freeHead;
|
||||
QMPoolSize m_blockSize;
|
||||
QMPoolCtr m_nTot;
|
||||
QMPoolCtr volatile m_nFree;
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
QMPoolCtr m_nMin;
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
std::uintptr_t m_free_head_dis;
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
std::uintptr_t m_freeHead_dis;
|
||||
QMPoolCtr m_nFree_dis;
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
@ -116,13 +85,13 @@ public:
|
||||
QMPool()
|
||||
: m_start(nullptr),
|
||||
m_end(nullptr),
|
||||
m_free_head(nullptr),
|
||||
m_freeHead(nullptr),
|
||||
m_blockSize(0U),
|
||||
m_nTot(0U),
|
||||
m_nFree(0U)
|
||||
m_nFree(0U),
|
||||
m_nMin(0U)
|
||||
#ifndef Q_UNSAFE
|
||||
,m_nMin(0U),
|
||||
m_free_head_dis(static_cast<std::uintptr_t>(~0U)),
|
||||
,m_freeHead_dis(static_cast<std::uintptr_t>(~0U)),
|
||||
m_nFree_dis(static_cast<QEQueueCtr>(~0U))
|
||||
#endif
|
||||
{}
|
||||
@ -136,7 +105,9 @@ public:
|
||||
void put(
|
||||
void * const block,
|
||||
std::uint_fast8_t const qsId) noexcept;
|
||||
QMPoolSize getBlockSize() const noexcept;
|
||||
QMPoolSize getBlockSize() const noexcept {
|
||||
return m_blockSize;
|
||||
}
|
||||
QMPoolCtr getNMin() const noexcept {
|
||||
#ifndef Q_UNSAFE
|
||||
return m_nMin;
|
||||
@ -168,6 +139,5 @@ public:
|
||||
}; // class QMPool
|
||||
|
||||
} // namespace QP
|
||||
//$enddecl${QF::QMPool} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
#endif // QMPOOL_HPP_
|
||||
|
625
include/qp.hpp
625
include/qp.hpp
File diff suppressed because it is too large
Load Diff
@ -1,10 +1,6 @@
|
||||
//$file${include::qp_pkg.hpp} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
//
|
||||
// Model: qpcpp.qm
|
||||
// File: ${include::qp_pkg.hpp}
|
||||
//
|
||||
// This code has been generated by QM 7.0.0 <www.state-machine.com/qm>.
|
||||
// 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,8 +10,8 @@
|
||||
//
|
||||
// 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-
|
||||
// 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.
|
||||
@ -30,68 +26,54 @@
|
||||
// Quantum Leaps contact information:
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//
|
||||
//$endhead${include::qp_pkg.hpp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//============================================================================
|
||||
#ifndef QP_PKG_HPP_
|
||||
#define QP_PKG_HPP_
|
||||
|
||||
//$declare${QF::QF-pkg} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
//============================================================================
|
||||
#define QF_CONST_CAST_(type_, ptr_) const_cast<type_>(ptr_)
|
||||
#define Q_PTR2UINT_CAST_(ptr_) (reinterpret_cast<std::uintptr_t>(ptr_))
|
||||
#define QF_PTR_RANGE_(x_, min_, max_) (((min_) <= (x_)) && ((x_) <= (max_)))
|
||||
|
||||
//============================================================================
|
||||
namespace QP {
|
||||
namespace QF {
|
||||
|
||||
//${QF::QF-pkg::Attr} ........................................................
|
||||
class Attr {
|
||||
public:
|
||||
|
||||
#if (QF_MAX_EPOOL > 0U)
|
||||
QF_EPOOL_TYPE_ ePool_[QF_MAX_EPOOL];
|
||||
#endif // (QF_MAX_EPOOL > 0U)
|
||||
|
||||
#if (QF_MAX_EPOOL > 0U)
|
||||
std::uint_fast8_t maxPool_;
|
||||
#endif // (QF_MAX_EPOOL > 0U)
|
||||
|
||||
#if (QF_MAX_EPOOL == 0U)
|
||||
#else
|
||||
std::uint8_t dummy;
|
||||
#endif // (QF_MAX_EPOOL == 0U)
|
||||
}; // class Attr
|
||||
|
||||
//${QF::QF-pkg::priv_} .......................................................
|
||||
extern QF::Attr priv_;
|
||||
|
||||
//${QF::QF-pkg::bzero_} ......................................................
|
||||
void bzero_(
|
||||
void * const start,
|
||||
std::uint_fast16_t const len) noexcept;
|
||||
|
||||
} // namespace QF
|
||||
} // namespace QP
|
||||
//$enddecl${QF::QF-pkg} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
#define QF_CONST_CAST_(type_, ptr_) const_cast<type_>(ptr_)
|
||||
#define Q_PTR2UINT_CAST_(ptr_) (reinterpret_cast<std::uintptr_t>(ptr_))
|
||||
#define QF_PTR_RANGE_(x_, min_, max_) (((min_) <= (x_)) && ((x_) <= (max_)))
|
||||
|
||||
namespace QP {
|
||||
|
||||
//============================================================================
|
||||
// Bitmasks are for the QTimeEvt::flags attribute
|
||||
constexpr std::uint8_t QTE_FLAG_IS_LINKED {1U << 7U};
|
||||
constexpr std::uint8_t QTE_FLAG_WAS_DISARMED {1U << 6U};
|
||||
|
||||
//============================================================================
|
||||
inline void QEvt_refCtr_inc_(QEvt const * const e) noexcept {
|
||||
// NOTE: this function must be called inside a critical section
|
||||
std::uint8_t rc = e->refCtr_ + 1U;
|
||||
(QF_CONST_CAST_(QEvt*, e))->refCtr_ = rc; // cast away 'const'
|
||||
#ifndef Q_UNSAFE
|
||||
(QF_CONST_CAST_(QEvt*, e))->evtTag_ = (e->evtTag_ & 0xF0U) | ((~rc) & 0x0FU);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void QEvt_refCtr_dec_(QEvt const * const e) noexcept {
|
||||
// NOTE: this function must be called inside a critical section
|
||||
std::uint8_t rc = e->refCtr_ - 1U;
|
||||
(QF_CONST_CAST_(QEvt*, e))->refCtr_ = rc; // cast away 'const'
|
||||
#ifndef Q_UNSAFE
|
||||
(QF_CONST_CAST_(QEvt*, e))->evtTag_ = (e->evtTag_ & 0xF0U) | ((~rc) & 0x0FU);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace QP
|
||||
|
@ -1,10 +1,6 @@
|
||||
//$file${include::qpcpp.hpp} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
//
|
||||
// Model: qpcpp.qm
|
||||
// File: ${include::qpcpp.hpp}
|
||||
//
|
||||
// This code has been generated by QM 7.0.0 <www.state-machine.com/qm>.
|
||||
// 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,8 +10,8 @@
|
||||
//
|
||||
// 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-
|
||||
// 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.
|
||||
@ -30,8 +26,7 @@
|
||||
// Quantum Leaps contact information:
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//
|
||||
//$endhead${include::qpcpp.hpp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//============================================================================
|
||||
#ifndef QPCPP_HPP_
|
||||
#define QPCPP_HPP_
|
||||
|
||||
@ -47,11 +42,11 @@
|
||||
//============================================================================
|
||||
#ifndef QP_API_VERSION
|
||||
#define QP_API_VERSION 0
|
||||
#endif // QP_API_VERSION
|
||||
#endif // QP_API_VERSION
|
||||
|
||||
// QP API compatibility layer...
|
||||
//============================================================================
|
||||
#if (QP_API_VERSION < 750)
|
||||
#if (QP_API_VERSION < 800)
|
||||
|
||||
#define QM_SM_STATE_DECL(subm_, state_) error "submachines no longer supported"
|
||||
#define qm_super_sub(sm_state_) error "submachines no longer supported"
|
||||
@ -64,7 +59,7 @@
|
||||
#define QEVT_PAR_INIT
|
||||
#endif
|
||||
|
||||
//! @deprecated plain 'char' is no longer forbidden in MISRA/AUTOSAR-C++
|
||||
//! @deprecated plain 'char' is no longer forbidden in MISRA-C++:2023
|
||||
using char_t = char;
|
||||
|
||||
//! @deprecated assertion failure handler
|
||||
@ -111,123 +106,11 @@ using char_t = char;
|
||||
#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_)
|
||||
|
||||
//! @deprecated use QP::QF::NO_MARGIN instead
|
||||
#define QF_NO_MARGIN QP::QF::NO_MARGIN
|
||||
|
||||
//============================================================================
|
||||
#if (QP_API_VERSION < 691)
|
||||
|
||||
//! @deprecated enable the QS global filter
|
||||
#define QS_FILTER_ON(rec_) QS_GLB_FILTER((rec_))
|
||||
|
||||
//! @deprecated disable the QS global filter
|
||||
#define QS_FILTER_OFF(rec_) QS_GLB_FILTER(-(rec_))
|
||||
|
||||
//! @deprecated enable the QS local filter for SM (state machine) object
|
||||
#define QS_FILTER_SM_OBJ(obj_) (static_cast<void>(0))
|
||||
|
||||
//! @deprecated enable the QS local filter for AO (active objects)
|
||||
#define QS_FILTER_AO_OBJ(obj_) (static_cast<void>(0))
|
||||
|
||||
//! @deprecated enable the QS local filter for MP (memory pool) object
|
||||
#define QS_FILTER_MP_OBJ(obj_) (static_cast<void>(0))
|
||||
|
||||
//! @deprecated enable the QS local filter for EQ (event queue) object
|
||||
#define QS_FILTER_EQ_OBJ(obj_) (static_cast<void>(0))
|
||||
|
||||
//! @deprecated enable the QS local filter for TE (time event) object
|
||||
#define QS_FILTER_TE_OBJ(obj_) (static_cast<void>(0))
|
||||
|
||||
#ifdef Q_SPY
|
||||
|
||||
//! @deprecated local Filter for a generic application object `obj_`.
|
||||
#define QS_FILTER_AP_OBJ(obj_) \
|
||||
(QP::QS::filt_.loc_AP = (obj_))
|
||||
|
||||
//! @deprecated begin of a user QS record, instead use QS_BEGIN_ID()
|
||||
#define QS_BEGIN(rec_, obj_) \
|
||||
if (QS_GLB_FILTER_(rec_) && \
|
||||
((QP::QS::filt_.loc[QP::QS::AP_OBJ] == nullptr) \
|
||||
|| (QP::QS::filt_.loc_AP == (obj_)))) \
|
||||
{ \
|
||||
QS_CRIT_STAT \
|
||||
QS_CRIT_ENTRY(); \
|
||||
QP::QS::beginRec_(static_cast<std::uint_fast8_t>(rec_)); \
|
||||
QS_TIME_PRE();
|
||||
|
||||
//! @deprecated output hex-formatted std::uint32_t to the QS record
|
||||
#define QS_U32_HEX(width_, data_) \
|
||||
(QP::QS::u32_fmt_(static_cast<std::uint8_t>( \
|
||||
(static_cast<std::uint8_t>((width_) << 4)) | QS_HEX_FMT), (data_)))
|
||||
|
||||
#else
|
||||
|
||||
#define QS_FILTER_AP_OBJ(obj_) (static_cast<void>(0))
|
||||
#define QS_BEGIN(rec_, obj_) if (false) {
|
||||
#define QS_U32_HEX(width_, data_) (Q_UNUSED_PAR(0))
|
||||
|
||||
#endif // def Q_SPY
|
||||
|
||||
//============================================================================
|
||||
#if (QP_API_VERSION < 680)
|
||||
|
||||
//! @deprecated
|
||||
//! Macro to specify a tran. in the "me->" impl-strategy.
|
||||
//! Instead use the new impl-strategy without the "me->" pointer, where
|
||||
//! you call tran(Q_STATE_CAST(target_)).
|
||||
#define Q_TRAN(target_) (me->tran(Q_STATE_CAST(target_)))
|
||||
|
||||
//! @deprecated
|
||||
//! Macro to specify a tran-to-history in the "me->" impl-strategy.
|
||||
//! Instead use the new impl-strategy without the "me->" pointer, where
|
||||
//! you call tran_hist(Q_STATE_CAST(hist_)).
|
||||
#define Q_TRAN_HIST(hist_) (me->tran_hist((hist_)))
|
||||
|
||||
//! @deprecated
|
||||
//! Macro to specify the superstate in the "me->" impl-strategy.
|
||||
//! Instead use the new impl-strategy without the "me->" pointer, where
|
||||
//! you call super(state_)).
|
||||
#define Q_SUPER(state_) (me->super(Q_STATE_CAST(state_)))
|
||||
|
||||
//! @deprecated
|
||||
//! Macro to call in a QM state entry-handler. Applicable only to QMSMs.
|
||||
//! Instead use the new impl-strategy without the "me->" pointer, where
|
||||
//! the QM-generated code calls qm_entry(Q_STATE_CAST(state_)).
|
||||
#define QM_ENTRY(state_) (me->qm_entry((state_)))
|
||||
|
||||
//! @deprecated
|
||||
//! Macro to call in a QM state exit-handler. Applicable only to QMSMs.
|
||||
//! Instead use the new impl-strategy without the "me->" pointer, where
|
||||
//! the QM-generated code calls qm_exit(Q_STATE_CAST(state_)).
|
||||
#define QM_EXIT(state_) (me->qm_exit((state_)))
|
||||
|
||||
//! @deprecated
|
||||
//! Macro to call in a QM state-handler when it executes a tran.
|
||||
//! Instead use the new impl-strategy without the "me->" pointer, where
|
||||
//! the QM-generated code calls qm_tran((tatbl_)).
|
||||
#define QM_TRAN(tatbl_) (me->qm_tran((tatbl_)))
|
||||
|
||||
//! @deprecated
|
||||
//! Macro to call in a QM state-handler when it executes an initial tran.
|
||||
//! Instead use the new impl-strategy without the "me->" pointer, where
|
||||
//! the QM-generated code calls qm_tran_init((tatbl_)).
|
||||
#define QM_TRAN_INIT(tatbl_) (me->qm_tran_init((tatbl_)))
|
||||
|
||||
//! @deprecated
|
||||
//! Macro to call in a QM state-handler when it executes a tran-to-history.
|
||||
//! Instead use the new impl-strategy without the "me->" pointer, where
|
||||
//! the QM-generated code calls qm_tran_hist((history_), (tatbl_)).
|
||||
#define QM_TRAN_HIST(history_, tatbl_) \
|
||||
(me->qm_tran_hist((history_), (tatbl_)))
|
||||
|
||||
#endif // QP_API_VERSION < 680
|
||||
#endif // QP_API_VERSION < 691
|
||||
#endif // QP_API_VERSION < 750
|
||||
#endif // QP_API_VERSION < 800
|
||||
|
||||
#endif // QPCPP_HPP_
|
||||
|
@ -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_HPP_
|
||||
|
||||
#ifdef Q_SPY
|
||||
#error "Q_SPY must NOT be defined to include qs_dummy.hpp"
|
||||
error Q_SPY must NOT be defined to include qs_dummy.hpp
|
||||
#endif
|
||||
|
||||
#ifdef Q_UTEST
|
||||
#error "Q_UTEST must NOT be defined to include qs_dummy.hpp"
|
||||
error Q_UTEST must NOT be defined to include qs_dummy.hpp
|
||||
#endif
|
||||
|
||||
#define QS_INIT(arg_) (true)
|
||||
@ -166,9 +166,6 @@ void QS_onTestLoop(void);
|
||||
#define QS_CRIT_ENTRY() static_cast<void>(0)
|
||||
#define QS_CRIT_EXIT() static_cast<void>(0)
|
||||
|
||||
#define QS_MEM_SYS() static_cast<void>(0)
|
||||
#define QS_MEM_APP() static_cast<void>(0)
|
||||
|
||||
#define QS_TR_CRIT_ENTRY() static_cast<void>(0)
|
||||
#define QS_TR_CRIT_EXIT() static_cast<void>(0)
|
||||
#define QS_TR_ISR_ENTRY(isrnest_, prio_) static_cast<void>(0)
|
||||
|
159
include/qsafe.h
159
include/qsafe.h
@ -1,82 +1,58 @@
|
||||
//$file${include::qsafe.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
//============================================================================
|
||||
// SafeQP/C Real-Time Embedded Framework (RTEF)
|
||||
// Version 8.0.2
|
||||
//
|
||||
// Model: qpc.qm
|
||||
// File: ${include::qsafe.h}
|
||||
//
|
||||
// This code has been generated by QM 6.1.1 <www.state-machine.com/qm>.
|
||||
// DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
|
||||
//
|
||||
// This code is covered by the following QP license:
|
||||
// License # : LicenseRef-QL-dual
|
||||
// Issued to : Any user of the QP/C real-time embedded framework
|
||||
// Framework(s) : qpc
|
||||
// Support ends : 2024-12-31
|
||||
// License scope:
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC <state-machine.com>.
|
||||
// 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
|
||||
// SPDX-License-Identifier: 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.
|
||||
// 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.
|
||||
//
|
||||
// The terms of the open source GNU General Public License version 3
|
||||
// can be found at: <www.gnu.org/licenses/gpl-3.0>
|
||||
// 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.
|
||||
//
|
||||
// The terms of the closed source Quantum Leaps commercial licenses
|
||||
// can be found at: <www.state-machine.com/licensing>
|
||||
//
|
||||
// Redistributions in source code must retain this top-level comment block.
|
||||
// Plagiarizing this software to sidestep the license obligations is illegal.
|
||||
//
|
||||
// Contact information:
|
||||
// Quantum Leaps contact information:
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//
|
||||
//$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(); \
|
||||
@ -84,99 +60,64 @@ 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
|
||||
|
||||
#endif // QF-FuSa disabled
|
||||
|
||||
//============================================================================
|
||||
//$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__)
|
||||
|
||||
//${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
|
||||
|
||||
//============================================================================
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef QP_VERSION
|
||||
typedef int int_t;
|
||||
#endif // ndef QP_VERSION
|
||||
|
||||
//${QP-FuSa::Q_onError} ......................................................
|
||||
Q_NORETURN Q_onError(
|
||||
char const * const module,
|
||||
int_t const id);
|
||||
|
||||
//${QP-FuSa::Q_DIM} ..........................................................
|
||||
#ifndef QP_VERSION
|
||||
#define Q_DIM(array_) (sizeof(array_) / sizeof((array_)[0U]))
|
||||
#endif // ndef QP_VERSION
|
||||
//$enddecl${QP-FuSa} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -1,10 +1,6 @@
|
||||
//$file${include::qstamp.hpp} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
//
|
||||
// Model: qpcpp.qm
|
||||
// File: ${include::qstamp.hpp}
|
||||
//
|
||||
// This code has been generated by QM 7.0.0 <www.state-machine.com/qm>.
|
||||
// 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,8 +10,8 @@
|
||||
//
|
||||
// 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-
|
||||
// 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.
|
||||
@ -30,8 +26,7 @@
|
||||
// Quantum Leaps contact information:
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//
|
||||
//$endhead${include::qstamp.hpp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//============================================================================
|
||||
#ifndef QSTAMP_HPP_
|
||||
#define QSTAMP_HPP_
|
||||
|
||||
|
@ -1,10 +1,6 @@
|
||||
//$file${include::qv.hpp} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
//
|
||||
// Model: qpcpp.qm
|
||||
// File: ${include::qv.hpp}
|
||||
//
|
||||
// This code has been generated by QM 7.0.0 <www.state-machine.com/qm>.
|
||||
// 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,8 +10,8 @@
|
||||
//
|
||||
// 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-
|
||||
// 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.
|
||||
@ -30,97 +26,53 @@
|
||||
// Quantum Leaps contact information:
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//
|
||||
//$endhead${include::qv.hpp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//============================================================================
|
||||
#ifndef QV_HPP_
|
||||
#define QV_HPP_
|
||||
|
||||
//$declare${QV::QV-base} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
namespace QP {
|
||||
namespace QV {
|
||||
|
||||
//${QV::QV-base::Attr} .......................................................
|
||||
//============================================================================
|
||||
class Attr {
|
||||
public:
|
||||
QPSet readySet;
|
||||
std::uint_fast8_t schedCeil;
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
QPSet readySet_dis;
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
std::uint_fast8_t schedCeil_dis;
|
||||
#endif // ndef Q_UNSAFE
|
||||
}; // class Attr
|
||||
|
||||
//${QV::QV-base::priv_} ......................................................
|
||||
extern QV::Attr priv_;
|
||||
|
||||
//${QV::QV-base::schedDisable} ...............................................
|
||||
void schedDisable(std::uint_fast8_t const ceiling);
|
||||
|
||||
//${QV::QV-base::schedEnable} ................................................
|
||||
void schedEnable();
|
||||
|
||||
//${QV::QV-base::onIdle} .....................................................
|
||||
void onIdle();
|
||||
|
||||
} // namespace QV
|
||||
} // namespace QP
|
||||
//$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) (static_cast<void>(0))
|
||||
#define QF_SCHED_UNLOCK_() (static_cast<void>(0))
|
||||
|
||||
//${QV-impl::QF_SCHED_UNLOCK_} ...............................................
|
||||
#define QF_SCHED_UNLOCK_() (static_cast<void>(0))
|
||||
|
||||
//${QV-impl::QACTIVE_EQUEUE_WAIT_} ...........................................
|
||||
// QActive event queue customization for QV...
|
||||
#define QACTIVE_EQUEUE_WAIT_(me_) (static_cast<void>(0))
|
||||
|
||||
//${QV-impl::QACTIVE_EQUEUE_SIGNAL_} .........................................
|
||||
#ifndef Q_UNSAFE
|
||||
#define QACTIVE_EQUEUE_SIGNAL_(me_) \
|
||||
QV::priv_.readySet.insert((me_)->m_prio); \
|
||||
QV::priv_.readySet.update_(&QV::priv_.readySet_dis)
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
//${QV-impl::QACTIVE_EQUEUE_SIGNAL_} .........................................
|
||||
#ifdef Q_UNSAFE
|
||||
#define QACTIVE_EQUEUE_SIGNAL_(me_) \
|
||||
(QV::priv_.readySet.insert((me_)->m_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_) \
|
||||
(p_).init((poolSto_), (poolSize_), (evtSize_))
|
||||
|
||||
//${QF_EPOOL-impl::QF_EPOOL_EVENT_SIZE_} .....................................
|
||||
#define QF_EPOOL_EVENT_SIZE_(p_) ((p_).getBlockSize())
|
||||
|
||||
//${QF_EPOOL-impl::QF_EPOOL_GET_} ............................................
|
||||
#define QF_EPOOL_GET_(p_, e_, m_, qsId_) \
|
||||
((e_) = static_cast<QEvt *>((p_).get((m_), (qsId_))))
|
||||
|
||||
//${QF_EPOOL-impl::QF_EPOOL_PUT_} ............................................
|
||||
#define QF_EPOOL_PUT_(p_, e_, qsId_) ((p_).put((e_), (qsId_)))
|
||||
//$enddecl${QF_EPOOL-impl} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
#endif // QP_IMPL
|
||||
|
||||
|
@ -3,13 +3,13 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
@ -35,9 +35,9 @@
|
||||
// <o>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)
|
||||
// <i>QP API backwards compatibility with the QP/C API version.
|
||||
// <i>QP API backwards compatibility with the QP API version.
|
||||
// <i>Lower QP_API_VERSION values enable backwards compatibility
|
||||
// <i>with lower (older) QP API versions.
|
||||
// <i>For example, QP_API_VERSION==691 will enable the compatibility
|
||||
@ -191,7 +191,7 @@
|
||||
// </c>
|
||||
|
||||
// <c2>Enable memory isolation (QF_MEM_ISOLATE)
|
||||
// <i>Memory isolation (requires MPU)
|
||||
// <i>Memory isolation (supported in SafeQP only, requires MPU)
|
||||
// <i>NOTE: implies QF_ON_CONTEXT_SW.
|
||||
//#define QF_MEM_ISOLATE
|
||||
// </c>
|
||||
@ -201,11 +201,13 @@
|
||||
//..........................................................................
|
||||
// <h>QV/QK/QXK built-in kernels (ARM Cortex-M)
|
||||
|
||||
#if (__ARM_ARCH > 6)
|
||||
// <c2>Kernel uses critical section based on BASEPRI (QF_USE_BASEPRI)
|
||||
// <i>If not selected, critical section will be based on PRIMASK
|
||||
// <i>NOTE: The BASEPRI threshold can be adjusted in the "Text Editor" mode.
|
||||
//#define QF_USE_BASEPRI 0x3F
|
||||
// </c>
|
||||
#endif // (__ARM_ARCH > 6)
|
||||
|
||||
// <c2>QK Kernel uses IRQ for return-from-preemption
|
||||
// <i>NOTE: Use "editor mode" to edit QK_USE_IRQ_NUM
|
||||
|
@ -1,5 +1,6 @@
|
||||
//============================================================================
|
||||
// QP/C++ Real-Time Embedded Framework (RTEF)
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// Q u a n t u m L e a P s
|
||||
@ -8,7 +9,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.
|
||||
//
|
||||
|
@ -9,7 +9,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.
|
||||
//
|
||||
|
@ -1,38 +1,32 @@
|
||||
//============================================================================
|
||||
// QP/C++ Real-Time Embedded Framework (RTEF)
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// Q u a n t u m L e a P s
|
||||
// ------------------------
|
||||
// Modern Embedded Software
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
//
|
||||
// This software is dual-licensed under the terms of the open source GNU
|
||||
// General Public License version 3 (or any later version), or alternatively,
|
||||
// under the terms of one of the closed source Quantum Leaps commercial
|
||||
// licenses.
|
||||
//
|
||||
// The terms of the open source GNU General Public License version 3
|
||||
// can be found at: <www.gnu.org/licenses/gpl-3.0>
|
||||
//
|
||||
// The terms of the closed source Quantum Leaps commercial licenses
|
||||
// can be found at: <www.state-machine.com/licensing>
|
||||
// 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:
|
||||
// <www.state-machine.com>
|
||||
// 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>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-06-06
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QS/C++ port to a 32-bit CPU, generic C++11 compiler
|
||||
|
||||
#ifndef QS_PORT_HPP_
|
||||
#define QS_PORT_HPP_
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
//============================================================================
|
||||
// QP/C++ Real-Time Embedded Framework (RTEF)
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// Q u a n t u m L e a P s
|
||||
@ -8,7 +9,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.
|
||||
//
|
||||
|
@ -9,7 +9,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.
|
||||
//
|
||||
|
@ -1,38 +1,32 @@
|
||||
//============================================================================
|
||||
// QP/C++ Real-Time Embedded Framework (RTEF)
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// Q u a n t u m L e a P s
|
||||
// ------------------------
|
||||
// Modern Embedded Software
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
//
|
||||
// This software is dual-licensed under the terms of the open source GNU
|
||||
// General Public License version 3 (or any later version), or alternatively,
|
||||
// under the terms of one of the closed source Quantum Leaps commercial
|
||||
// licenses.
|
||||
//
|
||||
// The terms of the open source GNU General Public License version 3
|
||||
// can be found at: <www.gnu.org/licenses/gpl-3.0>
|
||||
//
|
||||
// The terms of the closed source Quantum Leaps commercial licenses
|
||||
// can be found at: <www.state-machine.com/licensing>
|
||||
// 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:
|
||||
// <www.state-machine.com>
|
||||
// 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>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-06-06
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QS/C++ port to a 32-bit CPU, generic C++11 compiler
|
||||
|
||||
#ifndef QS_PORT_HPP_
|
||||
#define QS_PORT_HPP_
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
//============================================================================
|
||||
// QP/C++ Real-Time Embedded Framework (RTEF)
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// Q u a n t u m L e a P s
|
||||
@ -8,7 +9,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.
|
||||
//
|
||||
|
@ -9,7 +9,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.
|
||||
//
|
||||
|
@ -1,38 +1,32 @@
|
||||
//============================================================================
|
||||
// QP/C++ Real-Time Embedded Framework (RTEF)
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// Q u a n t u m L e a P s
|
||||
// ------------------------
|
||||
// Modern Embedded Software
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
//
|
||||
// This software is dual-licensed under the terms of the open source GNU
|
||||
// General Public License version 3 (or any later version), or alternatively,
|
||||
// under the terms of one of the closed source Quantum Leaps commercial
|
||||
// licenses.
|
||||
//
|
||||
// The terms of the open source GNU General Public License version 3
|
||||
// can be found at: <www.gnu.org/licenses/gpl-3.0>
|
||||
//
|
||||
// The terms of the closed source Quantum Leaps commercial licenses
|
||||
// can be found at: <www.state-machine.com/licensing>
|
||||
// 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:
|
||||
// <www.state-machine.com>
|
||||
// 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>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-06-06
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QS/C++ port to a 32-bit CPU, generic C++11 compiler
|
||||
|
||||
#ifndef QS_PORT_HPP_
|
||||
#define QS_PORT_HPP_
|
||||
|
||||
|
@ -9,7 +9,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.
|
||||
//
|
||||
|
@ -1,38 +1,32 @@
|
||||
//============================================================================
|
||||
// QP/C++ Real-Time Embedded Framework (RTEF)
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// Q u a n t u m L e a P s
|
||||
// ------------------------
|
||||
// Modern Embedded Software
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
//
|
||||
// This software is dual-licensed under the terms of the open source GNU
|
||||
// General Public License version 3 (or any later version), or alternatively,
|
||||
// under the terms of one of the closed source Quantum Leaps commercial
|
||||
// licenses.
|
||||
//
|
||||
// The terms of the open source GNU General Public License version 3
|
||||
// can be found at: <www.gnu.org/licenses/gpl-3.0>
|
||||
//
|
||||
// The terms of the closed source Quantum Leaps commercial licenses
|
||||
// can be found at: <www.state-machine.com/licensing>
|
||||
// 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:
|
||||
// <www.state-machine.com>
|
||||
// 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>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-06-06
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QS/C++ port to a 32-bit CPU, generic C++11 compiler
|
||||
|
||||
#ifndef QS_PORT_HPP_
|
||||
#define QS_PORT_HPP_
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
//============================================================================
|
||||
// QP/C++ Real-Time Embedded Framework (RTEF)
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// Q u a n t u m L e a P s
|
||||
@ -8,7 +9,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.
|
||||
//
|
||||
|
@ -9,7 +9,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.
|
||||
//
|
||||
|
@ -1,38 +1,32 @@
|
||||
//============================================================================
|
||||
// QP/C++ Real-Time Embedded Framework (RTEF)
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// Q u a n t u m L e a P s
|
||||
// ------------------------
|
||||
// Modern Embedded Software
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
//
|
||||
// This software is dual-licensed under the terms of the open source GNU
|
||||
// General Public License version 3 (or any later version), or alternatively,
|
||||
// under the terms of one of the closed source Quantum Leaps commercial
|
||||
// licenses.
|
||||
//
|
||||
// The terms of the open source GNU General Public License version 3
|
||||
// can be found at: <www.gnu.org/licenses/gpl-3.0>
|
||||
//
|
||||
// The terms of the closed source Quantum Leaps commercial licenses
|
||||
// can be found at: <www.state-machine.com/licensing>
|
||||
// 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:
|
||||
// <www.state-machine.com>
|
||||
// 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>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-06-06
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QS/C++ port to a 32-bit CPU, generic C++11 compiler
|
||||
|
||||
#ifndef QS_PORT_HPP_
|
||||
#define QS_PORT_HPP_
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
//============================================================================
|
||||
// QP/C++ Real-Time Embedded Framework (RTEF)
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// Q u a n t u m L e a P s
|
||||
@ -8,7 +9,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.
|
||||
//
|
||||
|
@ -9,7 +9,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.
|
||||
//
|
||||
|
@ -1,38 +1,32 @@
|
||||
//============================================================================
|
||||
// QP/C++ Real-Time Embedded Framework (RTEF)
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// Q u a n t u m L e a P s
|
||||
// ------------------------
|
||||
// Modern Embedded Software
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
//
|
||||
// This software is dual-licensed under the terms of the open source GNU
|
||||
// General Public License version 3 (or any later version), or alternatively,
|
||||
// under the terms of one of the closed source Quantum Leaps commercial
|
||||
// licenses.
|
||||
//
|
||||
// The terms of the open source GNU General Public License version 3
|
||||
// can be found at: <www.gnu.org/licenses/gpl-3.0>
|
||||
//
|
||||
// The terms of the closed source Quantum Leaps commercial licenses
|
||||
// can be found at: <www.state-machine.com/licensing>
|
||||
// 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:
|
||||
// <www.state-machine.com>
|
||||
// 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>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-06-06
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QS/C++ port to a 32-bit CPU, generic C++11 compiler
|
||||
|
||||
#ifndef QS_PORT_HPP_
|
||||
#define QS_PORT_HPP_
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
//============================================================================
|
||||
// QP/C++ Real-Time Embedded Framework (RTEF)
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// Q u a n t u m L e a P s
|
||||
@ -8,7 +9,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.
|
||||
//
|
||||
|
@ -9,7 +9,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.
|
||||
//
|
||||
@ -191,7 +191,7 @@
|
||||
// </c>
|
||||
|
||||
// <c2>Enable memory isolation (QF_MEM_ISOLATE)
|
||||
// <i>Memory isolation (requires MPU)
|
||||
// <i>Memory isolation (supported in SafeQP only, requires MPU)
|
||||
// <i>NOTE: implies QF_ON_CONTEXT_SW.
|
||||
//#define QF_MEM_ISOLATE
|
||||
// </c>
|
||||
|
@ -9,7 +9,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.
|
||||
//
|
||||
@ -27,12 +27,6 @@
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-11-22
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QP/C++ port to ARM Cortex-R, preemptive QK kernel, GNU-ARM
|
||||
|
||||
#ifndef QP_PORT_HPP_
|
||||
#define QP_PORT_HPP_
|
||||
|
||||
|
@ -1,38 +1,32 @@
|
||||
//============================================================================
|
||||
// QP/C++ Real-Time Embedded Framework (RTEF)
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// Q u a n t u m L e a P s
|
||||
// ------------------------
|
||||
// Modern Embedded Software
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
//
|
||||
// This software is dual-licensed under the terms of the open source GNU
|
||||
// General Public License version 3 (or any later version), or alternatively,
|
||||
// under the terms of one of the closed source Quantum Leaps commercial
|
||||
// licenses.
|
||||
//
|
||||
// The terms of the open source GNU General Public License version 3
|
||||
// can be found at: <www.gnu.org/licenses/gpl-3.0>
|
||||
//
|
||||
// The terms of the closed source Quantum Leaps commercial licenses
|
||||
// can be found at: <www.state-machine.com/licensing>
|
||||
// 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:
|
||||
// <www.state-machine.com>
|
||||
// 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>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-06-06
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QS/C++ port to a 32-bit CPU, generic C++11 compiler
|
||||
|
||||
#ifndef QS_PORT_HPP_
|
||||
#define QS_PORT_HPP_
|
||||
|
||||
|
@ -9,7 +9,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.
|
||||
//
|
||||
@ -27,12 +27,6 @@
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-09-30
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QP/C++ port to ARM Cortex-R, preemptive QK kernel, IAR-ARM
|
||||
|
||||
#ifndef QP_PORT_HPP_
|
||||
#define QP_PORT_HPP_
|
||||
|
||||
|
@ -1,38 +1,32 @@
|
||||
//============================================================================
|
||||
// QP/C++ Real-Time Embedded Framework (RTEF)
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// Q u a n t u m L e a P s
|
||||
// ------------------------
|
||||
// Modern Embedded Software
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
//
|
||||
// This software is dual-licensed under the terms of the open source GNU
|
||||
// General Public License version 3 (or any later version), or alternatively,
|
||||
// under the terms of one of the closed source Quantum Leaps commercial
|
||||
// licenses.
|
||||
//
|
||||
// The terms of the open source GNU General Public License version 3
|
||||
// can be found at: <www.gnu.org/licenses/gpl-3.0>
|
||||
//
|
||||
// The terms of the closed source Quantum Leaps commercial licenses
|
||||
// can be found at: <www.state-machine.com/licensing>
|
||||
// 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:
|
||||
// <www.state-machine.com>
|
||||
// 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>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-06-06
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QS/C++ port to a 32-bit CPU, generic C++11 compiler
|
||||
|
||||
#ifndef QS_PORT_HPP_
|
||||
#define QS_PORT_HPP_
|
||||
|
||||
|
@ -9,7 +9,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.
|
||||
//
|
||||
@ -27,12 +27,6 @@
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-09-30
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QP/C++ port to ARM Cortex-R, preemptive QK kernel, TI-ARM
|
||||
|
||||
#ifndef QP_PORT_HPP_
|
||||
#define QP_PORT_HPP_
|
||||
|
||||
|
@ -1,38 +1,32 @@
|
||||
//============================================================================
|
||||
// QP/C++ Real-Time Embedded Framework (RTEF)
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// Q u a n t u m L e a P s
|
||||
// ------------------------
|
||||
// Modern Embedded Software
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
//
|
||||
// This software is dual-licensed under the terms of the open source GNU
|
||||
// General Public License version 3 (or any later version), or alternatively,
|
||||
// under the terms of one of the closed source Quantum Leaps commercial
|
||||
// licenses.
|
||||
//
|
||||
// The terms of the open source GNU General Public License version 3
|
||||
// can be found at: <www.gnu.org/licenses/gpl-3.0>
|
||||
//
|
||||
// The terms of the closed source Quantum Leaps commercial licenses
|
||||
// can be found at: <www.state-machine.com/licensing>
|
||||
// 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:
|
||||
// <www.state-machine.com>
|
||||
// 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>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-06-06
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QS/C++ port to a 32-bit CPU, generic C++11 compiler
|
||||
|
||||
#ifndef QS_PORT_HPP_
|
||||
#define QS_PORT_HPP_
|
||||
|
||||
|
@ -9,7 +9,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.
|
||||
//
|
||||
@ -27,12 +27,6 @@
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-11-22
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QP/C port to ARM Cortex-R, cooperative QV kernel, GNU-ARM
|
||||
|
||||
#ifndef QP_PORT_HPP_
|
||||
#define QP_PORT_HPP_
|
||||
|
||||
|
@ -1,38 +1,32 @@
|
||||
//============================================================================
|
||||
// QP/C++ Real-Time Embedded Framework (RTEF)
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// Q u a n t u m L e a P s
|
||||
// ------------------------
|
||||
// Modern Embedded Software
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
//
|
||||
// This software is dual-licensed under the terms of the open source GNU
|
||||
// General Public License version 3 (or any later version), or alternatively,
|
||||
// under the terms of one of the closed source Quantum Leaps commercial
|
||||
// licenses.
|
||||
//
|
||||
// The terms of the open source GNU General Public License version 3
|
||||
// can be found at: <www.gnu.org/licenses/gpl-3.0>
|
||||
//
|
||||
// The terms of the closed source Quantum Leaps commercial licenses
|
||||
// can be found at: <www.state-machine.com/licensing>
|
||||
// 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:
|
||||
// <www.state-machine.com>
|
||||
// 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>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-06-06
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QS/C++ port to a 32-bit CPU, generic C++11 compiler
|
||||
|
||||
#ifndef QS_PORT_HPP_
|
||||
#define QS_PORT_HPP_
|
||||
|
||||
|
@ -9,7 +9,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.
|
||||
//
|
||||
@ -27,12 +27,6 @@
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-09-30
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QP/C++ port to Cortex-R, cooperative QV kernel, IAR-ARM
|
||||
|
||||
#ifndef QP_PORT_HPP_
|
||||
#define QP_PORT_HPP_
|
||||
|
||||
|
@ -1,38 +1,32 @@
|
||||
//============================================================================
|
||||
// QP/C++ Real-Time Embedded Framework (RTEF)
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// Q u a n t u m L e a P s
|
||||
// ------------------------
|
||||
// Modern Embedded Software
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
//
|
||||
// This software is dual-licensed under the terms of the open source GNU
|
||||
// General Public License version 3 (or any later version), or alternatively,
|
||||
// under the terms of one of the closed source Quantum Leaps commercial
|
||||
// licenses.
|
||||
//
|
||||
// The terms of the open source GNU General Public License version 3
|
||||
// can be found at: <www.gnu.org/licenses/gpl-3.0>
|
||||
//
|
||||
// The terms of the closed source Quantum Leaps commercial licenses
|
||||
// can be found at: <www.state-machine.com/licensing>
|
||||
// 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:
|
||||
// <www.state-machine.com>
|
||||
// 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>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-06-06
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QS/C++ port to a 32-bit CPU, generic C++11 compiler
|
||||
|
||||
#ifndef QS_PORT_HPP_
|
||||
#define QS_PORT_HPP_
|
||||
|
||||
|
@ -9,7 +9,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.
|
||||
//
|
||||
@ -27,12 +27,6 @@
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-09-30
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QP/C++ port to ARM Cortex-R, cooperative QV kernel, TI-ARM
|
||||
|
||||
#ifndef QP_PORT_HPP_
|
||||
#define QP_PORT_HPP_
|
||||
|
||||
|
@ -1,38 +1,32 @@
|
||||
//============================================================================
|
||||
// QP/C++ Real-Time Embedded Framework (RTEF)
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// Q u a n t u m L e a P s
|
||||
// ------------------------
|
||||
// Modern Embedded Software
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
//
|
||||
// This software is dual-licensed under the terms of the open source GNU
|
||||
// General Public License version 3 (or any later version), or alternatively,
|
||||
// under the terms of one of the closed source Quantum Leaps commercial
|
||||
// licenses.
|
||||
//
|
||||
// The terms of the open source GNU General Public License version 3
|
||||
// can be found at: <www.gnu.org/licenses/gpl-3.0>
|
||||
//
|
||||
// The terms of the closed source Quantum Leaps commercial licenses
|
||||
// can be found at: <www.state-machine.com/licensing>
|
||||
// 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:
|
||||
// <www.state-machine.com>
|
||||
// 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>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-06-06
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QS/C++ port to a 32-bit CPU, generic C++11 compiler
|
||||
|
||||
#ifndef QS_PORT_HPP_
|
||||
#define QS_PORT_HPP_
|
||||
|
||||
|
@ -9,7 +9,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.
|
||||
//
|
||||
@ -191,7 +191,7 @@
|
||||
// </c>
|
||||
|
||||
// <c2>Enable memory isolation (QF_MEM_ISOLATE)
|
||||
// <i>Memory isolation (requires MPU)
|
||||
// <i>Memory isolation (supported in SafeQP only, requires MPU)
|
||||
// <i>NOTE: implies QF_ON_CONTEXT_SW.
|
||||
//#define QF_MEM_ISOLATE
|
||||
// </c>
|
||||
|
@ -7,7 +7,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.
|
||||
//
|
||||
@ -25,12 +25,6 @@
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-09-26
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QF/C++ port to embOS RTOS kernel, generic C++11 compiler
|
||||
|
||||
#define QP_IMPL // this is QP implementation
|
||||
#include "qp_port.hpp" // QP port
|
||||
#include "qp_pkg.hpp" // QP package-scope interface
|
||||
@ -206,9 +200,6 @@ bool QActive::post_(QEvt const * const e, std::uint_fast16_t const margin,
|
||||
QF_CRIT_ENTRY();
|
||||
|
||||
Q_REQUIRE_INCRIT(200, e != nullptr);
|
||||
#ifndef Q_UNSAFE
|
||||
Q_INVARIANT_INCRIT(201, e->verify_());
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
std::uint_fast16_t nFree =
|
||||
static_cast<std::uint_fast16_t>(m_eQueue.maxMsg - m_eQueue.nofMsg);
|
||||
@ -237,12 +228,13 @@ bool QActive::post_(QEvt const * const e, std::uint_fast16_t const margin,
|
||||
QS_OBJ_PRE(sender); // the sender object
|
||||
QS_SIG_PRE(e->sig); // the signal of the event
|
||||
QS_OBJ_PRE(this); // this active object (recipient)
|
||||
QS_2U8_PRE(e->getPoolNum_(), 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 (e->getPoolNum_() != 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();
|
||||
@ -260,7 +252,7 @@ bool QActive::post_(QEvt const * const e, std::uint_fast16_t const margin,
|
||||
QS_OBJ_PRE(sender); // the sender object
|
||||
QS_SIG_PRE(e->sig); // the signal of the event
|
||||
QS_OBJ_PRE(this); // this active object (recipient)
|
||||
QS_2U8_PRE(e->getPoolNum_(), e->refCtr_); // poolNum & refCtr
|
||||
QS_2U8_PRE(e->poolNum_, e->refCtr_); // poolNum & refCtr
|
||||
QS_EQC_PRE(nFree); // # free entries
|
||||
QS_EQC_PRE(margin); // margin requested
|
||||
QS_END_PRE()
|
||||
@ -275,20 +267,18 @@ void QActive::postLIFO(QEvt const * const e) noexcept {
|
||||
QF_CRIT_ENTRY();
|
||||
|
||||
Q_REQUIRE_INCRIT(300, e != nullptr);
|
||||
#ifndef Q_UNSAFE
|
||||
Q_INVARIANT_INCRIT(301, e->verify_());
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
QS_BEGIN_PRE(QS_QF_ACTIVE_POST_LIFO, m_prio)
|
||||
QS_TIME_PRE(); // timestamp
|
||||
QS_SIG_PRE(e->sig); // the signal of this event
|
||||
QS_OBJ_PRE(this); // this active object
|
||||
QS_2U8_PRE(e->getPoolNum_(), e->refCtr_);
|
||||
QS_2U8_PRE(e->poolNum_, e->refCtr_);
|
||||
QS_EQC_PRE(m_eQueue.maxMsg - m_eQueue.nofMsg); // # free entries
|
||||
QS_EQC_PRE(0U); // min # free entries (unknown)
|
||||
QS_END_PRE()
|
||||
|
||||
if (e->getPoolNum_() != 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();
|
||||
@ -311,7 +301,7 @@ QEvt const *QActive::get_() noexcept {
|
||||
QS_TIME_PRE(); // timestamp
|
||||
QS_SIG_PRE(e->sig); // the signal of this event
|
||||
QS_OBJ_PRE(this); // this active object
|
||||
QS_2U8_PRE(e->getPoolNum_(), e->refCtr_); // poolNum & refCtr
|
||||
QS_2U8_PRE(e->poolNum_, e->refCtr_); // poolNum & refCtr
|
||||
QS_EQC_PRE(m_eQueue.maxMsg - m_eQueue.nofMsg); // # free
|
||||
QS_END_PRE()
|
||||
QS_CRIT_EXIT();
|
||||
|
@ -9,7 +9,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.
|
||||
//
|
||||
@ -27,12 +27,6 @@
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-09-30
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QP/C++ port to embOS RTOS (v5), generic C++11 compiler
|
||||
|
||||
#ifndef QP_PORT_HPP_
|
||||
#define QP_PORT_HPP_
|
||||
|
||||
|
@ -1,38 +1,32 @@
|
||||
//============================================================================
|
||||
// QP/C++ Real-Time Embedded Framework (RTEF)
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// Q u a n t u m L e a P s
|
||||
// ------------------------
|
||||
// Modern Embedded Software
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
//
|
||||
// This software is dual-licensed under the terms of the open source GNU
|
||||
// General Public License version 3 (or any later version), or alternatively,
|
||||
// under the terms of one of the closed source Quantum Leaps commercial
|
||||
// licenses.
|
||||
//
|
||||
// The terms of the open source GNU General Public License version 3
|
||||
// can be found at: <www.gnu.org/licenses/gpl-3.0>
|
||||
//
|
||||
// The terms of the closed source Quantum Leaps commercial licenses
|
||||
// can be found at: <www.state-machine.com/licensing>
|
||||
// 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:
|
||||
// <www.state-machine.com>
|
||||
// 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>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-06-06
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QS/C++ port to a 32-bit CPU, generic C++11 compiler
|
||||
|
||||
#ifndef QS_PORT_HPP_
|
||||
#define QS_PORT_HPP_
|
||||
|
||||
|
@ -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 <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.
|
||||
// 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>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-10-29
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QF/C++ port to FreeRTOS 10.x, generic C++11 compiler
|
||||
|
||||
#define QP_IMPL // this is QP implementation
|
||||
#include "qp_port.hpp" // QP port
|
||||
#include "qp_pkg.hpp" // QP package-level interface
|
||||
@ -43,11 +39,11 @@
|
||||
#endif // Q_SPY
|
||||
|
||||
#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
|
||||
|
||||
namespace { // unnamed local namespace
|
||||
@ -181,7 +177,7 @@ void QActive::start(
|
||||
|
||||
// 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.
|
||||
@ -195,7 +191,7 @@ void QActive::start(
|
||||
// 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);
|
||||
@ -257,46 +253,48 @@ bool QActive::post_(QEvt const * const e, std::uint_fast16_t const margin,
|
||||
QF_CRIT_ENTRY();
|
||||
|
||||
Q_REQUIRE_INCRIT(200, e != nullptr);
|
||||
#ifndef Q_UNSAFE
|
||||
Q_INVARIANT_INCRIT(201, e->verify_());
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
// the number of free slots available in the queue
|
||||
std::uint_fast16_t nFree =
|
||||
static_cast<std::uint_fast16_t>(FREERTOS_QUEUE_GET_FREE());
|
||||
|
||||
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 > margin) {
|
||||
else if (nFree > 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, m_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(this); // this active object (recipient)
|
||||
QS_2U8_PRE(e->getPoolNum_(), 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(this); // this active object (recipient)
|
||||
QS_2U8_PRE(e->poolNum_, e->refCtr_);
|
||||
QS_EQC_PRE(static_cast<QEQueueCtr>(nFree)); // # free entries
|
||||
QS_EQC_PRE(0U); // min # free entries (unknown)
|
||||
QS_EQC_PRE(0U); // min # free entries (unknown)
|
||||
QS_END_PRE()
|
||||
|
||||
if (e->getPoolNum_() != 0U) { // is it a pool event?
|
||||
QEvt_refCtr_inc_(e); // increment the reference counter
|
||||
}
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
BaseType_t err = xQueueSendToBack(
|
||||
@ -305,49 +303,56 @@ bool QActive::post_(QEvt const * const e, std::uint_fast16_t const margin,
|
||||
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, m_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(this); // this active object (recipient)
|
||||
QS_2U8_PRE(e->getPoolNum_(), 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(this); // this active object (recipient)
|
||||
QS_2U8_PRE(e->poolNum_, e->refCtr_);
|
||||
QS_EQC_PRE(static_cast<QEQueueCtr>(nFree)); // # free entries
|
||||
QS_EQC_PRE(margin); // margin requested
|
||||
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(QEvt const * const e) noexcept {
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
|
||||
Q_REQUIRE_INCRIT(300, e != nullptr);
|
||||
#ifndef Q_UNSAFE
|
||||
Q_INVARIANT_INCRIT(301, e->verify_());
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
#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)
|
||||
|
||||
QS_BEGIN_PRE(QS_QF_ACTIVE_POST_LIFO, m_prio)
|
||||
QS_TIME_PRE(); // timestamp
|
||||
QS_SIG_PRE(e->sig); // the signal of this event
|
||||
QS_OBJ_PRE(this); // this active object
|
||||
QS_2U8_PRE(e->evtTag_, e->refCtr_); // pool Id & refCtr of the evt
|
||||
QS_2U8_PRE(e->poolNum_, e->refCtr_);
|
||||
QS_EQC_PRE(static_cast<QEQueueCtr>(FREERTOS_QUEUE_GET_FREE()));
|
||||
QS_EQC_PRE(0U); // min # free entries (unknown)
|
||||
QS_END_PRE()
|
||||
|
||||
if (e->getPoolNum_() != 0U) { // is it a pool event?
|
||||
QEvt_refCtr_inc_(e); // increment the reference counter
|
||||
}
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
BaseType_t err = xQueueSendToFront(
|
||||
@ -370,10 +375,10 @@ QEvt const *QActive::get_(void) noexcept {
|
||||
QS_CRIT_STAT
|
||||
QS_CRIT_ENTRY();
|
||||
QS_BEGIN_PRE(QS_QF_ACTIVE_GET, m_prio)
|
||||
QS_TIME_PRE(); // timestamp
|
||||
QS_SIG_PRE(e->sig); // the signal of this event
|
||||
QS_OBJ_PRE(this); // this active object
|
||||
QS_2U8_PRE(e->getPoolNum_(), e->refCtr_); // pool Id&ref Count
|
||||
QS_TIME_PRE(); // timestamp
|
||||
QS_SIG_PRE(e->sig); // the signal of this event
|
||||
QS_OBJ_PRE(this); // this active object
|
||||
QS_2U8_PRE(e->poolNum_, e->refCtr_);
|
||||
QS_EQC_PRE(static_cast<QEQueueCtr>(FREERTOS_QUEUE_GET_FREE()));
|
||||
QS_END_PRE()
|
||||
QS_CRIT_EXIT();
|
||||
@ -390,76 +395,80 @@ bool QActive::postFromISR(QEvt const * const e,
|
||||
{
|
||||
UBaseType_t uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||
|
||||
Q_REQUIRE_INCRIT(500, e != nullptr);
|
||||
#ifndef Q_UNSAFE
|
||||
Q_INVARIANT_INCRIT(501, e->verify_());
|
||||
#endif // ndef Q_UNSAFE
|
||||
Q_REQUIRE_INCRIT(400, e != nullptr);
|
||||
|
||||
// find the number of free slots available in the queue
|
||||
// the number of free slots available in the FreeRTOS queue
|
||||
std::uint_fast16_t const nFree =
|
||||
static_cast<std::uint_fast16_t>(FREERTOS_QUEUE_GET_FREE());
|
||||
|
||||
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 > 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, m_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(this); // this active object (recipient)
|
||||
QS_2U8_PRE(e->getPoolNum_(), e->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(this); // this active object (recipient)
|
||||
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 (e->getPoolNum_() != 0U) { // is it a pool event?
|
||||
QEvt_refCtr_inc_(e); // increment the reference counter
|
||||
}
|
||||
portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus);
|
||||
|
||||
BaseType_t err = xQueueSendToBackFromISR(m_eQueue,
|
||||
static_cast<void const *>(&e),
|
||||
static_cast<BaseType_t*>(par));
|
||||
|
||||
// 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, m_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(this); // this active object (recipient)
|
||||
QS_2U8_PRE(e->getPoolNum_(), e->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(this); // this active object (recipient)
|
||||
QS_2U8_PRE(e->poolNum_, e->refCtr_);
|
||||
QS_EQC_PRE(nFree); // # free entries available
|
||||
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;
|
||||
@ -469,152 +478,140 @@ void QActive::publishFromISR(QEvt const *e,
|
||||
void *par,
|
||||
void const * const sender) noexcept
|
||||
{
|
||||
Q_REQUIRE_INCRIT(600, e != nullptr);
|
||||
#ifndef Q_UNSAFE
|
||||
Q_INVARIANT_INCRIT(601, e->verify_());
|
||||
#endif // ndef Q_UNSAFE
|
||||
Q_REQUIRE_INCRIT(500, e != nullptr);
|
||||
|
||||
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 < QActive::maxPubSignal_);
|
||||
Q_REQUIRE_INCRIT(611,
|
||||
subscrList_[sig].m_set.verify_(&subscrList_[sig].m_set_dis));
|
||||
Q_REQUIRE_INCRIT(510, sig < 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(e->getPoolNum_(), e->refCtr_);
|
||||
QS_2U8_PRE(e->poolNum_, e->refCtr_);
|
||||
QS_END_PRE()
|
||||
|
||||
// is it a dynamic event?
|
||||
if (e->getPoolNum_() != 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.
|
||||
Q_ASSERT_INCRIT(505, 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].m_set;
|
||||
|
||||
portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus);
|
||||
|
||||
if (subscrSet.notEmpty()) { // any subscribers?
|
||||
// the highest-prio subscriber
|
||||
std::uint_fast8_t p = subscrSet.findMax();
|
||||
|
||||
// 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, registry_[p] != nullptr);
|
||||
portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus);
|
||||
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||
|
||||
// POST_FROM_ISR() asserts if the queue overflows
|
||||
registry_[p]->POST_FROM_ISR(e, par, sender);
|
||||
// no need to lock the scheduler in the ISR context
|
||||
QActive *a = registry_[p];
|
||||
Q_ASSERT_INCRIT(520, a != nullptr);
|
||||
|
||||
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
|
||||
a->POST_FROM_ISR(e, par, sender);
|
||||
|
||||
subscrSet.remove(p); // remove the handled subscriber
|
||||
if (subscrSet.notEmpty()) { // still more subscribers?
|
||||
if (subscrSet.notEmpty()) { // still more subscribers?
|
||||
p = subscrSet.findMax(); // the highest-prio subscriber
|
||||
|
||||
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||
|
||||
a = registry_[p];
|
||||
// the AO must be registered with the framework
|
||||
Q_ASSERT_INCRIT(530, a != nullptr);
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
//............................................................................
|
||||
void QTimeEvt::tickFromISR(std::uint_fast8_t const tickRate,
|
||||
void *pxHigherPriorityTaskWoken,
|
||||
void const * const sender) noexcept
|
||||
{
|
||||
#ifndef Q_SPY
|
||||
#ifndef Q_SPY
|
||||
Q_UNUSED_PAR(sender);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
UBaseType_t uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||
|
||||
Q_REQUIRE_INCRIT(700, tickRate < Q_DIM(timeEvtHead_));
|
||||
Q_REQUIRE_INCRIT(600, tickRate < Q_DIM(timeEvtHead_));
|
||||
|
||||
QTimeEvt *prev = &timeEvtHead_[tickRate];
|
||||
|
||||
#ifdef Q_SPY
|
||||
QS_BEGIN_PRE(QS_QF_TICK, 0U)
|
||||
prev->m_ctr = (prev->m_ctr + 1U);
|
||||
QS_TEC_PRE(prev->m_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...
|
||||
std::uint_fast8_t lbound = 2U*QF_MAX_ACTIVE; // fixed upper loop bound
|
||||
for (; lbound > 0U; --lbound) {
|
||||
Q_ASSERT_INCRIT(710, prev != nullptr); // sanity check
|
||||
while (true) {
|
||||
Q_ASSERT_INCRIT(610, prev != nullptr); // sanity check
|
||||
|
||||
QTimeEvt *te = prev->m_next; // advance down the time evt. list
|
||||
#ifndef Q_UNSAFE
|
||||
Q_INVARIANT_INCRIT(711,
|
||||
Q_PTR2UINT_CAST_(te) ==
|
||||
static_cast<std::uintptr_t>(~prev->m_next_dis));
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
if (te == nullptr) { // end of the list?
|
||||
|
||||
// any new time events armed since the last QTimeEvt_tick_()?
|
||||
if (timeEvtHead_[tickRate].m_act != nullptr) {
|
||||
#ifndef Q_UNSAFE
|
||||
Q_INVARIANT_INCRIT(712,
|
||||
Q_PTR2UINT_CAST_(timeEvtHead_[tickRate].m_act) ==
|
||||
static_cast<std::uintptr_t>(
|
||||
~timeEvtHead_dis_[tickRate].m_ptr_dis));
|
||||
#endif // ndef Q_UNSAFE
|
||||
prev->m_next = timeEvtHead_[tickRate].toTimeEvt();
|
||||
timeEvtHead_[tickRate].m_act = nullptr;
|
||||
#ifndef Q_UNSAFE
|
||||
prev->m_next_dis =
|
||||
static_cast<std::uintptr_t>(
|
||||
~Q_PTR2UINT_CAST_(prev->m_next));
|
||||
timeEvtHead_dis_[tickRate].m_ptr_dis =
|
||||
static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(nullptr));
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
te = prev->m_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 (timeEvtHead_[tickRate].m_act == nullptr) {
|
||||
break; // terminate the for-loop
|
||||
}
|
||||
|
||||
prev->m_next = timeEvtHead_[tickRate].toTimeEvt();
|
||||
timeEvtHead_[tickRate].m_act = nullptr;
|
||||
|
||||
te = prev->m_next; // switch to the new list
|
||||
}
|
||||
|
||||
// the time event 'te' must be valid
|
||||
Q_ASSERT_INCRIT(720, te != nullptr);
|
||||
Q_INVARIANT_INCRIT(721, te->verify_());
|
||||
Q_ASSERT_INCRIT(640, te != nullptr);
|
||||
|
||||
QTimeEvtCtr ctr = te->m_ctr;
|
||||
#ifndef Q_UNSAFE
|
||||
Q_INVARIANT_INCRIT(722, ctr ==
|
||||
static_cast<QTimeEvtCtr>(~te->m_ctr_dis));
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
if (ctr == 0U) { // time event scheduled for removal?
|
||||
prev->m_next = te->m_next;
|
||||
#ifndef Q_UNSAFE
|
||||
prev->m_next_dis =
|
||||
static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(te->m_next));
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
// mark time event 'te' as NOT linked
|
||||
te->m_flags &= static_cast<std::uint8_t>(~QTE_FLAG_IS_LINKED);
|
||||
|
||||
// do NOT advance the prev pointer
|
||||
|
||||
// exit crit. section to reduce latency
|
||||
@ -622,42 +619,7 @@ void QTimeEvt::tickFromISR(std::uint_fast8_t const tickRate,
|
||||
}
|
||||
else if (ctr == 1U) { // is time event about to expire?
|
||||
QActive * const act = te->toActive();
|
||||
if (te->m_interval != 0U) { // periodic time evt?
|
||||
te->m_ctr = te->m_interval; // rearm the time event
|
||||
#ifndef Q_UNSAFE
|
||||
te->m_ctr_dis = static_cast<QTimeEvtCtr>(~te->m_interval);
|
||||
#endif // ndef Q_UNSAFE
|
||||
prev = te; // advance to this time event
|
||||
}
|
||||
else { // one-shot time event: automatically disarm
|
||||
te->m_ctr = 0U;
|
||||
prev->m_next = te->m_next;
|
||||
#ifndef Q_UNSAFE
|
||||
te->m_ctr_dis =
|
||||
static_cast<QTimeEvtCtr>(~static_cast<QTimeEvtCtr>(0U));
|
||||
prev->m_next_dis =
|
||||
static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(te->m_next));
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
// mark time event 'te' as NOT linked
|
||||
te->m_flags &=
|
||||
static_cast<std::uint8_t>(~QTE_FLAG_IS_LINKED);
|
||||
// do NOT advance the prev pointer
|
||||
|
||||
QS_BEGIN_PRE(QS_QF_TIMEEVT_AUTO_DISARM, act->m_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->m_prio)
|
||||
QS_TIME_PRE(); // timestamp
|
||||
QS_OBJ_PRE(te); // the time event object
|
||||
QS_SIG_PRE(te->sig); // signal of this time event
|
||||
QS_OBJ_PRE(act); // the target AO
|
||||
QS_U8_PRE(tickRate); // tick rate
|
||||
QS_END_PRE()
|
||||
prev = te->expire_(prev, act, tickRate);
|
||||
|
||||
portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus);
|
||||
|
||||
@ -669,9 +631,6 @@ void QTimeEvt::tickFromISR(std::uint_fast8_t const tickRate,
|
||||
else { // time event keeps timing out
|
||||
--ctr; // decrement the tick counter
|
||||
te->m_ctr = ctr; // update the original
|
||||
#ifndef Q_UNSAFE
|
||||
te->m_ctr_dis = static_cast<QTimeEvtCtr>(~ctr);
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
prev = te; // advance to this time event
|
||||
|
||||
@ -681,16 +640,15 @@ void QTimeEvt::tickFromISR(std::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_(std::uint_fast16_t const evtSize,
|
||||
std::uint_fast16_t const margin,
|
||||
enum_t const sig) noexcept
|
||||
{
|
||||
// find the pool index that fits the requested event size...
|
||||
// find the pool number that fits the requested event size...
|
||||
std::uint_fast8_t poolNum = 0U; // zero-based poolNum initially
|
||||
for (; poolNum < priv_.maxPool_; ++poolNum) {
|
||||
if (evtSize <= QF_EPOOL_EVENT_SIZE_(priv_.ePool_[poolNum])) {
|
||||
@ -702,28 +660,29 @@ QEvt *QF::newXfromISR_(std::uint_fast16_t const evtSize,
|
||||
|
||||
// precondition:
|
||||
// - cannot run out of registered pools
|
||||
Q_REQUIRE_INCRIT(800, poolNum < priv_.maxPool_);
|
||||
Q_REQUIRE_INCRIT(700, poolNum < 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 = static_cast<QEvt *>(
|
||||
e = static_cast<QEvt *>(
|
||||
priv_.ePool_[poolNum - 1U].getFromISR(((margin != QF::NO_MARGIN)
|
||||
? margin : 0U),
|
||||
static_cast<std::uint_fast8_t>(QS_EP_ID) + poolNum));
|
||||
#else
|
||||
QEvt *e = static_cast<QEvt *>(
|
||||
e = static_cast<QEvt *>(
|
||||
priv_.ePool_[poolNum - 1U].getFromISR(((margin != QF::NO_MARGIN)
|
||||
? margin : 0U), 0U));
|
||||
#endif
|
||||
|
||||
if (e != nullptr) { // was e allocated correctly?
|
||||
e->sig = static_cast<QSignal>(sig); // set the signal
|
||||
e->refCtr_ = 0U;
|
||||
e->evtTag_ = static_cast<std::uint8_t>((poolNum << 4U) | 0x0FU);
|
||||
e->sig = static_cast<QSignal>(sig); // set the signal
|
||||
e->poolNum_ = poolNum;
|
||||
e->refCtr_ = 0U;
|
||||
|
||||
#ifdef Q_SPY
|
||||
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||
@ -742,7 +701,7 @@ QEvt *QF::newXfromISR_(std::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,
|
||||
static_cast<uint_fast8_t>(QS_EP_ID) + poolNum)
|
||||
@ -762,12 +721,9 @@ QEvt *QF::newXfromISR_(std::uint_fast16_t const evtSize,
|
||||
void QF::gcFromISR(QEvt const * const e) noexcept {
|
||||
UBaseType_t uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||
|
||||
Q_REQUIRE_INCRIT(700, e != nullptr);
|
||||
#ifndef Q_UNSAFE
|
||||
Q_INVARIANT_INCRIT(701, e->verify_());
|
||||
#endif
|
||||
Q_REQUIRE_INCRIT(800, e != nullptr);
|
||||
|
||||
std::uint_fast8_t const poolNum = e->getPoolNum_();
|
||||
std::uint_fast8_t const poolNum = e->poolNum_;
|
||||
|
||||
if (poolNum != 0U) { // is it a pool event (mutable)?
|
||||
|
||||
@ -780,6 +736,7 @@ void QF::gcFromISR(QEvt const * const e) noexcept {
|
||||
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);
|
||||
@ -790,19 +747,19 @@ void QF::gcFromISR(QEvt const * const e) noexcept {
|
||||
static_cast<uint_fast8_t>(QS_EP_ID) + poolNum)
|
||||
QS_TIME_PRE(); // timestamp
|
||||
QS_SIG_PRE(e->sig); // the signal of the event
|
||||
QS_2U8_PRE(e->getPoolNum_(), e->refCtr_);//poolNum & refCtr
|
||||
QS_2U8_PRE(poolNum, e->refCtr_);
|
||||
QS_END_PRE()
|
||||
|
||||
// pool number must be in range
|
||||
Q_ASSERT_INCRIT(710, (poolNum <= priv_.maxPool_)
|
||||
Q_ASSERT_INCRIT(810, (poolNum <= 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
|
||||
priv_.ePool_[poolNum - 1U].putFromISR(QF_CONST_CAST_(QEvt*, e),
|
||||
static_cast<uint_fast8_t>(QS_EP_ID) + e->getPoolNum_());
|
||||
static_cast<uint_fast8_t>(QS_EP_ID) + e->poolNum_);
|
||||
#else
|
||||
priv_.ePool_[poolNum - 1U].putFromISR(QF_CONST_CAST_(QEvt*, e), 0U);
|
||||
#endif
|
||||
@ -816,81 +773,57 @@ void QF::gcFromISR(QEvt const * const e) noexcept {
|
||||
void *QMPool::getFromISR(std::uint_fast16_t const margin,
|
||||
std::uint_fast8_t const qsId) noexcept
|
||||
{
|
||||
#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 = m_free_head;
|
||||
void * *pfb = static_cast<void**>(m_freeHead); // pointer to free block
|
||||
QMPoolCtr nFree = m_nFree;
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
Q_INVARIANT_INCRIT(801, Q_PTR2UINT_CAST_(fb)
|
||||
== static_cast<std::uintptr_t>(~m_free_head_dis));
|
||||
Q_INVARIANT_INCRIT(802, nFree == static_cast<QMPoolCtr>(~m_nFree_dis));
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
// have more free blocks than the requested margin?
|
||||
if (nFree > static_cast<QMPoolCtr>(margin)) {
|
||||
Q_ASSERT_INCRIT(810, fb != nullptr);
|
||||
Q_ASSERT_INCRIT(910, pfb != nullptr);
|
||||
|
||||
QFreeBlock * const fb_next = fb->m_next;
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
// the free block must have integrity (duplicate inverse storage)
|
||||
Q_INVARIANT_INCRIT(811, Q_PTR2UINT_CAST_(fb_next)
|
||||
== static_cast<std::uintptr_t>(~fb->m_next_dis));
|
||||
#endif // ndef Q_UNSAFE
|
||||
void ** const pfb_next = static_cast<void**>(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 == nullptr);
|
||||
Q_ASSERT_INCRIT(920, pfb_next == nullptr);
|
||||
|
||||
m_nFree = 0U;
|
||||
#ifndef Q_UNSAFE
|
||||
m_nFree_dis = static_cast<QMPoolCtr>(~m_nFree);
|
||||
m_nMin = 0U; // remember that the pool got empty
|
||||
#endif // ndef Q_UNSAFE
|
||||
m_nFree = 0U; // no more free blocks
|
||||
m_nMin = 0U; // remember that the pool got empty
|
||||
}
|
||||
else {
|
||||
else { // the pool is NOT empty
|
||||
|
||||
// the next free-block pointer must be in range
|
||||
Q_INVARIANT_INCRIT(930,
|
||||
QF_PTR_RANGE_(pfb_next, m_start, m_end));
|
||||
|
||||
m_nFree = nFree; // update the original
|
||||
#ifndef Q_UNSAFE
|
||||
m_nFree_dis = static_cast<QMPoolCtr>(~nFree);
|
||||
|
||||
// The pool is not empty, so the next free-block pointer
|
||||
// must be in range.
|
||||
Q_INVARIANT_INCRIT(830,
|
||||
QF_PTR_RANGE_(fb_next, m_start, m_end));
|
||||
|
||||
// is the # free blocks the new minimum so far?
|
||||
if (m_nMin > nFree) {
|
||||
if (m_nMin > nFree) { // is this the new minimum?
|
||||
m_nMin = nFree; // remember the minimum so far
|
||||
}
|
||||
#endif // ndef Q_UNSAFE
|
||||
}
|
||||
|
||||
m_free_head = fb_next; // set the head to the next free block
|
||||
#ifndef Q_UNSAFE
|
||||
m_free_head_dis =
|
||||
static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(fb_next));
|
||||
#endif // ndef Q_UNSAFE
|
||||
m_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] = &m_end[1]; // invalid location beyond the end
|
||||
|
||||
QS_BEGIN_PRE(QS_QF_MPOOL_GET, qsId)
|
||||
QS_TIME_PRE(); // timestamp
|
||||
QS_OBJ_PRE(this); // 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(m_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 = nullptr;
|
||||
pfb = nullptr;
|
||||
|
||||
QS_BEGIN_PRE(QS_QF_MPOOL_GET_ATTEMPT, qsId)
|
||||
QS_TIME_PRE(); // timestamp
|
||||
@ -902,43 +835,32 @@ void *QMPool::getFromISR(std::uint_fast16_t const margin,
|
||||
|
||||
portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus);
|
||||
|
||||
return fb; // return the block or nullptr to the caller
|
||||
return pfb; // return the block or nullptr to the caller
|
||||
}
|
||||
//............................................................................
|
||||
void QMPool::putFromISR(void *block,
|
||||
std::uint_fast8_t const qsId) noexcept
|
||||
{
|
||||
#ifndef Q_SPY
|
||||
#ifndef Q_SPY
|
||||
Q_UNUSED_PAR(qsId);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
QFreeBlock * const fb = static_cast<QFreeBlock *>(block);
|
||||
void * * const pfb = static_cast<void**>(block);
|
||||
|
||||
UBaseType_t uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||
|
||||
// get volatile into temporaries
|
||||
QFreeBlock * const free_head = m_free_head;
|
||||
void ** const freeHead = static_cast<void**>(m_freeHead);
|
||||
QMPoolCtr nFree = m_nFree;
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
Q_INVARIANT_INCRIT(901, Q_PTR2UINT_CAST_(free_head)
|
||||
== static_cast<std::uintptr_t>(~m_free_head_dis));
|
||||
Q_INVARIANT_INCRIT(902, nFree == static_cast<QMPoolCtr>(~m_nFree_dis));
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
Q_REQUIRE_INCRIT(910, nFree < m_nTot);
|
||||
Q_REQUIRE_INCRIT(911, QF_PTR_RANGE_(fb, m_start, m_end));
|
||||
Q_REQUIRE_INCRIT(1000, nFree < m_nTot);
|
||||
Q_REQUIRE_INCRIT(1010, QF_PTR_RANGE_(pfb, m_start, m_end));
|
||||
|
||||
++nFree; // one more free block in this pool
|
||||
|
||||
m_free_head = fb; // set as new head of the free list
|
||||
m_freeHead = pfb; // set as new head of the free list
|
||||
m_nFree = nFree;
|
||||
fb->m_next = free_head; // link into the list
|
||||
#ifndef Q_UNSAFE
|
||||
m_free_head_dis = static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(fb));
|
||||
m_nFree_dis = static_cast<QMPoolCtr>(~nFree);
|
||||
fb->m_next_dis = static_cast<std::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
|
||||
|
@ -9,7 +9,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.
|
||||
//
|
||||
@ -27,12 +27,6 @@
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-09-30
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QP/C++ port to FreeRTOS 10.x generic C++11 compiler
|
||||
|
||||
#ifndef QP_PORT_HPP_
|
||||
#define QP_PORT_HPP_
|
||||
|
||||
|
@ -1,38 +1,32 @@
|
||||
//============================================================================
|
||||
// QP/C++ Real-Time Embedded Framework (RTEF)
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// Q u a n t u m L e a P s
|
||||
// ------------------------
|
||||
// Modern Embedded Software
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
//
|
||||
// This software is dual-licensed under the terms of the open source GNU
|
||||
// General Public License version 3 (or any later version), or alternatively,
|
||||
// under the terms of one of the closed source Quantum Leaps commercial
|
||||
// licenses.
|
||||
//
|
||||
// The terms of the open source GNU General Public License version 3
|
||||
// can be found at: <www.gnu.org/licenses/gpl-3.0>
|
||||
//
|
||||
// The terms of the closed source Quantum Leaps commercial licenses
|
||||
// can be found at: <www.state-machine.com/licensing>
|
||||
// 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:
|
||||
// <www.state-machine.com>
|
||||
// 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>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-06-06
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QS/C++ port to a 32-bit CPU, generic C++11 compiler
|
||||
|
||||
#ifndef QS_PORT_HPP_
|
||||
#define QS_PORT_HPP_
|
||||
|
||||
|
@ -9,7 +9,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.
|
||||
//
|
||||
@ -27,12 +27,6 @@
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-09-30
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QP/C++ port to MSP430, preemptive QK kernel
|
||||
|
||||
#ifndef QP_PORT_HPP_
|
||||
#define QP_PORT_HPP_
|
||||
|
||||
|
@ -1,38 +1,32 @@
|
||||
//============================================================================
|
||||
// QP/C++ Real-Time Embedded Framework (RTEF)
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// Q u a n t u m L e a P s
|
||||
// ------------------------
|
||||
// Modern Embedded Software
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
//
|
||||
// This software is dual-licensed under the terms of the open source GNU
|
||||
// General Public License version 3 (or any later version), or alternatively,
|
||||
// under the terms of one of the closed source Quantum Leaps commercial
|
||||
// licenses.
|
||||
//
|
||||
// The terms of the open source GNU General Public License version 3
|
||||
// can be found at: <www.gnu.org/licenses/gpl-3.0>
|
||||
//
|
||||
// The terms of the closed source Quantum Leaps commercial licenses
|
||||
// can be found at: <www.state-machine.com/licensing>
|
||||
// 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:
|
||||
// <www.state-machine.com>
|
||||
// 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>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-06-06
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QS/C++ port to a 16-bit CPU, generic C++11 compiler
|
||||
|
||||
#ifndef QS_PORT_HPP_
|
||||
#define QS_PORT_HPP_
|
||||
|
||||
|
@ -9,7 +9,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.
|
||||
//
|
||||
@ -27,12 +27,6 @@
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-09-30
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QP/C++ to MSP40, QUTEST unit test harness, generic C++11 compiler
|
||||
|
||||
#ifndef QP_PORT_HPP_
|
||||
#define QP_PORT_HPP_
|
||||
|
||||
@ -42,12 +36,8 @@
|
||||
// no-return function specifier (C++11 Standard)
|
||||
#define Q_NORETURN [[ noreturn ]] void
|
||||
|
||||
// QF configuration for QK -- data members of the QActive class...
|
||||
|
||||
// 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
|
||||
|
||||
// QF interrupt disable/enable
|
||||
#define QF_INT_DISABLE() (++QP::QF::intLock_)
|
||||
@ -74,33 +64,28 @@
|
||||
|
||||
//============================================================================
|
||||
// interface used only inside QF implementation, but not in applications
|
||||
|
||||
#ifdef QP_IMPL
|
||||
|
||||
// QUTest scheduler locking (not used)
|
||||
#define QF_SCHED_STAT_
|
||||
#define QF_SCHED_LOCK_(dummy) ((void)0)
|
||||
#define QF_SCHED_UNLOCK_() ((void)0)
|
||||
#define QF_SCHED_LOCK_(dummy) (static_cast<void>(0))
|
||||
#define QF_SCHED_UNLOCK_() (static_cast<void>(0))
|
||||
|
||||
// native event queue operations
|
||||
// native QEQueue operations
|
||||
#define QACTIVE_EQUEUE_WAIT_(me_) (static_cast<void>(0))
|
||||
#define QACTIVE_EQUEUE_SIGNAL_(me_) \
|
||||
(QP::QS::tstPriv_.readySet.insert( \
|
||||
static_cast<std::uint_fast8_t>((me_)->m_prio)))
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
#define QACTIVE_EQUEUE_SIGNAL_(me_) \
|
||||
QF::readySet_.insert(static_cast<std::uint_fast8_t>((me_)->m_prio));
|
||||
QF::readySet_.update_(&QF::readySet_dis)
|
||||
#else
|
||||
#define QACTIVE_EQUEUE_SIGNAL_(me_) \
|
||||
QF::readySet_.insert(static_cast<std::uint_fast8_t>((me_)->m_prio))
|
||||
#endif
|
||||
|
||||
// native QF event pool operations
|
||||
// native QMPool operations
|
||||
#define QF_EPOOL_TYPE_ QMPool
|
||||
#define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \
|
||||
(p_).init((poolSto_), (poolSize_), (evtSize_))
|
||||
#define QF_EPOOL_EVENT_SIZE_(p_) ((p_).getBlockSize())
|
||||
#define QF_EPOOL_GET_(p_, e_, m_, qsId_) \
|
||||
((e_) = static_cast<QEvt *>((p_).get((m_), (qsId_))))
|
||||
#define QF_EPOOL_PUT_(p_, e_, qsId_) ((p_).put((e_), (qsId_)))
|
||||
#define QF_EPOOL_PUT_(p_, e_, qsId_) ((p_).put((e_), (qsId_)))
|
||||
|
||||
#endif // QP_IMPL
|
||||
|
||||
|
@ -1,38 +1,32 @@
|
||||
//============================================================================
|
||||
// QP/C++ Real-Time Embedded Framework (RTEF)
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// Q u a n t u m L e a P s
|
||||
// ------------------------
|
||||
// Modern Embedded Software
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
//
|
||||
// This software is dual-licensed under the terms of the open source GNU
|
||||
// General Public License version 3 (or any later version), or alternatively,
|
||||
// under the terms of one of the closed source Quantum Leaps commercial
|
||||
// licenses.
|
||||
//
|
||||
// The terms of the open source GNU General Public License version 3
|
||||
// can be found at: <www.gnu.org/licenses/gpl-3.0>
|
||||
//
|
||||
// The terms of the closed source Quantum Leaps commercial licenses
|
||||
// can be found at: <www.state-machine.com/licensing>
|
||||
// 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:
|
||||
// <www.state-machine.com>
|
||||
// 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>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-06-06
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QS/C++ port to a 16-bit CPU, generic C++11 compiler
|
||||
|
||||
#ifndef QS_PORT_HPP_
|
||||
#define QS_PORT_HPP_
|
||||
|
||||
|
@ -9,7 +9,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.
|
||||
//
|
||||
@ -27,12 +27,6 @@
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-09-30
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QP/C++ port to MSP430, cooperative QV kernel
|
||||
|
||||
#ifndef QP_PORT_HPP_
|
||||
#define QP_PORT_HPP_
|
||||
|
||||
|
@ -1,38 +1,32 @@
|
||||
//============================================================================
|
||||
// QP/C++ Real-Time Embedded Framework (RTEF)
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// Q u a n t u m L e a P s
|
||||
// ------------------------
|
||||
// Modern Embedded Software
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
//
|
||||
// This software is dual-licensed under the terms of the open source GNU
|
||||
// General Public License version 3 (or any later version), or alternatively,
|
||||
// under the terms of one of the closed source Quantum Leaps commercial
|
||||
// licenses.
|
||||
//
|
||||
// The terms of the open source GNU General Public License version 3
|
||||
// can be found at: <www.gnu.org/licenses/gpl-3.0>
|
||||
//
|
||||
// The terms of the closed source Quantum Leaps commercial licenses
|
||||
// can be found at: <www.state-machine.com/licensing>
|
||||
// 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:
|
||||
// <www.state-machine.com>
|
||||
// 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>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-06-06
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QS/C++ port to a 16-bit CPU, generic C++11 compiler
|
||||
|
||||
#ifndef QS_PORT_HPP_
|
||||
#define QS_PORT_HPP_
|
||||
|
||||
|
@ -1,32 +1,32 @@
|
||||
//============================================================================
|
||||
// QP/C++ Real-Time Embedded Framework (RTEF)
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC <state-machine.com>.
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// This software is dual-licensed under the terms of the open source GNU
|
||||
// General Public License version 3 (or any later version), or alternatively,
|
||||
// under the terms of one of the closed source Quantum Leaps commercial
|
||||
// licenses.
|
||||
//
|
||||
// The terms of the open source GNU General Public License version 3
|
||||
// can be found at: <www.gnu.org/licenses/gpl-3.0>
|
||||
//
|
||||
// The terms of the closed source Quantum Leaps commercial licenses
|
||||
// can be found at: <www.state-machine.com/licensing>
|
||||
// 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 (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>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-09-19
|
||||
//! @version Last updated for: @ref qpcpp_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
|
||||
@ -188,9 +188,6 @@ void init() {
|
||||
pthread_cond_init(&condVar_, NULL);
|
||||
|
||||
readySet_.setEmpty();
|
||||
#ifndef Q_UNSAFE
|
||||
readySet_.update_(&readySet_dis_);
|
||||
#endif
|
||||
|
||||
// lock memory so we're never swapped out to disk
|
||||
//mlockall(MCL_CURRENT | MCL_FUTURE); // un-comment when supported
|
||||
@ -282,9 +279,6 @@ int run() {
|
||||
QF_CRIT_ENTRY();
|
||||
if (a->getEQueue().isEmpty()) { // empty queue?
|
||||
readySet_.remove(p);
|
||||
#ifndef Q_UNSAFE
|
||||
readySet_.update_(&readySet_dis_);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -318,9 +312,6 @@ void stop() {
|
||||
|
||||
// unblock the event-loop so it can terminate
|
||||
readySet_.insert(1U);
|
||||
#ifndef Q_UNSAFE
|
||||
readySet_.update_(&readySet_dis_);
|
||||
#endif
|
||||
pthread_cond_signal(&condVar_);
|
||||
}
|
||||
//............................................................................
|
||||
@ -406,9 +397,6 @@ void QActive::stop() {
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
QF::readySet_.remove(m_prio);
|
||||
#ifndef Q_UNSAFE
|
||||
QF::readySet_.update_(&QF::readySet_dis_);
|
||||
#endif
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
unregister_();
|
||||
|
@ -9,7 +9,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.
|
||||
//
|
||||
@ -27,12 +27,6 @@
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-09-30
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QP/C++ port to POSIX-QV (signgle threaded), generic C++11
|
||||
|
||||
#ifndef QP_PORT_HPP_
|
||||
#define QP_PORT_HPP_
|
||||
|
||||
@ -97,16 +91,9 @@ void onClockTick();
|
||||
// QF event queue customization for POSIX-QV...
|
||||
#define QACTIVE_EQUEUE_WAIT_(me_) (static_cast<void>(0))
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
#define QACTIVE_EQUEUE_SIGNAL_(me_) \
|
||||
QF::readySet_.insert((me_)->m_prio); \
|
||||
QF::readySet_.update_(&QF::readySet_dis_); \
|
||||
pthread_cond_signal(&QP::QF::condVar_)
|
||||
#else
|
||||
#define QACTIVE_EQUEUE_SIGNAL_(me_) \
|
||||
QF::readySet_.insert((me_)->m_prio); \
|
||||
pthread_cond_signal(&QP::QF::condVar_)
|
||||
#endif
|
||||
|
||||
// native QF event pool operations
|
||||
#define QF_EPOOL_TYPE_ QMPool
|
||||
|
@ -1,38 +1,38 @@
|
||||
//============================================================================
|
||||
// QP/C++ Real-Time Embedded Framework (RTEF)
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// This software is dual-licensed under the terms of the open source GNU
|
||||
// General Public License version 3 (or any later version), or alternatively,
|
||||
// under the terms of one of the closed source Quantum Leaps commercial
|
||||
// licenses.
|
||||
//
|
||||
// The terms of the open source GNU General Public License version 3
|
||||
// can be found at: <www.gnu.org/licenses/gpl-3.0>
|
||||
//
|
||||
// The terms of the closed source Quantum Leaps commercial licenses
|
||||
// can be found at: <www.state-machine.com/licensing>
|
||||
// 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:
|
||||
// <www.state-machine.com>
|
||||
// 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>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-07-18
|
||||
//! @version Last updated for: @ref qpcpp_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.cpp"
|
||||
#error Q_SPY must be defined to compile qs_port.cpp
|
||||
#endif // Q_SPY
|
||||
|
||||
#define QP_IMPL // this is QP implementation
|
||||
|
@ -1,38 +1,32 @@
|
||||
//============================================================================
|
||||
// QP/C++ Real-Time Embedded Framework (RTEF)
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// Q u a n t u m L e a P s
|
||||
// ------------------------
|
||||
// Modern Embedded Software
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
//
|
||||
// This software is dual-licensed under the terms of the open source GNU
|
||||
// General Public License version 3 (or any later version), or alternatively,
|
||||
// under the terms of one of the closed source Quantum Leaps commercial
|
||||
// licenses.
|
||||
//
|
||||
// The terms of the open source GNU General Public License version 3
|
||||
// can be found at: <www.gnu.org/licenses/gpl-3.0>
|
||||
//
|
||||
// The terms of the closed source Quantum Leaps commercial licenses
|
||||
// can be found at: <www.state-machine.com/licensing>
|
||||
// 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:
|
||||
// <www.state-machine.com>
|
||||
// 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>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-06-06
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QS/C++ port to POSIX/Win32
|
||||
|
||||
#ifndef QS_PORT_HPP_
|
||||
#define QS_PORT_HPP_
|
||||
|
||||
|
@ -1,32 +1,32 @@
|
||||
//============================================================================
|
||||
// QP/C++ Real-Time Embedded Framework (RTEF)
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC <state-machine.com>.
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// This software is dual-licensed under the terms of the open source GNU
|
||||
// General Public License version 3 (or any later version), or alternatively,
|
||||
// under the terms of one of the closed source Quantum Leaps commercial
|
||||
// licenses.
|
||||
//
|
||||
// The terms of the open source GNU General Public License version 3
|
||||
// can be found at: <www.gnu.org/licenses/gpl-3.0>
|
||||
//
|
||||
// The terms of the closed source Quantum Leaps commercial licenses
|
||||
// can be found at: <www.state-machine.com/licensing>
|
||||
// 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 (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>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-09-19
|
||||
//! @version Last updated for: @ref qpcpp_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
|
||||
|
@ -9,7 +9,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.
|
||||
//
|
||||
@ -27,12 +27,6 @@
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-09-30
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QP/C++ port to POSIX (multithreaded with P-threads), generic C++11
|
||||
|
||||
#ifndef QP_PORT_HPP_
|
||||
#define QP_PORT_HPP_
|
||||
|
||||
|
@ -1,38 +1,38 @@
|
||||
//============================================================================
|
||||
// QP/C++ Real-Time Embedded Framework (RTEF)
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// This software is dual-licensed under the terms of the open source GNU
|
||||
// General Public License version 3 (or any later version), or alternatively,
|
||||
// under the terms of one of the closed source Quantum Leaps commercial
|
||||
// licenses.
|
||||
//
|
||||
// The terms of the open source GNU General Public License version 3
|
||||
// can be found at: <www.gnu.org/licenses/gpl-3.0>
|
||||
//
|
||||
// The terms of the closed source Quantum Leaps commercial licenses
|
||||
// can be found at: <www.state-machine.com/licensing>
|
||||
// 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:
|
||||
// <www.state-machine.com>
|
||||
// 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>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-07-18
|
||||
//! @version Last updated for: @ref qpcpp_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.cpp"
|
||||
#error Q_SPY must be defined to compile qs_port.cpp
|
||||
#endif // Q_SPY
|
||||
|
||||
#define QP_IMPL // this is QP implementation
|
||||
|
@ -1,38 +1,32 @@
|
||||
//============================================================================
|
||||
// QP/C++ Real-Time Embedded Framework (RTEF)
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// Q u a n t u m L e a P s
|
||||
// ------------------------
|
||||
// Modern Embedded Software
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
|
||||
//
|
||||
// This software is dual-licensed under the terms of the open source GNU
|
||||
// General Public License version 3 (or any later version), or alternatively,
|
||||
// under the terms of one of the closed source Quantum Leaps commercial
|
||||
// licenses.
|
||||
//
|
||||
// The terms of the open source GNU General Public License version 3
|
||||
// can be found at: <www.gnu.org/licenses/gpl-3.0>
|
||||
//
|
||||
// The terms of the closed source Quantum Leaps commercial licenses
|
||||
// can be found at: <www.state-machine.com/licensing>
|
||||
// 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:
|
||||
// <www.state-machine.com>
|
||||
// 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>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-06-06
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QS/C++ port to POSIX/Win32
|
||||
|
||||
#ifndef QS_PORT_HPP_
|
||||
#define QS_PORT_HPP_
|
||||
|
||||
|
@ -9,7 +9,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.
|
||||
//
|
||||
@ -27,12 +27,6 @@
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-09-30
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QP/C dummy port
|
||||
|
||||
#ifndef QP_PORT_HPP_
|
||||
#define QP_PORT_HPP_
|
||||
|
||||
|
@ -7,7 +7,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.
|
||||
//
|
||||
@ -25,12 +25,6 @@
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-09-26
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QF/C++ port to ThreadX (a.k.a. Azure RTOS), generic C++11 compiler
|
||||
|
||||
#define QP_IMPL // this is QP implementation
|
||||
#include "qp_port.hpp" // QP port
|
||||
#include "qp_pkg.hpp" // QP package-scope interface
|
||||
@ -165,9 +159,6 @@ bool QActive::post_(QEvt const * const e, std::uint_fast16_t const margin,
|
||||
QF_CRIT_ENTRY();
|
||||
|
||||
Q_REQUIRE_INCRIT(200, e != nullptr);
|
||||
#ifndef Q_UNSAFE
|
||||
Q_INVARIANT_INCRIT(201, e->verify_());
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
std::uint_fast16_t nFree =
|
||||
static_cast<std::uint_fast16_t>(m_eQueue.tx_queue_available_storage);
|
||||
@ -196,12 +187,13 @@ bool QActive::post_(QEvt const * const e, std::uint_fast16_t const margin,
|
||||
QS_OBJ_PRE(sender); // the sender object
|
||||
QS_SIG_PRE(e->sig); // the signal of the event
|
||||
QS_OBJ_PRE(this); // this active object (recipient)
|
||||
QS_2U8_PRE(e->getPoolNum_(), 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 (e->getPoolNum_() != 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();
|
||||
@ -220,7 +212,7 @@ bool QActive::post_(QEvt const * const e, std::uint_fast16_t const margin,
|
||||
QS_OBJ_PRE(sender); // the sender object
|
||||
QS_SIG_PRE(e->sig); // the signal of the event
|
||||
QS_OBJ_PRE(this); // this active object (recipient)
|
||||
QS_2U8_PRE(e->getPoolNum_(), 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()
|
||||
@ -236,21 +228,18 @@ void QActive::postLIFO(QEvt const * const e) noexcept {
|
||||
QF_CRIT_ENTRY();
|
||||
|
||||
Q_REQUIRE_INCRIT(300, e != nullptr);
|
||||
#ifndef Q_UNSAFE
|
||||
Q_INVARIANT_INCRIT(301, e->verify_());
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
|
||||
QS_BEGIN_PRE(QS_QF_ACTIVE_POST_LIFO, m_prio)
|
||||
QS_TIME_PRE(); // timestamp
|
||||
QS_SIG_PRE(e->sig); // the signal of this event
|
||||
QS_OBJ_PRE(this); // this active object
|
||||
QS_2U8_PRE(e->getPoolNum_(), e->refCtr_);
|
||||
QS_2U8_PRE(e->poolNum_, e->refCtr_);
|
||||
QS_EQC_PRE(m_eQueue.tx_queue_available_storage); // # free
|
||||
QS_EQC_PRE(0U); // min # free entries (unknown)
|
||||
QS_END_PRE()
|
||||
|
||||
if (e->getPoolNum_() != 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();
|
||||
@ -276,7 +265,7 @@ QEvt const *QActive::get_(void) noexcept {
|
||||
QS_TIME_PRE(); // timestamp
|
||||
QS_SIG_PRE(e->sig); // the signal of this event
|
||||
QS_OBJ_PRE(this); // this active object
|
||||
QS_2U8_PRE(e->getPoolNum_(), e->refCtr_);
|
||||
QS_2U8_PRE(e->poolNum_, e->refCtr_);
|
||||
QS_EQC_PRE(m_eQueue.tx_queue_available_storage); // # free
|
||||
QS_END_PRE()
|
||||
QF_CRIT_EXIT();
|
||||
|
@ -1,15 +1,13 @@
|
||||
//============================================================================
|
||||
// QP/C++ Real-Time Embedded Framework (RTEF)
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
@ -27,12 +25,6 @@
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-09-30
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QP/C++ port to ThreadX (a.k.a, Azure RTOS), generic C++11 compiler
|
||||
|
||||
#ifndef QP_PORT_HPP_
|
||||
#define QP_PORT_HPP_
|
||||
|
||||
@ -51,9 +43,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
|
||||
|
@ -1,38 +1,30 @@
|
||||
//============================================================================
|
||||
// QP/C++ Real-Time Embedded Framework (RTEF)
|
||||
//
|
||||
// Q u a n t u m L e a P s
|
||||
// ------------------------
|
||||
// Modern Embedded Software
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// This software is dual-licensed under the terms of the open source GNU
|
||||
// General Public License version 3 (or any later version), or alternatively,
|
||||
// under the terms of one of the closed source Quantum Leaps commercial
|
||||
// licenses.
|
||||
//
|
||||
// The terms of the open source GNU General Public License version 3
|
||||
// can be found at: <www.gnu.org/licenses/gpl-3.0>
|
||||
//
|
||||
// The terms of the closed source Quantum Leaps commercial licenses
|
||||
// can be found at: <www.state-machine.com/licensing>
|
||||
// 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:
|
||||
// <www.state-machine.com>
|
||||
// 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>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-06-06
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QS/C++ port to a 32-bit CPU, generic C++11 compiler
|
||||
|
||||
#ifndef QS_PORT_HPP_
|
||||
#define QS_PORT_HPP_
|
||||
|
||||
|
@ -7,7 +7,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.
|
||||
//
|
||||
@ -25,12 +25,6 @@
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-09-26
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QF/C++ port to uC-OS2 RTOS, generic C++11 compiler
|
||||
|
||||
#define QP_IMPL // this is QP implementation
|
||||
#include "qp_port.hpp" // QP port
|
||||
#include "qp_pkg.hpp" // QP package-scope interface
|
||||
@ -207,9 +201,6 @@ bool QActive::post_(QEvt const * const e, std::uint_fast16_t const margin,
|
||||
QF_CRIT_ENTRY();
|
||||
|
||||
Q_REQUIRE_INCRIT(200, e != nullptr);
|
||||
#ifndef Q_UNSAFE
|
||||
Q_INVARIANT_INCRIT(201, e->verify_());
|
||||
#endif
|
||||
|
||||
std::uint_fast16_t const nFree = static_cast<std::uint_fast16_t>(
|
||||
reinterpret_cast<OS_Q_DATA *>(m_eQueue)->OSQSize
|
||||
@ -239,12 +230,13 @@ bool QActive::post_(QEvt const * const e, std::uint_fast16_t const margin,
|
||||
QS_OBJ_PRE(sender); // the sender object
|
||||
QS_SIG_PRE(e->sig); // the signal of the event
|
||||
QS_OBJ_PRE(this); // this active object (recipient)
|
||||
QS_2U8_PRE(e->getPoolNum_(), 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 (e->getPoolNum_() != 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();
|
||||
@ -267,7 +259,7 @@ bool QActive::post_(QEvt const * const e, std::uint_fast16_t const margin,
|
||||
QS_OBJ_PRE(sender); // the sender object
|
||||
QS_SIG_PRE(e->sig); // the signal of the event
|
||||
QS_OBJ_PRE(this); // this active object (recipient)
|
||||
QS_2U8_PRE(e->getPoolNum_(), 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()
|
||||
@ -283,22 +275,20 @@ void QActive::postLIFO(QEvt const * const e) noexcept {
|
||||
QF_CRIT_ENTRY();
|
||||
|
||||
Q_REQUIRE_INCRIT(300, e != nullptr);
|
||||
#ifndef Q_UNSAFE
|
||||
Q_INVARIANT_INCRIT(301, e->verify_());
|
||||
#endif
|
||||
|
||||
QS_BEGIN_PRE(QS_QF_ACTIVE_POST_LIFO, m_prio)
|
||||
QS_TIME_PRE(); // timestamp
|
||||
QS_SIG_PRE(e->sig); // the signal of this event
|
||||
QS_OBJ_PRE(this); // this active object
|
||||
QS_2U8_PRE(e->getPoolNum_(), e->refCtr_);
|
||||
QS_2U8_PRE(e->poolNum_, e->refCtr_);
|
||||
// # free entries
|
||||
QS_EQC_PRE(reinterpret_cast<OS_Q *>(m_eQueue)->OSQSize
|
||||
- reinterpret_cast<OS_Q *>(m_eQueue)->OSQEntries);
|
||||
QS_EQC_PRE(0U); // min # free entries (unknown)
|
||||
QS_END_PRE()
|
||||
|
||||
if (e->getPoolNum_() != 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();
|
||||
@ -328,7 +318,7 @@ QEvt const *QActive::get_(void) noexcept {
|
||||
QS_TIME_PRE(); // timestamp
|
||||
QS_SIG_PRE(e->sig); // the signal of this event
|
||||
QS_OBJ_PRE(this); // this active object
|
||||
QS_2U8_PRE(e->getPoolNum_(), e->refCtr_);
|
||||
QS_2U8_PRE(e->poolNum_, e->refCtr_);
|
||||
// # free entries
|
||||
QS_EQC_PRE(reinterpret_cast<OS_Q *>(m_eQueue)->OSQSize
|
||||
- reinterpret_cast<OS_Q *>(m_eQueue)->OSQEntries);
|
||||
|
@ -9,7 +9,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.
|
||||
//
|
||||
@ -27,12 +27,6 @@
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-09-30
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QP/C++ port to uC-OS2 RTOS, generic C++11 compiler
|
||||
|
||||
#ifndef QP_PORT_HPP_
|
||||
#define QP_PORT_HPP_
|
||||
|
||||
|
@ -1,38 +1,30 @@
|
||||
//============================================================================
|
||||
// QP/C++ Real-Time Embedded Framework (RTEF)
|
||||
//
|
||||
// Q u a n t u m L e a P s
|
||||
// ------------------------
|
||||
// Modern Embedded Software
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// This software is dual-licensed under the terms of the open source GNU
|
||||
// General Public License version 3 (or any later version), or alternatively,
|
||||
// under the terms of one of the closed source Quantum Leaps commercial
|
||||
// licenses.
|
||||
//
|
||||
// The terms of the open source GNU General Public License version 3
|
||||
// can be found at: <www.gnu.org/licenses/gpl-3.0>
|
||||
//
|
||||
// The terms of the closed source Quantum Leaps commercial licenses
|
||||
// can be found at: <www.state-machine.com/licensing>
|
||||
// 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:
|
||||
// <www.state-machine.com>
|
||||
// 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>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-06-06
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QS/C++ port to a 32-bit CPU, generic C++11 compiler
|
||||
|
||||
#ifndef QS_PORT_HPP_
|
||||
#define QS_PORT_HPP_
|
||||
|
||||
|
@ -22,12 +22,6 @@
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-09-19
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QF/C++ port to Win32 (single-threaded, like the QV kernel)
|
||||
|
||||
#define QP_IMPL // this is QP implementation
|
||||
#include "qp_port.hpp" // QP port
|
||||
#include "qp_pkg.hpp" // QP package-scope interface
|
||||
@ -114,10 +108,6 @@ void init() {
|
||||
win32Event_ = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
|
||||
readySet_.setEmpty();
|
||||
#ifndef Q_UNSAFE
|
||||
readySet_.update_(&readySet_dis_);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
//............................................................................
|
||||
@ -149,8 +139,6 @@ int run() {
|
||||
QS_END_PRE()
|
||||
|
||||
while (l_isRunning) {
|
||||
Q_ASSERT_INCRIT(300, readySet_.verify_(&readySet_dis_));
|
||||
|
||||
// find the maximum priority AO ready to run
|
||||
if (readySet_.notEmpty()) {
|
||||
std::uint_fast8_t p = readySet_.findMax();
|
||||
@ -169,9 +157,6 @@ int run() {
|
||||
QF_CRIT_ENTRY();
|
||||
if (a->getEQueue().isEmpty()) { // empty queue?
|
||||
readySet_.remove(p);
|
||||
#ifndef Q_UNSAFE
|
||||
readySet_.update_(&readySet_dis_);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -200,9 +185,6 @@ void stop() {
|
||||
|
||||
// unblock the event-loop so it can terminate
|
||||
readySet_.insert(1U);
|
||||
#ifndef Q_UNSAFE
|
||||
readySet_.update_(&readySet_dis_);
|
||||
#endif
|
||||
SetEvent(win32Event_);
|
||||
}
|
||||
//............................................................................
|
||||
@ -272,9 +254,6 @@ void QActive::stop() {
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
QF::readySet_.remove(m_prio);
|
||||
#ifndef Q_UNSAFE
|
||||
QF::readySet_.update_(&QF::readySet_dis_);
|
||||
#endif
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
unregister_(); // remove this AO from QF
|
||||
|
@ -9,7 +9,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.
|
||||
//
|
||||
@ -27,12 +27,6 @@
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-09-30
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QP/C++ port to Win32-QV (single-threaded), generic C++11
|
||||
|
||||
#ifndef QP_PORT_HPP_
|
||||
#define QP_PORT_HPP_
|
||||
|
||||
@ -104,16 +98,9 @@ void onClockTick();
|
||||
// QF event queue customization for Win32-QV...
|
||||
#define QACTIVE_EQUEUE_WAIT_(me_) (static_cast<void>(0))
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
#define QACTIVE_EQUEUE_SIGNAL_(me_) \
|
||||
QF::readySet_.insert((me_)->m_prio); \
|
||||
QF::readySet_.update_(&QF::readySet_dis_); \
|
||||
static_cast<void>(SetEvent(QP::QF::win32Event_))
|
||||
#else
|
||||
#define QACTIVE_EQUEUE_SIGNAL_(me_) \
|
||||
QF::readySet_.insert((me_)->m_prio); \
|
||||
static_cast<void>(SetEvent(QP::QF::win32Event_))
|
||||
#endif
|
||||
|
||||
// native QF event pool operations
|
||||
#define QF_EPOOL_TYPE_ QMPool
|
||||
|
@ -22,15 +22,8 @@
|
||||
// <www.state-machine.com>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-06-11
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QS/C++ port to Win32 API
|
||||
//!
|
||||
|
||||
#ifndef Q_SPY
|
||||
#error "Q_SPY must be defined to compile qs_port.cpp"
|
||||
#error Q_SPY must be defined to compile qs_port.cpp
|
||||
#endif // Q_SPY
|
||||
|
||||
#define QP_IMPL // this is QP implementation
|
||||
|
@ -27,12 +27,6 @@
|
||||
// <www.state-machine.com>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-06-06
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QS/C++ port to POSIX/Win32
|
||||
|
||||
#ifndef QS_PORT_HPP_
|
||||
#define QS_PORT_HPP_
|
||||
|
||||
|
@ -22,12 +22,6 @@
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-09-19
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QF/C++ port to Win32 (multithreaded)
|
||||
|
||||
#define QP_IMPL // this is QP implementation
|
||||
#include "qp_port.hpp" // QP port
|
||||
#include "qp_pkg.hpp" // QP package-scope interface
|
||||
|
@ -9,7 +9,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.
|
||||
//
|
||||
@ -27,12 +27,6 @@
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-09-30
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QP/C++ port to Win32 (multithreaded), generic C++11
|
||||
|
||||
#ifndef QP_PORT_HPP_
|
||||
#define QP_PORT_HPP_
|
||||
|
||||
@ -104,7 +98,8 @@ void onClockTick();
|
||||
#define QACTIVE_EQUEUE_WAIT_(me_) \
|
||||
while ((me_)->m_eQueue.m_frontEvt == nullptr) { \
|
||||
QF_CRIT_EXIT(); \
|
||||
static_cast<void>(WaitForSingleObject((me_)->m_osObject, INFINITE)); \
|
||||
static_cast<void>(WaitForSingleObject( \
|
||||
(me_)->m_osObject, INFINITE)); \
|
||||
QF_CRIT_ENTRY(); \
|
||||
}
|
||||
|
||||
|
@ -22,15 +22,8 @@
|
||||
// <www.state-machine.com>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-06-11
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QS/C++ port to Win32 API
|
||||
//!
|
||||
|
||||
#ifndef Q_SPY
|
||||
#error "Q_SPY must be defined to compile qs_port.cpp"
|
||||
#error Q_SPY must be defined to compile qs_port.cpp
|
||||
#endif // Q_SPY
|
||||
|
||||
#define QP_IMPL // this is QP implementation
|
||||
|
@ -27,12 +27,6 @@
|
||||
// <www.state-machine.com>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2024-06-06
|
||||
//! @version Last updated for: @ref qpcpp_8_0_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QS/C++ port to POSIX/Win32
|
||||
|
||||
#ifndef QS_PORT_HPP_
|
||||
#define QS_PORT_HPP_
|
||||
|
||||
|
162
qpcpp_8.0.1.sha1
162
qpcpp_8.0.1.sha1
@ -1,162 +0,0 @@
|
||||
bda783a346fb750c7a1fe32dc0a8ca52609cb5f4 *qpcpp.qm
|
||||
46578fc304c597329289978acee1027c8c533335 *include/qequeue.hpp
|
||||
1a8e0b05536b89c1cd3806782ae1a21dd4ceca69 *include/qk.hpp
|
||||
cb1c39aabacb619060924356f7c8e900686538e0 *include/qmpool.hpp
|
||||
559a9ca895f97f38c5d3bb0511675f321e041911 *include/qp.hpp
|
||||
bf47a939e525fa575673f89b8106bcee166240a2 *include/qp_pkg.hpp
|
||||
e5b0d14c9e6994b82a5cd9200bde46bd179bfb20 *include/qpcpp.hpp
|
||||
d4f14d2ed18ef725ea17d0a97b78ae22a283c96b *include/qs.hpp
|
||||
88220a7d892fee54053b467b596dc6b536aaf8be *include/qs_dummy.hpp
|
||||
9694f10e44d53563599410d37dd1c5a19cf1788b *include/qs_pkg.hpp
|
||||
49d2620b0afa9e74d73680495c3e8a931e5d8f73 *include/qsafe.h
|
||||
09e9ffe95120ba17a49d7039b5316f2614710dab *include/qstamp.hpp
|
||||
73749ed396bbc0419971769a47069448c8136960 *include/qv.hpp
|
||||
05b617dad20f07f07b64dccf84f9b7cd9b8d2bb7 *include/qxk.hpp
|
||||
0199f3eeb6c02b8cc890ee4c6f6d344569a0858f *include/README.md
|
||||
71899ce74eeb04f333ed00d53f87719f722a39ab *src/qf/CMakeLists.txt
|
||||
864d627f2600987a2194c57093e1f210e0de2a7a *src/qf/qep_hsm.cpp
|
||||
d3242def2b23df5b9704bb3b0411fd01de6c0a67 *src/qf/qep_msm.cpp
|
||||
62f87a60d04e1c98f40162a166ec14a1f2f1252f *src/qf/qf_act.cpp
|
||||
07671fb85e9b2492b0ea37b853d7e0eea42bf637 *src/qf/qf_actq.cpp
|
||||
ed83f5f8b3533cc97ffc2a85aeeb63f29b4f1dd8 *src/qf/qf_defer.cpp
|
||||
f41d8815460d26f5bbf89e40dcb607b6a3ddeaa8 *src/qf/qf_dyn.cpp
|
||||
974493184d40e0a2f698c6e63e0bc450343ef591 *src/qf/qf_mem.cpp
|
||||
ef51e4840107b0ed6ec97e170ac2689e1b1fdb95 *src/qf/qf_ps.cpp
|
||||
08b490d7505a7ff6fe493058975eb9f0a82daa3d *src/qf/qf_qact.cpp
|
||||
23892cde4fd7226e899026884e07b01e32d0aef4 *src/qf/qf_qeq.cpp
|
||||
5fc4874b74779641454e2d8e7960a5bf3d130115 *src/qf/qf_qmact.cpp
|
||||
04dd9fbddc336f096bd214f8e7368d7a6dce43c8 *src/qf/qf_time.cpp
|
||||
7cdab433e81612862fd27f0cf792d38e1197d064 *src/qk/CMakeLists.txt
|
||||
1be4743dc14186779abb96b4bd16ba9a99d3314d *src/qk/qk.cpp
|
||||
eb28260d471fc752ca54b2c1e2d763f28432c2c1 *src/qs/CMakeLists.txt
|
||||
66fd2a553c8ae6709dfe286b6ccce002208251f1 *src/qs/qs.cpp
|
||||
2ca73a0d38dd7b544864d72fd337f29c7dae2a85 *src/qs/qs_64bit.cpp
|
||||
349c18625bd2cceda297e1c98a85a9fa9538cef9 *src/qs/qs_fp.cpp
|
||||
ad4e3a9faacc038cb51a7773ffc42903be947a22 *src/qs/qs_rx.cpp
|
||||
8008d9c24757b2bb02e85123aa89a3a33090921d *src/qs/qstamp.cpp
|
||||
92338453dc612419b0e16e0560e761312d0f3900 *src/qs/qutest.cpp
|
||||
b6d93a16f5b176d3da4888a7efb265730337f46d *src/qv/CMakeLists.txt
|
||||
f530563e062ff7ea84763f6e799bf4ca1cb73054 *src/qv/qv.cpp
|
||||
2d0c3d3d93e4d4ac8e2218b9ed68e6269b02419e *src/qxk/qxk.cpp
|
||||
e0e633a980e4c04a85f877e810ce77ad51903e87 *src/qxk/qxk_mutex.cpp
|
||||
8e15812d14f250866dfa8a96fe5b14638ca2c4ae *src/qxk/qxk_sema.cpp
|
||||
58e6a9354a1c7c4d53204b7ad2fad05d6eb3117c *src/qxk/qxk_xthr.cpp
|
||||
81f1a6dbcebd0b5df9e437902ffbe0fecdd03d25 *ports/arm-cm/qk/armclang/qk_port.cpp
|
||||
7119fc94c0b5560ab8e3197a83917667e311e415 *ports/arm-cm/qk/armclang/qp_port.hpp
|
||||
5597ed8e115824f146a12f18c8142371bfa1852a *ports/arm-cm/qk/armclang/qs_port.hpp
|
||||
5f2353117f9940b0ea891d2e0bd486e0d024b67c *ports/arm-cm/qk/gnu/qk_port.cpp
|
||||
7119fc94c0b5560ab8e3197a83917667e311e415 *ports/arm-cm/qk/gnu/qp_port.hpp
|
||||
5597ed8e115824f146a12f18c8142371bfa1852a *ports/arm-cm/qk/gnu/qs_port.hpp
|
||||
2b9c1112e3e5be79ce2b1799adfd5e812467765b *ports/arm-cm/qk/iar/qk_port.cpp
|
||||
f54416674c33ffd19408f02af60f7d69b8613797 *ports/arm-cm/qk/iar/qp_port.hpp
|
||||
5597ed8e115824f146a12f18c8142371bfa1852a *ports/arm-cm/qk/iar/qs_port.hpp
|
||||
9cc71aed12d57408252019035aff449ce028372c *ports/arm-cm/qv/armclang/qp_port.hpp
|
||||
5597ed8e115824f146a12f18c8142371bfa1852a *ports/arm-cm/qv/armclang/qs_port.hpp
|
||||
90b14adcd8f8b29de3358073c39bd4161f5ce2eb *ports/arm-cm/qv/armclang/qv_port.cpp
|
||||
bed3687b29555f6fa9c721cf34a098218f64e1ad *ports/arm-cm/qv/gnu/qp_port.hpp
|
||||
5597ed8e115824f146a12f18c8142371bfa1852a *ports/arm-cm/qv/gnu/qs_port.hpp
|
||||
b2d5e72b65813bdc37bcab3c8cd9107bda009131 *ports/arm-cm/qv/gnu/qv_port.cpp
|
||||
424864680661227e4ab418b2af905d4bd92767ad *ports/arm-cm/qv/iar/qp_port.hpp
|
||||
5597ed8e115824f146a12f18c8142371bfa1852a *ports/arm-cm/qv/iar/qs_port.hpp
|
||||
15fb0660dff33295bad38facfc7aacca928133a3 *ports/arm-cm/qv/iar/qv_port.cpp
|
||||
9e248cb426d8495e5cd677ff79cd3b9ced2a76a5 *ports/arm-cm/qxk/armclang/qp_port.hpp
|
||||
5597ed8e115824f146a12f18c8142371bfa1852a *ports/arm-cm/qxk/armclang/qs_port.hpp
|
||||
16423aebab91be16d8c2c7b128d8494709a6a746 *ports/arm-cm/qxk/armclang/qxk_port.cpp
|
||||
9ec8ed9717f9130b23252d2c381f779617165932 *ports/arm-cm/qxk/gnu/qp_port.hpp
|
||||
5597ed8e115824f146a12f18c8142371bfa1852a *ports/arm-cm/qxk/gnu/qs_port.hpp
|
||||
75fc7a6c1b0775832f3e0e0e2bbacc19f56ddc94 *ports/arm-cm/qxk/gnu/qxk_port.cpp
|
||||
f40b0ea4761d187ac7d4460a161efb9b4f3e6ef6 *ports/arm-cm/qxk/iar/qp_port.hpp
|
||||
5597ed8e115824f146a12f18c8142371bfa1852a *ports/arm-cm/qxk/iar/qs_port.hpp
|
||||
44509ff079ba173a28076f3fa1488582a6ef48a1 *ports/arm-cm/qxk/iar/qxk_port.cpp
|
||||
69256fd1a5b81db3e3174cba9196bf9da925e098 *ports/arm-cm/qutest/qp_port.hpp
|
||||
5597ed8e115824f146a12f18c8142371bfa1852a *ports/arm-cm/qutest/qs_port.hpp
|
||||
1194c26fdfc9665a04cc3d01e6de49afe1698376 *ports/arm-cr/qk/gnu/qp_port.hpp
|
||||
5597ed8e115824f146a12f18c8142371bfa1852a *ports/arm-cr/qk/gnu/qs_port.hpp
|
||||
a8f4351725564e449206909176d09bc58cd6f45d *ports/arm-cr/qk/iar/qp_port.hpp
|
||||
5597ed8e115824f146a12f18c8142371bfa1852a *ports/arm-cr/qk/iar/qs_port.hpp
|
||||
7203200deaa5dbb4746434d4a3d79a160d4ccf4b *ports/arm-cr/qk/ti/qp_port.hpp
|
||||
5597ed8e115824f146a12f18c8142371bfa1852a *ports/arm-cr/qk/ti/qs_port.hpp
|
||||
fd3e4b882efb671f2522ae83bfde016ea416d4a7 *ports/arm-cr/qv/gnu/qp_port.hpp
|
||||
5597ed8e115824f146a12f18c8142371bfa1852a *ports/arm-cr/qv/gnu/qs_port.hpp
|
||||
fafbe56ae4266a412cb1b6db6e146fbfe5022b4a *ports/arm-cr/qv/iar/qp_port.hpp
|
||||
5597ed8e115824f146a12f18c8142371bfa1852a *ports/arm-cr/qv/iar/qs_port.hpp
|
||||
78d39f7479a0ea046e77607740e4211d9e4cb60f *ports/arm-cr/qv/ti/qp_port.hpp
|
||||
5597ed8e115824f146a12f18c8142371bfa1852a *ports/arm-cr/qv/ti/qs_port.hpp
|
||||
bc080e68d0edfc28da2df882ed3661cf99f2942c *ports/msp430/qk/qp_port.hpp
|
||||
197ec45394793b79a29afe5bb31b6de1ad78ad00 *ports/msp430/qk/qs_port.hpp
|
||||
7b2654746a747c427b5ee1dd7f8b4b82c372a040 *ports/msp430/qv/qp_port.hpp
|
||||
197ec45394793b79a29afe5bb31b6de1ad78ad00 *ports/msp430/qv/qs_port.hpp
|
||||
650f628d87a39c559a87c6f849c58fb9a8e777a7 *ports/msp430/qutest/qp_port.hpp
|
||||
197ec45394793b79a29afe5bb31b6de1ad78ad00 *ports/msp430/qutest/qs_port.hpp
|
||||
8614593b911e6db6f634d972e79093e964756556 *ports/config/qp_config.hpp
|
||||
b6b5d23c618976a6fbed51dc5a13e227928e1d4b *ports/embos/CMakeLists.txt
|
||||
0b5ad806f47800c1481c9af3d88c1bff3cb1d784 *ports/embos/qf_port.cpp
|
||||
5e28aa0e89239f970e4b5e85be4e5c3b6a34dd69 *ports/embos/qp_port.hpp
|
||||
5597ed8e115824f146a12f18c8142371bfa1852a *ports/embos/qs_port.hpp
|
||||
e4f00894f86806af6d88d38e831a8fc0ad36059e *ports/freertos/CMakeLists.txt
|
||||
699baf504d4d3df68b0e66196c48516490e795be *ports/freertos/qf_port.cpp
|
||||
c7efbc2cc8425c0e21d5bd892584b3e2ff7a145b *ports/freertos/qp_port.hpp
|
||||
5597ed8e115824f146a12f18c8142371bfa1852a *ports/freertos/qs_port.hpp
|
||||
18df978f665338c757f1a2a284c2acc779bd59d3 *ports/threadx/CMakeLists.txt
|
||||
90717daaf983e8425a9939d17f732ce3d4646bb4 *ports/threadx/qf_port.cpp
|
||||
f0d61f6806b0207e56dd75f8aaac55c4b1393996 *ports/threadx/qp_port.hpp
|
||||
5597ed8e115824f146a12f18c8142371bfa1852a *ports/threadx/qs_port.hpp
|
||||
46699d3c8ad92f9c98ea5e03e72d4190a7794aa4 *ports/threadx/README.md
|
||||
0ab8b95f50fa767b951c6f56efe86789623b7127 *ports/uc-os2/CMakeLists.txt
|
||||
3624f6191213536a8be528185d97d1e35b1fa369 *ports/uc-os2/qf_port.cpp
|
||||
528d3c2c337c639f3879d24da74369facea0bca6 *ports/uc-os2/qp_port.hpp
|
||||
5597ed8e115824f146a12f18c8142371bfa1852a *ports/uc-os2/qs_port.hpp
|
||||
227dedab24f1e20440103a0cabc210b4b5adedef *ports/qep-only/CMakeLists.txt
|
||||
6d75bdbb41cd68d2fcab63d0eb8ff91f96f52c24 *ports/qep-only/qp_port.hpp
|
||||
7235457eb9529f9fe2459ce869e63294ec5c5df6 *ports/qep-only/safe_std.h
|
||||
12255313ebcf963d29d91bee4c917bb6ab2f9e1d *ports/posix/CMakeLists.txt
|
||||
9119c0c12ecc34d41cba8da898496c1f99ea47ac *ports/posix/qf_port.cpp
|
||||
56956443bf38d12075ce2ddc53f8a0e8b86f135b *ports/posix/qp_port.hpp
|
||||
66922bad40ecb6b213858f935849569713457f71 *ports/posix/qs_port.cpp
|
||||
f38e2f9bfe4df4d44a8f9a5fa2c0b2dfd79f35ae *ports/posix/qs_port.hpp
|
||||
e6a5523e16619370638f6305687cd480d1e3744b *ports/posix/README.md
|
||||
7235457eb9529f9fe2459ce869e63294ec5c5df6 *ports/posix/safe_std.h
|
||||
493900b9aa5475785c65458332995a184690d43f *ports/posix-qv/CMakeLists.txt
|
||||
819137bb54242fd0279ed152fe874decb9fd3c16 *ports/posix-qv/qf_port.cpp
|
||||
f458af1511007d6ba2a4a0a0e40d74e03719ceb1 *ports/posix-qv/qp_port.hpp
|
||||
66922bad40ecb6b213858f935849569713457f71 *ports/posix-qv/qs_port.cpp
|
||||
f38e2f9bfe4df4d44a8f9a5fa2c0b2dfd79f35ae *ports/posix-qv/qs_port.hpp
|
||||
e2e295c371bc14f0089a888b07d98c657dea07bf *ports/posix-qv/README.md
|
||||
7235457eb9529f9fe2459ce869e63294ec5c5df6 *ports/posix-qv/safe_std.h
|
||||
c9969a454b540a3b1abd3dd5cc46fb211663310e *ports/posix-qutest/CMakeLists.txt
|
||||
edfa2baff22735f98a094e315db11c40ed07e5e8 *ports/posix-qutest/qp_port.hpp
|
||||
f38e2f9bfe4df4d44a8f9a5fa2c0b2dfd79f35ae *ports/posix-qutest/qs_port.hpp
|
||||
772fdcf6a4ca3e3303016384de92874ec06c11fe *ports/posix-qutest/qutest_port.cpp
|
||||
7235457eb9529f9fe2459ce869e63294ec5c5df6 *ports/posix-qutest/safe_std.h
|
||||
06b76c6c30ea880876b47ee27115178ff62ea66b *ports/win32/CMakeLists.txt
|
||||
48dfd18fce993f237138d5d99f2fb0e385efbe93 *ports/win32/qf_port.cpp
|
||||
ea88910c991455756433cff5338a62ed3d181bf2 *ports/win32/qp_port.hpp
|
||||
6e6aef4b105bd807de96922fcb5698b695fce7e2 *ports/win32/qs_port.cpp
|
||||
f38e2f9bfe4df4d44a8f9a5fa2c0b2dfd79f35ae *ports/win32/qs_port.hpp
|
||||
40f18295a0013cbba3c6b270d1d70748ec1d325a *ports/win32/qwin_gui.c
|
||||
ddc62932b46bbc0ad147193d0dd7efa28127c6c4 *ports/win32/qwin_gui.h
|
||||
ad6de94157c477eacb61f321870b5f8c1a09a5cd *ports/win32/README.md
|
||||
7235457eb9529f9fe2459ce869e63294ec5c5df6 *ports/win32/safe_std.h
|
||||
dd5b9a8736e1a1171f7d8565e29e1acb6f7a9691 *ports/win32-qv/CMakeLists.txt
|
||||
55381dce63d87ddee340d5a153f6054c4fbf5c0e *ports/win32-qv/qf_port.cpp
|
||||
b2c8d14a04c2bbf3f6f0f3dae097e485a55dc008 *ports/win32-qv/qp_port.hpp
|
||||
6e6aef4b105bd807de96922fcb5698b695fce7e2 *ports/win32-qv/qs_port.cpp
|
||||
f38e2f9bfe4df4d44a8f9a5fa2c0b2dfd79f35ae *ports/win32-qv/qs_port.hpp
|
||||
40f18295a0013cbba3c6b270d1d70748ec1d325a *ports/win32-qv/qwin_gui.c
|
||||
ddc62932b46bbc0ad147193d0dd7efa28127c6c4 *ports/win32-qv/qwin_gui.h
|
||||
ddd27415c3d1df6d8c210966e8915c407b15bf58 *ports/win32-qv/README.md
|
||||
7235457eb9529f9fe2459ce869e63294ec5c5df6 *ports/win32-qv/safe_std.h
|
||||
3c23c06f425a8d8dbb18d1f191ac6cab483a8e51 *ports/win32-qutest/CMakeLists.txt
|
||||
edfa2baff22735f98a094e315db11c40ed07e5e8 *ports/win32-qutest/qp_port.hpp
|
||||
f38e2f9bfe4df4d44a8f9a5fa2c0b2dfd79f35ae *ports/win32-qutest/qs_port.hpp
|
||||
5bda26c8c82914e6cc16685e4adc02cbc32c5291 *ports/win32-qutest/qutest_port.cpp
|
||||
7235457eb9529f9fe2459ce869e63294ec5c5df6 *ports/win32-qutest/safe_std.h
|
||||
76dd9078dc4311d53d3862d44177a8660258da6d *zephyr/CMakeLists.txt
|
||||
36a0252cf0bfd6be0d345c48c00b2300f8917f05 *zephyr/Kconfig
|
||||
2eb2a922e18b4760a68151ebee1b6282d20b4692 *zephyr/module.yml
|
||||
36ceff869a883b6cb0a262755e3bf03d790f3a87 *zephyr/qf_port.cpp
|
||||
109c291df50110f185adc17bcdf8becc0a79346c *zephyr/qp-zephyr.jpg
|
||||
76548c9e125899106122946cdba17b7da1a32c91 *zephyr/qp_port.hpp
|
||||
d414f620c05844bbad1988f0951509856acc63db *zephyr/qs_port.hpp
|
||||
50863abaf410b184dbe28b36f6e63b74e26af26e *zephyr/qutest_port.cpp
|
||||
791248d57ce8dfa6497728c7c2d0734c2c581625 *zephyr/README.md
|
163
qpcpp_8.0.2.sha1
Normal file
163
qpcpp_8.0.2.sha1
Normal file
@ -0,0 +1,163 @@
|
||||
10c35486e20dc82668e4a77ec1a4cc427ba92b21 *include/qequeue.hpp
|
||||
2af472589274db820aa2a3e7928d7100d2f87cb3 *include/qk.hpp
|
||||
7394e76571868dfaea3c297e9d00e9f429cbdc3c *include/qmpool.hpp
|
||||
acc36cf4768e1707256f9891edb39850ad754ab0 *include/qp.hpp
|
||||
4a28afe5b5fabfa5ce45c2eb07c63388d8cd92b1 *include/qp_pkg.hpp
|
||||
c8c44d7959d255f98aac76f6040433aaa20956b6 *include/qpcpp.hpp
|
||||
0b4b406267c65182e40565ce01f510554827f005 *include/qs.hpp
|
||||
40f446662e01fcd410b0be8f7813dcd86995f22a *include/qs_dummy.hpp
|
||||
007ade6761260b32bf34ebaaea633977f0cff881 *include/qs_pkg.hpp
|
||||
cf142966637ce4c4ae831017e8a77fb1fe3a678a *include/qsafe.h
|
||||
87c77d984d77178533b4e76eb204c4e265b23e9e *include/qstamp.hpp
|
||||
0e7a9cc9d0511828380e5cd5ee2d7f35ed1bf317 *include/qv.hpp
|
||||
1cb8c24e0188d17c3c0ca4c12fe88f8c04a9e1e7 *include/qxk.hpp
|
||||
0199f3eeb6c02b8cc890ee4c6f6d344569a0858f *include/README.md
|
||||
71899ce74eeb04f333ed00d53f87719f722a39ab *src/qf/CMakeLists.txt
|
||||
750abbc6caf645de293f5107b10fba3fdbb107c9 *src/qf/qep_hsm.cpp
|
||||
875f0a15305079a6d5861d66fbcceb8333e9b75b *src/qf/qep_msm.cpp
|
||||
43eef9ea75c14b1378fc01772bf5e4bdc0621ba2 *src/qf/qf_act.cpp
|
||||
a8608d5b17afbe82161b01bf0a2edfdc8bbc5a44 *src/qf/qf_actq.cpp
|
||||
42aa87da9938aea033cda394b2677743d9733149 *src/qf/qf_defer.cpp
|
||||
19e4d2302186284364543182f6f5af5133516827 *src/qf/qf_dyn.cpp
|
||||
a06e9252217812cebd30b93fee4c0e4892b7e8e3 *src/qf/qf_mem.cpp
|
||||
91de7f212c546469f0b7ac9127ccc02860bd6abe *src/qf/qf_ps.cpp
|
||||
dffd53a967ea218a38c23e71d1aec228a5641b66 *src/qf/qf_qact.cpp
|
||||
1171eac0c4d4a69a1994e0e9461b785d5ce9803b *src/qf/qf_qeq.cpp
|
||||
06a3f2fc2b976f7948cac34a434b00ebfbf4a198 *src/qf/qf_qmact.cpp
|
||||
685aaac6419b8e86e8d6a8029bd2210bb582322c *src/qf/qf_time.cpp
|
||||
7cdab433e81612862fd27f0cf792d38e1197d064 *src/qk/CMakeLists.txt
|
||||
5c7393e1bf2f1f336ffda9b4ccfda7849bae6842 *src/qk/qk.cpp
|
||||
eb28260d471fc752ca54b2c1e2d763f28432c2c1 *src/qs/CMakeLists.txt
|
||||
450e30ae7919195dc76d934297e3bacd39eed7dc *src/qs/qs.cpp
|
||||
a49e4cc82d27458d880e3cea5edf7111228b5c83 *src/qs/qs_64bit.cpp
|
||||
a79389856629896857f68345a0aa908c07d5ac92 *src/qs/qs_fp.cpp
|
||||
0f206dfea5178ff9d5217b64d112053abb415627 *src/qs/qs_rx.cpp
|
||||
6e68d4e35a2743c33c45792c922ce065639b8bf5 *src/qs/qstamp.cpp
|
||||
b4a201fc64467596edadda63dd7f0c8e8344f99d *src/qs/qutest.cpp
|
||||
b6d93a16f5b176d3da4888a7efb265730337f46d *src/qv/CMakeLists.txt
|
||||
1588af3ba142febd147eace532cd1993c53a0d11 *src/qv/qv.cpp
|
||||
2242492063a43fbb9d1725bc243ab30018634bfc *src/qxk/qxk.cpp
|
||||
97f0a0bd72757e02e422d1a1d7ecb53343295942 *src/qxk/qxk_mutex.cpp
|
||||
7081b032e0db0675840a6c8b75edf4d47d13c9c7 *src/qxk/qxk_sema.cpp
|
||||
70982d9277482d775c967aaf745e9c4c442aef19 *src/qxk/qxk_xthr.cpp
|
||||
99754876405825cd0cd3a6257f27525455288c9d *ports/arm-cm/config/qp_config.hpp
|
||||
ae09530b01a3ce4f2cdc5dc007c97dcc0e08bae1 *ports/arm-cm/qk/armclang/qk_port.cpp
|
||||
5e2f09fa46a4a3bfd1c84126c845c9d86849f306 *ports/arm-cm/qk/armclang/qp_port.hpp
|
||||
e46cc02128baae0e52ff5dce6537f1a3d3f6c514 *ports/arm-cm/qk/armclang/qs_port.hpp
|
||||
4e10609efc099d39294cd0713e304b3de812fac6 *ports/arm-cm/qk/gnu/qk_port.cpp
|
||||
5e2f09fa46a4a3bfd1c84126c845c9d86849f306 *ports/arm-cm/qk/gnu/qp_port.hpp
|
||||
e46cc02128baae0e52ff5dce6537f1a3d3f6c514 *ports/arm-cm/qk/gnu/qs_port.hpp
|
||||
eebf9abd3858d108b12735c308c52725b777a676 *ports/arm-cm/qk/iar/qk_port.cpp
|
||||
52b074dacb05c7af593a56a375f4462c1de1ed8f *ports/arm-cm/qk/iar/qp_port.hpp
|
||||
e46cc02128baae0e52ff5dce6537f1a3d3f6c514 *ports/arm-cm/qk/iar/qs_port.hpp
|
||||
2c0ec84bc34f1368c8ea5ccde2cdf08eb7aaed5f *ports/arm-cm/qv/armclang/qp_port.hpp
|
||||
e46cc02128baae0e52ff5dce6537f1a3d3f6c514 *ports/arm-cm/qv/armclang/qs_port.hpp
|
||||
fd3556c0d6af1042ecafeefa6d9aff66d1a39244 *ports/arm-cm/qv/armclang/qv_port.cpp
|
||||
8e732484b6a9742d4e54bfe33c30b01a87ab02a3 *ports/arm-cm/qv/gnu/qp_port.hpp
|
||||
e46cc02128baae0e52ff5dce6537f1a3d3f6c514 *ports/arm-cm/qv/gnu/qs_port.hpp
|
||||
1399bbbce01a1269e41463d35c3431061e8b16a3 *ports/arm-cm/qv/gnu/qv_port.cpp
|
||||
f26fb7762d713962854dc16b3bc82ebdd03c33c9 *ports/arm-cm/qv/iar/qp_port.hpp
|
||||
e46cc02128baae0e52ff5dce6537f1a3d3f6c514 *ports/arm-cm/qv/iar/qs_port.hpp
|
||||
839ccd47dc6e513c5b850a1a6c9158d4909920e1 *ports/arm-cm/qv/iar/qv_port.cpp
|
||||
d4edac916a2df8dc2880467d01792f22f5939177 *ports/arm-cm/qxk/armclang/qp_port.hpp
|
||||
e46cc02128baae0e52ff5dce6537f1a3d3f6c514 *ports/arm-cm/qxk/armclang/qs_port.hpp
|
||||
c6804025f48f7ea744db38ad5d7955696c1ccdcf *ports/arm-cm/qxk/armclang/qxk_port.cpp
|
||||
d4edac916a2df8dc2880467d01792f22f5939177 *ports/arm-cm/qxk/gnu/qp_port.hpp
|
||||
e46cc02128baae0e52ff5dce6537f1a3d3f6c514 *ports/arm-cm/qxk/gnu/qs_port.hpp
|
||||
eec76849164d90d48cfd080dced937b07627e8c4 *ports/arm-cm/qxk/gnu/qxk_port.cpp
|
||||
2db00521dc7bdca6467f9c7978f4a47daf375688 *ports/arm-cm/qxk/iar/qp_port.hpp
|
||||
e46cc02128baae0e52ff5dce6537f1a3d3f6c514 *ports/arm-cm/qxk/iar/qs_port.hpp
|
||||
c6dbe8a03de76baad665faf5a50c863d38334b58 *ports/arm-cm/qxk/iar/qxk_port.cpp
|
||||
b83cf186b80decce5fdeb5f66080d7a88d9436e3 *ports/arm-cm/qutest/qp_port.hpp
|
||||
e46cc02128baae0e52ff5dce6537f1a3d3f6c514 *ports/arm-cm/qutest/qs_port.hpp
|
||||
5808649f96e035b70d0d752602883528aacb283a *ports/arm-cr/config/qp_config.hpp
|
||||
496bf7670fae59aa34ea0a7dfde8bb4d70a6a2a9 *ports/arm-cr/qk/gnu/qp_port.hpp
|
||||
e46cc02128baae0e52ff5dce6537f1a3d3f6c514 *ports/arm-cr/qk/gnu/qs_port.hpp
|
||||
1dd57dbde83ee29ef6a40cd6150aeaa181937957 *ports/arm-cr/qk/iar/qp_port.hpp
|
||||
e46cc02128baae0e52ff5dce6537f1a3d3f6c514 *ports/arm-cr/qk/iar/qs_port.hpp
|
||||
410cfb06e914a9a7efa9d321e8e63e8b132e5567 *ports/arm-cr/qk/ti/qp_port.hpp
|
||||
e46cc02128baae0e52ff5dce6537f1a3d3f6c514 *ports/arm-cr/qk/ti/qs_port.hpp
|
||||
ad5ba7bf199209edb6683128638d596c8056a1a0 *ports/arm-cr/qv/gnu/qp_port.hpp
|
||||
e46cc02128baae0e52ff5dce6537f1a3d3f6c514 *ports/arm-cr/qv/gnu/qs_port.hpp
|
||||
631549a2f7f4aab54d469b4f711e79e499b604be *ports/arm-cr/qv/iar/qp_port.hpp
|
||||
e46cc02128baae0e52ff5dce6537f1a3d3f6c514 *ports/arm-cr/qv/iar/qs_port.hpp
|
||||
75a60334fe636906329001ed18f5c54033ed9d04 *ports/arm-cr/qv/ti/qp_port.hpp
|
||||
e46cc02128baae0e52ff5dce6537f1a3d3f6c514 *ports/arm-cr/qv/ti/qs_port.hpp
|
||||
18596df7b34eb99db5d580d4f1c2b2a43e3ab3a3 *ports/msp430/qk/qp_port.hpp
|
||||
6577bacc46c9a9f0cc27893506be39b1e69dd240 *ports/msp430/qk/qs_port.hpp
|
||||
90e2a0391ea79ae8507a06356a06e8c1f942daee *ports/msp430/qv/qp_port.hpp
|
||||
6577bacc46c9a9f0cc27893506be39b1e69dd240 *ports/msp430/qv/qs_port.hpp
|
||||
55012fd62bb201af549da0c39d6ef85ea225790a *ports/msp430/qutest/qp_port.hpp
|
||||
6577bacc46c9a9f0cc27893506be39b1e69dd240 *ports/msp430/qutest/qs_port.hpp
|
||||
ea650ce477ced748760fdad526ea964be5c5ff95 *ports/config/qp_config.hpp
|
||||
b6b5d23c618976a6fbed51dc5a13e227928e1d4b *ports/embos/CMakeLists.txt
|
||||
670c6241eb418c66d46fc024fec33a623a2c2457 *ports/embos/qf_port.cpp
|
||||
b80f7433aa174c6560ba1fd7f4ae2f2c94938906 *ports/embos/qp_port.hpp
|
||||
e46cc02128baae0e52ff5dce6537f1a3d3f6c514 *ports/embos/qs_port.hpp
|
||||
e4f00894f86806af6d88d38e831a8fc0ad36059e *ports/freertos/CMakeLists.txt
|
||||
19acb29335a0244d1838102237aa4b8330df2f6a *ports/freertos/qf_port.cpp
|
||||
96b4b2111d90b5326bed4de44e05830ada4e8678 *ports/freertos/qp_port.hpp
|
||||
e46cc02128baae0e52ff5dce6537f1a3d3f6c514 *ports/freertos/qs_port.hpp
|
||||
18df978f665338c757f1a2a284c2acc779bd59d3 *ports/threadx/CMakeLists.txt
|
||||
931be3f4d0a2761d69ac8285d128fe1668731604 *ports/threadx/qf_port.cpp
|
||||
29ab3ac5a56faaaf5d866a43d2e4edff7013a1ae *ports/threadx/qp_port.hpp
|
||||
0182f7957f25390579a30b7ab56604819f9a3773 *ports/threadx/qs_port.hpp
|
||||
46699d3c8ad92f9c98ea5e03e72d4190a7794aa4 *ports/threadx/README.md
|
||||
0ab8b95f50fa767b951c6f56efe86789623b7127 *ports/uc-os2/CMakeLists.txt
|
||||
989f46b139112b66f31f516266db338971bdef7f *ports/uc-os2/qf_port.cpp
|
||||
1b511d790891f3f1fb78f6c7272c20205a4eb0dd *ports/uc-os2/qp_port.hpp
|
||||
0182f7957f25390579a30b7ab56604819f9a3773 *ports/uc-os2/qs_port.hpp
|
||||
227dedab24f1e20440103a0cabc210b4b5adedef *ports/qep-only/CMakeLists.txt
|
||||
c96963c82a774605baab1839214e8bd32d173a68 *ports/qep-only/qp_port.hpp
|
||||
7235457eb9529f9fe2459ce869e63294ec5c5df6 *ports/qep-only/safe_std.h
|
||||
12255313ebcf963d29d91bee4c917bb6ab2f9e1d *ports/posix/CMakeLists.txt
|
||||
720ff5c7ed5de9f9630ce5b80d34d157f0cb8151 *ports/posix/qf_port.cpp
|
||||
c735c52b19b7692464902aca05dcd13cb7d2236e *ports/posix/qp_port.hpp
|
||||
b566671ee550bd9735005b04f474cac6eb3301dd *ports/posix/qs_port.cpp
|
||||
0242b0613d7133442426f5834f2677e77b32014b *ports/posix/qs_port.hpp
|
||||
e6a5523e16619370638f6305687cd480d1e3744b *ports/posix/README.md
|
||||
7235457eb9529f9fe2459ce869e63294ec5c5df6 *ports/posix/safe_std.h
|
||||
493900b9aa5475785c65458332995a184690d43f *ports/posix-qv/CMakeLists.txt
|
||||
0e0243f24a521c6c135c548b22854543a5cdf4b1 *ports/posix-qv/qf_port.cpp
|
||||
2909abe049eff960b4008efaa9c6a12eff5a6517 *ports/posix-qv/qp_port.hpp
|
||||
b566671ee550bd9735005b04f474cac6eb3301dd *ports/posix-qv/qs_port.cpp
|
||||
0242b0613d7133442426f5834f2677e77b32014b *ports/posix-qv/qs_port.hpp
|
||||
e2e295c371bc14f0089a888b07d98c657dea07bf *ports/posix-qv/README.md
|
||||
7235457eb9529f9fe2459ce869e63294ec5c5df6 *ports/posix-qv/safe_std.h
|
||||
c9969a454b540a3b1abd3dd5cc46fb211663310e *ports/posix-qutest/CMakeLists.txt
|
||||
2c96ee69ca3c443a1224c4eacb83bbfb3cb60300 *ports/posix-qutest/qp_port.hpp
|
||||
0242b0613d7133442426f5834f2677e77b32014b *ports/posix-qutest/qs_port.hpp
|
||||
24b9c9258b3621ac757439cc7e93b817ffe9fefe *ports/posix-qutest/qutest_port.cpp
|
||||
7235457eb9529f9fe2459ce869e63294ec5c5df6 *ports/posix-qutest/safe_std.h
|
||||
06b76c6c30ea880876b47ee27115178ff62ea66b *ports/win32/CMakeLists.txt
|
||||
0c2a046c664038d547e8dc8ba9573c599c087c60 *ports/win32/qf_port.cpp
|
||||
6d89a4f5c91649cfff645f13a24cc632522797d4 *ports/win32/qp_port.hpp
|
||||
a816ee62f507984cdbc37ac190b9f8a23a461bfb *ports/win32/qs_port.cpp
|
||||
9daff0910db201c165600d3e55458f2ebec2dcc8 *ports/win32/qs_port.hpp
|
||||
40f18295a0013cbba3c6b270d1d70748ec1d325a *ports/win32/qwin_gui.c
|
||||
ddc62932b46bbc0ad147193d0dd7efa28127c6c4 *ports/win32/qwin_gui.h
|
||||
ad6de94157c477eacb61f321870b5f8c1a09a5cd *ports/win32/README.md
|
||||
7235457eb9529f9fe2459ce869e63294ec5c5df6 *ports/win32/safe_std.h
|
||||
dd5b9a8736e1a1171f7d8565e29e1acb6f7a9691 *ports/win32-qv/CMakeLists.txt
|
||||
eebb50308338c99e97d4f99272f37a4e9989d9ea *ports/win32-qv/qf_port.cpp
|
||||
4b947280e9b569adb81afe7d72abca402bc39e9d *ports/win32-qv/qp_port.hpp
|
||||
a816ee62f507984cdbc37ac190b9f8a23a461bfb *ports/win32-qv/qs_port.cpp
|
||||
9daff0910db201c165600d3e55458f2ebec2dcc8 *ports/win32-qv/qs_port.hpp
|
||||
40f18295a0013cbba3c6b270d1d70748ec1d325a *ports/win32-qv/qwin_gui.c
|
||||
ddc62932b46bbc0ad147193d0dd7efa28127c6c4 *ports/win32-qv/qwin_gui.h
|
||||
ddd27415c3d1df6d8c210966e8915c407b15bf58 *ports/win32-qv/README.md
|
||||
7235457eb9529f9fe2459ce869e63294ec5c5df6 *ports/win32-qv/safe_std.h
|
||||
3c23c06f425a8d8dbb18d1f191ac6cab483a8e51 *ports/win32-qutest/CMakeLists.txt
|
||||
2c96ee69ca3c443a1224c4eacb83bbfb3cb60300 *ports/win32-qutest/qp_port.hpp
|
||||
9daff0910db201c165600d3e55458f2ebec2dcc8 *ports/win32-qutest/qs_port.hpp
|
||||
2b66a9145abdee9e280c67f78fe892c069bfabea *ports/win32-qutest/qutest_port.cpp
|
||||
7235457eb9529f9fe2459ce869e63294ec5c5df6 *ports/win32-qutest/safe_std.h
|
||||
76dd9078dc4311d53d3862d44177a8660258da6d *zephyr/CMakeLists.txt
|
||||
36a0252cf0bfd6be0d345c48c00b2300f8917f05 *zephyr/Kconfig
|
||||
2eb2a922e18b4760a68151ebee1b6282d20b4692 *zephyr/module.yml
|
||||
bab81f1bd3833d059c0e2276380d82ed18aa514e *zephyr/qf_port.cpp
|
||||
109c291df50110f185adc17bcdf8becc0a79346c *zephyr/qp-zephyr.jpg
|
||||
b91b2672da8f3108e103f44d649e90afec956e46 *zephyr/qp_port.hpp
|
||||
e390a0d4bef60bf18fa5ce4527c3d4e5eef0a473 *zephyr/qs_port.hpp
|
||||
986dbb809e35eace3e8b2b9941df76c7153a8c0c *zephyr/qutest_port.cpp
|
||||
791248d57ce8dfa6497728c7c2d0734c2c581625 *zephyr/README.md
|
@ -1,6 +1,6 @@
|
||||
@setlocal
|
||||
|
||||
set VERSION=8.0.1
|
||||
set VERSION=8.0.2
|
||||
|
||||
:: usage
|
||||
@echo Usage: qppcp_sha1 [gen]
|
||||
@ -15,14 +15,15 @@ goto end
|
||||
)
|
||||
|
||||
@echo generating qpcpp_%VERSION%.sha1...
|
||||
@sha1sum qpcpp.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/* ^
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,10 +1,6 @@
|
||||
//$file${src::qf::qep_msm.cpp} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
//
|
||||
// Model: qpcpp.qm
|
||||
// File: ${src::qf::qep_msm.cpp}
|
||||
//
|
||||
// This code has been generated by QM 7.0.0 <www.state-machine.com/qm>.
|
||||
// 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,8 +10,8 @@
|
||||
//
|
||||
// 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-
|
||||
// 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.
|
||||
@ -30,8 +26,7 @@
|
||||
// Quantum Leaps contact information:
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//
|
||||
//$endhead${src::qf::qep_msm.cpp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//============================================================================
|
||||
#define QP_IMPL // this is QP implementation
|
||||
#include "qp_port.hpp" // QP port
|
||||
#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem
|
||||
@ -42,16 +37,18 @@
|
||||
#include "qs_dummy.hpp" // disable the QS software tracing
|
||||
#endif // Q_SPY
|
||||
|
||||
//============================================================================
|
||||
//! @cond INTERNAL
|
||||
|
||||
// unnamed namespace for local definitions with internal linkage
|
||||
namespace {
|
||||
|
||||
Q_DEFINE_THIS_MODULE("qep_msm")
|
||||
|
||||
// maximum depth of entry levels in a MSM for tran. to history.
|
||||
static constexpr std::int_fast8_t QMSM_MAX_ENTRY_DEPTH_ {4};
|
||||
|
||||
//! @cond INTERNAL
|
||||
|
||||
// top-state object for QMsm-style state machines
|
||||
QP::QMState const l_msm_top_s = {
|
||||
constexpr QP::QMState l_msm_top_s = {
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
@ -59,32 +56,75 @@ QP::QMState const l_msm_top_s = {
|
||||
nullptr
|
||||
};
|
||||
|
||||
// maximum depth of state nesting in a QMsm (including the top level)
|
||||
static constexpr std::int_fast8_t QMSM_MAX_NEST_DEPTH_ {8};
|
||||
|
||||
// maximum length of transition-action array
|
||||
static constexpr std::int_fast8_t QMSM_MAX_TRAN_LENGTH_ {2*QMSM_MAX_NEST_DEPTH_};
|
||||
|
||||
// maximum depth of entry levels in a MSM for tran. to history.
|
||||
static constexpr std::int_fast8_t QMSM_MAX_ENTRY_DEPTH_ {4};
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
//! @endcond
|
||||
//============================================================================
|
||||
#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(this); \
|
||||
QS_FUN_PRE(state_); \
|
||||
QS_END_PRE() \
|
||||
QS_CRIT_EXIT()
|
||||
|
||||
//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
// Check for the minimum required QP version
|
||||
#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U)%0x2710U))
|
||||
#error qpcpp version 7.3.0 or higher required
|
||||
// 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(this); \
|
||||
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(this); \
|
||||
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(this); \
|
||||
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(this); \
|
||||
QS_FUN_PRE(src_); \
|
||||
QS_FUN_PRE(trg_); \
|
||||
QS_END_PRE() \
|
||||
QS_CRIT_EXIT()
|
||||
|
||||
#else
|
||||
#define QS_STATE_ACT_(rec_, state_) (static_cast<void>(0))
|
||||
#define QS_TOP_INIT_(rec_, trg_) (static_cast<void>(0))
|
||||
#define QS_TRAN_SEG_(rec_, src_, trg_) (static_cast<void>(0))
|
||||
#define QS_TRAN0_(rec_, trg_) (static_cast<void>(0))
|
||||
#define QS_TRAN_END_(rec_, src_, trg_) (static_cast<void>(0))
|
||||
#endif
|
||||
//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//$define${QEP::QMsm} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
|
||||
//! @endcond
|
||||
|
||||
//============================================================================
|
||||
namespace QP {
|
||||
|
||||
//${QEP::QMsm} ...............................................................
|
||||
|
||||
//${QEP::QMsm::QMsm} .........................................................
|
||||
//............................................................................
|
||||
QMsm::QMsm(QStateHandler const initial) noexcept
|
||||
: QAsm()
|
||||
{
|
||||
@ -92,19 +132,20 @@ QMsm::QMsm(QStateHandler const initial) noexcept
|
||||
m_temp.fun = initial; // the initial tran. handler
|
||||
}
|
||||
|
||||
//${QEP::QMsm::init} .........................................................
|
||||
//............................................................................
|
||||
void QMsm::init(
|
||||
void const * const e,
|
||||
std::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, (m_temp.fun != nullptr)
|
||||
&& (m_state.obj == &l_msm_top_s));
|
||||
Q_REQUIRE_INCRIT(200,
|
||||
(m_temp.fun != nullptr)
|
||||
&& (m_state.obj == &l_msm_top_s));
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
// execute the top-most initial tran.
|
||||
@ -113,140 +154,85 @@ 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(this); // this state machine object
|
||||
QS_FUN_PRE(m_state.obj->stateHandler); // source state
|
||||
QS_FUN_PRE(m_temp.tatbl->target->stateHandler); // target state
|
||||
QS_END_PRE()
|
||||
QS_MEM_APP();
|
||||
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
QS_TRAN_SEG_(QS_QEP_STATE_INIT,
|
||||
m_state.obj->stateHandler, m_temp.tatbl->target->stateHandler);
|
||||
|
||||
// set state to the last tran. target
|
||||
m_state.obj = m_temp.tatbl->target;
|
||||
|
||||
// drill down into the state hierarchy with initial transitions...
|
||||
std::int_fast8_t lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound
|
||||
do {
|
||||
while (r >= Q_RET_TRAN_INIT) {
|
||||
// execute the tran. table
|
||||
r = execTatbl_(m_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(this); // this state machine object
|
||||
QS_FUN_PRE(m_state.obj->stateHandler); // the new current state
|
||||
QS_END_PRE()
|
||||
QS_MEM_APP();
|
||||
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
m_temp.uint = ~m_state.uint;
|
||||
#endif
|
||||
QS_TOP_INIT_(QS_QEP_INIT_TRAN, m_state.obj->stateHandler);
|
||||
}
|
||||
|
||||
//${QEP::QMsm::dispatch} .....................................................
|
||||
//............................................................................
|
||||
void QMsm::dispatch(
|
||||
QEvt const * const e,
|
||||
std::uint_fast8_t const qsId)
|
||||
{
|
||||
#ifndef Q_SPY
|
||||
#ifndef Q_SPY
|
||||
Q_UNUSED_PAR(qsId);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
QMState const *s = m_state.obj; // store the current state
|
||||
QMState const *t = s;
|
||||
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
Q_REQUIRE_INCRIT(300, (e != nullptr) && (s != nullptr));
|
||||
Q_INVARIANT_INCRIT(301,
|
||||
e->verify_()
|
||||
&& (m_state.uint == static_cast<std::uintptr_t>(~m_temp.uint)));
|
||||
|
||||
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(this); // this state machine object
|
||||
QS_FUN_PRE(s->stateHandler); // the current state handler
|
||||
QS_END_PRE()
|
||||
QS_MEM_APP();
|
||||
|
||||
Q_REQUIRE_INCRIT(300,
|
||||
(e != nullptr)
|
||||
&& (s != nullptr));
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
QS_TRAN0_(QS_QEP_DISPATCH, s->stateHandler);
|
||||
|
||||
// scan the state hierarchy up to the top state...
|
||||
QState r;
|
||||
std::int_fast8_t lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound
|
||||
do {
|
||||
QState r = Q_RET_SUPER;
|
||||
while (t != nullptr) {
|
||||
r = (*t->stateHandler)(this, 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(this); // this state machine object
|
||||
QS_FUN_PRE(t->stateHandler); // the current state
|
||||
QS_SIG_PRE(e->sig);
|
||||
QS_OBJ_PRE(this);
|
||||
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 != nullptr) && (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();
|
||||
// the tran. source state must not be nullptr
|
||||
// the tran. source state must not be NULL
|
||||
Q_ASSERT_INCRIT(330, t != nullptr);
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
#ifdef Q_SPY
|
||||
QMState const * const ts = t; // for saving tran. table
|
||||
#endif // Q_SPY
|
||||
QMTranActTable const *tatbl;
|
||||
#ifdef Q_SPY
|
||||
QMState const * const ts = t; // tran. source for QS tracing
|
||||
#endif // Q_SPY
|
||||
|
||||
if (r == Q_RET_TRAN_HIST) { // was it tran. to history?
|
||||
QMState const * const hist = m_state.obj; // save history
|
||||
m_state.obj = s; // restore the original state
|
||||
|
||||
QS_CRIT_ENTRY();
|
||||
QS_MEM_SYS();
|
||||
QS_BEGIN_PRE(QS_QEP_TRAN_HIST, qsId)
|
||||
QS_OBJ_PRE(this); // 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 = m_temp.tatbl;
|
||||
QMTranActTable const *tatbl = m_temp.tatbl;
|
||||
exitToTranSource_(s, t, qsId);
|
||||
static_cast<void>(execTatbl_(tatbl, qsId));
|
||||
r = enterHistory_(hist, qsId);
|
||||
@ -254,205 +240,120 @@ 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 = m_temp.tatbl;
|
||||
QMTranActTable const *tatbl = m_temp.tatbl;
|
||||
m_temp.obj = nullptr; // clear
|
||||
exitToTranSource_(s, t, qsId);
|
||||
r = execTatbl_(tatbl, qsId);
|
||||
s = m_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(this); // 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 nullptr
|
||||
// internal tran. source can't be NULL
|
||||
Q_ASSERT_INCRIT(380, t != nullptr);
|
||||
|
||||
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(this); // 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 == nullptr) {
|
||||
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(this); // this state machine object
|
||||
QS_FUN_PRE(s->stateHandler); // the current state
|
||||
QS_END_PRE()
|
||||
QS_MEM_APP();
|
||||
QS_CRIT_EXIT();
|
||||
else if (t == nullptr) { // event bubbled to the 'top' state?
|
||||
QS_TRAN0_(QS_QEP_IGNORED, s->stateHandler);
|
||||
}
|
||||
#endif // Q_SPY
|
||||
#endif // Q_SPY
|
||||
else {
|
||||
// empty
|
||||
}
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
m_temp.uint = ~m_state.uint;
|
||||
#endif
|
||||
}
|
||||
|
||||
//${QEP::QMsm::isIn} .........................................................
|
||||
//............................................................................
|
||||
bool QMsm::isIn(QStateHandler const state) noexcept {
|
||||
bool inState = false; // assume that this SM is not in 'state'
|
||||
|
||||
QMState const *s = m_state.obj;
|
||||
std::int_fast8_t lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound
|
||||
for (; (s != nullptr) && (lbound > 0); --lbound) {
|
||||
while (s != nullptr) {
|
||||
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} ................................................
|
||||
QMState const * QMsm::childStateObj(QMState const * const parent) const noexcept {
|
||||
QMState const *child = m_state.obj;
|
||||
bool isFound = false; // start with the child not found
|
||||
QMState const *s;
|
||||
//............................................................................
|
||||
QMState const * QMsm::childStateObj(QMState const * const parent)
|
||||
const noexcept
|
||||
{
|
||||
QMState const *s = m_state.obj; // start with current state
|
||||
QMState const *child = s;
|
||||
bool isFound = false; // assume the child NOT found
|
||||
|
||||
std::int_fast8_t lbound = QMSM_MAX_NEST_DEPTH_; // fixed upper loop bound
|
||||
for (s = m_state.obj;
|
||||
(s != nullptr) && (lbound > 0);
|
||||
s = s->superstate)
|
||||
{
|
||||
while (s != nullptr) {
|
||||
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 = m_temp.obj;
|
||||
(s != nullptr) && (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_} ...................................................
|
||||
//............................................................................
|
||||
QState QMsm::execTatbl_(
|
||||
QMTranActTable const * const tatbl,
|
||||
std::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 != nullptr);
|
||||
Q_REQUIRE_INCRIT(600, tatbl != nullptr);
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
QState r = Q_RET_NULL;
|
||||
std::int_fast8_t lbound = QMSM_MAX_TRAN_LENGTH_; // fixed upper loop bound
|
||||
QActionHandler const *a = &tatbl->act[0];
|
||||
for (; (*a != nullptr) && (lbound > 0); ++a) {
|
||||
while (*a != nullptr) {
|
||||
r = (*(*a))(this); // 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(this); // this state machine object
|
||||
QS_FUN_PRE(m_temp.obj->stateHandler); // entered state
|
||||
QS_END_PRE()
|
||||
QS_STATE_ACT_(QS_QEP_STATE_ENTRY, m_temp.obj->stateHandler);
|
||||
}
|
||||
else if (r == Q_RET_EXIT) {
|
||||
QS_BEGIN_PRE(QS_QEP_STATE_EXIT, qsId)
|
||||
QS_OBJ_PRE(this); // this state machine object
|
||||
QS_FUN_PRE(m_temp.obj->stateHandler); // exited state
|
||||
QS_END_PRE()
|
||||
QS_STATE_ACT_(QS_QEP_STATE_EXIT, m_temp.obj->stateHandler);
|
||||
}
|
||||
else if (r == Q_RET_TRAN_INIT) {
|
||||
QS_BEGIN_PRE(QS_QEP_STATE_INIT, qsId)
|
||||
QS_OBJ_PRE(this); // this state machine object
|
||||
QS_FUN_PRE(tatbl->target->stateHandler); // source
|
||||
QS_FUN_PRE(m_temp.tatbl->target->stateHandler); // target
|
||||
QS_END_PRE()
|
||||
QS_TRAN_SEG_(QS_QEP_STATE_INIT,
|
||||
tatbl->target->stateHandler,
|
||||
m_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 == nullptr);
|
||||
Q_ASSERT_INCRIT(690, *a == nullptr);
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
m_state.obj = (r >= Q_RET_TRAN)
|
||||
@ -461,58 +362,45 @@ QState QMsm::execTatbl_(
|
||||
return r;
|
||||
}
|
||||
|
||||
//${QEP::QMsm::exitToTranSource_} ............................................
|
||||
//............................................................................
|
||||
void QMsm::exitToTranSource_(
|
||||
QMState const * const cs,
|
||||
QMState const * const ts,
|
||||
std::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;
|
||||
std::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 != nullptr) {
|
||||
// execute the exit action
|
||||
static_cast<void>((*s->exitAction)(this));
|
||||
|
||||
QS_CRIT_ENTRY();
|
||||
QS_MEM_SYS();
|
||||
QS_BEGIN_PRE(QS_QEP_STATE_EXIT, qsId)
|
||||
QS_OBJ_PRE(this); // 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, m_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_} ................................................
|
||||
//............................................................................
|
||||
QState QMsm::enterHistory_(
|
||||
QMState const * const hist,
|
||||
std::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;
|
||||
std::int_fast8_t i = 0; // tran. entry path index
|
||||
while ((s != m_state.obj) && (i < (QMSM_MAX_ENTRY_DEPTH_ - 1))) {
|
||||
std::int_fast8_t i = 0; // tran. entry path index & fixed upper loop bound
|
||||
while ((s != m_state.obj) && (i < QMSM_MAX_ENTRY_DEPTH_)) {
|
||||
if (s->entryAction != nullptr) {
|
||||
epath[i] = s;
|
||||
++i;
|
||||
@ -521,51 +409,34 @@ QState QMsm::enterHistory_(
|
||||
}
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ASSERT_INCRIT(910, s == m_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;
|
||||
(*epath[i]->entryAction)(this); // run entry action in epath[i]
|
||||
// NOTE: i the fixed upper loop bound
|
||||
for (i = i - 1; i >= 0; --i) {
|
||||
// run entry action in epath[i]
|
||||
static_cast<void>((*epath[i]->entryAction)(this));
|
||||
|
||||
QS_CRIT_ENTRY();
|
||||
QS_MEM_SYS();
|
||||
QS_BEGIN_PRE(QS_QEP_STATE_ENTRY, qsId)
|
||||
QS_OBJ_PRE(this);
|
||||
QS_FUN_PRE(epath[i]->stateHandler); // entered state handler
|
||||
QS_END_PRE()
|
||||
QS_MEM_APP();
|
||||
QS_CRIT_EXIT();
|
||||
QS_STATE_ACT_(QS_QEP_STATE_ENTRY, epath[i]->stateHandler);
|
||||
}
|
||||
|
||||
m_state.obj = hist; // set current state to the tran. target
|
||||
|
||||
// initial tran. present?
|
||||
QState r;
|
||||
QState r = Q_RET_NULL;
|
||||
if (hist->initAction != nullptr) {
|
||||
r = (*hist->initAction)(this); // execute the tran. action
|
||||
QS_CRIT_ENTRY();
|
||||
QS_MEM_SYS();
|
||||
QS_BEGIN_PRE(QS_QEP_STATE_INIT, qsId)
|
||||
QS_OBJ_PRE(this); // this state machine object
|
||||
QS_FUN_PRE(hist->stateHandler); // source
|
||||
QS_FUN_PRE(m_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, m_temp.tatbl->target->stateHandler);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
//${QEP::QMsm::topQMState} ...................................................
|
||||
//............................................................................
|
||||
QMState const * QMsm::topQMState() const noexcept {
|
||||
return &l_msm_top_s;
|
||||
}
|
||||
|
||||
} // namespace QP
|
||||
//$enddef${QEP::QMsm} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -1,10 +1,6 @@
|
||||
//$file${src::qf::qf_act.cpp} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
//
|
||||
// Model: qpcpp.qm
|
||||
// File: ${src::qf::qf_act.cpp}
|
||||
//
|
||||
// This code has been generated by QM 7.0.0 <www.state-machine.com/qm>.
|
||||
// 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,8 +10,8 @@
|
||||
//
|
||||
// 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-
|
||||
// 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.
|
||||
@ -30,8 +26,7 @@
|
||||
// Quantum Leaps contact information:
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//
|
||||
//$endhead${src::qf::qf_act.cpp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//============================================================================
|
||||
#define QP_IMPL // this is QP implementation
|
||||
#include "qp_port.hpp" // QP port
|
||||
#include "qp_pkg.hpp" // QP package-scope interface
|
||||
@ -48,27 +43,17 @@ namespace {
|
||||
//Q_DEFINE_THIS_MODULE("qf_act")
|
||||
} // unnamed namespace
|
||||
|
||||
//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
// Check for the minimum required QP version
|
||||
#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U)%0x2710U))
|
||||
#error qpcpp version 7.3.0 or higher required
|
||||
#endif
|
||||
//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//$define${QF::QActive::registry_[QF_MAX_ACTIVE + 1U]} vvvvvvvvvvvvvvvvvvvvvvv
|
||||
namespace QP {
|
||||
|
||||
// QP version string embedded in the binary image
|
||||
char const versionStr[] = "QP/C++ " QP_VERSION_STR;
|
||||
|
||||
QActive * QActive::registry_[QF_MAX_ACTIVE + 1U];
|
||||
|
||||
} // namespace QP
|
||||
//$enddef${QF::QActive::registry_[QF_MAX_ACTIVE + 1U]} ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
//$define${QF::QF-pkg} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
namespace QP {
|
||||
namespace QF {
|
||||
|
||||
//${QF::QF-pkg::priv_} .......................................................
|
||||
QF::Attr priv_;
|
||||
|
||||
//${QF::QF-pkg::bzero_} ......................................................
|
||||
void bzero_(
|
||||
void * const start,
|
||||
std::uint_fast16_t const len) noexcept
|
||||
@ -81,57 +66,47 @@ void bzero_(
|
||||
}
|
||||
|
||||
} // namespace QF
|
||||
} // namespace QP
|
||||
//$enddef${QF::QF-pkg} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//$define${QF::types::QF_LOG2} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
namespace QP {
|
||||
|
||||
//${QF::types::QF_LOG2} ......................................................
|
||||
//............................................................................
|
||||
#ifndef QF_LOG2
|
||||
std::uint_fast8_t QF_LOG2(QP::QPSetBits x) noexcept {
|
||||
static std::uint8_t const log2LUT[16] = {
|
||||
std::uint_fast8_t QF_LOG2(QP::QPSetBits const bitmask) noexcept {
|
||||
static constexpr std::uint8_t log2LUT[16] = {
|
||||
0U, 1U, 2U, 2U, 3U, 3U, 3U, 3U,
|
||||
4U, 4U, 4U, 4U, 4U, 4U, 4U, 4U
|
||||
};
|
||||
std::uint_fast8_t n = 0U;
|
||||
QP::QPSetBits t;
|
||||
QP::QPSetBits x = bitmask;
|
||||
QP::QPSetBits tmp;
|
||||
|
||||
#if (QF_MAX_ACTIVE > 16U)
|
||||
t = static_cast<QP::QPSetBits>(x >> 16U);
|
||||
if (t != 0U) {
|
||||
#if (QF_MAX_ACTIVE > 16U)
|
||||
tmp = static_cast<QP::QPSetBits>(x >> 16U);
|
||||
if (tmp != 0U) {
|
||||
n += 16U;
|
||||
x = t;
|
||||
x = tmp;
|
||||
}
|
||||
#endif
|
||||
#if (QF_MAX_ACTIVE > 8U)
|
||||
t = (x >> 8U);
|
||||
if (t != 0U) {
|
||||
#endif
|
||||
#if (QF_MAX_ACTIVE > 8U)
|
||||
tmp = (x >> 8U);
|
||||
if (tmp != 0U) {
|
||||
n += 8U;
|
||||
x = t;
|
||||
x = tmp;
|
||||
}
|
||||
#endif
|
||||
t = (x >> 4U);
|
||||
if (t != 0U) {
|
||||
#endif
|
||||
tmp = (x >> 4U);
|
||||
if (tmp != 0U) {
|
||||
n += 4U;
|
||||
x = t;
|
||||
x = tmp;
|
||||
}
|
||||
return n + log2LUT[x];
|
||||
}
|
||||
#endif // ndef QF_LOG2
|
||||
|
||||
} // namespace QP
|
||||
//$enddef${QF::types::QF_LOG2} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//............................................................................
|
||||
#ifndef Q_UNSAFE
|
||||
//$define${QF::types::QPtrDis} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
namespace QP {
|
||||
|
||||
//${QF::types::QPtrDis} ......................................................
|
||||
|
||||
//${QF::types::QPtrDis::QPtrDis} .............................................
|
||||
QPtrDis::QPtrDis(void const * const ptr) noexcept
|
||||
: m_ptr_dis(static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(ptr)))
|
||||
{}
|
||||
#endif
|
||||
|
||||
} // namespace QP
|
||||
//$enddef${QF::types::QPtrDis} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
#endif
|
||||
|
||||
|
@ -1,10 +1,6 @@
|
||||
//$file${src::qf::qf_actq.cpp} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
//
|
||||
// Model: qpcpp.qm
|
||||
// File: ${src::qf::qf_actq.cpp}
|
||||
//
|
||||
// This code has been generated by QM 7.0.0 <www.state-machine.com/qm>.
|
||||
// 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,8 +10,8 @@
|
||||
//
|
||||
// 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-
|
||||
// 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.
|
||||
@ -30,8 +26,7 @@
|
||||
// Quantum Leaps contact information:
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//
|
||||
//$endhead${src::qf::qf_actq.cpp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//============================================================================
|
||||
#define QP_IMPL // this is QP implementation
|
||||
#include "qp_port.hpp" // QP port
|
||||
#include "qp_pkg.hpp" // QP package-scope interface
|
||||
@ -49,243 +44,122 @@ namespace {
|
||||
Q_DEFINE_THIS_MODULE("qf_actq")
|
||||
} // unnamed namespace
|
||||
|
||||
//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
// Check for the minimum required QP version
|
||||
#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U)%0x2710U))
|
||||
#error qpcpp version 7.3.0 or higher required
|
||||
#endif
|
||||
//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//$define${QF::QActive::post_} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
namespace QP {
|
||||
|
||||
//${QF::QActive::post_} ......................................................
|
||||
//............................................................................
|
||||
bool QActive::post_(
|
||||
QEvt const * const e,
|
||||
std::uint_fast16_t const margin,
|
||||
void const * const sender) noexcept
|
||||
{
|
||||
#ifndef Q_SPY
|
||||
#ifndef Q_SPY
|
||||
Q_UNUSED_PAR(sender);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef Q_UTEST // test?
|
||||
#if (Q_UTEST != 0) // testing QP-stub?
|
||||
#ifdef Q_UTEST // test?
|
||||
#if (Q_UTEST != 0) // testing QP-stub?
|
||||
if (m_temp.fun == Q_STATE_CAST(0)) { // QActiveDummy?
|
||||
return static_cast<QActiveDummy *>(this)->fakePost(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 != nullptr);
|
||||
|
||||
QEQueueCtr tmp = m_eQueue.m_nFree; // get volatile into temporary
|
||||
#ifndef Q_UNSAFE
|
||||
QEQueueCtr dis = static_cast<QEQueueCtr>(~m_eQueue.m_nFree_dis);
|
||||
Q_INVARIANT_INCRIT(201, e->verify_() && (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 = m_eQueue.m_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 > static_cast<QEQueueCtr>(margin)) {
|
||||
else if (nFree > static_cast<QEQueueCtr>(margin)) { // enough free?
|
||||
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 (e->getPoolNum_() != 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
|
||||
|
||||
m_eQueue.m_nFree = tmp; // update the original
|
||||
#ifndef Q_UNSAFE
|
||||
m_eQueue.m_nFree_dis = static_cast<QEQueueCtr>(~tmp);
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
if (m_eQueue.m_nMin > tmp) {
|
||||
m_eQueue.m_nMin = tmp; // update minimum so far
|
||||
}
|
||||
|
||||
QS_BEGIN_PRE(QS_QF_ACTIVE_POST, m_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(this); // this active object
|
||||
QS_2U8_PRE(e->getPoolNum_(), e->refCtr_);
|
||||
QS_EQC_PRE(tmp); // # free entries
|
||||
QS_EQC_PRE(m_eQueue.m_nMin); // min # free entries
|
||||
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 ('m_prio') is set
|
||||
if (QS_LOC_CHECK_(m_prio)) {
|
||||
QF_MEM_APP();
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
QS::onTestPost(sender, this, e, status);
|
||||
|
||||
QF_CRIT_ENTRY();
|
||||
QF_MEM_SYS();
|
||||
}
|
||||
#endif // def Q_UTEST
|
||||
|
||||
if (m_eQueue.m_frontEvt == nullptr) { // is the queue empty?
|
||||
m_eQueue.m_frontEvt = e; // deliver event directly
|
||||
#ifndef Q_UNSAFE
|
||||
Q_INVARIANT_INCRIT(211, m_eQueue.m_frontEvt_dis
|
||||
== static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(nullptr)));
|
||||
m_eQueue.m_frontEvt_dis =
|
||||
static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(e));
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
#ifdef QXK_HPP_
|
||||
if (m_state.act == nullptr) { // eXtended thread?
|
||||
QXTHREAD_EQUEUE_SIGNAL_(this); // signal eXtended Thread
|
||||
}
|
||||
else {
|
||||
QACTIVE_EQUEUE_SIGNAL_(this); // signal the Active Object
|
||||
}
|
||||
#else
|
||||
QACTIVE_EQUEUE_SIGNAL_(this); // signal the Active Object
|
||||
#endif // def QXK_HPP_
|
||||
}
|
||||
else { // queue was not empty, insert event into the ring-buffer
|
||||
tmp = m_eQueue.m_head; // get volatile into temporary
|
||||
#ifndef Q_UNSAFE
|
||||
dis = static_cast<QEQueueCtr>(~m_eQueue.m_head_dis);
|
||||
Q_INVARIANT_INCRIT(212, tmp == dis);
|
||||
#endif // ndef Q_UNSAFE
|
||||
m_eQueue.m_ring[tmp] = e; // insert e into buffer
|
||||
|
||||
if (tmp == 0U) { // need to wrap the head?
|
||||
tmp = m_eQueue.m_end;
|
||||
}
|
||||
--tmp; // advance the head (counter-clockwise)
|
||||
|
||||
m_eQueue.m_head = tmp; // update the original
|
||||
#ifndef Q_UNSAFE
|
||||
m_eQueue.m_head_dis = static_cast<QEQueueCtr>(~tmp);
|
||||
#endif // ndef Q_UNSAFE
|
||||
}
|
||||
|
||||
QF_MEM_APP();
|
||||
postFIFO_(e, sender);
|
||||
QF_CRIT_EXIT();
|
||||
}
|
||||
else { // event cannot be posted
|
||||
|
||||
QS_BEGIN_PRE(QS_QF_ACTIVE_POST_ATTEMPT, m_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(this); // this active object
|
||||
QS_2U8_PRE(e->getPoolNum_(), e->refCtr_);
|
||||
QS_EQC_PRE(tmp); // # free entries
|
||||
QS_OBJ_PRE(this); // 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()
|
||||
|
||||
#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 ('m_prio') is set
|
||||
#ifdef Q_UTEST
|
||||
if (QS_LOC_CHECK_(m_prio)) {
|
||||
QF_MEM_APP();
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
QS::onTestPost(sender, this, e, status);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
} // namespace QP
|
||||
//$enddef${QF::QActive::post_} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
//$define${QF::QActive::postLIFO} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
namespace QP {
|
||||
|
||||
//${QF::QActive::postLIFO} ...................................................
|
||||
//............................................................................
|
||||
void QActive::postLIFO(QEvt const * const e) noexcept {
|
||||
#ifdef Q_UTEST // test?
|
||||
#if (Q_UTEST != 0) // testing QP-stub?
|
||||
#ifdef Q_UTEST // test?
|
||||
#if (Q_UTEST != 0) // testing QP-stub?
|
||||
if (m_temp.fun == Q_STATE_CAST(0)) { // QActiveDummy?
|
||||
static_cast<QActiveDummy *>(this)->QActiveDummy::fakePostLIFO(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 != nullptr);
|
||||
|
||||
QEQueueCtr tmp = m_eQueue.m_nFree; // get volatile into temporary
|
||||
#ifndef Q_UNSAFE
|
||||
QEQueueCtr dis = static_cast<QEQueueCtr>(~m_eQueue.m_nFree_dis);
|
||||
Q_INVARIANT_INCRIT(301, e->verify_() && (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 (e->getPoolNum_() != 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
|
||||
}
|
||||
|
||||
--tmp; // one free entry just used up
|
||||
|
||||
m_eQueue.m_nFree = tmp; // update the original
|
||||
#ifndef Q_UNSAFE
|
||||
m_eQueue.m_nFree_dis = static_cast<QEQueueCtr>(~tmp);
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
if (m_eQueue.m_nMin > tmp) {
|
||||
m_eQueue.m_nMin = tmp; // update minimum so far
|
||||
}
|
||||
@ -294,113 +168,77 @@ void QActive::postLIFO(QEvt const * const e) noexcept {
|
||||
QS_TIME_PRE(); // timestamp
|
||||
QS_SIG_PRE(e->sig); // the signal of this event
|
||||
QS_OBJ_PRE(this); // this active object
|
||||
QS_2U8_PRE(e->getPoolNum_(), e->refCtr_);
|
||||
QS_2U8_PRE(e->poolNum_, e->refCtr_);
|
||||
QS_EQC_PRE(tmp); // # free entries
|
||||
QS_EQC_PRE(m_eQueue.m_nMin); // min # free entries
|
||||
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 ('m_prio') is set
|
||||
if (QS_LOC_CHECK_(m_prio)) {
|
||||
QF_MEM_APP();
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
QS::onTestPost(nullptr, this, e, true);
|
||||
|
||||
QF_CRIT_ENTRY();
|
||||
QF_MEM_SYS();
|
||||
}
|
||||
#endif // def Q_UTEST
|
||||
#endif // def Q_UTEST
|
||||
|
||||
QEvt const * const frontEvt = m_eQueue.m_frontEvt;
|
||||
m_eQueue.m_frontEvt = e; // deliver the event directly to the front
|
||||
#ifndef Q_UNSAFE
|
||||
m_eQueue.m_frontEvt_dis =
|
||||
static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(e));
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
if (frontEvt != nullptr) { // was the queue NOT empty?
|
||||
tmp = m_eQueue.m_tail; // get volatile into temporary;
|
||||
#ifndef Q_UNSAFE
|
||||
dis = static_cast<QEQueueCtr>(~m_eQueue.m_tail_dis);
|
||||
Q_INVARIANT_INCRIT(311, tmp == dis);
|
||||
#endif // ndef Q_UNSAFE
|
||||
++tmp;
|
||||
if (tmp == m_eQueue.m_end) { // need to wrap the tail?
|
||||
tmp = 0U; // wrap around
|
||||
}
|
||||
m_eQueue.m_tail = tmp;
|
||||
#ifndef Q_UNSAFE
|
||||
m_eQueue.m_tail_dis = static_cast<QEQueueCtr>(~tmp);
|
||||
#endif // ndef Q_UNSAFE
|
||||
m_eQueue.m_ring[tmp] = frontEvt;
|
||||
}
|
||||
else { // queue was empty
|
||||
QACTIVE_EQUEUE_SIGNAL_(this); // signal the event queue
|
||||
}
|
||||
|
||||
QF_MEM_APP();
|
||||
QF_CRIT_EXIT();
|
||||
}
|
||||
|
||||
} // namespace QP
|
||||
//$enddef${QF::QActive::postLIFO} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
//$define${QF::QActive::get_} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
namespace QP {
|
||||
|
||||
//${QF::QActive::get_} .......................................................
|
||||
//............................................................................
|
||||
QEvt const * QActive::get_() noexcept {
|
||||
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_(this); // wait for event to arrive directly
|
||||
|
||||
// always remove evt from the front
|
||||
// always remove event from the front
|
||||
QEvt const * const e = m_eQueue.m_frontEvt;
|
||||
QEQueueCtr tmp = m_eQueue.m_nFree; // get volatile into tmp
|
||||
QEQueueCtr tmp = m_eQueue.m_nFree; // get volatile into temporary
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
Q_INVARIANT_INCRIT(410, e != nullptr); // queue must NOT be empty
|
||||
Q_INVARIANT_INCRIT(411, Q_PTR2UINT_CAST_(e)
|
||||
== static_cast<std::uintptr_t>(~m_eQueue.m_frontEvt_dis));
|
||||
QEQueueCtr dis = static_cast<QEQueueCtr>(~m_eQueue.m_nFree_dis);
|
||||
Q_INVARIANT_INCRIT(412, tmp == dis);
|
||||
#endif // ndef Q_UNSAFE
|
||||
Q_REQUIRE_INCRIT(410, e != nullptr); // queue must NOT be empty
|
||||
|
||||
++tmp; // one more free event in the queue
|
||||
|
||||
m_eQueue.m_nFree = tmp; // update the # free
|
||||
#ifndef Q_UNSAFE
|
||||
m_eQueue.m_nFree_dis = static_cast<QEQueueCtr>(~tmp);
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
if (tmp <= m_eQueue.m_end) { // any events in the ring buffer?
|
||||
|
||||
QS_BEGIN_PRE(QS_QF_ACTIVE_GET, m_prio)
|
||||
QS_TIME_PRE(); // timestamp
|
||||
QS_SIG_PRE(e->sig); // the signal of this event
|
||||
QS_OBJ_PRE(this); // this active object
|
||||
QS_2U8_PRE(e->getPoolNum_(), e->refCtr_);
|
||||
QS_2U8_PRE(e->poolNum_, e->refCtr_);
|
||||
QS_EQC_PRE(tmp); // # free entries
|
||||
QS_END_PRE()
|
||||
|
||||
// remove event from the tail
|
||||
tmp = m_eQueue.m_tail; // get volatile into temporary
|
||||
#ifndef Q_UNSAFE
|
||||
dis = static_cast<QEQueueCtr>(~m_eQueue.m_tail_dis);
|
||||
Q_INVARIANT_INCRIT(420, tmp == dis);
|
||||
#endif // ndef Q_UNSAFE
|
||||
QEvt const * const frontEvt = m_eQueue.m_ring[tmp];
|
||||
#ifndef Q_UNSAFE
|
||||
Q_ASSERT_INCRIT(421, frontEvt != nullptr);
|
||||
m_eQueue.m_frontEvt_dis =
|
||||
static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(frontEvt));
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
Q_ASSERT_INCRIT(430, frontEvt != nullptr);
|
||||
m_eQueue.m_frontEvt = frontEvt; // update the original
|
||||
|
||||
if (tmp == 0U) { // need to wrap the tail?
|
||||
@ -409,54 +247,100 @@ QEvt const * QActive::get_() noexcept {
|
||||
--tmp; // advance the tail (counter-clockwise)
|
||||
|
||||
m_eQueue.m_tail = tmp; // update the original
|
||||
#ifndef Q_UNSAFE
|
||||
m_eQueue.m_tail_dis = static_cast<QEQueueCtr>(~tmp);
|
||||
#endif // ndef Q_UNSAFE
|
||||
}
|
||||
else {
|
||||
m_eQueue.m_frontEvt = nullptr; // the queue becomes empty
|
||||
#ifndef Q_UNSAFE
|
||||
m_eQueue.m_frontEvt_dis =
|
||||
static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(nullptr));
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
// all entries in the queue must be free (+1 for fronEvt)
|
||||
Q_ASSERT_INCRIT(310, tmp == (m_eQueue.m_end + 1U));
|
||||
Q_ASSERT_INCRIT(440, tmp == (m_eQueue.m_end + 1U));
|
||||
|
||||
QS_BEGIN_PRE(QS_QF_ACTIVE_GET_LAST, m_prio)
|
||||
QS_TIME_PRE(); // timestamp
|
||||
QS_SIG_PRE(e->sig); // the signal of this event
|
||||
QS_OBJ_PRE(this); // this active object
|
||||
QS_2U8_PRE(e->getPoolNum_(), e->refCtr_);
|
||||
QS_2U8_PRE(e->poolNum_, e->refCtr_);
|
||||
QS_END_PRE()
|
||||
}
|
||||
|
||||
QF_MEM_APP();
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
} // namespace QP
|
||||
//$enddef${QF::QActive::get_} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//............................................................................
|
||||
void QActive::postFIFO_(
|
||||
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
|
||||
|
||||
//$define${QF::QTicker} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
namespace QP {
|
||||
QEQueueCtr tmp = m_eQueue.m_nFree; // get volatile into temporary
|
||||
--tmp; // one free entry just used up
|
||||
|
||||
//${QF::QTicker} .............................................................
|
||||
m_eQueue.m_nFree = tmp; // update the original
|
||||
if (m_eQueue.m_nMin > tmp) {
|
||||
m_eQueue.m_nMin = tmp; // update minimum so far
|
||||
}
|
||||
|
||||
QS_BEGIN_PRE(QS_QF_ACTIVE_POST, m_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(this); // this active object (recipient)
|
||||
QS_2U8_PRE(e->poolNum_, e->refCtr_);
|
||||
QS_EQC_PRE(tmp); // # free entries
|
||||
QS_EQC_PRE(m_eQueue.m_nMin); // min # free entries
|
||||
QS_END_PRE()
|
||||
|
||||
#ifdef Q_UTEST
|
||||
if (QS_LOC_CHECK_(m_prio)) {
|
||||
QF_CRIT_EXIT();
|
||||
QS::onTestPost(sender, this, e, true); // QUTEst callback
|
||||
QF_CRIT_ENTRY();
|
||||
}
|
||||
#endif // def Q_UTEST
|
||||
|
||||
if (m_eQueue.m_frontEvt == nullptr) { // is the queue empty?
|
||||
m_eQueue.m_frontEvt = e; // deliver event directly
|
||||
|
||||
#ifdef QXK_HPP_
|
||||
if (m_state.act == nullptr) { // eXtended thread?
|
||||
QXTHREAD_EQUEUE_SIGNAL_(this); // signal eXtended Thread
|
||||
}
|
||||
else {
|
||||
QACTIVE_EQUEUE_SIGNAL_(this); // signal the Active Object
|
||||
}
|
||||
#else
|
||||
QACTIVE_EQUEUE_SIGNAL_(this); // signal the Active Object
|
||||
#endif // def QXK_HPP_
|
||||
}
|
||||
else { // queue was not empty, insert event into the ring-buffer
|
||||
tmp = m_eQueue.m_head; // get volatile into temporary
|
||||
m_eQueue.m_ring[tmp] = e; // insert e into buffer
|
||||
|
||||
if (tmp == 0U) { // need to wrap the head?
|
||||
tmp = m_eQueue.m_end;
|
||||
}
|
||||
--tmp; // advance the head (counter-clockwise)
|
||||
|
||||
m_eQueue.m_head = tmp; // update the original
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
|
||||
//${QF::QTicker::QTicker} ....................................................
|
||||
QTicker::QTicker(std::uint_fast8_t const tickRate) noexcept
|
||||
: QActive(nullptr)
|
||||
{
|
||||
// reuse m_head for tick-rate
|
||||
m_eQueue.m_head = static_cast<QEQueueCtr>(tickRate);
|
||||
#ifndef Q_UNSAFE
|
||||
m_eQueue.m_head_dis = static_cast<QEQueueCtr>(~tickRate);
|
||||
#endif // ndef Q_UNSAFE
|
||||
}
|
||||
|
||||
//${QF::QTicker::init} .......................................................
|
||||
//............................................................................
|
||||
void QTicker::init(
|
||||
void const * const e,
|
||||
std::uint_fast8_t const qsId)
|
||||
@ -466,18 +350,11 @@ void QTicker::init(
|
||||
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
QF_MEM_SYS();
|
||||
|
||||
m_eQueue.m_tail = 0U;
|
||||
#ifndef Q_UNSAFE
|
||||
m_eQueue.m_tail_dis = static_cast<QEQueueCtr>(~0U);
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
QF_MEM_APP();
|
||||
QF_CRIT_EXIT();
|
||||
}
|
||||
|
||||
//${QF::QTicker::dispatch} ...................................................
|
||||
//............................................................................
|
||||
void QTicker::dispatch(
|
||||
QEvt const * const e,
|
||||
std::uint_fast8_t const qsId)
|
||||
@ -487,26 +364,13 @@ void QTicker::dispatch(
|
||||
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
QF_MEM_SYS();
|
||||
|
||||
// get volatile into temporaries
|
||||
QEQueueCtr nTicks = m_eQueue.m_tail;
|
||||
QEQueueCtr const tickRate = m_eQueue.m_head;
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
Q_REQUIRE_INCRIT(700, nTicks > 0U);
|
||||
Q_INVARIANT_INCRIT(701, nTicks
|
||||
== static_cast<QEQueueCtr>(~m_eQueue.m_tail_dis));
|
||||
Q_INVARIANT_INCRIT(702, tickRate
|
||||
== static_cast<QEQueueCtr>(~m_eQueue.m_head_dis));
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
Q_REQUIRE_INCRIT(800, nTicks > 0U);
|
||||
m_eQueue.m_tail = 0U; // clear # ticks
|
||||
#ifndef Q_UNSAFE
|
||||
m_eQueue.m_tail_dis = static_cast<QEQueueCtr>(~0U);
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
QF_MEM_APP();
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
for (; nTicks > 0U; --nTicks) {
|
||||
@ -515,61 +379,37 @@ void QTicker::dispatch(
|
||||
}
|
||||
}
|
||||
|
||||
//${QF::QTicker::trig_} ......................................................
|
||||
//............................................................................
|
||||
void QTicker::trig_(void const * const sender) noexcept {
|
||||
#ifndef Q_SPY
|
||||
#ifndef Q_SPY
|
||||
Q_UNUSED_PAR(sender);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static QEvt const tickEvt(0U); // immutable event
|
||||
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
QF_MEM_SYS();
|
||||
|
||||
QEQueueCtr nTicks = m_eQueue.m_tail; // get volatile into temporary
|
||||
|
||||
if (m_eQueue.m_frontEvt == nullptr) {
|
||||
#ifndef Q_UNSAFE
|
||||
Q_REQUIRE_INCRIT(800, nTicks == 0U);
|
||||
Q_REQUIRE_INCRIT(801, m_eQueue.m_nFree == 1U);
|
||||
Q_INVARIANT_INCRIT(802, m_eQueue.m_frontEvt_dis
|
||||
== static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(nullptr)));
|
||||
Q_INVARIANT_INCRIT(803,
|
||||
1U == static_cast<QEQueueCtr>(~m_eQueue.m_nFree_dis));
|
||||
Q_INVARIANT_INCRIT(804,
|
||||
0U == static_cast<QEQueueCtr>(~m_eQueue.m_tail_dis));
|
||||
#endif // ndef Q_UNSAFE
|
||||
Q_REQUIRE_INCRIT(900,
|
||||
(m_eQueue.m_nFree == 1U)
|
||||
&& (nTicks == 0U));
|
||||
|
||||
m_eQueue.m_frontEvt = &tickEvt; // deliver event directly
|
||||
m_eQueue.m_nFree = 0U;
|
||||
#ifndef Q_UNSAFE
|
||||
m_eQueue.m_frontEvt_dis =
|
||||
static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(&tickEvt));
|
||||
m_eQueue.m_nFree_dis = static_cast<QEQueueCtr>(~0U);
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
QACTIVE_EQUEUE_SIGNAL_(this); // signal the event queue
|
||||
}
|
||||
else {
|
||||
#ifndef Q_UNSAFE
|
||||
Q_REQUIRE_INCRIT(810, (nTicks > 0U) && (nTicks < 0xFFU));
|
||||
Q_REQUIRE_INCRIT(811, m_eQueue.m_nFree == 0U);
|
||||
Q_INVARIANT_INCRIT(812, m_eQueue.m_frontEvt_dis
|
||||
== static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(&tickEvt)));
|
||||
Q_INVARIANT_INCRIT(813,
|
||||
0U == static_cast<QEQueueCtr>(~m_eQueue.m_nFree_dis));
|
||||
Q_INVARIANT_INCRIT(814,
|
||||
nTicks == static_cast<QEQueueCtr>(~m_eQueue.m_tail_dis));
|
||||
#endif // ndef Q_UNSAFE
|
||||
Q_REQUIRE_INCRIT(910, (nTicks > 0U) && (nTicks < 0xFFU));
|
||||
Q_REQUIRE_INCRIT(920, m_eQueue.m_nFree == 0U);
|
||||
}
|
||||
|
||||
++nTicks; // account for one more tick event
|
||||
|
||||
m_eQueue.m_tail = nTicks; // update the original
|
||||
#ifndef Q_UNSAFE
|
||||
m_eQueue.m_tail_dis = static_cast<QEQueueCtr>(~nTicks);
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
QS_BEGIN_PRE(QS_QF_ACTIVE_POST, m_prio)
|
||||
QS_TIME_PRE(); // timestamp
|
||||
@ -581,9 +421,7 @@ void QTicker::trig_(void const * const sender) noexcept {
|
||||
QS_EQC_PRE(0U); // min # free entries
|
||||
QS_END_PRE()
|
||||
|
||||
QF_MEM_APP();
|
||||
QF_CRIT_EXIT();
|
||||
}
|
||||
|
||||
} // namespace QP
|
||||
//$enddef${QF::QTicker} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -1,10 +1,6 @@
|
||||
//$file${src::qf::qf_defer.cpp} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
//
|
||||
// Model: qpcpp.qm
|
||||
// File: ${src::qf::qf_defer.cpp}
|
||||
//
|
||||
// This code has been generated by QM 7.0.0 <www.state-machine.com/qm>.
|
||||
// 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,8 +10,8 @@
|
||||
//
|
||||
// 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-
|
||||
// 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.
|
||||
@ -30,8 +26,7 @@
|
||||
// Quantum Leaps contact information:
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//
|
||||
//$endhead${src::qf::qf_defer.cpp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//============================================================================
|
||||
#define QP_IMPL // this is QP implementation
|
||||
#include "qp_port.hpp" // QP port
|
||||
#include "qp_pkg.hpp" // QP package-scope interface
|
||||
@ -48,16 +43,9 @@ namespace {
|
||||
Q_DEFINE_THIS_MODULE("qf_defer")
|
||||
} // unnamed namespace
|
||||
|
||||
//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
// Check for the minimum required QP version
|
||||
#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U)%0x2710U))
|
||||
#error qpcpp version 7.3.0 or higher required
|
||||
#endif
|
||||
//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//$define${QF::QActive::defer} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
namespace QP {
|
||||
|
||||
//${QF::QActive::defer} ......................................................
|
||||
//............................................................................
|
||||
bool QActive::defer(
|
||||
QEQueue * const eq,
|
||||
QEvt const * const e) const noexcept
|
||||
@ -66,27 +54,19 @@ bool QActive::defer(
|
||||
|
||||
QS_CRIT_STAT
|
||||
QS_CRIT_ENTRY();
|
||||
QS_MEM_SYS();
|
||||
QS_BEGIN_PRE(QS_QF_ACTIVE_DEFER, m_prio)
|
||||
QS_TIME_PRE(); // time stamp
|
||||
QS_OBJ_PRE(this); // this active object
|
||||
QS_OBJ_PRE(eq); // the deferred queue
|
||||
QS_SIG_PRE(e->sig); // the signal of the event
|
||||
QS_2U8_PRE(e->getPoolNum_(), e->refCtr_);
|
||||
QS_2U8_PRE(e->poolNum_, e->refCtr_);
|
||||
QS_END_PRE()
|
||||
QS_MEM_APP();
|
||||
QS_CRIT_EXIT();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
} // namespace QP
|
||||
//$enddef${QF::QActive::defer} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
//$define${QF::QActive::recall} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
namespace QP {
|
||||
|
||||
//${QF::QActive::recall} .....................................................
|
||||
//............................................................................
|
||||
bool QActive::recall(QEQueue * const eq) noexcept {
|
||||
QEvt const * const e = eq->get(m_prio); // get evt from deferred queue
|
||||
QF_CRIT_STAT
|
||||
@ -96,15 +76,14 @@ bool QActive::recall(QEQueue * const eq) noexcept {
|
||||
postLIFO(e); // post it to the _front_ of the AO's queue
|
||||
|
||||
QF_CRIT_ENTRY();
|
||||
QF_MEM_SYS();
|
||||
|
||||
if (e->getPoolNum_() != 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.
|
||||
@ -116,17 +95,15 @@ bool QActive::recall(QEQueue * const eq) noexcept {
|
||||
QS_OBJ_PRE(this); // this active object
|
||||
QS_OBJ_PRE(eq); // the deferred queue
|
||||
QS_SIG_PRE(e->sig); // the signal of the event
|
||||
QS_2U8_PRE(e->getPoolNum_(), 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, m_prio)
|
||||
QS_TIME_PRE(); // time stamp
|
||||
@ -134,7 +111,6 @@ bool QActive::recall(QEQueue * const eq) noexcept {
|
||||
QS_OBJ_PRE(eq); // the deferred queue
|
||||
QS_END_PRE()
|
||||
|
||||
QS_MEM_APP();
|
||||
QS_CRIT_EXIT();
|
||||
|
||||
recalled = false;
|
||||
@ -142,13 +118,7 @@ bool QActive::recall(QEQueue * const eq) noexcept {
|
||||
return recalled;
|
||||
}
|
||||
|
||||
} // namespace QP
|
||||
//$enddef${QF::QActive::recall} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
//$define${QF::QActive::flushDeferred} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
namespace QP {
|
||||
|
||||
//${QF::QActive::flushDeferred} ..............................................
|
||||
//............................................................................
|
||||
std::uint_fast16_t QActive::flushDeferred(
|
||||
QEQueue * const eq,
|
||||
std::uint_fast16_t const num) const noexcept
|
||||
@ -158,9 +128,9 @@ std::uint_fast16_t QActive::flushDeferred(
|
||||
QEvt const * const e = eq->get(m_prio);
|
||||
if (e != nullptr) {
|
||||
++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;
|
||||
@ -171,4 +141,3 @@ std::uint_fast16_t QActive::flushDeferred(
|
||||
}
|
||||
|
||||
} // namespace QP
|
||||
//$enddef${QF::QActive::flushDeferred} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -1,10 +1,6 @@
|
||||
//$file${src::qf::qf_dyn.cpp} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
//
|
||||
// Model: qpcpp.qm
|
||||
// File: ${src::qf::qf_dyn.cpp}
|
||||
//
|
||||
// This code has been generated by QM 7.0.0 <www.state-machine.com/qm>.
|
||||
// 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,8 +10,8 @@
|
||||
//
|
||||
// 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-
|
||||
// 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.
|
||||
@ -30,8 +26,7 @@
|
||||
// Quantum Leaps contact information:
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//
|
||||
//$endhead${src::qf::qf_dyn.cpp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//============================================================================
|
||||
#define QP_IMPL // this is QP implementation
|
||||
#include "qp_port.hpp" // QP port
|
||||
#include "qp_pkg.hpp" // QP package-scope interface
|
||||
@ -50,17 +45,10 @@ namespace {
|
||||
Q_DEFINE_THIS_MODULE("qf_dyn")
|
||||
} // unnamed namespace
|
||||
|
||||
//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
// Check for the minimum required QP version
|
||||
#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U)%0x2710U))
|
||||
#error qpcpp version 7.3.0 or higher required
|
||||
#endif
|
||||
//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//$define${QF::QF-dyn} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
namespace QP {
|
||||
namespace QF {
|
||||
|
||||
//${QF::QF-dyn::poolInit} ....................................................
|
||||
//............................................................................
|
||||
void poolInit(
|
||||
void * const poolSto,
|
||||
std::uint_fast32_t const poolSize,
|
||||
@ -71,22 +59,20 @@ void 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_(priv_.ePool_[poolNum - 1U]) < evtSize);
|
||||
}
|
||||
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_(priv_.ePool_[poolNum], poolSto, poolSize, evtSize);
|
||||
|
||||
#ifdef Q_SPY
|
||||
#ifdef Q_SPY
|
||||
// generate the object-dictionary entry for the initialized pool
|
||||
{
|
||||
std::uint8_t obj_name[9] = "EvtPool?";
|
||||
@ -96,41 +82,37 @@ void poolInit(
|
||||
QS::obj_dict_pre_(&priv_.ePool_[poolNum],
|
||||
reinterpret_cast<char *>(&obj_name[0]));
|
||||
}
|
||||
#endif // Q_SPY
|
||||
#endif // Q_SPY
|
||||
}
|
||||
|
||||
//${QF::QF-dyn::poolGetMaxBlockSize} .........................................
|
||||
//............................................................................
|
||||
std::uint_fast16_t poolGetMaxBlockSize() noexcept {
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
QF_MEM_SYS();
|
||||
std::uint_fast16_t const max_size =
|
||||
QF_EPOOL_EVENT_SIZE_(priv_.ePool_[priv_.maxPool_ - 1U]);
|
||||
QF_MEM_APP();
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
return max_size;
|
||||
}
|
||||
|
||||
//${QF::QF-dyn::getPoolMin} ..................................................
|
||||
//............................................................................
|
||||
std::uint_fast16_t getPoolMin(std::uint_fast8_t const poolNum) noexcept {
|
||||
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 <= priv_.maxPool_));
|
||||
|
||||
std::uint_fast16_t const min = static_cast<std::uint_fast16_t>(
|
||||
priv_.ePool_[poolNum - 1U].getNMin());
|
||||
|
||||
QF_MEM_APP();
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
return min;
|
||||
}
|
||||
|
||||
//${QF::QF-dyn::newX_} .......................................................
|
||||
//............................................................................
|
||||
QEvt * newX_(
|
||||
std::uint_fast16_t const evtSize,
|
||||
std::uint_fast16_t const margin,
|
||||
@ -138,10 +120,9 @@ QEvt * newX_(
|
||||
{
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
QF_MEM_SYS();
|
||||
|
||||
// find the pool id that fits the requested event size...
|
||||
std::uint_fast8_t poolNum = 0U; // zero-based poolNum initially
|
||||
std::uint8_t poolNum = 0U; // zero-based poolNum initially
|
||||
for (; poolNum < priv_.maxPool_; ++poolNum) {
|
||||
if (evtSize <= QF_EPOOL_EVENT_SIZE_(priv_.ePool_[poolNum])) {
|
||||
break;
|
||||
@ -150,38 +131,35 @@ QEvt * newX_(
|
||||
|
||||
// precondition:
|
||||
// - cannot run out of registered pools
|
||||
Q_REQUIRE_INCRIT(300, poolNum < priv_.maxPool_);
|
||||
Q_REQUIRE_INCRIT(400, poolNum < priv_.maxPool_);
|
||||
|
||||
++poolNum; // convert to 1-based poolNum
|
||||
|
||||
QF_MEM_APP();
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
// get event e (port-dependent)...
|
||||
QEvt *e;
|
||||
#ifdef Q_SPY
|
||||
// get event `e` out of the event pool (port-dependent)...
|
||||
QEvt *e = nullptr;
|
||||
#ifdef Q_SPY
|
||||
QF_EPOOL_GET_(priv_.ePool_[poolNum - 1U], e,
|
||||
((margin != NO_MARGIN) ? margin : 0U),
|
||||
static_cast<std::uint_fast8_t>(QS_EP_ID) + poolNum);
|
||||
#else
|
||||
#else
|
||||
QF_EPOOL_GET_(priv_.ePool_[poolNum - 1U], e,
|
||||
((margin != NO_MARGIN) ? margin : 0U), 0U);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (e != nullptr) { // was e allocated correctly?
|
||||
e->sig = static_cast<QSignal>(sig); // set the signal
|
||||
e->evtTag_ = static_cast<std::uint8_t>((poolNum << 4U) | 0x0FU);
|
||||
e->refCtr_ = 0U; // initialize the reference counter to 0
|
||||
e->sig = static_cast<QSignal>(sig); // set the signal
|
||||
e->poolNum_ = poolNum;
|
||||
e->refCtr_ = 0U; // initialize the reference counter to 0
|
||||
|
||||
QS_CRIT_ENTRY();
|
||||
QS_MEM_SYS();
|
||||
QS_BEGIN_PRE(QS_QF_NEW,
|
||||
static_cast<std::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
|
||||
@ -190,16 +168,14 @@ QEvt * 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 != NO_MARGIN);
|
||||
Q_ASSERT_INCRIT(420, margin != NO_MARGIN);
|
||||
|
||||
QS_MEM_SYS();
|
||||
QS_BEGIN_PRE(QS_QF_NEW_ATTEMPT,
|
||||
static_cast<std::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();
|
||||
}
|
||||
@ -209,17 +185,16 @@ QEvt * newX_(
|
||||
return e;
|
||||
}
|
||||
|
||||
//${QF::QF-dyn::gc} ..........................................................
|
||||
//............................................................................
|
||||
void gc(QEvt const * const e) noexcept {
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
Q_REQUIRE_INCRIT(400, e != nullptr);
|
||||
Q_INVARIANT_INCRIT(401, e->verify_());
|
||||
|
||||
std::uint_fast8_t const poolNum = e->getPoolNum_();
|
||||
Q_REQUIRE_INCRIT(500, e != nullptr);
|
||||
|
||||
std::uint_fast8_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?
|
||||
|
||||
@ -230,9 +205,9 @@ void gc(QEvt const * const e) noexcept {
|
||||
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
|
||||
@ -245,20 +220,19 @@ void gc(QEvt const * const e) noexcept {
|
||||
QS_END_PRE()
|
||||
|
||||
// pool number must be in range
|
||||
Q_ASSERT_INCRIT(410, (poolNum <= priv_.maxPool_)
|
||||
Q_ASSERT_INCRIT(510, (poolNum <= 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
|
||||
#ifdef Q_SPY
|
||||
QF_EPOOL_PUT_(priv_.ePool_[poolNum - 1U],
|
||||
QF_CONST_CAST_(QEvt*, e),
|
||||
static_cast<std::uint_fast8_t>(QS_EP_ID) + poolNum);
|
||||
#else
|
||||
#else
|
||||
QF_EPOOL_PUT_(priv_.ePool_[poolNum - 1U],
|
||||
QF_CONST_CAST_(QEvt*, e), 0U);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -266,74 +240,68 @@ void gc(QEvt const * const e) noexcept {
|
||||
}
|
||||
}
|
||||
|
||||
//${QF::QF-dyn::newRef_} .....................................................
|
||||
//............................................................................
|
||||
QEvt const * newRef_(
|
||||
QEvt const * const e,
|
||||
QEvt const * const evtRef) noexcept
|
||||
{
|
||||
#ifdef Q_UNSAFE
|
||||
#ifdef Q_UNSAFE
|
||||
Q_UNUSED_PAR(evtRef);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
|
||||
Q_REQUIRE_INCRIT(500, e != nullptr);
|
||||
Q_INVARIANT_INCRIT(501, e->verify_());
|
||||
Q_REQUIRE_INCRIT(600, e != nullptr);
|
||||
|
||||
std::uint_fast8_t const poolNum = e->getPoolNum_();
|
||||
std::uint_fast8_t const poolNum = e->poolNum_;
|
||||
Q_UNUSED_PAR(poolNum); // might be unused
|
||||
|
||||
Q_REQUIRE_INCRIT(501, (poolNum != 0U)
|
||||
Q_REQUIRE_INCRIT(610, (poolNum != 0U)
|
||||
&& (evtRef == nullptr));
|
||||
|
||||
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,
|
||||
static_cast<std::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_} ..................................................
|
||||
//............................................................................
|
||||
void deleteRef_(QEvt const * const evtRef) noexcept {
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
|
||||
QEvt const * const e = evtRef;
|
||||
Q_REQUIRE_INCRIT(600, e != nullptr);
|
||||
Q_INVARIANT_INCRIT(601, e->verify_());
|
||||
Q_REQUIRE_INCRIT(700, e != nullptr);
|
||||
|
||||
#ifdef Q_SPY
|
||||
std::uint_fast8_t const poolNum = e->getPoolNum_();
|
||||
#endif
|
||||
#ifdef Q_SPY
|
||||
std::uint_fast8_t const poolNum = e->poolNum_;
|
||||
|
||||
QS_MEM_SYS();
|
||||
QS_BEGIN_PRE(QS_QF_DELETE_REF,
|
||||
static_cast<std::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)
|
||||
#if (QF_MAX_EPOOL > 0U)
|
||||
gc(e); // recycle the referenced event
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace QF
|
||||
} // namespace QP
|
||||
//$enddef${QF::QF-dyn} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
#endif // (QF_MAX_EPOOL > 0U) mutable events configured
|
||||
|
@ -1,10 +1,6 @@
|
||||
//$file${src::qf::qf_mem.cpp} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
//
|
||||
// Model: qpcpp.qm
|
||||
// File: ${src::qf::qf_mem.cpp}
|
||||
//
|
||||
// This code has been generated by QM 7.0.0 <www.state-machine.com/qm>.
|
||||
// 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,8 +10,8 @@
|
||||
//
|
||||
// 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-
|
||||
// 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.
|
||||
@ -30,15 +26,14 @@
|
||||
// Quantum Leaps contact information:
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//
|
||||
//$endhead${src::qf::qf_mem.cpp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//============================================================================
|
||||
#define QP_IMPL // this is QP implementation
|
||||
#include "qp_port.hpp" // QP port
|
||||
#include "qp_pkg.hpp" // QP package-scope interface
|
||||
#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem
|
||||
#ifdef Q_SPY // QS software tracing enabled?
|
||||
#include "qs_port.hpp" // QS port
|
||||
#include "qs_pkg.hpp" // QS facilities for pre-defined trace records
|
||||
#include "qs_pkg.hpp" // QS package-scope internal interface
|
||||
#else
|
||||
#include "qs_dummy.hpp" // disable the QS software tracing
|
||||
#endif // Q_SPY
|
||||
@ -48,18 +43,9 @@ namespace {
|
||||
Q_DEFINE_THIS_MODULE("qf_mem")
|
||||
} // unnamed namespace
|
||||
|
||||
//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
// Check for the minimum required QP version
|
||||
#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U)%0x2710U))
|
||||
#error qpcpp version 7.3.0 or higher required
|
||||
#endif
|
||||
//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//$define${QF::QMPool} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
namespace QP {
|
||||
|
||||
//${QF::QMPool} ..............................................................
|
||||
|
||||
//${QF::QMPool::init} ........................................................
|
||||
//............................................................................
|
||||
void QMPool::init(
|
||||
void * const poolSto,
|
||||
std::uint_fast32_t const poolSize,
|
||||
@ -67,30 +53,24 @@ void QMPool::init(
|
||||
{
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
QF_MEM_SYS();
|
||||
|
||||
Q_REQUIRE_INCRIT(100, poolSto != nullptr);
|
||||
Q_REQUIRE_INCRIT(101,
|
||||
poolSize >= static_cast<std::uint_fast32_t>(sizeof(QFreeBlock)));
|
||||
Q_REQUIRE_INCRIT(102,
|
||||
static_cast<std::uint_fast16_t>(blockSize + sizeof(QFreeBlock))
|
||||
> blockSize);
|
||||
|
||||
m_free_head = static_cast<QFreeBlock *>(poolSto);
|
||||
m_freeHead = static_cast<void * *>(poolSto);
|
||||
|
||||
// find # free blocks in a memory block, NO DIVISION
|
||||
// find # free links in a memory block, see NOTE1
|
||||
m_blockSize = static_cast<QMPoolSize>(2U * sizeof(void *));
|
||||
std::uint_fast16_t nblocks = 1U;
|
||||
std::uint_fast16_t inext = 2U;
|
||||
while (m_blockSize < static_cast<QMPoolSize>(blockSize)) {
|
||||
m_blockSize += static_cast<QMPoolSize>(sizeof(QFreeBlock));
|
||||
++nblocks;
|
||||
m_blockSize += static_cast<QMPoolSize>(sizeof(void *));
|
||||
++inext;
|
||||
}
|
||||
|
||||
// the pool buffer must fit at least one rounded-up block
|
||||
Q_ASSERT_INCRIT(110, poolSize >= m_blockSize);
|
||||
|
||||
// start at the head of the free list
|
||||
QFreeBlock *fb = m_free_head;
|
||||
void * *pfb = m_freeHead; // pointer to free block
|
||||
std::uint32_t nTot = 1U; // the last block already in the list
|
||||
|
||||
// chain all blocks together in a free-list...
|
||||
@ -98,179 +78,125 @@ void QMPool::init(
|
||||
size >= static_cast<std::uint_fast32_t>(m_blockSize);
|
||||
size -= static_cast<std::uint_fast32_t>(m_blockSize))
|
||||
{
|
||||
fb->m_next = &fb[nblocks]; // point next link to next block
|
||||
#ifndef Q_UNSAFE
|
||||
fb->m_next_dis = ~Q_PTR2UINT_CAST_(fb->m_next);
|
||||
#endif
|
||||
fb = fb->m_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 = static_cast<void * *>(pfb[0]); // advance to the next block
|
||||
++nTot; // one more free block in the pool
|
||||
}
|
||||
pfb[0] = nullptr; // 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->m_next = nullptr; // 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
|
||||
|
||||
m_nTot = static_cast<QMPoolCtr>(nTot);
|
||||
m_nFree = m_nTot; // all blocks are free
|
||||
m_start = static_cast<QFreeBlock *>(poolSto); // original start
|
||||
m_end = fb; // the last block in this pool
|
||||
m_nFree = m_nTot; // all blocks are free
|
||||
m_start = static_cast<void * *>(poolSto); // original start
|
||||
m_end = pfb; // the last block in this pool
|
||||
m_nMin = m_nTot; // the minimum # free blocks
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
m_free_head_dis =
|
||||
static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(m_free_head));
|
||||
m_nFree_dis = static_cast<QMPoolCtr>(~m_nFree);
|
||||
m_nMin = m_nTot; // the minimum # free blocks
|
||||
fb->m_next_dis = ~Q_PTR2UINT_CAST_(fb->m_next);
|
||||
#endif
|
||||
|
||||
QF_MEM_APP();
|
||||
QF_CRIT_EXIT();
|
||||
}
|
||||
|
||||
//${QF::QMPool::get} .........................................................
|
||||
//............................................................................
|
||||
void * QMPool::get(
|
||||
std::uint_fast16_t const margin,
|
||||
std::uint_fast8_t const qsId) noexcept
|
||||
{
|
||||
#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 = m_free_head;
|
||||
void * *pfb = m_freeHead; // pointer to free block
|
||||
QMPoolCtr nFree = m_nFree;
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
Q_INVARIANT_INCRIT(301, Q_PTR2UINT_CAST_(fb)
|
||||
== static_cast<std::uintptr_t>(~m_free_head_dis));
|
||||
Q_INVARIANT_INCRIT(302, nFree == static_cast<QMPoolCtr>(~m_nFree_dis));
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
// have more free blocks than the requested margin?
|
||||
if (nFree > static_cast<QMPoolCtr>(margin)) {
|
||||
Q_ASSERT_INCRIT(310, fb != nullptr);
|
||||
Q_ASSERT_INCRIT(310, pfb != nullptr);
|
||||
|
||||
QFreeBlock * const fb_next = fb->m_next;
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
// the free block must have integrity (duplicate inverse storage)
|
||||
Q_INVARIANT_INCRIT(311, Q_PTR2UINT_CAST_(fb_next)
|
||||
== static_cast<std::uintptr_t>(~fb->m_next_dis));
|
||||
#endif // ndef Q_UNSAFE
|
||||
// fast temporary
|
||||
void * * const pfb_next = static_cast<void * *>(pfb[0]);
|
||||
|
||||
--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 == nullptr);
|
||||
Q_ASSERT_INCRIT(320, pfb_next == nullptr);
|
||||
|
||||
m_nFree = 0U;
|
||||
#ifndef Q_UNSAFE
|
||||
m_nFree_dis = static_cast<QMPoolCtr>(~m_nFree);
|
||||
m_nMin = 0U; // remember that the pool got empty
|
||||
#endif // ndef Q_UNSAFE
|
||||
m_nFree = 0U; // no more free blocks
|
||||
m_nMin = 0U; // remember that the pool got empty
|
||||
}
|
||||
else {
|
||||
else { // the pool is NOT empty
|
||||
|
||||
// the next free-block pointer must be in range
|
||||
Q_ASSERT_INCRIT(330, QF_PTR_RANGE_(pfb_next, m_start, m_end));
|
||||
|
||||
m_nFree = nFree; // update the original
|
||||
#ifndef Q_UNSAFE
|
||||
m_nFree_dis = static_cast<QMPoolCtr>(~nFree);
|
||||
|
||||
// The pool is not empty, so the next free-block pointer
|
||||
// must be in range.
|
||||
Q_INVARIANT_INCRIT(330,
|
||||
QF_PTR_RANGE_(fb_next, m_start, m_end));
|
||||
|
||||
// is the # free blocks the new minimum so far?
|
||||
if (m_nMin > nFree) {
|
||||
if (m_nMin > nFree) { // is this the new minimum?
|
||||
m_nMin = nFree; // remember the minimum so far
|
||||
}
|
||||
#endif // ndef Q_UNSAFE
|
||||
}
|
||||
|
||||
m_free_head = fb_next; // set the head to the next free block
|
||||
#ifndef Q_UNSAFE
|
||||
m_free_head_dis =
|
||||
static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(fb_next));
|
||||
#endif // ndef Q_UNSAFE
|
||||
m_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] = &m_end[1]; // invalid location beyond the end
|
||||
|
||||
QS_BEGIN_PRE(QS_QF_MPOOL_GET, qsId)
|
||||
QS_TIME_PRE(); // timestamp
|
||||
QS_OBJ_PRE(this); // 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(m_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 = nullptr;
|
||||
pfb = nullptr;
|
||||
|
||||
QS_BEGIN_PRE(QS_QF_MPOOL_GET_ATTEMPT, qsId)
|
||||
QS_TIME_PRE(); // timestamp
|
||||
QS_OBJ_PRE(this); // 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 nullptr to the caller
|
||||
return pfb; // return the block or nullptr to the caller
|
||||
}
|
||||
|
||||
//${QF::QMPool::put} .........................................................
|
||||
//............................................................................
|
||||
void QMPool::put(
|
||||
void * const block,
|
||||
std::uint_fast8_t const qsId) noexcept
|
||||
{
|
||||
#ifndef Q_SPY
|
||||
#ifndef Q_SPY
|
||||
Q_UNUSED_PAR(qsId);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
QFreeBlock * const fb = static_cast<QFreeBlock *>(block);
|
||||
void * * const pfb = static_cast<void * *>(block); // pointer to free block
|
||||
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
QF_MEM_SYS();
|
||||
|
||||
// get volatile into temporaries
|
||||
QFreeBlock * const free_head = m_free_head;
|
||||
void * * const freeHead = m_freeHead;
|
||||
QMPoolCtr nFree = m_nFree;
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
Q_INVARIANT_INCRIT(401, Q_PTR2UINT_CAST_(free_head)
|
||||
== static_cast<std::uintptr_t>(~m_free_head_dis));
|
||||
Q_INVARIANT_INCRIT(402, nFree == static_cast<QMPoolCtr>(~m_nFree_dis));
|
||||
|
||||
Q_REQUIRE_INCRIT(410, nFree < m_nTot);
|
||||
Q_REQUIRE_INCRIT(411, QF_PTR_RANGE_(fb, m_start, m_end));
|
||||
|
||||
// the block must not be in the pool already
|
||||
Q_REQUIRE_INCRIT(412, Q_PTR2UINT_CAST_(fb->m_next)
|
||||
!= static_cast<std::uintptr_t>(~fb->m_next_dis));
|
||||
#endif // ndef Q_UNSAFE
|
||||
Q_REQUIRE_INCRIT(400, nFree < m_nTot);
|
||||
Q_REQUIRE_INCRIT(410, QF_PTR_RANGE_(pfb, m_start, m_end));
|
||||
|
||||
++nFree; // one more free block in this pool
|
||||
|
||||
m_free_head = fb; // set as new head of the free list
|
||||
m_nFree = nFree;
|
||||
fb->m_next = free_head; // link into the list
|
||||
#ifndef Q_UNSAFE
|
||||
m_free_head_dis = static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(fb));
|
||||
m_nFree_dis = static_cast<QMPoolCtr>(~nFree);
|
||||
fb->m_next_dis = static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(free_head));
|
||||
#endif
|
||||
m_freeHead = pfb; // set as new head of the free list
|
||||
m_nFree = nFree;
|
||||
pfb[0] = freeHead; // link into the list
|
||||
|
||||
QS_BEGIN_PRE(QS_QF_MPOOL_PUT, qsId)
|
||||
QS_TIME_PRE(); // timestamp
|
||||
@ -278,14 +204,18 @@ void QMPool::put(
|
||||
QS_MPC_PRE(nFree); // the # free blocks in the pool
|
||||
QS_END_PRE()
|
||||
|
||||
QF_MEM_APP();
|
||||
QF_CRIT_EXIT();
|
||||
}
|
||||
|
||||
//${QF::QMPool::getBlockSize} ................................................
|
||||
QMPoolSize QMPool::getBlockSize() const noexcept {
|
||||
return m_blockSize;
|
||||
}
|
||||
|
||||
} // namespace QP
|
||||
//$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.
|
||||
|
126
src/qf/qf_ps.cpp
126
src/qf/qf_ps.cpp
@ -1,10 +1,6 @@
|
||||
//$file${src::qf::qf_ps.cpp} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
//
|
||||
// Model: qpcpp.qm
|
||||
// File: ${src::qf::qf_ps.cpp}
|
||||
//
|
||||
// This code has been generated by QM 7.0.0 <www.state-machine.com/qm>.
|
||||
// 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,8 +10,8 @@
|
||||
//
|
||||
// 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-
|
||||
// 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.
|
||||
@ -30,8 +26,7 @@
|
||||
// Quantum Leaps contact information:
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//
|
||||
//$endhead${src::qf::qf_ps.cpp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//============================================================================
|
||||
#define QP_IMPL // this is QP implementation
|
||||
#include "qp_port.hpp" // QP port
|
||||
#include "qp_pkg.hpp" // QP package-scope interface
|
||||
@ -48,30 +43,12 @@ namespace {
|
||||
Q_DEFINE_THIS_MODULE("qf_ps")
|
||||
} // unnamed namespace
|
||||
|
||||
//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
// Check for the minimum required QP version
|
||||
#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U)%0x2710U))
|
||||
#error qpcpp version 7.3.0 or higher required
|
||||
#endif
|
||||
//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//$define${QF::QActive::subscrList_} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
namespace QP {
|
||||
QSubscrList * QActive::subscrList_;
|
||||
|
||||
} // namespace QP
|
||||
//$enddef${QF::QActive::subscrList_} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
//$define${QF::QActive::maxPubSignal_} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
namespace QP {
|
||||
enum_t QActive::maxPubSignal_;
|
||||
|
||||
} // namespace QP
|
||||
//$enddef${QF::QActive::maxPubSignal_} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
//$define${QF::QActive::psInit} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
namespace QP {
|
||||
|
||||
//${QF::QActive::psInit} .....................................................
|
||||
//............................................................................
|
||||
void QActive::psInit(
|
||||
QSubscrList * const subscrSto,
|
||||
enum_t const maxSignal) noexcept
|
||||
@ -82,61 +59,49 @@ void QActive::psInit(
|
||||
// initialize the subscriber list
|
||||
for (enum_t sig = 0; sig < maxSignal; ++sig) {
|
||||
subscrSto[sig].m_set.setEmpty();
|
||||
#ifndef Q_UNSAFE
|
||||
subscrSto[sig].m_set.update_(&subscrSto[sig].m_set_dis);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace QP
|
||||
//$enddef${QF::QActive::psInit} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
//$define${QF::QActive::publish_} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
namespace QP {
|
||||
|
||||
//${QF::QActive::publish_} ...................................................
|
||||
//............................................................................
|
||||
void QActive::publish_(
|
||||
QEvt const * const e,
|
||||
void const * const sender,
|
||||
std::uint_fast8_t const qsId) noexcept
|
||||
{
|
||||
#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 < static_cast<QSignal>(maxPubSignal_));
|
||||
Q_INVARIANT_INCRIT(202,
|
||||
subscrList_[sig].m_set.verify_(&subscrList_[sig].m_set_dis));
|
||||
|
||||
QS_BEGIN_PRE(QS_QF_PUBLISH, qsId)
|
||||
QS_TIME_PRE(); // the timestamp
|
||||
QS_OBJ_PRE(sender); // the sender object
|
||||
QS_SIG_PRE(e->sig); // the signal of the event
|
||||
QS_2U8_PRE(e->getPoolNum_(), e->refCtr_);
|
||||
QS_2U8_PRE(e->poolNum_, e->refCtr_);
|
||||
QS_END_PRE()
|
||||
|
||||
// is it a mutable event?
|
||||
if (e->getPoolNum_() != 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 = subscrList_[sig].m_set;
|
||||
|
||||
QF_MEM_APP();
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
if (subscrSet.notEmpty()) { // any subscribers?
|
||||
@ -144,21 +109,16 @@ void QActive::publish_(
|
||||
std::uint_fast8_t p = subscrSet.findMax();
|
||||
|
||||
QF_CRIT_ENTRY();
|
||||
QF_MEM_SYS();
|
||||
|
||||
QActive *a = registry_[p];
|
||||
// the AO must be registered with the framework
|
||||
Q_ASSERT_INCRIT(210, a != nullptr);
|
||||
|
||||
QF_MEM_APP();
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
QF_SCHED_STAT_
|
||||
QF_SCHED_LOCK_(p); // lock the scheduler up to AO's prio
|
||||
std::uint_fast8_t lbound = QF_MAX_ACTIVE + 1U;
|
||||
do { // loop over all subscribers
|
||||
--lbound;
|
||||
|
||||
// POST() asserts internally if the queue overflows
|
||||
a->POST(e, sender);
|
||||
|
||||
@ -167,22 +127,20 @@ void QActive::publish_(
|
||||
p = subscrSet.findMax(); // highest-prio subscriber
|
||||
|
||||
QF_CRIT_ENTRY();
|
||||
QF_MEM_SYS();
|
||||
|
||||
a = registry_[p];
|
||||
// the AO must be registered with the framework
|
||||
Q_ASSERT_INCRIT(220, a != nullptr);
|
||||
|
||||
QF_MEM_APP();
|
||||
QF_CRIT_EXIT();
|
||||
}
|
||||
else {
|
||||
p = 0U; // no more subscribers
|
||||
}
|
||||
} while ((p != 0U) && (lbound > 0U));
|
||||
} while (p != 0U);
|
||||
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ENSURE_INCRIT(290, p == 0U);
|
||||
Q_ASSERT_INCRIT(290, p == 0U); // all subscribers processed
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
QF_SCHED_UNLOCK_(); // unlock the scheduler
|
||||
@ -191,31 +149,22 @@ void QActive::publish_(
|
||||
// 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);
|
||||
#endif
|
||||
#if (QF_MAX_EPOOL > 0U)
|
||||
QF::gc(e); // recycle the event to avoid a leak
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace QP
|
||||
//$enddef${QF::QActive::publish_} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
//$define${QF::QActive::subscribe} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
namespace QP {
|
||||
|
||||
//${QF::QActive::subscribe} ..................................................
|
||||
//............................................................................
|
||||
void QActive::subscribe(enum_t const sig) const noexcept {
|
||||
std::uint_fast8_t const p = static_cast<std::uint_fast8_t>(m_prio);
|
||||
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
QF_MEM_SYS();
|
||||
|
||||
Q_REQUIRE_INCRIT(300, (Q_USER_SIG <= sig)
|
||||
&& (sig < maxPubSignal_)
|
||||
&& (0U < p) && (p <= QF_MAX_ACTIVE)
|
||||
&& (registry_[p] == this));
|
||||
Q_INVARIANT_INCRIT(302,
|
||||
subscrList_[sig].m_set.verify_(&subscrList_[sig].m_set_dis));
|
||||
|
||||
QS_BEGIN_PRE(QS_QF_ACTIVE_SUBSCRIBE, m_prio)
|
||||
QS_TIME_PRE(); // timestamp
|
||||
@ -225,36 +174,23 @@ void QActive::subscribe(enum_t const sig) const noexcept {
|
||||
|
||||
// insert the prio. into the subscriber set
|
||||
subscrList_[sig].m_set.insert(p);
|
||||
#ifndef Q_UNSAFE
|
||||
subscrList_[sig].m_set.update_(&subscrList_[sig].m_set_dis);
|
||||
#endif
|
||||
|
||||
QF_MEM_APP();
|
||||
QF_CRIT_EXIT();
|
||||
}
|
||||
|
||||
} // namespace QP
|
||||
//$enddef${QF::QActive::subscribe} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
//$define${QF::QActive::unsubscribe} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
namespace QP {
|
||||
|
||||
//${QF::QActive::unsubscribe} ................................................
|
||||
//............................................................................
|
||||
void QActive::unsubscribe(enum_t const sig) const noexcept {
|
||||
std::uint_fast8_t const p = static_cast<std::uint_fast8_t>(m_prio);
|
||||
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
QF_MEM_SYS();
|
||||
|
||||
Q_REQUIRE_INCRIT(400, (Q_USER_SIG <= sig)
|
||||
&& (sig < maxPubSignal_)
|
||||
&& (0U < p) && (p <= QF_MAX_ACTIVE)
|
||||
&& (registry_[p] == this));
|
||||
Q_INVARIANT_INCRIT(402,
|
||||
subscrList_[sig].m_set.verify_(&subscrList_[sig].m_set_dis));
|
||||
|
||||
QS_BEGIN_PRE(QS_QF_ACTIVE_UNSUBSCRIBE, m_prio)
|
||||
QS_BEGIN_PRE(QS_QF_ACTIVE_UNSUBSCRIBE, p)
|
||||
QS_TIME_PRE(); // timestamp
|
||||
QS_SIG_PRE(sig); // the signal of this event
|
||||
QS_OBJ_PRE(this); // this active object
|
||||
@ -262,25 +198,14 @@ void QActive::unsubscribe(enum_t const sig) const noexcept {
|
||||
|
||||
// remove the prio. from the subscriber set
|
||||
subscrList_[sig].m_set.remove(p);
|
||||
#ifndef Q_UNSAFE
|
||||
subscrList_[sig].m_set.update_(&subscrList_[sig].m_set_dis);
|
||||
#endif
|
||||
|
||||
QF_MEM_APP();
|
||||
QF_CRIT_EXIT();
|
||||
}
|
||||
|
||||
} // namespace QP
|
||||
//$enddef${QF::QActive::unsubscribe} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
//$define${QF::QActive::unsubscribeAll} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
namespace QP {
|
||||
|
||||
//${QF::QActive::unsubscribeAll} .............................................
|
||||
//............................................................................
|
||||
void QActive::unsubscribeAll() const noexcept {
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
QF_MEM_SYS();
|
||||
|
||||
std::uint_fast8_t const p = static_cast<std::uint_fast8_t>(m_prio);
|
||||
|
||||
@ -288,25 +213,19 @@ void QActive::unsubscribeAll() const noexcept {
|
||||
&& (registry_[p] == this));
|
||||
enum_t const maxPubSig = maxPubSignal_;
|
||||
|
||||
QF_MEM_APP();
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
for (enum_t sig = Q_USER_SIG; sig < maxPubSig; ++sig) {
|
||||
QF_CRIT_ENTRY();
|
||||
QF_MEM_SYS();
|
||||
|
||||
if (subscrList_[sig].m_set.hasElement(p)) {
|
||||
subscrList_[sig].m_set.remove(p);
|
||||
#ifndef Q_UNSAFE
|
||||
subscrList_[sig].m_set.update_(&subscrList_[sig].m_set_dis);
|
||||
#endif
|
||||
QS_BEGIN_PRE(QS_QF_ACTIVE_UNSUBSCRIBE, m_prio)
|
||||
QS_TIME_PRE(); // timestamp
|
||||
QS_SIG_PRE(sig); // the signal of this event
|
||||
QS_OBJ_PRE(this); // this active object
|
||||
QS_END_PRE()
|
||||
}
|
||||
QF_MEM_APP();
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
QF_CRIT_EXIT_NOP(); // prevent merging critical sections
|
||||
@ -314,4 +233,3 @@ void QActive::unsubscribeAll() const noexcept {
|
||||
}
|
||||
|
||||
} // namespace QP
|
||||
//$enddef${QF::QActive::unsubscribeAll} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -1,10 +1,6 @@
|
||||
//$file${src::qf::qf_qact.cpp} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
//
|
||||
// Model: qpcpp.qm
|
||||
// File: ${src::qf::qf_qact.cpp}
|
||||
//
|
||||
// This code has been generated by QM 7.0.0 <www.state-machine.com/qm>.
|
||||
// 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,8 +10,8 @@
|
||||
//
|
||||
// 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-
|
||||
// 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.
|
||||
@ -30,8 +26,7 @@
|
||||
// Quantum Leaps contact information:
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//
|
||||
//$endhead${src::qf::qf_qact.cpp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//============================================================================
|
||||
#define QP_IMPL // this is QP implementation
|
||||
#include "qp_port.hpp" // QP port
|
||||
#include "qp_pkg.hpp" // QP package-scope interface
|
||||
@ -48,36 +43,22 @@ namespace {
|
||||
Q_DEFINE_THIS_MODULE("qf_qact")
|
||||
} // unnamed namespace
|
||||
|
||||
//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
// Check for the minimum required QP version
|
||||
#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U)%0x2710U))
|
||||
#error qpcpp version 7.3.0 or higher required
|
||||
#endif
|
||||
//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//$define${QF::QActive::QActive} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
namespace QP {
|
||||
|
||||
} // namespace QP
|
||||
//$enddef${QF::QActive::QActive} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
//$define${QF::QActive::register_} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
namespace QP {
|
||||
|
||||
//${QF::QActive::register_} ..................................................
|
||||
//............................................................................
|
||||
void QActive::register_() noexcept {
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
QF_MEM_SYS();
|
||||
|
||||
if (m_pthre == 0U) { // preemption-threshold not defined?
|
||||
m_pthre = m_prio; // apply the default
|
||||
}
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
|
||||
Q_REQUIRE_INCRIT(100, (0U < m_prio) && (m_prio <= QF_MAX_ACTIVE)
|
||||
&& (registry_[m_prio] == nullptr)
|
||||
&& (m_prio <= m_pthre));
|
||||
#ifndef Q_UNSAFE
|
||||
Q_REQUIRE_INCRIT(100,
|
||||
(0U < m_prio) && (m_prio <= QF_MAX_ACTIVE)
|
||||
&& (registry_[m_prio] == nullptr)
|
||||
&& (m_prio <= m_pthre));
|
||||
|
||||
std::uint8_t prev_thre = m_pthre;
|
||||
std::uint8_t next_thre = m_pthre;
|
||||
@ -98,43 +79,30 @@ void QActive::register_() noexcept {
|
||||
}
|
||||
}
|
||||
|
||||
Q_ASSERT_INCRIT(190, (prev_thre <= m_pthre)
|
||||
&& (m_pthre <= next_thre));
|
||||
|
||||
m_prio_dis = static_cast<std::uint8_t>(~m_prio);
|
||||
m_pthre_dis = static_cast<std::uint8_t>(~m_pthre);
|
||||
|
||||
#endif // Q_UNSAFE
|
||||
Q_ASSERT_INCRIT(190,
|
||||
(prev_thre <= m_pthre)
|
||||
&& (m_pthre <= next_thre));
|
||||
#endif // Q_UNSAFE
|
||||
|
||||
// register the AO at the QF-prio.
|
||||
registry_[m_prio] = this;
|
||||
|
||||
QF_MEM_APP();
|
||||
QF_CRIT_EXIT();
|
||||
}
|
||||
|
||||
} // namespace QP
|
||||
//$enddef${QF::QActive::register_} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
//$define${QF::QActive::unregister_} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
namespace QP {
|
||||
|
||||
//${QF::QActive::unregister_} ................................................
|
||||
//............................................................................
|
||||
void QActive::unregister_() noexcept {
|
||||
std::uint_fast8_t const p = static_cast<std::uint_fast8_t>(m_prio);
|
||||
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
QF_MEM_SYS();
|
||||
|
||||
Q_REQUIRE_INCRIT(200, (0U < p) && (p <= QF_MAX_ACTIVE)
|
||||
&& (registry_[p] == this));
|
||||
registry_[p] = nullptr; // free-up the priority level
|
||||
m_state.fun = nullptr; // invalidate the state
|
||||
|
||||
QF_MEM_APP();
|
||||
QF_CRIT_EXIT();
|
||||
}
|
||||
|
||||
} // namespace QP
|
||||
//$enddef${QF::QActive::unregister_} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -1,10 +1,6 @@
|
||||
//$file${src::qf::qf_qeq.cpp} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
//
|
||||
// Model: qpcpp.qm
|
||||
// File: ${src::qf::qf_qeq.cpp}
|
||||
//
|
||||
// This code has been generated by QM 7.0.0 <www.state-machine.com/qm>.
|
||||
// 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,8 +10,8 @@
|
||||
//
|
||||
// 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-
|
||||
// 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.
|
||||
@ -30,8 +26,7 @@
|
||||
// Quantum Leaps contact information:
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//
|
||||
//$endhead${src::qf::qf_qeq.cpp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//============================================================================
|
||||
#define QP_IMPL // this is QP implementation
|
||||
#include "qp_port.hpp" // QP port
|
||||
#include "qp_pkg.hpp" // QP package-scope interface
|
||||
@ -48,124 +43,83 @@ namespace {
|
||||
Q_DEFINE_THIS_MODULE("qf_qeq")
|
||||
} // unnamed namespace
|
||||
|
||||
//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
// Check for the minimum required QP version
|
||||
#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U)%0x2710U))
|
||||
#error qpcpp version 7.3.0 or higher required
|
||||
#endif
|
||||
//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//$define${QF::QEQueue} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
namespace QP {
|
||||
|
||||
//${QF::QEQueue} .............................................................
|
||||
|
||||
//${QF::QEQueue::init} .......................................................
|
||||
//............................................................................
|
||||
void QEQueue::init(
|
||||
QEvt const * qSto[],
|
||||
QEvt const * * const qSto,
|
||||
std::uint_fast16_t const qLen) noexcept
|
||||
{
|
||||
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
|
||||
|
||||
m_frontEvt = nullptr; // no events in the queue
|
||||
m_ring = &qSto[0];
|
||||
m_ring = qSto;
|
||||
m_end = static_cast<QEQueueCtr>(qLen);
|
||||
if (qLen > 0U) {
|
||||
m_head = 0U;
|
||||
m_tail = 0U;
|
||||
}
|
||||
m_nFree = static_cast<QEQueueCtr>(qLen + 1U); //+1 for frontEvt
|
||||
m_nMin = m_nFree;
|
||||
m_nFree = static_cast<QEQueueCtr>(qLen + 1U); //+1 for frontEvt
|
||||
m_nMin = m_nFree;
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
m_frontEvt_dis = static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(m_frontEvt));
|
||||
m_head_dis = static_cast<QEQueueCtr>(~m_head);
|
||||
m_tail_dis = static_cast<QEQueueCtr>(~m_tail);
|
||||
m_nFree_dis = static_cast<QEQueueCtr>(~m_nFree);
|
||||
#endif
|
||||
|
||||
QF_MEM_APP();
|
||||
QF_CRIT_EXIT();
|
||||
}
|
||||
|
||||
//${QF::QEQueue::post} .......................................................
|
||||
//............................................................................
|
||||
bool QEQueue::post(
|
||||
QEvt const * const e,
|
||||
std::uint_fast16_t const margin,
|
||||
std::uint_fast8_t const qsId) noexcept
|
||||
{
|
||||
#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 != nullptr);
|
||||
Q_INVARIANT_INCRIT(201, e->verify_());
|
||||
|
||||
QEQueueCtr tmp = m_nFree; // get volatile into temporary
|
||||
#ifndef Q_UNSAFE
|
||||
QEQueueCtr dis = static_cast<QEQueueCtr>(~m_nFree_dis);
|
||||
Q_INVARIANT_INCRIT(201, 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 > static_cast<QEQueueCtr>(margin)))
|
||||
{
|
||||
// can the queue accept the event?
|
||||
bool status = ((margin == QF::NO_MARGIN) && (tmp > 0U))
|
||||
|| (tmp > static_cast<QEQueueCtr>(margin));
|
||||
if (status) {
|
||||
// is it a mutable event?
|
||||
if (e->getPoolNum_() != 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
|
||||
|
||||
m_nFree = tmp; // update the original
|
||||
#ifndef Q_UNSAFE
|
||||
m_nFree_dis = static_cast<QEQueueCtr>(~tmp);
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
if (m_nMin > tmp) {
|
||||
if (m_nMin > tmp) { // is this the new minimum?
|
||||
m_nMin = tmp; // update minimum so far
|
||||
}
|
||||
|
||||
#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(this); // this queue object
|
||||
QS_2U8_PRE(e->getPoolNum_(), e->refCtr_);
|
||||
QS_2U8_PRE(e->poolNum_, e->refCtr_);
|
||||
QS_EQC_PRE(tmp); // # free entries
|
||||
QS_EQC_PRE(m_nMin); // min # free entries
|
||||
QS_END_PRE()
|
||||
#endif // def Q_SPY
|
||||
|
||||
if (m_frontEvt == nullptr) { // is the queue empty?
|
||||
m_frontEvt = e; // deliver event directly
|
||||
#ifndef Q_UNSAFE
|
||||
Q_INVARIANT_INCRIT(211, m_frontEvt_dis
|
||||
== static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(nullptr)));
|
||||
m_frontEvt_dis = static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(e));
|
||||
#endif // ndef Q_UNSAFE
|
||||
}
|
||||
else { // queue was not empty, insert event into the ring-buffer
|
||||
tmp = m_head; // get volatile into temporary
|
||||
#ifndef Q_UNSAFE
|
||||
dis = static_cast<QEQueueCtr>(~m_head_dis);
|
||||
Q_INVARIANT_INCRIT(212, tmp == dis);
|
||||
#endif // ndef Q_UNSAFE
|
||||
m_ring[tmp] = e; // insert e into buffer
|
||||
|
||||
if (tmp == 0U) { // need to wrap the head?
|
||||
@ -174,77 +128,57 @@ bool QEQueue::post(
|
||||
--tmp; // advance head (counter-clockwise)
|
||||
|
||||
m_head = tmp; // update the original
|
||||
#ifndef Q_UNSAFE
|
||||
m_head_dis = static_cast<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(this); // this queue object
|
||||
QS_2U8_PRE(e->getPoolNum_(), 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} ...................................................
|
||||
//............................................................................
|
||||
void QEQueue::postLIFO(
|
||||
QEvt const * const e,
|
||||
std::uint_fast8_t const qsId) noexcept
|
||||
{
|
||||
#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 != nullptr);
|
||||
Q_INVARIANT_INCRIT(301, e->verify_());
|
||||
|
||||
QEQueueCtr tmp = m_nFree; // get volatile into temporary
|
||||
#ifndef Q_UNSAFE
|
||||
QEQueueCtr dis = static_cast<QEQueueCtr>(~m_nFree_dis);
|
||||
Q_INVARIANT_INCRIT(301, 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 (e->getPoolNum_() != 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
|
||||
|
||||
m_nFree = tmp; // update the original
|
||||
#ifndef Q_UNSAFE
|
||||
m_nFree_dis = static_cast<QEQueueCtr>(~tmp);
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
if (m_nMin > tmp) {
|
||||
if (m_nMin > tmp) { // is this the new minimum?
|
||||
m_nMin = tmp; // update minimum so far
|
||||
}
|
||||
|
||||
@ -252,67 +186,44 @@ void QEQueue::postLIFO(
|
||||
QS_TIME_PRE(); // timestamp
|
||||
QS_SIG_PRE(e->sig); // the signal of this event
|
||||
QS_OBJ_PRE(this); // this queue object
|
||||
QS_2U8_PRE(e->getPoolNum_(), e->refCtr_);
|
||||
QS_2U8_PRE(e->poolNum_, e->refCtr_);
|
||||
QS_EQC_PRE(tmp); // # free entries
|
||||
QS_EQC_PRE(m_nMin); // min # free entries
|
||||
QS_END_PRE()
|
||||
|
||||
QEvt const * const frontEvt = m_frontEvt; // read into temporary
|
||||
m_frontEvt = e; // deliver the event directly to the front
|
||||
#ifndef Q_UNSAFE
|
||||
m_frontEvt_dis = static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(e));
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
if (frontEvt != nullptr) { // was the queue NOT empty?
|
||||
tmp = m_tail; // get volatile into temporary;
|
||||
#ifndef Q_UNSAFE
|
||||
dis = static_cast<QEQueueCtr>(~m_tail_dis);
|
||||
Q_INVARIANT_INCRIT(311, tmp == dis);
|
||||
#endif // ndef Q_UNSAFE
|
||||
++tmp;
|
||||
if (tmp == m_end) { // need to wrap the tail?
|
||||
tmp = 0U; // wrap around
|
||||
}
|
||||
m_tail = tmp;
|
||||
#ifndef Q_UNSAFE
|
||||
m_tail_dis = static_cast<QEQueueCtr>(~tmp);
|
||||
#endif
|
||||
m_ring[tmp] = frontEvt;
|
||||
}
|
||||
|
||||
QF_MEM_APP();
|
||||
QF_CRIT_EXIT();
|
||||
}
|
||||
|
||||
//${QF::QEQueue::get} ........................................................
|
||||
//............................................................................
|
||||
QEvt const * QEQueue::get(std::uint_fast8_t const qsId) noexcept {
|
||||
#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 = m_frontEvt; // always remove evt from the front
|
||||
#ifndef Q_UNSAFE
|
||||
Q_INVARIANT_INCRIT(411, Q_PTR2UINT_CAST_(e)
|
||||
== static_cast<std::uintptr_t>(~m_frontEvt_dis));
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
if (e != nullptr) { // was the queue not empty?
|
||||
QEQueueCtr tmp = m_nFree; // get volatile into temporary
|
||||
#ifndef Q_UNSAFE
|
||||
QEQueueCtr const dis = static_cast<QEQueueCtr>(~m_nFree_dis);
|
||||
Q_INVARIANT_INCRIT(412, tmp == dis);
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
++tmp; // one more free event in the queue
|
||||
|
||||
m_nFree = tmp; // update the # free
|
||||
#ifndef Q_UNSAFE
|
||||
m_nFree_dis = static_cast<QEQueueCtr>(~tmp);
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
// any events in the ring buffer?
|
||||
if (tmp <= m_end) {
|
||||
@ -321,17 +232,15 @@ QEvt const * QEQueue::get(std::uint_fast8_t const qsId) noexcept {
|
||||
QS_TIME_PRE(); // timestamp
|
||||
QS_SIG_PRE(e->sig); // the signal of this event
|
||||
QS_OBJ_PRE(this); // this queue object
|
||||
QS_2U8_PRE(e->getPoolNum_(), e->refCtr_);
|
||||
QS_2U8_PRE(e->poolNum_, e->refCtr_);
|
||||
QS_EQC_PRE(tmp); // # free entries
|
||||
QS_END_PRE()
|
||||
|
||||
tmp = m_tail; // get volatile into temporary
|
||||
QEvt const * const frontEvt = m_ring[tmp];
|
||||
#ifndef Q_UNSAFE
|
||||
Q_ASSERT_INCRIT(421, frontEvt != nullptr);
|
||||
m_frontEvt_dis =
|
||||
static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(frontEvt));
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
Q_ASSERT_INCRIT(420, frontEvt != nullptr);
|
||||
|
||||
m_frontEvt = frontEvt; // update the original
|
||||
|
||||
if (tmp == 0U) { // need to wrap the tail?
|
||||
@ -339,16 +248,9 @@ QEvt const * QEQueue::get(std::uint_fast8_t const qsId) noexcept {
|
||||
}
|
||||
--tmp; // advance the tail (counter-clockwise)
|
||||
m_tail = tmp; // update the original
|
||||
#ifndef Q_UNSAFE
|
||||
m_tail_dis = static_cast<QEQueueCtr>(~tmp);
|
||||
#endif // ndef Q_UNSAFE
|
||||
}
|
||||
else {
|
||||
m_frontEvt = nullptr; // queue becomes empty
|
||||
#ifndef Q_UNSAFE
|
||||
m_frontEvt_dis =
|
||||
static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(nullptr));
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
// all entries in the queue must be free (+1 for frontEvt)
|
||||
Q_INVARIANT_INCRIT(440, tmp == (m_end + 1U));
|
||||
@ -357,16 +259,14 @@ QEvt const * QEQueue::get(std::uint_fast8_t const qsId) noexcept {
|
||||
QS_TIME_PRE(); // timestamp
|
||||
QS_SIG_PRE(e->sig); // the signal of this event
|
||||
QS_OBJ_PRE(this); // this queue object
|
||||
QS_2U8_PRE(e->getPoolNum_(), e->refCtr_);
|
||||
QS_2U8_PRE(e->poolNum_, e->refCtr_);
|
||||
QS_END_PRE()
|
||||
}
|
||||
}
|
||||
|
||||
QF_MEM_APP();
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
} // namespace QP
|
||||
//$enddef${QF::QEQueue} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -1,10 +1,6 @@
|
||||
//$file${src::qf::qf_qmact.cpp} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
//
|
||||
// Model: qpcpp.qm
|
||||
// File: ${src::qf::qf_qmact.cpp}
|
||||
//
|
||||
// This code has been generated by QM 7.0.0 <www.state-machine.com/qm>.
|
||||
// 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,8 +10,8 @@
|
||||
//
|
||||
// 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-
|
||||
// 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.
|
||||
@ -30,8 +26,7 @@
|
||||
// Quantum Leaps contact information:
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//
|
||||
//$endhead${src::qf::qf_qmact.cpp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//============================================================================
|
||||
#define QP_IMPL // this is QP implementation
|
||||
#include "qp_port.hpp" // QP port
|
||||
#include "qp_pkg.hpp" // QP package-scope interface
|
||||
@ -48,18 +43,9 @@ namespace {
|
||||
//Q_DEFINE_THIS_MODULE("qf_qmact")
|
||||
} // unnamed namespace
|
||||
|
||||
//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
// Check for the minimum required QP version
|
||||
#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U)%0x2710U))
|
||||
#error qpcpp version 7.3.0 or higher required
|
||||
#endif
|
||||
//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//$define${QF::QMActive} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
namespace QP {
|
||||
|
||||
//${QF::QMActive} ............................................................
|
||||
|
||||
//${QF::QMActive::QMActive} ..................................................
|
||||
//............................................................................
|
||||
QMActive::QMActive(QStateHandler const initial) noexcept
|
||||
: QActive(initial)
|
||||
{
|
||||
@ -68,4 +54,3 @@ QMActive::QMActive(QStateHandler const initial) noexcept
|
||||
}
|
||||
|
||||
} // namespace QP
|
||||
//$enddef${QF::QMActive} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -1,10 +1,6 @@
|
||||
//$file${src::qf::qf_time.cpp} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
//
|
||||
// Model: qpcpp.qm
|
||||
// File: ${src::qf::qf_time.cpp}
|
||||
//
|
||||
// This code has been generated by QM 7.0.0 <www.state-machine.com/qm>.
|
||||
// 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,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:
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//
|
||||
//$endhead${src::qf::qf_time.cpp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//============================================================================
|
||||
#define QP_IMPL // this is QP implementation
|
||||
#include "qp_port.hpp" // QP port
|
||||
#include "qp_pkg.hpp" // QP package-scope interface
|
||||
@ -48,37 +42,20 @@ namespace {
|
||||
Q_DEFINE_THIS_MODULE("qf_time")
|
||||
} // unnamed namespace
|
||||
|
||||
//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
// Check for the minimum required QP version
|
||||
#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U)%0x2710U))
|
||||
#error qpcpp version 7.3.0 or higher required
|
||||
#endif
|
||||
//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//$define${QF::QTimeEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
namespace QP {
|
||||
|
||||
//${QF::QTimeEvt} ............................................................
|
||||
QTimeEvt QTimeEvt::timeEvtHead_[QF_MAX_TICK_RATE];
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
QPtrDis QTimeEvt::timeEvtHead_dis_[QF_MAX_TICK_RATE];
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
//${QF::QTimeEvt::QTimeEvt} ..................................................
|
||||
//............................................................................
|
||||
QTimeEvt::QTimeEvt(
|
||||
QActive * const act,
|
||||
QSignal const sig,
|
||||
std::uint_fast8_t const tickRate) noexcept
|
||||
: QEvt(sig),
|
||||
m_next(nullptr),
|
||||
#ifndef Q_UNSAFE
|
||||
m_next_dis(static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(nullptr))),
|
||||
#endif
|
||||
m_act(act),
|
||||
m_ctr(0U),
|
||||
#ifndef Q_UNSAFE
|
||||
m_ctr_dis(static_cast<QTimeEvtCtr>(~static_cast<QTimeEvtCtr>(0U))),
|
||||
#endif
|
||||
m_interval(0U),
|
||||
m_tickRate(0U),
|
||||
m_flags(0U)
|
||||
@ -89,56 +66,48 @@ QTimeEvt::QTimeEvt(
|
||||
&& (tickRate < QF_MAX_TICK_RATE));
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
// adjust the settings from the QEvt(sig) ctor
|
||||
evtTag_ = 0x0FU;
|
||||
refCtr_ = 0U;
|
||||
refCtr_ = 0U; // adjust from the QEvt(sig) ctor
|
||||
}
|
||||
|
||||
//${QF::QTimeEvt::armX} ......................................................
|
||||
//............................................................................
|
||||
void QTimeEvt::armX(
|
||||
std::uint32_t const nTicks,
|
||||
std::uint32_t const interval) noexcept
|
||||
{
|
||||
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
|
||||
|
||||
Q_REQUIRE_INCRIT(401, verify_() && (nTicks != 0U));
|
||||
#endif
|
||||
|
||||
QTimeEvtCtr const ctr = m_ctr;
|
||||
std::uint8_t const tickRate = m_tickRate;
|
||||
#ifdef Q_SPY
|
||||
#ifdef Q_SPY
|
||||
std::uint_fast8_t const qsId =
|
||||
static_cast<QActive const *>(m_act)->m_prio;
|
||||
#endif // def Q_SPY
|
||||
#endif // def Q_SPY
|
||||
|
||||
Q_REQUIRE_INCRIT(410, (ctr == 0U)
|
||||
Q_REQUIRE_INCRIT(410,
|
||||
(nTicks != 0U)
|
||||
&& (ctr == 0U)
|
||||
&& (m_act != nullptr)
|
||||
&& (tickRate < QF_MAX_TICK_RATE));
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
Q_INVARIANT_INCRIT(411, ctr == static_cast<QTimeEvtCtr>(~m_ctr_dis));
|
||||
#else
|
||||
#ifdef Q_UNSAFE
|
||||
Q_UNUSED_PAR(ctr);
|
||||
#endif // ndef Q_UNSAFE
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
m_ctr = static_cast<QTimeEvtCtr>(nTicks);
|
||||
m_interval = static_cast<QTimeEvtCtr>(interval);
|
||||
#ifndef Q_UNSAFE
|
||||
m_ctr_dis = static_cast<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 the QF_tickX() function.
|
||||
// because un-linking is performed exclusively in the QTimeEvt::tick().
|
||||
if ((m_flags & QTE_FLAG_IS_LINKED) == 0U) {
|
||||
m_flags |= QTE_FLAG_IS_LINKED; // mark as linked
|
||||
|
||||
@ -148,22 +117,8 @@ void QTimeEvt::armX(
|
||||
// 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().
|
||||
#ifndef Q_UNSAFE
|
||||
Q_INVARIANT_INCRIT(420,
|
||||
Q_PTR2UINT_CAST_(m_next) ==
|
||||
static_cast<std::uintptr_t>(~m_next_dis));
|
||||
Q_INVARIANT_INCRIT(411,
|
||||
Q_PTR2UINT_CAST_(timeEvtHead_[tickRate].m_act) ==
|
||||
static_cast<std::uintptr_t>(~timeEvtHead_dis_[tickRate].m_ptr_dis));
|
||||
#endif
|
||||
m_next = timeEvtHead_[tickRate].toTimeEvt();
|
||||
timeEvtHead_[tickRate].m_act = this;
|
||||
#ifndef Q_UNSAFE
|
||||
m_next_dis =
|
||||
static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(m_next));
|
||||
timeEvtHead_dis_[tickRate].m_ptr_dis =
|
||||
static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(this));
|
||||
#endif // ndef Q_UNSAFE
|
||||
}
|
||||
|
||||
QS_BEGIN_PRE(QS_QF_TIMEEVT_ARM, qsId)
|
||||
@ -175,36 +130,26 @@ void QTimeEvt::armX(
|
||||
QS_U8_PRE(tickRate); // tick rate
|
||||
QS_END_PRE()
|
||||
|
||||
QF_MEM_APP();
|
||||
QF_CRIT_EXIT();
|
||||
}
|
||||
|
||||
//${QF::QTimeEvt::disarm} ....................................................
|
||||
//............................................................................
|
||||
bool QTimeEvt::disarm() noexcept {
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
QF_MEM_SYS();
|
||||
|
||||
Q_REQUIRE_INCRIT(500, verify_());
|
||||
|
||||
QTimeEvtCtr const ctr = m_ctr;
|
||||
#ifndef Q_UNSAFE
|
||||
Q_INVARIANT_INCRIT(501, ctr == static_cast<QTimeEvtCtr>(~m_ctr_dis));
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
#ifdef Q_SPY
|
||||
#ifdef Q_SPY
|
||||
std::uint_fast8_t const qsId = static_cast<QActive *>(m_act)->m_prio;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// was the time event actually armed?
|
||||
bool wasArmed;
|
||||
bool wasArmed = false;
|
||||
if (ctr != 0U) {
|
||||
wasArmed = true;
|
||||
m_flags |= QTE_FLAG_WAS_DISARMED;
|
||||
m_ctr = 0U; // schedule removal from the list
|
||||
#ifndef Q_UNSAFE
|
||||
m_ctr_dis = static_cast<QTimeEvtCtr>(~static_cast<QTimeEvtCtr>(0U));
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
QS_BEGIN_PRE(QS_QF_TIMEEVT_DISARM, qsId)
|
||||
QS_TIME_PRE(); // timestamp
|
||||
@ -216,7 +161,6 @@ bool QTimeEvt::disarm() noexcept {
|
||||
QS_END_PRE()
|
||||
}
|
||||
else { // the time event was already disarmed automatically
|
||||
wasArmed = false;
|
||||
m_flags &= static_cast<std::uint8_t>(~QTE_FLAG_WAS_DISARMED);
|
||||
|
||||
QS_BEGIN_PRE(QS_QF_TIMEEVT_DISARM_ATTEMPT, qsId)
|
||||
@ -227,55 +171,46 @@ bool QTimeEvt::disarm() noexcept {
|
||||
QS_END_PRE()
|
||||
}
|
||||
|
||||
QF_MEM_APP();
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
return wasArmed;
|
||||
}
|
||||
|
||||
//${QF::QTimeEvt::rearm} .....................................................
|
||||
//............................................................................
|
||||
bool QTimeEvt::rearm(std::uint32_t const nTicks) noexcept {
|
||||
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
|
||||
|
||||
Q_REQUIRE_INCRIT(601, verify_() && (nTicks != 0U));
|
||||
|
||||
QTimeEvtCtr const ctr = m_ctr;
|
||||
std::uint8_t const tickRate = m_tickRate;
|
||||
#ifdef Q_SPY
|
||||
std::uint_fast8_t const qsId = static_cast<QActive *>(m_act)->m_prio;
|
||||
#endif
|
||||
QTimeEvtCtr const ctr = m_ctr;
|
||||
|
||||
Q_REQUIRE_INCRIT(610, (m_act != nullptr)
|
||||
Q_REQUIRE_INCRIT(610,
|
||||
(nTicks != 0U)
|
||||
&& (m_act != nullptr)
|
||||
&& (tickRate < QF_MAX_TICK_RATE));
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
Q_INVARIANT_INCRIT(602, ctr == static_cast<QTimeEvtCtr>(~m_ctr_dis));
|
||||
#endif // ndef Q_UNSAFE
|
||||
#ifdef Q_SPY
|
||||
std::uint_fast8_t const qsId = static_cast<QActive *>(m_act)->m_prio;
|
||||
#endif
|
||||
|
||||
m_ctr = static_cast<QTimeEvtCtr>(nTicks);
|
||||
#ifndef Q_UNSAFE
|
||||
m_ctr_dis = static_cast<QTimeEvtCtr>(~nTicks);
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
// is the time evt not running?
|
||||
bool wasArmed;
|
||||
// was the time evt not running?
|
||||
bool wasArmed = false;
|
||||
if (ctr == 0U) {
|
||||
wasArmed = false;
|
||||
|
||||
// NOTE: For a duration of a single clock tick of the specified
|
||||
// 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.
|
||||
|
||||
// was the time event unlinked?
|
||||
// is the time event unlinked?
|
||||
if ((m_flags & QTE_FLAG_IS_LINKED) == 0U) {
|
||||
m_flags |= QTE_FLAG_IS_LINKED; // mark as linked
|
||||
|
||||
@ -285,22 +220,8 @@ bool QTimeEvt::rearm(std::uint32_t const nTicks) noexcept {
|
||||
// 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().
|
||||
#ifndef Q_UNSAFE
|
||||
Q_INVARIANT_INCRIT(620,
|
||||
Q_PTR2UINT_CAST_(m_next) ==
|
||||
static_cast<std::uintptr_t>(~m_next_dis));
|
||||
Q_INVARIANT_INCRIT(611,
|
||||
Q_PTR2UINT_CAST_(timeEvtHead_[tickRate].m_act) ==
|
||||
static_cast<std::uintptr_t>(~timeEvtHead_dis_[tickRate].m_ptr_dis));
|
||||
#endif
|
||||
m_next = timeEvtHead_[tickRate].toTimeEvt();
|
||||
timeEvtHead_[tickRate].m_act = this;
|
||||
#ifndef Q_UNSAFE
|
||||
m_next_dis =
|
||||
static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(m_next));
|
||||
timeEvtHead_dis_[tickRate].m_ptr_dis =
|
||||
static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(this));
|
||||
#endif // ndef Q_UNSAFE
|
||||
}
|
||||
}
|
||||
else { // the time event was armed
|
||||
@ -316,245 +237,186 @@ bool QTimeEvt::rearm(std::uint32_t const nTicks) noexcept {
|
||||
QS_2U8_PRE(tickRate, (wasArmed ? 1U : 0U));
|
||||
QS_END_PRE()
|
||||
|
||||
QF_MEM_APP();
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
return wasArmed;
|
||||
}
|
||||
|
||||
//${QF::QTimeEvt::wasDisarmed} ...............................................
|
||||
//............................................................................
|
||||
bool QTimeEvt::wasDisarmed() noexcept {
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
QF_MEM_SYS();
|
||||
|
||||
bool const wasDisarmed = (m_flags & QTE_FLAG_WAS_DISARMED) != 0U;
|
||||
m_flags |= QTE_FLAG_WAS_DISARMED;
|
||||
|
||||
QF_MEM_APP();
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
return wasDisarmed;
|
||||
}
|
||||
|
||||
//${QF::QTimeEvt::tick} ......................................................
|
||||
//............................................................................
|
||||
void QTimeEvt::tick(
|
||||
std::uint_fast8_t const tickRate,
|
||||
void const * const sender) noexcept
|
||||
{
|
||||
#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(timeEvtHead_));
|
||||
|
||||
QTimeEvt *prev = &timeEvtHead_[tickRate];
|
||||
|
||||
#ifdef Q_SPY
|
||||
QS_BEGIN_PRE(QS_QF_TICK, 0U)
|
||||
prev->m_ctr = (prev->m_ctr + 1U);
|
||||
QS_TEC_PRE(prev->m_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...
|
||||
std::uint_fast8_t lbound = 2U*QF_MAX_ACTIVE; // fixed upper loop bound
|
||||
for (; lbound > 0U; --lbound) {
|
||||
while (true) {
|
||||
Q_ASSERT_INCRIT(810, prev != nullptr); // sanity check
|
||||
|
||||
QTimeEvt *te = prev->m_next; // advance down the time evt. list
|
||||
#ifndef Q_UNSAFE
|
||||
Q_INVARIANT_INCRIT(811,
|
||||
Q_PTR2UINT_CAST_(te) ==
|
||||
static_cast<std::uintptr_t>(~prev->m_next_dis));
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
if (te == nullptr) { // end of the list?
|
||||
|
||||
// any new time events armed since the last QTimeEvt_tick_()?
|
||||
if (timeEvtHead_[tickRate].m_act != nullptr) {
|
||||
#ifndef Q_UNSAFE
|
||||
Q_INVARIANT_INCRIT(812,
|
||||
Q_PTR2UINT_CAST_(timeEvtHead_[tickRate].m_act) ==
|
||||
static_cast<std::uintptr_t>(
|
||||
~timeEvtHead_dis_[tickRate].m_ptr_dis));
|
||||
#endif // ndef Q_UNSAFE
|
||||
prev->m_next = timeEvtHead_[tickRate].toTimeEvt();
|
||||
timeEvtHead_[tickRate].m_act = nullptr;
|
||||
#ifndef Q_UNSAFE
|
||||
prev->m_next_dis =
|
||||
static_cast<std::uintptr_t>(
|
||||
~Q_PTR2UINT_CAST_(prev->m_next));
|
||||
timeEvtHead_dis_[tickRate].m_ptr_dis =
|
||||
static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(nullptr));
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
te = prev->m_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 (timeEvtHead_[tickRate].m_act == nullptr) {
|
||||
break; // terminate the while-loop
|
||||
}
|
||||
|
||||
prev->m_next = timeEvtHead_[tickRate].toTimeEvt();
|
||||
timeEvtHead_[tickRate].m_act = nullptr;
|
||||
|
||||
te = prev->m_next; // switch to the new list
|
||||
}
|
||||
|
||||
// the time event 'te' must be valid
|
||||
Q_ASSERT_INCRIT(820, te != nullptr);
|
||||
Q_INVARIANT_INCRIT(821, te->verify_());
|
||||
Q_ASSERT_INCRIT(840, te != nullptr);
|
||||
|
||||
QTimeEvtCtr ctr = te->m_ctr;
|
||||
#ifndef Q_UNSAFE
|
||||
Q_INVARIANT_INCRIT(822, ctr ==
|
||||
static_cast<QTimeEvtCtr>(~te->m_ctr_dis));
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
if (ctr == 0U) { // time event scheduled for removal?
|
||||
prev->m_next = te->m_next;
|
||||
#ifndef Q_UNSAFE
|
||||
prev->m_next_dis =
|
||||
static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(te->m_next));
|
||||
#endif // ndef Q_UNSAFE
|
||||
|
||||
// mark time event 'te' as NOT linked
|
||||
te->m_flags &= static_cast<std::uint8_t>(~QTE_FLAG_IS_LINKED);
|
||||
|
||||
// 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 evt about to expire?
|
||||
else if (ctr == 1U) { // is time event about to expire?
|
||||
QActive * const act = te->toActive();
|
||||
if (te->m_interval != 0U) { // periodic time evt?
|
||||
te->m_ctr = te->m_interval; // rearm the time event
|
||||
#ifndef Q_UNSAFE
|
||||
te->m_ctr_dis = static_cast<QTimeEvtCtr>(~te->m_interval);
|
||||
#endif // ndef Q_UNSAFE
|
||||
prev = te; // advance to this time event
|
||||
}
|
||||
else { // one-shot time event: automatically disarm
|
||||
te->m_ctr = 0U;
|
||||
prev->m_next = te->m_next;
|
||||
#ifndef Q_UNSAFE
|
||||
te->m_ctr_dis =
|
||||
static_cast<QTimeEvtCtr>(~static_cast<QTimeEvtCtr>(0U));
|
||||
prev->m_next_dis =
|
||||
static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(te->m_next));
|
||||
#endif // ndef Q_UNSAFE
|
||||
prev = te->expire_(prev, act, tickRate);
|
||||
|
||||
// mark time event 'te' as NOT linked
|
||||
te->m_flags &=
|
||||
static_cast<std::uint8_t>(~QTE_FLAG_IS_LINKED);
|
||||
// do NOT advance the prev pointer
|
||||
|
||||
QS_BEGIN_PRE(QS_QF_TIMEEVT_AUTO_DISARM, act->m_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->m_prio)
|
||||
QS_TIME_PRE(); // timestamp
|
||||
QS_OBJ_PRE(te); // the time event object
|
||||
QS_SIG_PRE(te->sig); // signal of this time event
|
||||
QS_OBJ_PRE(act); // the target AO
|
||||
QS_U8_PRE(tickRate); // tick rate
|
||||
QS_END_PRE()
|
||||
|
||||
#ifdef QXK_HPP_
|
||||
#ifdef QXK_HPP_
|
||||
if (te->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
|
||||
|
||||
// act->POST() asserts if the queue overflows
|
||||
act->POST(te, sender);
|
||||
}
|
||||
#else
|
||||
QF_MEM_APP();
|
||||
#else // not QXK
|
||||
QF_CRIT_EXIT(); // exit crit. section before posting
|
||||
|
||||
// act->POST() asserts if the queue overflows
|
||||
act->POST(te, sender);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
else { // time event keeps timing out
|
||||
--ctr; // decrement the tick counter
|
||||
te->m_ctr = ctr; // update the original
|
||||
#ifndef Q_UNSAFE
|
||||
te->m_ctr_dis = static_cast<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} ..................................................
|
||||
//............................................................................
|
||||
bool QTimeEvt::noActive(std::uint_fast8_t const tickRate) noexcept {
|
||||
// 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 (timeEvtHead_[tickRate].m_next != nullptr) {
|
||||
inactive = false;
|
||||
// empty
|
||||
}
|
||||
else if (timeEvtHead_[tickRate].m_act != nullptr) {
|
||||
inactive = false;
|
||||
// empty
|
||||
}
|
||||
else {
|
||||
inactive = true;
|
||||
}
|
||||
QF_MEM_APP();
|
||||
|
||||
return inactive;
|
||||
}
|
||||
|
||||
//${QF::QTimeEvt::QTimeEvt} ..................................................
|
||||
//............................................................................
|
||||
QTimeEvt::QTimeEvt() noexcept
|
||||
: QEvt(0U),
|
||||
m_next(nullptr),
|
||||
#ifndef Q_UNSAFE
|
||||
m_next_dis(static_cast<std::uintptr_t>(~Q_PTR2UINT_CAST_(nullptr))),
|
||||
#endif
|
||||
m_act(nullptr),
|
||||
m_ctr(0U),
|
||||
#ifndef Q_UNSAFE
|
||||
m_ctr_dis(static_cast<QTimeEvtCtr>(~static_cast<QTimeEvtCtr>(0U))),
|
||||
#endif
|
||||
m_interval(0U),
|
||||
m_tickRate(0U),
|
||||
m_flags(0U)
|
||||
{}
|
||||
|
||||
//............................................................................
|
||||
QTimeEvt *QTimeEvt::expire_(
|
||||
QTimeEvt * const prev_link,
|
||||
QActive const * const act,
|
||||
std::uint_fast8_t const tickRate) noexcept
|
||||
{
|
||||
// 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 (m_interval != 0U) { // periodic time evt?
|
||||
m_ctr = m_interval; // rearm the time event
|
||||
prev = this; // advance to this time event
|
||||
}
|
||||
else { // one-shot time event: automatically disarm
|
||||
m_ctr = 0U;
|
||||
prev->m_next = m_next;
|
||||
|
||||
// mark this time event as NOT linked
|
||||
m_flags &=
|
||||
static_cast<std::uint8_t>(~QTE_FLAG_IS_LINKED);
|
||||
// do NOT advance the prev pointer
|
||||
|
||||
QS_BEGIN_PRE(QS_QF_TIMEEVT_AUTO_DISARM, act->m_prio)
|
||||
QS_OBJ_PRE(this); // 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->m_prio)
|
||||
QS_TIME_PRE(); // timestamp
|
||||
QS_OBJ_PRE(this); // the time event object
|
||||
QS_SIG_PRE(sig); // signal of this time event
|
||||
QS_OBJ_PRE(act); // the target AO
|
||||
QS_U8_PRE(tickRate); // tick rate
|
||||
QS_END_PRE()
|
||||
|
||||
return prev;
|
||||
}
|
||||
|
||||
} // namespace QP
|
||||
//$enddef${QF::QTimeEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
293
src/qk/qk.cpp
293
src/qk/qk.cpp
@ -1,10 +1,6 @@
|
||||
//$file${src::qk::qk.cpp} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
//
|
||||
// Model: qpcpp.qm
|
||||
// File: ${src::qk::qk.cpp}
|
||||
//
|
||||
// This code has been generated by QM 7.0.0 <www.state-machine.com/qm>.
|
||||
// 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,8 +10,8 @@
|
||||
//
|
||||
// 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-
|
||||
// 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.
|
||||
@ -30,8 +26,7 @@
|
||||
// Quantum Leaps contact information:
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//
|
||||
//$endhead${src::qk::qk.cpp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//============================================================================
|
||||
#define QP_IMPL // this is QP implementation
|
||||
#include "qp_port.hpp" // QP port
|
||||
#include "qp_pkg.hpp" // QP package-scope interface
|
||||
@ -45,7 +40,7 @@
|
||||
|
||||
// protection against including this source file in a wrong project
|
||||
#ifndef QK_HPP_
|
||||
#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_HPP_
|
||||
|
||||
// unnamed namespace for local definitions with internal linkage
|
||||
@ -53,28 +48,18 @@ namespace {
|
||||
Q_DEFINE_THIS_MODULE("qk")
|
||||
} // unnamed namespace
|
||||
|
||||
//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
// Check for the minimum required QP version
|
||||
#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U)%0x2710U))
|
||||
#error qpcpp version 7.3.0 or higher required
|
||||
#endif
|
||||
//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//$define${QK::QK-base} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
namespace QP {
|
||||
namespace QK {
|
||||
|
||||
//${QK::QK-base::schedLock} ..................................................
|
||||
//............................................................................
|
||||
QSchedStatus schedLock(std::uint_fast8_t const ceiling) noexcept {
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
QF_MEM_SYS();
|
||||
|
||||
Q_REQUIRE_INCRIT(100, !QK_ISR_CONTEXT_());
|
||||
Q_INVARIANT_INCRIT(102, QK_priv_.lockCeil
|
||||
== static_cast<std::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
|
||||
@ -88,33 +73,21 @@ QSchedStatus schedLock(std::uint_fast8_t const ceiling) noexcept {
|
||||
|
||||
// new status of the lock
|
||||
QK_priv_.lockCeil = ceiling;
|
||||
#ifndef Q_UNSAFE
|
||||
QK_priv_.lockCeil_dis = static_cast<std::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} ................................................
|
||||
//............................................................................
|
||||
void schedUnlock(QSchedStatus const prevCeil) noexcept {
|
||||
// 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
|
||||
== static_cast<std::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)
|
||||
@ -124,68 +97,44 @@ void schedUnlock(QSchedStatus const prevCeil) noexcept {
|
||||
|
||||
// restore the previous lock ceiling
|
||||
QK_priv_.lockCeil = prevCeil;
|
||||
#ifndef Q_UNSAFE
|
||||
QK_priv_.lockCeil_dis = static_cast<std::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();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace QK
|
||||
} // namespace QP
|
||||
//$enddef${QK::QK-base} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
//============================================================================
|
||||
extern "C" {
|
||||
//$define${QK-extern-C} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
|
||||
//${QK-extern-C::QK_priv_} ...................................................
|
||||
QK_Attr QK_priv_;
|
||||
|
||||
//${QK-extern-C::QK_sched_} ..................................................
|
||||
//............................................................................
|
||||
std::uint_fast8_t QK_sched_() noexcept {
|
||||
// NOTE: this function is entered with interrupts DISABLED
|
||||
|
||||
Q_INVARIANT_INCRIT(402,
|
||||
QK_priv_.readySet.verify_(&QK_priv_.readySet_dis));
|
||||
|
||||
std::uint_fast8_t p;
|
||||
if (QK_priv_.readySet.isEmpty()) {
|
||||
p = 0U; // no activation needed
|
||||
}
|
||||
else {
|
||||
std::uint_fast8_t p = 0U; // assume NO activation needed
|
||||
if (QK_priv_.readySet.notEmpty()) {
|
||||
// find the highest-prio AO with non-empty event queue
|
||||
p = QK_priv_.readySet.findMax();
|
||||
|
||||
Q_INVARIANT_INCRIT(412, QK_priv_.actThre
|
||||
== static_cast<std::uint_fast8_t>(~QK_priv_.actThre_dis));
|
||||
|
||||
// is the AO's prio. below the active preemption-threshold?
|
||||
if (p <= QK_priv_.actThre) {
|
||||
p = 0U; // no activation needed
|
||||
}
|
||||
else {
|
||||
Q_INVARIANT_INCRIT(422, QK_priv_.lockCeil
|
||||
== static_cast<std::uint_fast8_t>(~QK_priv_.lockCeil_dis));
|
||||
|
||||
// is the AO's prio. below the lock-ceiling?
|
||||
if (p <= QK_priv_.lockCeil) {
|
||||
p = 0U; // no activation needed
|
||||
}
|
||||
else {
|
||||
Q_INVARIANT_INCRIT(432, QK_priv_.nextPrio
|
||||
== static_cast<std::uint_fast8_t>(~QK_priv_.nextPrio_dis));
|
||||
QK_priv_.nextPrio = p; // next AO to run
|
||||
#ifndef Q_UNSAFE
|
||||
QK_priv_.nextPrio_dis
|
||||
= static_cast<std::uint_fast8_t>(~QK_priv_.nextPrio);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -193,60 +142,77 @@ std::uint_fast8_t QK_sched_() noexcept {
|
||||
return p;
|
||||
}
|
||||
|
||||
//${QK-extern-C::QK_activate_} ...............................................
|
||||
//............................................................................
|
||||
std::uint_fast8_t QK_sched_act_(
|
||||
QP::QActive const * const act,
|
||||
std::uint_fast8_t const pthre_in) noexcept
|
||||
{
|
||||
// NOTE: this function is entered with interrupts DISABLED
|
||||
|
||||
std::uint_fast8_t p = act->getPrio();
|
||||
if (act->getEQueue().isEmpty()) { // empty queue?
|
||||
QK_priv_.readySet.remove(p);
|
||||
}
|
||||
|
||||
if (QK_priv_.readySet.isEmpty()) {
|
||||
p = 0U; // no activation needed
|
||||
}
|
||||
else {
|
||||
// find new highest-prio AO ready to run...
|
||||
p = QK_priv_.readySet.findMax();
|
||||
// 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;
|
||||
}
|
||||
|
||||
//............................................................................
|
||||
void QK_activate_() noexcept {
|
||||
// NOTE: this function is entered with interrupts DISABLED
|
||||
|
||||
std::uint_fast8_t const prio_in = QK_priv_.actPrio; // save initial prio.
|
||||
std::uint_fast8_t p = QK_priv_.nextPrio; // next prio to run
|
||||
|
||||
Q_INVARIANT_INCRIT(502,
|
||||
(prio_in == static_cast<std::uint_fast8_t>(~QK_priv_.actPrio_dis))
|
||||
&& (p == static_cast<std::uint_fast8_t>(~QK_priv_.nextPrio_dis)));
|
||||
Q_REQUIRE_INCRIT(510, (prio_in <= QF_MAX_ACTIVE)
|
||||
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)
|
||||
std::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 = static_cast<std::uint_fast8_t>(~QK_priv_.nextPrio);
|
||||
#endif
|
||||
|
||||
std::uint_fast8_t pthre_in;
|
||||
QP::QActive *a;
|
||||
if (prio_in == 0U) { // preempting the idle thread?
|
||||
pthre_in = 0U;
|
||||
}
|
||||
else {
|
||||
a = QP::QActive::registry_[prio_in];
|
||||
std::uint_fast8_t pthre_in = 0U; // assume preempting the idle thread
|
||||
if (prio_in != 0U) { // preempting NOT the idle thread
|
||||
QP::QActive const * const a = QP::QActive::registry_[prio_in];
|
||||
Q_ASSERT_INCRIT(510, a != nullptr);
|
||||
|
||||
pthre_in = static_cast<std::uint_fast8_t>(a->getPThre());
|
||||
Q_INVARIANT_INCRIT(511, pthre_in == static_cast<std::uint_fast8_t>(
|
||||
~static_cast<std::uint_fast8_t>(a->m_pthre_dis) & 0xFFU));
|
||||
}
|
||||
|
||||
// loop until no more ready-to-run AOs of higher pthre than the initial
|
||||
do {
|
||||
a = QP::QActive::registry_[p]; // obtain the pointer to the AO
|
||||
QP::QActive * const a = QP::QActive::registry_[p];
|
||||
Q_ASSERT_INCRIT(520, a != nullptr); // the AO must be registered
|
||||
std::uint_fast8_t const pthre
|
||||
= static_cast<std::uint_fast8_t>(a->getPThre());
|
||||
Q_INVARIANT_INCRIT(522, pthre == static_cast<std::uint_fast8_t>(
|
||||
~static_cast<std::uint_fast8_t>(a->m_pthre_dis) & 0xFFU));
|
||||
|
||||
// set new active prio. and preemption-threshold
|
||||
QK_priv_.actPrio = p;
|
||||
QK_priv_.actThre = pthre;
|
||||
#ifndef Q_UNSAFE
|
||||
QK_priv_.actPrio_dis = static_cast<std::uint_fast8_t>(~p);
|
||||
QK_priv_.actThre_dis = static_cast<std::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(QP::QS_SCHED_NEXT, p)
|
||||
@ -255,108 +221,68 @@ void QK_activate_() noexcept {
|
||||
pprev); // previous prio.
|
||||
QS_END_PRE()
|
||||
|
||||
#ifdef QF_ON_CONTEXT_SW
|
||||
#ifdef QF_ON_CONTEXT_SW
|
||||
QF_onContextSw(QP::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
|
||||
|
||||
QP::QEvt const * const e = a->get_();
|
||||
// NOTE QActive_get_() performs QF_MEM_APP() before return
|
||||
|
||||
// dispatch event (virtual call)
|
||||
a->dispatch(e, a->getPrio());
|
||||
#if (QF_MAX_EPOOL > 0U)
|
||||
#if (QF_MAX_EPOOL > 0U)
|
||||
QP::QF::gc(e);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// determine the next highest-prio. AO ready to run...
|
||||
QF_INT_DISABLE(); // unconditionally disable interrupts
|
||||
QF_MEM_SYS();
|
||||
p = QK_sched_act_(a, pthre_in); // schedule next AO
|
||||
|
||||
// internal integrity check (duplicate inverse storage)
|
||||
Q_INVARIANT_INCRIT(532,
|
||||
QK_priv_.readySet.verify_(&QK_priv_.readySet_dis));
|
||||
|
||||
if (a->getEQueue().isEmpty()) { // empty queue?
|
||||
QK_priv_.readySet.remove(p);
|
||||
#ifndef Q_UNSAFE
|
||||
QK_priv_.readySet.update_(&QK_priv_.readySet_dis);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (QK_priv_.readySet.isEmpty()) {
|
||||
p = 0U; // no activation needed
|
||||
}
|
||||
else {
|
||||
// find new highest-prio AO ready to run...
|
||||
p = QK_priv_.readySet.findMax();
|
||||
|
||||
// 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 == ~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 = static_cast<std::uint_fast8_t>(~QK_priv_.actPrio);
|
||||
QK_priv_.actThre_dis = static_cast<std::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 = QP::QActive::registry_[prio_in]; // pointer to preempted AO
|
||||
|
||||
QS_BEGIN_PRE(QP::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(QP::QActive::registry_[pprev],
|
||||
QP::QActive::registry_[prio_in]);
|
||||
#endif // QF_ON_CONTEXT_SW
|
||||
}
|
||||
else { // resuming prio.==0 --> idle
|
||||
a = nullptr; // QK idle loop
|
||||
|
||||
QS_BEGIN_PRE(QP::QS_SCHED_IDLE, pprev)
|
||||
QS_TIME_PRE(); // timestamp
|
||||
QS_U8_PRE(pprev); // previous prio.
|
||||
QS_END_PRE()
|
||||
|
||||
#ifdef QF_ON_CONTEXT_SW
|
||||
QF_onContextSw(QP::QActive::registry_[pprev], nullptr);
|
||||
#endif // QF_ON_CONTEXT_SW
|
||||
}
|
||||
|
||||
#ifdef QF_ON_CONTEXT_SW
|
||||
QF_onContextSw(QP::QActive::registry_[pprev], a);
|
||||
#endif // QF_ON_CONTEXT_SW
|
||||
|
||||
#endif // QF_ON_CONTEXT_SW || Q_SPY
|
||||
#endif // QF_ON_CONTEXT_SW || Q_SPY
|
||||
}
|
||||
//$enddef${QK-extern-C} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
} // extern "C"
|
||||
|
||||
//$define${QK::QF-cust} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
//............................................................................
|
||||
namespace QP {
|
||||
namespace QF {
|
||||
|
||||
//${QK::QF-cust::init} .......................................................
|
||||
//............................................................................
|
||||
void init() {
|
||||
bzero_(&QF::priv_, sizeof(QF::priv_));
|
||||
bzero_(&QK_priv_, sizeof(QK_priv_));
|
||||
@ -365,83 +291,61 @@ void init() {
|
||||
// setup the QK scheduler as initially locked and not running
|
||||
QK_priv_.lockCeil = (QF_MAX_ACTIVE + 1U); // scheduler locked
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
QK_priv_.readySet.update_(&QK_priv_.readySet_dis);
|
||||
QK_priv_.actPrio_dis = static_cast<std::uint_fast8_t>(~QK_priv_.actPrio);
|
||||
QK_priv_.nextPrio_dis = static_cast<std::uint_fast8_t>(~QK_priv_.nextPrio);
|
||||
QK_priv_.actThre_dis = static_cast<std::uint_fast8_t>(~QK_priv_.actThre);
|
||||
QK_priv_.lockCeil_dis = static_cast<std::uint_fast8_t>(~QK_priv_.lockCeil);
|
||||
#endif
|
||||
|
||||
#ifdef QK_INIT
|
||||
#ifdef QK_INIT
|
||||
QK_INIT(); // port-specific initialization of the QK kernel
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
//${QK::QF-cust::stop} .......................................................
|
||||
//............................................................................
|
||||
void stop() {
|
||||
onCleanup(); // cleanup callback
|
||||
// nothing else to do for the QK preemptive kernel
|
||||
onCleanup(); // application-specific cleanup callback
|
||||
// nothing else to do for the preemptive QK kernel
|
||||
}
|
||||
|
||||
//${QK::QF-cust::run} ........................................................
|
||||
//............................................................................
|
||||
int_t run() {
|
||||
#ifdef Q_SPY
|
||||
#ifdef Q_SPY
|
||||
// produce the QS_QF_RUN trace record
|
||||
QF_INT_DISABLE();
|
||||
QF_MEM_SYS();
|
||||
QS::beginRec_(QS_REC_NUM_(QS_QF_RUN));
|
||||
QS::endRec_();
|
||||
QF_MEM_APP();
|
||||
QF_INT_ENABLE();
|
||||
#endif // Q_SPY
|
||||
#endif // Q_SPY
|
||||
|
||||
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 = static_cast<std::uint_fast8_t>(~QK_priv_.lockCeil);
|
||||
#endif
|
||||
|
||||
#ifdef QF_ON_CONTEXT_SW
|
||||
#ifdef QF_ON_CONTEXT_SW
|
||||
// officially switch to the idle context
|
||||
QF_onContextSw(nullptr, 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__ // GNU compiler?
|
||||
#ifdef __GNUC__ // GNU compiler?
|
||||
return 0;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace QF
|
||||
} // namespace QP
|
||||
//$enddef${QK::QF-cust} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
//$define${QK::QActive} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
namespace QP {
|
||||
|
||||
//${QK::QActive} .............................................................
|
||||
|
||||
//${QK::QActive::start} ......................................................
|
||||
//............................................................................
|
||||
void QActive::start(
|
||||
QPrioSpec const prioSpec,
|
||||
QEvtPtr * const qSto,
|
||||
@ -455,15 +359,13 @@ void QActive::start(
|
||||
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
QF_MEM_SYS();
|
||||
|
||||
Q_REQUIRE_INCRIT(300, (!QK_ISR_CONTEXT_())
|
||||
&& (stkSto == nullptr));
|
||||
QF_MEM_APP();
|
||||
Q_REQUIRE_INCRIT(300,
|
||||
(stkSto == nullptr));
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
m_prio = static_cast<std::uint8_t>(prioSpec & 0xFFU); // QF-prio.
|
||||
m_pthre = static_cast<std::uint8_t>(prioSpec >> 8U); // preemption-thre.
|
||||
m_pthre = static_cast<std::uint8_t>(prioSpec >> 8U); // preemption-thre.
|
||||
register_(); // make QF aware of this AO
|
||||
|
||||
m_eQueue.init(qSto, qLen); // init the built-in queue
|
||||
@ -474,13 +376,10 @@ void QActive::start(
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
} // namespace QP
|
||||
//$enddef${QK::QActive} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -1,10 +1,6 @@
|
||||
//$file${src::qs::qstamp.cpp} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
//
|
||||
// Model: qpcpp.qm
|
||||
// File: ${src::qs::qstamp.cpp}
|
||||
//
|
||||
// This code has been generated by QM 7.0.0 <www.state-machine.com/qm>.
|
||||
// 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:
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//
|
||||
//$endhead${src::qs::qstamp.cpp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//============================================================================
|
||||
#include "qstamp.hpp"
|
||||
|
||||
namespace QP {
|
||||
|
149
src/qv/qv.cpp
149
src/qv/qv.cpp
@ -1,10 +1,6 @@
|
||||
//$file${src::qv::qv.cpp} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
//
|
||||
// Model: qpcpp.qm
|
||||
// File: ${src::qv::qv.cpp}
|
||||
//
|
||||
// This code has been generated by QM 7.0.0 <www.state-machine.com/qm>.
|
||||
// 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,8 +10,8 @@
|
||||
//
|
||||
// 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-
|
||||
// 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.
|
||||
@ -30,8 +26,7 @@
|
||||
// Quantum Leaps contact information:
|
||||
// <www.state-machine.com/licensing>
|
||||
// <info@state-machine.com>
|
||||
//
|
||||
//$endhead${src::qv::qv.cpp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//============================================================================
|
||||
#define QP_IMPL // this is QP implementation
|
||||
#include "qp_port.hpp" // QP port
|
||||
#include "qp_pkg.hpp" // QP package-scope interface
|
||||
@ -45,7 +40,7 @@
|
||||
|
||||
// protection against including this source file in a wrong project
|
||||
#ifndef QV_HPP_
|
||||
#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_HPP_
|
||||
|
||||
// unnamed namespace for local definitions with internal linkage
|
||||
@ -53,27 +48,15 @@ namespace {
|
||||
Q_DEFINE_THIS_MODULE("qv")
|
||||
} // unnamed namespace
|
||||
|
||||
//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
// Check for the minimum required QP version
|
||||
#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE^4294967295U)%0x2710U))
|
||||
#error qpcpp version 7.3.0 or higher required
|
||||
#endif
|
||||
//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//$define${QV::QV-base} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
namespace QP {
|
||||
namespace QV {
|
||||
|
||||
//${QV::QV-base::priv_} ......................................................
|
||||
QV::Attr priv_;
|
||||
|
||||
//${QV::QV-base::schedDisable} ...............................................
|
||||
//............................................................................
|
||||
void schedDisable(std::uint_fast8_t const ceiling) {
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
QF_MEM_SYS();
|
||||
|
||||
Q_INVARIANT_INCRIT(102, priv_.schedCeil
|
||||
== static_cast<std::uint_fast8_t>(~priv_.schedCeil_dis));
|
||||
|
||||
if (ceiling > priv_.schedCeil) { // raising the scheduler ceiling?
|
||||
|
||||
@ -85,22 +68,14 @@ void schedDisable(std::uint_fast8_t const ceiling) {
|
||||
QS_END_PRE()
|
||||
|
||||
priv_.schedCeil = ceiling;
|
||||
#ifndef Q_UNSAFE
|
||||
priv_.schedCeil_dis = static_cast<std::uint_fast8_t>(~ceiling);
|
||||
#endif
|
||||
}
|
||||
QF_MEM_APP();
|
||||
QF_CRIT_EXIT();
|
||||
}
|
||||
|
||||
//${QV::QV-base::schedEnable} ................................................
|
||||
//............................................................................
|
||||
void schedEnable() {
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
QF_MEM_SYS();
|
||||
|
||||
Q_INVARIANT_INCRIT(202, priv_.schedCeil
|
||||
== static_cast<std::uint_fast8_t>(~priv_.schedCeil_dis));
|
||||
|
||||
if (priv_.schedCeil != 0U) { // actually enabling the scheduler?
|
||||
|
||||
@ -111,39 +86,26 @@ void schedEnable() {
|
||||
QS_END_PRE()
|
||||
|
||||
priv_.schedCeil = 0U;
|
||||
#ifndef Q_UNSAFE
|
||||
priv_.schedCeil_dis = ~static_cast<std::uint_fast8_t>(0U);
|
||||
#endif
|
||||
}
|
||||
QF_MEM_APP();
|
||||
QF_CRIT_EXIT();
|
||||
}
|
||||
|
||||
} // namespace QV
|
||||
} // namespace QP
|
||||
//$enddef${QV::QV-base} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
//$define${QV::QF-cust} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
namespace QP {
|
||||
namespace QF {
|
||||
|
||||
//${QV::QF-cust::init} .......................................................
|
||||
//............................................................................
|
||||
void init() {
|
||||
bzero_(&QF::priv_, sizeof(QF::priv_));
|
||||
bzero_(&QV::priv_, sizeof(QV::priv_));
|
||||
bzero_(&QActive::registry_[0], sizeof(QActive::registry_));
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
QV::priv_.readySet.update_(&QV::priv_.readySet_dis);
|
||||
QV::priv_.schedCeil_dis = ~static_cast<std::uint_fast8_t>(0U);
|
||||
#endif
|
||||
|
||||
#ifdef QV_INIT
|
||||
#ifdef QV_INIT
|
||||
QV_INIT(); // port-specific initialization of the QV kernel
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
//${QV::QF-cust::stop} .......................................................
|
||||
//............................................................................
|
||||
void stop() {
|
||||
onCleanup(); // cleanup callback
|
||||
// nothing else to do for the QV kernel
|
||||
@ -151,44 +113,33 @@ void stop() {
|
||||
|
||||
//${QV::QF-cust::run} ........................................................
|
||||
int_t run() {
|
||||
#ifdef Q_SPY
|
||||
#ifdef Q_SPY
|
||||
// produce the QS_QF_RUN trace record
|
||||
QF_INT_DISABLE();
|
||||
QF_MEM_SYS();
|
||||
QS::beginRec_(QS_REC_NUM_(QS_QF_RUN));
|
||||
QS::endRec_();
|
||||
QF_MEM_APP();
|
||||
QF_INT_ENABLE();
|
||||
#endif // Q_SPY
|
||||
#endif // Q_SPY
|
||||
|
||||
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)
|
||||
std::uint_fast8_t pprev = 0U; // previous prio.
|
||||
|
||||
#ifdef QF_ON_CONTEXT_SW
|
||||
#ifdef QF_ON_CONTEXT_SW
|
||||
// officially switch to the idle cotext
|
||||
QF_onContextSw(nullptr, nullptr);
|
||||
#endif // def QF_ON_CONTEXT_SW
|
||||
#endif // def QF_ON_CONTEXT_SW
|
||||
|
||||
#endif // (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,
|
||||
QV::priv_.readySet.verify_(&QV::priv_.readySet_dis));
|
||||
// check internal integrity (duplicate inverse storage)
|
||||
Q_INVARIANT_INCRIT(303, QV::priv_.schedCeil
|
||||
== static_cast<std::uint_fast8_t>(~QV::priv_.schedCeil_dis));
|
||||
|
||||
// find the maximum prio. AO ready to run
|
||||
std::uint_fast8_t const p = (QV::priv_.readySet.notEmpty()
|
||||
? QV::priv_.readySet.findMax()
|
||||
@ -197,90 +148,72 @@ int_t run() {
|
||||
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(static_cast<std::uint8_t>(p),
|
||||
static_cast<std::uint8_t>(pprev));
|
||||
QS_END_PRE()
|
||||
|
||||
#ifdef QF_ON_CONTEXT_SW
|
||||
#ifdef QF_ON_CONTEXT_SW
|
||||
QF_onContextSw(((pprev != 0U)
|
||||
? QActive::registry_[pprev]
|
||||
: nullptr), 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 = a->get_();
|
||||
// NOTE QActive::get_() performs QF_MEM_APP() before return
|
||||
|
||||
// dispatch event (virtual call)
|
||||
a->dispatch(e, a->getPrio());
|
||||
#if (QF_MAX_EPOOL > 0U)
|
||||
#if (QF_MAX_EPOOL > 0U)
|
||||
gc(e);
|
||||
#endif
|
||||
#endif
|
||||
QF_INT_DISABLE();
|
||||
QF_MEM_SYS();
|
||||
|
||||
if (a->getEQueue().isEmpty()) { // empty queue?
|
||||
QV::priv_.readySet.remove(p);
|
||||
#ifndef Q_UNSAFE
|
||||
QV::priv_.readySet.update_(&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(static_cast<std::uint8_t>(pprev));
|
||||
QS_END_PRE()
|
||||
|
||||
#ifdef QF_ON_CONTEXT_SW
|
||||
#ifdef QF_ON_CONTEXT_SW
|
||||
QF_onContextSw(QActive::registry_[pprev], nullptr);
|
||||
#endif // QF_ON_CONTEXT_SW
|
||||
#endif // QF_ON_CONTEXT_SW
|
||||
|
||||
pprev = 0U; // update previous prio
|
||||
}
|
||||
#endif // (defined QF_ON_CONTEXT_SW) || (defined Q_SPY)
|
||||
#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 (all event
|
||||
// queues empty) can change at any time by an interrupt posting
|
||||
// events to a queue.
|
||||
// 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 at the same time as putting the CPU into a power-
|
||||
// saving mode.
|
||||
// NOTE: QV::onIdle() MUST enable interrupts internally, ideally
|
||||
// atomically with putting the CPU into a power-saving mode.
|
||||
QV::onIdle();
|
||||
|
||||
QF_INT_DISABLE();
|
||||
QF_MEM_SYS();
|
||||
}
|
||||
}
|
||||
#ifdef __GNUC__ // GNU compiler?
|
||||
#ifdef __GNUC__ // GNU compiler?
|
||||
return 0;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace QF
|
||||
} // namespace QP
|
||||
//$enddef${QV::QF-cust} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
//$define${QV::QActive} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
namespace QP {
|
||||
|
||||
//${QV::QActive} .............................................................
|
||||
|
||||
//${QV::QActive::start} ......................................................
|
||||
//............................................................................
|
||||
void QActive::start(
|
||||
QPrioSpec const prioSpec,
|
||||
QEvtPtr * const qSto,
|
||||
@ -294,7 +227,8 @@ void QActive::start(
|
||||
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
Q_REQUIRE_INCRIT(300, stkSto == nullptr);
|
||||
Q_REQUIRE_INCRIT(300,
|
||||
stkSto == nullptr);
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
m_prio = static_cast<std::uint8_t>(prioSpec & 0xFFU); // QF-prio.
|
||||
@ -308,4 +242,3 @@ void QActive::start(
|
||||
}
|
||||
|
||||
} // namespace QP
|
||||
//$enddef${QV::QActive} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user