mirror of
https://github.com/QuantumLeaps/qpcpp.git
synced 2025-01-14 05:42:57 +08:00
a2c05d3b05
bug https://sourceforge.net/p/qpc/bugs/349/ QS adaptation for MPU isolation
1281 lines
40 KiB
C++
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_
|