//$file${include::qp.hpp} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv // // Model: qpcpp.qm // File: ${include::qp.hpp} // // This code has been generated by QM 6.1.1 . // 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 . // // 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: // // The terms of the closed source Quantum Leaps commercial licenses // can be found at: // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // // Contact information: // // // //$endhead${include::qp.hpp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #ifndef QP_HPP_ #define QP_HPP_ //============================================================================ #define QP_VERSION_STR "7.4.0-rc.1" #define QP_VERSION 740U #define QP_RELEASE 0x7092C3BBU //============================================================================ //! @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}; enum DynEvt: std::uint8_t { DYNAMIC }; public: explicit constexpr QEvt(QSignal const s) noexcept : sig(s), refCtr_(0U), evtTag_(MARKER) {} QEvt() = delete; void init() noexcept { // no event parameters to initialize } void init(DynEvt const dummy) noexcept { static_cast(dummy); // no event parameters to initialize } 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(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(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(me); static_cast(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(tatbl); return Q_RET_TRAN; } QState qm_tran_init(void const * const tatbl) noexcept { m_temp.tatbl = static_cast(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(tatbl); return Q_RET_TRAN_HIST; } QState qm_tran_ep(void const * const tatbl) noexcept { m_temp.tatbl = static_cast(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(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(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(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(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(e)) //${QEP-macros::Q_STATE_CAST} ................................................ #define Q_STATE_CAST(handler_) \ (reinterpret_cast(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(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(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(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(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(1U) << (n - 1U))) != 0U; #else return (n <= 32U) ? ((m_bits[0] & (static_cast(1U) << (n - 1U))) != 0U) : ((m_bits[1] & (static_cast(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(1U) << (n - 1U))); #else if (n <= 32U) { m_bits[0] = (m_bits[0] | (static_cast(1U) << (n - 1U))); } else { m_bits[1] = (m_bits[1] | (static_cast(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(~(1U << (n - 1U)))); #else if (n <= 32U) { (m_bits[0] = (m_bits[0] & ~(static_cast(1U) << (n - 1U)))); } else { (m_bits[1] = (m_bits[1] & ~(static_cast(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(~dis->m_bits[0]); #else return (m_bits[0] == static_cast(~dis->m_bits[0])) && (m_bits[1] == static_cast(~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(~m_prio); m_pthre_dis = static_cast(~m_pthre); #endif } public: void init( void const * const e, std::uint_fast8_t const qsId) override { reinterpret_cast(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(this)->QHsm::dispatch(e, qsId); } bool isIn(QStateHandler const state) noexcept override { return reinterpret_cast(this)->QHsm::isIn(state); } QStateHandler childState(QStateHandler const parent) noexcept { return reinterpret_cast(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(m_prio); } void setPrio(QPrioSpec const prio) noexcept { m_prio = static_cast(prio & 0xFFU); m_pthre = static_cast(prio >> 8U); } std::uint_fast8_t getPThre() const noexcept { return static_cast(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(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(this)->QMsm::dispatch(e, qsId); } bool isIn(QStateHandler const state) noexcept override { return reinterpret_cast(this)->QMsm::isIn(state); } #ifdef Q_SPY QStateHandler getStateHandler() noexcept override { return reinterpret_cast(this)->QMsm::getStateHandler(); } #endif // def Q_SPY bool isInState(QMState const * const st) const noexcept { return reinterpret_cast(this)->QMsm::isInState(st); } QMState const * childStateObj(QMState const * const parent) const noexcept { return reinterpret_cast(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; 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(m_act); } QTimeEvt * toTimeEvt() noexcept { return static_cast(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::q_new} ....................................................... #ifndef QEVT_PAR_INIT template inline evtT_ * q_new(enum_t const sig) { return static_cast( QP::QF::newX_(sizeof(evtT_), QP::QF::NO_MARGIN, sig)); } #endif // ndef QEVT_PAR_INIT //${QF::QF-dyn::q_new} ....................................................... #ifdef QEVT_PAR_INIT template inline evtT_ * q_new( enum_t const sig, Args... args) { evtT_ *e = static_cast( QP::QF::newX_(sizeof(evtT_), QP::QF::NO_MARGIN, sig)); e->init(args...); // e cannot be nullptr return e; } #endif // def QEVT_PAR_INIT //${QF::QF-dyn::q_new_x} ..................................................... #ifndef QEVT_PAR_INIT template inline evtT_ * q_new_x( std::uint_fast16_t const margin, enum_t const sig) { return static_cast(QP::QF::newX_(sizeof(evtT_), margin, sig)); } #endif // ndef QEVT_PAR_INIT //${QF::QF-dyn::q_new_x} ..................................................... #ifdef QEVT_PAR_INIT template inline evtT_ * q_new_x( std::uint_fast16_t const margin, enum_t const sig, Args... args) { evtT_ *e = static_cast(QP::QF::newX_(sizeof(evtT_), margin, sig)); if (e != nullptr) { e->init(args...); } return e; } #endif // def QEVT_PAR_INIT //${QF::QF-dyn::q_new_ref} ................................................... template inline void q_new_ref( QP::QEvt const * const e, evtT_ const *& evtRef) { evtRef = static_cast(QP::QF::newRef_(e, evtRef)); } //${QF::QF-dyn::q_delete_ref} ................................................ template inline void q_delete_ref(evtT_ const *& evtRef) { QP::QF::deleteRef_(evtRef); evtRef = nullptr; } //${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((prio_) | (pthre_) << 8U)) //${QF-macros::Q_NEW} ........................................................ #ifndef QEVT_PAR_INIT #define Q_NEW(evtT_, sig_) (QP::QF::q_new((sig_))) #endif // ndef QEVT_PAR_INIT //${QF-macros::Q_NEW} ........................................................ #ifdef QEVT_PAR_INIT #define Q_NEW(evtT_, sig_, ...) (QP::QF::q_new((sig_), __VA_ARGS__)) #endif // def QEVT_PAR_INIT //${QF-macros::Q_NEW_X} ...................................................... #ifndef QEVT_PAR_INIT #define Q_NEW_X(evtT_, margin_, sig_) (QP::QF::q_new_x((margin_), (sig_))) #endif // ndef QEVT_PAR_INIT //${QF-macros::Q_NEW_X} ...................................................... #ifdef QEVT_PAR_INIT #define Q_NEW_X(evtT_, margin_, sig_, ...) (QP::QF::q_new_x((margin_), (sig_), __VA_ARGS__)) #endif // def QEVT_PAR_INIT //${QF-macros::Q_NEW_REF} .................................................... #define Q_NEW_REF(evtRef_, evtT_) (QP::QF::q_new_ref(e, (evtRef_))) //${QF-macros::Q_DELETE_REF} ................................................. #define Q_DELETE_REF(evtRef_) do { \ QP::QF::deleteRef_((evtRef_)); \ (evtRef_) = nullptr; \ } 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(0)) #endif // ndef QF_CRIT_EXIT_NOP //${QF-macros::QF_MEM_SYS} ................................................... #ifndef QF_MEM_SYS #define QF_MEM_SYS() (static_cast(0)) #endif // ndef QF_MEM_SYS //${QF-macros::QF_MEM_APP} ................................................... #ifndef QF_MEM_APP #define QF_MEM_APP() (static_cast(0)) #endif // ndef QF_MEM_APP //$enddecl${QF-macros} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #endif // QP_HPP_