qpcpp/include/qp.hpp
MMS a2c05d3b05 7.3.3
bug https://sourceforge.net/p/qpc/bugs/349/
QS adaptation for MPU isolation
2024-02-22 18:52:20 -05:00

1281 lines
40 KiB
C++

//$file${include::qp.hpp} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
//
// Model: qpcpp.qm
// File: ${include::qp.hpp}
//
// 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) : qpcpp
// Support ends : 2024-12-31
// License scope:
//
// Copyright (C) 2005 Quantum Leaps, LLC <state-machine.com>.
//
// 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>
//
// 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/licensing>
// <info@state-machine.com>
//
//$endhead${include::qp.hpp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#ifndef QP_HPP_
#define QP_HPP_
//============================================================================
#define QP_VERSION 733U
#define QP_VERSION_STR "7.3.3"
//! Encrypted current QP release (7.3.3) and date (2024-03-01)
#define QP_RELEASE 0x70C4F752U
//============================================================================
//! @cond INTERNAL
#ifndef Q_SIGNAL_SIZE
#define Q_SIGNAL_SIZE 2U
#endif // ndef Q_SIGNAL_SIZE
#ifndef QF_MAX_ACTIVE
#define QF_MAX_ACTIVE 32U
#endif
#if (QF_MAX_ACTIVE > 64U)
#error QF_MAX_ACTIVE exceeds the maximum of 64U;
#endif
#ifndef QF_MAX_TICK_RATE
#define QF_MAX_TICK_RATE 1U
#endif
#if (QF_MAX_TICK_RATE > 15U)
#error QF_MAX_TICK_RATE exceeds the maximum of 15U;
#endif
#ifndef QF_MAX_EPOOL
#define QF_MAX_EPOOL 3U
#endif
#if (QF_MAX_EPOOL > 15U)
#error QF_MAX_EPOOL exceeds the maximum of 15U;
#endif
#ifndef QF_TIMEEVT_CTR_SIZE
#define QF_TIMEEVT_CTR_SIZE 4U
#endif
#if (QF_TIMEEVT_CTR_SIZE > 4U)
#error QF_TIMEEVT_CTR_SIZE defined incorrectly, expected 1U, 2U, or 4U;
#endif
#ifndef QF_EVENT_SIZ_SIZE
#define QF_EVENT_SIZ_SIZE 2U
#endif
#if (QF_EVENT_SIZ_SIZE > 4U)
#error QF_EVENT_SIZ_SIZE defined incorrectly, expected 1U, 2U, or 4U;
#endif
//! @endcond
//============================================================================
//$declare${glob-types} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
//${glob-types::int_t} .......................................................
using int_t = int;
//${glob-types::enum_t} ......................................................
using enum_t = int;
//${glob-types::float32_t} ...................................................
using float32_t = float;
//${glob-types::float64_t} ...................................................
using float64_t = double;
//$enddecl${glob-types} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//$declare${QEP} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
namespace QP {
//${QEP::versionStr[]} .......................................................
constexpr char const versionStr[] {QP_VERSION_STR};
//${QEP::QSignal} ............................................................
#if (Q_SIGNAL_SIZE == 1U)
using QSignal = std::uint8_t;
#endif // (Q_SIGNAL_SIZE == 1U)
//${QEP::QSignal} ............................................................
#if (Q_SIGNAL_SIZE == 2U)
using QSignal = std::uint16_t;
#endif // (Q_SIGNAL_SIZE == 2U)
//${QEP::QSignal} ............................................................
#if (Q_SIGNAL_SIZE == 4U)
using QSignal = std::uint32_t;
#endif // (Q_SIGNAL_SIZE == 4U)
//${QEP::QEvt} ...............................................................
class QEvt {
public:
QSignal sig;
std::uint8_t volatile refCtr_;
std::uint8_t evtTag_;
public:
static constexpr std::uint8_t MARKER {0xE0U};
#ifdef QEVT_DYN_CTOR
enum DynEvt: std::uint8_t { DYNAMIC };
#endif // def QEVT_DYN_CTOR
public:
#ifdef QEVT_DYN_CTOR
QEvt * ctor(DynEvt const dummy) noexcept;
#endif // def QEVT_DYN_CTOR
explicit constexpr QEvt(QSignal const s) noexcept
: sig(s),
refCtr_(0U),
evtTag_(MARKER)
{}
QEvt() = delete;
static bool verify_(QEvt const * const e) noexcept {
return (e != nullptr)
&& ((e->evtTag_ & 0xF0U) == MARKER);
}
std::uint_fast8_t getPoolNum_() const noexcept {
return static_cast<std::uint8_t>(evtTag_) & 0x0FU;
}
}; // class QEvt
//${QEP::QState} .............................................................
using QState = std::uint_fast8_t;
//${QEP::QStateHandler} ......................................................
using QStateHandler = QState (*)(void * const me, QEvt const * const e);
//${QEP::QActionHandler} .....................................................
using QActionHandler = QState (*)(void * const me);
//${QEP::QXThread} ...........................................................
// forward declaration
class QXThread;
//${QEP::QXThreadHandler} ....................................................
using QXThreadHandler = void (*)(QXThread * const me);
//${QEP::QMState} ............................................................
struct QMState {
QMState const * superstate;
QStateHandler const stateHandler;
QActionHandler const entryAction;
QActionHandler const exitAction;
QActionHandler const initAction;
};
//${QEP::QMTranActTable} .....................................................
struct QMTranActTable {
QMState const * target;
QActionHandler const act[1];
};
//${QEP::QAsmAttr} ...........................................................
union QAsmAttr {
QStateHandler fun;
QActionHandler act;
QXThreadHandler thr;
QMState const *obj;
QMTranActTable const *tatbl;
#ifndef Q_UNSAFE
std::uintptr_t uint;
#endif
constexpr QAsmAttr() : fun(nullptr) {}
};
//${QEP::Q_USER_SIG} .........................................................
constexpr enum_t Q_USER_SIG {4};
//${QEP::QAsm} ...............................................................
class QAsm {
protected:
QAsmAttr m_state;
QAsmAttr m_temp;
public:
//! All possible return values from state-handlers
//! @note
//! The order is important for algorithmic correctness.
enum QStateRet : QState {
// unhandled and need to "bubble up"
Q_RET_SUPER, //!< event passed to superstate to handle
Q_RET_SUPER_SUB, //!< event passed to submachine superstate
Q_RET_UNHANDLED, //!< event unhandled due to a guard
// handled and do not need to "bubble up"
Q_RET_HANDLED, //!< event handled (internal transition)
Q_RET_IGNORED, //!< event silently ignored (bubbled up to top)
// entry/exit
Q_RET_ENTRY, //!< state entry action executed
Q_RET_EXIT, //!< state exit action executed
// no side effects
Q_RET_NULL, //!< return value without any effect
// transitions need to execute transition-action table in QP::QMsm
Q_RET_TRAN, //!< regular transition
Q_RET_TRAN_INIT, //!< initial transition in a state or submachine
Q_RET_TRAN_EP, //!< entry-point transition into a submachine
// transitions that additionally clobber QHsm.m_state
Q_RET_TRAN_HIST, //!< transition to history of a given state
Q_RET_TRAN_XP //!< exit-point transition out of a submachine
};
//! Reserved signals by the QP-framework.
enum ReservedSig : QSignal {
Q_EMPTY_SIG, //!< signal to execute the default case
Q_ENTRY_SIG, //!< signal for entry actions
Q_EXIT_SIG, //!< signal for exit actions
Q_INIT_SIG //!< signal for nested initial transitions
};
protected:
explicit QAsm() noexcept
: m_state(),
m_temp ()
{}
public:
#ifdef Q_XTOR
virtual ~QAsm() noexcept {
// empty
}
#endif // def Q_XTOR
virtual void init(
void const * const e,
std::uint_fast8_t const qsId) = 0;
virtual void init(std::uint_fast8_t const qsId) {
this->init(nullptr, qsId);
}
virtual void dispatch(
QEvt const * const e,
std::uint_fast8_t const qsId) = 0;
virtual bool isIn(QStateHandler const state) noexcept {
static_cast<void>(state);
return false;
}
QStateHandler state() const noexcept {
return m_state.fun;
}
QMState const * stateObj() const noexcept {
return m_state.obj;
}
#ifdef Q_SPY
virtual QStateHandler getStateHandler() noexcept {
return m_state.fun;
}
#endif // def Q_SPY
static QState top(
void * const me,
QEvt const * const e) noexcept
{
static_cast<void>(me);
static_cast<void>(e);
return Q_RET_IGNORED; // the top state ignores all events
}
protected:
QState tran(QStateHandler const target) noexcept {
m_temp.fun = target;
return Q_RET_TRAN;
}
QState tran_hist(QStateHandler const hist) noexcept {
m_temp.fun = hist;
return Q_RET_TRAN_HIST;
}
QState super(QStateHandler const superstate) noexcept {
m_temp.fun = superstate;
return Q_RET_SUPER;
}
QState qm_tran(void const * const tatbl) noexcept {
m_temp.tatbl = static_cast<QP::QMTranActTable const *>(tatbl);
return Q_RET_TRAN;
}
QState qm_tran_init(void const * const tatbl) noexcept {
m_temp.tatbl = static_cast<QP::QMTranActTable const *>(tatbl);
return Q_RET_TRAN_INIT;
}
QState qm_tran_hist(
QMState const * const hist,
void const * const tatbl) noexcept
{
m_state.obj = hist;
m_temp.tatbl = static_cast<QP::QMTranActTable const *>(tatbl);
return Q_RET_TRAN_HIST;
}
QState qm_tran_ep(void const * const tatbl) noexcept {
m_temp.tatbl = static_cast<QP::QMTranActTable const *>(tatbl);
return Q_RET_TRAN_EP;
}
QState qm_tran_xp(
QActionHandler const xp,
void const * const tatbl) noexcept
{
m_state.act = xp;
m_temp.tatbl = static_cast<QP::QMTranActTable const *>(tatbl);
return Q_RET_TRAN_XP;
}
#ifdef Q_SPY
QState qm_entry(QMState const * const s) noexcept {
m_temp.obj = s;
return Q_RET_ENTRY;
}
#endif // def Q_SPY
#ifndef Q_SPY
QState qm_entry(QMState const * const s) noexcept {
static_cast<void>(s); // unused parameter
return Q_RET_ENTRY;
}
#endif // ndef Q_SPY
#ifdef Q_SPY
QState qm_exit(QMState const * const s) noexcept {
m_temp.obj = s;
return Q_RET_EXIT;
}
#endif // def Q_SPY
#ifndef Q_SPY
QState qm_exit(QMState const * const s) noexcept {
static_cast<void>(s); // unused parameter
return Q_RET_EXIT;
}
#endif // ndef Q_SPY
QState qm_sm_exit(QMState const * const s) noexcept {
m_temp.obj = s;
return Q_RET_EXIT;
}
QState qm_super_sub(QMState const * const s) noexcept {
m_temp.obj = s;
return Q_RET_SUPER_SUB;
}
}; // class QAsm
//${QEP::QHsm} ...............................................................
class QHsm : public QP::QAsm {
public:
static constexpr std::int_fast8_t MAX_NEST_DEPTH_{6};
protected:
explicit QHsm(QStateHandler const initial) noexcept;
public:
void init(
void const * const e,
std::uint_fast8_t const qsId) override;
void init(std::uint_fast8_t const qsId) override {
this->init(nullptr, qsId);
}
void dispatch(
QEvt const * const e,
std::uint_fast8_t const qsId) override;
bool isIn(QStateHandler const state) noexcept override;
QStateHandler childState(QStateHandler const parent) noexcept;
#ifdef Q_SPY
QStateHandler getStateHandler() noexcept override {
return m_state.fun;
}
#endif // def Q_SPY
private:
std::int_fast8_t hsm_tran(
QStateHandler (&path)[MAX_NEST_DEPTH_],
std::uint_fast8_t const qsId);
}; // class QHsm
//${QEP::QMsm} ...............................................................
class QMsm : public QP::QAsm {
protected:
explicit QMsm(QStateHandler const initial) noexcept;
public:
void init(
void const * const e,
std::uint_fast8_t const qsId) override;
void init(std::uint_fast8_t const qsId) override {
this->init(nullptr, qsId);
}
void dispatch(
QEvt const * const e,
std::uint_fast8_t const qsId) override;
#ifdef Q_SPY
QStateHandler getStateHandler() noexcept override {
return m_state.obj->stateHandler;
}
#endif // def Q_SPY
bool isIn(QStateHandler const state) noexcept override;
//! @deprecated instead use: QMsm::isIn()
bool isInState(QMState const * const stateObj) const noexcept;
QMState const * childStateObj(QMState const * const parent) const noexcept;
private:
QState execTatbl_(
QMTranActTable const * const tatbl,
std::uint_fast8_t const qsId);
void exitToTranSource_(
QMState const * const cs,
QMState const * const ts,
std::uint_fast8_t const qsId);
QState enterHistory_(
QMState const * const hist,
std::uint_fast8_t const qsId);
public:
QMState const * topQMState() const noexcept;
}; // class QMsm
} // namespace QP
//$enddecl${QEP} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//$declare${QEP-macros} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
//${QEP-macros::Q_STATE_DECL} ................................................
#define Q_STATE_DECL(state_) \
QP::QState state_ ## _h(QP::QEvt const * const e); \
static QP::QState state_(void * const me, QP::QEvt const * const e)
//${QEP-macros::Q_STATE_DEF} .................................................
#define Q_STATE_DEF(subclass_, state_) \
QP::QState subclass_::state_(void * const me, QP::QEvt const * const e) { \
return static_cast<subclass_ *>(me)->state_ ## _h(e); } \
QP::QState subclass_::state_ ## _h(QP::QEvt const * const e)
//${QEP-macros::Q_HANDLED} ...................................................
#define Q_HANDLED() (Q_RET_HANDLED)
//${QEP-macros::Q_UNHANDLED} .................................................
#define Q_UNHANDLED() (Q_RET_UNHANDLED)
//${QEP-macros::Q_EVT_CAST} ..................................................
#define Q_EVT_CAST(subclass_) (static_cast<subclass_ const *>(e))
//${QEP-macros::Q_STATE_CAST} ................................................
#define Q_STATE_CAST(handler_) \
(reinterpret_cast<QP::QStateHandler>(handler_))
//${QEP-macros::QM_STATE_DECL} ...............................................
#define QM_STATE_DECL(state_) \
QP::QState state_ ## _h(QP::QEvt const * const e); \
static QP::QState state_(void * const me, QP::QEvt const * const e); \
static QP::QMState const state_ ## _s
//${QEP-macros::QM_SM_STATE_DECL} ............................................
#define QM_SM_STATE_DECL(subm_, state_) \
QP::QState state_ ## _h(QP::QEvt const * const e);\
static QP::QState state_(void * const me, QP::QEvt const * const e); \
static SM_ ## subm_ const state_ ## _s
//${QEP-macros::QM_ACTION_DECL} ..............................................
#define QM_ACTION_DECL(action_) \
QP::QState action_ ## _h(); \
static QP::QState action_(void * const me)
//${QEP-macros::QM_STATE_DEF} ................................................
#define QM_STATE_DEF(subclass_, state_) \
QP::QState subclass_::state_(void * const me, QP::QEvt const * const e) {\
return static_cast<subclass_ *>(me)->state_ ## _h(e); } \
QP::QState subclass_::state_ ## _h(QP::QEvt const * const e)
//${QEP-macros::QM_ACTION_DEF} ...............................................
#define QM_ACTION_DEF(subclass_, action_) \
QP::QState subclass_::action_(void * const me) { \
return static_cast<subclass_ *>(me)->action_ ## _h(); } \
QP::QState subclass_::action_ ## _h()
//${QEP-macros::QM_HANDLED} ..................................................
#define QM_HANDLED() (Q_RET_HANDLED)
//${QEP-macros::QM_UNHANDLED} ................................................
#define QM_UNHANDLED() (Q_RET_HANDLED)
//${QEP-macros::QM_SUPER} ....................................................
#define QM_SUPER() (Q_RET_SUPER)
//${QEP-macros::QM_STATE_NULL} ...............................................
#define QM_STATE_NULL (nullptr)
//${QEP-macros::Q_ACTION_NULL} ...............................................
#define Q_ACTION_NULL (nullptr)
//${QEP-macros::Q_UNUSED_PAR} ................................................
#define Q_UNUSED_PAR(par_) (static_cast<void>(par_))
//${QEP-macros::Q_DIM} .......................................................
#define Q_DIM(array_) (sizeof(array_) / sizeof((array_)[0U]))
//${QEP-macros::Q_UINT2PTR_CAST} .............................................
#define Q_UINT2PTR_CAST(type_, uint_) (reinterpret_cast<type_ *>(uint_))
//${QEP-macros::INIT} ........................................................
#ifdef Q_SPY
#define INIT(qsId_) init((qsId_))
#endif // def Q_SPY
//${QEP-macros::INIT} ........................................................
#ifndef Q_SPY
#define INIT(dummy) init(0U)
#endif // ndef Q_SPY
//${QEP-macros::DISPATCH} ....................................................
#ifdef Q_SPY
#define DISPATCH(e_, qsId_) dispatch((e_), (qsId_))
#endif // def Q_SPY
//${QEP-macros::DISPATCH} ....................................................
#ifndef Q_SPY
#define DISPATCH(e_, dummy) dispatch((e_), 0U)
#endif // ndef Q_SPY
//$enddecl${QEP-macros} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//$declare${QF::types} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
namespace QP {
//${QF::types::QPrioSpec} ....................................................
using QPrioSpec = std::uint16_t;
//${QF::types::QTimeEvtCtr} ..................................................
#if (QF_TIMEEVT_CTR_SIZE == 1U)
using QTimeEvtCtr = std::uint8_t;
#endif // (QF_TIMEEVT_CTR_SIZE == 1U)
//${QF::types::QTimeEvtCtr} ..................................................
#if (QF_TIMEEVT_CTR_SIZE == 2U)
using QTimeEvtCtr = std::uint16_t;
#endif // (QF_TIMEEVT_CTR_SIZE == 2U)
//${QF::types::QTimeEvtCtr} ..................................................
#if (QF_TIMEEVT_CTR_SIZE == 4U)
using QTimeEvtCtr = std::uint32_t;
#endif // (QF_TIMEEVT_CTR_SIZE == 4U)
//${QF::types::QPSetBits} ....................................................
#if (QF_MAX_ACTIVE <= 8U)
using QPSetBits = std::uint8_t;
#endif // (QF_MAX_ACTIVE <= 8U)
//${QF::types::QPSetBits} ....................................................
#if (8U < QF_MAX_ACTIVE) && (QF_MAX_ACTIVE <= 16U)
using QPSetBits = std::uint16_t;
#endif // (8U < QF_MAX_ACTIVE) && (QF_MAX_ACTIVE <= 16U)
//${QF::types::QPSetBits} ....................................................
#if (16 < QF_MAX_ACTIVE)
using QPSetBits = std::uint32_t;
#endif // (16 < QF_MAX_ACTIVE)
//${QF::types::QF_LOG2} ......................................................
#ifndef QF_LOG2
std::uint_fast8_t QF_LOG2(QP::QPSetBits x) noexcept;
#endif // ndef QF_LOG2
//${QF::types::QPSet} ........................................................
class QPSet {
private:
QPSetBits m_bits[((QF_MAX_ACTIVE + (8U*sizeof(QPSetBits))) - 1U)/(8U*sizeof(QPSetBits))];
public:
void setEmpty() noexcept {
m_bits[0] = 0U;
#if (QF_MAX_ACTIVE > 32)
m_bits[1] = 0U;
#endif
}
bool isEmpty() const noexcept {
#if (QF_MAX_ACTIVE <= 32U)
return (m_bits[0] == 0U);
#else
return (m_bits[0] == 0U) ? (m_bits[1] == 0U) : false;
#endif
}
bool notEmpty() const noexcept {
#if (QF_MAX_ACTIVE <= 32U)
return (m_bits[0] != 0U);
#else
return (m_bits[0] != 0U) ? true : (m_bits[1] != 0U);
#endif
}
bool hasElement(std::uint_fast8_t const n) const noexcept {
#if (QF_MAX_ACTIVE <= 32U)
return (m_bits[0] & (static_cast<QPSetBits>(1U) << (n - 1U))) != 0U;
#else
return (n <= 32U)
? ((m_bits[0] & (static_cast<QPSetBits>(1U) << (n - 1U))) != 0U)
: ((m_bits[1] & (static_cast<QPSetBits>(1U) << (n - 33U))) != 0U);
#endif
}
void insert(std::uint_fast8_t const n) noexcept {
#if (QF_MAX_ACTIVE <= 32U)
m_bits[0] = (m_bits[0] | (static_cast<QPSetBits>(1U) << (n - 1U)));
#else
if (n <= 32U) {
m_bits[0] = (m_bits[0] | (static_cast<QPSetBits>(1U) << (n - 1U)));
}
else {
m_bits[1] = (m_bits[1] | (static_cast<QPSetBits>(1U) << (n - 33U)));
}
#endif
}
void remove(std::uint_fast8_t const n) noexcept {
#if (QF_MAX_ACTIVE <= 32U)
m_bits[0] = (m_bits[0] & static_cast<QPSetBits>(~(1U << (n - 1U))));
#else
if (n <= 32U) {
(m_bits[0] = (m_bits[0] & ~(static_cast<QPSetBits>(1U) << (n - 1U))));
}
else {
(m_bits[1] = (m_bits[1] & ~(static_cast<QPSetBits>(1U) << (n - 33U))));
}
#endif
}
std::uint_fast8_t findMax() const noexcept {
#if (QF_MAX_ACTIVE <= 32U)
return QF_LOG2(m_bits[0]);
#else
return (m_bits[1] != 0U)
? (QF_LOG2(m_bits[1]) + 32U)
: (QF_LOG2(m_bits[0]));
#endif
}
#ifndef Q_UNSAFE
void update_(QPSet * const dis) const noexcept {
dis->m_bits[0] = ~m_bits[0];
#if (QF_MAX_ACTIVE > 32U)
dis->m_bits[1] = ~m_bits[1];
#endif
}
#endif // ndef Q_UNSAFE
#ifndef Q_UNSAFE
bool verify_(QPSet const * const dis) const noexcept {
#if (QF_MAX_ACTIVE <= 32U)
return m_bits[0] == static_cast<QPSetBits>(~dis->m_bits[0]);
#else
return (m_bits[0] == static_cast<QPSetBits>(~dis->m_bits[0]))
&& (m_bits[1] == static_cast<QPSetBits>(~dis->m_bits[1]));
#endif
}
#endif // ndef Q_UNSAFE
}; // class QPSet
//${QF::types::QSubscrList} ..................................................
class QSubscrList {
private:
QPSet m_set;
#ifndef Q_UNSAFE
QPSet m_set_dis;
#endif // ndef Q_UNSAFE
// friends...
friend class QActive;
}; // class QSubscrList
//${QF::types::QEQueue} ......................................................
class QEQueue;
} // namespace QP
//$enddecl${QF::types} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//$declare${QF::QActive} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
namespace QP {
//${QF::QActive} .............................................................
class QActive : public QP::QAsm {
protected:
std::uint8_t m_prio;
std::uint8_t m_pthre;
#ifdef QACTIVE_THREAD_TYPE
QACTIVE_THREAD_TYPE m_thread;
#endif // def QACTIVE_THREAD_TYPE
#ifdef QACTIVE_OS_OBJ_TYPE
QACTIVE_OS_OBJ_TYPE m_osObject;
#endif // def QACTIVE_OS_OBJ_TYPE
#ifdef QACTIVE_EQUEUE_TYPE
QACTIVE_EQUEUE_TYPE m_eQueue;
#endif // def QACTIVE_EQUEUE_TYPE
public:
#ifndef Q_UNSAFE
std::uint8_t m_prio_dis;
#endif // ndef Q_UNSAFE
#ifndef Q_UNSAFE
std::uint8_t m_pthre_dis;
#endif // ndef Q_UNSAFE
static QActive * registry_[QF_MAX_ACTIVE + 1U];
static QSubscrList * subscrList_;
static enum_t maxPubSignal_;
// friends...
friend class QTimeEvt;
friend class QTicker;
friend class QXThread;
friend class QXMutex;
friend class QXSemaphore;
friend class QActiveDummy;
friend class GuiQActive;
friend class GuiQMActive;
friend void schedLock();
protected:
explicit QActive(QStateHandler const initial) noexcept
: QAsm(),
m_prio(0U),
m_pthre(0U)
{
m_state.fun = Q_STATE_CAST(&top);
m_temp.fun = initial;
#ifndef Q_UNSAFE
m_prio_dis = static_cast<std::uint8_t>(~m_prio);
m_pthre_dis = static_cast<std::uint8_t>(~m_pthre);
#endif
}
public:
void init(
void const * const e,
std::uint_fast8_t const qsId) override
{
reinterpret_cast<QHsm *>(this)->QHsm::init(e, qsId);
}
void init(std::uint_fast8_t const qsId) override {
this->init(nullptr, qsId);
}
void dispatch(
QEvt const * const e,
std::uint_fast8_t const qsId) override
{
reinterpret_cast<QHsm *>(this)->QHsm::dispatch(e, qsId);
}
bool isIn(QStateHandler const state) noexcept override {
return reinterpret_cast<QHsm *>(this)->QHsm::isIn(state);
}
QStateHandler childState(QStateHandler const parent) noexcept {
return reinterpret_cast<QHsm *>(this)->QHsm::childState(parent);
}
void setAttr(
std::uint32_t attr1,
void const * attr2 = nullptr);
void start(
QPrioSpec const prioSpec,
QEvt const * * const qSto,
std::uint_fast16_t const qLen,
void * const stkSto,
std::uint_fast16_t const stkSize,
void const * const par);
void start(
QPrioSpec const prioSpec,
QEvt const * * const qSto,
std::uint_fast16_t const qLen,
void * const stkSto,
std::uint_fast16_t const stkSize)
{
this->start(prioSpec, qSto, qLen, stkSto, stkSize, nullptr);
}
#ifdef QACTIVE_CAN_STOP
void stop();
#endif // def QACTIVE_CAN_STOP
void register_() noexcept;
void unregister_() noexcept;
bool post_(
QEvt const * const e,
std::uint_fast16_t const margin,
void const * const sender) noexcept;
void postLIFO(QEvt const * const e) noexcept;
QEvt const * get_() noexcept;
static std::uint_fast16_t getQueueMin(std::uint_fast8_t const prio) noexcept;
static void psInit(
QSubscrList * const subscrSto,
enum_t const maxSignal) noexcept;
static void publish_(
QEvt const * const e,
void const * const sender,
std::uint_fast8_t const qsId) noexcept;
void subscribe(enum_t const sig) const noexcept;
void unsubscribe(enum_t const sig) const noexcept;
void unsubscribeAll() const noexcept;
bool defer(
QEQueue * const eq,
QEvt const * const e) const noexcept;
bool recall(QEQueue * const eq) noexcept;
std::uint_fast16_t flushDeferred(
QEQueue * const eq,
std::uint_fast16_t const num = 0xFFFFU) const noexcept;
std::uint_fast8_t getPrio() const noexcept {
return static_cast<std::uint_fast8_t>(m_prio);
}
void setPrio(QPrioSpec const prio) noexcept {
m_prio = static_cast<std::uint8_t>(prio & 0xFFU);
m_pthre = static_cast<std::uint8_t>(prio >> 8U);
}
std::uint_fast8_t getPThre() const noexcept {
return static_cast<std::uint_fast8_t>(m_pthre);
}
#ifdef QACTIVE_EQUEUE_TYPE
QACTIVE_EQUEUE_TYPE const & getEQueue() const noexcept {
return m_eQueue;
}
#endif // def QACTIVE_EQUEUE_TYPE
#ifdef QACTIVE_OS_OBJ_TYPE
QACTIVE_OS_OBJ_TYPE const & getOsObject() const noexcept {
return m_osObject;
}
#endif // def QACTIVE_OS_OBJ_TYPE
#ifdef QACTIVE_THREAD_TYPE
QACTIVE_THREAD_TYPE const & getThread() const noexcept {
return m_thread;
}
#endif // def QACTIVE_THREAD_TYPE
#ifdef QACTIVE_THREAD_TYPE
void setThread(QACTIVE_THREAD_TYPE const & thr) {
m_thread = thr;
}
#endif // def QACTIVE_THREAD_TYPE
static void evtLoop_(QActive * act);
#ifdef QF_ISR_API
virtual bool postFromISR(
QEvt const * const e,
std::uint_fast16_t const margin,
void * par,
void const * const sender) noexcept;
#endif // def QF_ISR_API
#ifdef QF_ISR_API
static void publishFromISR(
QEvt const * e,
void * par,
void const * sender) noexcept;
#endif // def QF_ISR_API
}; // class QActive
} // namespace QP
//$enddecl${QF::QActive} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//$declare${QF::QMActive} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
namespace QP {
//${QF::QMActive} ............................................................
class QMActive : public QP::QActive {
protected:
QMActive(QStateHandler const initial) noexcept;
public:
void init(
void const * const e,
std::uint_fast8_t const qsId) override
{
reinterpret_cast<QMsm *>(this)->QMsm::init(e, qsId);
}
void init(std::uint_fast8_t const qsId) override {
this->init(nullptr, qsId);
}
void dispatch(
QEvt const * const e,
std::uint_fast8_t const qsId) override
{
reinterpret_cast<QMsm *>(this)->QMsm::dispatch(e, qsId);
}
bool isIn(QStateHandler const state) noexcept override {
return reinterpret_cast<QMsm *>(this)->QMsm::isIn(state);
}
#ifdef Q_SPY
QStateHandler getStateHandler() noexcept override {
return reinterpret_cast<QMsm *>(this)->QMsm::getStateHandler();
}
#endif // def Q_SPY
bool isInState(QMState const * const st) const noexcept {
return reinterpret_cast<QMsm const *>(this)->QMsm::isInState(st);
}
QMState const * childStateObj(QMState const * const parent) const noexcept {
return reinterpret_cast<QMsm const *>(this)
->QMsm::childStateObj(parent);
}
}; // class QMActive
} // namespace QP
//$enddecl${QF::QMActive} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//$declare${QF::QTimeEvt} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
namespace QP {
//${QF::QTimeEvt} ............................................................
class QTimeEvt : public QP::QEvt {
private:
QTimeEvt * volatile m_next;
void * m_act;
QTimeEvtCtr volatile m_ctr;
QTimeEvtCtr m_interval;
public:
static QTimeEvt timeEvtHead_[QF_MAX_TICK_RATE];
private:
friend class QXThread;
public:
QTimeEvt(
QActive * const act,
QSignal const sig,
std::uint_fast8_t const tickRate = 0U) noexcept;
#ifdef Q_XTOR
~QTimeEvt();
#endif // def Q_XTOR
void armX(
QTimeEvtCtr const nTicks,
QTimeEvtCtr const interval = 0U) noexcept;
bool disarm() noexcept;
bool rearm(QTimeEvtCtr const nTicks) noexcept;
bool wasDisarmed() noexcept;
void const * getAct() const noexcept {
return m_act;
}
QTimeEvtCtr getCtr() const noexcept {
return m_ctr;
}
QTimeEvtCtr getInterval() const noexcept {
return m_interval;
}
static void tick(
std::uint_fast8_t const tickRate,
void const * const sender) noexcept;
#ifdef Q_UTEST
static void tick1_(
std::uint_fast8_t const tickRate,
void const * const sender);
#endif // def Q_UTEST
#ifdef QF_ISR_API
static void tickFromISR(
std::uint_fast8_t const tickRate,
void * par,
void const * sender) noexcept;
#endif // def QF_ISR_API
static bool noActive(std::uint_fast8_t const tickRate) noexcept;
QActive * toActive() noexcept {
return static_cast<QActive *>(m_act);
}
QTimeEvt * toTimeEvt() noexcept {
return static_cast<QTimeEvt *>(m_act);
}
private:
QTimeEvt() noexcept;
QTimeEvt(QTimeEvt const & other) = delete;
QTimeEvt & operator=(QTimeEvt const & other) = delete;
}; // class QTimeEvt
} // namespace QP
//$enddecl${QF::QTimeEvt} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//$declare${QF::QTicker} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
namespace QP {
//${QF::QTicker} .............................................................
class QTicker : public QP::QActive {
public:
explicit QTicker(std::uint_fast8_t const tickRate) noexcept;
void init(
void const * const e,
std::uint_fast8_t const qsId) override;
void init(std::uint_fast8_t const qsId) override {
this->init(nullptr, qsId);
}
void dispatch(
QEvt const * const e,
std::uint_fast8_t const qsId) override;
void trig_(void const * const sender) noexcept;
}; // class QTicker
} // namespace QP
//$enddecl${QF::QTicker} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//$declare${QF::QF-base} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
namespace QP {
namespace QF {
//${QF::QF-base::init} .......................................................
void init();
//${QF::QF-base::stop} .......................................................
void stop();
//${QF::QF-base::run} ........................................................
int_t run();
//${QF::QF-base::onStartup} ..................................................
void onStartup();
//${QF::QF-base::onCleanup} ..................................................
void onCleanup();
//${QF::QF-base::psInit} .....................................................
//! @deprecated
inline void psInit(
QSubscrList * const subscrSto,
enum_t const maxSignal) noexcept
{
QActive::psInit(subscrSto, maxSignal);
}
//${QF::QF-base::publish_} ...................................................
//! @deprecated
inline void publish_(
QEvt const * const e,
void const * const sender,
std::uint_fast8_t const qsId) noexcept
{
QActive::publish_(e, sender, qsId);
}
//${QF::QF-base::tick} .......................................................
//! @deprecated
inline void tick(
std::uint_fast8_t const tickRate,
void const * const sender) noexcept
{
QTimeEvt::tick(tickRate, sender);
}
//${QF::QF-base::getQueueMin} ................................................
//! @deprecated
inline std::uint_fast16_t getQueueMin(std::uint_fast8_t const prio) noexcept {
return QActive::getQueueMin(prio);
}
//${QF::QF-base::NO_MARGIN} ..................................................
constexpr std::uint_fast16_t NO_MARGIN {0xFFFFU};
} // namespace QF
} // namespace QP
//$enddecl${QF::QF-base} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//$declare${QF::QF-dyn} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
namespace QP {
namespace QF {
//${QF::QF-dyn::poolInit} ....................................................
void poolInit(
void * const poolSto,
std::uint_fast32_t const poolSize,
std::uint_fast16_t const evtSize) noexcept;
//${QF::QF-dyn::poolGetMaxBlockSize} .........................................
std::uint_fast16_t poolGetMaxBlockSize() noexcept;
//${QF::QF-dyn::getPoolMin} ..................................................
std::uint_fast16_t getPoolMin(std::uint_fast8_t const poolNum) noexcept;
//${QF::QF-dyn::newX_} .......................................................
QEvt * newX_(
std::uint_fast16_t const evtSize,
std::uint_fast16_t const margin,
enum_t const sig) noexcept;
//${QF::QF-dyn::gc} ..........................................................
void gc(QEvt const * const e) noexcept;
//${QF::QF-dyn::newRef_} .....................................................
QEvt const * newRef_(
QEvt const * const e,
QEvt const * const evtRef) noexcept;
//${QF::QF-dyn::deleteRef_} ..................................................
void deleteRef_(QEvt const * const evtRef) noexcept;
//${QF::QF-dyn::newXfromISR_} ................................................
#ifdef QF_ISR_API
QEvt * newXfromISR_(
std::uint_fast16_t const evtSize,
std::uint_fast16_t const margin,
enum_t const sig) noexcept;
#endif // def QF_ISR_API
//${QF::QF-dyn::gcFromISR} ...................................................
#ifdef QF_ISR_API
void gcFromISR(QEvt const * e) noexcept;
#endif // def QF_ISR_API
} // namespace QF
} // namespace QP
//$enddecl${QF::QF-dyn} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
extern "C" {
//$declare${QF-extern-C} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
//${QF-extern-C::QF_onContextSw} .............................................
#ifdef QF_ON_CONTEXT_SW
void QF_onContextSw(
QP::QActive * prev,
QP::QActive * next);
#endif // def QF_ON_CONTEXT_SW
//$enddecl${QF-extern-C} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
} // extern "C"
//$declare${QF-macros} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
//${QF-macros::Q_PRIO} .......................................................
#define Q_PRIO(prio_, pthre_) \
(static_cast<QP::QPrioSpec>((prio_) | (pthre_) << 8U))
//${QF-macros::Q_NEW} ........................................................
#ifndef QEVT_DYN_CTOR
#define Q_NEW(evtT_, sig_) (static_cast<evtT_ *>( \
QP::QF::newX_(sizeof(evtT_), QP::QF::NO_MARGIN, (sig_))))
#endif // ndef QEVT_DYN_CTOR
//${QF-macros::Q_NEW} ........................................................
#ifdef QEVT_DYN_CTOR
#define Q_NEW(evtT_, sig_, ...) ( static_cast<evtT_ *>( \
QP::QF::newX_(sizeof(evtT_), QP::QF::NO_MARGIN, (sig_)))->ctor(__VA_ARGS__))
#endif // def QEVT_DYN_CTOR
//${QF-macros::Q_NEW_X} ......................................................
#ifndef QEVT_DYN_CTOR
#define Q_NEW_X(evtT_, margin_, sig_) (static_cast<evtT_ *>( \
QP::QF::newX_(sizeof(evtT_), (margin_), (sig_))))
#endif // ndef QEVT_DYN_CTOR
//${QF-macros::Q_NEW_X} ......................................................
#ifdef QEVT_DYN_CTOR
#define Q_NEW_X(evtT_, margin_, sig_, ...) ( static_cast<evtT_ *>( \
QP::QF::newX_(sizeof(evtT_), (margin_), (sig_)))->ctor(__VA_ARGS__))
#endif // def QEVT_DYN_CTOR
//${QF-macros::Q_NEW_REF} ....................................................
#define Q_NEW_REF(evtRef_, evtT_) \
((evtRef_) = static_cast<evtT_ const *>(QP::QF::newRef_(e, (evtRef_))))
//${QF-macros::Q_DELETE_REF} .................................................
#define Q_DELETE_REF(evtRef_) do { \
QP::QF::deleteRef_((evtRef_)); \
(evtRef_) = 0U; \
} while (false)
//${QF-macros::PUBLISH} ......................................................
#ifdef Q_SPY
#define PUBLISH(e_, sender_) \
publish_((e_), (sender_), (sender_)->getPrio())
#endif // def Q_SPY
//${QF-macros::PUBLISH} ......................................................
#ifndef Q_SPY
#define PUBLISH(e_, dummy) publish_((e_), nullptr, 0U)
#endif // ndef Q_SPY
//${QF-macros::POST} .........................................................
#ifdef Q_SPY
#define POST(e_, sender_) post_((e_), QP::QF::NO_MARGIN, (sender_))
#endif // def Q_SPY
//${QF-macros::POST} .........................................................
#ifndef Q_SPY
#define POST(e_, dummy) post_((e_), QP::QF::NO_MARGIN, nullptr)
#endif // ndef Q_SPY
//${QF-macros::POST_X} .......................................................
#ifdef Q_SPY
#define POST_X(e_, margin_, sender_) \
post_((e_), (margin_), (sender_))
#endif // def Q_SPY
//${QF-macros::POST_X} .......................................................
#ifndef Q_SPY
#define POST_X(e_, margin_, dummy) post_((e_), (margin_), nullptr)
#endif // ndef Q_SPY
//${QF-macros::TICK_X} .......................................................
#ifdef Q_SPY
#define TICK_X(tickRate_, sender_) tick((tickRate_), (sender_))
#endif // def Q_SPY
//${QF-macros::TICK_X} .......................................................
#ifndef Q_SPY
#define TICK_X(tickRate_, dummy) tick((tickRate_), nullptr)
#endif // ndef Q_SPY
//${QF-macros::TICK} .........................................................
#define TICK(sender_) TICK_X(0U, (sender_))
//${QF-macros::TRIG} .........................................................
#ifdef Q_SPY
#define TRIG(sender_) trig_((sender_))
#endif // def Q_SPY
//${QF-macros::TRIG} .........................................................
#ifndef Q_SPY
#define TRIG(sender_) trig_(nullptr)
#endif // ndef Q_SPY
//${QF-macros::QF_CRIT_EXIT_NOP} .............................................
#ifndef QF_CRIT_EXIT_NOP
#define QF_CRIT_EXIT_NOP() (static_cast<void>(0))
#endif // ndef QF_CRIT_EXIT_NOP
//${QF-macros::QF_MEM_SYS} ...................................................
#ifndef QF_MEM_SYS
#define QF_MEM_SYS() (static_cast<void>(0))
#endif // ndef QF_MEM_SYS
//${QF-macros::QF_MEM_APP} ...................................................
#ifndef QF_MEM_APP
#define QF_MEM_APP() (static_cast<void>(0))
#endif // ndef QF_MEM_APP
//$enddecl${QF-macros} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#endif // QP_HPP_